Skip to content
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

Merged
merged 13 commits into from
Aug 4, 2023

Conversation

dagar
Copy link
Member

@dagar dagar commented Feb 28, 2023

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.

@dagar dagar changed the base branch from main to pr-ekf2_control_status_mag March 1, 2023 15:49
@dagar dagar force-pushed the pr-ekf2_mag_control_split_and_refactor branch from f1d5ab7 to f2c503a Compare March 1, 2023 15:50
@dagar dagar force-pushed the pr-ekf2_control_status_mag branch from 93e3c52 to fceda82 Compare March 6, 2023 16:00
@dagar dagar changed the base branch from pr-ekf2_control_status_mag to main March 9, 2023 15:36
@dagar dagar force-pushed the pr-ekf2_mag_control_split_and_refactor branch from f2c503a to b0559f3 Compare March 9, 2023 15:44
@dagar dagar requested a review from bresch March 13, 2023 14:01
@dagar dagar force-pushed the pr-ekf2_mag_control_split_and_refactor branch from b0559f3 to 3ea66d0 Compare March 13, 2023 14:01
@dagar
Copy link
Member Author

dagar commented May 30, 2023

#21305 could be reviewed and merged separately as an incremental piece.

@dagar dagar force-pushed the pr-ekf2_mag_control_split_and_refactor branch from 24f708e to d091c45 Compare July 24, 2023 16:06
@dagar dagar force-pushed the pr-ekf2_mag_control_split_and_refactor branch 2 times, most recently from be5f0ea to 3d88bea Compare July 25, 2023 20:52
@dagar dagar changed the title [WIP] ekf2: separate mag and mag heading control logic ekf2: separate mag and mag heading control logic Jul 25, 2023
@dagar dagar marked this pull request as ready for review July 25, 2023 21:13
@dagar dagar force-pushed the pr-ekf2_mag_control_split_and_refactor branch 5 times, most recently from ba1ef02 to c2c78ba Compare July 26, 2023 14:09
@dagar
Copy link
Member Author

dagar commented Jul 26, 2023

@dagar dagar force-pushed the pr-ekf2_mag_control_split_and_refactor branch 5 times, most recently from ff45e9a to a978a42 Compare July 26, 2023 16:54
src/modules/ekf2/EKF/estimator_interface.cpp Outdated Show resolved Hide resolved
src/modules/ekf2/EKF/gps_checks.cpp Outdated Show resolved Hide resolved
// 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)
Copy link
Member

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?

Copy link
Member Author

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).

Copy link
Member Author

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);
Copy link
Member

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

Copy link
Member Author

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.

Copy link
Member

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;
Copy link
Member

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?

Copy link
Member Author

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.

Copy link
Member

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?

Copy link
Member Author

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;
Copy link
Member

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);
Copy link
Member

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.

Copy link
Member Author

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.

https://github.com/PX4/PX4-Autopilot/blob/444e5d2d4abbb0adaabf1ad3cddaa2f9d2f9ee2b/src/modules/ekf2/EKF/gps_checks.cpp#L63C30-L63C53

It would probably be better to continue updating it periodically just in case anyone wants to fly around the world.

Copy link
Member

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)

Copy link
Member Author

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?).

src/modules/ekf2/EKF/mag_control.cpp Outdated Show resolved Hide resolved
src/modules/ekf2/EKF/mag_control.cpp Outdated Show resolved Hide resolved
src/modules/ekf2/EKF2.cpp Outdated Show resolved Hide resolved
@dagar dagar force-pushed the pr-ekf2_mag_control_split_and_refactor branch 2 times, most recently from 4e9e0d3 to b744440 Compare July 28, 2023 19:07
 - periodically check for WMM changes
 - cleanup mag declination limiting logic and remove mag_3d arbitrary 5s requirement
@dagar dagar force-pushed the pr-ekf2_mag_control_split_and_refactor branch from b744440 to 6eb09a8 Compare July 28, 2023 19:59
src/modules/ekf2/EKF/ekf.h Outdated Show resolved Hide resolved
// 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);
Copy link
Member

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.

src/modules/ekf2/EKF/mag_control.cpp Outdated Show resolved Hide resolved

if (_control_status.flags.mag) {
aid_src.timestamp_sample = mag_sample.time_us;
aid_src.fusion_enabled = true;
Copy link
Member

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?

case MagFuseType::AUTO:
selectMagAuto();
break;
if (!_control_status.flags.tilt_align && !_control_status.flags.yaw_align && starting_conditions_passing) {
Copy link
Member

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.

Copy link
Member Author

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.

src/modules/ekf2/EKF/mag_control.cpp Outdated Show resolved Hide resolved
src/modules/ekf2/EKF/mag_control.cpp Show resolved Hide resolved
@@ -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();
Copy link
Member

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)

@dagar
Copy link
Member Author

dagar commented Jul 31, 2023

@bresch without yaw reset during tilt alignment.

Screenshot from 2023-07-31 11-15-22

@dagar dagar force-pushed the pr-ekf2_mag_control_split_and_refactor branch from 6310d45 to 4f2f7e7 Compare July 31, 2023 16:29
@dagar dagar force-pushed the pr-ekf2_mag_control_split_and_refactor branch from 4f2f7e7 to a81e115 Compare July 31, 2023 16:39
@dagar
Copy link
Member Author

dagar commented Jul 31, 2023

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.

Screenshot from 2023-07-31 12-40-42

image

- avoid multiple re-initializations
- fuse zero heading innovation to stabilize the yaw during leveling
@bresch bresch force-pushed the pr-ekf2_mag_control_split_and_refactor branch from 2238b34 to 6a2568f Compare August 2, 2023 13:03
{
// TODO: precision = 0.0002f is only required for the pitch90 test to pass
Copy link
Member

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()) {
Copy link
Member

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?

Copy link
Member Author

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;
Copy link
Member

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?

Copy link
Member Author

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.

Copy link
Member

@bresch bresch left a 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.

@dagar
Copy link
Member Author

dagar commented Aug 4, 2023

Thanks @bresch

@dagar dagar merged commit d75bb62 into main Aug 4, 2023
84 of 86 checks passed
@dagar dagar deleted the pr-ekf2_mag_control_split_and_refactor branch August 4, 2023 14:39
antbre pushed a commit to BioMorphic-Intelligence-Lab/PX4-Autopilot that referenced this pull request Sep 14, 2023
 - 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: ✅ Done
Development

Successfully merging this pull request may close these issues.

None yet

2 participants