2024-02-23 04:29:09 -04:00
# include "AP_Compass_config.h"
# if AP_COMPASS_ENABLED
2015-08-11 03:28:42 -03:00
# include <AP_HAL/AP_HAL.h>
2016-03-23 20:10:21 -03:00
# if CONFIG_HAL_BOARD == HAL_BOARD_LINUX
# include <AP_HAL_Linux/I2CDevice.h>
# endif
2022-09-29 20:10:40 -03:00
# include <AP_Vehicle/AP_Vehicle_Type.h>
2016-10-31 22:20:31 -03:00
# include <AP_BoardConfig/AP_BoardConfig.h>
2019-03-24 00:24:56 -03:00
# include <AP_Logger/AP_Logger.h>
2020-04-14 07:38:50 -03:00
# include <AP_Vehicle/AP_Vehicle_Type.h>
2020-12-28 01:26:18 -04:00
# include <AP_ExternalAHRS/AP_ExternalAHRS.h>
2021-11-05 13:13:55 -03:00
# include <AP_CustomRotations/AP_CustomRotations.h>
2022-09-29 20:10:40 -03:00
# include <GCS_MAVLink/GCS.h>
2024-08-30 23:01:02 -03:00
# include <AP_AHRS/AP_AHRS.h>
2015-02-23 19:17:44 -04:00
2022-10-26 06:21:36 -03:00
# include "AP_Compass_config.h"
2017-06-21 14:39:07 -03:00
# include "AP_Compass_SITL.h"
2016-03-10 20:41:18 -04:00
# include "AP_Compass_AK8963.h"
# include "AP_Compass_Backend.h"
2016-07-05 11:54:25 -03:00
# include "AP_Compass_BMM150.h"
2024-09-11 06:10:44 -03:00
# include "AP_Compass_BMM350.h"
2016-03-10 20:41:18 -04:00
# include "AP_Compass_HMC5843.h"
2018-08-14 15:01:05 -03:00
# include "AP_Compass_IST8308.h"
2017-02-10 19:33:23 -04:00
# include "AP_Compass_IST8310.h"
2016-03-10 20:41:18 -04:00
# include "AP_Compass_LSM303D.h"
2016-04-22 12:12:23 -03:00
# include "AP_Compass_LSM9DS1.h"
2016-11-24 02:54:44 -04:00
# include "AP_Compass_LIS3MDL.h"
2016-11-24 03:46:47 -04:00
# include "AP_Compass_AK09916.h"
2017-06-16 02:50:09 -03:00
# include "AP_Compass_QMC5883L.h"
2023-04-08 00:58:13 -03:00
# if AP_COMPASS_DRONECAN_ENABLED
2023-04-08 00:55:40 -03:00
# include "AP_Compass_DroneCAN.h"
2017-04-02 11:56:15 -03:00
# endif
2023-11-11 00:00:55 -04:00
# include "AP_Compass_QMC5883P.h"
2016-12-19 02:53:48 -04:00
# include "AP_Compass_MMC3416.h"
2021-03-23 18:06:38 -03:00
# include "AP_Compass_MMC5xx3.h"
2018-02-02 05:25:24 -04:00
# include "AP_Compass_MAG3110.h"
2019-02-01 11:13:28 -04:00
# include "AP_Compass_RM3100.h"
2022-10-26 06:21:36 -03:00
# if AP_COMPASS_MSP_ENABLED
2020-09-03 19:11:05 -03:00
# include "AP_Compass_MSP.h"
# endif
2022-10-26 06:21:36 -03:00
# if AP_COMPASS_EXTERNALAHRS_ENABLED
2020-12-28 01:26:18 -04:00
# include "AP_Compass_ExternalAHRS.h"
# endif
2016-03-10 20:41:18 -04:00
# include "AP_Compass.h"
2018-10-19 02:07:53 -03:00
# include "Compass_learn.h"
2019-11-20 03:18:10 -04:00
# include <stdio.h>
2018-12-27 07:57:39 -04:00
extern const AP_HAL : : HAL & hal ;
2015-02-23 19:17:44 -04:00
2022-01-27 23:51:02 -04:00
# ifndef AP_COMPASS_ENABLE_DEFAULT
# define AP_COMPASS_ENABLE_DEFAULT 1
# endif
2019-10-23 00:23:41 -03:00
# ifndef COMPASS_LEARN_DEFAULT
2016-04-28 05:51:06 -03:00
# define COMPASS_LEARN_DEFAULT Compass::LEARN_NONE
2015-02-23 19:17:44 -04:00
# endif
2011-02-14 00:25:20 -04:00
2017-04-03 19:38:14 -03:00
# ifndef AP_COMPASS_OFFSETS_MAX_DEFAULT
2019-02-03 06:04:47 -04:00
# define AP_COMPASS_OFFSETS_MAX_DEFAULT 1800
2017-04-03 19:38:14 -03:00
# endif
2018-03-12 04:59:32 -03:00
# ifndef HAL_COMPASS_FILTER_DEFAULT
2020-02-15 02:30:10 -04:00
# define HAL_COMPASS_FILTER_DEFAULT 0 // turned off by default
2018-03-12 04:59:32 -03:00
# endif
2018-07-28 02:37:46 -03:00
# ifndef HAL_COMPASS_AUTO_ROT_DEFAULT
# define HAL_COMPASS_AUTO_ROT_DEFAULT 2
# endif
2015-10-25 14:03:46 -03:00
const AP_Param : : GroupInfo Compass : : var_info [ ] = {
2012-03-09 22:45:35 -04:00
// index 0 was used for the old orientation matrix
2013-01-02 03:07:33 -04:00
2023-11-06 22:51:20 -04:00
# ifndef HAL_BUILD_AP_PERIPH
2021-12-04 00:22:56 -04:00
// @Param: OFS_X
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass offsets in milligauss on the X axis
// @Description: Offset to be added to the compass x-axis values to compensate for metal in the frame
// @Range: -400 400
// @Units: mGauss
// @Increment: 1
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: OFS_Y
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass offsets in milligauss on the Y axis
// @Description: Offset to be added to the compass y-axis values to compensate for metal in the frame
// @Range: -400 400
// @Units: mGauss
// @Increment: 1
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: OFS_Z
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass offsets in milligauss on the Z axis
// @Description: Offset to be added to the compass z-axis values to compensate for metal in the frame
// @Range: -400 400
// @Units: mGauss
// @Increment: 1
// @User: Advanced
2024-10-25 10:59:44 -03:00
// @Calibration: 1
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " OFS " , 1 , Compass , _state . _priv_instance [ 0 ] . offset , 0 ) ,
2021-11-02 22:27:50 -03:00
2021-12-04 00:22:56 -04:00
// @Param: DEC
2013-01-02 03:07:33 -04:00
// @DisplayName: Compass declination
// @Description: An angle to compensate between the true north and magnetic north
// @Range: -3.142 3.142
2017-05-02 10:42:55 -03:00
// @Units: rad
2013-01-02 03:07:33 -04:00
// @Increment: 0.01
// @User: Standard
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " DEC " , 2 , Compass , _declination , 0 ) ,
2023-11-06 22:51:20 -04:00
# endif // HAL_BUILD_AP_PERIPH
2013-01-02 03:07:33 -04:00
2020-04-29 00:27:58 -03:00
# if COMPASS_LEARN_ENABLED
2021-12-04 00:22:56 -04:00
// @Param: LEARN
2013-01-02 03:07:33 -04:00
// @DisplayName: Learn compass offsets automatically
2019-01-26 23:31:28 -04:00
// @Description: Enable or disable the automatic learning of compass offsets. You can enable learning either using a compass-only method that is suitable only for fixed wing aircraft or using the offsets learnt by the active EKF state estimator. If this option is enabled then the learnt offsets are saved when you disarm the vehicle. If InFlight learning is enabled then the compass with automatically start learning once a flight starts (must be armed). While InFlight learning is running you cannot use position control modes.
// @Values: 0:Disabled,1:Internal-Learning,2:EKF-Learning,3:InFlight-Learning
2013-01-02 03:07:33 -04:00
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " LEARN " , 3 , Compass , _learn , COMPASS_LEARN_DEFAULT ) ,
2020-04-29 00:27:58 -03:00
# endif
2013-01-02 03:07:33 -04:00
2023-11-06 22:51:20 -04:00
# ifndef HAL_BUILD_AP_PERIPH
2021-12-04 00:22:56 -04:00
// @Param: USE
2021-11-02 22:27:50 -03:00
// @DisplayName: Use compass for yaw
// @Description: Enable or disable the use of the compass (instead of the GPS) for determining heading
// @Values: 0:Disabled,1:Enabled
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " USE " , 4 , Compass , _use_for_yaw . _priv_instance [ 0 ] , 1 ) , // true if used for DCM yaw
2021-12-01 11:46:30 -04:00
2021-12-04 00:22:56 -04:00
// @Param: AUTODEC
2013-01-02 03:07:33 -04:00
// @DisplayName: Auto Declination
// @Description: Enable or disable the automatic calculation of the declination based on gps location
// @Values: 0:Disabled,1:Enabled
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " AUTODEC " , 5 , Compass , _auto_declination , 1 ) ,
2023-11-06 22:51:20 -04:00
# endif
2013-02-27 03:57:04 -04:00
2020-04-29 00:27:58 -03:00
# if COMPASS_MOT_ENABLED
2021-12-04 00:22:56 -04:00
// @Param: MOTCT
2013-03-03 10:02:12 -04:00
// @DisplayName: Motor interference compensation type
2013-05-11 02:50:36 -03:00
// @Description: Set motor interference compensation type to disabled, throttle or current. Do not change manually.
2013-03-03 10:02:12 -04:00
// @Values: 0:Disabled,1:Use Throttle,2:Use Current
2015-10-15 08:32:47 -03:00
// @User: Advanced
2020-02-01 20:57:19 -04:00
// @Calibration: 1
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " MOTCT " , 6 , Compass , _motor_comp_type , AP_COMPASS_MOT_COMP_DISABLED ) ,
2013-02-27 03:57:04 -04:00
2021-12-04 00:22:56 -04:00
// @Param: MOT_X
2021-11-02 22:27:50 -03:00
// @DisplayName: Motor interference compensation for body frame X axis
// @Description: Multiplied by the current throttle and added to the compass's x-axis values to compensate for motor interference (Offset per Amp or at Full Throttle)
// @Range: -1000 1000
// @Units: mGauss/A
// @Increment: 1
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: MOT_Y
2021-11-02 22:27:50 -03:00
// @DisplayName: Motor interference compensation for body frame Y axis
// @Description: Multiplied by the current throttle and added to the compass's y-axis values to compensate for motor interference (Offset per Amp or at Full Throttle)
// @Range: -1000 1000
// @Units: mGauss/A
// @Increment: 1
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: MOT_Z
2021-11-02 22:27:50 -03:00
// @DisplayName: Motor interference compensation for body frame Z axis
// @Description: Multiplied by the current throttle and added to the compass's z-axis values to compensate for motor interference (Offset per Amp or at Full Throttle)
// @Range: -1000 1000
// @Units: mGauss/A
// @Increment: 1
// @User: Advanced
2024-10-25 10:59:44 -03:00
// @Calibration: 1
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " MOT " , 7 , Compass , _state . _priv_instance [ 0 ] . motor_compensation , 0 ) ,
# endif
2021-12-01 11:46:30 -04:00
2023-11-06 22:51:20 -04:00
# ifndef HAL_BUILD_AP_PERIPH
2021-12-04 00:22:56 -04:00
// @Param: ORIENT
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass orientation
2022-07-20 17:47:27 -03:00
// @Description: The orientation of the first external compass relative to the vehicle frame. This value will be ignored unless this compass is set as an external compass. When set correctly in the northern hemisphere, pointing the nose and right side down should increase the MagX and MagY values respectively. Rolling the vehicle upside down should decrease the MagZ value. For southern hemisphere, switch increase and decrease. NOTE: For internal compasses, AHRS_ORIENT is used. The label for each option is specified in the order of rotations for that orientation. Firmware versions 4.2 and prior can use a CUSTOM (100) rotation to set the COMPASS_CUS_ROLL/PIT/YAW angles for Compass orientation. Later versions provide two general custom rotations which can be used, Custom 1 and Custom 2, with CUST_1_ROLL/PIT/YAW or CUST_2_ROLL/PIT/YAW angles.
2021-11-05 13:11:09 -03:00
// @Values: 0:None,1:Yaw45,2:Yaw90,3:Yaw135,4:Yaw180,5:Yaw225,6:Yaw270,7:Yaw315,8:Roll180,9:Yaw45Roll180,10:Yaw90Roll180,11:Yaw135Roll180,12:Pitch180,13:Yaw225Roll180,14:Yaw270Roll180,15:Yaw315Roll180,16:Roll90,17:Yaw45Roll90,18:Yaw90Roll90,19:Yaw135Roll90,20:Roll270,21:Yaw45Roll270,22:Yaw90Roll270,23:Yaw135Roll270,24:Pitch90,25:Pitch270,26:Yaw90Pitch180,27:Yaw270Pitch180,28:Pitch90Roll90,29:Pitch90Roll180,30:Pitch90Roll270,31:Pitch180Roll90,32:Pitch180Roll270,33:Pitch270Roll90,34:Pitch270Roll180,35:Pitch270Roll270,36:Yaw90Pitch180Roll90,37:Yaw270Roll90,38:Yaw293Pitch68Roll180,39:Pitch315,40:Pitch315Roll90,42:Roll45,43:Roll315,100:Custom 4.1 and older,101:Custom 1,102:Custom 2
2021-11-02 22:27:50 -03:00
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " ORIENT " , 8 , Compass , _state . _priv_instance [ 0 ] . orientation , ROTATION_NONE ) ,
2021-12-01 11:46:30 -04:00
2021-12-04 00:22:56 -04:00
// @Param: EXTERNAL
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass is attached via an external cable
// @Description: Configure compass so it is attached externally. This is auto-detected on most boards. Set to 1 if the compass is externally connected. When externally connected the COMPASS_ORIENT option operates independently of the AHRS_ORIENTATION board orientation option. If set to 0 or 1 then auto-detection by bus connection can override the value. If set to 2 then auto-detection will be disabled.
// @Values: 0:Internal,1:External,2:ForcedExternal
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " EXTERNAL " , 9 , Compass , _state . _priv_instance [ 0 ] . external , 0 ) ,
2023-11-06 22:51:20 -04:00
# endif
2021-12-01 11:46:30 -04:00
2021-12-04 00:22:56 -04:00
# if COMPASS_MAX_INSTANCES > 1
// @Param: OFS2_X
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass2 offsets in milligauss on the X axis
// @Description: Offset to be added to compass2's x-axis values to compensate for metal in the frame
// @Range: -400 400
// @Units: mGauss
// @Increment: 1
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: OFS2_Y
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass2 offsets in milligauss on the Y axis
// @Description: Offset to be added to compass2's y-axis values to compensate for metal in the frame
// @Range: -400 400
// @Units: mGauss
// @Increment: 1
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: OFS2_Z
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass2 offsets in milligauss on the Z axis
// @Description: Offset to be added to compass2's z-axis values to compensate for metal in the frame
// @Range: -400 400
// @Units: mGauss
// @Increment: 1
// @User: Advanced
2024-10-25 10:59:44 -03:00
// @Calibration: 1
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " OFS2 " , 10 , Compass , _state . _priv_instance [ 1 ] . offset , 0 ) ,
2021-12-01 11:46:30 -04:00
2021-12-04 00:22:56 -04:00
// @Param: MOT2_X
2021-11-02 22:27:50 -03:00
// @DisplayName: Motor interference compensation to compass2 for body frame X axis
// @Description: Multiplied by the current throttle and added to compass2's x-axis values to compensate for motor interference (Offset per Amp or at Full Throttle)
// @Range: -1000 1000
// @Units: mGauss/A
// @Increment: 1
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: MOT2_Y
2021-11-02 22:27:50 -03:00
// @DisplayName: Motor interference compensation to compass2 for body frame Y axis
// @Description: Multiplied by the current throttle and added to compass2's y-axis values to compensate for motor interference (Offset per Amp or at Full Throttle)
// @Range: -1000 1000
// @Units: mGauss/A
// @Increment: 1
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: MOT2_Z
2021-11-02 22:27:50 -03:00
// @DisplayName: Motor interference compensation to compass2 for body frame Z axis
// @Description: Multiplied by the current throttle and added to compass2's z-axis values to compensate for motor interference (Offset per Amp or at Full Throttle)
// @Range: -1000 1000
// @Units: mGauss/A
// @Increment: 1
// @User: Advanced
2024-10-25 10:59:44 -03:00
// @Calibration: 1
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " MOT2 " , 11 , Compass , _state . _priv_instance [ 1 ] . motor_compensation , 0 ) ,
2021-12-01 11:46:30 -04:00
2021-12-04 00:22:56 -04:00
# endif // COMPASS_MAX_INSTANCES
2021-11-02 22:27:50 -03:00
2021-12-04 00:22:56 -04:00
# if COMPASS_MAX_INSTANCES > 2
// @Param: OFS3_X
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass3 offsets in milligauss on the X axis
// @Description: Offset to be added to compass3's x-axis values to compensate for metal in the frame
// @Range: -400 400
// @Units: mGauss
// @Increment: 1
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: OFS3_Y
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass3 offsets in milligauss on the Y axis
// @Description: Offset to be added to compass3's y-axis values to compensate for metal in the frame
// @Range: -400 400
// @Units: mGauss
// @Increment: 1
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: OFS3_Z
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass3 offsets in milligauss on the Z axis
// @Description: Offset to be added to compass3's z-axis values to compensate for metal in the frame
// @Range: -400 400
// @Units: mGauss
// @Increment: 1
// @User: Advanced
2024-10-25 10:59:44 -03:00
// @Calibration: 1
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " OFS3 " , 13 , Compass , _state . _priv_instance [ 2 ] . offset , 0 ) ,
2021-12-01 11:46:30 -04:00
2021-12-04 00:22:56 -04:00
// @Param: MOT3_X
2021-11-02 22:27:50 -03:00
// @DisplayName: Motor interference compensation to compass3 for body frame X axis
// @Description: Multiplied by the current throttle and added to compass3's x-axis values to compensate for motor interference (Offset per Amp or at Full Throttle)
// @Range: -1000 1000
// @Units: mGauss/A
// @Increment: 1
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: MOT3_Y
2021-11-02 22:27:50 -03:00
// @DisplayName: Motor interference compensation to compass3 for body frame Y axis
// @Description: Multiplied by the current throttle and added to compass3's y-axis values to compensate for motor interference (Offset per Amp or at Full Throttle)
// @Range: -1000 1000
// @Units: mGauss/A
// @Increment: 1
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: MOT3_Z
2021-11-02 22:27:50 -03:00
// @DisplayName: Motor interference compensation to compass3 for body frame Z axis
// @Description: Multiplied by the current throttle and added to compass3's z-axis values to compensate for motor interference (Offset per Amp or at Full Throttle)
// @Range: -1000 1000
// @Units: mGauss/A
// @Increment: 1
// @User: Advanced
2024-10-25 10:59:44 -03:00
// @Calibration: 1
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " MOT3 " , 14 , Compass , _state . _priv_instance [ 2 ] . motor_compensation , 0 ) ,
# endif // COMPASS_MAX_INSTANCES
2021-12-01 11:46:30 -04:00
2021-12-04 00:22:56 -04:00
// @Param: DEV_ID
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass device id
// @Description: Compass device id. Automatically detected, do not set manually
// @ReadOnly: True
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " DEV_ID " , 15 , Compass , _state . _priv_instance [ 0 ] . dev_id , 0 ) ,
2021-12-01 11:46:30 -04:00
2021-12-04 00:22:56 -04:00
# if COMPASS_MAX_INSTANCES > 1
// @Param: DEV_ID2
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass2 device id
// @Description: Second compass's device id. Automatically detected, do not set manually
// @ReadOnly: True
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " DEV_ID2 " , 16 , Compass , _state . _priv_instance [ 1 ] . dev_id , 0 ) ,
# endif // COMPASS_MAX_INSTANCES
2021-12-01 11:46:30 -04:00
2021-12-04 00:22:56 -04:00
# if COMPASS_MAX_INSTANCES > 2
// @Param: DEV_ID3
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass3 device id
// @Description: Third compass's device id. Automatically detected, do not set manually
// @ReadOnly: True
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " DEV_ID3 " , 17 , Compass , _state . _priv_instance [ 2 ] . dev_id , 0 ) ,
# endif // COMPASS_MAX_INSTANCES
2021-12-01 11:46:30 -04:00
2021-12-04 00:22:56 -04:00
# if COMPASS_MAX_INSTANCES > 1
// @Param: USE2
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass2 used for yaw
// @Description: Enable or disable the secondary compass for determining heading.
// @Values: 0:Disabled,1:Enabled
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " USE2 " , 18 , Compass , _use_for_yaw . _priv_instance [ 1 ] , 1 ) ,
2021-12-01 11:46:30 -04:00
2021-12-04 00:22:56 -04:00
// @Param: ORIENT2
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass2 orientation
2022-07-20 17:47:27 -03:00
// @Description: The orientation of a second external compass relative to the vehicle frame. This value will be ignored unless this compass is set as an external compass. When set correctly in the northern hemisphere, pointing the nose and right side down should increase the MagX and MagY values respectively. Rolling the vehicle upside down should decrease the MagZ value. For southern hemisphere, switch increase and decrease. NOTE: For internal compasses, AHRS_ORIENT is used. The label for each option is specified in the order of rotations for that orientation. Firmware versions 4.2 and prior can use a CUSTOM (100) rotation to set the COMPASS_CUS_ROLL/PIT/YAW angles for Compass orientation. Later versions provide two general custom rotations which can be used, Custom 1 and Custom 2, with CUST_1_ROLL/PIT/YAW or CUST_2_ROLL/PIT/YAW angles.
2021-11-05 13:11:09 -03:00
// @Values: 0:None,1:Yaw45,2:Yaw90,3:Yaw135,4:Yaw180,5:Yaw225,6:Yaw270,7:Yaw315,8:Roll180,9:Yaw45Roll180,10:Yaw90Roll180,11:Yaw135Roll180,12:Pitch180,13:Yaw225Roll180,14:Yaw270Roll180,15:Yaw315Roll180,16:Roll90,17:Yaw45Roll90,18:Yaw90Roll90,19:Yaw135Roll90,20:Roll270,21:Yaw45Roll270,22:Yaw90Roll270,23:Yaw135Roll270,24:Pitch90,25:Pitch270,26:Yaw90Pitch180,27:Yaw270Pitch180,28:Pitch90Roll90,29:Pitch90Roll180,30:Pitch90Roll270,31:Pitch180Roll90,32:Pitch180Roll270,33:Pitch270Roll90,34:Pitch270Roll180,35:Pitch270Roll270,36:Yaw90Pitch180Roll90,37:Yaw270Roll90,38:Yaw293Pitch68Roll180,39:Pitch315,40:Pitch315Roll90,42:Roll45,43:Roll315,100:Custom 4.1 and older,101:Custom 1,102:Custom 2
2021-11-02 22:27:50 -03:00
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " ORIENT2 " , 19 , Compass , _state . _priv_instance [ 1 ] . orientation , ROTATION_NONE ) ,
2021-12-01 11:46:30 -04:00
2021-12-04 00:22:56 -04:00
// @Param: EXTERN2
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass2 is attached via an external cable
// @Description: Configure second compass so it is attached externally. This is auto-detected on most boards. If set to 0 or 1 then auto-detection by bus connection can override the value. If set to 2 then auto-detection will be disabled.
// @Values: 0:Internal,1:External,2:ForcedExternal
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " EXTERN2 " , 20 , Compass , _state . _priv_instance [ 1 ] . external , 0 ) ,
# endif // COMPASS_MAX_INSTANCES
2021-12-01 11:46:30 -04:00
2021-12-04 00:22:56 -04:00
# if COMPASS_MAX_INSTANCES > 2
// @Param: USE3
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass3 used for yaw
// @Description: Enable or disable the tertiary compass for determining heading.
// @Values: 0:Disabled,1:Enabled
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " USE3 " , 21 , Compass , _use_for_yaw . _priv_instance [ 2 ] , 1 ) ,
2021-12-01 11:46:30 -04:00
2021-12-04 00:22:56 -04:00
// @Param: ORIENT3
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass3 orientation
2022-07-20 17:47:27 -03:00
// @Description: The orientation of a third external compass relative to the vehicle frame. This value will be ignored unless this compass is set as an external compass. When set correctly in the northern hemisphere, pointing the nose and right side down should increase the MagX and MagY values respectively. Rolling the vehicle upside down should decrease the MagZ value. For southern hemisphere, switch increase and decrease. NOTE: For internal compasses, AHRS_ORIENT is used. The label for each option is specified in the order of rotations for that orientation. Firmware versions 4.2 and prior can use a CUSTOM (100) rotation to set the COMPASS_CUS_ROLL/PIT/YAW angles for Compass orientation. Later versions provide two general custom rotations which can be used, Custom 1 and Custom 2, with CUST_1_ROLL/PIT/YAW or CUST_2_ROLL/PIT/YAW angles.
2021-11-05 13:11:09 -03:00
// @Values: 0:None,1:Yaw45,2:Yaw90,3:Yaw135,4:Yaw180,5:Yaw225,6:Yaw270,7:Yaw315,8:Roll180,9:Yaw45Roll180,10:Yaw90Roll180,11:Yaw135Roll180,12:Pitch180,13:Yaw225Roll180,14:Yaw270Roll180,15:Yaw315Roll180,16:Roll90,17:Yaw45Roll90,18:Yaw90Roll90,19:Yaw135Roll90,20:Roll270,21:Yaw45Roll270,22:Yaw90Roll270,23:Yaw135Roll270,24:Pitch90,25:Pitch270,26:Yaw90Pitch180,27:Yaw270Pitch180,28:Pitch90Roll90,29:Pitch90Roll180,30:Pitch90Roll270,31:Pitch180Roll90,32:Pitch180Roll270,33:Pitch270Roll90,34:Pitch270Roll180,35:Pitch270Roll270,36:Yaw90Pitch180Roll90,37:Yaw270Roll90,38:Yaw293Pitch68Roll180,39:Pitch315,40:Pitch315Roll90,42:Roll45,43:Roll315,100:Custom 4.1 and older,101:Custom 1,102:Custom 2
2021-11-02 22:27:50 -03:00
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " ORIENT3 " , 22 , Compass , _state . _priv_instance [ 2 ] . orientation , ROTATION_NONE ) ,
2021-12-01 11:46:30 -04:00
2021-12-04 00:22:56 -04:00
// @Param: EXTERN3
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass3 is attached via an external cable
// @Description: Configure third compass so it is attached externally. This is auto-detected on most boards. If set to 0 or 1 then auto-detection by bus connection can override the value. If set to 2 then auto-detection will be disabled.
// @Values: 0:Internal,1:External,2:ForcedExternal
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " EXTERN3 " , 23 , Compass , _state . _priv_instance [ 2 ] . external , 0 ) ,
# endif // COMPASS_MAX_INSTANCES
2021-12-01 11:46:30 -04:00
2022-10-04 21:22:17 -03:00
# if AP_COMPASS_DIAGONALS_ENABLED
2021-12-04 00:22:56 -04:00
// @Param: DIA_X
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass soft-iron diagonal X component
// @Description: DIA_X in the compass soft-iron calibration matrix: [[DIA_X, ODI_X, ODI_Y], [ODI_X, DIA_Y, ODI_Z], [ODI_Y, ODI_Z, DIA_Z]]
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: DIA_Y
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass soft-iron diagonal Y component
// @Description: DIA_Y in the compass soft-iron calibration matrix: [[DIA_X, ODI_X, ODI_Y], [ODI_X, DIA_Y, ODI_Z], [ODI_Y, ODI_Z, DIA_Z]]
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: DIA_Z
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass soft-iron diagonal Z component
// @Description: DIA_Z in the compass soft-iron calibration matrix: [[DIA_X, ODI_X, ODI_Y], [ODI_X, DIA_Y, ODI_Z], [ODI_Y, ODI_Z, DIA_Z]]
// @User: Advanced
2024-10-25 10:59:44 -03:00
// @Calibration: 1
2022-07-27 14:14:01 -03:00
AP_GROUPINFO ( " DIA " , 24 , Compass , _state . _priv_instance [ 0 ] . diagonals , 1.0 ) ,
2021-12-01 11:46:30 -04:00
2021-12-04 00:22:56 -04:00
// @Param: ODI_X
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass soft-iron off-diagonal X component
// @Description: ODI_X in the compass soft-iron calibration matrix: [[DIA_X, ODI_X, ODI_Y], [ODI_X, DIA_Y, ODI_Z], [ODI_Y, ODI_Z, DIA_Z]]
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: ODI_Y
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass soft-iron off-diagonal Y component
// @Description: ODI_Y in the compass soft-iron calibration matrix: [[DIA_X, ODI_X, ODI_Y], [ODI_X, DIA_Y, ODI_Z], [ODI_Y, ODI_Z, DIA_Z]]
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: ODI_Z
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass soft-iron off-diagonal Z component
// @Description: ODI_Z in the compass soft-iron calibration matrix: [[DIA_X, ODI_X, ODI_Y], [ODI_X, DIA_Y, ODI_Z], [ODI_Y, ODI_Z, DIA_Z]]
// @User: Advanced
2024-10-25 10:59:44 -03:00
// @Calibration: 1
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " ODI " , 25 , Compass , _state . _priv_instance [ 0 ] . offdiagonals , 0 ) ,
2021-12-01 11:46:30 -04:00
2021-12-04 00:22:56 -04:00
# if COMPASS_MAX_INSTANCES > 1
// @Param: DIA2_X
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass2 soft-iron diagonal X component
// @Description: DIA_X in the compass2 soft-iron calibration matrix: [[DIA_X, ODI_X, ODI_Y], [ODI_X, DIA_Y, ODI_Z], [ODI_Y, ODI_Z, DIA_Z]]
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: DIA2_Y
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass2 soft-iron diagonal Y component
// @Description: DIA_Y in the compass2 soft-iron calibration matrix: [[DIA_X, ODI_X, ODI_Y], [ODI_X, DIA_Y, ODI_Z], [ODI_Y, ODI_Z, DIA_Z]]
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: DIA2_Z
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass2 soft-iron diagonal Z component
// @Description: DIA_Z in the compass2 soft-iron calibration matrix: [[DIA_X, ODI_X, ODI_Y], [ODI_X, DIA_Y, ODI_Z], [ODI_Y, ODI_Z, DIA_Z]]
// @User: Advanced
2024-10-25 10:59:44 -03:00
// @Calibration: 1
2022-07-27 14:14:01 -03:00
AP_GROUPINFO ( " DIA2 " , 26 , Compass , _state . _priv_instance [ 1 ] . diagonals , 1.0 ) ,
2021-12-01 11:46:30 -04:00
2021-12-04 00:22:56 -04:00
// @Param: ODI2_X
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass2 soft-iron off-diagonal X component
// @Description: ODI_X in the compass2 soft-iron calibration matrix: [[DIA_X, ODI_X, ODI_Y], [ODI_X, DIA_Y, ODI_Z], [ODI_Y, ODI_Z, DIA_Z]]
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: ODI2_Y
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass2 soft-iron off-diagonal Y component
// @Description: ODI_Y in the compass2 soft-iron calibration matrix: [[DIA_X, ODI_X, ODI_Y], [ODI_X, DIA_Y, ODI_Z], [ODI_Y, ODI_Z, DIA_Z]]
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: ODI2_Z
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass2 soft-iron off-diagonal Z component
// @Description: ODI_Z in the compass2 soft-iron calibration matrix: [[DIA_X, ODI_X, ODI_Y], [ODI_X, DIA_Y, ODI_Z], [ODI_Y, ODI_Z, DIA_Z]]
// @User: Advanced
2024-10-25 10:59:44 -03:00
// @Calibration: 1
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " ODI2 " , 27 , Compass , _state . _priv_instance [ 1 ] . offdiagonals , 0 ) ,
# endif // COMPASS_MAX_INSTANCES
2021-12-01 11:46:30 -04:00
2021-12-04 00:22:56 -04:00
# if COMPASS_MAX_INSTANCES > 2
// @Param: DIA3_X
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass3 soft-iron diagonal X component
// @Description: DIA_X in the compass3 soft-iron calibration matrix: [[DIA_X, ODI_X, ODI_Y], [ODI_X, DIA_Y, ODI_Z], [ODI_Y, ODI_Z, DIA_Z]]
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: DIA3_Y
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass3 soft-iron diagonal Y component
// @Description: DIA_Y in the compass3 soft-iron calibration matrix: [[DIA_X, ODI_X, ODI_Y], [ODI_X, DIA_Y, ODI_Z], [ODI_Y, ODI_Z, DIA_Z]]
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: DIA3_Z
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass3 soft-iron diagonal Z component
// @Description: DIA_Z in the compass3 soft-iron calibration matrix: [[DIA_X, ODI_X, ODI_Y], [ODI_X, DIA_Y, ODI_Z], [ODI_Y, ODI_Z, DIA_Z]]
// @User: Advanced
2024-10-25 10:59:44 -03:00
// @Calibration: 1
2022-07-27 14:14:01 -03:00
AP_GROUPINFO ( " DIA3 " , 28 , Compass , _state . _priv_instance [ 2 ] . diagonals , 1.0 ) ,
2021-12-01 11:46:30 -04:00
2021-12-04 00:22:56 -04:00
// @Param: ODI3_X
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass3 soft-iron off-diagonal X component
// @Description: ODI_X in the compass3 soft-iron calibration matrix: [[DIA_X, ODI_X, ODI_Y], [ODI_X, DIA_Y, ODI_Z], [ODI_Y, ODI_Z, DIA_Z]]
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: ODI3_Y
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass3 soft-iron off-diagonal Y component
// @Description: ODI_Y in the compass3 soft-iron calibration matrix: [[DIA_X, ODI_X, ODI_Y], [ODI_X, DIA_Y, ODI_Z], [ODI_Y, ODI_Z, DIA_Z]]
// @User: Advanced
// @Calibration: 1
2021-12-04 00:22:56 -04:00
// @Param: ODI3_Z
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass3 soft-iron off-diagonal Z component
// @Description: ODI_Z in the compass3 soft-iron calibration matrix: [[DIA_X, ODI_X, ODI_Y], [ODI_X, DIA_Y, ODI_Z], [ODI_Y, ODI_Z, DIA_Z]]
// @User: Advanced
2024-10-25 10:59:44 -03:00
// @Calibration: 1
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " ODI3 " , 29 , Compass , _state . _priv_instance [ 2 ] . offdiagonals , 0 ) ,
# endif // COMPASS_MAX_INSTANCES
2022-10-04 21:22:17 -03:00
# endif // AP_COMPASS_DIAGONALS_ENABLED
2015-03-18 20:18:47 -03:00
2020-04-29 00:27:58 -03:00
# if COMPASS_CAL_ENABLED
2021-12-04 00:22:56 -04:00
// @Param: CAL_FIT
2015-09-14 04:01:14 -03:00
// @DisplayName: Compass calibration fitness
// @Description: This controls the fitness level required for a successful compass calibration. A lower value makes for a stricter fit (less likely to pass). This is the value used for the primary magnetometer. Other magnetometers get double the value.
2016-09-13 21:57:52 -03:00
// @Range: 4 32
2017-01-25 04:27:53 -04:00
// @Values: 4:Very Strict,8:Strict,16:Default,32:Relaxed
2015-09-14 04:01:14 -03:00
// @Increment: 0.1
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " CAL_FIT " , 30 , Compass , _calibration_threshold , AP_COMPASS_CALIBRATION_FITNESS_DEFAULT ) ,
2020-04-29 00:27:58 -03:00
# endif
2016-03-01 15:16:04 -04:00
2021-04-29 02:40:15 -03:00
# ifndef HAL_BUILD_AP_PERIPH
2021-12-04 00:22:56 -04:00
// @Param: OFFS_MAX
2017-04-03 19:38:14 -03:00
// @DisplayName: Compass maximum offset
// @Description: This sets the maximum allowed compass offset in calibration and arming checks
// @Range: 500 3000
// @Increment: 1
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " OFFS_MAX " , 31 , Compass , _offset_max , AP_COMPASS_OFFSETS_MAX_DEFAULT ) ,
2021-04-29 02:40:15 -03:00
# endif
2017-06-18 04:26:25 -03:00
2019-05-26 22:49:12 -03:00
# if COMPASS_MOT_ENABLED
2021-12-04 00:22:56 -04:00
// @Group: PMOT
2018-01-05 06:08:04 -04:00
// @Path: Compass_PerMotor.cpp
2021-12-04 00:22:56 -04:00
AP_SUBGROUPINFO ( _per_motor , " PMOT " , 32 , Compass , Compass_PerMotor ) ,
2019-05-26 22:49:12 -03:00
# endif
2018-01-05 06:08:04 -04:00
2024-01-21 22:24:58 -04:00
// @Param: DISBLMSK
2017-06-18 04:26:25 -03:00
// @DisplayName: Compass disable driver type mask
// @Description: This is a bitmask of driver types to disable. If a driver type is set in this mask then that driver will not try to find a sensor at startup
2024-09-21 04:24:04 -03:00
// @Bitmask: 0:HMC5883,1:LSM303D,2:AK8963,3:BMM150,4:LSM9DS1,5:LIS3MDL,6:AK09916,7:IST8310,8:ICM20948,9:MMC3416,11:DroneCAN,12:QMC5883,14:MAG3110,15:IST8308,16:RM3100,17:MSP,18:ExternalAHRS,19:MMC5XX3,20:QMC5883P,21:BMM350
2017-06-18 04:26:25 -03:00
// @User: Advanced
2024-01-21 22:24:58 -04:00
AP_GROUPINFO ( " DISBLMSK " , 33 , Compass , _driver_type_mask , 0 ) ,
2018-03-12 04:59:32 -03:00
2021-12-04 00:22:56 -04:00
// @Param: FLTR_RNG
2018-03-12 04:59:32 -03:00
// @DisplayName: Range in which sample is accepted
// @Description: This sets the range around the average value that new samples must be within to be accepted. This can help reduce the impact of noise on sensors that are on long I2C cables. The value is a percentage from the average value. A value of zero disables this filter.
// @Units: %
// @Range: 0 100
// @Increment: 1
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " FLTR_RNG " , 34 , Compass , _filter_range , HAL_COMPASS_FILTER_DEFAULT ) ,
2018-07-16 05:21:53 -03:00
2020-04-29 00:27:58 -03:00
# if COMPASS_CAL_ENABLED
2021-12-04 00:22:56 -04:00
// @Param: AUTO_ROT
2018-07-17 21:09:21 -03:00
// @DisplayName: Automatically check orientation
// @Description: When enabled this will automatically check the orientation of compasses on successful completion of compass calibration. If set to 2 then external compasses will have their orientation automatically corrected.
2021-07-23 16:48:40 -03:00
// @Values: 0:Disabled,1:CheckOnly,2:CheckAndFix,3:use same tolerance to auto rotate 45 deg rotations
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " AUTO_ROT " , 35 , Compass , _rotate_auto , HAL_COMPASS_AUTO_ROT_DEFAULT ) ,
2020-04-29 00:27:58 -03:00
# endif
2018-07-10 15:28:32 -03:00
2020-04-29 00:27:58 -03:00
# if COMPASS_MAX_INSTANCES > 1
2021-12-04 00:22:56 -04:00
// @Param: PRIO1_ID
2019-11-20 03:18:10 -04:00
// @DisplayName: Compass device id with 1st order priority
// @Description: Compass device id with 1st order priority, set automatically if 0. Reboot required after change.
2020-04-14 07:38:50 -03:00
// @RebootRequired: True
2018-07-10 15:28:32 -03:00
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " PRIO1_ID " , 36 , Compass , _priority_did_stored_list . _priv_instance [ 0 ] , 0 ) ,
2018-07-10 15:28:32 -03:00
2021-12-04 00:22:56 -04:00
// @Param: PRIO2_ID
2019-11-20 03:18:10 -04:00
// @DisplayName: Compass device id with 2nd order priority
// @Description: Compass device id with 2nd order priority, set automatically if 0. Reboot required after change.
2020-04-14 07:38:50 -03:00
// @RebootRequired: True
2018-07-10 15:28:32 -03:00
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " PRIO2_ID " , 37 , Compass , _priority_did_stored_list . _priv_instance [ 1 ] , 0 ) ,
2020-03-09 23:14:45 -03:00
# endif // COMPASS_MAX_INSTANCES
2018-07-10 15:28:32 -03:00
2020-03-09 23:14:45 -03:00
# if COMPASS_MAX_INSTANCES > 2
2021-12-04 00:22:56 -04:00
// @Param: PRIO3_ID
2019-11-20 03:18:10 -04:00
// @DisplayName: Compass device id with 3rd order priority
// @Description: Compass device id with 3rd order priority, set automatically if 0. Reboot required after change.
2020-04-14 07:38:50 -03:00
// @RebootRequired: True
2018-07-10 15:28:32 -03:00
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " PRIO3_ID " , 38 , Compass , _priority_did_stored_list . _priv_instance [ 2 ] , 0 ) ,
2020-03-09 23:14:45 -03:00
# endif // COMPASS_MAX_INSTANCES
2019-03-24 00:24:56 -03:00
2021-12-04 00:22:56 -04:00
// @Param: ENABLE
// @DisplayName: Enable Compass
// @Description: Setting this to Enabled(1) will enable the compass. Setting this to Disabled(0) will disable the compass. Note that this is separate from COMPASS_USE. This will enable the low level senor, and will enable logging of magnetometer data. To use the compass for navigation you must also set COMPASS_USE to 1.
// @User: Standard
// @RebootRequired: True
// @Values: 0:Disabled,1:Enabled
2022-01-27 23:51:02 -04:00
AP_GROUPINFO ( " ENABLE " , 39 , Compass , _enabled , AP_COMPASS_ENABLE_DEFAULT ) ,
2019-11-26 18:11:54 -04:00
2021-12-04 00:22:56 -04:00
# ifndef HAL_BUILD_AP_PERIPH
// @Param: SCALE
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass1 scale factor
// @Description: Scaling factor for first compass to compensate for sensor scaling errors. If this is 0 then no scaling is done
// @User: Standard
// @Range: 0 1.3
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " SCALE " , 40 , Compass , _state . _priv_instance [ 0 ] . scale_factor , 0 ) ,
2021-12-01 11:46:30 -04:00
2021-12-04 00:22:56 -04:00
# if COMPASS_MAX_INSTANCES > 1
// @Param: SCALE2
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass2 scale factor
// @Description: Scaling factor for 2nd compass to compensate for sensor scaling errors. If this is 0 then no scaling is done
// @User: Standard
// @Range: 0 1.3
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " SCALE2 " , 41 , Compass , _state . _priv_instance [ 1 ] . scale_factor , 0 ) ,
# endif
2021-12-01 11:46:30 -04:00
2021-12-04 00:22:56 -04:00
# if COMPASS_MAX_INSTANCES > 2
// @Param: SCALE3
2021-11-02 22:27:50 -03:00
// @DisplayName: Compass3 scale factor
// @Description: Scaling factor for 3rd compass to compensate for sensor scaling errors. If this is 0 then no scaling is done
// @User: Standard
// @Range: 0 1.3
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " SCALE3 " , 42 , Compass , _state . _priv_instance [ 2 ] . scale_factor , 0 ) ,
# endif
# endif // HAL_BUILD_AP_PERIPH
2021-12-01 11:46:30 -04:00
2023-11-06 22:51:20 -04:00
# ifndef HAL_BUILD_AP_PERIPH
2021-12-04 00:22:56 -04:00
// @Param: OPTIONS
2019-11-26 18:45:02 -04:00
// @DisplayName: Compass options
// @Description: This sets options to change the behaviour of the compass
// @Bitmask: 0:CalRequireGPS
2023-06-18 15:19:39 -03:00
// @Bitmask: 1: Allow missing DroneCAN compasses to be automaticaly replaced (calibration still required)
2019-11-26 18:45:02 -04:00
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " OPTIONS " , 43 , Compass , _options , 0 ) ,
2023-11-06 22:51:20 -04:00
# endif
2019-11-26 18:45:02 -04:00
2019-11-20 03:18:10 -04:00
# if COMPASS_MAX_UNREG_DEV > 0
2021-12-04 00:22:56 -04:00
// @Param: DEV_ID4
2019-11-20 01:06:54 -04:00
// @DisplayName: Compass4 device id
// @Description: Extra 4th compass's device id. Automatically detected, do not set manually
// @ReadOnly: True
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " DEV_ID4 " , 44 , Compass , extra_dev_id [ 0 ] , 0 ) ,
2019-11-20 03:18:10 -04:00
# endif // COMPASS_MAX_UNREG_DEV
2019-11-20 01:06:54 -04:00
2019-11-20 03:18:10 -04:00
# if COMPASS_MAX_UNREG_DEV > 1
2021-12-04 00:22:56 -04:00
// @Param: DEV_ID5
2019-11-20 01:06:54 -04:00
// @DisplayName: Compass5 device id
// @Description: Extra 5th compass's device id. Automatically detected, do not set manually
// @ReadOnly: True
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " DEV_ID5 " , 45 , Compass , extra_dev_id [ 1 ] , 0 ) ,
2019-11-20 03:18:10 -04:00
# endif // COMPASS_MAX_UNREG_DEV
2019-11-20 01:06:54 -04:00
2019-11-20 03:18:10 -04:00
# if COMPASS_MAX_UNREG_DEV > 2
2021-12-04 00:22:56 -04:00
// @Param: DEV_ID6
2019-11-20 01:06:54 -04:00
// @DisplayName: Compass6 device id
// @Description: Extra 6th compass's device id. Automatically detected, do not set manually
// @ReadOnly: True
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " DEV_ID6 " , 46 , Compass , extra_dev_id [ 2 ] , 0 ) ,
2019-11-20 03:18:10 -04:00
# endif // COMPASS_MAX_UNREG_DEV
2019-11-20 01:06:54 -04:00
2019-11-20 03:18:10 -04:00
# if COMPASS_MAX_UNREG_DEV > 3
2021-12-04 00:22:56 -04:00
// @Param: DEV_ID7
2019-11-20 01:06:54 -04:00
// @DisplayName: Compass7 device id
// @Description: Extra 7th compass's device id. Automatically detected, do not set manually
// @ReadOnly: True
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " DEV_ID7 " , 47 , Compass , extra_dev_id [ 3 ] , 0 ) ,
2019-11-20 03:18:10 -04:00
# endif // COMPASS_MAX_UNREG_DEV
2019-11-20 01:06:54 -04:00
2019-11-20 03:18:10 -04:00
# if COMPASS_MAX_UNREG_DEV > 4
2021-12-04 00:22:56 -04:00
// @Param: DEV_ID8
2019-11-20 01:06:54 -04:00
// @DisplayName: Compass8 device id
// @Description: Extra 8th compass's device id. Automatically detected, do not set manually
// @ReadOnly: True
// @User: Advanced
2021-12-04 00:22:56 -04:00
AP_GROUPINFO ( " DEV_ID8 " , 48 , Compass , extra_dev_id [ 4 ] , 0 ) ,
2019-11-20 03:18:10 -04:00
# endif // COMPASS_MAX_UNREG_DEV
2019-11-20 01:06:54 -04:00
2021-12-04 00:22:56 -04:00
// @Param: CUS_ROLL
2020-04-14 07:38:50 -03:00
// @DisplayName: Custom orientation roll offset
2021-12-04 00:22:56 -04:00
// @Description: Compass mounting position roll offset. Positive values = roll right, negative values = roll left. This parameter is only used when COMPASS_ORIENT/2/3 is set to CUSTOM.
2020-04-14 07:38:50 -03:00
// @Range: -180 180
// @Units: deg
// @Increment: 1
// @RebootRequired: True
// @User: Advanced
2021-11-05 13:13:55 -03:00
2021-11-05 13:11:09 -03:00
// index 49
2020-04-14 07:38:50 -03:00
2021-12-04 00:22:56 -04:00
// @Param: CUS_PIT
2020-04-14 07:38:50 -03:00
// @DisplayName: Custom orientation pitch offset
2021-12-04 00:22:56 -04:00
// @Description: Compass mounting position pitch offset. Positive values = pitch up, negative values = pitch down. This parameter is only used when COMPASS_ORIENT/2/3 is set to CUSTOM.
2020-04-14 07:38:50 -03:00
// @Range: -180 180
// @Units: deg
// @Increment: 1
// @RebootRequired: True
// @User: Advanced
2021-11-05 13:13:55 -03:00
2021-11-05 13:11:09 -03:00
// index 50
2020-04-14 07:38:50 -03:00
2021-12-04 00:22:56 -04:00
// @Param: CUS_YAW
2020-04-14 07:38:50 -03:00
// @DisplayName: Custom orientation yaw offset
2021-12-04 00:22:56 -04:00
// @Description: Compass mounting position yaw offset. Positive values = yaw right, negative values = yaw left. This parameter is only used when COMPASS_ORIENT/2/3 is set to CUSTOM.
2020-04-14 07:38:50 -03:00
// @Range: -180 180
// @Units: deg
// @Increment: 1
// @RebootRequired: True
// @User: Advanced
2021-11-05 13:13:55 -03:00
2021-11-05 13:11:09 -03:00
// index 51
2021-11-05 13:13:55 -03:00
2012-02-12 03:23:19 -04:00
AP_GROUPEND
2012-02-11 07:53:30 -04:00
} ;
2011-02-14 00:25:20 -04:00
// Default constructor.
// Note that the Vector/Matrix constructors already implicitly zero
// their values.
//
2018-03-28 20:57:17 -03:00
Compass : : Compass ( void )
2011-02-14 00:25:20 -04:00
{
2018-03-29 01:13:55 -03:00
if ( _singleton ! = nullptr ) {
# if CONFIG_HAL_BOARD == HAL_BOARD_SITL
AP_HAL : : panic ( " Compass must be singleton " ) ;
# endif
return ;
}
_singleton = this ;
2012-12-12 17:43:51 -04:00
AP_Param : : setup_object_defaults ( this , var_info ) ;
2011-02-14 00:25:20 -04:00
}
2014-11-15 21:58:23 -04:00
// Default init method
2011-02-14 00:25:20 -04:00
//
2018-07-03 04:36:32 -03:00
void Compass : : init ( )
2011-02-14 00:25:20 -04:00
{
2021-07-27 21:27:38 -03:00
if ( ! _enabled ) {
2019-03-24 00:24:56 -03:00
return ;
}
2023-09-20 20:03:24 -03:00
/*
on init ( ) if any devid is set then we set suppress_devid_save to
false . This is used to determine if we save device ids during
the init process .
*/
suppress_devid_save = true ;
for ( uint8_t i = 0 ; i < COMPASS_MAX_INSTANCES ; i + + ) {
if ( _state . _priv_instance [ i ] . dev_id ! = 0 ) {
suppress_devid_save = false ;
break ;
}
# if COMPASS_MAX_INSTANCES > 1
if ( _priority_did_stored_list . _priv_instance [ i ] ! = 0 ) {
suppress_devid_save = false ;
break ;
}
# endif
}
2021-11-05 13:13:55 -03:00
// convert to new custom rotation method
// PARAMETER_CONVERSION - Added: Nov-2021
2024-02-29 00:39:18 -04:00
# if AP_CUSTOMROTATIONS_ENABLED
2021-11-05 13:13:55 -03:00
for ( StateIndex i ( 0 ) ; i < COMPASS_MAX_INSTANCES ; i + + ) {
if ( _state [ i ] . orientation ! = ROTATION_CUSTOM_OLD ) {
continue ;
}
_state [ i ] . orientation . set_and_save ( ROTATION_CUSTOM_2 ) ;
AP_Param : : ConversionInfo info ;
if ( AP_Param : : find_top_level_key_by_pointer ( this , info . old_key ) ) {
info . type = AP_PARAM_FLOAT ;
float rpy [ 3 ] = { } ;
AP_Float rpy_param ;
for ( info . old_group_element = 49 ; info . old_group_element < = 51 ; info . old_group_element + + ) {
if ( AP_Param : : find_old_parameter ( & info , & rpy_param ) ) {
rpy [ info . old_group_element - 49 ] = rpy_param . get ( ) ;
}
}
AP : : custom_rotations ( ) . convert ( ROTATION_CUSTOM_2 , rpy [ 0 ] , rpy [ 1 ] , rpy [ 2 ] ) ;
}
break ;
}
2024-02-29 00:39:18 -04:00
# endif // AP_CUSTOMROTATIONS_ENABLED
2021-11-05 13:13:55 -03:00
2020-04-29 00:27:58 -03:00
# if COMPASS_MAX_INSTANCES > 1
2019-11-20 03:18:10 -04:00
// Look if there was a primary compass setup in previous version
2022-05-23 01:52:09 -03:00
// if so and the primary compass is not set in current setup
2019-11-20 03:18:10 -04:00
// make the devid as primary.
if ( _priority_did_stored_list [ Priority ( 0 ) ] = = 0 ) {
uint16_t k_param_compass ;
if ( AP_Param : : find_top_level_key_by_pointer ( this , k_param_compass ) ) {
const AP_Param : : ConversionInfo primary_compass_old_param = { k_param_compass , 12 , AP_PARAM_INT8 , " " } ;
AP_Int8 value ;
value . set ( 0 ) ;
bool primary_param_exists = AP_Param : : find_old_parameter ( & primary_compass_old_param , & value ) ;
int8_t oldvalue = value . get ( ) ;
if ( ( oldvalue ! = 0 ) & & ( oldvalue < COMPASS_MAX_INSTANCES ) & & primary_param_exists ) {
2021-12-04 00:22:56 -04:00
_priority_did_stored_list [ Priority ( 0 ) ] . set_and_save_ifchanged ( _state [ StateIndex ( oldvalue ) ] . dev_id ) ;
2019-11-20 03:18:10 -04:00
}
}
}
2020-02-15 02:30:10 -04:00
// Load priority list from storage, the changes to priority list
2019-11-20 03:18:10 -04:00
// by user only take effect post reboot, after this
2023-09-20 20:03:24 -03:00
if ( ! suppress_devid_save ) {
for ( Priority i ( 0 ) ; i < COMPASS_MAX_INSTANCES ; i + + ) {
if ( _priority_did_stored_list [ i ] ! = 0 ) {
_priority_did_list [ i ] = _priority_did_stored_list [ i ] ;
} else {
// Maintain a list without gaps and duplicates
for ( Priority j ( i + 1 ) ; j < COMPASS_MAX_INSTANCES ; j + + ) {
int32_t temp ;
if ( _priority_did_stored_list [ j ] = = _priority_did_stored_list [ i ] ) {
_priority_did_stored_list [ j ] . set_and_save_ifchanged ( 0 ) ;
}
if ( _priority_did_stored_list [ j ] = = 0 ) {
continue ;
}
temp = _priority_did_stored_list [ j ] ;
2020-08-26 16:06:46 -03:00
_priority_did_stored_list [ j ] . set_and_save_ifchanged ( 0 ) ;
2023-09-20 20:03:24 -03:00
_priority_did_list [ i ] = temp ;
_priority_did_stored_list [ i ] . set_and_save_ifchanged ( temp ) ;
break ;
2020-07-20 18:25:08 -03:00
}
2019-11-20 03:18:10 -04:00
}
}
}
2020-04-29 00:27:58 -03:00
# endif // COMPASS_MAX_INSTANCES
2019-11-20 03:18:10 -04:00
// cache expected dev ids for use during runtime detection
for ( StateIndex i ( 0 ) ; i < COMPASS_MAX_INSTANCES ; i + + ) {
2021-12-04 00:22:56 -04:00
_state [ i ] . expected_dev_id = _state [ i ] . dev_id ;
2019-11-20 03:18:10 -04:00
}
# if COMPASS_MAX_UNREG_DEV
// set the dev_id to 0 for undetected compasses. extra_dev_id is just an
// interface for users to see unreg compasses, we actually never store it
// in storage.
for ( uint8_t i = _unreg_compass_count ; i < COMPASS_MAX_UNREG_DEV ; i + + ) {
2020-07-20 18:25:08 -03:00
// cache the extra devices detected in last boot
// for detecting replacement mag
_previously_unreg_mag [ i ] = extra_dev_id [ i ] ;
2023-09-20 20:03:24 -03:00
extra_dev_id [ i ] . set ( 0 ) ;
2019-11-20 03:18:10 -04:00
}
# endif
2020-08-16 07:20:06 -03:00
# if COMPASS_MAX_INSTANCES > 1
2020-08-26 16:06:46 -03:00
// This method calls set_and_save_ifchanged on parameters
// which are set() but not saved() during normal runtime,
// do not move this call without ensuring that is not happening
// read comments under set_and_save_ifchanged for details
2023-09-20 20:03:24 -03:00
if ( ! suppress_devid_save ) {
_reorder_compass_params ( ) ;
}
2020-08-16 07:20:06 -03:00
# endif
2019-11-20 03:18:10 -04:00
2014-11-15 21:58:23 -04:00
if ( _compass_count = = 0 ) {
// detect available backends. Only called once
_detect_backends ( ) ;
}
2019-11-20 03:18:10 -04:00
2015-03-13 02:43:34 -03:00
if ( _compass_count ! = 0 ) {
// get initial health status
hal . scheduler - > delay ( 100 ) ;
read ( ) ;
}
2018-07-29 21:42:59 -03:00
// set the dev_id to 0 for undetected compasses, to make it easier
// for users to see how many compasses are detected. We don't do a
// set_and_save() as the user may have temporarily removed the
// compass, and we don't want to force a re-cal if they plug it
// back in again
2019-11-20 03:18:10 -04:00
for ( StateIndex i ( 0 ) ; i < COMPASS_MAX_INSTANCES ; i + + ) {
if ( ! _state [ i ] . registered ) {
2021-12-04 00:22:56 -04:00
_state [ i ] . dev_id . set ( 0 ) ;
2019-11-20 03:18:10 -04:00
}
2018-07-29 21:42:59 -03:00
}
2019-03-24 00:24:56 -03:00
2019-05-26 22:49:12 -03:00
# ifndef HAL_BUILD_AP_PERIPH
2021-07-25 21:32:11 -03:00
// updating the AHRS orientation updates our own orientation:
AP : : ahrs ( ) . update_orientation ( ) ;
2019-05-26 22:49:12 -03:00
# endif
2020-09-03 19:11:05 -03:00
init_done = true ;
2023-09-20 20:03:24 -03:00
suppress_devid_save = false ;
2019-11-20 03:18:10 -04:00
}
2020-04-29 00:27:58 -03:00
# if COMPASS_MAX_INSTANCES > 1 || COMPASS_MAX_UNREG_DEV
2019-11-20 03:18:10 -04:00
// Update Priority List for Mags, by default, we just
// load them as they come up the first time
Compass : : Priority Compass : : _update_priority_list ( int32_t dev_id )
{
// Check if already in priority list
2020-02-15 02:30:10 -04:00
for ( Priority i ( 0 ) ; i < COMPASS_MAX_INSTANCES ; i + + ) {
2019-11-20 03:18:10 -04:00
if ( _priority_did_list [ i ] = = dev_id ) {
if ( i > = _compass_count ) {
_compass_count = uint8_t ( i ) + 1 ;
}
return i ;
}
2019-03-24 00:24:56 -03:00
}
2019-11-20 03:18:10 -04:00
// We are not in priority list, let's add at first empty
2020-02-15 02:30:10 -04:00
for ( Priority i ( 0 ) ; i < COMPASS_MAX_INSTANCES ; i + + ) {
2019-11-20 03:18:10 -04:00
if ( _priority_did_stored_list [ i ] = = 0 ) {
2023-09-20 20:03:24 -03:00
if ( suppress_devid_save ) {
_priority_did_stored_list [ i ] . set ( dev_id ) ;
} else {
_priority_did_stored_list [ i ] . set_and_save ( dev_id ) ;
}
2019-11-20 03:18:10 -04:00
_priority_did_list [ i ] = dev_id ;
if ( i > = _compass_count ) {
_compass_count = uint8_t ( i ) + 1 ;
}
return i ;
}
}
return Priority ( COMPASS_MAX_INSTANCES ) ;
2011-02-14 00:25:20 -04:00
}
2020-04-29 00:27:58 -03:00
# endif
2011-02-14 00:25:20 -04:00
2020-08-16 07:20:06 -03:00
# if COMPASS_MAX_INSTANCES > 1
2019-11-20 03:18:10 -04:00
// This method reorganises devid list to match
// priority list, only call before detection at boot
void Compass : : _reorder_compass_params ( )
{
mag_state swap_state ;
StateIndex curr_state_id ;
2020-02-15 02:30:10 -04:00
for ( Priority i ( 0 ) ; i < COMPASS_MAX_INSTANCES ; i + + ) {
2020-08-16 07:20:06 -03:00
if ( _priority_did_list [ i ] = = 0 ) {
continue ;
}
curr_state_id = COMPASS_MAX_INSTANCES ;
for ( StateIndex j ( 0 ) ; j < COMPASS_MAX_INSTANCES ; j + + ) {
2021-12-04 00:22:56 -04:00
if ( _priority_did_list [ i ] = = _state [ j ] . dev_id ) {
2020-08-16 07:20:06 -03:00
curr_state_id = j ;
break ;
}
}
2019-11-20 03:18:10 -04:00
if ( curr_state_id ! = COMPASS_MAX_INSTANCES & & uint8_t ( curr_state_id ) ! = uint8_t ( i ) ) {
//let's swap
swap_state . copy_from ( _state [ curr_state_id ] ) ;
_state [ curr_state_id ] . copy_from ( _state [ StateIndex ( uint8_t ( i ) ) ] ) ;
_state [ StateIndex ( uint8_t ( i ) ) ] . copy_from ( swap_state ) ;
}
}
}
2020-08-16 07:20:06 -03:00
# endif
2019-11-20 03:18:10 -04:00
void Compass : : mag_state : : copy_from ( const Compass : : mag_state & state )
{
2021-12-04 00:22:56 -04:00
external . set_and_save_ifchanged ( state . external ) ;
orientation . set_and_save_ifchanged ( state . orientation ) ;
offset . set_and_save_ifchanged ( state . offset ) ;
2022-10-26 04:14:11 -03:00
# if AP_COMPASS_DIAGONALS_ENABLED
2021-12-04 00:22:56 -04:00
diagonals . set_and_save_ifchanged ( state . diagonals ) ;
offdiagonals . set_and_save_ifchanged ( state . offdiagonals ) ;
2022-09-27 04:17:08 -03:00
# endif
2021-12-04 00:22:56 -04:00
scale_factor . set_and_save_ifchanged ( state . scale_factor ) ;
dev_id . set_and_save_ifchanged ( state . dev_id ) ;
motor_compensation . set_and_save_ifchanged ( state . motor_compensation ) ;
2019-11-20 03:18:10 -04:00
expected_dev_id = state . expected_dev_id ;
2020-07-20 18:25:08 -03:00
detected_dev_id = state . detected_dev_id ;
2019-11-20 03:18:10 -04:00
}
2014-11-15 21:58:23 -04:00
// Register a new compass instance
//
2019-11-20 03:18:10 -04:00
bool Compass : : register_compass ( int32_t dev_id , uint8_t & instance )
2014-11-15 21:58:23 -04:00
{
2019-11-20 03:18:10 -04:00
2020-04-29 00:27:58 -03:00
# if COMPASS_MAX_INSTANCES == 1 && !COMPASS_MAX_UNREG_DEV
// simple single compass setup for AP_Periph
Priority priority ( 0 ) ;
StateIndex i ( 0 ) ;
if ( _state [ i ] . registered ) {
return false ;
}
_state [ i ] . registered = true ;
_state [ i ] . priority = priority ;
instance = uint8_t ( i ) ;
2021-05-20 05:16:18 -03:00
_compass_count = 1 ;
2020-04-29 00:27:58 -03:00
return true ;
# else
Priority priority ;
2019-11-20 03:18:10 -04:00
// Check if we already have this dev_id registered
for ( StateIndex i ( 0 ) ; i < COMPASS_MAX_INSTANCES ; i + + ) {
priority = _update_priority_list ( dev_id ) ;
if ( _state [ i ] . expected_dev_id = = dev_id & & priority < COMPASS_MAX_INSTANCES ) {
_state [ i ] . registered = true ;
_state [ i ] . priority = priority ;
instance = uint8_t ( i ) ;
return true ;
}
}
// This is an unregistered compass, check if any free slot is available
for ( StateIndex i ( 0 ) ; i < COMPASS_MAX_INSTANCES ; i + + ) {
priority = _update_priority_list ( dev_id ) ;
2021-12-04 00:22:56 -04:00
if ( _state [ i ] . dev_id = = 0 & & priority < COMPASS_MAX_INSTANCES ) {
2019-11-20 03:18:10 -04:00
_state [ i ] . registered = true ;
_state [ i ] . priority = priority ;
instance = uint8_t ( i ) ;
return true ;
}
}
// This might be a replacement compass module, find any unregistered compass
// instance and replace that
for ( StateIndex i ( 0 ) ; i < COMPASS_MAX_INSTANCES ; i + + ) {
priority = _update_priority_list ( dev_id ) ;
if ( ! _state [ i ] . registered & & priority < COMPASS_MAX_INSTANCES ) {
_state [ i ] . registered = true ;
_state [ i ] . priority = priority ;
instance = uint8_t ( i ) ;
return true ;
}
}
2020-04-29 00:27:58 -03:00
# endif
2019-11-20 03:18:10 -04:00
# if COMPASS_MAX_UNREG_DEV
// Set extra dev id
if ( _unreg_compass_count > = COMPASS_MAX_UNREG_DEV ) {
2015-11-19 23:09:17 -04:00
AP_HAL : : panic ( " Too many compass instances " ) ;
2014-11-15 21:58:23 -04:00
}
2019-11-20 03:18:10 -04:00
for ( uint8_t i = 0 ; i < COMPASS_MAX_UNREG_DEV ; i + + ) {
if ( extra_dev_id [ i ] = = dev_id ) {
if ( i > = _unreg_compass_count ) {
_unreg_compass_count = i + 1 ;
}
instance = i + COMPASS_MAX_INSTANCES ;
return false ;
} else if ( extra_dev_id [ i ] = = 0 ) {
extra_dev_id [ _unreg_compass_count + + ] . set ( dev_id ) ;
instance = i + COMPASS_MAX_INSTANCES ;
return false ;
}
}
# else
AP_HAL : : panic ( " Too many compass instances " ) ;
# endif
return false ;
}
Compass : : StateIndex Compass : : _get_state_id ( Compass : : Priority priority ) const
{
2020-04-29 00:27:58 -03:00
# if COMPASS_MAX_INSTANCES > 1
2020-06-05 06:47:54 -03:00
if ( _priority_did_list [ priority ] = = 0 ) {
return StateIndex ( COMPASS_MAX_INSTANCES ) ;
}
2020-02-15 02:30:10 -04:00
for ( StateIndex i ( 0 ) ; i < COMPASS_MAX_INSTANCES ; i + + ) {
2020-07-20 18:25:08 -03:00
if ( _priority_did_list [ priority ] = = _state [ i ] . detected_dev_id ) {
2019-11-20 03:18:10 -04:00
return i ;
}
}
return StateIndex ( COMPASS_MAX_INSTANCES ) ;
2020-04-29 00:27:58 -03:00
# else
return StateIndex ( 0 ) ;
# endif
2014-11-15 21:58:23 -04:00
}
2018-08-06 20:08:09 -03:00
bool Compass : : _add_backend ( AP_Compass_Backend * backend )
2014-11-15 21:58:23 -04:00
{
2016-05-13 14:37:30 -03:00
if ( ! backend ) {
return false ;
}
if ( _backend_count = = COMPASS_MAX_BACKEND ) {
2019-11-20 03:18:10 -04:00
return false ;
2016-05-13 14:37:30 -03:00
}
2015-08-05 17:02:32 -03:00
_backends [ _backend_count + + ] = backend ;
2016-05-13 14:37:30 -03:00
return true ;
2014-11-15 21:58:23 -04:00
}
2017-06-18 04:26:25 -03:00
/*
return true if a driver type is enabled
*/
bool Compass : : _driver_enabled ( enum DriverType driver_type )
{
uint32_t mask = ( 1U < < uint8_t ( driver_type ) ) ;
return ( mask & uint32_t ( _driver_type_mask . get ( ) ) ) = = 0 ;
}
2017-10-02 04:23:57 -03:00
/*
2018-07-13 06:56:24 -03:00
wrapper around hal . i2c_mgr - > get_device ( ) that prevents duplicate devices being opened
2017-10-02 04:23:57 -03:00
*/
2018-07-13 06:56:24 -03:00
bool Compass : : _have_i2c_driver ( uint8_t bus , uint8_t address ) const
2017-10-02 04:23:57 -03:00
{
2019-11-20 03:18:10 -04:00
for ( StateIndex i ( 0 ) ; i < COMPASS_MAX_INSTANCES ; i + + ) {
if ( ! _state [ i ] . registered ) {
continue ;
}
2018-07-13 06:56:24 -03:00
if ( AP_HAL : : Device : : make_bus_id ( AP_HAL : : Device : : BUS_TYPE_I2C , bus , address , 0 ) = =
2021-12-04 00:22:56 -04:00
AP_HAL : : Device : : change_bus_id ( uint32_t ( _state [ i ] . dev_id . get ( ) ) , 0 ) ) {
2018-07-13 06:56:24 -03:00
// we are already using this device
2017-10-02 04:23:57 -03:00
return true ;
}
}
return false ;
}
2020-03-25 06:33:40 -03:00
# if COMPASS_MAX_UNREG_DEV > 0
# define CHECK_UNREG_LIMIT_RETURN if (_unreg_compass_count == COMPASS_MAX_UNREG_DEV) return
# else
# define CHECK_UNREG_LIMIT_RETURN
# endif
2018-07-13 06:56:24 -03:00
/*
macro to add a backend with check for too many backends or compass
instances . We don ' t try to start more than the maximum allowed
*/
2018-08-06 20:08:09 -03:00
# define ADD_BACKEND(driver_type, backend) \
do { if ( _driver_enabled ( driver_type ) ) { _add_backend ( backend ) ; } \
2020-03-25 06:33:40 -03:00
CHECK_UNREG_LIMIT_RETURN ; \
2018-07-13 06:56:24 -03:00
} while ( 0 )
# define GET_I2C_DEVICE(bus, address) _have_i2c_driver(bus, address)?nullptr:hal.i2c_mgr->get_device(bus, address)
/*
look for compasses on external i2c buses
*/
void Compass : : _probe_external_i2c_compasses ( void )
{
2022-10-25 21:33:50 -03:00
# if !defined(HAL_SKIP_AUTO_INTERNAL_I2C_PROBE)
2018-08-07 03:33:14 -03:00
bool all_external = ( AP_BoardConfig : : get_board_type ( ) = = AP_BoardConfig : : PX4_BOARD_PIXHAWK2 ) ;
2023-02-19 21:04:50 -04:00
( void ) all_external ; // in case all backends using this are compiled out
2022-10-25 21:33:50 -03:00
# endif
2023-01-29 19:33:08 -04:00
# if AP_COMPASS_HMC5843_ENABLED
2018-07-13 06:56:24 -03:00
// external i2c bus
FOREACH_I2C_EXTERNAL ( i ) {
2019-05-29 07:57:28 -03:00
ADD_BACKEND ( DRIVER_HMC5843 , AP_Compass_HMC5843 : : probe ( GET_I2C_DEVICE ( i , HAL_COMPASS_HMC5843_I2C_ADDR ) ,
2020-02-15 02:30:10 -04:00
true , ROTATION_ROLL_180 ) ) ;
2018-07-13 06:56:24 -03:00
}
2019-02-20 09:13:33 -04:00
2022-10-25 21:33:50 -03:00
# if !defined(HAL_SKIP_AUTO_INTERNAL_I2C_PROBE)
2018-08-06 18:35:40 -03:00
if ( AP_BoardConfig : : get_board_type ( ) ! = AP_BoardConfig : : PX4_BOARD_MINDPXV2 & &
AP_BoardConfig : : get_board_type ( ) ! = AP_BoardConfig : : PX4_BOARD_AEROFC ) {
2018-07-13 06:56:24 -03:00
// internal i2c bus
FOREACH_I2C_INTERNAL ( i ) {
2019-05-29 07:57:28 -03:00
ADD_BACKEND ( DRIVER_HMC5843 , AP_Compass_HMC5843 : : probe ( GET_I2C_DEVICE ( i , HAL_COMPASS_HMC5843_I2C_ADDR ) ,
2020-02-15 02:30:10 -04:00
all_external , all_external ? ROTATION_ROLL_180 : ROTATION_YAW_270 ) ) ;
2018-07-13 06:56:24 -03:00
}
}
2023-01-29 19:33:08 -04:00
# endif // !defined(HAL_SKIP_AUTO_INTERNAL_I2C_PROBE)
# endif // AP_COMPASS_HMC5843_ENABLED
2019-02-20 09:13:33 -04:00
2023-02-19 21:05:13 -04:00
# if AP_COMPASS_QMC5883L_ENABLED
2018-07-13 06:56:24 -03:00
//external i2c bus
FOREACH_I2C_EXTERNAL ( i ) {
2019-09-01 19:16:12 -03:00
ADD_BACKEND ( DRIVER_QMC5883L , AP_Compass_QMC5883L : : probe ( GET_I2C_DEVICE ( i , HAL_COMPASS_QMC5883L_I2C_ADDR ) ,
2020-02-15 02:30:10 -04:00
true , HAL_COMPASS_QMC5883L_ORIENTATION_EXTERNAL ) ) ;
2018-07-13 06:56:24 -03:00
}
2019-02-20 09:13:33 -04:00
2019-09-01 19:16:12 -03:00
// internal i2c bus
2022-10-25 21:33:50 -03:00
# if !defined(HAL_SKIP_AUTO_INTERNAL_I2C_PROBE)
2019-09-01 19:16:12 -03:00
if ( all_external ) {
// only probe QMC5883L on internal if we are treating internals as externals
FOREACH_I2C_INTERNAL ( i ) {
ADD_BACKEND ( DRIVER_QMC5883L , AP_Compass_QMC5883L : : probe ( GET_I2C_DEVICE ( i , HAL_COMPASS_QMC5883L_I2C_ADDR ) ,
2020-02-15 02:30:10 -04:00
all_external ,
all_external ? HAL_COMPASS_QMC5883L_ORIENTATION_EXTERNAL : HAL_COMPASS_QMC5883L_ORIENTATION_INTERNAL ) ) ;
2019-09-01 19:16:12 -03:00
}
2018-07-13 06:56:24 -03:00
}
2020-08-23 17:04:55 -03:00
# endif
2023-02-19 21:05:13 -04:00
# endif // AP_COMPASS_QMC5883L_ENABLED
2019-02-20 09:13:33 -04:00
2023-11-11 00:00:55 -04:00
# if AP_COMPASS_QMC5883P_ENABLED
//external i2c bus
FOREACH_I2C_EXTERNAL ( i ) {
ADD_BACKEND ( DRIVER_QMC5883P , AP_Compass_QMC5883P : : probe ( GET_I2C_DEVICE ( i , HAL_COMPASS_QMC5883P_I2C_ADDR ) ,
true , HAL_COMPASS_QMC5883P_ORIENTATION_EXTERNAL ) ) ;
}
// internal i2c bus
# if !defined(HAL_SKIP_AUTO_INTERNAL_I2C_PROBE)
if ( all_external ) {
// only probe QMC5883P on internal if we are treating internals as externals
FOREACH_I2C_INTERNAL ( i ) {
ADD_BACKEND ( DRIVER_QMC5883P , AP_Compass_QMC5883P : : probe ( GET_I2C_DEVICE ( i , HAL_COMPASS_QMC5883P_I2C_ADDR ) ,
all_external ,
all_external ? HAL_COMPASS_QMC5883P_ORIENTATION_EXTERNAL : HAL_COMPASS_QMC5883P_ORIENTATION_INTERNAL ) ) ;
}
}
# endif
# endif // AP_COMPASS_QMC5883P_ENABLED
2019-11-17 22:59:23 -04:00
# ifndef HAL_BUILD_AP_PERIPH
2018-07-13 06:56:24 -03:00
// AK09916 on ICM20948
2023-02-19 21:05:07 -04:00
# if AP_COMPASS_AK09916_ENABLED && AP_COMPASS_ICM20948_ENABLED
2018-07-13 06:56:24 -03:00
FOREACH_I2C_EXTERNAL ( i ) {
2018-08-06 19:21:27 -03:00
ADD_BACKEND ( DRIVER_ICM20948 , AP_Compass_AK09916 : : probe_ICM20948 ( GET_I2C_DEVICE ( i , HAL_COMPASS_AK09916_I2C_ADDR ) ,
2020-02-15 02:30:10 -04:00
GET_I2C_DEVICE ( i , HAL_COMPASS_ICM20948_I2C_ADDR ) ,
true , ROTATION_PITCH_180_YAW_90 ) ) ;
2021-04-12 01:08:53 -03:00
ADD_BACKEND ( DRIVER_ICM20948 , AP_Compass_AK09916 : : probe_ICM20948 ( GET_I2C_DEVICE ( i , HAL_COMPASS_AK09916_I2C_ADDR ) ,
GET_I2C_DEVICE ( i , HAL_COMPASS_ICM20948_I2C_ADDR2 ) ,
true , ROTATION_PITCH_180_YAW_90 ) ) ;
2018-07-13 06:56:24 -03:00
}
2019-02-20 09:13:33 -04:00
2022-10-25 21:33:50 -03:00
# if !defined(HAL_SKIP_AUTO_INTERNAL_I2C_PROBE)
2018-07-13 06:56:24 -03:00
FOREACH_I2C_INTERNAL ( i ) {
2018-08-06 19:21:27 -03:00
ADD_BACKEND ( DRIVER_ICM20948 , AP_Compass_AK09916 : : probe_ICM20948 ( GET_I2C_DEVICE ( i , HAL_COMPASS_AK09916_I2C_ADDR ) ,
2020-02-15 02:30:10 -04:00
GET_I2C_DEVICE ( i , HAL_COMPASS_ICM20948_I2C_ADDR ) ,
all_external , ROTATION_PITCH_180_YAW_90 ) ) ;
2021-04-12 01:08:53 -03:00
ADD_BACKEND ( DRIVER_ICM20948 , AP_Compass_AK09916 : : probe_ICM20948 ( GET_I2C_DEVICE ( i , HAL_COMPASS_AK09916_I2C_ADDR ) ,
GET_I2C_DEVICE ( i , HAL_COMPASS_ICM20948_I2C_ADDR2 ) ,
all_external , ROTATION_PITCH_180_YAW_90 ) ) ;
2018-07-13 06:56:24 -03:00
}
2022-10-25 21:33:50 -03:00
# endif
2023-02-19 21:05:07 -04:00
# endif // AP_COMPASS_AK09916_ENABLED && AP_COMPASS_ICM20948_ENABLED
2019-11-17 22:59:23 -04:00
# endif // HAL_BUILD_AP_PERIPH
2019-03-05 08:22:03 -04:00
2023-02-15 07:53:48 -04:00
# if AP_COMPASS_LIS3MDL_ENABLED
2018-07-13 06:56:24 -03:00
// lis3mdl on bus 0 with default address
2022-10-25 21:33:50 -03:00
# if !defined(HAL_SKIP_AUTO_INTERNAL_I2C_PROBE)
2018-07-13 06:56:24 -03:00
FOREACH_I2C_INTERNAL ( i ) {
2018-08-06 19:21:27 -03:00
ADD_BACKEND ( DRIVER_LIS3MDL , AP_Compass_LIS3MDL : : probe ( GET_I2C_DEVICE ( i , HAL_COMPASS_LIS3MDL_I2C_ADDR ) ,
2020-02-15 02:30:10 -04:00
all_external , all_external ? ROTATION_YAW_90 : ROTATION_NONE ) ) ;
2018-07-13 06:56:24 -03:00
}
2019-02-20 09:13:33 -04:00
2018-07-13 06:56:24 -03:00
// lis3mdl on bus 0 with alternate address
FOREACH_I2C_INTERNAL ( i ) {
2018-08-06 19:21:27 -03:00
ADD_BACKEND ( DRIVER_LIS3MDL , AP_Compass_LIS3MDL : : probe ( GET_I2C_DEVICE ( i , HAL_COMPASS_LIS3MDL_I2C_ADDR2 ) ,
2020-02-15 02:30:10 -04:00
all_external , all_external ? ROTATION_YAW_90 : ROTATION_NONE ) ) ;
2018-07-13 06:56:24 -03:00
}
2022-10-25 21:33:50 -03:00
# endif
2018-07-13 06:56:24 -03:00
// external lis3mdl on bus 1 with default address
FOREACH_I2C_EXTERNAL ( i ) {
2018-08-06 19:21:27 -03:00
ADD_BACKEND ( DRIVER_LIS3MDL , AP_Compass_LIS3MDL : : probe ( GET_I2C_DEVICE ( i , HAL_COMPASS_LIS3MDL_I2C_ADDR ) ,
2020-02-15 02:30:10 -04:00
true , ROTATION_YAW_90 ) ) ;
2018-07-13 06:56:24 -03:00
}
2019-02-20 09:13:33 -04:00
2018-07-13 06:56:24 -03:00
// external lis3mdl on bus 1 with alternate address
FOREACH_I2C_EXTERNAL ( i ) {
2018-08-06 19:21:27 -03:00
ADD_BACKEND ( DRIVER_LIS3MDL , AP_Compass_LIS3MDL : : probe ( GET_I2C_DEVICE ( i , HAL_COMPASS_LIS3MDL_I2C_ADDR2 ) ,
2020-02-15 02:30:10 -04:00
true , ROTATION_YAW_90 ) ) ;
2018-07-13 06:56:24 -03:00
}
2023-02-15 07:53:48 -04:00
# endif // AP_COMPASS_LIS3MDL_ENABLED
2019-02-20 09:13:33 -04:00
2023-02-19 21:05:04 -04:00
# if AP_COMPASS_AK09916_ENABLED
2018-07-13 06:56:24 -03:00
// AK09916. This can be found twice, due to the ICM20948 i2c bus pass-thru, so we need to be careful to avoid that
FOREACH_I2C_EXTERNAL ( i ) {
2018-08-06 19:21:27 -03:00
ADD_BACKEND ( DRIVER_AK09916 , AP_Compass_AK09916 : : probe ( GET_I2C_DEVICE ( i , HAL_COMPASS_AK09916_I2C_ADDR ) ,
2020-02-15 02:30:10 -04:00
true , ROTATION_YAW_270 ) ) ;
2018-07-13 06:56:24 -03:00
}
2022-10-25 21:33:50 -03:00
# if !defined(HAL_SKIP_AUTO_INTERNAL_I2C_PROBE)
2018-07-13 06:56:24 -03:00
FOREACH_I2C_INTERNAL ( i ) {
2018-08-06 19:21:27 -03:00
ADD_BACKEND ( DRIVER_AK09916 , AP_Compass_AK09916 : : probe ( GET_I2C_DEVICE ( i , HAL_COMPASS_AK09916_I2C_ADDR ) ,
2020-02-15 02:30:10 -04:00
all_external , all_external ? ROTATION_YAW_270 : ROTATION_NONE ) ) ;
2018-07-13 06:56:24 -03:00
}
2020-08-23 17:04:55 -03:00
# endif
2023-02-19 21:05:04 -04:00
# endif // AP_COMPASS_AK09916_ENABLED
2019-02-20 09:13:33 -04:00
2023-02-09 21:48:02 -04:00
# if AP_COMPASS_IST8310_ENABLED
2018-07-13 06:56:24 -03:00
// IST8310 on external and internal bus
2019-02-06 17:09:52 -04:00
if ( AP_BoardConfig : : get_board_type ( ) ! = AP_BoardConfig : : PX4_BOARD_FMUV5 & &
AP_BoardConfig : : get_board_type ( ) ! = AP_BoardConfig : : PX4_BOARD_FMUV6 ) {
2023-08-02 03:39:34 -03:00
enum Rotation default_rotation = AP_COMPASS_IST8310_DEFAULT_ROTATION ;
2018-08-06 18:35:40 -03:00
if ( AP_BoardConfig : : get_board_type ( ) = = AP_BoardConfig : : PX4_BOARD_AEROFC ) {
default_rotation = ROTATION_PITCH_180_YAW_90 ;
}
2019-09-05 17:28:11 -03:00
// probe all 4 possible addresses
const uint8_t ist8310_addr [ ] = { 0x0C , 0x0D , 0x0E , 0x0F } ;
for ( uint8_t a = 0 ; a < ARRAY_SIZE ( ist8310_addr ) ; a + + ) {
FOREACH_I2C_EXTERNAL ( i ) {
ADD_BACKEND ( DRIVER_IST8310 , AP_Compass_IST8310 : : probe ( GET_I2C_DEVICE ( i , ist8310_addr [ a ] ) ,
2020-02-15 02:30:10 -04:00
true , default_rotation ) ) ;
2019-09-05 17:28:11 -03:00
}
2022-10-25 21:33:50 -03:00
# if !defined(HAL_COMPASS_DISABLE_IST8310_INTERNAL_PROBE) && !defined(HAL_SKIP_AUTO_INTERNAL_I2C_PROBE)
2019-09-05 17:28:11 -03:00
FOREACH_I2C_INTERNAL ( i ) {
ADD_BACKEND ( DRIVER_IST8310 , AP_Compass_IST8310 : : probe ( GET_I2C_DEVICE ( i , ist8310_addr [ a ] ) ,
2020-02-15 02:30:10 -04:00
all_external , default_rotation ) ) ;
2019-09-05 17:28:11 -03:00
}
2022-06-21 09:01:51 -03:00
# endif
2018-07-13 06:56:24 -03:00
}
}
2023-02-09 21:48:02 -04:00
# endif // AP_COMPASS_IST8310_ENABLED
2018-08-14 15:01:05 -03:00
2023-01-04 18:47:39 -04:00
# if AP_COMPASS_IST8308_ENABLED
2018-08-14 15:01:05 -03:00
// external i2c bus
FOREACH_I2C_EXTERNAL ( i ) {
ADD_BACKEND ( DRIVER_IST8308 , AP_Compass_IST8308 : : probe ( GET_I2C_DEVICE ( i , HAL_COMPASS_IST8308_I2C_ADDR ) ,
2020-02-15 02:30:10 -04:00
true , ROTATION_NONE ) ) ;
2018-08-14 15:01:05 -03:00
}
2022-10-25 21:33:50 -03:00
# if !defined(HAL_SKIP_AUTO_INTERNAL_I2C_PROBE)
2021-04-16 17:53:34 -03:00
FOREACH_I2C_INTERNAL ( i ) {
ADD_BACKEND ( DRIVER_IST8308 , AP_Compass_IST8308 : : probe ( GET_I2C_DEVICE ( i , HAL_COMPASS_IST8308_I2C_ADDR ) ,
all_external , ROTATION_NONE ) ) ;
}
2020-08-23 17:04:55 -03:00
# endif
2023-01-04 18:47:39 -04:00
# endif // AP_COMPASS_IST8308_ENABLED
2019-02-20 09:13:33 -04:00
2023-02-19 21:05:08 -04:00
# if AP_COMPASS_MMC3416_ENABLED
2021-06-15 05:56:24 -03:00
// external i2c bus
FOREACH_I2C_EXTERNAL ( i ) {
ADD_BACKEND ( DRIVER_MMC3416 , AP_Compass_MMC3416 : : probe ( GET_I2C_DEVICE ( i , HAL_COMPASS_MMC3416_I2C_ADDR ) ,
true , ROTATION_NONE ) ) ;
}
2022-10-25 21:33:50 -03:00
# if !defined(HAL_SKIP_AUTO_INTERNAL_I2C_PROBE)
2021-06-15 05:56:24 -03:00
FOREACH_I2C_INTERNAL ( i ) {
ADD_BACKEND ( DRIVER_MMC3416 , AP_Compass_MMC3416 : : probe ( GET_I2C_DEVICE ( i , HAL_COMPASS_MMC3416_I2C_ADDR ) ,
all_external , ROTATION_NONE ) ) ;
}
# endif
2023-02-19 21:05:08 -04:00
# endif // AP_COMPASS_MMC3416_ENABLED
2021-06-15 05:56:24 -03:00
2023-02-19 21:05:17 -04:00
# if AP_COMPASS_RM3100_ENABLED
2020-07-30 02:29:55 -03:00
# ifdef HAL_COMPASS_RM3100_I2C_ADDR
const uint8_t rm3100_addresses [ ] = { HAL_COMPASS_RM3100_I2C_ADDR } ;
# else
// RM3100 can be on 4 different addresses
const uint8_t rm3100_addresses [ ] = { HAL_COMPASS_RM3100_I2C_ADDR1 ,
HAL_COMPASS_RM3100_I2C_ADDR2 ,
HAL_COMPASS_RM3100_I2C_ADDR3 ,
HAL_COMPASS_RM3100_I2C_ADDR4 } ;
# endif
2019-02-20 09:13:33 -04:00
// external i2c bus
FOREACH_I2C_EXTERNAL ( i ) {
2020-07-30 02:29:55 -03:00
for ( uint8_t j = 0 ; j < ARRAY_SIZE ( rm3100_addresses ) ; j + + ) {
ADD_BACKEND ( DRIVER_RM3100 , AP_Compass_RM3100 : : probe ( GET_I2C_DEVICE ( i , rm3100_addresses [ j ] ) , true , ROTATION_NONE ) ) ;
}
2019-02-20 09:13:33 -04:00
}
2020-08-23 17:04:55 -03:00
2022-10-25 21:33:50 -03:00
# if !defined(HAL_SKIP_AUTO_INTERNAL_I2C_PROBE)
2019-02-20 09:13:33 -04:00
FOREACH_I2C_INTERNAL ( i ) {
2020-07-30 02:29:55 -03:00
for ( uint8_t j = 0 ; j < ARRAY_SIZE ( rm3100_addresses ) ; j + + ) {
ADD_BACKEND ( DRIVER_RM3100 , AP_Compass_RM3100 : : probe ( GET_I2C_DEVICE ( i , rm3100_addresses [ j ] ) , all_external , ROTATION_NONE ) ) ;
}
2019-02-20 09:13:33 -04:00
}
2020-08-23 17:04:55 -03:00
# endif
2023-02-19 21:05:17 -04:00
# endif // AP_COMPASS_RM3100_ENABLED
2020-12-16 19:16:36 -04:00
2023-02-07 19:48:11 -04:00
# if AP_COMPASS_BMM150_DETECT_BACKENDS_ENABLED
2023-02-07 18:55:11 -04:00
// BMM150 on I2C
2020-12-16 19:16:36 -04:00
FOREACH_I2C_EXTERNAL ( i ) {
for ( uint8_t addr = BMM150_I2C_ADDR_MIN ; addr < = BMM150_I2C_ADDR_MAX ; addr + + ) {
ADD_BACKEND ( DRIVER_BMM150 ,
2020-12-16 21:16:59 -04:00
AP_Compass_BMM150 : : probe ( GET_I2C_DEVICE ( i , addr ) , true , ROTATION_NONE ) ) ;
2020-12-16 19:16:36 -04:00
}
}
2023-02-07 18:55:11 -04:00
# endif // AP_COMPASS_BMM150_ENABLED
2024-09-11 06:10:44 -03:00
# if AP_COMPASS_BMM350_ENABLED
// BMM350 on I2C
FOREACH_I2C_EXTERNAL ( i ) {
for ( uint8_t addr = BMM350_I2C_ADDR_MIN ; addr < = BMM350_I2C_ADDR_MAX ; addr + + ) {
ADD_BACKEND ( DRIVER_BMM350 ,
AP_Compass_BMM350 : : probe ( GET_I2C_DEVICE ( i , addr ) , true , ROTATION_NONE ) ) ;
}
}
# if !defined(HAL_SKIP_AUTO_INTERNAL_I2C_PROBE)
FOREACH_I2C_INTERNAL ( i ) {
for ( uint8_t addr = BMM350_I2C_ADDR_MIN ; addr < = BMM350_I2C_ADDR_MAX ; addr + + ) {
ADD_BACKEND ( DRIVER_BMM350 , AP_Compass_BMM350 : : probe ( GET_I2C_DEVICE ( i , addr ) , all_external , ROTATION_NONE ) ) ;
}
}
# endif
# endif // AP_COMPASS_BMM350_ENABLED
2018-07-13 06:56:24 -03:00
}
2014-11-15 21:58:23 -04:00
/*
detect available backends for this board
*/
2015-08-05 17:02:32 -03:00
void Compass : : _detect_backends ( void )
2014-11-15 21:58:23 -04:00
{
2022-10-26 06:21:36 -03:00
# if AP_COMPASS_EXTERNALAHRS_ENABLED
2023-01-24 00:40:17 -04:00
const int8_t serial_port = AP : : externalAHRS ( ) . get_port ( AP_ExternalAHRS : : AvailableSensor : : COMPASS ) ;
2021-08-10 19:29:32 -03:00
if ( serial_port > = 0 ) {
2024-05-26 22:24:10 -03:00
ADD_BACKEND ( DRIVER_EXTERNALAHRS , NEW_NOTHROW AP_Compass_ExternalAHRS ( serial_port ) ) ;
2020-12-28 01:26:18 -04:00
}
# endif
2018-01-10 06:34:13 -04:00
# if AP_FEATURE_BOARD_DETECT
2017-06-18 04:26:25 -03:00
if ( AP_BoardConfig : : get_board_type ( ) = = AP_BoardConfig : : PX4_BOARD_PIXHAWK2 ) {
// default to disabling LIS3MDL on pixhawk2 due to hardware issue
2023-02-15 07:53:48 -04:00
# if AP_COMPASS_LIS3MDL_ENABLED
_driver_type_mask . set_default ( 1U < < DRIVER_LIS3MDL ) ;
# endif
2017-06-18 04:26:25 -03:00
}
# endif
2020-02-15 02:30:10 -04:00
2023-01-03 22:04:50 -04:00
# if AP_COMPASS_SITL_ENABLED && !AP_TEST_DRONECAN_DRIVERS
2024-05-26 22:24:10 -03:00
ADD_BACKEND ( DRIVER_SITL , NEW_NOTHROW AP_Compass_SITL ( ) ) ;
2017-06-21 14:39:07 -03:00
# endif
2018-07-13 06:56:24 -03:00
2023-10-27 21:33:07 -03:00
# if AP_COMPASS_DRONECAN_ENABLED
// probe DroneCAN before I2C and SPI so that DroneCAN compasses
// default to first in the list for a new board
probe_dronecan_compasses ( ) ;
CHECK_UNREG_LIMIT_RETURN ;
# endif
2018-07-13 06:56:24 -03:00
# ifdef HAL_PROBE_EXTERNAL_I2C_COMPASSES
// allow boards to ask for external probing of all i2c compass types in hwdef.dat
_probe_external_i2c_compasses ( ) ;
2020-03-25 06:33:40 -03:00
CHECK_UNREG_LIMIT_RETURN ;
2018-07-13 06:56:24 -03:00
# endif
2019-05-29 08:01:33 -03:00
2022-10-26 06:21:36 -03:00
# if AP_COMPASS_MSP_ENABLED
2020-09-03 19:11:05 -03:00
for ( uint8_t i = 0 ; i < 8 ; i + + ) {
if ( msp_instance_mask & ( 1U < < i ) ) {
2024-05-26 22:24:10 -03:00
ADD_BACKEND ( DRIVER_MSP , NEW_NOTHROW AP_Compass_MSP ( i ) ) ;
2020-09-03 19:11:05 -03:00
}
}
# endif
2023-10-27 21:33:07 -03:00
// finally look for i2c and spi compasses not found yet
CHECK_UNREG_LIMIT_RETURN ;
2023-10-27 21:26:12 -03:00
probe_i2c_spi_compasses ( ) ;
if ( _backend_count = = 0 | |
_compass_count = = 0 ) {
DEV_PRINTF ( " No Compass backends available \n " ) ;
}
}
/*
probe i2c and SPI compasses
*/
void Compass : : probe_i2c_spi_compasses ( void )
{
2019-05-29 08:01:33 -03:00
# if defined(HAL_MAG_PROBE_LIST)
// driver probes defined by COMPASS lines in hwdef.dat
HAL_MAG_PROBE_LIST ;
2018-01-10 06:34:13 -04:00
# elif AP_FEATURE_BOARD_DETECT
2016-12-19 13:10:47 -04:00
switch ( AP_BoardConfig : : get_board_type ( ) ) {
case AP_BoardConfig : : PX4_BOARD_PX4V1 :
case AP_BoardConfig : : PX4_BOARD_PIXHAWK :
case AP_BoardConfig : : PX4_BOARD_PHMINI :
2017-02-28 21:42:23 -04:00
case AP_BoardConfig : : PX4_BOARD_AUAV21 :
2016-12-19 13:10:47 -04:00
case AP_BoardConfig : : PX4_BOARD_PH2SLIM :
case AP_BoardConfig : : PX4_BOARD_PIXHAWK2 :
2019-05-29 08:01:33 -03:00
case AP_BoardConfig : : PX4_BOARD_MINDPXV2 :
2018-05-29 08:49:40 -03:00
case AP_BoardConfig : : PX4_BOARD_FMUV5 :
2019-02-06 17:09:52 -04:00
case AP_BoardConfig : : PX4_BOARD_FMUV6 :
2018-07-13 06:56:24 -03:00
case AP_BoardConfig : : PX4_BOARD_PIXHAWK_PRO :
2018-08-06 18:35:40 -03:00
case AP_BoardConfig : : PX4_BOARD_AEROFC :
2018-07-13 06:56:24 -03:00
_probe_external_i2c_compasses ( ) ;
2020-03-25 06:33:40 -03:00
CHECK_UNREG_LIMIT_RETURN ;
2016-12-19 13:10:47 -04:00
break ;
2017-06-21 04:03:13 -03:00
case AP_BoardConfig : : PX4_BOARD_PCNC1 :
2023-02-07 18:55:11 -04:00
# if AP_COMPASS_BMM150_ENABLED
2017-06-21 04:03:13 -03:00
ADD_BACKEND ( DRIVER_BMM150 ,
2020-12-16 21:16:59 -04:00
AP_Compass_BMM150 : : probe ( GET_I2C_DEVICE ( 0 , 0x10 ) , false , ROTATION_NONE ) ) ;
2023-02-07 18:55:11 -04:00
# endif
2017-06-21 04:03:13 -03:00
break ;
2019-04-16 18:13:33 -03:00
case AP_BoardConfig : : VRX_BOARD_BRAIN54 :
case AP_BoardConfig : : VRX_BOARD_BRAIN51 : {
2023-01-29 19:33:08 -04:00
# if AP_COMPASS_HMC5843_ENABLED
2018-02-03 09:56:02 -04:00
// external i2c bus
2019-05-29 07:57:28 -03:00
ADD_BACKEND ( DRIVER_HMC5843 , AP_Compass_HMC5843 : : probe ( GET_I2C_DEVICE ( 1 , HAL_COMPASS_HMC5843_I2C_ADDR ) ,
2020-02-15 02:30:10 -04:00
true , ROTATION_ROLL_180 ) ) ;
2019-04-16 18:13:33 -03:00
2018-02-03 09:56:02 -04:00
// internal i2c bus
2019-04-16 18:13:33 -03:00
ADD_BACKEND ( DRIVER_HMC5843 , AP_Compass_HMC5843 : : probe ( GET_I2C_DEVICE ( 0 , HAL_COMPASS_HMC5843_I2C_ADDR ) ,
false , ROTATION_YAW_270 ) ) ;
2023-01-29 19:33:08 -04:00
# endif // AP_COMPASS_HMC5843_ENABLED
2019-04-16 18:13:33 -03:00
}
2020-02-15 02:30:10 -04:00
break ;
2018-02-03 09:56:02 -04:00
case AP_BoardConfig : : VRX_BOARD_BRAIN52 :
case AP_BoardConfig : : VRX_BOARD_BRAIN52E :
case AP_BoardConfig : : VRX_BOARD_CORE10 :
case AP_BoardConfig : : VRX_BOARD_UBRAIN51 :
case AP_BoardConfig : : VRX_BOARD_UBRAIN52 : {
2023-01-29 19:33:08 -04:00
# if AP_COMPASS_HMC5843_ENABLED
2018-02-03 09:56:02 -04:00
// external i2c bus
2019-05-29 07:57:28 -03:00
ADD_BACKEND ( DRIVER_HMC5843 , AP_Compass_HMC5843 : : probe ( GET_I2C_DEVICE ( 1 , HAL_COMPASS_HMC5843_I2C_ADDR ) ,
2020-02-15 02:30:10 -04:00
true , ROTATION_ROLL_180 ) ) ;
2023-01-29 19:33:08 -04:00
# endif // AP_COMPASS_HMC5843_ENABLED
2020-02-15 02:30:10 -04:00
}
break ;
2018-02-03 09:56:02 -04:00
2016-12-19 13:10:47 -04:00
default :
break ;
2016-11-09 06:19:24 -04:00
}
2016-12-19 13:10:47 -04:00
switch ( AP_BoardConfig : : get_board_type ( ) ) {
case AP_BoardConfig : : PX4_BOARD_PIXHAWK :
2023-01-29 19:33:08 -04:00
# if AP_COMPASS_HMC5843_ENABLED
2019-05-29 07:57:28 -03:00
ADD_BACKEND ( DRIVER_HMC5843 , AP_Compass_HMC5843 : : probe ( hal . spi - > get_device ( HAL_COMPASS_HMC5843_NAME ) ,
2020-02-15 02:30:10 -04:00
false , ROTATION_PITCH_180 ) ) ;
2023-01-29 19:33:08 -04:00
# endif
2023-01-27 00:09:50 -04:00
# if AP_COMPASS_LSM303D_ENABLED
2019-09-01 19:30:57 -03:00
ADD_BACKEND ( DRIVER_LSM303D , AP_Compass_LSM303D : : probe ( hal . spi - > get_device ( HAL_INS_LSM9DS0_A_NAME ) , ROTATION_NONE ) ) ;
2023-01-27 00:09:50 -04:00
# endif
2016-12-19 13:10:47 -04:00
break ;
case AP_BoardConfig : : PX4_BOARD_PIXHAWK2 :
2023-01-27 00:09:50 -04:00
# if AP_COMPASS_LSM303D_ENABLED
2018-08-06 20:08:09 -03:00
ADD_BACKEND ( DRIVER_LSM303D , AP_Compass_LSM303D : : probe ( hal . spi - > get_device ( HAL_INS_LSM9DS0_EXT_A_NAME ) , ROTATION_YAW_270 ) ) ;
2023-01-27 00:09:50 -04:00
# endif
2023-02-01 08:53:43 -04:00
# if AP_COMPASS_AK8963_ENABLED
2016-11-09 22:05:22 -04:00
// we run the AK8963 only on the 2nd MPU9250, which leaves the
// first MPU9250 to run without disturbance at high rate
2018-08-06 20:08:09 -03:00
ADD_BACKEND ( DRIVER_AK8963 , AP_Compass_AK8963 : : probe_mpu9250 ( 1 , ROTATION_YAW_270 ) ) ;
2023-02-01 08:53:43 -04:00
# endif
2023-02-19 21:05:07 -04:00
# if AP_COMPASS_AK09916_ENABLED && AP_COMPASS_ICM20948_ENABLED
2019-04-08 07:37:43 -03:00
ADD_BACKEND ( DRIVER_AK09916 , AP_Compass_AK09916 : : probe_ICM20948 ( 0 , ROTATION_ROLL_180_YAW_90 ) ) ;
2023-02-19 21:05:04 -04:00
# endif
2016-12-19 13:10:47 -04:00
break ;
2018-05-29 08:49:40 -03:00
case AP_BoardConfig : : PX4_BOARD_FMUV5 :
2019-02-06 17:09:52 -04:00
case AP_BoardConfig : : PX4_BOARD_FMUV6 :
2023-02-09 21:48:02 -04:00
# if AP_COMPASS_IST8310_ENABLED
2018-07-10 03:09:16 -03:00
FOREACH_I2C_EXTERNAL ( i ) {
2018-08-06 19:21:27 -03:00
ADD_BACKEND ( DRIVER_IST8310 , AP_Compass_IST8310 : : probe ( GET_I2C_DEVICE ( i , HAL_COMPASS_IST8310_I2C_ADDR ) ,
2020-02-15 02:30:10 -04:00
true , ROTATION_ROLL_180_YAW_90 ) ) ;
2018-07-10 03:09:16 -03:00
}
FOREACH_I2C_INTERNAL ( i ) {
2018-08-06 19:21:27 -03:00
ADD_BACKEND ( DRIVER_IST8310 , AP_Compass_IST8310 : : probe ( GET_I2C_DEVICE ( i , HAL_COMPASS_IST8310_I2C_ADDR ) ,
2020-02-15 02:30:10 -04:00
false , ROTATION_ROLL_180_YAW_90 ) ) ;
2018-07-10 03:09:16 -03:00
}
2023-02-09 21:48:02 -04:00
# endif // AP_COMPASS_IST8310_ENABLED
2018-05-29 08:49:40 -03:00
break ;
2020-02-15 02:30:10 -04:00
2018-02-14 01:35:51 -04:00
case AP_BoardConfig : : PX4_BOARD_SP01 :
2023-02-01 08:53:43 -04:00
# if AP_COMPASS_AK8963_ENABLED
2018-08-06 20:08:09 -03:00
ADD_BACKEND ( DRIVER_AK8963 , AP_Compass_AK8963 : : probe_mpu9250 ( 1 , ROTATION_NONE ) ) ;
2023-02-01 08:53:43 -04:00
# endif
2018-02-14 01:35:51 -04:00
break ;
2020-02-15 02:30:10 -04:00
2017-07-15 02:13:44 -03:00
case AP_BoardConfig : : PX4_BOARD_PIXHAWK_PRO :
2023-02-01 08:53:43 -04:00
# if AP_COMPASS_AK8963_ENABLED
2018-08-06 20:08:09 -03:00
ADD_BACKEND ( DRIVER_AK8963 , AP_Compass_AK8963 : : probe_mpu9250 ( 0 , ROTATION_ROLL_180_YAW_90 ) ) ;
2023-02-01 08:53:43 -04:00
# endif
2023-02-15 07:53:48 -04:00
# if AP_COMPASS_LIS3MDL_ENABLED
2018-08-06 19:21:27 -03:00
ADD_BACKEND ( DRIVER_LIS3MDL , AP_Compass_LIS3MDL : : probe ( hal . spi - > get_device ( HAL_COMPASS_LIS3MDL_NAME ) ,
2020-02-15 02:30:10 -04:00
false , ROTATION_NONE ) ) ;
2023-02-15 07:53:48 -04:00
# endif // AP_COMPASS_LIS3MDL_ENABLED
2016-12-19 13:10:47 -04:00
break ;
case AP_BoardConfig : : PX4_BOARD_PHMINI :
2023-02-01 08:53:43 -04:00
# if AP_COMPASS_AK8963_ENABLED
2018-08-06 20:08:09 -03:00
ADD_BACKEND ( DRIVER_AK8963 , AP_Compass_AK8963 : : probe_mpu9250 ( 0 , ROTATION_ROLL_180 ) ) ;
2023-02-01 08:53:43 -04:00
# endif
2016-12-19 13:10:47 -04:00
break ;
2017-02-28 21:42:23 -04:00
case AP_BoardConfig : : PX4_BOARD_AUAV21 :
2023-02-01 08:53:43 -04:00
# if AP_COMPASS_AK8963_ENABLED
2018-08-06 20:08:09 -03:00
ADD_BACKEND ( DRIVER_AK8963 , AP_Compass_AK8963 : : probe_mpu9250 ( 0 , ROTATION_ROLL_180_YAW_90 ) ) ;
2023-02-01 08:53:43 -04:00
# endif
2017-02-28 21:42:23 -04:00
break ;
2020-02-15 02:30:10 -04:00
2016-12-19 13:10:47 -04:00
case AP_BoardConfig : : PX4_BOARD_PH2SLIM :
2023-02-01 08:53:43 -04:00
# if AP_COMPASS_AK8963_ENABLED
2018-08-06 20:08:09 -03:00
ADD_BACKEND ( DRIVER_AK8963 , AP_Compass_AK8963 : : probe_mpu9250 ( 0 , ROTATION_YAW_270 ) ) ;
2023-02-01 08:53:43 -04:00
# endif
2016-12-19 13:10:47 -04:00
break ;
2018-01-11 21:16:53 -04:00
case AP_BoardConfig : : PX4_BOARD_MINDPXV2 :
2023-01-29 19:33:08 -04:00
# if AP_COMPASS_HMC5843_ENABLED
2019-05-29 07:57:28 -03:00
ADD_BACKEND ( DRIVER_HMC5843 , AP_Compass_HMC5843 : : probe ( GET_I2C_DEVICE ( 0 , HAL_COMPASS_HMC5843_I2C_ADDR ) ,
2020-02-15 02:30:10 -04:00
false , ROTATION_YAW_90 ) ) ;
2023-01-29 19:33:08 -04:00
# endif
2023-01-27 00:09:50 -04:00
# if AP_COMPASS_LSM303D_ENABLED
2018-08-06 20:08:09 -03:00
ADD_BACKEND ( DRIVER_LSM303D , AP_Compass_LSM303D : : probe ( hal . spi - > get_device ( HAL_INS_LSM9DS0_A_NAME ) , ROTATION_PITCH_180_YAW_270 ) ) ;
2023-01-27 00:09:50 -04:00
# endif
2018-01-11 21:16:53 -04:00
break ;
2020-02-15 02:30:10 -04:00
2016-12-19 13:10:47 -04:00
default :
break ;
2016-11-09 06:19:24 -04:00
}
2014-11-15 21:58:23 -04:00
# endif
2023-10-27 21:26:12 -03:00
}
2018-02-28 03:09:04 -04:00
2023-04-08 00:58:13 -03:00
# if AP_COMPASS_DRONECAN_ENABLED
2023-10-27 21:26:12 -03:00
/*
look for DroneCAN compasses
*/
void Compass : : probe_dronecan_compasses ( void )
{
if ( ! _driver_enabled ( DRIVER_UAVCAN ) ) {
return ;
}
for ( uint8_t i = 0 ; i < COMPASS_MAX_BACKEND ; i + + ) {
AP_Compass_Backend * _uavcan_backend = AP_Compass_DroneCAN : : probe ( i ) ;
if ( _uavcan_backend ) {
_add_backend ( _uavcan_backend ) ;
}
2020-07-20 18:25:08 -03:00
# if COMPASS_MAX_UNREG_DEV > 0
2023-10-27 21:26:12 -03:00
if ( _unreg_compass_count = = COMPASS_MAX_UNREG_DEV ) {
break ;
2020-07-20 18:25:08 -03:00
}
2023-10-27 21:26:12 -03:00
# endif
}
2020-07-20 18:25:08 -03:00
# if COMPASS_MAX_UNREG_DEV > 0
2023-10-27 21:26:12 -03:00
if ( option_set ( Option : : ALLOW_DRONECAN_AUTO_REPLACEMENT ) & & ! suppress_devid_save ) {
// 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 < COMPASS_MAX_INSTANCES ; i + + ) {
if ( AP_HAL : : Device : : devid_get_bus_type ( _priority_did_list [ i ] ) ! = AP_HAL : : Device : : BUS_TYPE_UAVCAN
| | _get_state ( i ) . registered ) {
continue ;
}
// There's a UAVCAN compass missing
// Let's check if there's a replacement
for ( uint8_t j = 0 ; j < COMPASS_MAX_INSTANCES ; j + + ) {
uint32_t detected_devid = AP_Compass_DroneCAN : : get_detected_devid ( j ) ;
// Check if this is a potential replacement mag
if ( ! is_replacement_mag ( detected_devid ) ) {
2020-07-20 18:25:08 -03:00
continue ;
}
2023-10-27 21:26:12 -03:00
// We have found a replacement mag, let's replace the existing one
// with this by setting the priority to zero and calling uavcan probe
2024-08-07 00:17:20 -03:00
GCS_SEND_TEXT ( MAV_SEVERITY_ALERT , " Mag: Compass #%d with DEVID %lu replaced " , uint8_t ( i ) , ( unsigned long ) _priority_did_list [ i ] ) ;
2023-10-27 21:26:12 -03:00
_priority_did_stored_list [ i ] . set_and_save ( 0 ) ;
_priority_did_list [ i ] = 0 ;
AP_Compass_Backend * _uavcan_backend = AP_Compass_DroneCAN : : probe ( j ) ;
if ( _uavcan_backend ) {
_add_backend ( _uavcan_backend ) ;
// we also need to remove the id from unreg list
remove_unreg_dev_id ( detected_devid ) ;
} else {
// the mag has already been allocated,
// let's begin the replacement
bool found_replacement = false ;
for ( StateIndex k ( 0 ) ; k < COMPASS_MAX_INSTANCES ; k + + ) {
if ( ( uint32_t ) _state [ k ] . dev_id = = detected_devid ) {
if ( _state [ k ] . priority < = uint8_t ( i ) ) {
// we are already on higher priority
// nothing to do
break ;
2020-07-20 18:25:08 -03:00
}
2023-10-27 21:26:12 -03:00
found_replacement = true ;
// reset old priority of replacement mag
_priority_did_stored_list [ _state [ k ] . priority ] . set_and_save ( 0 ) ;
_priority_did_list [ _state [ k ] . priority ] = 0 ;
// update new priority
_state [ k ] . priority = i ;
2020-07-20 18:25:08 -03:00
}
}
2023-10-27 21:26:12 -03:00
if ( ! found_replacement ) {
continue ;
}
_priority_did_stored_list [ i ] . set_and_save ( detected_devid ) ;
_priority_did_list [ i ] = detected_devid ;
2020-07-20 18:25:08 -03:00
}
}
2019-11-20 03:18:10 -04:00
}
2017-06-18 04:26:25 -03:00
}
2023-10-27 21:26:12 -03:00
# endif // #if COMPASS_MAX_UNREG_DEV > 0
}
2023-04-08 00:58:13 -03:00
# endif // AP_COMPASS_DRONECAN_ENABLED
2017-06-18 04:26:25 -03:00
2014-11-15 21:58:23 -04:00
2020-07-20 18:25:08 -03:00
// Check if the devid is a potential replacement compass
// Following are the checks done to ensure the compass is a replacement
// * The compass is an UAVCAN compass
// * The compass wasn't seen before this boot as additional unreg mag
// * The compass might have been seen before but never setup
bool Compass : : is_replacement_mag ( uint32_t devid ) {
# if COMPASS_MAX_INSTANCES > 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 ;
}
2021-06-05 21:51:03 -03:00
# if COMPASS_MAX_UNREG_DEV > 0
2020-07-20 18:25:08 -03:00
// Check that its not an unused additional mag
for ( uint8_t i = 0 ; i < COMPASS_MAX_UNREG_DEV ; i + + ) {
if ( _previously_unreg_mag [ i ] = = devid ) {
return false ;
}
}
2021-06-05 21:51:03 -03:00
# endif
2020-07-20 18:25:08 -03:00
// Check that its not previously setup mag
for ( StateIndex i ( 0 ) ; i < COMPASS_MAX_INSTANCES ; i + + ) {
if ( ( uint32_t ) _state [ i ] . expected_dev_id = = devid ) {
return false ;
}
}
# endif
return true ;
}
void Compass : : remove_unreg_dev_id ( uint32_t devid )
{
# if COMPASS_MAX_INSTANCES > 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 ;
}
2021-06-05 21:51:03 -03:00
# if COMPASS_MAX_UNREG_DEV > 0
2020-07-20 18:25:08 -03:00
for ( uint8_t i = 0 ; i < COMPASS_MAX_UNREG_DEV ; i + + ) {
if ( ( uint32_t ) extra_dev_id [ i ] = = devid ) {
2023-09-20 20:03:24 -03:00
extra_dev_id [ i ] . set ( 0 ) ;
2020-07-20 18:25:08 -03:00
return ;
}
}
# endif
2021-06-05 21:51:03 -03:00
# endif
2020-07-20 18:25:08 -03:00
}
void Compass : : _reset_compass_id ( )
{
# if COMPASS_MAX_INSTANCES > 1
// Check if any of the registered devs are not registered
for ( Priority i ( 0 ) ; i < COMPASS_MAX_INSTANCES ; i + + ) {
if ( _priority_did_stored_list [ i ] ! = _priority_did_list [ i ] | |
_priority_did_stored_list [ i ] = = 0 ) {
//We don't touch priorities that might have been touched by the user
continue ;
}
if ( ! _get_state ( i ) . registered ) {
_priority_did_stored_list [ i ] . set_and_save ( 0 ) ;
2021-06-05 21:51:03 -03:00
GCS_SEND_TEXT ( MAV_SEVERITY_ALERT , " Mag: Compass #%d with DEVID %lu removed " , uint8_t ( i ) , ( unsigned long ) _priority_did_list [ i ] ) ;
2020-07-20 18:25:08 -03:00
}
}
// Check if any of the old registered devs are not registered
// and hence can be removed
for ( StateIndex i ( 0 ) ; i < COMPASS_MAX_INSTANCES ; i + + ) {
2021-12-04 00:22:56 -04:00
if ( _state [ i ] . dev_id = = 0 & & _state [ i ] . expected_dev_id ! = 0 ) {
2020-07-20 18:25:08 -03:00
// also hard reset dev_ids that are not detected
2021-12-04 00:22:56 -04:00
_state [ i ] . dev_id . save ( ) ;
2020-07-20 18:25:08 -03:00
}
}
# endif
}
2019-11-20 03:18:10 -04:00
// Look for devices beyond initialisation
void
Compass : : _detect_runtime ( void )
{
2023-04-08 00:58:13 -03:00
# if AP_COMPASS_DRONECAN_ENABLED
2021-07-27 02:50:24 -03:00
if ( ! available ( ) ) {
return ;
}
2019-11-20 03:18:10 -04:00
//Don't try to add device while armed
if ( hal . util - > get_soft_armed ( ) ) {
return ;
}
static uint32_t last_try ;
//Try once every second
if ( ( AP_HAL : : millis ( ) - last_try ) < 1000 ) {
return ;
}
last_try = AP_HAL : : millis ( ) ;
if ( _driver_enabled ( DRIVER_UAVCAN ) ) {
for ( uint8_t i = 0 ; i < COMPASS_MAX_BACKEND ; i + + ) {
2023-04-08 01:09:10 -03:00
AP_Compass_Backend * _uavcan_backend = AP_Compass_DroneCAN : : probe ( i ) ;
2019-11-20 03:18:10 -04:00
if ( _uavcan_backend ) {
_add_backend ( _uavcan_backend ) ;
}
2020-03-25 06:33:40 -03:00
CHECK_UNREG_LIMIT_RETURN ;
2019-11-20 03:18:10 -04:00
}
}
2023-04-08 00:58:13 -03:00
# endif // AP_COMPASS_DRONECAN_ENABLED
2019-11-20 03:18:10 -04:00
}
2016-03-01 15:16:04 -04:00
bool
2014-11-15 21:58:23 -04:00
Compass : : read ( void )
{
2021-07-27 02:50:24 -03:00
if ( ! available ( ) ) {
return false ;
}
2022-05-02 22:50:34 -03:00
# if HAL_LOGGING_ENABLED
const bool old_healthy = healthy ( ) ;
# endif
2019-05-26 22:49:12 -03:00
# ifndef HAL_BUILD_AP_PERIPH
2019-03-27 04:01:18 -03:00
if ( ! _initial_location_set ) {
try_set_initial_location ( ) ;
}
2019-05-26 22:49:12 -03:00
# endif
2019-11-20 03:18:10 -04:00
_detect_runtime ( ) ;
2015-02-23 19:17:44 -04:00
for ( uint8_t i = 0 ; i < _backend_count ; i + + ) {
2014-11-15 21:58:23 -04:00
// call read on each of the backend. This call updates field[i]
_backends [ i ] - > read ( ) ;
2016-03-01 15:16:04 -04:00
}
2017-09-05 22:58:35 -03:00
uint32_t time = AP_HAL : : millis ( ) ;
2020-08-28 01:08:48 -03:00
bool any_healthy = false ;
2019-11-20 03:18:10 -04:00
for ( StateIndex i ( 0 ) ; i < COMPASS_MAX_INSTANCES ; i + + ) {
2017-09-05 22:58:35 -03:00
_state [ i ] . healthy = ( time - _state [ i ] . last_update_ms < 500 ) ;
2020-08-28 01:08:48 -03:00
any_healthy | = _state [ i ] . healthy ;
2015-03-13 02:43:34 -03:00
}
2019-05-26 22:49:12 -03:00
# if COMPASS_LEARN_ENABLED
2018-10-19 02:07:53 -03:00
if ( _learn = = LEARN_INFLIGHT & & ! learn_allocated ) {
learn_allocated = true ;
2024-05-26 22:24:10 -03:00
learn = NEW_NOTHROW CompassLearn ( * this ) ;
2018-10-19 02:07:53 -03:00
}
if ( _learn = = LEARN_INFLIGHT & & learn ! = nullptr ) {
learn - > update ( ) ;
}
2020-08-28 01:08:48 -03:00
# endif
2021-05-17 03:51:35 -03:00
# if HAL_LOGGING_ENABLED
2020-11-07 01:58:05 -04:00
if ( any_healthy & & _log_bit ! = ( uint32_t ) - 1 & & AP : : logger ( ) . should_log ( _log_bit ) ) {
2019-03-25 09:42:34 -03:00
AP : : logger ( ) . Write_Compass ( ) ;
}
2019-05-26 22:49:12 -03:00
# endif
2021-03-31 11:04:57 -03:00
// Set _first_usable parameter
for ( Priority i ( 0 ) ; i < COMPASS_MAX_INSTANCES ; i + + ) {
2021-12-04 00:22:56 -04:00
if ( _use_for_yaw [ i ] ) {
2021-03-31 11:04:57 -03:00
_first_usable = uint8_t ( i ) ;
break ;
}
}
2022-05-02 22:50:34 -03:00
const bool new_healthy = healthy ( ) ;
# if HAL_LOGGING_ENABLED
# define MASK_LOG_ANY 0xFFFF
if ( new_healthy ! = old_healthy ) {
if ( AP : : logger ( ) . should_log ( MASK_LOG_ANY ) ) {
const LogErrorCode code = new_healthy ? LogErrorCode : : ERROR_RESOLVED : LogErrorCode : : UNHEALTHY ;
AP : : logger ( ) . Write_Error ( LogErrorSubsystem : : COMPASS , code ) ;
}
}
# endif
return new_healthy ;
2014-11-15 21:58:23 -04:00
}
2015-03-18 20:42:30 -03:00
uint8_t
Compass : : get_healthy_mask ( ) const
{
uint8_t healthy_mask = 0 ;
2020-02-15 02:30:10 -04:00
for ( Priority i ( 0 ) ; i < COMPASS_MAX_INSTANCES ; i + + ) {
if ( healthy ( uint8_t ( i ) ) ) {
2019-11-20 03:18:10 -04:00
healthy_mask | = 1 < < uint8_t ( i ) ;
2015-03-18 20:42:30 -03:00
}
}
return healthy_mask ;
}
2014-10-14 19:16:31 -03:00
void
Compass : : set_offsets ( uint8_t i , const Vector3f & offsets )
{
// sanity check compass instance provided
2019-11-20 03:18:10 -04:00
StateIndex id = _get_state_id ( Priority ( i ) ) ;
2020-02-15 02:30:10 -04:00
if ( id < COMPASS_MAX_INSTANCES ) {
2021-12-04 00:22:56 -04:00
_state [ id ] . offset . set ( offsets ) ;
2014-10-14 19:16:31 -03:00
}
}
2011-02-14 00:25:20 -04:00
void
2014-07-09 05:09:02 -03:00
Compass : : set_and_save_offsets ( uint8_t i , const Vector3f & offsets )
2011-02-14 00:25:20 -04:00
{
2014-07-10 02:37:27 -03:00
// sanity check compass instance provided
2019-11-20 03:18:10 -04:00
StateIndex id = _get_state_id ( Priority ( i ) ) ;
2020-02-15 02:30:10 -04:00
if ( id < COMPASS_MAX_INSTANCES ) {
2021-12-04 00:22:56 -04:00
_state [ id ] . offset . set ( offsets ) ;
2014-07-10 02:37:27 -03:00
save_offsets ( i ) ;
}
2011-02-14 00:25:20 -04:00
}
2022-10-04 21:22:17 -03:00
# if AP_COMPASS_DIAGONALS_ENABLED
2015-03-18 20:18:47 -03:00
void
Compass : : set_and_save_diagonals ( uint8_t i , const Vector3f & diagonals )
{
// sanity check compass instance provided
2019-11-20 03:18:10 -04:00
StateIndex id = _get_state_id ( Priority ( i ) ) ;
2020-02-15 02:30:10 -04:00
if ( id < COMPASS_MAX_INSTANCES ) {
2021-12-04 00:22:56 -04:00
_state [ id ] . diagonals . set_and_save ( diagonals ) ;
2015-03-18 20:18:47 -03:00
}
}
void
Compass : : set_and_save_offdiagonals ( uint8_t i , const Vector3f & offdiagonals )
{
// sanity check compass instance provided
2019-11-20 03:18:10 -04:00
StateIndex id = _get_state_id ( Priority ( i ) ) ;
2020-02-15 02:30:10 -04:00
if ( id < COMPASS_MAX_INSTANCES ) {
2021-12-04 00:22:56 -04:00
_state [ id ] . offdiagonals . set_and_save ( offdiagonals ) ;
2015-03-18 20:18:47 -03:00
}
}
2022-10-04 21:22:17 -03:00
# endif // AP_COMPASS_DIAGONALS_ENABLED
2015-03-18 20:18:47 -03:00
2019-11-26 18:11:54 -04:00
void
Compass : : set_and_save_scale_factor ( uint8_t i , float scale_factor )
{
2019-11-20 03:18:10 -04:00
StateIndex id = _get_state_id ( Priority ( i ) ) ;
2019-11-26 18:11:54 -04:00
if ( i < COMPASS_MAX_INSTANCES ) {
2021-12-04 00:22:56 -04:00
_state [ id ] . scale_factor . set_and_save ( scale_factor ) ;
2019-11-26 18:11:54 -04:00
}
}
2011-02-14 00:25:20 -04:00
void
2014-07-09 05:07:30 -03:00
Compass : : save_offsets ( uint8_t i )
2011-02-14 00:25:20 -04:00
{
2019-11-20 03:18:10 -04:00
StateIndex id = _get_state_id ( Priority ( i ) ) ;
2020-02-15 02:30:10 -04:00
if ( id < COMPASS_MAX_INSTANCES ) {
2021-12-04 00:22:56 -04:00
_state [ id ] . offset . save ( ) ; // save offsets
_state [ id ] . dev_id . set_and_save ( _state [ id ] . detected_dev_id ) ;
2019-11-20 03:18:10 -04:00
}
}
void
Compass : : set_and_save_orientation ( uint8_t i , Rotation orientation )
{
StateIndex id = _get_state_id ( Priority ( i ) ) ;
2020-02-15 02:30:10 -04:00
if ( id < COMPASS_MAX_INSTANCES ) {
2021-12-04 00:22:56 -04:00
_state [ id ] . orientation . set_and_save_ifchanged ( orientation ) ;
2019-11-20 03:18:10 -04:00
}
2014-07-09 05:07:30 -03:00
}
void
Compass : : save_offsets ( void )
{
2019-11-20 03:18:10 -04:00
for ( Priority i ( 0 ) ; i < COMPASS_MAX_INSTANCES ; i + + ) {
save_offsets ( uint8_t ( i ) ) ;
2013-12-09 02:33:54 -04:00
}
2011-02-14 00:25:20 -04:00
}
2013-02-27 03:57:04 -04:00
void
2014-07-22 04:29:43 -03:00
Compass : : set_motor_compensation ( uint8_t i , const Vector3f & motor_comp_factor )
2013-02-27 03:57:04 -04:00
{
2019-11-20 03:18:10 -04:00
StateIndex id = _get_state_id ( Priority ( i ) ) ;
2020-02-15 02:30:10 -04:00
if ( id < COMPASS_MAX_INSTANCES ) {
2021-12-04 00:22:56 -04:00
_state [ id ] . motor_compensation . set ( motor_comp_factor ) ;
2019-11-20 03:18:10 -04:00
}
2013-02-27 03:57:04 -04:00
}
void
Compass : : save_motor_compensation ( )
{
2019-11-20 03:18:10 -04:00
StateIndex id ;
2013-03-03 10:02:12 -04:00
_motor_comp_type . save ( ) ;
2019-11-20 03:18:10 -04:00
for ( Priority k ( 0 ) ; k < COMPASS_MAX_INSTANCES ; k + + ) {
id = _get_state_id ( k ) ;
2020-02-15 02:30:10 -04:00
if ( id < COMPASS_MAX_INSTANCES ) {
2021-12-04 00:22:56 -04:00
_state [ id ] . motor_compensation . save ( ) ;
2019-11-20 03:18:10 -04:00
}
2013-12-09 04:45:31 -04:00
}
2013-02-27 03:57:04 -04:00
}
2019-03-27 04:01:18 -03:00
void Compass : : try_set_initial_location ( )
2012-03-10 19:19:04 -04:00
{
2019-03-27 04:01:18 -03:00
if ( ! _auto_declination ) {
return ;
}
if ( ! _enabled ) {
return ;
}
Location loc ;
2022-01-20 19:42:40 -04:00
if ( ! AP : : ahrs ( ) . get_location ( loc ) ) {
2019-03-27 04:01:18 -03:00
return ;
}
_initial_location_set = true ;
2012-03-30 00:18:06 -03:00
// if automatic declination is configured, then compute
// the declination based on the initial GPS fix
2019-03-27 04:01:18 -03:00
// Set the declination based on the lat/lng from GPS
_declination . set ( radians (
AP_Declination : : get_declination (
( float ) loc . lat / 10000000 ,
( float ) loc . lng / 10000000 ) ) ) ;
2012-03-10 19:19:04 -04:00
}
2014-09-18 09:56:13 -03:00
/// return true if the compass should be used for yaw calculations
bool
Compass : : use_for_yaw ( void ) const
{
2021-03-31 11:04:57 -03:00
return healthy ( _first_usable ) & & use_for_yaw ( _first_usable ) ;
2014-09-18 09:56:13 -03:00
}
/// return true if the specified compass can be used for yaw calculations
bool
Compass : : use_for_yaw ( uint8_t i ) const
{
2021-07-27 02:50:24 -03:00
if ( ! available ( ) ) {
return false ;
}
2017-08-18 05:58:08 -03:00
// when we are doing in-flight compass learning the state
// estimator must not use the compass. The learning code turns off
// inflight learning when it has converged
2021-12-04 00:22:56 -04:00
return _use_for_yaw [ Priority ( i ) ] & & _learn . get ( ) ! = LEARN_INFLIGHT ;
2019-11-20 03:18:10 -04:00
}
2020-05-08 20:46:59 -03:00
/*
return the number of enabled sensors . Used to determine if
non - compass operation is desired
*/
uint8_t Compass : : get_num_enabled ( void ) const
{
if ( get_count ( ) = = 0 ) {
return 0 ;
}
uint8_t count = 0 ;
for ( uint8_t i = 0 ; i < COMPASS_MAX_INSTANCES ; i + + ) {
if ( use_for_yaw ( i ) ) {
count + + ;
}
}
return count ;
}
2011-02-14 00:25:20 -04:00
void
2013-04-15 09:50:44 -03:00
Compass : : set_declination ( float radians , bool save_to_eeprom )
2011-02-14 00:25:20 -04:00
{
2013-04-15 09:50:44 -03:00
if ( save_to_eeprom ) {
_declination . set_and_save ( radians ) ;
2020-02-15 02:30:10 -04:00
} else {
2013-04-15 09:50:44 -03:00
_declination . set ( radians ) ;
}
2011-02-14 00:25:20 -04:00
}
2011-02-18 23:57:53 -04:00
float
2013-05-08 20:22:00 -03:00
Compass : : get_declination ( ) const
2011-02-18 23:57:53 -04:00
{
2012-08-17 03:19:22 -03:00
return _declination . get ( ) ;
2011-02-18 23:57:53 -04:00
}
2013-08-18 08:08:34 -03:00
/*
calculate a compass heading given the attitude from DCM and the mag vector
*/
2012-06-20 06:30:30 -03:00
float
2016-01-22 13:30:59 -04:00
Compass : : calculate_heading ( const Matrix3f & dcm_matrix , uint8_t i ) const
2011-02-14 00:25:20 -04:00
{
2023-10-22 16:38:56 -03:00
/*
This extracts a roll / pitch - only rotation which is then used to rotate the body frame field into earth frame so the heading can be calculated .
One could do :
float roll , pitch , yaw ;
dcm_matrix . to_euler ( roll , pitch , yaw )
Matrix3f rp_rot ;
rp_rot . from_euler ( roll , pitch , 0 )
Vector3f ef = rp_rot * field
Because only the X and Y components are needed it ' s more efficient to manually calculate :
rp_rot = [ cos ( pitch ) , sin ( roll ) * sin ( pitch ) , cos ( roll ) * sin ( pitch )
0 , cos ( roll ) , - sin ( roll ) ]
If the whole matrix is multiplied by cos ( pitch ) the required trigonometric values can be extracted directly from the existing dcm matrix .
This multiplication has no effect on the calculated heading as it changes the length of the North / East vector but not its angle .
rp_rot = [ cos ( pitch ) ^ 2 , sin ( roll ) * sin ( pitch ) * cos ( pitch ) , cos ( roll ) * sin ( pitch ) * cos ( pitch )
0 , cos ( roll ) * cos ( pitch ) , - sin ( roll ) * cos ( pitch ) ]
Preexisting values can be substituted in :
dcm_matrix . c . x = - sin ( pitch )
dcm_matrix . c . y = sin ( roll ) * cos ( pitch )
dcm_matrix . c . z = cos ( roll ) * cos ( pitch )
rp_rot = [ cos ( pitch ) ^ 2 , dcm_matrix . c . y * - dcm_matrix . c . x , dcm_matrix . c . z * - dcm_matrix . c . x
0 , dcm_matrix . c . z , - dcm_matrix . c . y ]
cos ( pitch ) ^ 2 is stil needed . This is the same as 1 - sin ( pitch ) ^ 2.
sin ( pitch ) is avalable as dcm_matrix . c . x
*/
const float cos_pitch_sq = 1.0f - ( dcm_matrix . c . x * dcm_matrix . c . x ) ;
2013-08-18 08:08:34 -03:00
2011-05-08 15:15:29 -03:00
// Tilt compensated magnetic field Y component:
2016-01-22 13:30:59 -04:00
const Vector3f & field = get_field ( i ) ;
2015-02-23 19:17:44 -04:00
2023-10-22 16:38:56 -03:00
const float headY = field . y * dcm_matrix . c . z - field . z * dcm_matrix . c . y ;
2012-02-23 19:42:03 -04:00
2011-02-14 00:25:20 -04:00
// Tilt compensated magnetic field X component:
2023-10-22 16:38:56 -03:00
const float headX = field . x * cos_pitch_sq - dcm_matrix . c . x * ( field . y * dcm_matrix . c . y + field . z * dcm_matrix . c . z ) ;
2013-05-08 20:19:01 -03:00
2011-02-14 00:25:20 -04:00
// magnetic heading
2011-07-08 00:56:04 -03:00
// 6/4/11 - added constrain to keep bad values from ruining DCM Yaw - Jason S.
2023-10-22 16:38:56 -03:00
const float heading = constrain_float ( atan2f ( - headY , headX ) , - M_PI , M_PI ) ;
2011-02-14 00:25:20 -04:00
2023-10-22 16:38:56 -03:00
// Declination correction
return wrap_PI ( heading + _declination ) ;
2011-02-14 00:25:20 -04:00
}
2014-07-07 09:24:18 -03:00
/// Returns True if the compasses have been configured (i.e. offsets saved)
///
/// @returns True if compass has been configured
///
bool Compass : : configured ( uint8_t i )
{
// exit immediately if instance is beyond the number of compasses we have available
if ( i > get_count ( ) ) {
return false ;
}
// exit immediately if all offsets are zero
2015-09-28 16:56:49 -03:00
if ( is_zero ( get_offsets ( i ) . length ( ) ) ) {
2015-08-24 11:53:17 -03:00
return false ;
}
2019-11-20 03:18:10 -04:00
StateIndex id = _get_state_id ( Priority ( i ) ) ;
2018-03-19 20:58:40 -03:00
// exit immediately if dev_id hasn't been detected
2020-06-05 06:47:54 -03:00
if ( _state [ id ] . detected_dev_id = = 0 | |
id = = COMPASS_MAX_INSTANCES ) {
2018-03-19 20:58:40 -03:00
return false ;
}
2021-12-11 02:13:36 -04:00
# ifdef HAL_USE_EMPTY_STORAGE
// the load() call below returns zeroes on empty storage, so the
// check-stored-value check here will always fail. Since nobody
// really cares about the empty-storage case, shortcut out here
// for simplicity.
return true ;
# endif
2018-03-19 20:58:40 -03:00
// back up cached value of dev_id
2021-12-04 00:22:56 -04:00
int32_t dev_id_cache_value = _state [ id ] . dev_id ;
2014-07-07 09:24:18 -03:00
// load dev_id from eeprom
2021-12-04 00:22:56 -04:00
_state [ id ] . dev_id . load ( ) ;
2014-07-07 09:24:18 -03:00
2018-03-19 20:58:40 -03:00
// if dev_id loaded from eeprom is different from detected dev id or dev_id loaded from eeprom is different from cached dev_id, compass is unconfigured
2021-12-04 00:22:56 -04:00
if ( _state [ id ] . dev_id ! = _state [ id ] . detected_dev_id | | _state [ id ] . dev_id ! = dev_id_cache_value ) {
2018-03-19 20:58:40 -03:00
// restore cached value
2022-07-05 00:08:56 -03:00
_state [ id ] . dev_id . set ( dev_id_cache_value ) ;
2014-07-07 09:24:18 -03:00
// return failure
return false ;
}
2012-03-27 01:16:00 -03:00
2014-07-07 09:24:18 -03:00
// if we got here then it must be configured
return true ;
}
2019-11-20 03:18:10 -04:00
bool Compass : : configured ( char * failure_msg , uint8_t failure_msg_len )
2014-07-07 09:24:18 -03:00
{
2020-04-29 00:27:58 -03:00
# if COMPASS_MAX_INSTANCES > 1
2019-11-20 03:18:10 -04:00
// Check if any of the registered devs are not registered
for ( Priority i ( 0 ) ; i < COMPASS_MAX_INSTANCES ; i + + ) {
if ( _priority_did_list [ i ] ! = 0 & & use_for_yaw ( uint8_t ( i ) ) ) {
if ( ! _get_state ( i ) . registered ) {
2022-02-28 17:48:30 -04:00
snprintf ( failure_msg , failure_msg_len , " Compass %d not found " , uint8_t ( i + 1 ) ) ;
2019-11-20 03:18:10 -04:00
return false ;
}
if ( _priority_did_list [ i ] ! = _priority_did_stored_list [ i ] ) {
snprintf ( failure_msg , failure_msg_len , " Compass order change requires reboot " ) ;
return false ;
}
}
}
2020-04-29 00:27:58 -03:00
# endif
2019-11-20 03:18:10 -04:00
2014-07-07 09:24:18 -03:00
bool all_configured = true ;
2020-02-15 02:30:10 -04:00
for ( uint8_t i = 0 ; i < get_count ( ) ; i + + ) {
2021-11-01 02:27:28 -03:00
if ( configured ( i ) ) {
continue ;
}
if ( ! use_for_yaw ( i ) ) {
// we're not planning on using this anyway so sure,
// whatever, it's configured....
continue ;
}
all_configured = false ;
break ;
2014-07-07 09:24:18 -03:00
}
2019-11-20 03:18:10 -04:00
if ( ! all_configured ) {
snprintf ( failure_msg , failure_msg_len , " Compass not calibrated " ) ;
}
2014-07-07 09:24:18 -03:00
return all_configured ;
}
2014-07-31 22:19:53 -03:00
2015-02-23 19:17:44 -04:00
/*
set the type of motor compensation to use
*/
void Compass : : motor_compensation_type ( const uint8_t comp_type )
{
if ( _motor_comp_type < = AP_COMPASS_MOT_COMP_CURRENT & & _motor_comp_type ! = ( int8_t ) comp_type ) {
2022-07-05 00:08:56 -03:00
_motor_comp_type . set ( ( int8_t ) comp_type ) ;
2018-03-01 17:42:31 -04:00
_thr = 0 ; // set current throttle to zero
2015-02-23 19:17:44 -04:00
for ( uint8_t i = 0 ; i < COMPASS_MAX_INSTANCES ; i + + ) {
set_motor_compensation ( i , Vector3f ( 0 , 0 , 0 ) ) ; // clear out invalid compensation vectors
}
}
2014-11-15 21:58:23 -04:00
}
2015-08-14 21:27:23 -03:00
2015-09-15 03:54:26 -03:00
bool Compass : : consistent ( ) const
2015-08-14 21:27:23 -03:00
{
2023-04-17 19:57:13 -03:00
const Vector3f & primary_mag_field { get_field ( ) } ;
const Vector2f & primary_mag_field_xy { primary_mag_field . xy ( ) } ;
2015-08-14 21:27:23 -03:00
2015-09-15 03:54:26 -03:00
for ( uint8_t i = 0 ; i < get_count ( ) ; i + + ) {
2018-06-21 20:43:30 -03:00
if ( ! use_for_yaw ( i ) ) {
// configured not-to-be-used
continue ;
}
2015-08-14 21:27:23 -03:00
2023-04-17 19:57:13 -03:00
const Vector3f & mag_field = get_field ( i ) ;
const Vector2f & mag_field_xy = mag_field . xy ( ) ;
2015-08-14 21:27:23 -03:00
2018-06-21 20:43:30 -03:00
if ( mag_field_xy . is_zero ( ) ) {
return false ;
}
2015-08-14 21:27:23 -03:00
2018-06-21 20:43:30 -03:00
// check for gross misalignment on all axes
2023-04-17 19:57:13 -03:00
const float xyz_ang_diff = mag_field . angle ( primary_mag_field ) ;
2018-06-21 20:43:30 -03:00
if ( xyz_ang_diff > AP_COMPASS_MAX_XYZ_ANG_DIFF ) {
return false ;
}
2015-08-14 21:27:23 -03:00
2018-06-21 20:43:30 -03:00
// check for an unacceptable angle difference on the xy plane
2023-04-17 19:57:13 -03:00
const float xy_ang_diff = mag_field_xy . angle ( primary_mag_field_xy ) ;
2018-06-21 20:43:30 -03:00
if ( xy_ang_diff > AP_COMPASS_MAX_XY_ANG_DIFF ) {
return false ;
}
// check for an unacceptable length difference on the xy plane
2023-04-17 19:57:13 -03:00
const float xy_len_diff = ( primary_mag_field_xy - mag_field_xy ) . length ( ) ;
2018-06-21 20:43:30 -03:00
if ( xy_len_diff > AP_COMPASS_MAX_XY_LENGTH_DIFF ) {
return false ;
2015-08-14 21:27:23 -03:00
}
}
return true ;
}
2015-09-15 03:54:26 -03:00
2023-05-22 01:04:04 -03:00
bool Compass : : healthy ( uint8_t i ) const
{
return ( i < COMPASS_MAX_INSTANCES ) ? _get_state ( Priority ( i ) ) . healthy : false ;
}
2019-11-26 18:11:54 -04:00
/*
return true if we have a valid scale factor
*/
bool Compass : : have_scale_factor ( uint8_t i ) const
{
2021-07-27 02:50:24 -03:00
if ( ! available ( ) ) {
return false ;
}
2019-11-20 03:18:10 -04:00
StateIndex id = _get_state_id ( Priority ( i ) ) ;
if ( id > = COMPASS_MAX_INSTANCES | |
2021-12-04 00:22:56 -04:00
_state [ id ] . scale_factor < COMPASS_MIN_SCALE_FACTOR | |
_state [ id ] . scale_factor > COMPASS_MAX_SCALE_FACTOR ) {
2019-11-26 18:11:54 -04:00
return false ;
}
return true ;
}
2022-10-26 06:21:36 -03:00
# if AP_COMPASS_MSP_ENABLED
2020-09-03 19:11:05 -03:00
void Compass : : handle_msp ( const MSP : : msp_compass_data_message_t & pkt )
{
if ( ! _driver_enabled ( DRIVER_MSP ) ) {
return ;
}
if ( ! init_done ) {
if ( pkt . instance < 8 ) {
msp_instance_mask | = 1U < < pkt . instance ;
}
} else {
for ( uint8_t i = 0 ; i < _backend_count ; i + + ) {
_backends [ i ] - > handle_msp ( pkt ) ;
}
}
}
2022-10-26 06:21:36 -03:00
# endif // AP_COMPASS_MSP_ENABLED
2018-03-29 01:13:55 -03:00
2022-10-26 06:21:36 -03:00
# if AP_COMPASS_EXTERNALAHRS_ENABLED
2020-12-28 01:26:18 -04:00
void Compass : : handle_external ( const AP_ExternalAHRS : : mag_data_message_t & pkt )
{
2023-02-19 21:05:16 -04:00
if ( ! _driver_enabled ( DRIVER_EXTERNALAHRS ) ) {
2020-12-28 01:26:18 -04:00
return ;
}
for ( uint8_t i = 0 ; i < _backend_count ; i + + ) {
_backends [ i ] - > handle_external ( pkt ) ;
}
}
2022-10-26 06:21:36 -03:00
# endif // AP_COMPASS_EXTERNALAHRS_ENABLED
2020-12-28 01:26:18 -04:00
2021-02-10 20:49:21 -04:00
// force save of current calibration as valid
void Compass : : force_save_calibration ( void )
{
for ( StateIndex i ( 0 ) ; i < COMPASS_MAX_INSTANCES ; i + + ) {
2021-12-04 00:22:56 -04:00
if ( _state [ i ] . dev_id ! = 0 ) {
_state [ i ] . dev_id . save ( ) ;
2021-02-10 20:49:21 -04:00
}
}
}
2018-03-29 01:13:55 -03:00
// singleton instance
Compass * Compass : : _singleton ;
2020-02-15 02:30:10 -04:00
namespace AP
{
2018-03-29 01:13:55 -03:00
Compass & compass ( )
{
return * Compass : : get_singleton ( ) ;
}
}
2024-02-23 04:29:09 -04:00
# endif // AP_COMPASS_ENABLED