-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
ekf2: separate mag and mag heading control logic #21212
Conversation
f1d5ab7
to
f2c503a
Compare
93e3c52
to
fceda82
Compare
f2c503a
to
b0559f3
Compare
b0559f3
to
3ea66d0
Compare
|
24f708e
to
d091c45
Compare
be5f0ea
to
3d88bea
Compare
ba1ef02
to
c2c78ba
Compare
So far so good in SITL. https://logs.px4.io/plot_app?log=59b15e06-54e2-4c6a-b6d9-d4c71f278435 |
ff45e9a
to
a978a42
Compare
// before they are used to constrain heading drift | ||
_control_status.flags.mag_3D = (_params.mag_fusion_type == MagFuseType::AUTO) | ||
&& _control_status.flags.mag | ||
&& _control_status.flags.mag_aligned_in_flight && isTimedOut(_flt_mag_align_start_time, (uint64_t)5e6) |
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.
Do we really to wait for a defined amount of time if we already check if the mag bias variance is low enough?
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 assumed not, but these are the details I wanted us to review and possibly remove (conservatively).
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 removed the magic timing check, but perhaps we should review the magic "variance good" threshold.
// then the declination must be fused as an observation to prevent long term heading drift | ||
// fusing declination when gps aiding is available is optional, but recommended to prevent | ||
// problem if the vehicle is static for extended periods of time | ||
const bool mag_decl_user_selected = (_params.mag_declination_source & GeoDeclinationMask::FUSE_DECL); |
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.
maybe we should also remove the option to force the fusion and only do it if there is no GNSS aiding
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.
It's not clear to me why someone would want/need to have control over this.
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.
Me neither, and I don't think anyone is actually changing this parameter, I guess it was introduced for testing purposes.
|
||
if (_control_status.flags.mag) { | ||
aid_src.timestamp_sample = mag_sample.time_us; | ||
aid_src.fusion_enabled = true; |
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.
but if the continuing_conditions_passing == false
, do we still want to have fusion_enabled = true
?
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.
Yes that's not quite right, we need to revamp the aid_src population so it's correct and useful on start/reset/stop cycles.
For now I'll move setting fusion_enabled to the end.
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.
is that one still needed then?
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.
Yes for now because of the check in fuseYaw(), but like I said needs a bit of a review/revamp overall.
} else if (starting_conditions_passing) { | ||
// Data seems good, but previous reset did not fix the issue | ||
// something else must be wrong, declare the sensor faulty and stop the fusion | ||
//_control_status.flags.mag_fault = true; |
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.
yes, we could make it faulty here and add a logic to clear the fault if we see that he innovation is continuously low
|
||
resetEstimatorAidStatus(aid_src); | ||
|
||
const bool wmm_updated = (_wmm_gps_time_last_set > aid_src.time_last_fuse); |
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 is a bit misleading: the wmm is constantly updated, but we only need to do a reset when the wmm is set for the first time.
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.
Actually it's only updated twice, first when we get a 2d fix with eph < 1000, then again when the NED origin is initialised.
It would probably be better to continue updating it periodically just in case anyone wants to fly around the world.
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.
Right, we should update it periodically (but only trigger a reset after 2d fix and NED init)
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 changed it to check for WMM changes periodically, but only update if the declination or inclination changed by more than a degree (better arbitrary threshold?).
4e9e0d3
to
b744440
Compare
- periodically check for WMM changes - cleanup mag declination limiting logic and remove mag_3d arbitrary 5s requirement
b744440
to
6eb09a8
Compare
// then the declination must be fused as an observation to prevent long term heading drift | ||
// fusing declination when gps aiding is available is optional, but recommended to prevent | ||
// problem if the vehicle is static for extended periods of time | ||
const bool mag_decl_user_selected = (_params.mag_declination_source & GeoDeclinationMask::FUSE_DECL); |
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.
Me neither, and I don't think anyone is actually changing this parameter, I guess it was introduced for testing purposes.
|
||
if (_control_status.flags.mag) { | ||
aid_src.timestamp_sample = mag_sample.time_us; | ||
aid_src.fusion_enabled = true; |
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.
is that one still needed then?
src/modules/ekf2/EKF/mag_control.cpp
Outdated
case MagFuseType::AUTO: | ||
selectMagAuto(); | ||
break; | ||
if (!_control_status.flags.tilt_align && !_control_status.flags.yaw_align && starting_conditions_passing) { |
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 know that it was already there before, but why do we want to reset the yaw if tilt is not aligned? What's the benefit?
During leveling, we can just fuse a constant position and wait for it to complete before doing the yaw alignment.
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 actually dropped it initially, but kept it for now due to unit test failures (initializeWithTilt, etc). Do you want to take a closer look? Feel free to change the branch directly.
@@ -75,7 +75,12 @@ bool Ekf::fuseMag(const Vector3f &mag, estimator_aid_source3d_s &aid_src_mag, bo | |||
_fault_status.flags.bad_mag_x = true; | |||
|
|||
// we need to re-initialise covariances and abort this fusion step | |||
resetMagRelatedCovariances(); | |||
if (update_all_states) { | |||
resetQuatCov(); |
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.
Side note: I'm actually wondering what's happening if we reset the quat cov like that in air (tilt cov are also reset)
@bresch without yaw reset during tilt alignment. |
6310d45
to
4f2f7e7
Compare
4f2f7e7
to
a81e115
Compare
I removed the yaw reset during tilt alignment and did a pass updating EkfInitializationTest a bit more intelligently (we weren't even checking for tilt_align to complete). a81e115 The non-level initialization tests need a closer look. |
- avoid multiple re-initializations - fuse zero heading innovation to stabilize the yaw during leveling
2238b34
to
6a2568f
Compare
{ | ||
// TODO: precision = 0.0002f is only required for the pitch90 test to pass |
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.
mystery solved!
|
||
if (continuing_conditions_passing && _control_status.flags.yaw_align) { | ||
|
||
if (mag_sample.reset || checkHaglYawResetReq()) { |
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.
so no more yaw reset at 1.5m if we're in mag heading fusion mode?
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.
To be honest I've mainly been thinking of mag type AUTO, but I can throw this into mag heading fusion as well to preserve dedicated mag type heading configuration.
_control_status.flags.mag_dec = (_control_status.flags.mag && (not_using_ne_aiding || mag_decl_user_selected)); | ||
|
||
if (_control_status.flags.mag) { | ||
aid_src.timestamp_sample = mag_sample.time_us; |
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.
Setting the timestamp here prevents the publication of the aid source if inactive. Didn't we want to publish it regardless of this?
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.
Yes I'd like to, but in this particular case most of it is computed and populated within fuseMag(). We should do a refactor later with these things in mind, this overlaps with other comments about aid_src_status usage.
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.
Reviewed again and tested in SITL, I think it's in a good shape now.
Thanks @bresch |
- split mag_3d into new standalone mag fusion and mag fusion allowed to update all states (full mag_3d) - new dedicated control logic for mag/mag_3d fusion and standalone mag heading fusion - if WMM available use for mag_I and mag_B init - mag states reset if external yaw reset (yaw estimator, GPS yaw, etc) - mag reset if declination changed (eliminate _mag_yaw_reset_req) - mag fusion (but not mag_hdg or mag_3d) can be active during gps_yaw or ev_yaw (if yaw aligned north) Co-authored-by: bresch <brescianimathieu@gmail.com>
This is built on standalone mag fusion. #20933
This ended up being a huge overhaul of ekf2 mag control logic, and needs a very thorough review of the full logic, both how it actually works and original intent.