mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-01-03 14:38:30 -04:00
cd1118acb4
* remove unnecessary nullptr check, these are always called from an initialized AP_DroneCAN so if it's nullptr something has gone horrifically wrong * pass in driver index instead of repeatedly calling function to get it * simplify error handling; knowing exactly which allocation failed is not super helpful and one failing likely means subsequent ones will too, as it can only fail due to being out of memory
187 lines
6.0 KiB
C++
187 lines
6.0 KiB
C++
#include "AP_Airspeed_DroneCAN.h"
|
|
|
|
#if AP_AIRSPEED_DRONECAN_ENABLED
|
|
|
|
#include <AP_CANManager/AP_CANManager.h>
|
|
#include <AP_DroneCAN/AP_DroneCAN.h>
|
|
#include <AP_BoardConfig/AP_BoardConfig.h>
|
|
|
|
extern const AP_HAL::HAL& hal;
|
|
|
|
#define LOG_TAG "AirSpeed"
|
|
|
|
AP_Airspeed_DroneCAN::DetectedModules AP_Airspeed_DroneCAN::_detected_modules[];
|
|
HAL_Semaphore AP_Airspeed_DroneCAN::_sem_registry;
|
|
|
|
bool AP_Airspeed_DroneCAN::subscribe_msgs(AP_DroneCAN* ap_dronecan)
|
|
{
|
|
const auto driver_index = ap_dronecan->get_driver_index();
|
|
|
|
return (Canard::allocate_sub_arg_callback(ap_dronecan, &handle_airspeed, driver_index) != nullptr)
|
|
#if AP_AIRSPEED_HYGROMETER_ENABLE
|
|
&& (Canard::allocate_sub_arg_callback(ap_dronecan, &handle_hygrometer, driver_index) != nullptr)
|
|
#endif
|
|
;
|
|
}
|
|
|
|
AP_Airspeed_Backend* AP_Airspeed_DroneCAN::probe(AP_Airspeed &_frontend, uint8_t _instance, uint32_t previous_devid)
|
|
{
|
|
WITH_SEMAPHORE(_sem_registry);
|
|
|
|
AP_Airspeed_DroneCAN* backend = nullptr;
|
|
|
|
for (uint8_t i = 0; i < AIRSPEED_MAX_SENSORS; i++) {
|
|
if (_detected_modules[i].driver == nullptr && _detected_modules[i].ap_dronecan != nullptr) {
|
|
const auto bus_id = AP_HAL::Device::make_bus_id(AP_HAL::Device::BUS_TYPE_UAVCAN,
|
|
_detected_modules[i].ap_dronecan->get_driver_index(),
|
|
_detected_modules[i].node_id, 0);
|
|
if (previous_devid != 0 && previous_devid != bus_id) {
|
|
// match with previous ID only
|
|
continue;
|
|
}
|
|
backend = NEW_NOTHROW AP_Airspeed_DroneCAN(_frontend, _instance);
|
|
if (backend == nullptr) {
|
|
AP::can().log_text(AP_CANManager::LOG_INFO,
|
|
LOG_TAG,
|
|
"Failed register DroneCAN Airspeed Node %d on Bus %d\n",
|
|
_detected_modules[i].node_id,
|
|
_detected_modules[i].ap_dronecan->get_driver_index());
|
|
} else {
|
|
_detected_modules[i].driver = backend;
|
|
AP::can().log_text(AP_CANManager::LOG_INFO,
|
|
LOG_TAG,
|
|
"Registered DroneCAN Airspeed Node %d on Bus %d\n",
|
|
_detected_modules[i].node_id,
|
|
_detected_modules[i].ap_dronecan->get_driver_index());
|
|
backend->set_bus_id(bus_id);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return backend;
|
|
}
|
|
|
|
AP_Airspeed_DroneCAN* AP_Airspeed_DroneCAN::get_dronecan_backend(AP_DroneCAN* ap_dronecan, uint8_t node_id)
|
|
{
|
|
if (ap_dronecan == nullptr) {
|
|
return nullptr;
|
|
}
|
|
|
|
for (uint8_t i = 0; i < AIRSPEED_MAX_SENSORS; i++) {
|
|
if (_detected_modules[i].driver != nullptr &&
|
|
_detected_modules[i].ap_dronecan == ap_dronecan &&
|
|
_detected_modules[i].node_id == node_id ) {
|
|
return _detected_modules[i].driver;
|
|
}
|
|
}
|
|
|
|
bool detected = false;
|
|
for (uint8_t i = 0; i < AIRSPEED_MAX_SENSORS; i++) {
|
|
if (_detected_modules[i].ap_dronecan == ap_dronecan && _detected_modules[i].node_id == node_id) {
|
|
// detected
|
|
detected = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!detected) {
|
|
for (uint8_t i = 0; i < AIRSPEED_MAX_SENSORS; i++) {
|
|
if (_detected_modules[i].ap_dronecan == nullptr) {
|
|
_detected_modules[i].ap_dronecan = ap_dronecan;
|
|
_detected_modules[i].node_id = node_id;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
void AP_Airspeed_DroneCAN::handle_airspeed(AP_DroneCAN *ap_dronecan, const CanardRxTransfer& transfer, const uavcan_equipment_air_data_RawAirData &msg)
|
|
{
|
|
WITH_SEMAPHORE(_sem_registry);
|
|
|
|
AP_Airspeed_DroneCAN* driver = get_dronecan_backend(ap_dronecan, transfer.source_node_id);
|
|
|
|
if (driver != nullptr) {
|
|
WITH_SEMAPHORE(driver->_sem_airspeed);
|
|
driver->_pressure = msg.differential_pressure;
|
|
if (!isnan(msg.static_air_temperature) &&
|
|
msg.static_air_temperature > 0) {
|
|
driver->_temperature = KELVIN_TO_C(msg.static_air_temperature);
|
|
driver->_have_temperature = true;
|
|
}
|
|
driver->_last_sample_time_ms = AP_HAL::millis();
|
|
}
|
|
}
|
|
|
|
#if AP_AIRSPEED_HYGROMETER_ENABLE
|
|
void AP_Airspeed_DroneCAN::handle_hygrometer(AP_DroneCAN *ap_dronecan, const CanardRxTransfer& transfer, const dronecan_sensors_hygrometer_Hygrometer &msg)
|
|
{
|
|
WITH_SEMAPHORE(_sem_registry);
|
|
|
|
AP_Airspeed_DroneCAN* driver = get_dronecan_backend(ap_dronecan, transfer.source_node_id);
|
|
|
|
if (driver != nullptr) {
|
|
WITH_SEMAPHORE(driver->_sem_airspeed);
|
|
driver->_hygrometer.temperature = KELVIN_TO_C(msg.temperature);
|
|
driver->_hygrometer.humidity = msg.humidity;
|
|
driver->_hygrometer.last_sample_ms = AP_HAL::millis();
|
|
}
|
|
}
|
|
#endif // AP_AIRSPEED_HYGROMETER_ENABLE
|
|
|
|
bool AP_Airspeed_DroneCAN::init()
|
|
{
|
|
// always returns true
|
|
return true;
|
|
}
|
|
|
|
bool AP_Airspeed_DroneCAN::get_differential_pressure(float &pressure)
|
|
{
|
|
WITH_SEMAPHORE(_sem_airspeed);
|
|
|
|
if ((AP_HAL::millis() - _last_sample_time_ms) > 250) {
|
|
return false;
|
|
}
|
|
|
|
pressure = _pressure;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool AP_Airspeed_DroneCAN::get_temperature(float &temperature)
|
|
{
|
|
if (!_have_temperature) {
|
|
return false;
|
|
}
|
|
WITH_SEMAPHORE(_sem_airspeed);
|
|
|
|
if ((AP_HAL::millis() - _last_sample_time_ms) > 100) {
|
|
return false;
|
|
}
|
|
|
|
temperature = _temperature;
|
|
|
|
return true;
|
|
}
|
|
|
|
#if AP_AIRSPEED_HYGROMETER_ENABLE
|
|
/*
|
|
return hygrometer data if available
|
|
*/
|
|
bool AP_Airspeed_DroneCAN::get_hygrometer(uint32_t &last_sample_ms, float &temperature, float &humidity)
|
|
{
|
|
if (_hygrometer.last_sample_ms == 0) {
|
|
return false;
|
|
}
|
|
WITH_SEMAPHORE(_sem_airspeed);
|
|
last_sample_ms = _hygrometer.last_sample_ms;
|
|
temperature = _hygrometer.temperature;
|
|
humidity = _hygrometer.humidity;
|
|
return true;
|
|
}
|
|
#endif // AP_AIRSPEED_HYGROMETER_ENABLE
|
|
#endif // AP_AIRSPEED_DRONECAN_ENABLED
|