From f31cf7debe8b2071803801fe264935fd169d6c27 Mon Sep 17 00:00:00 2001 From: Siddharth Purohit Date: Tue, 21 Jul 2020 02:55:08 +0530 Subject: [PATCH] AP_Compass: reset compass ids not present after compass cal also implement replacement mechanism for UAVCAN compasses --- libraries/AP_Compass/AP_Compass.cpp | 158 +++++++++++++++++- libraries/AP_Compass/AP_Compass.h | 11 ++ libraries/AP_Compass/AP_Compass_Backend.cpp | 1 - .../AP_Compass/AP_Compass_Calibration.cpp | 2 + libraries/AP_Compass/AP_Compass_UAVCAN.cpp | 17 +- libraries/AP_Compass/AP_Compass_UAVCAN.h | 6 +- 6 files changed, 180 insertions(+), 15 deletions(-) diff --git a/libraries/AP_Compass/AP_Compass.cpp b/libraries/AP_Compass/AP_Compass.cpp index c213c8b8c5..08060e984b 100644 --- a/libraries/AP_Compass/AP_Compass.cpp +++ b/libraries/AP_Compass/AP_Compass.cpp @@ -696,9 +696,12 @@ void Compass::init() if (_priority_did_stored_list[i] != 0) { _priority_did_list[i] = _priority_did_stored_list[i]; } else { - // Maintain a list without gaps + // Maintain a list without gaps and duplicates for (Priority j(i+1); jdelay(100); @@ -813,6 +829,7 @@ void Compass::mag_state::copy_from(const Compass::mag_state& state) dev_id.set_and_save(state.dev_id); motor_compensation.set_and_save(state.motor_compensation); expected_dev_id = state.expected_dev_id; + detected_dev_id = state.detected_dev_id; } // Register a new compass instance // @@ -900,7 +917,7 @@ Compass::StateIndex Compass::_get_state_id(Compass::Priority priority) const return StateIndex(COMPASS_MAX_INSTANCES); } for (StateIndex i(0); i 0 + if (_unreg_compass_count == COMPASS_MAX_UNREG_DEV) { + break; + } +#endif } + +#if COMPASS_MAX_UNREG_DEV > 0 + // check if there's any uavcan compass in prio slot that's not found + // and replace it if there's a replacement compass + for (Priority i(0); i 1 + // We only do this for UAVCAN mag + if (devid == 0 || (AP_HAL::Device::devid_get_bus_type(devid) != AP_HAL::Device::BUS_TYPE_UAVCAN)) { + return false; + } + + // Check that its not an unused additional mag + for (uint8_t i = 0; i 1 + // We only do this for UAVCAN mag + if (devid == 0 || (AP_HAL::Device::devid_get_bus_type(devid) != AP_HAL::Device::BUS_TYPE_UAVCAN)) { + return; + } + + for (uint8_t i = 0; i 1 + // Check if any of the registered devs are not registered + for (Priority i(0); i _use_for_yaw; #if COMPASS_MAX_INSTANCES > 1 @@ -560,6 +570,7 @@ private: #if COMPASS_MAX_UNREG_DEV // Put extra dev ids detected AP_Int32 extra_dev_id[COMPASS_MAX_UNREG_DEV]; + uint32_t _previously_unreg_mag[COMPASS_MAX_UNREG_DEV]; #endif AP_Int8 _filter_range; diff --git a/libraries/AP_Compass/AP_Compass_Backend.cpp b/libraries/AP_Compass/AP_Compass_Backend.cpp index 48b55bb2ee..cba5958283 100644 --- a/libraries/AP_Compass/AP_Compass_Backend.cpp +++ b/libraries/AP_Compass/AP_Compass_Backend.cpp @@ -202,7 +202,6 @@ void AP_Compass_Backend::set_dev_id(uint8_t instance, uint32_t dev_id) { _compass._state[Compass::StateIndex(instance)].dev_id.set_and_notify(dev_id); _compass._state[Compass::StateIndex(instance)].detected_dev_id = dev_id; - _compass._state[Compass::StateIndex(instance)].expected_dev_id = dev_id; } /* diff --git a/libraries/AP_Compass/AP_Compass_Calibration.cpp b/libraries/AP_Compass/AP_Compass_Calibration.cpp index 442892c4b2..86b69e127b 100644 --- a/libraries/AP_Compass/AP_Compass_Calibration.cpp +++ b/libraries/AP_Compass/AP_Compass_Calibration.cpp @@ -329,6 +329,7 @@ MAV_RESULT Compass::handle_mag_cal_command(const mavlink_command_long_t &packet) bool autoreboot = !is_zero(packet.param5); if (mag_mask == 0) { // 0 means all + _reset_compass_id(); start_calibration_all(retry, autosave, delay, autoreboot); } else { if (!_start_calibration_mask(mag_mask, retry, autosave, delay, autoreboot)) { @@ -429,6 +430,7 @@ bool Compass::get_uncorrected_field(uint8_t instance, Vector3f &field) MAV_RESULT Compass::mag_cal_fixed_yaw(float yaw_deg, uint8_t compass_mask, float lat_deg, float lon_deg) { + _reset_compass_id(); if (is_zero(lat_deg) && is_zero(lon_deg)) { Location loc; // get AHRS position. If unavailable then try GPS location diff --git a/libraries/AP_Compass/AP_Compass_UAVCAN.cpp b/libraries/AP_Compass/AP_Compass_UAVCAN.cpp index 3e66c31edf..e06c41551b 100644 --- a/libraries/AP_Compass/AP_Compass_UAVCAN.cpp +++ b/libraries/AP_Compass/AP_Compass_UAVCAN.cpp @@ -37,10 +37,11 @@ UC_REGISTRY_BINDER(Mag2Cb, uavcan::equipment::ahrs::MagneticFieldStrength2); AP_Compass_UAVCAN::DetectedModules AP_Compass_UAVCAN::_detected_modules[] = {0}; HAL_Semaphore AP_Compass_UAVCAN::_sem_registry; -AP_Compass_UAVCAN::AP_Compass_UAVCAN(AP_UAVCAN* ap_uavcan, uint8_t node_id, uint8_t sensor_id) +AP_Compass_UAVCAN::AP_Compass_UAVCAN(AP_UAVCAN* ap_uavcan, uint8_t node_id, uint8_t sensor_id, uint32_t devid) : _ap_uavcan(ap_uavcan) , _node_id(node_id) , _sensor_id(sensor_id) + , _devid(devid) { } @@ -75,7 +76,7 @@ AP_Compass_Backend* AP_Compass_UAVCAN::probe(uint8_t index) if (!_detected_modules[index].driver && _detected_modules[index].ap_uavcan) { WITH_SEMAPHORE(_sem_registry); // Register new Compass mode to a backend - driver = new AP_Compass_UAVCAN(_detected_modules[index].ap_uavcan, _detected_modules[index].node_id, _detected_modules[index].sensor_id); + driver = new AP_Compass_UAVCAN(_detected_modules[index].ap_uavcan, _detected_modules[index].node_id, _detected_modules[index].sensor_id, _detected_modules[index].devid); if (driver) { if (!driver->init()) { delete driver; @@ -95,16 +96,12 @@ AP_Compass_Backend* AP_Compass_UAVCAN::probe(uint8_t index) bool AP_Compass_UAVCAN::init() { - uint32_t devid = AP_HAL::Device::make_bus_id(AP_HAL::Device::BUS_TYPE_UAVCAN, - _ap_uavcan->get_driver_index(), - _node_id, - _sensor_id + 1); // we use sensor_id as devtype // Adding 1 is necessary to allow backward compatibilty, where this field was set as 1 by default - if (!register_compass(devid, _instance)) { + if (!register_compass(_devid, _instance)) { return false; } - set_dev_id(_instance, devid); + set_dev_id(_instance, _devid); set_external(_instance, true); debug_mag_uavcan(2, _ap_uavcan->get_driver_index(), "AP_Compass_UAVCAN loaded\n\r"); @@ -142,6 +139,10 @@ AP_Compass_UAVCAN* AP_Compass_UAVCAN::get_uavcan_backend(AP_UAVCAN* ap_uavcan, u _detected_modules[i].ap_uavcan = ap_uavcan; _detected_modules[i].node_id = node_id; _detected_modules[i].sensor_id = sensor_id; + _detected_modules[i].devid = AP_HAL::Device::make_bus_id(AP_HAL::Device::BUS_TYPE_UAVCAN, + ap_uavcan->get_driver_index(), + node_id, + sensor_id + 1); // we use sensor_id as devtype break; } } diff --git a/libraries/AP_Compass/AP_Compass_UAVCAN.h b/libraries/AP_Compass/AP_Compass_UAVCAN.h index f487b4287c..d469b03597 100644 --- a/libraries/AP_Compass/AP_Compass_UAVCAN.h +++ b/libraries/AP_Compass/AP_Compass_UAVCAN.h @@ -10,13 +10,13 @@ class Mag2Cb; class AP_Compass_UAVCAN : public AP_Compass_Backend { public: - AP_Compass_UAVCAN(AP_UAVCAN* ap_uavcan, uint8_t node_id, uint8_t sensor_id); + AP_Compass_UAVCAN(AP_UAVCAN* ap_uavcan, uint8_t node_id, uint8_t sensor_id, uint32_t devid); void read(void) override; static void subscribe_msgs(AP_UAVCAN* ap_uavcan); static AP_Compass_Backend* probe(uint8_t index); - + static uint32_t get_detected_devid(uint8_t index) { return _detected_modules[index].devid; } static void handle_magnetic_field(AP_UAVCAN* ap_uavcan, uint8_t node_id, const MagCb &cb); static void handle_magnetic_field_2(AP_UAVCAN* ap_uavcan, uint8_t node_id, const Mag2Cb &cb); @@ -33,6 +33,7 @@ private: AP_UAVCAN* _ap_uavcan; uint8_t _node_id; uint8_t _sensor_id; + uint32_t _devid; // Module Detection Registry static struct DetectedModules { @@ -40,6 +41,7 @@ private: uint8_t node_id; uint8_t sensor_id; AP_Compass_UAVCAN *driver; + uint32_t devid; } _detected_modules[COMPASS_MAX_BACKEND]; static HAL_Semaphore _sem_registry;