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
Converge IMU faster at higher groundspeed during GPS Rescue #12738
Converge IMU faster at higher groundspeed during GPS Rescue #12738
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
(Did I mention Kalman filter in IMU this year?) |
1433ddc
to
4f3d45e
Compare
This comment has been minimized.
This comment has been minimized.
AUTOMERGE: (FAIL)
|
4f3d45e
to
273c65d
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
a3a13ca
to
b9121e9
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
94c0009
to
5f864f9
Compare
This comment has been minimized.
This comment has been minimized.
b5374d8
to
03ce10e
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK if it works in practice.
But remove M_HALF_PIf
, M_TWO_PIf
3908908
to
e00970b
Compare
This comment has been minimized.
This comment has been minimized.
e00970b
to
7b8ed25
Compare
This comment has been minimized.
This comment has been minimized.
@ledvinap @KarateBrot... I accepted your comments above and:
Both Sek101 and I have tested this code now, and it works very well. The higher gain for the IMU boost factor helps deal with IMU errors more quickly when needed, and does not induce circling or excessive overshoot, even with 120kph backwards flight with a full 180 degree IMU error. I think the gain factor is about as high as it should be. I'm very grateful for your advice and assistance with this PR. A final check, and if agreeable, approval, would be much appreciated. I am confident that it will make GPS rescues much safer. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
src/main/flight/gps_rescue.c
Outdated
@@ -567,6 +569,25 @@ static void sensorUpdate(void) | |||
rescueState.sensor.distanceToHomeM = rescueState.sensor.distanceToHomeCm / 100.0f; | |||
rescueState.sensor.groundSpeedCmS = gpsSol.groundSpeed; // cm/s | |||
|
|||
// when there is significant velocity error, increase IMU COG Gain for yaw to a higher value, and reduce max pitch angle | |||
if (gpsRescueConfig()->rescueGroundspeed) { | |||
const float rescueGroundspeed = 1000.0f; // equivalent of fixed 10 m/s groundspeed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const float rescueGroundspeed = 1000.0f; // equivalent of fixed 10 m/s groundspeed | |
const float rescueGroundspeed = 1000.0f; // in cm/s, fixed 10 m/s groundspeed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I'll make that change.
@@ -648,10 +669,13 @@ void descend(void) | |||
rescueState.intent.targetVelocityCmS = gpsRescueConfig()->rescueGroundspeed * rescueState.intent.proximityToLandingArea; | |||
// reduce target velocity as we get closer to home. Zero within 2m of home, reducing risk of overshooting. | |||
// if quad drifts further than 2m away from home, should by then have rotated towards home, so pitch is allowed | |||
rescueState.intent.rollAngleLimitDeg = gpsRescueConfig()->maxRescueAngle * rescueState.intent.proximityToLandingArea; | |||
rescueState.intent.rollAngleLimitDeg = 0.5f * gpsRescueConfig()->maxRescueAngle * rescueState.intent.proximityToLandingArea; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This changes scaling of user parameter. gpsRescueConfig()->maxRescueAngle shall be commented in CLI (only half is used for roll limit)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can document this behaviour in the wiki, but I'm not sure how to make a 'comment in the CLI' for the user to read.
Roll is significantly weaker than pitch in the rescue, and just about never reaches the limit of half the pitch angle. The main consideration is the limit on pitch, that's the one that concerns people the most.
The intent here is that if the user changes the pitch angle to a very low value, that the roll angle stays in approximate proportion to the pitch angle change.
The actual roll angle depends on yaw rate, and also on the amount of roll added by earth referencing code in Angle mode. By limiting the GPS part of the roll angle to half that of pitch, the user will likely not exceed the set max angle even with earth referenced yaw enabled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think code comment is enough. As you say, the 50% limit is more than enough. But make it easier for programmers to understand it and avoid confusion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do this in separate PR
|
||
if (FLIGHT_MODE(GPS_RESCUE_MODE)) { | ||
cogYawGain = gpsRescueGetImuYawCogGain(); // do not modify IMU yaw gain unless in a rescue | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} | |
} else { | |
cogYawGain = 1.0f; | |
} |
CoG is used to correct yaw in forward flight. Ideally, thrust vector horizontal vector shall be computed from roll/pitch and used to adjust courseOverGround
. But for now, don't change existing behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here I think the alternative,or else
condition, on line 498, should be a zero value, not a 1, to return the float equivalent of the boolean OFF. That's why I initialise cogYawGain
to 0.0f
on line 477. Our intent is to do nothing unless we are in FLIGHT_MODE(GPS_RESCUE_MODE)
. If we keep cogYawGain
at zero, it won't pass the check for if (cogYawGain != 0.0f)
back on line 213.
I agree it would be great to get a vector from roll/pitch attitude to help evaluate courseOverGround, especially if integrated over time, and also agree that for now I'd not want to change the existing behaviour.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Original code did set useCOG = true;
https://github.com/betaflight/betaflight/pull/12738/files#diff-de6b2b61376cbb30512686ebb362260facb69cf9a4281ebdcd59af61c0306f7aL498
This change would disable GPS yaw correction unless in GPS_RESCUE_MODE. It may be desirable, but it is unrelated to this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ledvinap Looks like this was merged before I had time to resolve this.
I'll make a small PR to restore the original behaviour. I'm not 100% exactly sure what is best, but I guess we should correct the quad's attitude throughout the flight, since otherwise it could drift. And in any case I had no intention of altering the existing behaviour.
Also I was reflecting on your comment, earlier, about using Pitch angle as a factor for IMU gain.
This could be done quite easily in the GPS Rescue case, and would be beneficial in the situation of a rescue initiated with very low groundspeed but an IMU that is 180 degrees wrong. Currently the quad will pitch forward, but it takes time to accumulate velocity before the IMU gain for yaw is increased. If we had a signal to boost IMU directly related to forward pitch angle (before adjustment for groundspeed error), this is nearly always high to maximal in groundspeed error settings, and is high from the moment the rescue starts. Using positive pitch angle to generate IMU yaw gain would act as a leading indicator of a 180 degree IMU error. Also, generally speaking, it is more likely that if the pitch angle is positive, then we should have direction over ground that corresponds 'better than usually' to the orientation of the nose of the quad.
A flight home at high angle against a strong headwind, or with a high target velocity, could require a high pitch angle all the time. The quad would then fly home with an increased IMU gain on yaw the whole time. In both these situations we should be pointing fairly directly to home, and the IMU error in any case resolves to reduce the effect of sideways drag. IMU yaw gain is functionally a time constant, so we are not going to change the magnitude of anything, just how quickly it happens, and this is probably not so bad in higher pitch angle environments.
I'm inclined to test this out. It will require some heuristic gain factor though :-)
Thanks again for all your input to date, I very much appreciate everything you've done here.
Do you want to test this code? Here you have an automated build: |
I flew a number of packs with this yesterday and it works VERY well one warning is not to stand to close to your launch point as it’ll try and land on your head 😂 |
1 similar comment
I flew a number of packs with this yesterday and it works VERY well one warning is not to stand to close to your launch point as it’ll try and land on your head 😂 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I flew a number of packs with this yesterday and it works VERY well one warning is not to stand to close to your launch point as it’ll try and land on your head 😂
…ht#12738) * dynamic dcm_kp depending on groundspeed vs velocity to home * reduce max pitch angle default to 40 * Only 10% of set velocity to home is enough, angle to 45 to reduce chance of sanity check against headwind * fixes, thanks @KarateBrot * Feedback from Ledvinap, ensure full pitch and yaw authority in descend * pitch limit max of 1/3 and dcm_kp gain to 6x max * apply IMU kP factor to yaw only via ez_ef * More from @ledvinap, constrain pitch in descent also * Fix the velocity error gain, refactoring thanks to Ledvinap * thanks, Mark! * fixes, must be fabsf * make IMU gain twice as sensitive to groundspeed error * useCOG as float * Fix unit test * ensure cogYawGain is zero, except during gps rescue * update comment after suggestion from ledvinap * keep roll angle limit consistently at 50% of pitch limit when active * changes to comments, thanks petr
…12785) Converge IMU faster at higher groundspeed during GPS Rescue (#12738) * dynamic dcm_kp depending on groundspeed vs velocity to home * reduce max pitch angle default to 40 * Only 10% of set velocity to home is enough, angle to 45 to reduce chance of sanity check against headwind * fixes, thanks @KarateBrot * Feedback from Ledvinap, ensure full pitch and yaw authority in descend * pitch limit max of 1/3 and dcm_kp gain to 6x max * apply IMU kP factor to yaw only via ez_ef * More from @ledvinap, constrain pitch in descent also * Fix the velocity error gain, refactoring thanks to Ledvinap * thanks, Mark! * fixes, must be fabsf * make IMU gain twice as sensitive to groundspeed error * useCOG as float * Fix unit test * ensure cogYawGain is zero, except during gps rescue * update comment after suggestion from ledvinap * keep roll angle limit consistently at 50% of pitch limit when active * changes to comments, thanks petr Co-authored-by: ctzsnooze <chris.thompson@sydney.edu.au>
…ht#12738) * dynamic dcm_kp depending on groundspeed vs velocity to home * reduce max pitch angle default to 40 * Only 10% of set velocity to home is enough, angle to 45 to reduce chance of sanity check against headwind * fixes, thanks @KarateBrot * Feedback from Ledvinap, ensure full pitch and yaw authority in descend * pitch limit max of 1/3 and dcm_kp gain to 6x max * apply IMU kP factor to yaw only via ez_ef * More from @ledvinap, constrain pitch in descent also * Fix the velocity error gain, refactoring thanks to Ledvinap * thanks, Mark! * fixes, must be fabsf * make IMU gain twice as sensitive to groundspeed error * useCOG as float * Fix unit test * ensure cogYawGain is zero, except during gps rescue * update comment after suggestion from ledvinap * keep roll angle limit consistently at 50% of pitch limit when active * changes to comments, thanks petr
…ht#12738) * dynamic dcm_kp depending on groundspeed vs velocity to home * reduce max pitch angle default to 40 * Only 10% of set velocity to home is enough, angle to 45 to reduce chance of sanity check against headwind * fixes, thanks @KarateBrot * Feedback from Ledvinap, ensure full pitch and yaw authority in descend * pitch limit max of 1/3 and dcm_kp gain to 6x max * apply IMU kP factor to yaw only via ez_ef * More from @ledvinap, constrain pitch in descent also * Fix the velocity error gain, refactoring thanks to Ledvinap * thanks, Mark! * fixes, must be fabsf * make IMU gain twice as sensitive to groundspeed error * useCOG as float * Fix unit test * ensure cogYawGain is zero, except during gps rescue * update comment after suggestion from ledvinap * keep roll angle limit consistently at 50% of pitch limit when active * changes to comments, thanks petr
Tested, works well, but would appreciate further testing please!
Makes the following changes:
FLY HOME
sanity check. Now the sanity check will only count up towards to the 15s disarm value if the quad fails to reach 10%, not 50%, of the set return speed, when checked each second. As before this is an up-down counter, so any time the quad attains >10% of the set return velocity to home, the counter decrements by 1, towards a minimum of zero, and when less than 10%, the counter increments by one. If there is a net cumulative period of more than 15s with less than 10% forward speed to home, the sanity check will disarm the quad, since it is most unlikely that it will return home. Users should expect some counting up in the early part of a rescue, especially with bad IMU disorientation, but with the above changes the quad should not disarm from this sanity check unless something really has gone badly wrong, eg stuck in a tree, or crashed, or extremely high wind.WARNING 1:
A GPS-only rescue system cannot handle high wind drift - do NOT rely on GPS Rescue in winds above 50-60kph unless you have a properly calibrated and fully functional, tested, Magnetometer (compass). Higher maximum angle will help handle strong winds better, but the max throttle must be increased also, and in the face of a temporary IMU error, the quad may fly off in the wrong direction at high speed. In practice, a 35-45 degree angle is more than enough for normal conditions, a 50-55 degree angle may be better in stronger winds. Always test the return in the conditions of the day to ensure your quad will turn and head for home effectively. If the wind is too high, the quad will kind of spiral around, at speed, making little or no headway. Don't let it do this for more than 15s or it will sanity check and drop.
WARNING 2:
IMU disorientation is always possible with GPS-only systems. If a rescue is initiated and the IMU is disoriented from prior drift or high wind, the quad may initially head off in completely the wrong direction, even though the arrow points straight up. Functionally the quad thinks it is flying home, but has temporarily got the orientation of the quad wrong. The IMU will, or should, correct itself over the next 2-3seconds, but will fly in a large arc while doing so. If the maxim allows angle in the rescue is set high, this arc may be flown at high speed, and cover some considerable distance, but the quad will likely handle higher wind rescues a bit more reliably.
To test: enter a GPS Rescue after a 6-8s period of tail drift (fly backwards at > 2m/s for say 6-10s). Hold that drift long enough for the arrow to rotate 180 degrees wrong. Initiate the rescue. The rescue will then rotate entirely the wrong direction, ie fly directly away from home. With this PR it should gain speed away from home for less than a second, and then smoothly and steadily, over 2-3 seconds rotate towards home. The arrow will keep pointing straight up all the time (the turning is the IMU correcting itself). After maybe 2-4s, it should be heading home. The quad will attain a decent speed while correcting itself. The max speed is determined mostly by the maximum angle.
If the debug mode
RTH
is displayed on the OSD screen, the sanity check timer is the value of the last two digits of the last debug element.Testing in high wind and/or with prior extreme back drift would be appreciated.
Testing to figure out how much wind can be tolerated would be helpful, too.
Thanks to @sek101 for investigating and clarifying the problem. To summarise, the problem is that:
This excellent video from Sek101 shows a takeoff, then a quick rotation to fly away from home backwards. The home arrow slowly orients itself to become 180 degrees wrong. When the rescue is initiated, the quad rotates according to the incorrect IMU orientation, and flies off 180 degrees in the wrong direction.
https://www.youtube.com/watch?v=DyEYdI-Qgtw
Code attempt 1 = FAILURE!
This idea was simple: make the dcm_kp value proportional to groundspeed during a GPS Rescue, using about a 4x increase in dcm_kp at normal rescue speed, and very low dcm_kp at low/zero groundspeed.
RESULT: spirals during initiation when IMU error existed at the start, quad flies off very fast, then enters a kind of "chasing the tail" behaviour.
Video shows, around 44s, quad in reverse, arrow going wrong, then persisting rotation.
https://www.youtube.com/watch?v=BSOgY-f1XtM
Code attempt 2 = NOT QUITE THERE YET!
Here we detect an absolute error between groundspeed and velocity to home, normalised to the intended return speed, plus one. If the quad is flying directly home, there is no velocity error, so this
groundspeedErrorRatio
value would be 0+1 , ie 1.0. If the quad is flying off at 90 degrees to home at a groundspeed equal to the intended return speed, thegroundspeedErrorRatio
would be 2.0. If flying off with a full 180 degree error, at the intended return speed, this factor would be 3.0.Then we use this factor to boost
dcm_kp
during the rescue.RESULT: Some improvement, but still tended to spiral and pick up a lot of speed.
Code attempt 3 = very good!
groundspeedErrorRatio
as above, and use it to boostdcm_kp
up to 5 times.dcm_kp
forcibly to zero while in the climb or rotate phases of the rescue. This locks in the pre-existing IMU state, which is normally pitch forward flight with a high likelihood of pointing to home. By locking in that IMU state, we prevent drift (from wind, etc) from building up an IMU error of the kind that could cause a flyaway.Here is some low-res video of the IMU problem and how this PR achieves a pretty good result in the face of the worst possible IMU errors.
https://www.youtube.com/watch?v=IKbeWCsQj24
This PR should significantly reduce the chance that a working GPS Rescue setup would fail, especially if there is, or has been, signficant sideways or rear-wards drift either for a period of time before the rescue was initiated, or during the climb period. Previous versions of GPS Rescue were very susceptible to IMU disorientation and could enter persistent non-recovering flyaways.