Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Ardupilot
GitHub Repository: Ardupilot/ardupilot
Path: blob/master/libraries/AP_Baro/AP_Baro.h
9695 views
1
#pragma once
2
3
#include "AP_Baro_config.h"
4
5
#include <AP_HAL/AP_HAL.h>
6
#include <AP_Param/AP_Param.h>
7
#include <AP_Math/AP_Math.h>
8
#include <Filter/DerivativeFilter.h>
9
#include <AP_MSP/msp.h>
10
#include <AP_ExternalAHRS/AP_ExternalAHRS.h>
11
12
// maximum number of sensor instances
13
#ifndef BARO_MAX_INSTANCES
14
#define BARO_MAX_INSTANCES 3
15
#endif
16
17
// maximum number of drivers. Note that a single driver can provide
18
// multiple sensor instances
19
#define BARO_MAX_DRIVERS 3
20
21
// timeouts for health reporting
22
#define BARO_TIMEOUT_MS 500 // timeout in ms since last successful read
23
24
class AP_Baro_Backend;
25
26
class AP_Baro
27
{
28
friend class AP_Baro_Backend;
29
friend class AP_Baro_SITL; // for access to sensors[]
30
friend class AP_Baro_DroneCAN; // for access to sensors[]
31
32
public:
33
AP_Baro();
34
35
/* Do not allow copies */
36
CLASS_NO_COPY(AP_Baro);
37
38
// get singleton
39
static AP_Baro *get_singleton(void) {
40
return _singleton;
41
}
42
43
// barometer types
44
typedef enum {
45
BARO_TYPE_AIR,
46
BARO_TYPE_WATER
47
} baro_type_t;
48
49
// initialise the barometer object, loading backend drivers
50
__INITFUNC__ void init(void);
51
52
// update the barometer object, asking backends to push data to
53
// the frontend
54
void update(void);
55
56
// healthy - returns true if sensor and derived altitude are good
57
bool healthy(void) const { return healthy(_primary); }
58
59
bool healthy(uint8_t instance) const;
60
61
// check if all baros are healthy - used for SYS_STATUS report
62
bool all_healthy(void) const;
63
64
// returns false if we fail arming checks, in which case the buffer will be populated with a failure message
65
bool arming_checks(size_t buflen, char *buffer) const;
66
67
// get primary sensor
68
uint8_t get_primary(void) const { return _primary; }
69
70
// pressure in Pascal. Divide by 100 for millibars or hectopascals
71
float get_pressure(void) const { return get_pressure(_primary); }
72
float get_pressure(uint8_t instance) const { return sensors[instance].pressure; }
73
#if HAL_BARO_WIND_COMP_ENABLED
74
// dynamic pressure in Pascal. Divide by 100 for millibars or hectopascals
75
const Vector3f& get_dynamic_pressure(uint8_t instance) const { return sensors[instance].dynamic_pressure; }
76
#endif
77
#if (HAL_BARO_WIND_COMP_ENABLED || AP_BARO_THST_COMP_ENABLED)
78
float get_corrected_pressure(uint8_t instance) const { return sensors[instance].corrected_pressure; }
79
#endif
80
81
// temperature in degrees C
82
float get_temperature(void) const { return get_temperature(_primary); }
83
float get_temperature(uint8_t instance) const { return sensors[instance].temperature; }
84
85
// get pressure correction in Pascal. Divide by 100 for millibars or hectopascals
86
float get_pressure_correction(void) const { return get_pressure_correction(_primary); }
87
float get_pressure_correction(uint8_t instance) const { return sensors[instance].p_correction; }
88
89
// calibrate the barometer. This must be called on startup if the
90
// altitude/climb_rate/acceleration interfaces are ever used
91
void calibrate(bool save=true);
92
93
// update the barometer calibration to the current pressure. Can
94
// be used for incremental preflight update of baro
95
void update_calibration(void);
96
97
// get current altitude in meters relative to altitude at the time
98
// of the last calibrate() call
99
float get_altitude(void) const { return get_altitude(_primary); }
100
float get_altitude(uint8_t instance) const { return sensors[instance].altitude; }
101
102
// get altitude above mean sea level
103
float get_altitude_AMSL(uint8_t instance) const { return get_altitude(instance) + _field_elevation_active; }
104
float get_altitude_AMSL(void) const { return get_altitude_AMSL(_primary); }
105
106
// returns which i2c bus is considered "the" external bus
107
uint8_t external_bus() const { return _ext_bus; }
108
109
// Atmospheric Model Functions
110
static float geometric_alt_to_geopotential(float alt);
111
static float geopotential_alt_to_geometric(float alt);
112
113
float get_temperature_from_altitude(float alt) const;
114
float get_altitude_from_pressure(float pressure) const;
115
116
// EAS2TAS for SITL
117
static float get_EAS2TAS_for_alt_amsl(float alt_amsl);
118
119
#if AP_BARO_1976_STANDARD_ATMOSPHERE_ENABLED
120
// lookup expected pressure for a given altitude. Used for SITL backend
121
static void get_pressure_temperature_for_alt_amsl(float alt_amsl, float &pressure, float &temperature_K);
122
#endif
123
124
// lookup expected temperature in degrees C for a given altitude. Used for SITL backend
125
static float get_temperatureC_for_alt_amsl(const float alt_amsl);
126
127
// lookup expected pressure in Pa for a given altitude. Used for SITL backend
128
static float get_pressure_for_alt_amsl(const float alt_amsl);
129
130
// get air density for SITL
131
static float get_air_density_for_alt_amsl(float alt_amsl);
132
133
// get altitude difference in meters relative given a base
134
// pressure in Pascal
135
float get_altitude_difference(float base_pressure, float pressure) const;
136
137
// get sea level pressure relative to 1976 standard atmosphere model
138
// pressure in Pascal
139
float get_sealevel_pressure(float pressure, float altitude) const;
140
141
// get scale factor required to convert equivalent to true
142
// airspeed. This should only be used to update the AHRS value
143
// once per loop. Please use AP::ahrs().get_EAS2TAS()
144
float _get_EAS2TAS(void) const;
145
146
// get air density / sea level density - decreases as altitude climbs
147
// please use AP::ahrs()::get_air_density_ratio()
148
float _get_air_density_ratio(void);
149
150
// get current climb rate in meters/s. A positive number means
151
// going up
152
float get_climb_rate(void);
153
154
// ground temperature in degrees C
155
// the ground values are only valid after calibration
156
float get_ground_temperature(void) const;
157
158
// ground pressure in Pascal
159
// the ground values are only valid after calibration
160
float get_ground_pressure(void) const { return get_ground_pressure(_primary); }
161
float get_ground_pressure(uint8_t i) const { return sensors[i].ground_pressure.get(); }
162
163
// set the temperature to be used for altitude calibration. This
164
// allows an external temperature source (such as a digital
165
// airspeed sensor) to be used as the temperature source
166
void set_external_temperature(float temperature);
167
168
// get last time sample was taken (in ms)
169
uint32_t get_last_update(void) const { return get_last_update(_primary); }
170
uint32_t get_last_update(uint8_t instance) const { return sensors[instance].last_update_ms; }
171
172
// settable parameters
173
static const struct AP_Param::GroupInfo var_info[];
174
175
float get_external_temperature(void) const { return get_external_temperature(_primary); };
176
float get_external_temperature(const uint8_t instance) const;
177
178
// Set the primary baro
179
void set_primary_baro(uint8_t primary) { _primary_baro.set_and_save(primary); };
180
181
// Set the type (Air or Water) of a particular instance
182
void set_type(uint8_t instance, baro_type_t type) { sensors[instance].type = type; };
183
184
// Get the type (Air or Water) of a particular instance
185
baro_type_t get_type(uint8_t instance) { return sensors[instance].type; };
186
187
// register a new sensor, claiming a sensor slot. If we are out of
188
// slots it will panic
189
uint8_t register_sensor(void);
190
191
// return number of registered sensors
192
uint8_t num_instances(void) const { return _num_sensors; }
193
194
// set baro drift amount
195
void set_baro_drift_altitude(float alt) { _alt_offset.set(alt); }
196
197
// get baro drift amount
198
float get_baro_drift_offset(void) const { return _alt_offset_active; }
199
200
// simple underwater atmospheric model
201
static void SimpleUnderWaterAtmosphere(float alt, float &rho, float &delta, float &theta);
202
203
// set a pressure correction from AP_TempCalibration
204
void set_pressure_correction(uint8_t instance, float p_correction);
205
206
uint8_t get_filter_range() const { return _filter_range; }
207
208
// indicate which bit in LOG_BITMASK indicates baro logging enabled
209
void set_log_baro_bit(uint32_t bit) { _log_baro_bit = bit; }
210
bool should_log() const;
211
212
// allow threads to lock against baro update
213
HAL_Semaphore &get_semaphore(void) {
214
return _rsem;
215
}
216
217
#if AP_BARO_MSP_ENABLED
218
void handle_msp(const MSP::msp_baro_data_message_t &pkt);
219
#endif
220
#if AP_BARO_EXTERNALAHRS_ENABLED
221
void handle_external(const AP_ExternalAHRS::baro_data_message_t &pkt);
222
#endif
223
224
enum Options : uint16_t {
225
TreatMS5611AsMS5607 = (1U << 0U),
226
};
227
228
// check if an option is set
229
bool option_enabled(const Options option) const
230
{
231
return (uint16_t(_options.get()) & uint16_t(option)) != 0;
232
}
233
234
private:
235
// singleton
236
static AP_Baro *_singleton;
237
238
// how many drivers do we have?
239
uint8_t _num_drivers;
240
AP_Baro_Backend *drivers[BARO_MAX_DRIVERS];
241
242
// how many sensors do we have?
243
uint8_t _num_sensors;
244
245
// what is the primary sensor at the moment?
246
uint8_t _primary;
247
248
uint32_t _log_baro_bit = -1;
249
250
bool init_done;
251
252
uint8_t msp_instance_mask;
253
254
// bitmask values for GND_PROBE_EXT
255
enum {
256
PROBE_BMP085=(1<<0),
257
PROBE_BMP280=(1<<1),
258
PROBE_MS5611=(1<<2),
259
PROBE_MS5607=(1<<3),
260
PROBE_MS5637=(1<<4),
261
PROBE_FBM320=(1<<5),
262
PROBE_DPS280=(1<<6),
263
PROBE_LPS25H=(1<<7),
264
PROBE_KELLER=(1<<8),
265
PROBE_MS5837=(1<<9),
266
PROBE_BMP388=(1<<10),
267
PROBE_SPL06 =(1<<11),
268
PROBE_MSP =(1<<12),
269
PROBE_BMP581=(1<<13),
270
PROBE_AUAV =(1<<14),
271
};
272
273
#if HAL_BARO_WIND_COMP_ENABLED
274
class WindCoeff {
275
public:
276
static const struct AP_Param::GroupInfo var_info[];
277
278
AP_Int8 enable; // enable compensation for this barometer
279
AP_Float xp; // ratio of static pressure rise to dynamic pressure when flying forwards
280
AP_Float xn; // ratio of static pressure rise to dynamic pressure when flying backwards
281
AP_Float yp; // ratio of static pressure rise to dynamic pressure when flying to the right
282
AP_Float yn; // ratio of static pressure rise to dynamic pressure when flying to the left
283
AP_Float zp; // ratio of static pressure rise to dynamic pressure when flying up
284
AP_Float zn; // ratio of static pressure rise to dynamic pressure when flying down
285
};
286
#endif
287
288
struct {
289
uint32_t last_update_ms; // last update time in ms
290
uint32_t last_change_ms; // last update time in ms that included a change in reading from previous readings
291
float pressure; // pressure in Pascal
292
float temperature; // temperature in degrees C
293
float altitude; // calculated altitude
294
AP_Float ground_pressure;
295
float p_correction;
296
baro_type_t type; // 0 for air pressure (default), 1 for water pressure
297
bool healthy; // true if sensor is healthy
298
bool alt_ok; // true if calculated altitude is ok
299
bool calibrated; // true if calculated calibrated successfully
300
AP_Int32 bus_id;
301
#if HAL_BARO_WIND_COMP_ENABLED
302
WindCoeff wind_coeff;
303
Vector3f dynamic_pressure; // calculated dynamic pressure
304
#endif
305
#if AP_BARO_THST_COMP_ENABLED
306
AP_Float mot_scale; // thrust-based pressure scaling
307
#endif
308
#if (HAL_BARO_WIND_COMP_ENABLED || AP_BARO_THST_COMP_ENABLED)
309
float corrected_pressure;
310
#endif
311
} sensors[BARO_MAX_INSTANCES];
312
313
AP_Float _alt_offset;
314
float _alt_offset_active;
315
AP_Float _field_elevation; // field elevation in meters
316
float _field_elevation_active;
317
uint32_t _field_elevation_last_ms;
318
AP_Int8 _primary_baro; // primary chosen by user
319
AP_Int8 _ext_bus; // bus number for external barometer
320
float _external_temperature;
321
uint32_t _last_external_temperature_ms;
322
DerivativeFilterFloat_Size7 _climb_rate_filter;
323
AP_Float _specific_gravity; // the specific gravity of fluid for an ROV 1.00 for freshwater, 1.024 for salt water
324
AP_Float _user_ground_temperature; // user override of the ground temperature used for EAS2TAS
325
float _guessed_ground_temperature; // currently ground temperature estimate using our best available source
326
327
// when did we last notify the GCS of new pressure reference?
328
uint32_t _last_notify_ms;
329
330
// see if we already have probed a i2c sensor by bus number and address
331
bool _i2c_sensor_is_registered(uint8_t bus_num, uint8_t address) const;
332
bool _add_backend(AP_Baro_Backend *backend);
333
void _probe_i2c_barometers(void);
334
335
void probe_i2c_dev(AP_Baro_Backend* (*probefn)(AP_Baro&, AP_HAL::Device&), uint8_t bus, uint8_t addr);
336
void probe_spi_dev(AP_Baro_Backend* (*probefn)(AP_Baro&, AP_HAL::Device&), const char *name);
337
void probe_dev(AP_Baro_Backend* (*probefn)(AP_Baro&, AP_HAL::Device&), AP_HAL::Device *dev);
338
#if AP_BARO_ICM20789_ENABLED
339
void probe_icm20789(uint8_t bus, uint8_t addr, const char *mpu_name);
340
void probe_icm20789(uint8_t bus, uint8_t addr, uint8_t mpu_bus, uint8_t mpu_addr);
341
// convenience underlying method for other probe functions;
342
// will. delete the passed-in devices if a backend is not found
343
void _probe_icm20789(AP_HAL::I2CDevice *i2c_dev, AP_HAL::Device *mpu_dev);
344
#endif // AP_BARO_ICM20789_ENABLED
345
346
#if AP_BARO_LPS2XH_ENABLED
347
void probe_lps2xh_via_Invensense_IMU(uint8_t bus, uint8_t addr, uint8_t mpu_addr);
348
#endif // AP_BARO_LPS2XH_ENABLED
349
350
AP_Int8 _filter_range; // valid value range from mean value
351
AP_Int32 _baro_probe_ext;
352
353
#ifndef HAL_BUILD_AP_PERIPH
354
AP_Float _alt_error_max;
355
#endif
356
357
AP_Int16 _options;
358
359
// semaphore for API access from threads
360
HAL_Semaphore _rsem;
361
362
#if HAL_BARO_WIND_COMP_ENABLED
363
/*
364
return pressure correction for wind based on GND_WCOEF parameters
365
*/
366
float wind_pressure_correction(uint8_t instance);
367
#endif
368
#if AP_BARO_THST_COMP_ENABLED
369
float thrust_pressure_correction(uint8_t instance);
370
#endif
371
// Logging function
372
void Write_Baro(void);
373
void Write_Baro_instance(uint64_t time_us, uint8_t baro_instance);
374
375
void update_field_elevation();
376
377
// atmosphere model functions
378
float get_altitude_difference_extended(float base_pressure, float pressure) const;
379
float get_EAS2TAS_extended(float pressure) const;
380
static float get_temperature_by_altitude_layer(float alt, int8_t idx);
381
382
float get_altitude_difference_simple(float base_pressure, float pressure) const;
383
float get_EAS2TAS_simple(float altitude, float pressure) const;
384
};
385
386
namespace AP {
387
AP_Baro &baro();
388
};
389
390