-
Notifications
You must be signed in to change notification settings - Fork 17.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
AP_Proximity: Add support for CAN MR72
- Loading branch information
1 parent
23e4dad
commit 61b1945
Showing
6 changed files
with
261 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
/* | ||
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; | ||
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters