Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/libraries/AP_Baro/AP_Baro.h
Views: 1798
#pragma once12#include "AP_Baro_config.h"34#include <AP_HAL/AP_HAL.h>5#include <AP_Param/AP_Param.h>6#include <AP_Math/AP_Math.h>7#include <Filter/DerivativeFilter.h>8#include <AP_MSP/msp.h>9#include <AP_ExternalAHRS/AP_ExternalAHRS.h>1011// maximum number of sensor instances12#ifndef BARO_MAX_INSTANCES13#define BARO_MAX_INSTANCES 314#endif1516// maximum number of drivers. Note that a single driver can provide17// multiple sensor instances18#define BARO_MAX_DRIVERS 31920// timeouts for health reporting21#define BARO_TIMEOUT_MS 500 // timeout in ms since last successful read22#define BARO_DATA_CHANGE_TIMEOUT_MS 2000 // timeout in ms since last successful read that involved temperature of pressure changing2324class AP_Baro_Backend;2526class AP_Baro27{28friend class AP_Baro_Backend;29friend class AP_Baro_SITL; // for access to sensors[]30friend class AP_Baro_DroneCAN; // for access to sensors[]3132public:33AP_Baro();3435/* Do not allow copies */36CLASS_NO_COPY(AP_Baro);3738// get singleton39static AP_Baro *get_singleton(void) {40return _singleton;41}4243// barometer types44typedef enum {45BARO_TYPE_AIR,46BARO_TYPE_WATER47} baro_type_t;4849// initialise the barometer object, loading backend drivers50void init(void);5152// update the barometer object, asking backends to push data to53// the frontend54void update(void);5556// healthy - returns true if sensor and derived altitude are good57bool healthy(void) const { return healthy(_primary); }5859bool healthy(uint8_t instance) const;6061// check if all baros are healthy - used for SYS_STATUS report62bool all_healthy(void) const;6364// returns false if we fail arming checks, in which case the buffer will be populated with a failure message65bool arming_checks(size_t buflen, char *buffer) const;6667// get primary sensor68uint8_t get_primary(void) const { return _primary; }6970// pressure in Pascal. Divide by 100 for millibars or hectopascals71float get_pressure(void) const { return get_pressure(_primary); }72float get_pressure(uint8_t instance) const { return sensors[instance].pressure; }73#if HAL_BARO_WIND_COMP_ENABLED74// dynamic pressure in Pascal. Divide by 100 for millibars or hectopascals75const Vector3f& get_dynamic_pressure(uint8_t instance) const { return sensors[instance].dynamic_pressure; }76#endif7778// temperature in degrees C79float get_temperature(void) const { return get_temperature(_primary); }80float get_temperature(uint8_t instance) const { return sensors[instance].temperature; }8182// get pressure correction in Pascal. Divide by 100 for millibars or hectopascals83float get_pressure_correction(void) const { return get_pressure_correction(_primary); }84float get_pressure_correction(uint8_t instance) const { return sensors[instance].p_correction; }8586// calibrate the barometer. This must be called on startup if the87// altitude/climb_rate/acceleration interfaces are ever used88void calibrate(bool save=true);8990// update the barometer calibration to the current pressure. Can91// be used for incremental preflight update of baro92void update_calibration(void);9394// get current altitude in meters relative to altitude at the time95// of the last calibrate() call96float get_altitude(void) const { return get_altitude(_primary); }97float get_altitude(uint8_t instance) const { return sensors[instance].altitude; }9899// get altitude above mean sea level100float get_altitude_AMSL(uint8_t instance) const { return get_altitude(instance) + _field_elevation_active; }101float get_altitude_AMSL(void) const { return get_altitude_AMSL(_primary); }102103// returns which i2c bus is considered "the" external bus104uint8_t external_bus() const { return _ext_bus; }105106// Atmospheric Model Functions107static float geometric_alt_to_geopotential(float alt);108static float geopotential_alt_to_geometric(float alt);109110float get_temperature_from_altitude(float alt) const;111float get_altitude_from_pressure(float pressure) const;112113// EAS2TAS for SITL114static float get_EAS2TAS_for_alt_amsl(float alt_amsl);115116#if AP_BARO_1976_STANDARD_ATMOSPHERE_ENABLED117// lookup expected pressure for a given altitude. Used for SITL backend118static void get_pressure_temperature_for_alt_amsl(float alt_amsl, float &pressure, float &temperature_K);119#endif120121// lookup expected temperature in degrees C for a given altitude. Used for SITL backend122static float get_temperatureC_for_alt_amsl(const float alt_amsl);123124// lookup expected pressure in Pa for a given altitude. Used for SITL backend125static float get_pressure_for_alt_amsl(const float alt_amsl);126127// get air density for SITL128static float get_air_density_for_alt_amsl(float alt_amsl);129130// get altitude difference in meters relative given a base131// pressure in Pascal132float get_altitude_difference(float base_pressure, float pressure) const;133134// get sea level pressure relative to 1976 standard atmosphere model135// pressure in Pascal136float get_sealevel_pressure(float pressure, float altitude) const;137138// get scale factor required to convert equivalent to true139// airspeed. This should only be used to update the AHRS value140// once per loop. Please use AP::ahrs().get_EAS2TAS()141float _get_EAS2TAS(void) const;142143// get air density / sea level density - decreases as altitude climbs144// please use AP::ahrs()::get_air_density_ratio()145float _get_air_density_ratio(void);146147// get current climb rate in meters/s. A positive number means148// going up149float get_climb_rate(void);150151// ground temperature in degrees C152// the ground values are only valid after calibration153float get_ground_temperature(void) const;154155// ground pressure in Pascal156// the ground values are only valid after calibration157float get_ground_pressure(void) const { return get_ground_pressure(_primary); }158float get_ground_pressure(uint8_t i) const { return sensors[i].ground_pressure.get(); }159160// set the temperature to be used for altitude calibration. This161// allows an external temperature source (such as a digital162// airspeed sensor) to be used as the temperature source163void set_external_temperature(float temperature);164165// get last time sample was taken (in ms)166uint32_t get_last_update(void) const { return get_last_update(_primary); }167uint32_t get_last_update(uint8_t instance) const { return sensors[instance].last_update_ms; }168169// settable parameters170static const struct AP_Param::GroupInfo var_info[];171172float get_external_temperature(void) const { return get_external_temperature(_primary); };173float get_external_temperature(const uint8_t instance) const;174175// Set the primary baro176void set_primary_baro(uint8_t primary) { _primary_baro.set_and_save(primary); };177178// Set the type (Air or Water) of a particular instance179void set_type(uint8_t instance, baro_type_t type) { sensors[instance].type = type; };180181// Get the type (Air or Water) of a particular instance182baro_type_t get_type(uint8_t instance) { return sensors[instance].type; };183184// register a new sensor, claiming a sensor slot. If we are out of185// slots it will panic186uint8_t register_sensor(void);187188// return number of registered sensors189uint8_t num_instances(void) const { return _num_sensors; }190191// set baro drift amount192void set_baro_drift_altitude(float alt) { _alt_offset.set(alt); }193194// get baro drift amount195float get_baro_drift_offset(void) const { return _alt_offset_active; }196197// simple underwater atmospheric model198static void SimpleUnderWaterAtmosphere(float alt, float &rho, float &delta, float &theta);199200// set a pressure correction from AP_TempCalibration201void set_pressure_correction(uint8_t instance, float p_correction);202203uint8_t get_filter_range() const { return _filter_range; }204205// indicate which bit in LOG_BITMASK indicates baro logging enabled206void set_log_baro_bit(uint32_t bit) { _log_baro_bit = bit; }207bool should_log() const;208209// allow threads to lock against baro update210HAL_Semaphore &get_semaphore(void) {211return _rsem;212}213214#if AP_BARO_MSP_ENABLED215void handle_msp(const MSP::msp_baro_data_message_t &pkt);216#endif217#if AP_BARO_EXTERNALAHRS_ENABLED218void handle_external(const AP_ExternalAHRS::baro_data_message_t &pkt);219#endif220221enum Options : uint16_t {222TreatMS5611AsMS5607 = (1U << 0U),223};224225// check if an option is set226bool option_enabled(const Options option) const227{228return (uint16_t(_options.get()) & uint16_t(option)) != 0;229}230231private:232// singleton233static AP_Baro *_singleton;234235// how many drivers do we have?236uint8_t _num_drivers;237AP_Baro_Backend *drivers[BARO_MAX_DRIVERS];238239// how many sensors do we have?240uint8_t _num_sensors;241242// what is the primary sensor at the moment?243uint8_t _primary;244245uint32_t _log_baro_bit = -1;246247bool init_done;248249uint8_t msp_instance_mask;250251// bitmask values for GND_PROBE_EXT252enum {253PROBE_BMP085=(1<<0),254PROBE_BMP280=(1<<1),255PROBE_MS5611=(1<<2),256PROBE_MS5607=(1<<3),257PROBE_MS5637=(1<<4),258PROBE_FBM320=(1<<5),259PROBE_DPS280=(1<<6),260PROBE_LPS25H=(1<<7),261PROBE_KELLER=(1<<8),262PROBE_MS5837=(1<<9),263PROBE_BMP388=(1<<10),264PROBE_SPL06 =(1<<11),265PROBE_MSP =(1<<12),266PROBE_BMP581=(1<<13),267};268269#if HAL_BARO_WIND_COMP_ENABLED270class WindCoeff {271public:272static const struct AP_Param::GroupInfo var_info[];273274AP_Int8 enable; // enable compensation for this barometer275AP_Float xp; // ratio of static pressure rise to dynamic pressure when flying forwards276AP_Float xn; // ratio of static pressure rise to dynamic pressure when flying backwards277AP_Float yp; // ratio of static pressure rise to dynamic pressure when flying to the right278AP_Float yn; // ratio of static pressure rise to dynamic pressure when flying to the left279AP_Float zp; // ratio of static pressure rise to dynamic pressure when flying up280AP_Float zn; // ratio of static pressure rise to dynamic pressure when flying down281};282#endif283284struct sensor {285uint32_t last_update_ms; // last update time in ms286uint32_t last_change_ms; // last update time in ms that included a change in reading from previous readings287float pressure; // pressure in Pascal288float temperature; // temperature in degrees C289float altitude; // calculated altitude290AP_Float ground_pressure;291float p_correction;292baro_type_t type; // 0 for air pressure (default), 1 for water pressure293bool healthy; // true if sensor is healthy294bool alt_ok; // true if calculated altitude is ok295bool calibrated; // true if calculated calibrated successfully296AP_Int32 bus_id;297#if HAL_BARO_WIND_COMP_ENABLED298WindCoeff wind_coeff;299Vector3f dynamic_pressure; // calculated dynamic pressure300#endif301} sensors[BARO_MAX_INSTANCES];302303AP_Float _alt_offset;304float _alt_offset_active;305AP_Float _field_elevation; // field elevation in meters306float _field_elevation_active;307uint32_t _field_elevation_last_ms;308AP_Int8 _primary_baro; // primary chosen by user309AP_Int8 _ext_bus; // bus number for external barometer310float _external_temperature;311uint32_t _last_external_temperature_ms;312DerivativeFilterFloat_Size7 _climb_rate_filter;313AP_Float _specific_gravity; // the specific gravity of fluid for an ROV 1.00 for freshwater, 1.024 for salt water314AP_Float _user_ground_temperature; // user override of the ground temperature used for EAS2TAS315float _guessed_ground_temperature; // currently ground temperature estimate using our best available source316317// when did we last notify the GCS of new pressure reference?318uint32_t _last_notify_ms;319320// see if we already have probed a i2c driver by bus number and address321bool _have_i2c_driver(uint8_t bus_num, uint8_t address) const;322bool _add_backend(AP_Baro_Backend *backend);323void _probe_i2c_barometers(void);324AP_Int8 _filter_range; // valid value range from mean value325AP_Int32 _baro_probe_ext;326327#ifndef HAL_BUILD_AP_PERIPH328AP_Float _alt_error_max;329#endif330331AP_Int16 _options;332333// semaphore for API access from threads334HAL_Semaphore _rsem;335336#if HAL_BARO_WIND_COMP_ENABLED337/*338return pressure correction for wind based on GND_WCOEF parameters339*/340float wind_pressure_correction(uint8_t instance);341#endif342343// Logging function344void Write_Baro(void);345void Write_Baro_instance(uint64_t time_us, uint8_t baro_instance);346347void update_field_elevation();348349// atmosphere model functions350float get_altitude_difference_extended(float base_pressure, float pressure) const;351float get_EAS2TAS_extended(float pressure) const;352static float get_temperature_by_altitude_layer(float alt, int8_t idx);353354float get_altitude_difference_simple(float base_pressure, float pressure) const;355float get_EAS2TAS_simple(float altitude, float pressure) const;356};357358namespace AP {359AP_Baro &baro();360};361362363