PX4-Autopilot icon indicating copy to clipboard operation
PX4-Autopilot copied to clipboard

New filter for distance sensor validation

Open haumarco opened this issue 1 year ago • 12 comments

Solved Problem

The distance sensor is being fused or used to reset the terrain state, even though its measurements do not accurately represent the distance to the ground due to obstructions caused by rain, snow, fog etc.

Solution

Now the distance sensor can be in 3 different states based on the lpf test ratio of a simple kalman filter: consistent, inconsistent and unknown. A terrain reset can only happen when the state is consistent. The sensor will be used for normal fusion in both consistent and inconsistent states. Together with the already existing fog detector, the robustness against sensor blockage/failure is increased.

new:

new-normal new-snow new-blocked

old:

old-normal old-snow old-blocked

haumarco avatar Dec 13 '24 13:12 haumarco

🔎 FLASH Analysis

px4_fmu-v5x [Total VM Diff: 1216 byte (0.06 %)]
    FILE SIZE        VM SIZE    
--------------  -------------- 
+0.1% +1.18Ki  +0.1% +1.18Ki    .text
   +27%    +552   +27%    +552    Ekf::controlRangeHaglFusion()
  +122%    +360  +122%    +360    RangeFinderConsistencyCheck::update()
  [NEW]    +116  [NEW]    +116    RangeFinderConsistencyCheck::evaluateState()
  +3.4%     +92  +3.4%     +92    EKF2::PublishAidSourceStatus()
  +2.7%     +92  +2.7%     +92    Ekf::Ekf()
  [NEW]     +68  [NEW]     +68    RangeFinderConsistencyCheck::init()
  +1.2%     +24  +1.2%     +24    Ekf::controlOpticalFlowFusion()
 -100.0%     +24 -100.0%     +24    [53 Others]
  +1.5%     +20  +1.5%     +20    ucdr_serialize_estimator_status_flags()
  +4.8%     +16  +4.8%     +16    EKF2::PublishInnovationTestRatios()
  +4.8%     +16  +4.8%     +16    EKF2::PublishInnovations()
  +1.6%     +16  +1.6%     +16    EKF2::PublishStatusFlags()
  +3.1%     +16  +3.1%     +16    Ekf::fuseGnssYaw()
  +3.5%     +12  +3.5%     +12    EKF2::PublishInnovationVariances()
  +1.2%     +12  +1.2%     +12    Ekf::controlGpsFusion()
  +0.2%     +12  +0.2%     +12    Ekf::controlMagFusion()
  -1.2%     -16  -1.2%     -16    Ekf::controlGnssHeightFusion()
  -5.6%     -16  -5.6%     -16    Ekf::updateRangeHagl()
  -7.7%     -24  -7.7%     -24    Ekf::stopGnssFusion()
  -2.9%     -44  -2.9%     -44    Ekf::controlBaroHeightFusion()
  [DEL]    -140  [DEL]    -140    RangeFinderConsistencyCheck::updateConsistency()
+0.1%      +8  +0.1%      +8    .ramfunc
  +0.3%      +4  +0.3%      +4    Ekf::controlGravityFusion()
  +1.2%      +4  +1.2%      +4    Ekf::measurementUpdate()
   +14%      +1   +14%      +1    __stm32_phywrite_veneer
 -12.5%      -1 -12.5%      -1    __nxsem_restore_baseprio_irq_veneer
+0.0%     +83  [ = ]       0    .debug_abbrev
+0.0%     +40  [ = ]       0    .debug_aranges
+0.0%    +184  [ = ]       0    .debug_frame
+0.0% +10.7Ki  [ = ]       0    .debug_info
+0.1% +6.26Ki  [ = ]       0    .debug_line
   +67%      +2  [ = ]       0    [Unmapped]
  +0.1% +6.26Ki  [ = ]       0    [section .debug_line]
