2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
29 #include "build/debug.h"
31 #include "common/maths.h"
33 #include "fc/runtime_config.h"
35 #include "flight/position.h"
36 #include "flight/imu.h"
37 #include "flight/pid.h"
41 #include "scheduler/scheduler.h"
43 #include "sensors/sensors.h"
44 #include "sensors/barometer.h"
47 #include "pg/pg_ids.h"
55 PG_REGISTER_WITH_RESET_TEMPLATE(positionConfig_t
, positionConfig
, PG_POSITION
, 1);
57 PG_RESET_TEMPLATE(positionConfig_t
, positionConfig
,
61 static int32_t estimatedAltitudeCm
= 0; // in cm
63 #define BARO_UPDATE_FREQUENCY_40HZ (1000 * 25)
66 static int16_t estimatedVario
= 0; // in cm/s
68 int16_t calculateEstimatedVario(int32_t baroAlt
, const uint32_t dTime
) {
70 static int32_t lastBaroAlt
= 0;
74 baroVel
= (baroAlt
- lastBaroAlt
) * 1000000.0f
/ dTime
;
75 lastBaroAlt
= baroAlt
;
77 baroVel
= constrain(baroVel
, -1500.0f
, 1500.0f
);
78 baroVel
= applyDeadband(baroVel
, 10.0f
);
80 vel
= vel
* CONVERT_PARAMETER_TO_FLOAT(barometerConfig()->baro_cf_vel
) + baroVel
* (1.0f
- CONVERT_PARAMETER_TO_FLOAT(barometerConfig()->baro_cf_vel
));
81 int32_t vel_tmp
= lrintf(vel
);
82 vel_tmp
= applyDeadband(vel_tmp
, 5.0f
);
84 return constrain(vel_tmp
, SHRT_MIN
, SHRT_MAX
);
88 #if defined(USE_BARO) || defined(USE_GPS)
89 static bool altitudeOffsetSet
= false;
91 void calculateEstimatedAltitude(timeUs_t currentTimeUs
)
93 static timeUs_t previousTimeUs
= 0;
94 static int32_t baroAltOffset
= 0;
95 static int32_t gpsAltOffset
= 0;
97 const uint32_t dTime
= currentTimeUs
- previousTimeUs
;
98 if (dTime
< BARO_UPDATE_FREQUENCY_40HZ
) {
99 schedulerIgnoreTaskExecTime();
102 previousTimeUs
= currentTimeUs
;
107 #if defined(USE_GPS) && defined(USE_VARIO)
108 int16_t gpsVertSpeed
= 0;
110 float gpsTrust
= 0.3; //conservative default
111 bool haveBaroAlt
= false;
112 bool haveGpsAlt
= false;
114 if (sensors(SENSOR_BARO
)) {
115 if (!baroIsCalibrationComplete()) {
116 performBaroCalibrationCycle();
118 baroAlt
= baroCalculateAltitude();
125 if (sensors(SENSOR_GPS
) && STATE(GPS_FIX
)) {
126 gpsAlt
= gpsSol
.llh
.altCm
;
128 gpsVertSpeed
= GPS_verticalSpeedInCmS
;
132 if (gpsSol
.hdop
!= 0) {
133 gpsTrust
= 100.0 / gpsSol
.hdop
;
135 // always use at least 10% of other sources besides gps if available
136 gpsTrust
= MIN(gpsTrust
, 0.9f
);
140 if (ARMING_FLAG(ARMED
) && !altitudeOffsetSet
) {
141 baroAltOffset
= baroAlt
;
142 gpsAltOffset
= gpsAlt
;
143 altitudeOffsetSet
= true;
144 } else if (!ARMING_FLAG(ARMED
) && altitudeOffsetSet
) {
145 altitudeOffsetSet
= false;
147 baroAlt
-= baroAltOffset
;
148 gpsAlt
-= gpsAltOffset
;
151 if (haveGpsAlt
&& haveBaroAlt
&& positionConfig()->altSource
== DEFAULT
) {
152 if (ARMING_FLAG(ARMED
)) {
153 estimatedAltitudeCm
= gpsAlt
* gpsTrust
+ baroAlt
* (1 - gpsTrust
);
155 estimatedAltitudeCm
= gpsAlt
; //absolute altitude is shown before arming, ignore baro
158 // baro is a better source for vario, so ignore gpsVertSpeed
159 estimatedVario
= calculateEstimatedVario(baroAlt
, dTime
);
161 } else if (haveGpsAlt
&& (positionConfig()->altSource
== GPS_ONLY
|| positionConfig()->altSource
== DEFAULT
)) {
162 estimatedAltitudeCm
= gpsAlt
;
163 #if defined(USE_VARIO) && defined(USE_GPS)
164 estimatedVario
= gpsVertSpeed
;
166 } else if (haveBaroAlt
&& (positionConfig()->altSource
== BARO_ONLY
|| positionConfig()->altSource
== DEFAULT
)) {
167 estimatedAltitudeCm
= baroAlt
;
169 estimatedVario
= calculateEstimatedVario(baroAlt
, dTime
);
175 DEBUG_SET(DEBUG_ALTITUDE
, 0, (int32_t)(100 * gpsTrust
));
176 DEBUG_SET(DEBUG_ALTITUDE
, 1, baroAlt
);
177 DEBUG_SET(DEBUG_ALTITUDE
, 2, gpsAlt
);
179 DEBUG_SET(DEBUG_ALTITUDE
, 3, estimatedVario
);
183 bool isAltitudeOffset(void)
185 return altitudeOffsetSet
;
189 int32_t getEstimatedAltitudeCm(void)
191 return estimatedAltitudeCm
;
195 int16_t getEstimatedVario(void)
197 return estimatedVario
;