ArduCopter 4.7.1 – Barometer/EKF altitude corruption after hard descent causes 0–100% throttle commands in AltHold/Loiter

Hi,

I am looking for some help understanding a potentially dangerous vertical control / EKF behaviour on a small, very high thrust-to-weight 3.5" quad running ArduCopter 4.7.1.

Complete DataFlash log:
2026-09-13 16-20-19.bin

Google Drive download:

Hardware / firmware

  • ArduCopter 4.7.1
  • Flywoo / GOKU H743 Pro Mini (STM32H743)
  • 3.5" quad, 6S
  • AM32 ESCs with ESC telemetry
  • FlyFish M10 GPS, 5 Hz
  • IST8310 external compass
  • DJI FPV Remote Controller 3
  • Onboard FC barometer
  • Vibration levels are low and there are no accelerometer clipping events

Relevant configuration

At the time of this flight:

EK3_SRC1_POSZ = 1 # Barometer
EK3_SRC1_VELZ = 3 # GPS
EK3_ALT_M_NSE = 2.0
EK3_HGT_I_GATE = 500
EK3_GLITCH_RAD = 25
EK3_GND_EFF_DZ = 4
GND_EFFECT_COMP = 1

PSC_D_POS_P = 1.0
PSC_D_VEL_P = 5.0
PSC_D_ACC_P = 0.017
PSC_D_ACC_I = 0.034

MOT_THST_HOVER = 0.17

The low ACC-Z P/I values are intentional because this quad requires only approximately 0.17 normalized thrust to hover.

What happened

The relevant part of the log is approximately 164–172 seconds.

The quad was descending very quickly and I switched into altitude-controlled modes in an attempt to arrest the descent.

Relevant mode transitions:


164.241  AltHold
164.521  Loiter
167.016  Stabilize
168.081  AltHold
171.868  Stabilize

Before the ground contact, the high descent rate appears to be real. GPS vertical velocity and the EKF both indicate approximately 6–9 m/s downward.

The altitude controller starts attempting to arrest the descent, but there is insufficient altitude and the vehicle reaches the ground.

Around the ground contact there is then a very large and physically impossible barometer transient.

For example:


165.258 s   EKF altitude ~6.3 m    Baro altitude ~3.0 m
165.458 s   EKF altitude ~4.3 m    Baro altitude ~16.6 m

So the indicated barometric altitude changes by approximately 13 m in only ~0.2 seconds.

After this event, the vertical state estimate becomes extremely abnormal.

Later in the event I see approximately:


CTUN.CRt maximum: +48.9 m/s
CTUN.CRt minimum: -24.0 m/s

Baro altitude maximum: ~43.8 m
EKF altitude maximum:  ~37.0 m

These vertical velocities and altitude changes clearly do not represent the actual vehicle motion.

Main concern: alternating 0–100% throttle

The part I am particularly concerned about happens after the altitude estimate becomes corrupted.

While an altitude-controlled mode is active, the controller begins commanding almost alternating minimum and maximum thrust:


ThO -> 0
ThO -> 1
ThO -> 0
ThO -> 1
...

The motors follow these commands and the quad is physically launched upwards.

GPS confirms that a substantial part of the subsequent climb is real, although the barometer/EKF altitude and vertical velocity estimates are clearly corrupted.

At approximately 171.87 s I switch back to Stabilize, removing the automatic altitude control, and I am able to recover the vehicle.

What I would like to understand

I understand that the initial high-speed descent and ground contact are extreme conditions, and I am not suggesting that ArduPilot caused the initial impact.

My concern is specifically the behaviour after the barometer transient and corruption of the vertical state estimate.

I would appreciate some guidance on the following:

  1. Is the alternating ThO 0 -> 1 -> 0 -> 1 response expected when the EKF vertical state becomes corrupted this severely?
  2. Should EKF3 have rejected the barometer measurement earlier in this situation?
  3. Is there a recommended EKF configuration for a small high-thrust quad where propwash / pressure transients can generate large, short-duration barometric altitude errors?
  4. Would increasing EK3_ALT_M_NSE be preferable to reducing EK3_HGT_I_GATE, or is there another EKF parameter/protection that would be more appropriate?
  5. Is there any existing mechanism that should prevent the altitude controller from repeatedly commanding full/minimum thrust when the vertical state estimate has become implausible?