+0.2% +5.79Ki  [ = ]       0    .debug_loclists
+0.3% +1.51Ki  [ = ]       0    .debug_rnglists
  [DEL]      -3  [ = ]       0    [Unmapped]
  +0.3% +1.51Ki  [ = ]       0    [section .debug_rnglists]
+0.0%    +624  [ = ]       0    .debug_str
-0.4%      -1  [ = ]       0    .shstrtab
+0.0%     +41  [ = ]       0    .strtab
  [NEW]     +52  [ = ]       0    RangeFinderConsistencyCheck::evaluateState()
  [NEW]     +43  [ = ]       0    RangeFinderConsistencyCheck::init()
  +2.1%      +1  [ = ]       0    RangeFinderConsistencyCheck::update()
  [DEL]     -55  [ = ]       0    RangeFinderConsistencyCheck::updateConsistency()
 -39.0%     -16  [ = ]       0    __nxsched_get_tcb_veneer
   +89%     +16  [ = ]       0    __wd_start_veneer
+0.0%     +64  [ = ]       0    .symtab
   +33%     +16  [ = ]       0    EKF2::PublishEventFlags()
 -50.0%     -16  [ = ]       0    EKF2::PublishGpsStatus()
  +100%     +16  [ = ]       0    EKF2::PublishInnovationTestRatios()
  +100%     +16  [ = ]       0    EKF2::PublishInnovationVariances()
  +100%     +16  [ = ]       0    EKF2::PublishInnovations()
 -50.0%     -16  [ = ]       0    EKF2::PublishWindEstimate()
   +50%     +16  [ = ]       0    EKF2::PublishYawEstimatorStatus()
 -33.3%     -16  [ = ]       0    EKF2::print_usage()
  +100%     +16  [ = ]       0    EKF2::updateParamsImpl()
 -66.7%     -32  [ = ]       0    Ekf::controlBetaFusion()
   +20%     +16  [ = ]       0    Ekf::controlEvPosFusion()
   +20%     +16  [ = ]       0    Ekf::controlRangeHaglFusion()
 -50.0%     -16  [ = ]       0    Ekf::get_ekf_lpos_accuracy()
   +33%     +16  [ = ]       0    Ekf::reset()
  +100%     +16  [ = ]       0    Ekf::resetAccelBias()
 -33.3%     -16  [ = ]       0    Ekf::resetGyroBias()
  +100%     +16  [ = ]       0    Ekf::resetWindCov()
 -25.0%     -16  [ = ]       0    Ekf::resetWindToExternalObservation()
 -25.0%     -16  [ = ]       0    Ekf::updateHorizontalDeadReckoningstatus()
 -66.7%     -32  [ = ]       0    Ekf::updateRangeHagl()
 -99.5%     +64  [ = ]       0    [15 Others]
-12.1% -1.19Ki  [ = ]       0    [Unmapped]
+0.1% +25.2Ki  +0.1% +1.19Ki    TOTAL

px4_fmu-v6x [Total VM Diff: 1192 byte (0.06 %)]
    FILE SIZE        VM SIZE    
