Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
air_data.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2013 Gautier Hattenberger
3 * 2014 Felix Ruess <felix.ruess@gmail.com>
4 *
5 * This file is part of paparazzi
6 *
7 * paparazzi is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
11 *
12 * paparazzi is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with paparazzi; see the file COPYING. If not, see
19 * <http://www.gnu.org/licenses/>.
20 */
21
32#include "modules/core/abi.h"
33#include "math/pprz_isa.h"
34#include "state.h"
35#include "generated/airframe.h"
36#include "generated/modules.h"
37#include "pprzlink/dl_protocol.h"
38
42
45#ifndef AIR_DATA_BARO_ABS_ID
46#define AIR_DATA_BARO_ABS_ID ABI_BROADCAST
47#endif
49
52#ifndef AIR_DATA_BARO_DIFF_ID
53#define AIR_DATA_BARO_DIFF_ID ABI_BROADCAST
54#endif
56
59#ifndef AIR_DATA_TEMPERATURE_ID
60#define AIR_DATA_TEMPERATURE_ID ABI_BROADCAST
61#endif
63
66#ifndef AIR_DATA_AIRSPEED_ID
67#define AIR_DATA_AIRSPEED_ID ABI_BROADCAST
68#endif
70
73#ifndef AIR_DATA_INCIDENCE_ID
74#define AIR_DATA_INCIDENCE_ID ABI_BROADCAST
75#endif
77
79#ifndef AIR_DATA_TAS_FACTOR
80#define AIR_DATA_TAS_FACTOR 1.0
81#endif
82
84#ifndef AIR_DATA_CALC_AIRSPEED
85#define AIR_DATA_CALC_AIRSPEED TRUE
86#endif
87
89#ifndef AIR_DATA_CALC_TAS_FACTOR
90#define AIR_DATA_CALC_TAS_FACTOR TRUE
91#endif
92
94#ifndef AIR_DATA_CALC_AMSL_BARO
95#define AIR_DATA_CALC_AMSL_BARO FALSE
96#endif
97
98
99#ifndef USE_AIRSPEED_AIR_DATA
100#if USE_AIRSPEED
101#define USE_AIRSPEED_AIR_DATA TRUE
102PRINT_CONFIG_MSG("USE_AIRSPEED_AIR_DATA automatically set to TRUE")
103#endif
104#endif
105
106/*
107 * Internal variable to keep track of validity.
108 */
109
112
113
115{
117
118 // calculate QNH from pressure and absolute altitude if that is available
121 // in the meantime use geoid separation at local reference frame origin
122 float geoid_separation = 0;
125 }
128 air_data.calc_qnh_once = false;
129 }
130
131 if (air_data.calc_amsl_baro && air_data.qnh > 0) {
133 air_data.qnh * 100.f);
135 }
136
137 /* reset baro health counter */
139}
140
152
153static void temperature_cb(uint8_t __attribute__((unused)) sender_id, float temp)
154{
155 air_data.temperature = temp;
156 /* only calculate tas factor if enabled and we have airspeed and valid data */
158 air_data.pressure > 0) {
160 }
161}
162
163static void airspeed_cb(uint8_t __attribute__((unused)) sender_id, float eas)
164{
168#if USE_AIRSPEED_AIR_DATA
170#endif
171 }
172}
173
174static void incidence_cb(uint8_t __attribute__((unused)) sender_id, uint8_t flag, float aoa, float sideslip)
175{
176 if (bit_is_set(flag, 0)) {
177 // update angle of attack
178 air_data.aoa = aoa;
180 }
181 if (bit_is_set(flag, 1)) {
182 // update sideslip angle
185 }
186}
187
188#if PERIODIC_TELEMETRY
190
191static void send_baro_raw(struct transport_tx *trans, struct link_device *dev)
192{
195}
196
205
206static void send_amsl(struct transport_tx *trans, struct link_device *dev)
207{
208 const float MeterPerFeet = 0.3048;
212}
213#endif
214
219{
224 air_data.calc_qnh_once = true;
226
227 /* initialize the output variables
228 * pressure, qnh, temperature and airspeed to invalid values,
229 * rest to zero
230 */
231 air_data.pressure = -1.0f;
232 air_data.qnh = -1.0f;
233 air_data.airspeed = -1.0f;
234 air_data.tas = -1.0f;
235 air_data.temperature = -1000.0f;
236 air_data.differential = 0.0f;
237 air_data.amsl_baro = 0.0f;
238 air_data.aoa = 0.0f;
239 air_data.sideslip = 0.0f;
240 air_data.wind_speed = 0.0f;
241 air_data.wind_dir = 0.0f;
242
243 /* internal variables */
245
251
252#if PERIODIC_TELEMETRY
256#endif
257}
258
260{
261 // If it has be calculated and baro is OK
263 return air_data.amsl_baro;
264 }
265 // Otherwise use real altitude (from GPS)
266 return stateGetPositionLla_f()->alt;
267}
268
270{
271 // Watchdog on baro
272 if (baro_health_counter > 0) {
274 } else {
276 }
277}
278
279void air_data_parse_WIND_INFO(struct link_device *dev __attribute__((unused)), struct transport_tx *trans __attribute__((unused)), uint8_t *buf)
280{
281 if (DL_WIND_INFO_ac_id(buf) != AC_ID) { return; }
282 uint8_t flags = DL_WIND_INFO_flags(buf);
283 struct FloatVect2 wind = { 0.f, 0.f };
284 float upwind = 0.f;
285 if (bit_is_set(flags, 0)) {
286 wind.x = DL_WIND_INFO_north(buf);
287 wind.y = DL_WIND_INFO_east(buf);
290 air_data.wind_dir = atan2f(wind.y, wind.x);
291 }
292 if (bit_is_set(flags, 1)) {
293 upwind = DL_WIND_INFO_up(buf);
295 }
296#if !USE_AIRSPEED
297 if (bit_is_set(flags, 2)) {
301 }
302#endif
303#ifdef WIND_INFO_RET
304 float airspeed = stateGetAirspeed_f();
305 pprz_msg_send_WIND_INFO_RET(trans, dev, AC_ID, &flags, &wind.y, &wind.x, &upwind, &airspeed);
306#endif
307}
308
323{
324 /* q (dynamic pressure) = total pressure - static pressure
325 * q = 1/2*rho*speed^2
326 * speed = sqrt(2*q/rho)
327 * With rho = air density at sea level.
328 * Lower bound of q at zero, no flying backwards guys...
329 */
330 const float two_div_rho_0 = 2.0 / PPRZ_ISA_AIR_DENSITY;
331 float sign = 1.0f;
332 if (q < 0) {
333 sign = -1.0f;
334 q = -q;
335 }
336 return sqrtf(q * two_div_rho_0) * sign;
337}
338
355float get_tas_factor(float p, float t)
356{
357 /* factor to convert EAS to TAS:
358 * sqrt(rho0 / rho) = sqrt((p0 * T) / (p * T0))
359 * convert input temp to Kelvin
360 */
363}
364
368static void compute_tas_factor(void)
369{
370 // update tas factor if requested
372 if (air_data.pressure > 0.f && air_data.temperature > -900.f) {
373 // compute air density from pressure and temperature
375 }
376 else {
377 // compute air density from altitude in ISA condition
378 const float z = air_data_get_amsl();
379 const float p = pprz_isa_pressure_of_altitude(z);
380 const float t = pprz_isa_temperature_of_altitude(z);
382 }
383 }
384}
385
395float tas_from_eas(float eas)
396{
398 return air_data.tas_factor * eas;
399}
400
410float eas_from_tas(float tas)
411{
413 return tas / air_data.tas_factor;
414}
415
425{
427}
static void h(const real32_T x[7], const real32_T q[4], real32_T y[6])
Main include for ABI (AirBorneInterface).
Event structure to store callbacks in a linked list.
Definition abi_common.h:67
float eas_from_dynamic_pressure(float q)
Calculate equivalent airspeed from dynamic pressure.
Definition air_data.c:322
void air_data_periodic(void)
Check health.
Definition air_data.c:269
static abi_event airspeed_ev
Definition air_data.c:69
static abi_event temperature_ev
Definition air_data.c:62
static uint8_t baro_health_counter
counter to check baro health
Definition air_data.c:111
static void compute_tas_factor(void)
Internal utility function to compute current tas factor if needed.
Definition air_data.c:368
#define AIR_DATA_AIRSPEED_ID
ABI binding for airspeed.
Definition air_data.c:67
struct AirData air_data
global AirData state
Definition air_data.c:41
float air_data_get_amsl(void)
Return AMSL (altitude AboveSeaLevel).
Definition air_data.c:259
#define AIR_DATA_TAS_FACTOR
Default factor to convert estimated airspeed (EAS) to true airspeed (TAS)
Definition air_data.c:80
#define AIR_DATA_CALC_TAS_FACTOR
Calculate tas_factor from temp and pressure by default.
Definition air_data.c:90
static void pressure_diff_cb(uint8_t sender_id, float pressure)
Definition air_data.c:141
#define AIR_DATA_CALC_AMSL_BARO
Don't calculate AMSL from baro and QNH by default.
Definition air_data.c:95
static void send_air_data(struct transport_tx *trans, struct link_device *dev)
Definition air_data.c:197
static abi_event pressure_diff_ev
Definition air_data.c:55
#define AIR_DATA_CALC_AIRSPEED
Calculate Airspeed from differential pressure by default.
Definition air_data.c:85
float eas_from_tas(float tas)
Calculate equivalent airspeed from true airspeed.
Definition air_data.c:410
static void temperature_cb(uint8_t sender_id, float temp)
Definition air_data.c:153
#define AIR_DATA_TEMPERATURE_ID
ABI binding for temperature.
Definition air_data.c:60
float tas_from_dynamic_pressure(float q)
Calculate true airspeed from dynamic pressure.
Definition air_data.c:424
static void incidence_cb(uint8_t sender_id, uint8_t flag, float aoa, float sideslip)
Definition air_data.c:174
#define AIR_DATA_BARO_ABS_ID
ABI binding for absolute pressure.
Definition air_data.c:46
#define AIR_DATA_BARO_DIFF_ID
ABI binding for differential pressure.
Definition air_data.c:53
static abi_event incidence_ev
Definition air_data.c:76
static void send_amsl(struct transport_tx *trans, struct link_device *dev)
Definition air_data.c:206
void air_data_parse_WIND_INFO(struct link_device *dev, struct transport_tx *trans, uint8_t *buf)
Parse datalink wind info message.
Definition air_data.c:279
static abi_event pressure_abs_ev
Definition air_data.c:48
static void pressure_abs_cb(uint8_t sender_id, uint32_t stamp, float pressure)
Definition air_data.c:114
#define AIR_DATA_INCIDENCE_ID
ABI binding for incidence angles.
Definition air_data.c:74
static void send_baro_raw(struct transport_tx *trans, struct link_device *dev)
Definition air_data.c:191
void air_data_init(void)
AirData initialization.
Definition air_data.c:218
float get_tas_factor(float p, float t)
Calculate true airspeed (TAS) factor.
Definition air_data.c:355
float tas_from_eas(float eas)
Calculate true airspeed from equivalent airspeed.
Definition air_data.c:395
static void airspeed_cb(uint8_t sender_id, float eas)
Definition air_data.c:163
Air Data interface.
bool calc_amsl_baro
if TRUE, calculate amsl_baro
Definition air_data.h:52
float sideslip
sideslip angle (rad)
Definition air_data.h:56
float wind_dir
wind direction (rad, 0 north, >0 clockwise)
Definition air_data.h:58
bool calc_tas_factor
if TRUE, calculate tas_factor when getting a temp measurement
Definition air_data.h:53
float tas_factor
factor to convert equivalent airspeed (EAS) to true airspeed (TAS)
Definition air_data.h:46
float temperature
temperature in degrees Celcius, -1000 if unknown
Definition air_data.h:42
float aoa
angle of attack (rad)
Definition air_data.h:55
float wind_speed
wind speed (m/s)
Definition air_data.h:57
bool calc_airspeed
if TRUE, calculate airspeed from differential pressure
Definition air_data.h:50
bool calc_qnh_once
flag to calculate QNH with next pressure measurement
Definition air_data.h:51
float airspeed
Equivalent Air Speed (equals to Calibrated Air Speed at low speed/altitude) (in m/s,...
Definition air_data.h:44
float differential
Differential pressure (total - static pressure) (Pa)
Definition air_data.h:41
float pressure
Static atmospheric pressure (Pa), -1 if unknown.
Definition air_data.h:40
float amsl_baro
altitude above sea level in m from pressure and QNH
Definition air_data.h:48
float tas
True Air Speed (TAS) in m/s, -1 if unknown.
Definition air_data.h:45
bool amsl_baro_valid
TRUE if amsl_baro is currently valid.
Definition air_data.h:49
float qnh
Barometric pressure adjusted to sea level in hPa, -1 if unknown.
Definition air_data.h:47
Air Data strucute.
Definition air_data.h:39
static float float_vect2_norm(struct FloatVect2 *v)
#define KelvinOfCelsius(_t)
Convert temperature from Celsius to Kelvin.
Definition pprz_isa.h:73
#define PPRZ_ISA_SEA_LEVEL_TEMP
ISA sea level standard temperature in Kelvin.
Definition pprz_isa.h:52
static float pprz_isa_pressure_of_altitude(float altitude)
Get pressure in Pa from absolute altitude (using simplified equation).
Definition pprz_isa.h:117
#define PPRZ_ISA_AIR_DENSITY
standard air density in kg/m^3
Definition pprz_isa.h:64
static float pprz_isa_temperature_of_altitude(float alt)
Get ISA temperature from a MSL altitude.
Definition pprz_isa.h:181
#define CelsiusOfKelvin(_t)
Convert temperature from Kelvin to Celsius.
Definition pprz_isa.h:71
#define PPRZ_ISA_SEA_LEVEL_PRESSURE
ISA sea level standard atmospheric pressure in Pascal.
Definition pprz_isa.h:50
static float pprz_isa_height_of_pressure_full(float pressure, float ref_p)
Get relative altitude from pressure (using full equation).
Definition pprz_isa.h:146
static float pprz_isa_ref_pressure_of_height_full(float pressure, float height)
Get reference pressure (QFE or QNH) from current pressure and height.
Definition pprz_isa.h:166
struct State state
Definition state.c:36
static struct LlaCoor_f * stateGetPositionLla_f(void)
Get position in LLA coordinates (float).
Definition state.h:857
bool ned_initialized_f
True if local float coordinate frame is initialsed.
Definition state.h:251
static bool stateIsGlobalCoordinateValid(void)
Test if global coordinates are valid.
Definition state.h:620
float stateGetHmslOrigin_f(void)
Get the HMSL of the frame origin (float)
Definition state.c:204
struct LlaCoor_f stateGetLlaOrigin_f(void)
Get the LLA position of the frame origin (float)
Definition state.c:143
static void stateSetAngleOfAttack_f(uint16_t id, float aoa)
Set angle of attack in radians (float).
Definition state.h:1497
static void stateSetSideslip_f(uint16_t id, float sideslip)
Set sideslip angle in radians (float).
Definition state.h:1508
static void stateSetVerticalWindspeed_f(uint16_t id, float v_windspeed)
Set vertical windspeed (float).
Definition state.h:1475
static float stateGetAirspeed_f(void)
Get airspeed (float).
Definition state.h:1590
static void stateSetHorizontalWindspeed_f(uint16_t id, struct FloatVect2 *h_windspeed)
Set horizontal windspeed (float).
Definition state.h:1464
static void stateSetAirspeed_f(uint16_t id, float airspeed)
Set airspeed (float).
Definition state.h:1486
static float p[2][2]
PRINT_CONFIG_MSG("USE_INS_NAV_INIT defaulting to TRUE")
uint16_t foo
Definition main_demo5.c:58
static float sign(float x)
sign function
Definition nav_fish.c:232
float alt
in meters (normally above WGS84 reference ellipsoid)
Paparazzi atmospheric pressure conversion utilities.
API to get/set the generic vehicle states.
static const struct usb_device_descriptor dev
Definition usb_ser_hw.c:74
int8_t register_periodic_telemetry(struct periodic_telemetry *_pt, uint8_t _id, telemetry_cb _cb)
Register a telemetry callback function.
Definition telemetry.c:51
Periodic telemetry system header (includes downlink utility and generated code).
#define DefaultPeriodic
Set default periodic telemetry.
Definition telemetry.h:66
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.