Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/libraries/AP_Airspeed/AP_Airspeed_DroneCAN.cpp
Views: 1798
#include "AP_Airspeed_DroneCAN.h"12#if AP_AIRSPEED_DRONECAN_ENABLED34#include <AP_CANManager/AP_CANManager.h>5#include <AP_DroneCAN/AP_DroneCAN.h>6#include <AP_BoardConfig/AP_BoardConfig.h>78extern const AP_HAL::HAL& hal;910#define LOG_TAG "AirSpeed"1112AP_Airspeed_DroneCAN::DetectedModules AP_Airspeed_DroneCAN::_detected_modules[];13HAL_Semaphore AP_Airspeed_DroneCAN::_sem_registry;1415bool AP_Airspeed_DroneCAN::subscribe_msgs(AP_DroneCAN* ap_dronecan)16{17const auto driver_index = ap_dronecan->get_driver_index();1819return (Canard::allocate_sub_arg_callback(ap_dronecan, &handle_airspeed, driver_index) != nullptr)20#if AP_AIRSPEED_HYGROMETER_ENABLE21&& (Canard::allocate_sub_arg_callback(ap_dronecan, &handle_hygrometer, driver_index) != nullptr)22#endif23;24}2526AP_Airspeed_Backend* AP_Airspeed_DroneCAN::probe(AP_Airspeed &_frontend, uint8_t _instance, uint32_t previous_devid)27{28WITH_SEMAPHORE(_sem_registry);2930AP_Airspeed_DroneCAN* backend = nullptr;3132for (uint8_t i = 0; i < AIRSPEED_MAX_SENSORS; i++) {33if (_detected_modules[i].driver == nullptr && _detected_modules[i].ap_dronecan != nullptr) {34const auto bus_id = AP_HAL::Device::make_bus_id(AP_HAL::Device::BUS_TYPE_UAVCAN,35_detected_modules[i].ap_dronecan->get_driver_index(),36_detected_modules[i].node_id, 0);37if (previous_devid != 0 && previous_devid != bus_id) {38// match with previous ID only39continue;40}41backend = NEW_NOTHROW AP_Airspeed_DroneCAN(_frontend, _instance);42if (backend == nullptr) {43AP::can().log_text(AP_CANManager::LOG_INFO,44LOG_TAG,45"Failed register DroneCAN Airspeed Node %d on Bus %d\n",46_detected_modules[i].node_id,47_detected_modules[i].ap_dronecan->get_driver_index());48} else {49_detected_modules[i].driver = backend;50AP::can().log_text(AP_CANManager::LOG_INFO,51LOG_TAG,52"Registered DroneCAN Airspeed Node %d on Bus %d\n",53_detected_modules[i].node_id,54_detected_modules[i].ap_dronecan->get_driver_index());55backend->set_bus_id(bus_id);56}57break;58}59}6061return backend;62}6364AP_Airspeed_DroneCAN* AP_Airspeed_DroneCAN::get_dronecan_backend(AP_DroneCAN* ap_dronecan, uint8_t node_id)65{66if (ap_dronecan == nullptr) {67return nullptr;68}6970for (uint8_t i = 0; i < AIRSPEED_MAX_SENSORS; i++) {71if (_detected_modules[i].driver != nullptr &&72_detected_modules[i].ap_dronecan == ap_dronecan &&73_detected_modules[i].node_id == node_id ) {74return _detected_modules[i].driver;75}76}7778bool detected = false;79for (uint8_t i = 0; i < AIRSPEED_MAX_SENSORS; i++) {80if (_detected_modules[i].ap_dronecan == ap_dronecan && _detected_modules[i].node_id == node_id) {81// detected82detected = true;83break;84}85}8687if (!detected) {88for (uint8_t i = 0; i < AIRSPEED_MAX_SENSORS; i++) {89if (_detected_modules[i].ap_dronecan == nullptr) {90_detected_modules[i].ap_dronecan = ap_dronecan;91_detected_modules[i].node_id = node_id;92break;93}94}95}9697return nullptr;98}99100void AP_Airspeed_DroneCAN::handle_airspeed(AP_DroneCAN *ap_dronecan, const CanardRxTransfer& transfer, const uavcan_equipment_air_data_RawAirData &msg)101{102WITH_SEMAPHORE(_sem_registry);103104AP_Airspeed_DroneCAN* driver = get_dronecan_backend(ap_dronecan, transfer.source_node_id);105106if (driver != nullptr) {107WITH_SEMAPHORE(driver->_sem_airspeed);108driver->_pressure = msg.differential_pressure;109if (!isnan(msg.static_air_temperature) &&110msg.static_air_temperature > 0) {111driver->_temperature = KELVIN_TO_C(msg.static_air_temperature);112driver->_have_temperature = true;113}114driver->_last_sample_time_ms = AP_HAL::millis();115}116}117118#if AP_AIRSPEED_HYGROMETER_ENABLE119void AP_Airspeed_DroneCAN::handle_hygrometer(AP_DroneCAN *ap_dronecan, const CanardRxTransfer& transfer, const dronecan_sensors_hygrometer_Hygrometer &msg)120{121WITH_SEMAPHORE(_sem_registry);122123AP_Airspeed_DroneCAN* driver = get_dronecan_backend(ap_dronecan, transfer.source_node_id);124125if (driver != nullptr) {126WITH_SEMAPHORE(driver->_sem_airspeed);127driver->_hygrometer.temperature = KELVIN_TO_C(msg.temperature);128driver->_hygrometer.humidity = msg.humidity;129driver->_hygrometer.last_sample_ms = AP_HAL::millis();130}131}132#endif // AP_AIRSPEED_HYGROMETER_ENABLE133134bool AP_Airspeed_DroneCAN::init()135{136// always returns true137return true;138}139140bool AP_Airspeed_DroneCAN::get_differential_pressure(float &pressure)141{142WITH_SEMAPHORE(_sem_airspeed);143144if ((AP_HAL::millis() - _last_sample_time_ms) > 250) {145return false;146}147148pressure = _pressure;149150return true;151}152153bool AP_Airspeed_DroneCAN::get_temperature(float &temperature)154{155if (!_have_temperature) {156return false;157}158WITH_SEMAPHORE(_sem_airspeed);159160if ((AP_HAL::millis() - _last_sample_time_ms) > 100) {161return false;162}163164temperature = _temperature;165166return true;167}168169#if AP_AIRSPEED_HYGROMETER_ENABLE170/*171return hygrometer data if available172*/173bool AP_Airspeed_DroneCAN::get_hygrometer(uint32_t &last_sample_ms, float &temperature, float &humidity)174{175if (_hygrometer.last_sample_ms == 0) {176return false;177}178WITH_SEMAPHORE(_sem_airspeed);179last_sample_ms = _hygrometer.last_sample_ms;180temperature = _hygrometer.temperature;181humidity = _hygrometer.humidity;182return true;183}184#endif // AP_AIRSPEED_HYGROMETER_ENABLE185#endif // AP_AIRSPEED_DRONECAN_ENABLED186187188