--------------  -------------- 
+0.1% +1.16Ki  +0.1% +1.16Ki    .text
   +27%    +552   +27%    +552    Ekf::controlRangeHaglFusion()
  +122%    +360  +122%    +360    RangeFinderConsistencyCheck::update()
  [NEW]    +116  [NEW]    +116    RangeFinderConsistencyCheck::evaluateState()
  +3.4%     +92  +3.4%     +92    EKF2::PublishAidSourceStatus()
  +2.7%     +92  +2.7%     +92    Ekf::Ekf()
  [NEW]     +68  [NEW]     +68    RangeFinderConsistencyCheck::init()
  +1.2%     +24  +1.2%     +24    Ekf::controlOpticalFlowFusion()
  +1.5%     +20  +1.5%     +20    ucdr_serialize_estimator_status_flags()
  +4.8%     +16  +4.8%     +16    EKF2::PublishInnovationTestRatios()
  +4.8%     +16  +4.8%     +16    EKF2::PublishInnovations()
  +1.6%     +16  +1.6%     +16    EKF2::PublishStatusFlags()
  +3.1%     +16  +3.1%     +16    Ekf::fuseGnssYaw()
  +3.5%     +12  +3.5%     +12    EKF2::PublishInnovationVariances()
  +1.2%     +12  +1.2%     +12    Ekf::controlGpsFusion()
  +0.2%     +12  +0.2%     +12    Ekf::controlMagFusion()
 -100.0%      +8 -100.0%      +8    [53 Others]
  -1.2%     -16  -1.2%     -16    Ekf::controlGnssHeightFusion()
  -5.6%     -16  -5.6%     -16    Ekf::updateRangeHagl()
  -7.7%     -24  -7.7%     -24    Ekf::stopGnssFusion()
  -2.9%     -44  -2.9%     -44    Ekf::controlBaroHeightFusion()
  [DEL]    -140  [DEL]    -140    RangeFinderConsistencyCheck::updateConsistency()
+0.0%     +83  [ = ]       0    .debug_abbrev
+0.0%     +40  [ = ]       0    .debug_aranges
+0.0%    +184  [ = ]       0    .debug_frame
+0.0% +10.7Ki  [ = ]       0    .debug_info
+0.1% +6.26Ki  [ = ]       0    .debug_line
   +67%      +2  [ = ]       0    [Unmapped]
  +0.1% +6.26Ki  [ = ]       0    [section .debug_line]
+0.2% +5.86Ki  [ = ]       0    .debug_loclists
+0.3% +1.52Ki  [ = ]       0    .debug_rnglists
  [NEW]      +2  [ = ]       0    [Unmapped]
  +0.3% +1.51Ki  [ = ]       0    [section .debug_rnglists]
+0.0%    +631  [ = ]       0    .debug_str
-0.4%      -1  [ = ]       0    .shstrtab
+0.0%     +41  [ = ]       0    .strtab
  [NEW]     +52  [ = ]       0    RangeFinderConsistencyCheck::evaluateState()
  [NEW]     +43  [ = ]       0    RangeFinderConsistencyCheck::init()
  +2.1%      +1  [ = ]       0    RangeFinderConsistencyCheck::update()
  [DEL]     -55  [ = ]       0    RangeFinderConsistencyCheck::updateConsistency()
+0.0%     +64  [ = ]       0    .symtab
   +33%     +16  [ = ]       0    EKF2::PublishEventFlags()
 -50.0%     -16  [ = ]       0    EKF2::PublishGpsStatus()
  +100%     +16  [ = ]       0    EKF2::PublishInnovationTestRatios()
  +100%     +16  [ = ]       0    EKF2::PublishInnovationVariances()
  +100%     +16  [ = ]       0    EKF2::PublishInnovations()
 -50.0%     -16  [ = ]       0    EKF2::PublishWindEstimate()
   +50%     +16  [ = ]       0    EKF2::PublishYawEstimatorStatus()
 -33.3%     -16  [ = ]       0    EKF2::print_usage()
  +100%     +16  [ = ]       0    EKF2::updateParamsImpl()
 -66.7%     -32  [ = ]       0    Ekf::controlBetaFusion()
   +67%     +32  [ = ]       0    Ekf::controlEvHeightFusion()
   +20%     +16  [ = ]       0    Ekf::controlEvPosFusion()
   +20%     +16  [ = ]       0    Ekf::controlRangeHaglFusion()
 -50.0%     -16  [ = ]       0    Ekf::get_ekf_lpos_accuracy()
   +33%     +16  [ = ]       0    Ekf::reset()
  +100%     +16  [ = ]       0    Ekf::resetAccelBias()
 -33.3%     -16  [ = ]       0    Ekf::resetGyroBias()
  +100%     +16  [ = ]       0    Ekf::resetWindCov()
 -25.0%     -16  [ = ]       0    Ekf::resetWindToExternalObservation()
 -25.0%     -16  [ = ]       0    Ekf::updateHorizontalDeadReckoningstatus()
