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_Baro/AP_Baro_DroneCAN.cpp
Views: 1798
#include "AP_Baro_DroneCAN.h"12#if AP_BARO_DRONECAN_ENABLED34#include <AP_CANManager/AP_CANManager.h>5#include <AP_BoardConfig/AP_BoardConfig.h>6#include "AP_Baro_SITL.h"7#include <AP_Vehicle/AP_Vehicle_Type.h>89extern const AP_HAL::HAL& hal;1011#define LOG_TAG "Baro"1213AP_Baro_DroneCAN::DetectedModules AP_Baro_DroneCAN::_detected_modules[];14HAL_Semaphore AP_Baro_DroneCAN::_sem_registry;1516/*17constructor - registers instance at top Baro driver18*/19AP_Baro_DroneCAN::AP_Baro_DroneCAN(AP_Baro &baro) :20AP_Baro_Backend(baro)21{}2223bool AP_Baro_DroneCAN::subscribe_msgs(AP_DroneCAN* ap_dronecan)24{25const auto driver_index = ap_dronecan->get_driver_index();2627return (Canard::allocate_sub_arg_callback(ap_dronecan, &handle_pressure, driver_index) != nullptr)28&& (Canard::allocate_sub_arg_callback(ap_dronecan, &handle_temperature, driver_index) != nullptr)29;30}3132AP_Baro_Backend* AP_Baro_DroneCAN::probe(AP_Baro &baro)33{34WITH_SEMAPHORE(_sem_registry);3536AP_Baro_DroneCAN* backend = nullptr;37for (uint8_t i = 0; i < BARO_MAX_DRIVERS; i++) {38if (_detected_modules[i].driver == nullptr && _detected_modules[i].ap_dronecan != nullptr) {39backend = NEW_NOTHROW AP_Baro_DroneCAN(baro);40if (backend == nullptr) {41AP::can().log_text(AP_CANManager::LOG_ERROR,42LOG_TAG,43"Failed register DroneCAN Baro Node %d on Bus %d\n",44_detected_modules[i].node_id,45_detected_modules[i].ap_dronecan->get_driver_index());46} else {47_detected_modules[i].driver = backend;48backend->_pressure = 0;49backend->_pressure_count = 0;50backend->_ap_dronecan = _detected_modules[i].ap_dronecan;51backend->_node_id = _detected_modules[i].node_id;5253backend->_instance = backend->_frontend.register_sensor();54backend->set_bus_id(backend->_instance, AP_HAL::Device::make_bus_id(AP_HAL::Device::BUS_TYPE_UAVCAN,55_detected_modules[i].ap_dronecan->get_driver_index(),56backend->_node_id, 0));5758AP::can().log_text(AP_CANManager::LOG_INFO,59LOG_TAG,60"Registered DroneCAN Baro Node %d on Bus %d\n",61_detected_modules[i].node_id,62_detected_modules[i].ap_dronecan->get_driver_index());63}64break;65}66}67return backend;68}6970AP_Baro_DroneCAN* AP_Baro_DroneCAN::get_dronecan_backend(AP_DroneCAN* ap_dronecan, uint8_t node_id, bool create_new)71{72if (ap_dronecan == nullptr) {73return nullptr;74}75for (uint8_t i = 0; i < BARO_MAX_DRIVERS; i++) {76if (_detected_modules[i].driver != nullptr &&77_detected_modules[i].ap_dronecan == ap_dronecan &&78_detected_modules[i].node_id == node_id) {79return _detected_modules[i].driver;80}81}8283if (create_new) {84bool already_detected = false;85//Check if there's an empty spot for possible registration86for (uint8_t i = 0; i < BARO_MAX_DRIVERS; i++) {87if (_detected_modules[i].ap_dronecan == ap_dronecan && _detected_modules[i].node_id == node_id) {88//Already Detected89already_detected = true;90break;91}92}93if (!already_detected) {94for (uint8_t i = 0; i < BARO_MAX_DRIVERS; i++) {95if (_detected_modules[i].ap_dronecan == nullptr) {96_detected_modules[i].ap_dronecan = ap_dronecan;97_detected_modules[i].node_id = node_id;98break;99}100}101}102}103104return nullptr;105}106107108void AP_Baro_DroneCAN::_update_and_wrap_accumulator(float *accum, float val, uint8_t *count, const uint8_t max_count)109{110*accum += val;111*count += 1;112if (*count == max_count) {113*count = max_count / 2;114*accum = *accum / 2;115}116}117118void AP_Baro_DroneCAN::handle_pressure(AP_DroneCAN *ap_dronecan, const CanardRxTransfer& transfer, const uavcan_equipment_air_data_StaticPressure &msg)119{120AP_Baro_DroneCAN* driver;121{122WITH_SEMAPHORE(_sem_registry);123driver = get_dronecan_backend(ap_dronecan, transfer.source_node_id, true);124if (driver == nullptr) {125return;126}127}128{129WITH_SEMAPHORE(driver->_sem_baro);130_update_and_wrap_accumulator(&driver->_pressure, msg.static_pressure, &driver->_pressure_count, 32);131driver->new_pressure = true;132}133}134135void AP_Baro_DroneCAN::handle_temperature(AP_DroneCAN *ap_dronecan, const CanardRxTransfer& transfer, const uavcan_equipment_air_data_StaticTemperature &msg)136{137AP_Baro_DroneCAN* driver;138{139WITH_SEMAPHORE(_sem_registry);140driver = get_dronecan_backend(ap_dronecan, transfer.source_node_id, false);141if (driver == nullptr) {142return;143}144}145{146WITH_SEMAPHORE(driver->_sem_baro);147driver->_temperature = KELVIN_TO_C(msg.static_temperature);148}149}150151// Read the sensor152void AP_Baro_DroneCAN::update(void)153{154float pressure = 0;155156WITH_SEMAPHORE(_sem_baro);157if (new_pressure) {158if (_pressure_count != 0) {159pressure = _pressure / _pressure_count;160_pressure_count = 0;161_pressure = 0;162}163_copy_to_frontend(_instance, pressure, _temperature);164165166_frontend.set_external_temperature(_temperature);167new_pressure = false;168}169}170171#endif // AP_BARO_DRONECAN_ENABLED172173174