Bug with EK2_RNG_USE_HGT parameter and sonar


I’ve played around with a sonar and have encountered what seems like a software issue.
When the EK2_RNG_USE_HGT parameter is different than 0, the drone tries to use the sonar even though RNGFND_TYPE for sonar 1 and 2 is equal to 0 (i.e. None).
This leads of course to a drone that isn’t able to fly and maintain its altitude in Loiter mode (and probably other modes that use altitude).

I’ve looked into the source code and and don’t see where this behaviour is coming from.
In the function selectHeightForFusion() (in AP_NavEKF2_PosVelFusion.cpp ) the code is as follow :

if (((frontend->_useRngSwHgt > 0) || (frontend->_altSource == 1)) && (imuSampleTime_ms - rngValidMeaTime_ms < 500)) {
} else if ((frontend->_altSource == 2) && ((imuSampleTime_ms - lastTimeGpsReceived_ms) < 500) && validOrigin && gpsAccuracyGood) {
activeHgtSource = HGT_SOURCE_GPS;
} else if ((frontend->_altSource == 3) && validOrigin && rngBcnGoodToAlign) {
activeHgtSource = HGT_SOURCE_BCN;
} else {
activeHgtSource = HGT_SOURCE_BARO;

Since my primary alt source is set to 0, and I have no sonars connected I would suspect the drone to ignore the 3 first “if” statements and use the BARO but this does not seem the case.

Am I doing something wrong ? If not, it might be interesting to correct this issue.

I’ve attached the logs of my last flight. The first half is when EK2_RNG_USE_HGT = -1 and the second half is with EK2_RNG_USE_HGT = 60. In red is the altitude as estimated by the EKF and in green is the altitude measured by the baro. In both cases there is no sonar connected and the RNGFND_TYPE are set to 0.

Thanks a lot for your help,


2017-06-23 18-39-39.bin (669.4 KB)

Hi, I am also learning the EKF.

I am sorry I can not find the two parameters(i.e. EK2_RNG_USE_HGT, RNGFND_TYPE ). The only information about EK2_RNG_USE_HGT in the source code of ardupilot is in


Could you list by URL where the two parameters are in the source code of ardupilot?(exclude the autotest, because I have not used the autotet yet).

How to list the URL of a parameter? Here is an example:


Hi, I was busy in weekend so sorry to not reply you untill now.

Although I do not figure out what the EK2_RNG_USE_HGT and RNGFND_TYPE mean because I have not seen the two parameters in sorce code ever, but I treat EK2_RNG_USE_HGT as _useRngSwHgt in source code and RNGFND_TYPE = 0 as RangeFinder_Type = RangeFinder_TYPE_NONE in source code.

Now look at your plot, at first half EK2_RNG_USE_HGT = -1 means do not use rangefinder, so the height source is barometer, at second half EK2_RNG_USE_HGT = 60 means that rangerfinder can be used even _altSource != 1, but here you said there is no sonars connected, so depend on

 if (((frontend->_useRngSwHgt > 0) || (frontend->_altSource == 1)) && (imuSampleTime_ms - rngValidMeaTime_ms < 500)) {

imuSampleTime_ms - rngValidMeaTime_ms will > 500, so the height source is still baro, so I donnt konw why at second half the EKF height does not follw the baro height

Hi luweikxy,

Thanks a lot for your answers !
I’m sorry about the parameters names. The names I wrote are the ones used in MissionPlanner, but you got it right in the source code.
You also pointed out in a way more understandable way what my problem is, so thanks a lot.

This is exactly the point I’m not understanding. It should go on using the baro even when _useRngSwHgt > 0 but it doesn’t.

Any idea why ?

Thanks again,



If you have no sonar connected, so the rngValidMeaTime_ms will always be 0. If you donnt know why, see here:


So even if you set _useRngSwHgt > 0, but no sonar, imuSampleTime_ms - rngValidMeaTime_ms will > 500, so the if condition will not be satisfied:

 if (((frontend->_useRngSwHgt > 0) || (frontend->_altSource == 1)) && (imuSampleTime_ms - rngValidMeaTime_ms < 500)) {

So baro is still the height source.

OK, I konw you have unerstood what I said above…

What makes me confused is that: where does sanar height data come from with no sonar connected?
It seems impossible…
So I have no idea about this…
I am sorry…


Thanks for your answer.

Exactly haha !
So that is why I am struggling right here…

Anyone else has any idea ?

Thanks a lot


The parameter notes in code and displayed on mission planner say:

“The range finder will be used as the primary height source when below a specified percentage of the sensor maximum as set by the RNGFND_MAX_CM parameter. Set to -1 to prevent range finder use.”

So I don’t know why you would be using this if you don’t have a range finder.

This overrides the selection specified by EK2_ALT_SOURCE when speed and height conditions are met. This enables the range finder to be used when hovering at slow speeds close to the ground when an accurate height control unaffected by baro disturbances is important.

When on the ground, many range finders do not return a value due to the ground being too close, so if the user has told the EKF to use range finder data, it will use an assumed value equal to the specified on-ground value when the vehicle is not flying.

I agree, there is a bug. In case for example your program crashes and no more altitude informations are sent, the sonar reading timeouts and goes to zero, yet the autopilot keeps using the data from the rangefinder (that is zero now) as primary altitude source. I’d expect that if a timeout was spotted, the rangefinder would be ignored.

In my program I added a failsafe that sets the EK2 parameter back to -1 before closing or in case I kill it with the keyboard, but still I think the autopilot should handle it better

maybe related to this? Follow terrain with range sensor Error Failsafe TERRAIN-1