-16.6% -1.16Ki  [ = ]       0    [Unmapped]
+0.1% +25.3Ki  +0.1% +1.16Ki    TOTAL

Updated: 2025-08-26T13:16:21

github-actions[bot] avatar Dec 13 '24 13:12 github-actions[bot]

@dakejahl Does this help our height issues?

AlexKlimaj avatar Dec 27 '24 02:12 AlexKlimaj

This was a quick indoor flight in manual mode.

https://review.px4.io/plot_app?log=e3d3cf76-563d-4a23-9308-d37cbdcd34c3

image

Vs current main

https://review.px4.io/plot_app?log=6d902213-02ef-4ff8-8474-d341bfcc7bd9 image

AlexKlimaj avatar Dec 31 '24 21:12 AlexKlimaj

@AlexKlimaj Your vertical velocity estimate seems to be off quite a lot. Can you increase the bias noise on the acc so the bias will converge a bit quicker? The new filter uses the velocity estimate of the EKF to verify if the measurement is correct or not but when the EKF estimate is off and has a low uncertainty then it will discard the range measurements.

haumarco avatar Jan 10 '25 09:01 haumarco

Did a quick flight indoors with the Dexi (Flow, range, and baro. EKF2_HGT_REF=1). Lots of wandering up and down, have to fight with the throttle to keep the altitude in place https://review.px4.io/plot_app?log=e0095444-5705-490b-82e3-ea1efb4784e5 image

dakejahl avatar Apr 05 '25 04:04 dakejahl

@dakejahl if i replay your log with main it looks pretty much the same. seems like the classic indoor z/vz inconsistency based on suboptimal bias-uncertainties. Or do you have a log where this is not the issue?

haumarco avatar Apr 22 '25 11:04 haumarco

Okay let's take a step back and just focus on outdoor flights.

@haumarco Here's an outdoor flight. EKF replay is enabled in this log. This is based on main from today with this PR and https://github.com/PX4/PX4-Autopilot/pull/24751 merged into it.

Dexi airframe (quad)

  • No GPS
  • Distance sensor
  • Optical Flow
  • Barometer

Mostly default params except reduced EKF2_RNG_NOISE to 0.01. So the EKF2_HGT_REF is gps (so it fallbacks to baro), although throughout most of the flight "range aiding" was active, but doesn't appear to work very well since the altitude is fluctuating quite a bit (there was a little bit of wind). I kept the throttle around 0 for most of the flight, for simply testing altitude hold performance. MPC_HOLD_DZ is left at the default of 0.1.

https://review.px4.io/plot_app?log=ddbf2f12-14a9-4400-815c-2520cd347313 Screenshot from 2025-04-22 17-49-22

dakejahl avatar Apr 23 '25 02:04 dakejahl

This pull request has been mentioned on Discussion Forum for PX4, Pixhawk, QGroundControl, MAVSDK, MAVLink. There might be relevant details there:

https://discuss.px4.io/t/px4-sync-q-a-april-23-2025/45198/3

DronecodeBot avatar Apr 23 '25 03:04 DronecodeBot

We should get this in. I've got a branch that improves altitude hold with a rangefinder which is based off of this work.

dakejahl avatar May 05 '25 00:05 dakejahl

@haumarco can you share the log those screenshots in the description are from? Or any other logs you have of this PR with a distance sensor would be helpful

dakejahl avatar May 06 '25 05:05 dakejahl

@haumarco can you provide an update please? I am working on a branch based off of this and I'd like to know the status. Is this code being tested/flown in Auterions version of PX4? Do you have any flight logs you can share? Can we get this merged soon?

dakejahl avatar Jun 10 '25 21:06 dakejahl

@dakejahl It was tested on a VTOL and 2 different quadcopters. I will react to the review this week which will be followed by another set of testflights. I'll share the logs.

haumarco avatar Jun 11 '25 11:06 haumarco