Additional test

After this incident I tested:


EK3_HGT_I_GATE = 300

During a subsequent normal flight, the primary EKF lane’s XKF4.SH remained below 1.0, with a maximum of approximately 0.68, so I did not observe a height measurement rejection.

For this reason I am hesitant to reduce the height innovation gate further without understanding whether that is actually the appropriate solution.

I am mainly trying to determine whether what I am seeing is:

  • expected behaviour following an extreme barometer disturbance,
  • an EKF configuration issue,
  • a vertical controller configuration issue,
  • or a situation where additional EKF/controller protection could be useful.

I can provide additional normal-flight logs for comparison if useful.

Thanks for taking a look.

UPDATE – Second occurrence without impact or IMU clipping

I found an earlier occurrence of the same 0% / 100% throttle oscillation in another log from the previous day.

This second event is important because it happened during an otherwise normal hover, with no ground impact and no IMU clipping.

September 12 BIN log:

The sequence is:

  • ~593.466 s: mode changes from Stabilize to AltHold.

  • Throttle stick is essentially stationary around center.

  • From 593.466 s until the vibration compensation activates, throttle output remains normal (CTUN.ThO approximately 0.09–0.13).

  • IMU clipping remains zero on both IMUs.

  • Maximum VibeZ in the surrounding interval is only about 11 m/s².

  • 594.469 s: the log reports “Vibration compensation ON”.

  • ~595.169 s: first CTUN.ThO = 0.

  • ~595.569 s: first CTUN.ThO = 1.

  • The output then begins the same violent 0 → 1 → 0 → 1 oscillation seen in the September 13 log.

  • The vehicle actually climbs as a consequence.

  • I switch back to Stabilize at ~596.789 s.

  • “Vibration compensation OFF” is logged much later, at ~611.869 s.

So in this occurrence the 0/100% oscillation clearly does not precede the vibration failsafe.

The order is:

normal AltHold → Vibration compensation ON → ~0.7 s → ThO 0/1 oscillation

There is no 0/1 saturation before “Vibration compensation ON”.

Comparison with the September 13 event

I checked the timing in the original September 13 log as well.

There the sequence is:

  • ~168.081 s: AltHold

  • CTUN.ThO remains in a normal range before the failsafe (approximately 0.12–0.18 in this interval)

  • 169.158 s: “Vibration compensation ON”

  • ~169.958 s: first ThO = 0

  • ~170.358 s: first ThO = 1

  • then the repeated 0 → 1 → 0 → 1 sequence begins

So again:

Vibration compensation ON → ~0.8 s → 0/100% oscillation

There were some zero-throttle samples earlier in the September 13 event following the hard descent/ground transient, but there was no alternating 0/100% pattern before vibration compensation became active.

This means the ground impact and IMU clipping in the September 13 log do not appear to be necessary to reproduce the problem.

Another observation: climb-rate source changes

I also compared CTUN.CRt with EKF vertical velocity.

Immediately before vibration compensation activates, CTUN.CRt closely matches the normal EKF vertical velocity (-XKF1.VD).

In the September 12 event, before the failsafe, the two are essentially identical.

After “Vibration compensation ON”, CTUN.CRt diverges dramatically from XKF1.VD and begins showing values such as approximately:

+10, -9, +29, -16, +24 m/s

while the EKF vertical velocity does not show corresponding changes.

The same behavior is present in the September 13 event, where CTUN.CRt reaches approximately:

+49, -20, +43 m/s

These extreme climb-rate estimates alternate in sign and correlate with the throttle saturation:

  • large positive CRt → ThO = 0

  • large negative CRt → ThO = 1

Possible relation to the vibration-compensation control path

Looking at the Copter 4.7.1 code, when high_vibes is active the position controller does not use the normal NED velocity estimate in the same way. AC_PosControl::update_estimates() can use get_vert_pos_rate_D() instead.

Also, the vibration-compensation vertical controller uses a different control path rather than the normal acceleration PID path.

This seems consistent with another strange observation in both logs: during the 0/1 event, the normal acceleration PID logging does not appear to explain the extreme throttle commands.

I am therefore wondering whether this could be an edge case in the vibration-compensation fallback:

