mirror of https://github.com/ArduPilot/ardupilot
AP_Proximity: Add support for CAN MR72
This commit is contained in:
parent
0cdfdc6234
commit
b8d08a7211
|
@ -30,6 +30,8 @@
|
||||||
#include "AP_Proximity_DroneCAN.h"
|
#include "AP_Proximity_DroneCAN.h"
|
||||||
#include "AP_Proximity_Scripting.h"
|
#include "AP_Proximity_Scripting.h"
|
||||||
#include "AP_Proximity_LD06.h"
|
#include "AP_Proximity_LD06.h"
|
||||||
|
#include "AP_Proximity_MR72_CAN.h"
|
||||||
|
|
||||||
|
|
||||||
#include <AP_Logger/AP_Logger.h>
|
#include <AP_Logger/AP_Logger.h>
|
||||||
|
|
||||||
|
@ -81,27 +83,45 @@ const AP_Param::GroupInfo AP_Proximity::var_info[] = {
|
||||||
// @Path: AP_Proximity_Params.cpp
|
// @Path: AP_Proximity_Params.cpp
|
||||||
AP_SUBGROUPINFO(params[0], "1", 21, AP_Proximity, AP_Proximity_Params),
|
AP_SUBGROUPINFO(params[0], "1", 21, AP_Proximity, AP_Proximity_Params),
|
||||||
|
|
||||||
|
// @Group: 1_
|
||||||
|
// @Path: AP_Proximity_MR72_CAN.cpp
|
||||||
|
AP_SUBGROUPVARPTR(drivers[0], "1_", 26, AP_Proximity, backend_var_info[0]),
|
||||||
|
|
||||||
#if PROXIMITY_MAX_INSTANCES > 1
|
#if PROXIMITY_MAX_INSTANCES > 1
|
||||||
// @Group: 2
|
// @Group: 2
|
||||||
// @Path: AP_Proximity_Params.cpp
|
// @Path: AP_Proximity_Params.cpp
|
||||||
AP_SUBGROUPINFO(params[1], "2", 22, AP_Proximity, AP_Proximity_Params),
|
AP_SUBGROUPINFO(params[1], "2", 22, AP_Proximity, AP_Proximity_Params),
|
||||||
|
|
||||||
|
// @Group: 2_
|
||||||
|
// @Path: AP_Proximity_MR72_CAN.cpp
|
||||||
|
AP_SUBGROUPVARPTR(drivers[1], "2_", 27, AP_Proximity, backend_var_info[1]),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PROXIMITY_MAX_INSTANCES > 2
|
#if PROXIMITY_MAX_INSTANCES > 2
|
||||||
// @Group: 3
|
// @Group: 3
|
||||||
// @Path: AP_Proximity_Params.cpp
|
// @Path: AP_Proximity_Params.cpp
|
||||||
AP_SUBGROUPINFO(params[2], "3", 23, AP_Proximity, AP_Proximity_Params),
|
AP_SUBGROUPINFO(params[2], "3", 23, AP_Proximity, AP_Proximity_Params),
|
||||||
|
|
||||||
|
// @Group: 3_
|
||||||
|
// @Path: AP_Proximity_MR72_CAN.cpp
|
||||||
|
AP_SUBGROUPVARPTR(drivers[2], "3_", 28, AP_Proximity, backend_var_info[2]),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PROXIMITY_MAX_INSTANCES > 3
|
#if PROXIMITY_MAX_INSTANCES > 3
|
||||||
// @Group: 4
|
// @Group: 4
|
||||||
// @Path: AP_Proximity_Params.cpp
|
// @Path: AP_Proximity_Params.cpp
|
||||||
AP_SUBGROUPINFO(params[3], "4", 24, AP_Proximity, AP_Proximity_Params),
|
AP_SUBGROUPINFO(params[3], "4", 24, AP_Proximity, AP_Proximity_Params),
|
||||||
|
|
||||||
|
// @Group: 4_
|
||||||
|
// @Path: AP_Proximity_MR72_CAN.cpp
|
||||||
|
AP_SUBGROUPVARPTR(drivers[3], "4_", 29, AP_Proximity, backend_var_info[3]),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
AP_GROUPEND
|
AP_GROUPEND
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const AP_Param::GroupInfo *AP_Proximity::backend_var_info[PROXIMITY_MAX_INSTANCES];
|
||||||
|
|
||||||
AP_Proximity::AP_Proximity()
|
AP_Proximity::AP_Proximity()
|
||||||
{
|
{
|
||||||
AP_Param::setup_object_defaults(this, var_info);
|
AP_Param::setup_object_defaults(this, var_info);
|
||||||
|
@ -206,6 +226,12 @@ void AP_Proximity::init()
|
||||||
drivers[instance] = new AP_Proximity_Scripting(*this, state[instance], params[instance]);
|
drivers[instance] = new AP_Proximity_Scripting(*this, state[instance], params[instance]);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#if AP_PROXIMITY_MR72_ENABLED
|
||||||
|
case Type::MR72:
|
||||||
|
state[instance].instance = instance;
|
||||||
|
drivers[instance] = new AP_Proximity_MR72_CAN(*this, state[instance], params[instance]);
|
||||||
|
break;
|
||||||
|
# endif
|
||||||
#if AP_PROXIMITY_SITL_ENABLED
|
#if AP_PROXIMITY_SITL_ENABLED
|
||||||
case Type::SITL:
|
case Type::SITL:
|
||||||
state[instance].instance = instance;
|
state[instance].instance = instance;
|
||||||
|
@ -237,6 +263,12 @@ void AP_Proximity::init()
|
||||||
|
|
||||||
// initialise status
|
// initialise status
|
||||||
state[instance].status = Status::NotConnected;
|
state[instance].status = Status::NotConnected;
|
||||||
|
|
||||||
|
// if the backend has some local parameters then make those available in the tree
|
||||||
|
if (drivers[instance] && state[instance].var_info) {
|
||||||
|
backend_var_info[instance] = state[instance].var_info;
|
||||||
|
AP_Param::load_object_from_eeprom(drivers[instance], backend_var_info[instance]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,9 @@ public:
|
||||||
#endif
|
#endif
|
||||||
#if AP_PROXIMITY_LD06_ENABLED
|
#if AP_PROXIMITY_LD06_ENABLED
|
||||||
LD06 = 16,
|
LD06 = 16,
|
||||||
|
#endif
|
||||||
|
#if AP_PROXIMITY_MR72_ENABLED
|
||||||
|
MR72 = 17,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -179,8 +182,12 @@ public:
|
||||||
struct Proximity_State {
|
struct Proximity_State {
|
||||||
uint8_t instance; // the instance number of this proximity sensor
|
uint8_t instance; // the instance number of this proximity sensor
|
||||||
Status status; // sensor status
|
Status status; // sensor status
|
||||||
|
|
||||||
|
const struct AP_Param::GroupInfo *var_info; // stores extra parameter information for the sensor (if it exists)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct AP_Param::GroupInfo *backend_var_info[PROXIMITY_MAX_INSTANCES];
|
||||||
|
|
||||||
// parameter list
|
// parameter list
|
||||||
static const struct AP_Param::GroupInfo var_info[];
|
static const struct AP_Param::GroupInfo var_info[];
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
/*
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "AP_Proximity_config.h"
|
||||||
|
|
||||||
|
#if AP_PROXIMITY_MR72_ENABLED
|
||||||
|
|
||||||
|
#include <AP_HAL/AP_HAL.h>
|
||||||
|
#include <AP_BoardConfig/AP_BoardConfig.h>
|
||||||
|
#include "AP_Proximity_MR72_CAN.h"
|
||||||
|
|
||||||
|
const AP_Param::GroupInfo AP_Proximity_MR72_CAN::var_info[] = {
|
||||||
|
|
||||||
|
// @Param: RECV_ID
|
||||||
|
// @DisplayName: CAN receive ID
|
||||||
|
// @Description: The receive ID of the CAN frames. A value of zero means all IDs are accepted.
|
||||||
|
// @Range: 0 65535
|
||||||
|
// @User: Advanced
|
||||||
|
AP_GROUPINFO("RECV_ID", 1, AP_Proximity_MR72_CAN, receive_id, 0),
|
||||||
|
|
||||||
|
AP_GROUPEND
|
||||||
|
};
|
||||||
|
|
||||||
|
MR72_MultiCAN *AP_Proximity_MR72_CAN::multican;
|
||||||
|
|
||||||
|
AP_Proximity_MR72_CAN::AP_Proximity_MR72_CAN(AP_Proximity &_frontend,
|
||||||
|
AP_Proximity::Proximity_State &_state,
|
||||||
|
AP_Proximity_Params& _params):
|
||||||
|
AP_Proximity_Backend(_frontend, _state, _params)
|
||||||
|
{
|
||||||
|
if (multican == nullptr) {
|
||||||
|
multican = new MR72_MultiCAN();
|
||||||
|
if (multican == nullptr) {
|
||||||
|
AP_BoardConfig::allocation_error("MR72_CAN");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// add to linked list of drivers
|
||||||
|
WITH_SEMAPHORE(multican->sem);
|
||||||
|
auto *prev = multican->drivers;
|
||||||
|
next = prev;
|
||||||
|
multican->drivers = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
AP_Param::setup_object_defaults(this, var_info);
|
||||||
|
state.var_info = var_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update state
|
||||||
|
void AP_Proximity_MR72_CAN::update(void)
|
||||||
|
{
|
||||||
|
WITH_SEMAPHORE(_sem);
|
||||||
|
const uint32_t now = AP_HAL::millis();
|
||||||
|
if (now - last_update_ms > 500) {
|
||||||
|
// no new data.
|
||||||
|
set_status(AP_Proximity::Status::NoData);
|
||||||
|
} else {
|
||||||
|
set_status(AP_Proximity::Status::Good);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// handler for incoming frames. These come in at 100Hz
|
||||||
|
bool AP_Proximity_MR72_CAN::handle_frame(AP_HAL::CANFrame &frame)
|
||||||
|
{
|
||||||
|
WITH_SEMAPHORE(_sem);
|
||||||
|
|
||||||
|
|
||||||
|
// check if message is coming from the right sensor ID
|
||||||
|
const uint16_t id = frame.id;
|
||||||
|
|
||||||
|
if (receive_id > 0 && (get_radar_id(frame.id) != uint32_t(receive_id))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (id & 0xFU) {
|
||||||
|
case 0xAU:
|
||||||
|
// number of objects
|
||||||
|
_object_count = frame.data[0];
|
||||||
|
_current_object_index = 0;
|
||||||
|
_temp_boundary.update_3D_boundary(state.instance, frontend.boundary);
|
||||||
|
_temp_boundary.reset();
|
||||||
|
last_update_ms = AP_HAL::millis();
|
||||||
|
break;
|
||||||
|
case 0xBU:
|
||||||
|
// obstacle data
|
||||||
|
parse_distance_message(frame);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse a distance message from CAN frame
|
||||||
|
bool AP_Proximity_MR72_CAN::parse_distance_message(AP_HAL::CANFrame &frame)
|
||||||
|
{
|
||||||
|
if (_current_object_index >= _object_count) {
|
||||||
|
// should never happen
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_current_object_index++;
|
||||||
|
|
||||||
|
Vector2f obstacle_fr;
|
||||||
|
// This parsing comes from the NanoRadar MR72 datasheet
|
||||||
|
obstacle_fr.x = ((frame.data[2] & 0x07U) * 256 + frame.data[3]) * 0.2 - 204.6;
|
||||||
|
obstacle_fr.y = (frame.data[1] * 32 + (frame.data[2] >> 3)) * 0.2 - 500;
|
||||||
|
const float yaw = correct_angle_for_orientation(wrap_360(degrees(atan2f(obstacle_fr.x, obstacle_fr.y))));
|
||||||
|
|
||||||
|
const float objects_dist = obstacle_fr.length();
|
||||||
|
|
||||||
|
if (ignore_reading(yaw, objects_dist)) {
|
||||||
|
// obstacle is probably near ground or out of range
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AP_Proximity_Boundary_3D::Face face = frontend.boundary.get_face(yaw);
|
||||||
|
_temp_boundary.add_distance(face, yaw, objects_dist);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle frames from CANSensor, passing to the drivers
|
||||||
|
void MR72_MultiCAN::handle_frame(AP_HAL::CANFrame &frame)
|
||||||
|
{
|
||||||
|
WITH_SEMAPHORE(sem);
|
||||||
|
for (auto *d = drivers; d; d=d->next) {
|
||||||
|
if (d->handle_frame(frame)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // HAL_PROXIMITY_ENABLED
|
|
@ -0,0 +1,68 @@
|
||||||
|
#pragma once
|
||||||
|
#include "AP_Proximity_config.h"
|
||||||
|
|
||||||
|
#if AP_PROXIMITY_MR72_ENABLED
|
||||||
|
|
||||||
|
#include "AP_Proximity.h"
|
||||||
|
#include "AP_Proximity_Backend.h"
|
||||||
|
#include <AP_HAL/AP_HAL.h>
|
||||||
|
#include <AP_CANManager/AP_CANSensor.h>
|
||||||
|
|
||||||
|
#define MR72_MAX_RANGE_M 50.0f // max range of the sensor in meters
|
||||||
|
#define MR72_MIN_RANGE_M 0.2f // min range of the sensor in meters
|
||||||
|
|
||||||
|
class MR72_MultiCAN;
|
||||||
|
|
||||||
|
class AP_Proximity_MR72_CAN : public AP_Proximity_Backend {
|
||||||
|
public:
|
||||||
|
friend class MR72_MultiCAN;
|
||||||
|
|
||||||
|
AP_Proximity_MR72_CAN(AP_Proximity &_frontend, AP_Proximity::Proximity_State &_state, AP_Proximity_Params& _params);
|
||||||
|
|
||||||
|
void update() override;
|
||||||
|
|
||||||
|
// handler for incoming frames. Return true if consumed
|
||||||
|
bool handle_frame(AP_HAL::CANFrame &frame);
|
||||||
|
|
||||||
|
// parse a distance message from CAN frame
|
||||||
|
bool parse_distance_message(AP_HAL::CANFrame &frame);
|
||||||
|
|
||||||
|
// get maximum and minimum distances (in meters) of sensor
|
||||||
|
float distance_max() const override { return MR72_MAX_RANGE_M; }
|
||||||
|
float distance_min() const override { return MR72_MIN_RANGE_M; }
|
||||||
|
|
||||||
|
static const struct AP_Param::GroupInfo var_info[];
|
||||||
|
|
||||||
|
AP_Proximity_Temp_Boundary _temp_boundary;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
uint32_t get_radar_id(uint32_t id) const { return ((id & 0xF0U) >> 4U); }
|
||||||
|
|
||||||
|
uint32_t _object_count; // total number of objects to read
|
||||||
|
uint32_t _current_object_index; // current object index
|
||||||
|
uint32_t last_update_ms; // last update time in ms
|
||||||
|
|
||||||
|
AP_Int32 receive_id; // ID of the sensor
|
||||||
|
|
||||||
|
static MR72_MultiCAN *multican; // linked list
|
||||||
|
AP_Proximity_MR72_CAN *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
// a class to allow for multiple MR_72 backends with one
|
||||||
|
// CANSensor driver
|
||||||
|
class MR72_MultiCAN : public CANSensor {
|
||||||
|
public:
|
||||||
|
MR72_MultiCAN() : CANSensor("MR72") {
|
||||||
|
register_driver(AP_CAN::Protocol::MR72);
|
||||||
|
}
|
||||||
|
|
||||||
|
// handler for incoming frames
|
||||||
|
void handle_frame(AP_HAL::CANFrame &frame) override;
|
||||||
|
|
||||||
|
HAL_Semaphore sem;
|
||||||
|
AP_Proximity_MR72_CAN *drivers;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HAL_PROXIMITY_ENABLED
|
|
@ -8,7 +8,7 @@ const AP_Param::GroupInfo AP_Proximity_Params::var_info[] = {
|
||||||
// @Param: _TYPE
|
// @Param: _TYPE
|
||||||
// @DisplayName: Proximity type
|
// @DisplayName: Proximity type
|
||||||
// @Description: What type of proximity sensor is connected
|
// @Description: What type of proximity sensor is connected
|
||||||
// @Values: 0:None,7:LightwareSF40c,2:MAVLink,3:TeraRangerTower,4:RangeFinder,5:RPLidarA2,6:TeraRangerTowerEvo,8:LightwareSF45B,10:SITL,12:AirSimSITL,13:CygbotD1, 14:DroneCAN, 15:Scripting, 16:LD06
|
// @Values: 0:None,7:LightwareSF40c,2:MAVLink,3:TeraRangerTower,4:RangeFinder,5:RPLidarA2,6:TeraRangerTowerEvo,8:LightwareSF45B,10:SITL,12:AirSimSITL,13:CygbotD1, 14:DroneCAN, 15:Scripting, 16:LD06, 17: MR72_CAN
|
||||||
// @RebootRequired: True
|
// @RebootRequired: True
|
||||||
// @User: Standard
|
// @User: Standard
|
||||||
AP_GROUPINFO_FLAGS("_TYPE", 1, AP_Proximity_Params, type, 0, AP_PARAM_FLAG_ENABLE),
|
AP_GROUPINFO_FLAGS("_TYPE", 1, AP_Proximity_Params, type, 0, AP_PARAM_FLAG_ENABLE),
|
||||||
|
|
|
@ -37,6 +37,11 @@
|
||||||
#define AP_PROXIMITY_LIGHTWARE_SF45B_ENABLED AP_PROXIMITY_BACKEND_DEFAULT_ENABLED
|
#define AP_PROXIMITY_LIGHTWARE_SF45B_ENABLED AP_PROXIMITY_BACKEND_DEFAULT_ENABLED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef AP_PROXIMITY_MR72_ENABLED
|
||||||
|
#define AP_PROXIMITY_MR72_ENABLED AP_PROXIMITY_BACKEND_DEFAULT_ENABLED && HAL_MAX_CAN_PROTOCOL_DRIVERS
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef AP_PROXIMITY_SCRIPTING_ENABLED
|
#ifndef AP_PROXIMITY_SCRIPTING_ENABLED
|
||||||
#define AP_PROXIMITY_SCRIPTING_ENABLED AP_PROXIMITY_BACKEND_DEFAULT_ENABLED && AP_SCRIPTING_ENABLED
|
#define AP_PROXIMITY_SCRIPTING_ENABLED AP_PROXIMITY_BACKEND_DEFAULT_ENABLED && AP_SCRIPTING_ENABLED
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue