-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Improve APA safety: pitot validation, reduced gains, safe defaults #11222
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve APA safety: pitot validation, reduced gains, safe defaults #11222
Conversation
PR Compliance Guide 🔍All compliance sections have been disabled in the configurations. |
d38c246 to
9afef93
Compare
Implements pitot sensor validation by comparing hardware pitot readings against virtual airspeed (GPS + wind estimator). Detects blocked or failed pitot tubes and automatically falls back to GPS-based airspeed. Features: - Compares pitot against virtual airspeed (wind-corrected, not raw GPS) - Wide thresholds (30%-200%) catch gross failures while avoiding false positives - Sustained failure detection (1 second) before declaring sensor failed - Automatic fallback to GPS airspeed when pitot fails validation - OSD warning displays "PITOT FAIL" when sensor invalid - Automatic recovery after 0.5 seconds of good readings - Conservative approach: only validates when GPS available and moving >7 m/s Safety improvements: - Detects blocked pitot tubes (forgotten cover, insects, ice) - Prevents dangerous high gains with invalid pitot data - Maintains aircraft controllability when pitot fails - Clear pilot awareness via OSD warning Addresses GitHub issue #11208
Changes to Airspeed-based PID Attenuation (APA) for fixed-wing aircraft: 1. Reduced I-term scaling aggressiveness - I-term now scales with (apa_pow/100 - 1) instead of apa_pow/100 - Example: apa_pow=120 → I uses 0.20 exponent vs 1.20 for P/D/FF - Prevents integral windup and overshoot - Follows industry best practice (Betaflight, ArduPilot) - Maintains trim stability across speed range 2. Reduced maximum gain increase from 200% to 150% - Changed upper constraint from 2.0 to 1.5 - Prevents excessive gain multiplication at low speeds - More conservative approach reduces control sensitivity spikes - Still provides adequate authority for slow-speed flight 3. Changed default apa_pow from 120 to 0 (disabled) - APA now opt-in for safety - Users must explicitly enable after validating pitot sensor - Updated description to reflect new behavior - Safer default for new users Control theory rationale: - P/D/FF scaling compensates for dynamic pressure (½ρV²) - I-term serves different purpose (steady-state trim) - Aggressive I scaling causes windup and oscillation - Conservative I scaling improves control stability Combined with pitot validation (previous commit), these changes provide comprehensive safety improvements for APA feature. Addresses GitHub issue #11208
9afef93 to
80ec5cd
Compare
Clamp airspeed to 100-20000 cm/s (3.6-720 km/h) before using in power calculations to prevent: - Division by zero or near-zero values - NaN results from invalid airspeed readings - Overflow from extreme values The constrainf() output clamps are still in place as the final safeguard, but this prevents bad intermediate calculations.
|
I have a couple of questions:
I agree with |
|
Excellent questions, thank you!
This is what I'm seeing; please tell me if you see anywhere I am mistaken: getVirtualAirspeedEstimate() returns 0 if GPS is not available So the pitot reading is treated as plausible and the failure counter in pitotValidForAirspeed() does not increase -- APA is used. I am also attaching a PDF with flowcharts and a decision table. That document is of course not authoritative - the code is.
wind_estimator.c will virtually never deem the wind estimate unreliable while the aircraft is moving, so let's consider the case where the wind estimator calls itself reliable, but the data isn't great. Suppose the following actual speeds: The pitot will be treated as plausible if reading is between 30-200% of the estimate. Let's try another: Still not even close to being treated as implausible. What if we fly really slow, only 10 km/h actual airspeed, with a strong tailwind? (With the wind being stronger than our airspeed, which will mess up other things) NOW it wouldn't be trusted and would revert to the existing TPA behavior, if the stale wind estimate is four times higher than our airspeed.
What gains (and therefore effective P-term and D-term) are "required" is of course a bit subjective and hard to measure - the PID loop will make things work with a range of PID/FF values. So this is an area it would be good to get feedback from testers - preferably with very clear observations of behavior, and blackbox logs would be wonderful. The earlier testing (RC4) improperly scaled the I-term changes, probably overdriving I and making the low-speed tests no longer applicable. 150 (50% increase) is conservative, IMHO. But 0% flew just fine for years before we had TPA. |
Shouldn't this instead be false; as there is no way to validate the airspeed sensor? So we don't know if it's reading is plausible or not. Erring on the side of caution, but it is a safety feature. It does tie having an airspeed sensor to needing a GPS. But we could always make an explicit parameter, with a warning, to bypass that safety check if no GPS is found. Then it's the pilot's responsibility if they disable the safety feature and things go wrong.
I seem to recall that the wind estimate is marked as stale (unreliable) after 10 minutes of flying in the same direction. It will show an X in the OSD to warn that the wind speed reading is stale.
Honestly, I'd have expected that to start being close to implausible. 200% seems like a big difference. If I'm seeing 20km/h difference at those sorts of speeds. I start not trusting the airspeed sensor. Usually calibration could be out. But not that the tube is blocked (unless it's reading wildly under). I'm visually looking at +/- ~30% difference at most for my known flying speed. Usually it is much closer, easily within 5-10%. Perhaps this could issue a calibration warning on the OSD. Then not fully trust the airspeed at higher values?
I'll trust the opinions of the @Jetrell and the guys who were testing this extensively with regard to this. I just wouldn't want to make this feature inapplicable in some applications. Especially when it's the result of one guy, who likely had his PIDs tuned too tightly. |
I'm showing 15 minutes without a combined change in pitch and yaw, 11.5 degrees. A bit higher than I was thinking. #define WINDESTIMATOR_TIMEOUT 60*15 // 15min with out altitude change
Let's consider what we do with other sensors. If the gyro is giving reasonable readings, maybe 30 degrees per second, and we have no other sensor to cross-validate, do we throw out the gyro reading, mark it as untrusted? If the GPS is giving reasonable location and speed readings, and we have no other location sensor to cross-validate, do we throw out the GPS reading, mark it as untrusted? Heck, if the RC commands from the receiver are reasonable values 1000us-2000us and we have no other source to cross-validate ... If every source of input required two independent sources -- well we'd be Ardupilot. 😀
Would you rather trust that the ground speed is the same as the airspeed? (Which will never be true for an airplane in flight). So long as the airspeed sensor isn't giving clearly questionable readings (-1, or INT16_MAX), I would treat it as the most reliable source of airspeed data, barring clear reason not to. Full scale pilots are trained that if your pitot says one thing and your eyes say another, trust your instruments more than your eyes. Given reasonable readings, I would certainly trust it more than the alternatives, which are guaranteed to be wrong.
Jetrell is amazing. And cross-validation is always good when can get it, so I'd also love to hear from anyone else who has some data. Especially with blackbox data. "Data is king." |
|
To be honest, with ground speed + wind speed available. I would use that as a pretty good indicator within reason. Certainly enough for a sanity check. If it's more than +/-50% off. Something is wrong. I completely agree with not trusting your eyes. Anyone who's flown lowish over water knows how deceiving that is. But, I would also say there are big differences between full size pitots and the size most people are using. The hole is tiny on the hobby tubes. I've seen a couple of occurrences of them getting foreign matter in there. It doesn't always completely block the tube too. So you still get readings. They're just off. We actually moved to a larger pitot tube to get away from this issue. But people in the hobby wouldn't. Mainly because of thse size. So would I 100% trust a pitot tube over everything else at the hobby scale? No. |
I would love to see those blackbox logs and see if higher-frequency components of the reading fluctuate a lot more than a clear tube, or any other signs we could pay attention to. I suppose a sudden drop in reported airspeed that doesn't correlate with either accelerometer or GPS could be a clue. If the airspeed drops from 60 km/h to 20 km/h in just 20 milliseconds, something is wrong. That would be a deceleration of 30G. I'm more comfortable looking at things like that. A bug strike or similar would be a sudden event, a sudden big change in reported speed. We pretty much know the aircraft didn't decelerate at 30G and remain in one piece, so that gives us a solid reason to say something is wrong with that pitot data. |
|
After again reviewing the changes @sensei-hacker made in these commits. It seems like it now accounts for far more failure conditions.
@MrD-RC I think that tuning the PID's too tight could always be a point of concern. Because it leaves little room for sensor deviation. I made a few notes about that in the Wiki. Edit : @sensei-hacker we are heading off soon. But I'll have a quick look and see if I can find that log to DM it to you. |
|
I started to write a draft for these changes to update the wiki once this is tested and merged. You may say. Isn't it the same attenuation/boost scaling as before. And the answer is yes. But now the base gains are tuned much tighter than they ever were with the old TPA/B method. And the dynamic gain control over TPA is much smoother and more incremental than before. With it always making adjustments as the planes pitch attitude changes. I'll explain. The defaults for TPA + Pitch angle are as followed -
And when it comes to the APA side of things. I consider the default of |
|
Thanks, Jetrell. That all makes sense about the default TPA + Pitch angle settings. Some of this comes back to a fundamental oversight in how TPA is currently implemented. The fundamental problem is that it currently treats a commanded change of setpoint from pilot input the same as a uncommanded change of attitude from a wind gust or from pitch-roll coupling. Treats trying to change the attitude the same as resisting a change of attitude. The proper response is different between those two. Between a command to change the setpoint vs an uncommanded disturbance to attitude. Trying to treat them as the same is what makes the tuning and settings necessary - trying to balance two things that shouldn't be mixed together at all. It's same thing that was discussed with the exponent for pow_apa. I'll have a PR for that in a future version. The exponent should actually be 1, 2, or 0, depending on what you're trying to accomplish (the term). Are you trying to change course (commanding a change to the setpoint, feed-forward FF), or are you trying to resist the force of the camera gimbal acting as a rudder (uncommanded disturbance, the P-term)? The setting exists only because the current *PA code mixes these different things together, requiring a compromise between the correct value of 1 and the correct value of 2, for the different things. Trying to find a value you can live with for both when the correct value is 1 for the first thing and 2 for the second thing. Separating them will especially help for tailless planes ("flying wings"). If you command pitch, TPA should be applied at ^2 to the pitch commmand. But you will also get uncommanded roll and yaw because elevons. That correction should either not be TPAed at all, or arguably linearly. Treating them the same as why you have to do the testing and tuning to try to find a balance you can live with. So the to account for the fact that the pilot is WANTING the attitude to change. But that's for future work. For now, we can adjust the default settings to work best with the TPA code we have. |
|
Gave this branch a try, quick first flight locally to test compile and flashing, had no issues and gave it the beans on 6s. Went out to a spot with some more room to test failures and first test with pitot sock left on failed. The code did not detect the poor data and did not display a OSD warning and I felt the impact of the increased gains almost immediately, could not test for long however as I had an ESC failure about 20sec into the flight so not much log data. Had to land some distance away from me that took a while to retrieve, so most of the log is just me fiddling the sticks on my walk to collect the airframe. Worth noting I set the TPA rate to 0 and breakpoint to 2000 so it would not come into play during the simulated airspeed sensor data failure. |
|
I'd like to voice my disagreement of the change of the max scaling to 1.5 instead of 2.0.
I understand this feels like risk mitigation, but its a bandaid that doesn't really solve anything and neuters some of the benefits of the *PA system. I fly a penguin that has a flight envelope from 100mph to as little as 10 mph when you're flying at a high AOA. The APA system at 2x scaling is perfect for stabilizing these high AOA flights. It holds attitude beautifully even at these super low speeds due to the high gains. Its like an F35 matching speed beside a Cessna 172 - the F35 control surfaces are fluttering all over the place, but the plane is rock-steady. If we are trying to satisfy all users here, maybe this needs to be a user-set variable. Someone like me can set it to 2.0, and someone like @quadlawnmowerman-coder can set it to 0 if he wants. Though - I think IF the airspeed detection could be adequate, this change isn't necessary at all. As a possible contributing factor, in my experience, some portion of the pitot initialization is not working right. Every time I plug in my plane (pitot sock installed), I have a residual pressure that is indicating something in the range of 7-12 mph airspeed when still sitting on the ground. At the recommendation from someone on discord, I have started restarting the FC via OSD after GNSS is satisfied, and the airspeeds appear much more accurate, and the residual pressure drops to ~0-4 mph - and returns there once landed. Not sure what your experience @quadlawnmowerman-coder is with the airspeed accuracy, but if you've got 11 mph at 0 dynamic pressure, at low speeds you could still be outside of the check that @sensei-hacker outlined:
@sensei-hacker, why are you checking the 200% case anyway? I think the only real concern here is if the pitot reports low, and indicating a clogged tip. For the use of any *PA system, the only real concern is over-gain, because over-attenuation will not crash the plane (at least - not due to oscillations). Is the only way to test this literally to take off with a pitot sock installed? A proper pitot sock really should be impossible to forget to remove. So we're really talking about solving either improper maintenance of the pitot tube, or the 1:1,000,000 chance of the perfect bug strike? @quadlawnmowerman-coder do you have an OSD video of the last test you can share? |
|
@trailx thats great feedback! And with the other planned validity checks in place, a blocked pitot tube should not be an issue anyway with the 2.0 factor. |
We do not. That change was simply an "abundance of caution" thing. Not based on any log, any actual experience, or any aerodynamic formula. It was purely a "it seems like maybe a good idea" thing. Personally, I think 2.0 or higher makes more sense. If TrailX and b14ckyy agree, we'll do that. The flight experience and log we have is from BEFORE other things were fixed. The most recent log and report from quadlawnmowerman-coder revealed another issue. I am pushing a commit to address that right now. |
When hardware pitot fails validation, getAirspeedEstimate() now returns GPS-based virtual airspeed instead of the corrupted pitot value. This ensures APA (Airspeed-based PID Attenuation) continues working correctly with valid airspeed data. Changes: - getAirspeedEstimate() falls back to virtual airspeed when pitotHardwareFailed - Faster failure detection: 0.2s (20 samples) vs 1s (100 samples) - Slower recovery: 2s of consecutive good readings required - Separate recovery counter prevents underflow with asymmetric thresholds Fixes issue where blocked pitot caused APA to use invalid airspeed, resulting in incorrect PID gain scaling. Co-Authored-By: Claude Opus 4.5 <[email protected]>
|
Thanks so much for the log and report, @quadlawnmowerman-coder ! I ran that log through SITL, reproducing the flight in an instrumented environment. From that, I was able to identify two issues, which should be fixed in the latest commits here. Note I am not able to fly right now, so I have only tested my fixes by a limited simulation. Actually I may do more simulator testing on it tomorrow, to double-check that the OSD message ACTUALLY appears. |
|
Yeah I would in this case also agree to leave the max gain at 2.0 at low speed. It makes sense mathematically and as long as we can exclude false low speed readings from the sensor, i see no reason for that extra caution that might reduce flight performance for the majority. |
|
Thanks for your comments, @trailx The consensus both here and on the Discord seem to be stick with 2.0 for maximum tpaFactor as originally written. Trailx wrote:
That sounds like an Issue that should be recorded separately so it doesn't get lost and we can address that. It may be we should delay pitot calibration by a few seconds --- if it ends up mattering anyway, though I suspect it won't because of one thing: 10 MPH is about 12 Pascals, so that would be 12 Pa of error. So 12 Pa of error reads as less than 1 MPH difference at flight speed. You asked:
My thinking is that if the GPS shows 40 MPH and the pitot is reading 2,300 MPH, maybe something is wrong with the pitot. :) In particular, one common sensor type maxes out at 223.694 MPH. If it reports infinity 223.694) while the GPS says 50 MPH, the pitot is broken. Different sesnors have different infinity / maxed out values. There's nothing special about the exact value of 200%, just trying to catch readings that look quite suspect.
True. And an improper one is just a piece of heat shrink with no tag, often forgotten. |
- Increase fw_tpa_time_constant default from 1500 to 2000ms - Raise airspeed TPA factor upper limit from 1.5 to 2.0
…alidation Adjust TPA parameters for fixed-wing aircraft
Updated fw_tpa_time_constant default value from 1500 to 2000 in Settings.md to match the authoritative value in settings.yaml. The discrepancy was caused by the documentation being out of sync with the YAML source. Regenerated using: python3 src/utils/update_cli_docs.py
|
@Jetrell wrote:
Thanks so much for doing that. If you want to chuckle at the different places a bot thought could be updated: Documentation Updates for PR #11222Pitot Sensor Validation & APA Safety ImprovementsSummary of ChangesPR #11222 implements:
✅ Already Updated in PR
🔴 Most important updatesinavwiki/PID-Attenuation-and-scaling.mdFile: https://github.com/iNavFlight/inav/wiki/PID-Attenuation-and-scaling Line 52: Update default value
Line 67-68: Update pitot reliability warning
**When INAV automatically detects pitot failures:**
- Compares pitot readings against GPS+wind virtual airspeed
- Automatically falls back to virtual airspeed if pitot reading is implausible
- Displays "PITOT FAIL" OSD warning when fallback is active
- Aircraft remains controllable with correct APA gains during fallbackLine 57: Update fallback behavior note
🟢 MEDIUM PRIORITY - Nice to Haveinavwiki/Sensor-auto-detect-and-hardware-failure-detection.mdFile: https://github.com/iNavFlight/inav/wiki/Sensor-auto-detect-and-hardware-failure-detection
inavwiki/Fixed-Wing-Guide.mdMention pitot and/or APA? inavwiki/Tune-INAV-PID‐FF-controller-for-fixedwing.md ? |
I am away for work for the next few days unfortunately @sensei-hacker so I won't get a chance to test until my return.
I don't see an issue increasing it once the data sanity check is confirmed working, but I think the apa-pow settings should also be split at the same time to enable control of the below and above fw_reference_airspeed rates changes independently so as to provide the ability to directly influence/tune above and below gain changes separately. |
@sensei-hacker |
@quadlawnmowerman-coder , I don't think I follow the reason behind this. Its not like we're entering different realms of aerodynamics with different fluid compressibility, which could be an argument for changing the pow above and below the breakpoint or ref airspeed. Based on the physics, a continuous gain tune makes sense here. One challenge is that to my knowledge the Airspeed POW has not been added to the adjustments tab yet - which would allow in-flight tuning. I've dialed in all my planes this way, but APA is not currently accessible in flight. So fine-tuning with guess-and-check of this parameter is difficult. (There's certainly a chance this has been done since my last test) That said, I think if you follow the following steps:
Then you should be able to get it really well dialed in without having to mess around with a high speed APApow and a low speed APApow. Is there a scenario I'm missing that you think requires this? I am contending with winter weather and haven't been able to fly lately, and a maiden flight of a new plane may take priority during the next decent day. |
The effect All So if you experience oscillation before minimum touch down speed on a fast airplane that has
This may all sound like workarounds. But that's the whole point of adjustable settings. So they can be tuned to suit the 5% of non typical airframes. That the defaults don't work as well with. |
|
You may not want to tune apa_pow that much based on oscillation - that may be more the base PIFF and rates. If you have oscillation at apa_pow 100, your PIFF are simply too high. (Probably mostly P). Putting in negative expo by lowering apa to less than unity would be a bodge, not a proper fix. Really, for apa_pow, if you do NOT want strong stabilization against turbulence etc, set it close to 100 (which is really 1, a straight line). 100 does "the right thing" aerodynamically if you assume the control surfaces are used only for performing maneuvers, based on stick input or position commands. 100 means the ailerons and elevator follow the sticks, they don't do much stabilization against turbulence etc. If you want more stabilization against turbulence etc, the aerodynamic effect of moving your camera gimbal, etc increase it. Closer to 200 (really 2) is the right fluid dynamics for a plane flying straight and level, only being stabilized against outside disturbances. So for cruise mode or long, straight missions. 200 would be "I don't plan to use the sticks at all, just keep it flying straight and level". Around 120-130 is a compromise, saying "mostly the control surfaces respond to my sticks, but also I want some stabilization". apa_pow below 100 will make the control response too flat in all conditions. Too much deflection at higher speeds and too little at lower speeds. apa_pow below 100 would be like having negative expo on your sticks. In fact, it actually WOULD be requesting negative expo on the I-term, saying that the surfaces should deflect FURTHER at higher speeds. I have a check in the code to prevent it from actually going negative for I (below a setting of 100) because that's obviously wrong. If you set less than 100, it'll just act like you set 100, for the I-term. apa_pow below 100 is a bit like if someone set a cruise speed of -25 km/h. Clearly wrong. Really, logically valid values are 100-200, or 0 to turn it off and fly like you don't have FC, using your fingers to reduce movement at higher speeds. If you're setting apa_pow below 100 to offset an issue at a certain velocity, that's likely a band-aid for having wrong PIFF settings to start with. Lower the P or FF. I don't see much to test and tune with this parameter unless you can repeatedly fly through the same turbulence. (Maybe at a cliff edge?) That's really what the setting does - higher for more rejection of turbulence. Lower to follow the sticks more closely. Use the P term, not the airspeed expo, to control how much the surfaces move when you move the sticks. apa_pow below 100 is almost like saying "do the opposite of what my sticks are commanding". If you find you need to SUBTRACT motion by having negative apa_pow, the P or FF is too dang high. (Below 100 is essentially negative expo). Maybe we should name the setting "turbulence_rejection" or similar to make it clear. |
|
@sensei-hacker , double check the way you're thinking about apa_pow. I think you're forgetting its an inverse power. pid_multiplier = referenceAirspeed / (airspeed ^ (apa_pow/100) ) So it only goes to a line when apa_pow = 0. A while back I had worked up this graph outlining a few examples of how the attenuation curve moves based on ref_airspeed and apa_pow:
apa_pow can absolutely be tuned based on the presence of oscillation, because that is exactly its job (at least at high speeds). Attenuation - because if you don't have it, the PIDs become too strong at high speeds, creating oscillations. This is how I knew the first draft of APA wasn't strong enough - because it generated oscillations at high speed. If it generates oscillations at a high speed above ref_airspeed, then there is not enough attenuation, so apa_pow needs to be raised (which may sound counter intuitive). If it generates oscillations at low speed, then the apa_pow line is too steep, and apa_pow needs to be reduced to flatten the gain/attenuation curve a little. @Jetrell you're right, you can also move the ref_airspeed down which effectively scales the whole curve in the airspeed axis, effectively very similar to just raising and lowering the PIDs. |
I played around with the tuning of it a couple of months back when testing its operation. I adjusted it from between 80 on a very quick airplane. Upto 200 on a park-flyer. But as you said. I really doubt that setting needs much inflight tuning. In general, just roughly working out what you should require in theory from the plot is good enough.
Pretty much. I agree. The math scaling does get a bit sloppy the lower you take it. From memory it was around 25000km/h at the low end of apa_pow. However it can still act as a workaround to provide some boardening of the scaling to suit airplanes that have a very high top-end speed. As mentioned earlier. Remembering, this is an edge case. Maybe the math could have been done better. But we have what we have. And it's still much better than what we had for 95% of users :-) |
|
Rmemeber what Jetrell played around with a couple months ago was a different implementation, with different characteristics. Do not confuse the older implementation with the current one, and which removes the additional use of apa_pow against the time integral. The workaround to deal with the incorrect initial implementation does not apply now that it has been corrected.
With apa_pow = 100 (which really means 1): so y = x "y = x" is a straight line, isn't it? Specifically, isn't it a very particular straight line - the straight line that corresponds with having the deflection (rather than the force) scale linearly with airspeed? And with apa_pow set to 0.5, what happens? (x is apa_pow) and the I-term multiple is of course: Now you have a curve going the wrong direction! More deflection at higher speeds, less deflection at lower speeds. |
|
To maybe clarify: Initial testers found they needed to reduce apa_pow BECAUSE it was improperly increasing (or decreasing) the time integral term. It was 100 too high on the I-term. Final release fixes that bug. We're no longer blowing out the I term. So you shouldn't need to cut apa_pow anymore. |
|
For even more detail on the fix for the bug that was overdriving it and creating the need to reduce apa_pow by 25% to 75, look closely at this code: Vs: Note the operator is for the time integral term is "+=". The I-term is increased or decreased each loop. The I-term is the time integral. Essentially a duration counter. Measuring the length of time that the error has persisted. You'll notice the P, D, and FF are just "=", not "+=". They are measure of the current state, not measurements of time. It was multiplying a time interval by a power of airspeed. Then we have: So when testing, the total that testers saw in the earlier version was: It would make sense you needed to reduce apa_pow by 25% in order to subtract out the incorrect scaling of the time integral. |


User description
Summary
Improves safety of Airspeed-based PID Attenuation (APA) feature with automatic pitot sensor validation and more conservative gain limits.
Changes
Pitot Sensor Validation:
Safer Gain Limits:
Safe Defaults:
Testing
Related Issues
Closes #11208