Skip to content

Commit 7ca514d

Browse files
committed
Plane: quantise the airspeed target from MIN_GROUNDSPEED
TECS is very sensitive to oscillation when it has a changing airspeed target which results from triggering of MIN_GROUNDSPEED. To avoid this we quantise the target and apply a hysteresis. This greatly reduces the oscillation, although it isn't completely eliminated
1 parent c4b091f commit 7ca514d

File tree

2 files changed

+23
-4
lines changed

2 files changed

+23
-4
lines changed

ArduPlane/Plane.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ class Plane : public AP_Vehicle {
437437
// The amount current ground speed is below min ground speed. Centimeters per second
438438
int32_t groundspeed_undershoot;
439439
bool groundspeed_undershoot_is_valid;
440+
float last_groundspeed_undershoot_offset;
440441

441442
// speed scaler for control surfaces, updated at 10Hz
442443
float surface_speed_scaler = 1.0;

ArduPlane/navigation.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -248,11 +248,29 @@ void Plane::calc_airspeed_errors()
248248
if (control_mode->does_auto_throttle() &&
249249
groundspeed_undershoot_is_valid &&
250250
control_mode != &mode_circle) {
251-
float EAS_undershoot = (int32_t)((float)groundspeed_undershoot / ahrs.get_EAS2TAS());
252-
int32_t min_gnd_target_airspeed = airspeed_measured*100 + EAS_undershoot;
253-
if (min_gnd_target_airspeed > target_airspeed_cm) {
254-
target_airspeed_cm = min_gnd_target_airspeed;
251+
/*
252+
calculate how much extra airspeed we need to target to
253+
achieve the desired ground speed in MIN_GROUNDSPEED
254+
255+
we quantise the additional airspeed and apply a hysteresis
256+
in order to avoid triggering an oscillation in TECS
257+
*/
258+
float target_airspeed = target_airspeed_cm*0.01;
259+
float EAS_undershoot = (groundspeed_undershoot*0.01) / ahrs.get_EAS2TAS();
260+
float min_gnd_target_airspeed = airspeed_measured + EAS_undershoot;
261+
float airspeed_target_offset = min_gnd_target_airspeed > target_airspeed? (min_gnd_target_airspeed - target_airspeed) : 0;
262+
263+
// round up to nearest m/s
264+
airspeed_target_offset = int(airspeed_target_offset + 0.5);
265+
266+
// apply some hysteresis
267+
if (airspeed_target_offset < last_groundspeed_undershoot_offset &&
268+
last_groundspeed_undershoot_offset - airspeed_target_offset < 1.2) {
269+
airspeed_target_offset = last_groundspeed_undershoot_offset;
255270
}
271+
last_groundspeed_undershoot_offset = airspeed_target_offset;
272+
273+
target_airspeed_cm += airspeed_target_offset * 100;
256274
}
257275

258276
// when using the special GUIDED mode features for slew control, don't allow airspeed nudging as it doesn't play nicely.

0 commit comments

Comments
 (0)