vertical-estimation inconsistency
→ high_vibes / vibration compensation
→ different vertical-rate estimate/control path
→ pathological vertical-rate estimate
→ very large velocity error
→ alternating minimum/maximum throttle

I am not claiming this is proven to be the root cause, but the timing is repeatable in two independent events.

Most importantly, the September 12 event demonstrates that the behavior can occur:

  • without an impact,

  • with Clip = 0,

  • with relatively low VIBE values,

  • during a normal hover/AltHold transition.

In both logs, the repeated 0/100% throttle oscillation starts only after “Vibration compensation ON”.

The September 12 BIN is available here for comparison with the September 13 event:

The vibration levels seem to be increasing slightly. I think it would be a good idea to check whether the aircraft is assembled properly and whether there are any hardware-related issues.

Also, the PID response currently appears to be quite unstable. There are cases where the actual response overshoots the target value or fails to track it properly. In this condition, the drone may oscillate significantly during a rapid descent, or in more severe cases, it may lose control and roll over.

  • Before taking off in GPS-assisted modes, please allow enough time for the GPS to fully stabilize. In this flight, the vehicle was armed before the GPS conditions, including HDOP, appeared to be sufficiently stable.

  • I recommend starting with the basic tuning procedures, including Hover Throttle / Hover Thrust calibration. If the Hover Thrust value is not estimated correctly or the related tuning has not been completed properly, the vehicle may have difficulty maintaining altitude in altitude-hold modes.

  • After performing the Motor Test, please also configure MOT_SPIN_ARM and MOT_SPIN_MIN according to the ArduPilot Copter tuning procedure.

Thanks for taking a look at the log.
I agree that the September 13 flight contains a hard descent/contact event and IMU clipping, so initially I also suspected that the 0/100% throttle behaviour could simply be a consequence of that event.
However, I have now found a second occurrence in a completely separate flight from September 12 which I think is important for the diagnosis.
In that flight there was no impact and both IMUs remained at Clip=0. VibeZ around the event was only about 11 m/s².
The interesting part is the timing:
593.466 s — AltHold
594.469 s — Vibration compensation ON
595.169 s — first CTUN.ThO = 0
595.569 s — first CTUN.ThO = 1
followed by the same repeated 0/100% throttle oscillation.
Before Vibration Compensation activates, CTUN.ThO remains approximately 0.09–0.13 with no saturation and the vertical controller is behaving normally.
I also noticed that before Vibration Compensation, CTUN.CRt closely follows -XKF1.VD. After Vibration Compensation activates, CTUN.CRt diverges dramatically from the normal EKF vertical velocity and reaches values such as approximately +10, -9, +29, -16, +24 m/s, while throttle alternates between its limits.
The same ordering occurs in the September 13 log:
Vibration compensation ON → ~0.8 s → repeated 0/100% throttle oscillation.
So my concern is not primarily the PID tuning or the impact in the September 13 flight. I am trying to understand why activation of the vibration-compensation vertical estimation/control path is followed by these extreme climb-rate estimates and full-range throttle commands.
Regarding the basic tuning: hover thrust was measured from a stable hover and is set to MOT_THST_HOVER=0.17. Following the Copter 4.7 tuning procedure, PSC_D_ACC_P=0.017 and PSC_D_ACC_I=0.034. Roll/pitch/yaw AutoTune has also been completed.
The September 12 log, where the same behaviour occurs without impact or clipping, is here:

I would be particularly interested in your opinion on why CTUN.CRt diverges so strongly from XKF1.VD after Vibration compensation ON, and whether the vibration-compensation fallback could be involved

Hi @Sokerer,

Txs for the report and the logs. I’m afraid that I don’t have much experience with these types of frames, @andyp1per is the expert in this area.

I think the core issue is that the barometer is getting a lot of interference when the throttle is raised and it’s the opposite of what we normally see. So normally as the throttle is increased, we see the barometer altitude fall (e.g. higher pressure from prop wash leads to lower altitude reported). In these logs though we see the opposite - the throttle is raised and the baro altitude jumps 3+ meters.

In the graph below the barometer altitude is blue, the EKF’s altitude is green and the GPS is yellow. I suspect the EKF and GPS are actually correct which means massive barometer interference is happening.

