@@ -336,7 +336,7 @@ bool Ekf::resetGlobalPosToExternalObservation(const double latitude, const doubl
336
336
const bool innov_rejected = (test_ratio > 1 .f );
337
337
338
338
if (!_control_status.flags .in_air || (eph > 0 .f && eph < 1 .f ) || innov_rejected) {
339
- // when on ground or accuracy chosen to be very low, we hard reset position
339
+ // When on ground or accuracy chosen to be very low, we hard reset position
340
340
// this allows the user to still send hard resets at any time
341
341
ECL_INFO (" reset position to external observation" );
342
342
_information_events.flags .reset_pos_to_ext_obs = true ;
@@ -346,13 +346,29 @@ bool Ekf::resetGlobalPosToExternalObservation(const double latitude, const doubl
346
346
347
347
} else {
348
348
ECL_INFO (" fuse external observation as position measurement" );
349
- fuseDirectStateMeasurement (innov (0 ), innov_var (0 ), obs_var, State::pos.idx + 0 );
350
- fuseDirectStateMeasurement (innov (1 ), innov_var (1 ), obs_var, State::pos.idx + 1 );
351
349
352
- // Use the reset counters to inform the controllers about a potential large position jump
353
- // TODO: compute the actual position change
354
- _state_reset_status.reset_count .posNE ++;
355
- _state_reset_status.posNE_change .zero ();
350
+ VectorState H;
351
+ VectorState K;
352
+
353
+ for (unsigned index = 0 ; index < 2 ; index++) {
354
+ K = VectorState (P.row (State::pos.idx + index)) / innov_var (index);
355
+ H (State::pos.idx + index) = 1 .f ;
356
+
357
+ // Artificially set the position Kalman gain to 1 in order to force a reset
358
+ // of the position through fusion. This allows the EKF to use part of the information
359
+ // to continue learning the correlated states (e.g.: velocity, heading, wind) while
360
+ // performing a position reset.
361
+ K (State::pos.idx + index) = 1 .f ;
362
+ measurementUpdate (K, H, obs_var, innov (index));
363
+ H (State::pos.idx + index) = 0 .f ; // Reset the whole vector to 0
364
+ }
365
+
366
+ // Use the reset counters to inform the controllers about a position jump
367
+ updateHorizontalPositionResetStatus (-innov);
368
+
369
+ // Reset the positon of the output predictor to avoid a transient that would disturb the
370
+ // position controller
371
+ _output_predictor.resetLatLonTo (_gpos.latitude_deg (), _gpos.longitude_deg ());
356
372
357
373
_time_last_hor_pos_fuse = _time_delayed_us;
358
374
_last_known_gpos.setLatLon (gpos_corrected);
0 commit comments