|
|
|
@ -7,50 +7,25 @@
@@ -7,50 +7,25 @@
|
|
|
|
|
#include <AP_BoardConfig/AP_BoardConfig_CAN.h> |
|
|
|
|
#include <AP_UAVCAN/AP_UAVCAN.h> |
|
|
|
|
|
|
|
|
|
#include<zrzk/equipment/range_sensor/Proximity.hpp> |
|
|
|
|
#include <zrzk/equipment/range_sensor/Proximity.hpp> |
|
|
|
|
|
|
|
|
|
extern const AP_HAL::HAL& hal; |
|
|
|
|
AP_Proximity_UAVCAN::DetectedModules AP_Proximity_UAVCAN::_detected_modules[] = {0}; |
|
|
|
|
UC_REGISTRY_BINDER(ProximityCb, zrzk::equipment::range_sensor::Proximity); |
|
|
|
|
extern const AP_HAL::HAL &hal; |
|
|
|
|
|
|
|
|
|
#define debug_baro_uavcan(level_debug, can_driver, fmt, args...) do { if ((level_debug) <= AP::can().get_debug_level_driver(can_driver)) { printf(fmt, ##args); }} while (0) |
|
|
|
|
#define debug_proximity_uavcan(level_debug, can_driver, fmt, args...) \ |
|
|
|
|
do \
|
|
|
|
|
{ \
|
|
|
|
|
if ((level_debug) <= AP::can().get_debug_level_driver(can_driver)) \
|
|
|
|
|
{ \
|
|
|
|
|
printf(fmt, ##args); \
|
|
|
|
|
} \
|
|
|
|
|
} while (0) |
|
|
|
|
|
|
|
|
|
//HAL_Semaphore AP_Airspeed_UAVCAN::_sem_registry;
|
|
|
|
|
HAL_Semaphore AP_Proximity_UAVCAN::_sem_registry; |
|
|
|
|
UC_REGISTRY_BINDER(ProximityCb, zrzk::equipment::range_sensor::Proximity); |
|
|
|
|
AP_Proximity_UAVCAN::DetectedModules AP_Proximity_UAVCAN::_detected_modules[] = {0}; |
|
|
|
|
|
|
|
|
|
AP_Proximity_UAVCAN::AP_Proximity_UAVCAN( |
|
|
|
|
AP_Proximity &_frontend, |
|
|
|
|
AP_Proximity::Proximity_State &_state): |
|
|
|
|
AP_Proximity_Backend(_frontend,_state) |
|
|
|
|
AP_Proximity_UAVCAN::AP_Proximity_UAVCAN(AP_Proximity &_frontend, AP_Proximity::Proximity_State &_state) : AP_Proximity_Backend(_frontend, _state) |
|
|
|
|
{ |
|
|
|
|
AP_Proximity_UAVCAN *backend = nullptr; |
|
|
|
|
for (uint8_t i = 0; i < PROXIMITY_MAX_INSTANCES; i++) |
|
|
|
|
{ |
|
|
|
|
if (_detected_modules[i].driver == nullptr && _detected_modules[i].ap_uavcan != nullptr) |
|
|
|
|
{ |
|
|
|
|
backend = new AP_Proximity_UAVCAN(_frontend, _state); |
|
|
|
|
if (backend == nullptr) |
|
|
|
|
{ |
|
|
|
|
debug_baro_uavcan(2, |
|
|
|
|
_detected_modules[i].ap_uavcan->get_driver_index(), |
|
|
|
|
"Failed register UAVCAN Proximity Node %d on Bus %d\n", |
|
|
|
|
_detected_modules[i].node_id, |
|
|
|
|
_detected_modules[i].ap_uavcan->get_driver_index()); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
_detected_modules[i].driver = backend; |
|
|
|
|
backend->_ap_uavcan = _detected_modules[i].ap_uavcan; |
|
|
|
|
backend->_node_id = _detected_modules[i].node_id; |
|
|
|
|
backend->register_sensor(); |
|
|
|
|
debug_baro_uavcan(2, |
|
|
|
|
_detected_modules[i].ap_uavcan->get_driver_index(), |
|
|
|
|
"Registered UAVCAN Proximity Node %d on Bus %d\n", |
|
|
|
|
_detected_modules[i].node_id, |
|
|
|
|
_detected_modules[i].ap_uavcan->get_driver_index()); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void AP_Proximity_UAVCAN::subscribe_msgs(AP_UAVCAN *ap_uavcan) |
|
|
|
@ -65,7 +40,7 @@ void AP_Proximity_UAVCAN::subscribe_msgs(AP_UAVCAN *ap_uavcan)
@@ -65,7 +40,7 @@ void AP_Proximity_UAVCAN::subscribe_msgs(AP_UAVCAN *ap_uavcan)
|
|
|
|
|
uavcan::Subscriber<zrzk::equipment::range_sensor::Proximity, ProximityCb> *proximity_listener; |
|
|
|
|
proximity_listener = new uavcan::Subscriber<zrzk::equipment::range_sensor::Proximity, ProximityCb>(*node); |
|
|
|
|
// Register method to handle incoming RangeFinder measurement
|
|
|
|
|
const int proximity_listener_res = proximity_listener->start(ProximityCb(ap_uavcan, &handle_proximity_data)); |
|
|
|
|
const int proximity_listener_res = proximity_listener->start(ProximityCb(ap_uavcan, &handle_proximity_data_trampoline)); |
|
|
|
|
if (proximity_listener_res < 0) |
|
|
|
|
{ |
|
|
|
|
AP_HAL::panic("UAVCAN RangeFinder subscriber start problem\n\r"); |
|
|
|
@ -73,10 +48,13 @@ void AP_Proximity_UAVCAN::subscribe_msgs(AP_UAVCAN *ap_uavcan)
@@ -73,10 +48,13 @@ void AP_Proximity_UAVCAN::subscribe_msgs(AP_UAVCAN *ap_uavcan)
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool AP_Proximity_UAVCAN::detect(AP_Proximity &_frontend, |
|
|
|
|
AP_Proximity::Proximity_State &_state) |
|
|
|
|
AP_Proximity_Backend *AP_Proximity_UAVCAN::probe(AP_Proximity &_frontend, |
|
|
|
|
AP_Proximity::Proximity_State &_state) |
|
|
|
|
{ |
|
|
|
|
WITH_SEMAPHORE(_sem_registry); |
|
|
|
|
|
|
|
|
|
AP_Proximity_UAVCAN *backend = nullptr; |
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < PROXIMITY_MAX_INSTANCES; i++) |
|
|
|
|
{ |
|
|
|
|
if (_detected_modules[i].driver == nullptr && _detected_modules[i].ap_uavcan != nullptr) |
|
|
|
@ -84,23 +62,20 @@ bool AP_Proximity_UAVCAN::detect(AP_Proximity &_frontend,
@@ -84,23 +62,20 @@ bool AP_Proximity_UAVCAN::detect(AP_Proximity &_frontend,
|
|
|
|
|
backend = new AP_Proximity_UAVCAN(_frontend, _state); |
|
|
|
|
if (backend == nullptr) |
|
|
|
|
{ |
|
|
|
|
debug_baro_uavcan(2, |
|
|
|
|
_detected_modules[i].ap_uavcan->get_driver_index(), |
|
|
|
|
"Failed register UAVCAN Proximity Node %d on Bus %d\n", |
|
|
|
|
_detected_modules[i].node_id, |
|
|
|
|
_detected_modules[i].ap_uavcan->get_driver_index()); |
|
|
|
|
debug_proximity_uavcan(2, |
|
|
|
|
_detected_modules[i].ap_uavcan->get_driver_index(), |
|
|
|
|
"Failed register UAVCAN Proximity Node %d on Bus %d\n", |
|
|
|
|
_detected_modules[i].node_id, |
|
|
|
|
_detected_modules[i].ap_uavcan->get_driver_index()); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
_detected_modules[i].driver = backend; |
|
|
|
|
backend->_ap_uavcan = _detected_modules[i].ap_uavcan; |
|
|
|
|
backend->_node_id = _detected_modules[i].node_id; |
|
|
|
|
// backend->register_sensor();
|
|
|
|
|
debug_baro_uavcan(2, |
|
|
|
|
_detected_modules[i].ap_uavcan->get_driver_index(), |
|
|
|
|
"Registered UAVCAN Proximity Node %d on Bus %d\n", |
|
|
|
|
_detected_modules[i].node_id, |
|
|
|
|
_detected_modules[i].ap_uavcan->get_driver_index()); |
|
|
|
|
debug_proximity_uavcan(2, |
|
|
|
|
_detected_modules[i].ap_uavcan->get_driver_index(), |
|
|
|
|
"Registered UAVCAN Proximity Node %d on Bus %d\n", |
|
|
|
|
_detected_modules[i].node_id, |
|
|
|
|
_detected_modules[i].ap_uavcan->get_driver_index()); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
@ -108,44 +83,46 @@ bool AP_Proximity_UAVCAN::detect(AP_Proximity &_frontend,
@@ -108,44 +83,46 @@ bool AP_Proximity_UAVCAN::detect(AP_Proximity &_frontend,
|
|
|
|
|
return backend; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
AP_Proximity_UAVCAN *AP_Proximity_UAVCAN::get_uavcan_backend(AP_UAVCAN *ap_uavcan, uint8_t node_id, bool create_new) |
|
|
|
|
AP_Proximity_UAVCAN *AP_Proximity_UAVCAN::get_uavcan_backend(AP_UAVCAN *ap_uavcan) |
|
|
|
|
{ |
|
|
|
|
if (ap_uavcan == nullptr) |
|
|
|
|
{ |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < PROXIMITY_MAX_INSTANCES; i++) { |
|
|
|
|
for (uint8_t i = 0; i < PROXIMITY_MAX_INSTANCES; i++) |
|
|
|
|
{ |
|
|
|
|
if (_detected_modules[i].driver != nullptr && |
|
|
|
|
_detected_modules[i].ap_uavcan == ap_uavcan &&
|
|
|
|
|
_detected_modules[i].node_id == node_id) { |
|
|
|
|
_detected_modules[i].ap_uavcan == ap_uavcan) |
|
|
|
|
{ |
|
|
|
|
return _detected_modules[i].driver; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (create_new) { |
|
|
|
|
bool already_detected = false; |
|
|
|
|
//Check if there's an empty spot for possible registeration
|
|
|
|
|
for (uint8_t i = 0; i < PROXIMITY_MAX_INSTANCES; i++) { |
|
|
|
|
if (_detected_modules[i].ap_uavcan == ap_uavcan && _detected_modules[i].node_id == node_id) { |
|
|
|
|
//Already Detected
|
|
|
|
|
already_detected = true; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
bool detected = false; |
|
|
|
|
for (uint8_t i = 0; i < PROXIMITY_MAX_INSTANCES; i++) |
|
|
|
|
{ |
|
|
|
|
if (_detected_modules[i].ap_uavcan == ap_uavcan) |
|
|
|
|
{ |
|
|
|
|
// detected
|
|
|
|
|
detected = true; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
if (!already_detected) { |
|
|
|
|
for (uint8_t i = 0; i < PROXIMITY_MAX_INSTANCES; i++) { |
|
|
|
|
if (_detected_modules[i].ap_uavcan == nullptr) { |
|
|
|
|
_detected_modules[i].ap_uavcan = ap_uavcan; |
|
|
|
|
_detected_modules[i].node_id = node_id; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!detected) |
|
|
|
|
{ |
|
|
|
|
for (uint8_t i = 0; i < PROXIMITY_MAX_INSTANCES; i++) |
|
|
|
|
{ |
|
|
|
|
if (_detected_modules[i].ap_uavcan == nullptr) |
|
|
|
|
{ |
|
|
|
|
_detected_modules[i].ap_uavcan = ap_uavcan; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return nullptr; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
float AP_Proximity_UAVCAN::distance_max() const |
|
|
|
@ -160,21 +137,21 @@ float AP_Proximity_UAVCAN::distance_min() const
@@ -160,21 +137,21 @@ float AP_Proximity_UAVCAN::distance_min() const
|
|
|
|
|
|
|
|
|
|
void AP_Proximity_UAVCAN::update(void) |
|
|
|
|
{ |
|
|
|
|
//WITH_SEMAPHORE(_sem_registry);
|
|
|
|
|
update_sector_data(0, d1_cm); // d1
|
|
|
|
|
update_sector_data(45, d8_cm); // d8
|
|
|
|
|
update_sector_data(90, d7_cm); // d7
|
|
|
|
|
update_sector_data(135, d6_cm); // d6
|
|
|
|
|
update_sector_data(180, d5_cm); // d5
|
|
|
|
|
update_sector_data(225, d4_cm); // d4
|
|
|
|
|
update_sector_data(270, d3_cm); // d3
|
|
|
|
|
update_sector_data(315, d2_cm); // d2
|
|
|
|
|
|
|
|
|
|
gcs().send_text(MAV_SEVERITY_INFO,"update data\r\n"); |
|
|
|
|
WITH_SEMAPHORE(_sem_proximity); |
|
|
|
|
|
|
|
|
|
update_sector_data(0, _interim_data.d1_cm); // d1
|
|
|
|
|
update_sector_data(45, _interim_data.d8_cm); // d8
|
|
|
|
|
update_sector_data(90, _interim_data.d7_cm); // d7
|
|
|
|
|
update_sector_data(135, _interim_data.d6_cm); // d6
|
|
|
|
|
update_sector_data(180, _interim_data.d5_cm); // d5
|
|
|
|
|
update_sector_data(225, _interim_data.d4_cm); // d4
|
|
|
|
|
update_sector_data(270, _interim_data.d3_cm); // d3
|
|
|
|
|
update_sector_data(315, _interim_data.d2_cm); // d2
|
|
|
|
|
|
|
|
|
|
if ((_last_distance_received_ms == 0) || (AP_HAL::millis() - _last_distance_received_ms > PROXIMITY_UAVCAN_TIMEOUT_MS)) |
|
|
|
|
{ |
|
|
|
|
set_status(AP_Proximity::Status::NoData); |
|
|
|
|
gcs().send_text(MAV_SEVERITY_INFO,"NoData\r\n"); |
|
|
|
|
// gcs().send_text(MAV_SEVERITY_INFO, "NoData\r\n");
|
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
@ -182,24 +159,45 @@ void AP_Proximity_UAVCAN::update(void)
@@ -182,24 +159,45 @@ void AP_Proximity_UAVCAN::update(void)
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void AP_Proximity_UAVCAN::handle_proximity_data(AP_UAVCAN *ap_uavcan, uint8_t node_id, const ProximityCb &cb) |
|
|
|
|
void AP_Proximity_UAVCAN::handle_proximity_data_trampoline(AP_UAVCAN *ap_uavcan, uint8_t node_id, const ProximityCb &cb) |
|
|
|
|
{ |
|
|
|
|
// WITH_SEMAPHORE(_sem_registry);
|
|
|
|
|
AP_Proximity_UAVCAN *driver = get_uavcan_backend(ap_uavcan, node_id, true); |
|
|
|
|
WITH_SEMAPHORE(_sem_registry); |
|
|
|
|
|
|
|
|
|
AP_Proximity_UAVCAN *driver = get_uavcan_backend(ap_uavcan); |
|
|
|
|
if (driver == nullptr) |
|
|
|
|
{ |
|
|
|
|
gcs().send_text(MAV_SEVERITY_INFO, "driver == nullptr\r\n"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
// WITH_SEMAPHORE(driver->_sem_proximity);
|
|
|
|
|
driver->d1_cm = cb.msg->d0; |
|
|
|
|
driver->d2_cm = cb.msg->d45; |
|
|
|
|
driver->d3_cm = cb.msg->d90; |
|
|
|
|
driver->d5_cm = cb.msg->d90; |
|
|
|
|
driver->d6_cm = cb.msg->d90; |
|
|
|
|
driver->d7_cm = cb.msg->d90; |
|
|
|
|
driver->d8_cm = cb.msg->d90; |
|
|
|
|
gcs().send_text(MAV_SEVERITY_INFO, "get_proximity_data\r\n"); |
|
|
|
|
driver->handle_proximity_data(cb); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void AP_Proximity_UAVCAN::handle_proximity_data(const ProximityCb &cb) |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
WITH_SEMAPHORE(_sem_proximity); |
|
|
|
|
|
|
|
|
|
_interim_data.d1_cm = handle_data_valid(cb.msg->d0); |
|
|
|
|
_interim_data.d2_cm = handle_data_valid(cb.msg->d315); |
|
|
|
|
_interim_data.d3_cm = handle_data_valid(cb.msg->d315); |
|
|
|
|
_interim_data.d5_cm = handle_data_valid(cb.msg->d180); |
|
|
|
|
_interim_data.d6_cm = handle_data_valid(cb.msg->d135); |
|
|
|
|
_interim_data.d7_cm = handle_data_valid(cb.msg->d90); |
|
|
|
|
_interim_data.d8_cm = handle_data_valid(cb.msg->d45); |
|
|
|
|
|
|
|
|
|
_last_distance_received_ms = AP_HAL::millis(); |
|
|
|
|
// _last_sample_time_ms = AP_HAL::millis();
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint16_t AP_Proximity_UAVCAN::handle_data_valid(uint16_t data) |
|
|
|
|
{ |
|
|
|
|
if (data == 0xFFFF) |
|
|
|
|
{ |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
return data / 10; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void AP_Proximity_UAVCAN::update_sector_data(int16_t angle_deg, uint16_t distance_cm) |
|
|
|
@ -208,7 +206,7 @@ void AP_Proximity_UAVCAN::update_sector_data(int16_t angle_deg, uint16_t distanc
@@ -208,7 +206,7 @@ void AP_Proximity_UAVCAN::update_sector_data(int16_t angle_deg, uint16_t distanc
|
|
|
|
|
_angle[sector] = angle_deg; |
|
|
|
|
_distance[sector] = ((float)distance_cm) / 100; |
|
|
|
|
_distance_valid[sector] = distance_cm != 0xffff; |
|
|
|
|
_last_distance_received_ms = AP_HAL::millis(); |
|
|
|
|
//_last_distance_received_ms = AP_HAL::millis();
|
|
|
|
|
// update boundary used for avoidance
|
|
|
|
|
update_boundary_for_sector(sector, true); |
|
|
|
|
} |
|
|
|
|