2 ******************************************************************************
3 * @addtogroup OpenPilotModules OpenPilot Modules
5 * @addtogroup State Estimation
6 * @brief Acquires sensor data and computes state estimate
10 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013.
11 * @brief Barometric altitude filter, calculates altitude offset based on
12 * GPS altitude offset if available
14 * @see The GNU Public License (GPL) Version 3
16 ******************************************************************************/
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 3 of the License, or
21 * (at your option) any later version.
23 * This program is distributed in the hope that it will be useful, but
24 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28 * You should have received a copy of the GNU General Public License along
29 * with this program; if not, write to the Free Software Foundation, Inc.,
30 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 #include "inc/stateestimation.h"
35 #include <revosettings.h>
39 #define STACK_REQUIRED 128
40 #define INIT_CYCLES 100
45 float baroGPSOffsetCorrectionAlpha
;
56 static int32_t initwithgps(stateFilter
*self
);
57 static int32_t initwithoutgps(stateFilter
*self
);
58 static int32_t maininit(stateFilter
*self
);
59 static filterResult
filter(stateFilter
*self
, stateEstimation
*state
);
62 int32_t filterBaroInitialize(stateFilter
*handle
)
64 handle
->init
= &initwithgps
;
65 handle
->filter
= &filter
;
66 handle
->localdata
= pios_malloc(sizeof(struct data
));
67 return STACK_REQUIRED
;
70 int32_t filterBaroiInitialize(stateFilter
*handle
)
72 handle
->init
= &initwithoutgps
;
73 handle
->filter
= &filter
;
74 handle
->localdata
= pios_malloc(sizeof(struct data
));
75 return STACK_REQUIRED
;
78 static int32_t initwithgps(stateFilter
*self
)
80 struct data
*this = (struct data
*)self
->localdata
;
83 return maininit(self
);
86 static int32_t initwithoutgps(stateFilter
*self
)
88 struct data
*this = (struct data
*)self
->localdata
;
91 return maininit(self
);
94 static int32_t maininit(stateFilter
*self
)
96 struct data
*this = (struct data
*)self
->localdata
;
98 this->baroOffset
= 0.0f
;
100 this->first_run
= INIT_CYCLES
;
102 RevoSettingsInitialize();
103 RevoSettingsBaroGPSOffsetCorrectionAlphaGet(&this->baroGPSOffsetCorrectionAlpha
);
108 static filterResult
filter(stateFilter
*self
, stateEstimation
*state
)
110 struct data
*this = (struct data
*)self
->localdata
;
112 if (this->first_run
) {
113 // Make sure initial location is initialized properly before continuing
114 if (this->useGPS
&& IS_SET(state
->updated
, SENSORUPDATES_pos
)) {
115 if (this->first_run
== INIT_CYCLES
) {
116 this->gpsAlt
= state
->pos
[2];
120 // Initialize to current altitude reading at initial location
121 if (IS_SET(state
->updated
, SENSORUPDATES_baro
)) {
122 if (this->first_run
< INIT_CYCLES
|| !this->useGPS
) {
123 this->baroOffset
= (((float)(INIT_CYCLES
)-this->first_run
) / (float)(INIT_CYCLES
)) * this->baroOffset
+ (this->first_run
/ (float)(INIT_CYCLES
)) * (state
->baro
[0] + this->gpsAlt
);
124 this->baroAlt
= state
->baro
[0];
127 UNSET_MASK(state
->updated
, SENSORUPDATES_baro
);
129 // make sure we raise an error until properly initialized - would not be good if people arm and
130 // use altitudehold without initialized barometer filter
131 // Here, the filter is not initialized, return ERROR
132 return FILTERRESULT_CRITICAL
;
134 // Track barometric altitude offset with a low pass filter
135 // based on GPS altitude if available
136 if (this->useGPS
&& IS_SET(state
->updated
, SENSORUPDATES_pos
)) {
137 this->baroOffset
= this->baroOffset
* this->baroGPSOffsetCorrectionAlpha
+
138 (1.0f
- this->baroGPSOffsetCorrectionAlpha
) * (this->baroAlt
+ state
->pos
[2]);
140 // calculate bias corrected altitude
141 if (IS_SET(state
->updated
, SENSORUPDATES_baro
)) {
142 this->baroAlt
= state
->baro
[0];
143 state
->baro
[0] -= this->baroOffset
;
145 return FILTERRESULT_OK
;