I think the best solution is to try and resolve this perhaps by changing the vehicle’s frame design or possibly enabling the barometer is the GPS unit if it has one (the Here4 has one for example).

The vibration compensation feature is there to catch and try and handle bad altitude estimates that are normally caused by high vibration. It can be tricked though and in this case I think that’s what’s happening - the baro is bad but it upsets the EKF enough that the vibration compensation kicks in.

Another possibility is to not use the barometer for height - so you could change the EK3_SRC1_POSZ = 3 (GPS). It will still fall back to the barometer if the GPS fails for some reason.

Thanks Randy, this makes sense and it also seems consistent with the September 12 log, where the same event occurs with Clip=0 and relatively low vibration.

I will investigate using GPS as the primary height source as you suggest.

One thing I would like to clarify: after “Vibration compensation ON”, I see CTUN.CRt diverge dramatically from -XKF1.VD. In the September 12 event the normal EKF vertical velocity remains relatively reasonable initially, while CTUN.CRt starts reaching values such as +10, -9, +29 m/s and the throttle then alternates between 0 and 1.

Is this expected because vibration compensation switches to get_vert_pos_rate_D() / the alternative vertical-rate estimation path?

In other words, could the corrupted barometric height that triggers vibration compensation also cause the fallback vertical-rate estimate to become very large, creating this 0/100% throttle feedback?

I am asking because in both independent logs the repeated 0/100% throttle behaviour begins only about 0.7–0.8 seconds after “Vibration compensation ON”.

Is this a ducted frame design?

Yes! it’s a Speedybe 35 chassis, and I think I may have a plausible explanation for the unusual sign of the barometer error.
This cinewhoop frame has ventilation openings from the ducts into the FC compartment for cooling. My suspicion is that as motor thrust increases, airflow through the ducts creates a low-pressure region in the FC compartment.
Since the barometer is inside that compartment, it may see lower static pressure as throttle increases, which would explain why the reported barometric altitude increases instead of decreasing.
However, there is still one part of the behaviour that I do not understand: the repeated 0 → 1 → 0 → 1 throttle saturation.
I understand how the barometer interference can upset the EKF enough to trigger vibration compensation, but I still do not understand why, once vibration compensation becomes active, the vertical control response becomes so extreme.
In both independent logs the repeated 0/100% throttle oscillation begins only after Vibration compensation ON, and in the September 12 log it happens without impact or IMU clipping.
So my remaining question is whether the corrupted height estimate, once vibration compensation is active, can drive the fallback vertical-rate/control path into these very large CTUN.CRt values and consequently command full minimum/full maximum throttle.
That is the part I am still trying to understand.

You need to set the baro thrust scale parameter (new in 4.7) for this kind of frame. It’s very important.

Hi @Sokerer,

Yes, I think you’re right that CTUN.Crt should match -XKF1.VD so I’ve created an issue and added it to our 4.7 issues list. Thanks!

Thanks Randy!

In the meantime, while this issue is being investigated, would you recommend disabling Vibration Failsafe on this copter as a temporary workaround by setting FS_VIBE_ENABLE = 0?

In both of my problematic logs the 0/100% throttle oscillation starts only after “Vibration compensation ON”, while before that the throttle control is normal. In the Sept 12 log there was also no clipping and the logged vibration levels were not particularly high.

I understand that disabling FS_VIBE_ENABLE removes the protection intended for genuine high-vibration conditions, so I would like your advice before treating this as a safe workaround.

Also, can you confirm that FS_VIBE_ENABLE = 0 is the correct parameter to prevent the Vibration Compensation path from being activated?

Hi @Sokerer,

I think it would be good to follow @andyp1per’s advice and enable the barometer thrust scaling or better yet somehow change the hardware to remove the thrust’s effect on the barometer.

I’ll leave it up to you to decide if it is best to disable the vibration failsafe by setting FS_VIBE_ENABLE = 0. It might not be necessary if the baro thrust scaling is working OK.

@Sokerer,

We may have found the underlying cause of the throttle oscillation you mentioned higher up in this discussion. The fix is here and if confirmed we will get it out in a beta very soon.

Thanks Andy, and thanks to everyone who worked on tracking this down. Really appreciate the time and effort you all put into it.