update credits
[librepilot.git] / flight / modules / StateEstimation / filterbaro.c
blob6aefdb75734a5a26aeed40a12716d8dcf46e52b8
1 /**
2 ******************************************************************************
3 * @addtogroup OpenPilotModules OpenPilot Modules
4 * @{
5 * @addtogroup State Estimation
6 * @brief Acquires sensor data and computes state estimate
7 * @{
9 * @file filterbaro.c
10 * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2017.
11 * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013.
12 * @brief Barometric altitude filter, calculates altitude offset based on
13 * GPS altitude offset if available
15 * @see The GNU Public License (GPL) Version 3
17 ******************************************************************************/
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 3 of the License, or
22 * (at your option) any later version.
24 * This program is distributed in the hope that it will be useful, but
25 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27 * for more details.
29 * You should have received a copy of the GNU General Public License along
30 * with this program; if not, write to the Free Software Foundation, Inc.,
31 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 #include "inc/stateestimation.h"
36 #include <revosettings.h>
38 // Private constants
40 #define STACK_REQUIRED 128
41 #define INIT_CYCLES 500
42 #define BARO_OFFSET_ALPHA 0.02f
44 // Private types
45 struct data {
46 float baroOffset;
47 float baroGPSOffsetCorrectionAlpha;
48 float baroAlt;
49 float gpsAlt;
50 int16_t first_run;
51 bool useGPS;
54 // Private variables
56 // Private functions
58 static int32_t initwithgps(stateFilter *self);
59 static int32_t initwithoutgps(stateFilter *self);
60 static int32_t maininit(stateFilter *self);
61 static filterResult filter(stateFilter *self, stateEstimation *state);
64 int32_t filterBaroInitialize(stateFilter *handle)
66 handle->init = &initwithgps;
67 handle->filter = &filter;
68 handle->localdata = pios_malloc(sizeof(struct data));
69 return STACK_REQUIRED;
72 int32_t filterBaroiInitialize(stateFilter *handle)
74 handle->init = &initwithoutgps;
75 handle->filter = &filter;
76 handle->localdata = pios_malloc(sizeof(struct data));
77 return STACK_REQUIRED;
80 static int32_t initwithgps(stateFilter *self)
82 struct data *this = (struct data *)self->localdata;
84 this->useGPS = 1;
85 return maininit(self);
88 static int32_t initwithoutgps(stateFilter *self)
90 struct data *this = (struct data *)self->localdata;
92 this->useGPS = 0;
93 return maininit(self);
96 static int32_t maininit(stateFilter *self)
98 struct data *this = (struct data *)self->localdata;
100 this->baroOffset = 0.0f;
101 this->gpsAlt = 0.0f;
102 this->first_run = INIT_CYCLES;
104 RevoSettingsBaroGPSOffsetCorrectionAlphaGet(&this->baroGPSOffsetCorrectionAlpha);
106 return 0;
109 static filterResult filter(stateFilter *self, stateEstimation *state)
111 struct data *this = (struct data *)self->localdata;
113 if (this->first_run) {
114 // Make sure initial location is initialized properly before continuing
115 if (this->useGPS && IS_SET(state->updated, SENSORUPDATES_pos)) {
116 if (this->first_run == INIT_CYCLES) {
117 this->gpsAlt = state->pos[2];
118 this->first_run--;
121 // Initialize to current altitude reading at initial location
122 if (IS_SET(state->updated, SENSORUPDATES_baro)) {
123 if (this->first_run < INIT_CYCLES || !this->useGPS) {
124 if (this->first_run > INIT_CYCLES - 2) {
125 this->baroOffset = (state->baro[0] + this->gpsAlt);
127 // Set baroOffset using filtering, this allow better altitude zeroing
128 this->baroOffset = ((1.0f - BARO_OFFSET_ALPHA) * this->baroOffset) + (BARO_OFFSET_ALPHA * (state->baro[0] + this->gpsAlt));
129 this->baroAlt = state->baro[0];
130 this->first_run--;
132 UNSET_MASK(state->updated, SENSORUPDATES_baro);
134 // make sure we raise an error until properly initialized - would not be good if people arm and
135 // use altitudehold without initialized barometer filter
136 // Here, the filter is not initialized, return ERROR
137 return FILTERRESULT_CRITICAL;
138 } else {
139 // Track barometric altitude offset with a low pass filter
140 // based on GPS altitude if available
141 if (this->useGPS && IS_SET(state->updated, SENSORUPDATES_pos)) {
142 this->baroOffset = this->baroOffset * this->baroGPSOffsetCorrectionAlpha +
143 (1.0f - this->baroGPSOffsetCorrectionAlpha) * (this->baroAlt + state->pos[2]);
145 // calculate bias corrected altitude
146 if (IS_SET(state->updated, SENSORUPDATES_baro)) {
147 this->baroAlt = state->baro[0];
148 state->baro[0] -= this->baroOffset;
150 return FILTERRESULT_OK;
156 * @}
157 * @}