2013-08-29 02:34:34 -03:00
/*
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
2018-12-20 19:41:15 -04:00
2013-08-29 02:34:34 -03:00
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
2018-12-20 19:41:15 -04:00
2013-08-29 02:34:34 -03:00
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
2012-07-15 22:21:20 -03:00
/*
2018-07-23 20:47:40 -03:00
* AP_Airspeed . cpp - airspeed ( pitot ) driver
2012-08-17 03:08:43 -03:00
*/
2012-07-15 22:21:20 -03:00
2022-01-02 03:41:01 -04:00
# include <AP_Vehicle/AP_Vehicle_Type.h>
# include "AP_Airspeed.h"
// Dummy the AP_Airspeed class to allow building Airspeed only for plane, rover, sub, and copter & heli 2MB boards
// This could be removed once the build system allows for APM_BUILD_TYPE in header files
# ifndef AP_AIRSPEED_DUMMY_METHODS_ENABLED
# define AP_AIRSPEED_DUMMY_METHODS_ENABLED ((APM_BUILD_COPTER_OR_HELI && BOARD_FLASH_SIZE <= 1024) || \
APM_BUILD_TYPE ( APM_BUILD_AntennaTracker ) | | APM_BUILD_TYPE ( APM_BUILD_Blimp ) )
# endif
# if !AP_AIRSPEED_DUMMY_METHODS_ENABLED
2016-01-29 07:38:33 -04:00
# include <AP_Common/AP_Common.h>
2015-08-11 03:28:42 -03:00
# include <AP_HAL/AP_HAL.h>
2016-06-08 09:13:53 -03:00
# include <AP_HAL/I2CDevice.h>
2015-08-11 03:28:42 -03:00
# include <AP_Math/AP_Math.h>
2016-05-24 01:22:40 -03:00
# include <GCS_MAVLink/GCS.h>
2017-04-29 03:53:39 -03:00
# include <SRV_Channel/SRV_Channel.h>
2019-01-18 00:23:42 -04:00
# include <AP_Logger/AP_Logger.h>
2016-06-08 09:13:53 -03:00
# include <utility>
2020-07-18 16:49:08 -03:00
# include <AP_Vehicle/AP_Vehicle.h>
2016-11-30 00:59:20 -04:00
# include "AP_Airspeed_MS4525.h"
2016-11-30 02:21:48 -04:00
# include "AP_Airspeed_MS5525.h"
2017-11-03 01:47:32 -03:00
# include "AP_Airspeed_SDP3X.h"
2018-07-11 23:05:12 -03:00
# include "AP_Airspeed_DLVR.h"
2016-11-30 00:49:19 -04:00
# include "AP_Airspeed_analog.h"
2021-03-23 11:18:41 -03:00
# include "AP_Airspeed_ASP5033.h"
2017-11-03 01:47:32 -03:00
# include "AP_Airspeed_Backend.h"
2018-09-05 03:45:01 -03:00
# include "AP_Airspeed_UAVCAN.h"
2020-07-18 16:49:08 -03:00
# include "AP_Airspeed_NMEA.h"
2020-11-16 06:35:15 -04:00
# include "AP_Airspeed_MSP.h"
2022-05-24 01:14:25 -03:00
# include "AP_Airspeed_SITL.h"
2016-01-29 07:38:33 -04:00
extern const AP_HAL : : HAL & hal ;
2020-08-23 03:01:07 -03:00
# ifdef HAL_AIRSPEED_TYPE_DEFAULT
# define ARSPD_DEFAULT_TYPE HAL_AIRSPEED_TYPE_DEFAULT
# ifndef ARSPD_DEFAULT_PIN
# define ARSPD_DEFAULT_PIN 1
# endif
2021-11-02 23:32:05 -03:00
# elif APM_BUILD_TYPE(APM_BUILD_ArduPlane)
// The HAL_BOARD_SITL setting is required because of current probe process for MS4525 will
// connect and find the SIM_DLVR sensors & fault as there is no way to tell them apart
# if CONFIG_HAL_BOARD == HAL_BOARD_SITL
# define ARSPD_DEFAULT_TYPE TYPE_ANALOG
# define ARSPD_DEFAULT_PIN 1
# else
# define ARSPD_DEFAULT_TYPE TYPE_I2C_MS4525
# ifdef HAL_DEFAULT_AIRSPEED_PIN
# define ARSPD_DEFAULT_PIN HAL_DEFAULT_AIRSPEED_PIN
# else
# define ARSPD_DEFAULT_PIN 15
# endif
# endif //CONFIG_HAL_BOARD
# else // All Other Vehicle Types
2019-02-06 21:01:33 -04:00
# define ARSPD_DEFAULT_TYPE TYPE_NONE
# define ARSPD_DEFAULT_PIN 15
2019-07-11 22:38:39 -03:00
# endif
2016-10-31 06:48:22 -03:00
2019-10-03 08:02:07 -03:00
# ifndef HAL_AIRSPEED_BUS_DEFAULT
# define HAL_AIRSPEED_BUS_DEFAULT 1
# endif
2016-10-31 06:48:22 -03:00
# if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_DISCO
# define PSI_RANGE_DEFAULT 0.05
2013-06-02 22:40:06 -03:00
# endif
2016-06-08 21:10:54 -03:00
# ifndef PSI_RANGE_DEFAULT
# define PSI_RANGE_DEFAULT 1.0f
# endif
2020-10-09 09:38:25 -03:00
# define OPTIONS_DEFAULT AP_Airspeed::OptionsMask::ON_FAILURE_AHRS_WIND_MAX_DO_DISABLE | AP_Airspeed::OptionsMask::ON_FAILURE_AHRS_WIND_MAX_RECOVERY_DO_REENABLE
2012-07-15 22:21:20 -03:00
// table of user settable parameters
2015-10-25 14:03:46 -03:00
const AP_Param : : GroupInfo AP_Airspeed : : var_info [ ] = {
2012-07-15 22:21:20 -03:00
2017-11-03 03:17:34 -03:00
// @Param: _TYPE
2016-11-30 00:49:19 -04:00
// @DisplayName: Airspeed type
// @Description: Type of airspeed sensor
2022-05-24 01:14:25 -03:00
// @Values: 0:None,1:I2C-MS4525D0,2:Analog,3:I2C-MS5525,4:I2C-MS5525 (0x76),5:I2C-MS5525 (0x77),6:I2C-SDP3X,7:I2C-DLVR-5in,8:DroneCAN,9:I2C-DLVR-10in,10:I2C-DLVR-20in,11:I2C-DLVR-30in,12:I2C-DLVR-60in,13:NMEA water speed,14:MSP,15:ASP5033,100:SITL
2016-07-26 02:35:15 -03:00
// @User: Standard
2021-11-19 04:55:48 -04:00
AP_GROUPINFO_FLAGS ( " _TYPE " , 0 , AP_Airspeed , param [ 0 ] . type , ARSPD_DEFAULT_TYPE , AP_PARAM_FLAG_ENABLE ) , // NOTE: Index 0 is actually used as index 63 here
2012-07-15 22:21:20 -03:00
2021-07-15 00:13:03 -03:00
// @Param: _DEVID
// @DisplayName: Airspeed ID
// @Description: Airspeed sensor ID, taking into account its type, bus and instance
// @ReadOnly: True
// @User: Advanced
AP_GROUPINFO_FLAGS ( " _DEVID " , 24 , AP_Airspeed , param [ 0 ] . bus_id , 0 , AP_PARAM_FLAG_INTERNAL_USE_ONLY ) ,
2020-02-04 22:18:45 -04:00
# ifndef HAL_BUILD_AP_PERIPH
2017-11-03 03:17:34 -03:00
// @Param: _USE
2012-07-15 22:21:20 -03:00
// @DisplayName: Airspeed use
2022-04-01 12:55:42 -03:00
// @Description{Plane}: Enables airspeed use for automatic throttle modes and replaces control from THR_TRIM. Continues to display and log airspeed if set to 0. Uses airspeed for control if set to 1. Only uses airspeed when throttle = 0 if set to 2 (useful for gliders with airspeed sensors behind propellers).
// @Description{Copter, Blimp, Rover, Sub}: This parameter is not used by this vehicle. Always set to 0.
2018-12-20 19:41:15 -04:00
// @Values: 0:DoNotUse,1:Use,2:UseWhenZeroThrottle
2016-07-26 02:35:15 -03:00
// @User: Standard
2017-11-03 03:17:34 -03:00
AP_GROUPINFO ( " _USE " , 1 , AP_Airspeed , param [ 0 ] . use , 0 ) ,
2012-07-15 22:21:20 -03:00
2017-11-03 03:17:34 -03:00
// @Param: _OFFSET
2012-07-15 22:21:20 -03:00
// @DisplayName: Airspeed offset
// @Description: Airspeed calibration offset
// @Increment: 0.1
2016-07-26 02:35:15 -03:00
// @User: Advanced
2017-11-03 03:17:34 -03:00
AP_GROUPINFO ( " _OFFSET " , 2 , AP_Airspeed , param [ 0 ] . offset , 0 ) ,
2012-07-15 22:21:20 -03:00
2017-11-03 03:17:34 -03:00
// @Param: _RATIO
2012-07-15 22:21:20 -03:00
// @DisplayName: Airspeed ratio
2018-12-20 19:41:15 -04:00
// @Description: Calibrates pitot tube pressure to velocity. Increasing this value will indicate a higher airspeed at any given dynamic pressure.
2012-07-15 22:21:20 -03:00
// @Increment: 0.1
2016-07-26 02:35:15 -03:00
// @User: Advanced
2017-11-03 03:17:34 -03:00
AP_GROUPINFO ( " _RATIO " , 3 , AP_Airspeed , param [ 0 ] . ratio , 1.9936f ) ,
2012-07-15 22:21:20 -03:00
2017-11-03 03:17:34 -03:00
// @Param: _PIN
2013-06-02 22:40:06 -03:00
// @DisplayName: Airspeed pin
2016-11-30 00:49:19 -04:00
// @Description: The pin number that the airspeed sensor is connected to for analog sensors. Set to 15 on the Pixhawk for the analog airspeed port.
2013-06-02 22:40:06 -03:00
// @User: Advanced
2017-11-03 03:17:34 -03:00
AP_GROUPINFO ( " _PIN " , 4 , AP_Airspeed , param [ 0 ] . pin , ARSPD_DEFAULT_PIN ) ,
2020-02-04 22:18:45 -04:00
# endif // HAL_BUILD_AP_PERIPH
2013-06-02 22:40:06 -03:00
2019-10-03 08:02:07 -03:00
# if AP_AIRSPEED_AUTOCAL_ENABLE
2017-11-03 03:17:34 -03:00
// @Param: _AUTOCAL
2022-06-07 04:04:28 -03:00
// @DisplayName: Automatic airspeed ratio calibration
// @DisplayName{Copter, Blimp, Rover, Sub}: This parameter and function is not used by this vehicle. Always set to 0.
2018-12-20 19:41:15 -04:00
// @Description: Enables automatic adjustment of ARSPD_RATIO during a calibration flight based on estimation of ground speed and true airspeed. New ratio saved every 2 minutes if change is > 5%. Should not be left enabled.
2013-07-19 19:14:58 -03:00
// @User: Advanced
2017-11-03 03:17:34 -03:00
AP_GROUPINFO ( " _AUTOCAL " , 5 , AP_Airspeed , param [ 0 ] . autocal , 0 ) ,
2019-10-03 08:02:07 -03:00
# endif
2013-07-19 19:14:58 -03:00
2017-11-03 03:17:34 -03:00
// @Param: _TUBE_ORDER
2014-02-14 07:07:12 -04:00
// @DisplayName: Control pitot tube order
2022-02-28 17:06:36 -04:00
// @Description: This parameter allows you to control whether the order in which the tubes are attached to your pitot tube matters. If you set this to 0 then the first (often the top) connector on the sensor needs to be the stagnation pressure (the pressure at the tip of the pitot tube). If set to 1 then the second (often the bottom) connector needs to be the stagnation pressure. If set to 2 (the default) then the airspeed driver will accept either order. The reason you may wish to specify the order is it will allow your airspeed sensor to detect if the aircraft is receiving excessive pressure on the static port compared to the stagnation port such as during a stall, which would otherwise be seen as a positive airspeed.
2014-02-14 07:07:12 -04:00
// @User: Advanced
2022-02-28 17:06:36 -04:00
// @Values: 0:Normal,1:Swapped,2:Auto Detect
2017-11-03 03:17:34 -03:00
AP_GROUPINFO ( " _TUBE_ORDER " , 6 , AP_Airspeed , param [ 0 ] . tube_order , 2 ) ,
2014-02-14 07:07:12 -04:00
2020-02-04 22:18:45 -04:00
# ifndef HAL_BUILD_AP_PERIPH
2017-11-03 03:17:34 -03:00
// @Param: _SKIP_CAL
2022-04-01 12:55:42 -03:00
// @DisplayName: Skip airspeed offset calibration on startup
2014-11-13 06:12:37 -04:00
// @Description: This parameter allows you to skip airspeed offset calibration on startup, instead using the offset from the last calibration. This may be desirable if the offset variance between flights for your sensor is low and you want to avoid having to cover the pitot tube on each boot.
// @Values: 0:Disable,1:Enable
// @User: Advanced
2017-11-03 03:17:34 -03:00
AP_GROUPINFO ( " _SKIP_CAL " , 7 , AP_Airspeed , param [ 0 ] . skip_cal , 0 ) ,
2020-02-04 22:18:45 -04:00
# endif // HAL_BUILD_AP_PERIPH
2014-11-13 06:12:37 -04:00
2017-11-03 03:17:34 -03:00
// @Param: _PSI_RANGE
2016-06-08 21:10:54 -03:00
// @DisplayName: The PSI range of the device
2022-05-23 01:51:28 -03:00
// @Description: This parameter allows you to set the PSI (pounds per square inch) range for your sensor. You should not change this unless you examine the datasheet for your device
2016-06-08 21:10:54 -03:00
// @User: Advanced
2017-11-03 03:17:34 -03:00
AP_GROUPINFO ( " _PSI_RANGE " , 8 , AP_Airspeed , param [ 0 ] . psi_range , PSI_RANGE_DEFAULT ) ,
2016-11-30 02:21:48 -04:00
2020-02-04 22:18:45 -04:00
# ifndef HAL_BUILD_AP_PERIPH
2017-11-03 03:17:34 -03:00
// @Param: _BUS
2016-11-30 02:21:48 -04:00
// @DisplayName: Airspeed I2C bus
2018-12-20 19:41:15 -04:00
// @Description: Bus number of the I2C bus where the airspeed sensor is connected
2022-01-21 05:10:28 -04:00
// @Values: 0:Bus0(internal),1:Bus1(external),2:Bus2(auxiliary)
2016-11-30 02:21:48 -04:00
// @User: Advanced
2019-10-03 08:02:07 -03:00
AP_GROUPINFO ( " _BUS " , 9 , AP_Airspeed , param [ 0 ] . bus , HAL_AIRSPEED_BUS_DEFAULT ) ,
2020-02-04 22:18:45 -04:00
# endif // HAL_BUILD_AP_PERIPH
2017-11-03 03:17:34 -03:00
2019-10-03 08:02:07 -03:00
# if AIRSPEED_MAX_SENSORS > 1
2017-11-03 03:17:34 -03:00
// @Param: _PRIMARY
// @DisplayName: Primary airspeed sensor
// @Description: This selects which airspeed sensor will be the primary if multiple sensors are found
// @Values: 0:FirstSensor,1:2ndSensor
// @User: Advanced
AP_GROUPINFO ( " _PRIMARY " , 10 , AP_Airspeed , primary_sensor , 0 ) ,
2019-10-03 08:02:07 -03:00
# endif
2017-11-03 03:17:34 -03:00
2020-02-04 22:18:45 -04:00
# ifndef HAL_BUILD_AP_PERIPH
2019-01-29 19:03:35 -04:00
// @Param: _OPTIONS
// @DisplayName: Airspeed options bitmask
2022-04-01 12:55:42 -03:00
// @Description{Plane}: Bitmask of options to use with airspeed. 0:Disable use based on airspeed/groundspeed mismatch (see ARSPD_WIND_MAX), 1:Automatically reenable use based on airspeed/groundspeed mismatch recovery (see ARSPD_WIND_MAX) 2:Disable voltage correction
// @Description{Copter, Blimp, Rover, Sub}: This parameter and function is not used by this vehicle. Always set to 0.
2021-07-10 03:45:07 -03:00
// @Bitmask: 0:SpeedMismatchDisable, 1:AllowSpeedMismatchRecovery, 2:DisableVoltageCorrection
2020-10-09 09:38:25 -03:00
// @User: Advanced
AP_GROUPINFO ( " _OPTIONS " , 21 , AP_Airspeed , _options , OPTIONS_DEFAULT ) ,
// @Param: _WIND_MAX
// @DisplayName: Maximum airspeed and ground speed difference
// @Description: If the difference between airspeed and ground speed is greater than this value the sensor will be marked unhealthy. Using ARSPD_OPTION this health value can be used to disable the sensor.
2022-04-01 12:55:42 -03:00
// @Description{Copter, Blimp, Rover, Sub}: This parameter and function is not used by this vehicle. Always set to 0.
2020-10-09 09:38:25 -03:00
// @Units: m/s
// @User: Advanced
AP_GROUPINFO ( " _WIND_MAX " , 22 , AP_Airspeed , _wind_max , 0 ) ,
// @Param: _WIND_WARN
// @DisplayName: Airspeed and ground speed difference that gives a warning
// @Description: If the difference between airspeed and ground speed is greater than this value the sensor will issue a warning. If 0 ARSPD_WIND_MAX is used.
2022-04-01 12:55:42 -03:00
// @Description{Copter, Blimp, Rover, Sub}: This parameter and function is not used by this vehicle. Always set to 0.
2020-10-09 09:38:25 -03:00
// @Units: m/s
2019-01-29 19:03:35 -04:00
// @User: Advanced
2020-10-09 09:38:25 -03:00
AP_GROUPINFO ( " _WIND_WARN " , 23 , AP_Airspeed , _wind_warn , 0 ) ,
2020-02-04 22:18:45 -04:00
# endif
2019-01-29 19:03:35 -04:00
2019-10-03 08:02:07 -03:00
# if AIRSPEED_MAX_SENSORS > 1
2017-11-03 03:17:34 -03:00
// @Param: 2_TYPE
// @DisplayName: Second Airspeed type
// @Description: Type of 2nd airspeed sensor
2021-12-13 14:10:05 -04:00
// @Values: 0:None,1:I2C-MS4525D0,2:Analog,3:I2C-MS5525,4:I2C-MS5525 (0x76),5:I2C-MS5525 (0x77),6:I2C-SDP3X,7:I2C-DLVR-5in,8:DroneCAN,9:I2C-DLVR-10in,10:I2C-DLVR-20in,11:I2C-DLVR-30in,12:I2C-DLVR-60in,13:NMEA water speed,14:MSP,15:ASP5033
2017-11-03 03:17:34 -03:00
// @User: Standard
AP_GROUPINFO_FLAGS ( " 2_TYPE " , 11 , AP_Airspeed , param [ 1 ] . type , 0 , AP_PARAM_FLAG_ENABLE ) ,
// @Param: 2_USE
// @DisplayName: Enable use of 2nd airspeed sensor
2022-04-01 12:55:42 -03:00
// @Description{Plane}: use airspeed for flight control. When set to 0 airspeed sensor can be logged and displayed on a GCS but won't be used for flight. When set to 1 it will be logged and used. When set to 2 it will be only used when the throttle is zero, which can be useful in gliders with airspeed sensors behind a propeller
// @Description{Copter, Blimp, Rover, Sub}: This parameter and function is not used by this vehicle. Always set to 0.
2017-11-03 03:17:34 -03:00
// @Values: 0:Don't Use,1:use,2:UseWhenZeroThrottle
// @User: Standard
AP_GROUPINFO ( " 2_USE " , 12 , AP_Airspeed , param [ 1 ] . use , 0 ) ,
// @Param: 2_OFFSET
// @DisplayName: Airspeed offset for 2nd airspeed sensor
// @Description: Airspeed calibration offset
// @Increment: 0.1
// @User: Advanced
AP_GROUPINFO ( " 2_OFFSET " , 13 , AP_Airspeed , param [ 1 ] . offset , 0 ) ,
// @Param: 2_RATIO
// @DisplayName: Airspeed ratio for 2nd airspeed sensor
// @Description: Airspeed calibration ratio
// @Increment: 0.1
// @User: Advanced
AP_GROUPINFO ( " 2_RATIO " , 14 , AP_Airspeed , param [ 1 ] . ratio , 2 ) ,
// @Param: 2_PIN
// @DisplayName: Airspeed pin for 2nd airspeed sensor
2018-12-20 19:41:15 -04:00
// @Description: Pin number indicating location of analog airspeed sensors. Pixhawk/Cube if set to 15.
2017-11-03 03:17:34 -03:00
// @User: Advanced
AP_GROUPINFO ( " 2_PIN " , 15 , AP_Airspeed , param [ 1 ] . pin , 0 ) ,
// @Param: 2_AUTOCAL
// @DisplayName: Automatic airspeed ratio calibration for 2nd airspeed sensor
2022-04-01 12:55:42 -03:00
// @Description{Plane}: If this is enabled then the autopilot will automatically adjust the ARSPD_RATIO during flight, based upon an estimation filter using ground speed and true airspeed. The automatic calibration will save the new ratio to EEPROM every 2 minutes if it changes by more than 5%. This option should be enabled for a calibration flight then disabled again when calibration is complete. Leaving it enabled all the time is not recommended.
// @Description{Copter, Blimp, Rover, Sub}: This parameter and function is not used by this vehicle. Always set to 0.
2017-11-03 03:17:34 -03:00
// @User: Advanced
AP_GROUPINFO ( " 2_AUTOCAL " , 16 , AP_Airspeed , param [ 1 ] . autocal , 0 ) ,
// @Param: 2_TUBE_ORDR
// @DisplayName: Control pitot tube order of 2nd airspeed sensor
2022-02-28 17:06:36 -04:00
// @Description: This parameter allows you to control whether the order in which the tubes are attached to your pitot tube matters. If you set this to 0 then the first (often the top) connector on the sensor needs to be the stagnation pressure (the pressure at the tip of the pitot tube). If set to 1 then the second (often the bottom) connector needs to be the stagnation pressure. If set to 2 (the default) then the airspeed driver will accept either order. The reason you may wish to specify the order is it will allow your airspeed sensor to detect if the aircraft is receiving excessive pressure on the static port compared to the stagnation port such as during a stall, which would otherwise be seen as a positive airspeed.
2017-11-03 03:17:34 -03:00
// @User: Advanced
2022-02-28 17:06:36 -04:00
// @Values: 0:Normal,1:Swapped,2:Auto Detect
2017-11-03 03:17:34 -03:00
AP_GROUPINFO ( " 2_TUBE_ORDR " , 17 , AP_Airspeed , param [ 1 ] . tube_order , 2 ) ,
// @Param: 2_SKIP_CAL
2022-04-01 12:55:42 -03:00
// @DisplayName: Skip airspeed offset calibration on startup for 2nd sensor
2017-11-03 03:17:34 -03:00
// @Description: This parameter allows you to skip airspeed offset calibration on startup, instead using the offset from the last calibration. This may be desirable if the offset variance between flights for your sensor is low and you want to avoid having to cover the pitot tube on each boot.
// @Values: 0:Disable,1:Enable
// @User: Advanced
AP_GROUPINFO ( " 2_SKIP_CAL " , 18 , AP_Airspeed , param [ 1 ] . skip_cal , 0 ) ,
// @Param: 2_PSI_RANGE
// @DisplayName: The PSI range of the device for 2nd sensor
2022-05-23 01:51:28 -03:00
// @Description: This parameter allows you to set the PSI (pounds per square inch) range for your sensor. You should not change this unless you examine the datasheet for your device
2017-11-03 03:17:34 -03:00
// @User: Advanced
AP_GROUPINFO ( " 2_PSI_RANGE " , 19 , AP_Airspeed , param [ 1 ] . psi_range , PSI_RANGE_DEFAULT ) ,
// @Param: 2_BUS
// @DisplayName: Airspeed I2C bus for 2nd sensor
// @Description: The bus number of the I2C bus to look for the sensor on
2022-01-21 05:10:28 -04:00
// @Values: 0:Bus0(internal),1:Bus1(external),2:Bus2(auxiliary)
2017-11-03 03:17:34 -03:00
// @User: Advanced
AP_GROUPINFO ( " 2_BUS " , 20 , AP_Airspeed , param [ 1 ] . bus , 1 ) ,
2021-06-29 23:35:45 -03:00
# if AIRSPEED_MAX_SENSORS > 1
// @Param: 2_DEVID
// @DisplayName: Airspeed2 ID
// @Description: Airspeed2 sensor ID, taking into account its type, bus and instance
// @ReadOnly: True
// @User: Advanced
AP_GROUPINFO_FLAGS ( " 2_DEVID " , 25 , AP_Airspeed , param [ 1 ] . bus_id , 0 , AP_PARAM_FLAG_INTERNAL_USE_ONLY ) ,
# endif
2021-07-15 00:13:03 -03:00
# endif // AIRSPEED_MAX_SENSORS
// Note that 21, 22 and 23 are used above by the _OPTIONS, _WIND_MAX and _WIND_WARN parameters. Do not use them!!
2022-01-03 17:16:22 -04:00
// NOTE: Index 63 is used by AIRSPEED_TYPE, Do not use it!: AP_Param converts an index of 0 to 63 so that the index may be bit shifted
2012-07-15 22:21:20 -03:00
AP_GROUPEND
} ;
2018-11-16 12:16:23 -04:00
/*
this scaling factor converts from the old system where we used a
0 to 4095 raw ADC value for 0 - 5 V to the new system which gets the
voltage in volts directly from the ADC driver
*/
# define SCALING_OLD_CALIBRATION 819 // 4095/5
2018-03-09 17:12:05 -04:00
2016-08-08 00:29:50 -03:00
AP_Airspeed : : AP_Airspeed ( )
2016-06-08 09:13:53 -03:00
{
AP_Param : : setup_object_defaults ( this , var_info ) ;
2018-03-04 20:13:48 -04:00
if ( _singleton ! = nullptr ) {
AP_HAL : : panic ( " AP_Airspeed must be singleton " ) ;
}
_singleton = this ;
2016-08-07 21:48:54 -03:00
}
2016-06-08 09:13:53 -03:00
2021-09-03 20:56:09 -03:00
// macro for use by HAL_INS_PROBE_LIST
# define GET_I2C_DEVICE(bus, address) hal.i2c_mgr->get_device(bus, address)
bool AP_Airspeed : : add_backend ( AP_Airspeed_Backend * backend )
{
if ( ! backend ) {
return false ;
}
if ( num_sensors > = AIRSPEED_MAX_SENSORS ) {
AP_HAL : : panic ( " Too many airspeed drivers " ) ;
}
const uint8_t i = num_sensors ;
sensor [ num_sensors + + ] = backend ;
if ( ! sensor [ i ] - > init ( ) ) {
2021-11-03 17:19:47 -03:00
GCS_SEND_TEXT ( MAV_SEVERITY_ERROR , " Airspeed %u init failed " , i + 1 ) ;
2021-09-03 20:56:09 -03:00
delete sensor [ i ] ;
sensor [ i ] = nullptr ;
}
return true ;
}
/*
macro to add a backend with check for too many sensors
We don ' t try to start more than the maximum allowed
*/
# define ADD_BACKEND(backend) \
do { add_backend ( backend ) ; \
if ( num_sensors = = AIRSPEED_MAX_SENSORS ) { return ; } \
} while ( 0 )
2013-06-02 22:40:06 -03:00
void AP_Airspeed : : init ( )
2020-11-16 06:35:15 -04:00
{
2019-10-03 08:02:07 -03:00
if ( sensor [ 0 ] ! = nullptr ) {
// already initialised
return ;
}
2016-11-30 00:49:19 -04:00
// cope with upgrade from old system
2017-11-03 03:17:34 -03:00
if ( param [ 0 ] . pin . load ( ) & & param [ 0 ] . pin . get ( ) ! = 65 ) {
param [ 0 ] . type . set_default ( TYPE_ANALOG ) ;
2016-11-30 00:49:19 -04:00
}
2020-10-09 09:38:25 -03:00
# ifndef HAL_BUILD_AP_PERIPH
// Switch to dedicated WIND_MAX param
2021-11-23 01:33:31 -04:00
// PARAMETER_CONVERSION - Added: Oct-2020
2020-10-09 09:38:25 -03:00
const float ahrs_max_wind = AP : : ahrs ( ) . get_max_wind ( ) ;
if ( ! _wind_max . configured ( ) & & is_positive ( ahrs_max_wind ) ) {
_wind_max . set_and_save ( ahrs_max_wind ) ;
// Turn off _options to override the new default
if ( ! _options . configured ( ) ) {
_options . set_and_save ( 0 ) ;
}
}
# endif
2021-09-03 20:56:09 -03:00
# ifdef HAL_AIRSPEED_PROBE_LIST
// load sensors via a list from hwdef.dat
HAL_AIRSPEED_PROBE_LIST ;
# else
// look for sensors based on type parameters
2017-11-03 03:17:34 -03:00
for ( uint8_t i = 0 ; i < AIRSPEED_MAX_SENSORS ; i + + ) {
2019-10-03 08:02:07 -03:00
# if AP_AIRSPEED_AUTOCAL_ENABLE
2017-11-03 03:17:34 -03:00
state [ i ] . calibration . init ( param [ i ] . ratio ) ;
state [ i ] . last_saved_ratio = param [ i ] . ratio ;
2019-10-03 08:02:07 -03:00
# endif
2017-11-03 03:17:34 -03:00
2019-01-29 19:03:35 -04:00
// Set the enable automatically to false and set the probability that the airspeed is healhy to start with
state [ i ] . failures . health_probability = 1.0f ;
2017-11-03 03:17:34 -03:00
switch ( ( enum airspeed_type ) param [ i ] . type . get ( ) ) {
case TYPE_NONE :
// nothing to do
break ;
case TYPE_I2C_MS4525 :
2022-05-04 05:13:29 -03:00
# if AP_AIRSPEED_MS4525_ENABLED
2017-11-03 03:17:34 -03:00
sensor [ i ] = new AP_Airspeed_MS4525 ( * this , i ) ;
2022-05-24 01:14:25 -03:00
# endif
break ;
case TYPE_SITL :
# if AP_AIRSPEED_SITL_ENABLED
sensor [ i ] = new AP_Airspeed_SITL ( * this , i ) ;
2022-05-04 05:13:29 -03:00
# endif
2017-11-03 03:17:34 -03:00
break ;
case TYPE_ANALOG :
2022-05-04 05:13:29 -03:00
# if AP_AIRSPEED_ANALOG_ENABLED
2017-11-03 03:17:34 -03:00
sensor [ i ] = new AP_Airspeed_Analog ( * this , i ) ;
2022-05-04 05:13:29 -03:00
# endif
2017-11-03 03:17:34 -03:00
break ;
case TYPE_I2C_MS5525 :
2022-05-04 05:13:29 -03:00
# if AP_AIRSPEED_MS5525_ENABLED
2017-11-03 03:17:34 -03:00
sensor [ i ] = new AP_Airspeed_MS5525 ( * this , i , AP_Airspeed_MS5525 : : MS5525_ADDR_AUTO ) ;
2022-05-04 05:13:29 -03:00
# endif
2017-11-03 03:17:34 -03:00
break ;
case TYPE_I2C_MS5525_ADDRESS_1 :
2022-05-04 05:13:29 -03:00
# if AP_AIRSPEED_MS5525_ENABLED
2017-11-03 03:17:34 -03:00
sensor [ i ] = new AP_Airspeed_MS5525 ( * this , i , AP_Airspeed_MS5525 : : MS5525_ADDR_1 ) ;
2022-05-04 05:13:29 -03:00
# endif
2017-11-03 03:17:34 -03:00
break ;
case TYPE_I2C_MS5525_ADDRESS_2 :
2022-05-04 05:13:29 -03:00
# if AP_AIRSPEED_MS5525_ENABLED
2017-11-03 03:17:34 -03:00
sensor [ i ] = new AP_Airspeed_MS5525 ( * this , i , AP_Airspeed_MS5525 : : MS5525_ADDR_2 ) ;
2022-05-04 05:13:29 -03:00
# endif
2017-11-03 03:17:34 -03:00
break ;
case TYPE_I2C_SDP3X :
2022-05-04 05:13:29 -03:00
# if AP_AIRSPEED_SDP3X_ENABLED
2017-11-03 03:17:34 -03:00
sensor [ i ] = new AP_Airspeed_SDP3X ( * this , i ) ;
2022-05-04 05:13:29 -03:00
# endif
2017-11-03 03:17:34 -03:00
break ;
2019-07-18 02:19:09 -03:00
case TYPE_I2C_DLVR_5IN :
2022-05-04 05:13:29 -03:00
# if AP_AIRSPEED_DLVR_ENABLED
2019-07-18 02:19:09 -03:00
sensor [ i ] = new AP_Airspeed_DLVR ( * this , i , 5 ) ;
2022-05-04 05:13:29 -03:00
# endif
2019-07-18 02:19:09 -03:00
break ;
case TYPE_I2C_DLVR_10IN :
2022-05-04 05:13:29 -03:00
# if AP_AIRSPEED_DLVR_ENABLED
2019-07-18 02:19:09 -03:00
sensor [ i ] = new AP_Airspeed_DLVR ( * this , i , 10 ) ;
2022-05-04 05:13:29 -03:00
# endif
2020-08-04 18:53:27 -03:00
break ;
case TYPE_I2C_DLVR_20IN :
2022-05-04 05:13:29 -03:00
# if AP_AIRSPEED_DLVR_ENABLED
2020-08-04 18:53:27 -03:00
sensor [ i ] = new AP_Airspeed_DLVR ( * this , i , 20 ) ;
2022-05-04 05:13:29 -03:00
# endif
2020-08-04 18:53:27 -03:00
break ;
case TYPE_I2C_DLVR_30IN :
2022-05-04 05:13:29 -03:00
# if AP_AIRSPEED_DLVR_ENABLED
2020-08-04 18:53:27 -03:00
sensor [ i ] = new AP_Airspeed_DLVR ( * this , i , 30 ) ;
2022-05-04 05:13:29 -03:00
# endif
2020-08-04 18:53:27 -03:00
break ;
case TYPE_I2C_DLVR_60IN :
2022-05-04 05:13:29 -03:00
# if AP_AIRSPEED_DLVR_ENABLED
2020-08-04 18:53:27 -03:00
sensor [ i ] = new AP_Airspeed_DLVR ( * this , i , 60 ) ;
2022-05-04 05:13:29 -03:00
# endif // AP_AIRSPEED_DLVR_ENABLED
2021-03-23 11:18:41 -03:00
break ;
case TYPE_I2C_ASP5033 :
2022-05-04 05:13:29 -03:00
# if AP_AIRSPEED_ASP5033_ENABLED
2021-03-23 11:18:41 -03:00
sensor [ i ] = new AP_Airspeed_ASP5033 ( * this , i ) ;
2022-05-04 05:13:29 -03:00
# endif
2018-07-11 23:05:12 -03:00
break ;
2018-09-05 03:45:01 -03:00
case TYPE_UAVCAN :
2022-05-04 05:13:29 -03:00
# if AP_AIRSPEED_UAVCAN_ENABLED
2018-09-05 03:45:01 -03:00
sensor [ i ] = AP_Airspeed_UAVCAN : : probe ( * this , i ) ;
2020-07-18 16:49:08 -03:00
# endif
break ;
case TYPE_NMEA_WATER :
2022-05-04 05:13:29 -03:00
# if AP_AIRSPEED_NMEA_ENABLED
2020-07-18 16:49:08 -03:00
# if APM_BUILD_TYPE(APM_BUILD_Rover) || APM_BUILD_TYPE(APM_BUILD_ArduSub)
sensor [ i ] = new AP_Airspeed_NMEA ( * this , i ) ;
2022-05-04 05:13:29 -03:00
# endif
2020-11-16 06:35:15 -04:00
# endif
break ;
case TYPE_MSP :
2022-05-04 05:13:29 -03:00
# if AP_AIRSPEED_MSP_ENABLED
2020-11-16 06:35:15 -04:00
sensor [ i ] = new AP_Airspeed_MSP ( * this , i , 0 ) ;
2018-09-05 03:45:01 -03:00
# endif
break ;
2017-11-03 03:17:34 -03:00
}
if ( sensor [ i ] & & ! sensor [ i ] - > init ( ) ) {
2021-11-03 17:19:47 -03:00
GCS_SEND_TEXT ( MAV_SEVERITY_ERROR , " Airspeed %u init failed " , i + 1 ) ;
2017-11-03 03:17:34 -03:00
delete sensor [ i ] ;
sensor [ i ] = nullptr ;
}
2019-05-03 08:23:58 -03:00
if ( sensor [ i ] ! = nullptr ) {
num_sensors = i + 1 ;
}
2016-11-30 00:49:19 -04:00
}
2021-09-03 20:56:09 -03:00
# endif // HAL_AIRSPEED_PROBE_LIST
2013-06-02 22:40:06 -03:00
}
// read the airspeed sensor
2017-11-03 03:17:34 -03:00
float AP_Airspeed : : get_pressure ( uint8_t i )
2013-06-02 22:40:06 -03:00
{
2017-11-03 03:17:34 -03:00
if ( ! enabled ( i ) ) {
2013-06-02 22:40:06 -03:00
return 0 ;
}
2013-09-28 05:40:29 -03:00
float pressure = 0 ;
2017-11-03 03:17:34 -03:00
if ( sensor [ i ] ) {
state [ i ] . healthy = sensor [ i ] - > get_differential_pressure ( pressure ) ;
2013-06-02 22:40:06 -03:00
}
2013-09-28 05:40:29 -03:00
return pressure ;
2013-06-02 22:40:06 -03:00
}
2014-01-27 19:35:35 -04:00
// get a temperature reading if possible
2017-11-03 03:17:34 -03:00
bool AP_Airspeed : : get_temperature ( uint8_t i , float & temperature )
2014-01-27 19:35:35 -04:00
{
2017-11-03 03:17:34 -03:00
if ( ! enabled ( i ) ) {
2014-01-27 19:35:35 -04:00
return false ;
}
2017-11-03 03:17:34 -03:00
if ( sensor [ i ] ) {
return sensor [ i ] - > get_temperature ( temperature ) ;
2014-01-27 19:35:35 -04:00
}
return false ;
}
2017-11-03 03:17:34 -03:00
// calibrate the zero offset for the airspeed. This must be called at
// least once before the get_airspeed() interface can be used
2014-11-13 06:12:37 -04:00
void AP_Airspeed : : calibrate ( bool in_startup )
2012-07-15 22:21:20 -03:00
{
2019-04-11 06:57:19 -03:00
if ( hal . util - > was_watchdog_reset ( ) ) {
2019-10-03 08:02:07 -03:00
GCS_SEND_TEXT ( MAV_SEVERITY_INFO , " Airspeed: skipping cal " ) ;
2019-04-11 06:57:19 -03:00
return ;
}
2017-11-03 03:17:34 -03:00
for ( uint8_t i = 0 ; i < AIRSPEED_MAX_SENSORS ; i + + ) {
if ( ! enabled ( i ) ) {
continue ;
}
if ( state [ i ] . use_zero_offset ) {
param [ i ] . offset . set ( 0 ) ;
continue ;
}
if ( in_startup & & param [ i ] . skip_cal ) {
continue ;
}
2021-10-05 19:42:22 -03:00
if ( sensor [ i ] = = nullptr ) {
2021-11-03 17:19:47 -03:00
GCS_SEND_TEXT ( MAV_SEVERITY_ERROR , " Airspeed %u not initalized, cannot cal " , i + 1 ) ;
2021-10-05 19:42:22 -03:00
continue ;
}
2017-11-03 03:17:34 -03:00
state [ i ] . cal . start_ms = AP_HAL : : millis ( ) ;
state [ i ] . cal . count = 0 ;
state [ i ] . cal . sum = 0 ;
state [ i ] . cal . read_count = 0 ;
2020-07-13 13:09:55 -03:00
GCS_SEND_TEXT ( MAV_SEVERITY_INFO , " Airspeed %u calibration started " , i + 1 ) ;
2014-11-13 06:12:37 -04:00
}
2016-05-24 01:22:40 -03:00
}
2016-06-26 21:52:59 -03:00
/*
2017-11-03 03:17:34 -03:00
update async airspeed zero offset calibration
2016-06-26 21:52:59 -03:00
*/
2017-11-03 03:17:34 -03:00
void AP_Airspeed : : update_calibration ( uint8_t i , float raw_pressure )
2016-05-24 01:22:40 -03:00
{
2017-11-03 03:17:34 -03:00
if ( ! enabled ( i ) | | state [ i ] . cal . start_ms = = 0 ) {
return ;
}
2016-12-05 21:19:57 -04:00
// consider calibration complete when we have at least 15 samples
2016-06-26 21:52:59 -03:00
// over at least 1 second
2017-11-03 03:17:34 -03:00
if ( AP_HAL : : millis ( ) - state [ i ] . cal . start_ms > = 1000 & &
state [ i ] . cal . read_count > 15 ) {
if ( state [ i ] . cal . count = = 0 ) {
2021-11-03 17:19:47 -03:00
GCS_SEND_TEXT ( MAV_SEVERITY_WARNING , " Airspeed %u unhealthy " , i + 1 ) ;
2016-05-24 01:22:40 -03:00
} else {
2019-10-03 08:02:07 -03:00
GCS_SEND_TEXT ( MAV_SEVERITY_INFO , " Airspeed %u calibrated " , i + 1 ) ;
2017-11-03 03:17:34 -03:00
param [ i ] . offset . set_and_save ( state [ i ] . cal . sum / state [ i ] . cal . count ) ;
2013-09-28 05:40:29 -03:00
}
2017-11-03 03:17:34 -03:00
state [ i ] . cal . start_ms = 0 ;
2013-09-28 05:40:29 -03:00
return ;
2012-08-17 03:08:43 -03:00
}
2016-11-30 02:21:48 -04:00
// we discard the first 5 samples
2017-11-03 03:17:34 -03:00
if ( state [ i ] . healthy & & state [ i ] . cal . read_count > 5 ) {
state [ i ] . cal . sum + = raw_pressure ;
state [ i ] . cal . count + + ;
2016-05-24 01:22:40 -03:00
}
2017-11-03 03:17:34 -03:00
state [ i ] . cal . read_count + + ;
2012-07-15 22:21:20 -03:00
}
2017-11-03 03:17:34 -03:00
// read one airspeed sensor
void AP_Airspeed : : read ( uint8_t i )
2012-07-15 22:21:20 -03:00
{
2017-11-03 03:17:34 -03:00
if ( ! enabled ( i ) | | ! sensor [ i ] ) {
2012-08-17 03:08:43 -03:00
return ;
}
2020-07-18 16:49:08 -03:00
state [ i ] . last_update_ms = AP_HAL : : millis ( ) ;
// try and get a direct reading of airspeed
if ( sensor [ i ] - > has_airspeed ( ) ) {
state [ i ] . healthy = sensor [ i ] - > get_airspeed ( state [ i ] . airspeed ) ;
2020-12-03 23:12:54 -04:00
state [ i ] . raw_airspeed = state [ i ] . airspeed ; // for logging
2020-07-18 16:49:08 -03:00
return ;
}
2018-06-10 19:45:11 -03:00
bool prev_healthy = state [ i ] . healthy ;
2017-11-03 03:17:34 -03:00
float raw_pressure = get_pressure ( i ) ;
if ( state [ i ] . cal . start_ms ! = 0 ) {
update_calibration ( i , raw_pressure ) ;
2016-05-24 01:22:40 -03:00
}
2020-07-18 16:49:08 -03:00
float airspeed_pressure = raw_pressure - param [ i ] . offset ;
2014-02-14 07:07:12 -04:00
2014-11-13 02:49:04 -04:00
// remember raw pressure for logging
2017-11-03 03:17:34 -03:00
state [ i ] . corrected_pressure = airspeed_pressure ;
2014-11-13 02:49:04 -04:00
2017-09-19 16:28:56 -03:00
// filter before clamping positive
2018-06-10 19:45:11 -03:00
if ( ! prev_healthy ) {
// if the previous state was not healthy then we should not
// use an IIR filter, otherwise a bad reading will last for
// some time after the sensor becomees healthy again
state [ i ] . filtered_pressure = airspeed_pressure ;
} else {
state [ i ] . filtered_pressure = 0.7f * state [ i ] . filtered_pressure + 0.3f * airspeed_pressure ;
}
2017-09-19 16:28:56 -03:00
2014-02-13 02:21:06 -04:00
/*
2017-09-19 16:28:56 -03:00
we support different pitot tube setups so user can choose if
2014-02-14 07:07:12 -04:00
they want to be able to detect pressure on the static port
2014-02-13 02:21:06 -04:00
*/
2017-11-03 03:17:34 -03:00
switch ( ( enum pitot_tube_order ) param [ i ] . tube_order . get ( ) ) {
2014-02-14 07:07:12 -04:00
case PITOT_TUBE_ORDER_NEGATIVE :
2017-11-03 03:17:34 -03:00
state [ i ] . last_pressure = - airspeed_pressure ;
state [ i ] . raw_airspeed = sqrtf ( MAX ( - airspeed_pressure , 0 ) * param [ i ] . ratio ) ;
state [ i ] . airspeed = sqrtf ( MAX ( - state [ i ] . filtered_pressure , 0 ) * param [ i ] . ratio ) ;
2017-09-19 16:28:56 -03:00
break ;
2014-02-14 07:07:12 -04:00
case PITOT_TUBE_ORDER_POSITIVE :
2017-11-03 03:17:34 -03:00
state [ i ] . last_pressure = airspeed_pressure ;
state [ i ] . raw_airspeed = sqrtf ( MAX ( airspeed_pressure , 0 ) * param [ i ] . ratio ) ;
state [ i ] . airspeed = sqrtf ( MAX ( state [ i ] . filtered_pressure , 0 ) * param [ i ] . ratio ) ;
2014-02-14 07:07:12 -04:00
break ;
case PITOT_TUBE_ORDER_AUTO :
default :
2017-11-03 03:17:34 -03:00
state [ i ] . last_pressure = fabsf ( airspeed_pressure ) ;
state [ i ] . raw_airspeed = sqrtf ( fabsf ( airspeed_pressure ) * param [ i ] . ratio ) ;
state [ i ] . airspeed = sqrtf ( fabsf ( state [ i ] . filtered_pressure ) * param [ i ] . ratio ) ;
2014-02-14 07:07:12 -04:00
break ;
2014-02-13 02:21:06 -04:00
}
2017-11-03 03:17:34 -03:00
}
// read all airspeed sensors
2022-01-03 17:16:22 -04:00
void AP_Airspeed : : update ( )
2017-11-03 03:17:34 -03:00
{
for ( uint8_t i = 0 ; i < AIRSPEED_MAX_SENSORS ; i + + ) {
read ( i ) ;
}
2021-08-18 08:42:16 -03:00
# if HAL_GCS_ENABLED
2017-11-03 03:17:34 -03:00
// debugging until we get MAVLink support for 2nd airspeed sensor
if ( enabled ( 1 ) ) {
2018-05-13 06:29:47 -03:00
gcs ( ) . send_named_float ( " AS2 " , get_airspeed ( 1 ) ) ;
2017-11-03 03:17:34 -03:00
}
# endif
2022-05-13 01:02:24 -03:00
# if HAL_LOGGING_ENABLED
const uint8_t old_primary = primary ;
# endif
2018-03-09 17:12:05 -04:00
// setup primary
if ( healthy ( primary_sensor . get ( ) ) ) {
primary = primary_sensor . get ( ) ;
2019-01-29 22:02:40 -04:00
} else {
for ( uint8_t i = 0 ; i < AIRSPEED_MAX_SENSORS ; i + + ) {
if ( healthy ( i ) ) {
primary = i ;
break ;
}
}
2018-03-09 04:07:34 -04:00
}
2019-01-29 22:02:40 -04:00
check_sensor_failures ( ) ;
2022-01-03 17:16:22 -04:00
# if HAL_LOGGING_ENABLED
2022-05-13 01:02:24 -03:00
if ( primary ! = old_primary ) {
AP : : logger ( ) . Write_Event ( LogEvent : : AIRSPEED_PRIMARY_CHANGED ) ;
}
2022-01-03 17:16:22 -04:00
if ( _log_bit ! = ( uint32_t ) - 1 & & AP : : logger ( ) . should_log ( _log_bit ) ) {
2019-04-05 23:48:44 -03:00
Log_Airspeed ( ) ;
}
2019-10-03 08:02:07 -03:00
# endif
2019-04-05 23:48:44 -03:00
}
2022-05-04 05:13:29 -03:00
# if AP_AIRSPEED_MSP_ENABLED
2020-11-16 06:35:15 -04:00
/*
handle MSP airspeed data
*/
void AP_Airspeed : : handle_msp ( const MSP : : msp_airspeed_data_message_t & pkt )
{
if ( pkt . instance > 1 ) {
return ; //supporting 2 airspeed sensors at most
}
for ( uint8_t i = 0 ; i < AIRSPEED_MAX_SENSORS ; i + + ) {
if ( sensor [ i ] ) {
sensor [ i ] - > handle_msp ( pkt ) ;
}
}
}
# endif
2019-04-05 23:48:44 -03:00
void AP_Airspeed : : Log_Airspeed ( )
{
const uint64_t now = AP_HAL : : micros64 ( ) ;
for ( uint8_t i = 0 ; i < AIRSPEED_MAX_SENSORS ; i + + ) {
if ( ! enabled ( i ) ) {
continue ;
}
float temperature ;
if ( ! get_temperature ( i , temperature ) ) {
temperature = 0 ;
}
2020-11-18 18:52:48 -04:00
const struct log_ARSP pkt {
LOG_PACKET_HEADER_INIT ( LOG_ARSP_MSG ) ,
2019-04-05 23:48:44 -03:00
time_us : now ,
2020-11-18 18:52:48 -04:00
instance : i ,
2019-04-05 23:48:44 -03:00
airspeed : get_raw_airspeed ( i ) ,
diffpressure : get_differential_pressure ( i ) ,
temperature : ( int16_t ) ( temperature * 100.0f ) ,
rawpressure : get_corrected_pressure ( i ) ,
offset : get_offset ( i ) ,
use : use ( i ) ,
healthy : healthy ( i ) ,
2022-03-01 13:44:43 -04:00
health_prob : get_health_probability ( i ) ,
2019-04-05 23:48:44 -03:00
primary : get_primary ( )
} ;
AP : : logger ( ) . WriteBlock ( & pkt , sizeof ( pkt ) ) ;
2017-11-03 03:17:34 -03:00
}
2012-07-15 22:21:20 -03:00
}
2014-02-17 18:24:14 -04:00
2017-11-03 03:17:34 -03:00
bool AP_Airspeed : : use ( uint8_t i ) const
2017-04-29 03:53:39 -03:00
{
2021-06-17 03:03:35 -03:00
if ( _force_disable_use ) {
return false ;
}
2017-11-03 03:17:34 -03:00
if ( ! enabled ( i ) | | ! param [ i ] . use ) {
2017-04-29 03:53:39 -03:00
return false ;
}
2019-10-03 08:02:07 -03:00
# ifndef HAL_BUILD_AP_PERIPH
2021-09-18 14:55:41 -03:00
if ( param [ i ] . use = = 2 & & ! is_zero ( SRV_Channels : : get_output_scaled ( SRV_Channel : : k_throttle ) ) ) {
2017-04-29 03:53:39 -03:00
// special case for gliders with airspeed sensors behind the
// propeller. Allow airspeed to be disabled when throttle is
// running
return false ;
}
2019-10-03 08:02:07 -03:00
# endif
2017-04-29 03:53:39 -03:00
return true ;
}
2017-11-03 03:17:34 -03:00
/*
return true if all enabled sensors are healthy
*/
bool AP_Airspeed : : all_healthy ( void ) const
{
for ( uint8_t i = 0 ; i < AIRSPEED_MAX_SENSORS ; i + + ) {
if ( enabled ( i ) & & ! healthy ( i ) ) {
return false ;
}
}
return true ;
}
2018-03-04 20:13:48 -04:00
2022-04-20 06:06:58 -03:00
// return true if airspeed is enabled
bool AP_Airspeed : : enabled ( uint8_t i ) const {
if ( i < AIRSPEED_MAX_SENSORS ) {
return param [ i ] . type . get ( ) ! = TYPE_NONE ;
}
return false ;
}
// return health status of sensor
bool AP_Airspeed : : healthy ( uint8_t i ) const {
2022-04-20 06:07:57 -03:00
bool ok = state [ i ] . healthy & & enabled ( i ) & & sensor [ i ] ! = nullptr ;
2022-04-20 06:06:58 -03:00
# ifndef HAL_BUILD_AP_PERIPH
// sanity check the offset parameter. Zero is permitted if we are skipping calibration.
ok & = ( fabsf ( param [ i ] . offset ) > 0 | | state [ i ] . use_zero_offset | | param [ i ] . skip_cal ) ;
# endif
return ok ;
}
2022-04-20 06:09:12 -03:00
// return the current airspeed in m/s
float AP_Airspeed : : get_airspeed ( uint8_t i ) const {
if ( ! enabled ( i ) ) {
// we can't have negative airspeed so sending an obviously invalid value
return - 1.0 ;
}
return state [ i ] . airspeed ;
}
// return the unfiltered airspeed in m/s
float AP_Airspeed : : get_raw_airspeed ( uint8_t i ) const {
if ( ! enabled ( i ) ) {
// we can't have negative airspeed so sending an obviously invalid value
return - 1.0 ;
}
return state [ i ] . raw_airspeed ;
}
// return the differential pressure in Pascal for the last airspeed reading
float AP_Airspeed : : get_differential_pressure ( uint8_t i ) const {
if ( ! enabled ( i ) ) {
return 0.0 ;
}
return state [ i ] . last_pressure ;
}
// return the current corrected pressure
float AP_Airspeed : : get_corrected_pressure ( uint8_t i ) const {
if ( ! enabled ( i ) ) {
return 0.0 ;
}
return state [ i ] . corrected_pressure ;
}
2022-01-02 03:41:01 -04:00
# else // build type is not appropriate; provide a dummy implementation:
const AP_Param : : GroupInfo AP_Airspeed : : var_info [ ] = { AP_GROUPEND } ;
void AP_Airspeed : : update ( ) { } ;
bool AP_Airspeed : : get_temperature ( uint8_t i , float & temperature ) { return false ; }
void AP_Airspeed : : calibrate ( bool in_startup ) { }
bool AP_Airspeed : : use ( uint8_t i ) const { return false ; }
2022-04-20 06:06:58 -03:00
bool AP_Airspeed : : enabled ( uint8_t i ) const { return false ; }
bool AP_Airspeed : : healthy ( uint8_t i ) const { return false ; }
2022-04-20 06:09:12 -03:00
float AP_Airspeed : : get_airspeed ( uint8_t i ) const { return 0.0 ; }
float AP_Airspeed : : get_differential_pressure ( uint8_t i ) const { return 0.0 ; }
2022-01-02 03:41:01 -04:00
2022-05-04 05:13:29 -03:00
# if AP_AIRSPEED_MSP_ENABLED
2022-01-02 03:41:01 -04:00
void AP_Airspeed : : handle_msp ( const MSP : : msp_airspeed_data_message_t & pkt ) { }
# endif
bool AP_Airspeed : : all_healthy ( void ) const { return false ; }
void AP_Airspeed : : init ( void ) { } ;
AP_Airspeed : : AP_Airspeed ( ) { }
# endif // #if AP_AIRSPEED_DUMMY_METHODS_ENABLED
2018-03-04 20:13:48 -04:00
// singleton instance
AP_Airspeed * AP_Airspeed : : _singleton ;
2019-04-05 22:10:17 -03:00
namespace AP {
AP_Airspeed * airspeed ( )
{
return AP_Airspeed : : get_singleton ( ) ;
}
} ;