Receive Altitude that calculated by EKF with pymavlink

Hi.
In my project, I need to receive “The most accurate Altitude” from ground(perhaps in wiki it name is altitude above terrain or AGL) in real time. I choose pymavlink for my purpose and try to receive AHRS2, GLOBAL_POSITION_INT,DISTANCE_SENSOR(with my LiDAR Lite V3), VFR_HUD and etc, but those aren’t accurate and reliable for me.
after search in wiki and forums I saw the XKF1(XKF1_0 and XKF1_1) packet in .bin LOGS and PD in this packet. It is Altitude in NED coordinate and I think it is The most accurate Altitude and I think this is the EKF3 controller output data :slight_smile: (that exactly I want).
My question is, is there anyway to receive this altitude with pymavlink? I don’t see this packet on MAVLink Messages.
Regards.

1 Like

@ppoirier @stephendade @amilcarlucas @rmackay9

I think you need to further define what you mean by “most accurate”. There are a number of different methods of measuring the altitude, dependent on the sensors that you’re running. You can use the GPS, barometer, lidar to name a few.

VFR_HUD.altand AHRS2.alt will give you the absolute altitude (AMSL) of the vehicle, after EKF fusion. This is what Ardupilot uses internally.

1 Like

Hi Stephen.
Thanks for your reply.
I want the altitude that result of fusion all sensors data. I have GPS, Barometer and LiDAR.
I already use LiDAR data with “DISTANCE_SENSOR” in pymavlink for my purpose but it have offset and so noisy data!!! before that I used AHRS2 data but also this is so noisy and unreliable for me.
In matlab I use this code to comparison between LiDAR, XKF1 and AHSR2:

clc
close all

AHRS_ALT = AHR2(:,6);
OFFSET_AHRS = AHR2(1,6);
AHRS_ALT_C = AHRS_ALT - OFFSET_AHRS;

RNGFND = RFND_0(:,4);
OFFSET_RNGFND = RFND_0(1,4);
RNGFND_C = RNGFND - OFFSET_RNGFND;

XKF1_H0 = XKF1_0(:,13);
XKF1_H1 = XKF1_1(:,13);
XKF1_Ht = -(XKF1_H0 + XKF1_H1)/2;

figure
subplot(3,1,1)
plot(RNGFND_C)
title('LiDAR')
xlabel('t')
ylabel('Alt')

subplot(3,1,2)
plot(XKF1_Ht)
title('XKF1')
xlabel('t')
ylabel('ALT')

subplot(3,1,3)
plot(AHRS_ALT_C)
title('AHRS2')
xlabel('t')
ylabel('ALT')

And here is the output:

I don’t want noisy(such as LiDAR that is noisy and have offset!) and unreliable(such as AHRS2 that have so unreliable and it is AMSL) data. I want altitude data such as XKF1 output(PD). It has no offset and it is in meter and Above Ground Level that is so GREAT for my purpose.

@Leonardthall
Do you know about this?

Sorry @SAIKON I have no idea what you are asking here.

OK, so you want the EKF output

Note that the way the EKF works, it fuses the IMU with a single external sensor. There’s no “fusion of all sensors”. The EK3_SRC1_POSZ setting controls how Z-position data is fused with the IMU.

XKF1.PD is the vertical distance from origin (3d position when the vehicle was armed), not height above ground. For example, if the ground rises or falls (hill or valley) that will not be shown in the data.

XKF1.PD is only available in the on-board logs. For MAVLink streaming, I’d suggest GLOBAL_POSITION_INT.relative_alt instead.

I think what you want is LIDAR at a fast telemetry rate and then apply your own low pass filter rather than relying on ArduPilot to feed whatever custom use case you have.

Or perhaps LIDAR as your primary altitude source and then AHRS2 altitude.