QuadPlane: fix QLoiter backtransitions - #33874
Conversation
c8fafa1 to
9ed1275
Compare
a5cac18 to
7c0c8d4
Compare
This test takes off, transitions to fixed-wing, and enters QLAND abruptly. There are four variations of this test: different combinations of two options: - whether the takeoff/outbound-transition is turning when it completes - whether the QLAND entry is from a straight leg or from a circle. The vehicle must brake to a stop smoothly without excessive hunting or overshoot, and without fighting the airframe's aerodynamic stability. Red at this commit for the turning-takeoff-transition flavors: QLoiter initializes from the stale banked attitude target and S-turns through the deceleration. Fixed by the following commits.
On QLoiter/QLand entry from fixed-wing flight the loiter controller initialized from the multicopter attitude controller's target, which has been frozen since VTOL was last active. When the attitude controller has not run recently, initially command level for up to 3 seconds, or until a reasonable attitude target is reached for the loiter controller to initialize from.
|
I'm a bit surprised about the leftover state. We do relax the attitude controllers just before we run them if they have not been run recently. I guess the problem is that the loiter/pos-control init is called before that relax is done? So they see the stale values even though the attitude controller do not use them. |
It's the input shaping in the pos-control init that does it. If it initializes from a banked attitude, it will calculate the initial acceleration from that (which is huge), then jerk-limit smooth that out (slowly). This means it will try to follow the banked turn you're doing if you initialize off that (or, because of the leftovers, follow the curve of the banked turn you did an hour ago) You may notice I've completely reworked how I fix this now, I have a whole write-up with more details, but I wanted to wait until the morning to post it so I'd be fresh for any followup. Long story short
|
7c0c8d4 to
35b3381
Compare
|
I've reworked the mechanism of my fix in this PR, after some conversation with Leonard, a lot of thought, and a little sleep, and I think this is actually a good shape, with solid rationale. We know that the existing behavior is trying to initialize from attitude targets that may be hours old. The question is which approach to take to fix it. Option 1: Current Attitude, Immediate Handoff to AC_LoiterLeonard was experimenting with initializing the loiter controller with the current attitude among other things, which causes it initially to carry on with any banked fixed-wing turn you were doing at the time, braking while slowly leveling back out.
This definitely could be desirable behavior, but the main issue is that the heading stays locked, uncoordinating the turn and fighting physics on the airframe. If we can solve that problem, I'm onboard with it.
Leonard was attempting to solve it with One of the other really good things worth noting on that branch is the switch to using
(that change does have a couple unintended consequences to chase down, most notably making the pitch up way more aggressive, because it bypasses Option 2: Level Attitude, Immediate Handoff to AC_LoiterOne option I was playing with was zeroing out the target rates and roll/pitch angles, then doing the loiter init. This has the benefit of being identical to what we've been doing for years, only we've previously been doing it on accident, since that's the state we tend to be in at the end of transition. Doing it explicitly is just a strictly better version of what we're doing now, and I do think that patch would be safe. Leonard's reaction to this idea is "Loiter needs to be initialised as loiter is initialised. If you need it to behave differently you need a different flight mode.", and he's not wrong, so that leads me to option 3. Option 3: Level Out First, Later Handoff to AC_LoiterInitializing the loiter controller in the middle of a fixed-wing maneuver with accelerations far outside the limits it was designed for isn't great. We probably ultimately want to split this up into stages, like we do with auto landings, and hand off to AC_Loiter only when it's sane. If I wanted to start with the dead-simplest two-stage switch to QLoiter, it would be something like "level out briefly, then init QLoiter", so that's essentially all I'm doing in this PR. I was originally writing this whole thing up to justify option 2, but I tried this one real quick to see how well it would work. I was very surprised to see that it works almost identically to option 2. When hitting QLoiter/QLand from banked flight, this strategy only increases the stopping distance by about 2m and actually decreases the landing time by 1s (marginally less ballooning). If you enter during level flight, the leveling stage immediately ends, so it has zero impact on those cases. The benefit of this, over option 2, is that this requires no mucking around in the common libraries and lays the foundation for more sophisticated stage-1 behaviors later. In the future, things like the pitch-up rate limit with |
|
Sounds really interesting @robertlong13 have you had a chance to test it on a real plane? |



Summary
Fix a bug that can cause excessive position hunting when switching to QLoiter/QLand from fixed-wing.
Classification & Testing (check all that apply and add your own)
Description
Currently, the stopping behavior when switching to QLoiter depends on state that accumulated during your transition to fixed-wing flight. This bug is long-standing (tested back to 4.5). Below are two screenshots from a test on master.
If you don't do your outbound transition perfectly straight with wings level, you get this weird hard bank when you switch into QLoiter/QLand.
The fix I'm proposing in this PR is to initialize the loiter at the current position, re-seeding the velocity PID integrator for a pure brake (only when initializing from a period of position controller inactivity). The vehicle now rolls wings level and pitches back to a stop from any entry attitude, regardless of the state of the forwar-transition, stopping in ~6s from 25m/s and remaining within 2m of the final landing point, where it previously wallowed for 13s and wandered around more than 10m.
Screenshot of ground tracks before/after my fix:
My only issue is that the code for my fix looks a tad hacky with the
vel_pidstuff I'm doing, but I think the idea is sound, and I believe this is the cleanest way to achieve it. @lthall (or anyone else) if you have any opinions on a better shape of this, I'd be happy to hear them. Or if you just wanna swipe my autotest and fix this a different way in a superseding PR, I'm totally fine with that.The new autotest reliably fails, on all 4 criteria, before the fix, and reliably passes after. Plenty of headroom.
Turning transition (transition tail freezes a banked attitude target)
Every master run fails all four criteria; every fixed run passes all four.
Straight transition (control: transition tail freezes a level attitude target)
Master already passes when its stale attitude target happens to be level, the same code and thresholds, demonstrating the expectation is realistic and the fix simply makes the happy case the only case.