Vertical Datum used by C-RTK 2 GPS

I’m having an issue where I’m trying to have my UAV follow a target, in both X,Y and Z axes, but the GPS on the target and on the drone output altitudes with different datums.


  • UAV:
    • Pixhawk Cube Orange
    • CUAV C-RTK 2
  • Target:
    • Pixhawk Cube Orange
    • 2x CUAV C-RTK 9Ps

UAV and Target are linked by RFD900 radios, and share the same RTK corrections from a RTK base station (using C-RTK 2 on base station). Both UAV and Target operate with an RTK Fix. There are two 9Ps units on the target, to calculate the target’s heading, since the magnetometer is not reliable when the target is installed on a vehicle. Both CUAV GPS models use the U-blox F9P receiver.

Following in X-Y (North-East) works well, there is no issue there. However, there is a problem with altitude. I am forced to use the “relative altitude” following method (FOLL_ALT_TYPE parameter) and force reset the UAV’s and Target’s origin altitude almost every flight. I would ideally use the “absolute altitude” following method, but when I tried this, the drone would rise very high to reach the same altitude as the Target, yet the Target was at my feet.

Looking at a log, I started seeing my issue. On the following graph, the moment of the green vertical line indicates the moment of impact when the drone lands. The altitude of both Target and UAV is the same, but not in the graph. According to the logs of each Pixhawk, the Target is roughly 35 m above the drone.

After digging a little, I’ve learnt a few new things. There are different systems that represents the shape of the earth. EGM96 is a complex model representing the sea level as a smooth but
irregular shape (geoid). WGS84 is an ellipsoid which best fits the EGM96 geoid. “Undulation” is the height difference between both models at a specific lat/lon coordinate.

Using online calculators, I’ve found that at the location of the test on the graph, an ellipsoid (WGS84) elevation of 231 m is equivalent to a geoid (EGM96) altitude of 267 m, telling me that the Target’s Pixhawk is logging EGM96 altitude, while the UAV’s Pixhawk is logging WGS84 altitude.

One key main difference between both models of CUAV GPSs is that the 9Ps is serial (Pixhawk directly connected to the F9P’s UART port) and the C-RTK 2 is UAVCAN/DroneCAN. On the C-RTK 2, there is a STM32H743VIH6 microcontroller running the UAVCAN node and logging the F9P’s raw messages to an SD card, allowing for PPK after the flight is over.

From my understanding, depending if I’m using a serial connection to the F9P or UAVCAN, the code from AP_GPS_UBLOX.cpp or AP_GPS_UAVCAN.cpp will be executed. Both seem to consider both an MSL height (EGM96) and an ellipsoid height (WGS84) and calculate an undulation. Undulation is a value that is logged in the GPA structure.

Sure enough, by subtracting the target’s EGM96 logged altitude by the logged undulation, the altitude of the drone and Target match up at the green line on the graph. However, no undulation value is logged in the drone’s log, making me believe that have_undulation = false.

If I understand correctly, the GPS has to provide an MSL height and an ellipsoid height so that Ardupilot can calculate an undulation. I used the DroneCAN GUI to see what exactly the C-RTK 2 is sending to Ardupilot. : :

And sure enough, the ellipsoid and MSL heights are there, but they are the same. Maybe the reason why no undulation is calculated? (Note: this is at a different location than in my first graph, hence why the altitudes are different. At this new location, WGS84 (Ellipsoid) altitude = 181m and EGM96 (MSL) altitude = 209m) According to DroneCAN GUI’s webpage, a screenshot of the application shows different MSL and ellipsoid heights.

So, my questions are:

  • Does the fault lie in the UAVCAN node on the C-RTK 2? Firmware is installed by CUAV and I do not have access to rewrite the node.
  • Is there anyway for me to install my own UAVCAN node on the C-RTK 2? Or is there any open-source nodes available for the C-RTK 2?
  • Would a custom/open-source node disable the SD card writing function on the C-RTK 2? It is useful for me to log the raw GPS messages for doing PPK later. Or does the UAVCAN node on the C-RTK 2 not affect the SD card writing function?

In an effort to start answering my own question, I’ve found firmwares/binaries for the C-RTK 2 in the Ardupilot firmware repository. Are these firmware updates for the uavcan nodes? Or are these firmware updates for Ardupilot to be able to communicate with the node? If these files will update the node’s firmware, how do I know what the code does? Will it produce proper MSL and ellipsoid heights? Will it still save the F9P’s raw messages on the SD card?

I’m a bit lost and don’t know how to proceed.

Thanks in advance!

Hi @bobzwik ,
I am not expert, but try to understand. I plan to use same C-Rtk 2 for my project. So you use both C-Rtk 2 for UAV and Base station? What antenna do you use for the base station? Do you use mission planner system setup as in documentation? Can you share the screen shot of the MP displays showing how you inject signal from the base station? Do you follow all setup according to the Cuav docs.?
Hi @cuav_le pls. commennt on this issue.

Hi @ton999 ,
RTK works perfectly with the C-RTK 2. I use this GPS for both the base station and the UAV. For the base station I use the TOP106 antenna from Sparkfun. When the drone is motionless on the ground, there is only 4-8mm drift in the drone’s position. CUAV does not show how to use the C-RTK 2 as a base GPS, but by changing a parameter on the SD card of the C-RTK 2, it serves perfectly well as a base GPS, and I followed the Mission Planner instructions for RTK.

However, my issue is not about RTK, it is about the vertical datum outputted by the UAVCAN node of the C-RTK 2. The C-RTK 2 only outputs WGS84 (ellipsoid) altitude, when it should be outputting both WGS84 and EGM96 altitudes. This problem occurs whether or not I am using RTK. This makes it impossible to follow a target Pixhawk using a different GPS model, since Ardupilot uses EGM96 altitude.

Hi @bobzwik
Tks for your response… I have sent PM to Tina Lei of Cuav to respond to this issue. She told me that Cuav engineer is still analysing the issue .Hopely we get response in a few days.
I have simple question, how did you set up CUAV C-RTK 2 to be a Base station? You said the you change parameter in the sd card. Could pls. clarify what parameters did you change??
Second, how is communication between laptop and Base station? Did you use Usb cable? Or Wifi or bluetooth or what?

Hi @ton999 ,
Thanks for the info, I hope CUAV can enlighten us on my issue.

There is a .conf file on the C-RTK 2’s SD card. Here’s a description of the parameters on that file. By setting SYS_MODE=0, the GPS will act as a base GPS. Then you also have parameters to set the desired Survey-In duration and accuracy. But you can also set those once in Mission Planner on the RTK Inject tab. The GPS is connected with the provided USB cable to a laptop running Mission Planner. You connect to the GPS through the RTK Inject tab. It’s pretty easy (Method 1). Once Survey-In is completed, the GPS automatically starts sending corrections to Mission Planner, and once you connect Mission Planner to your drone, the drone automatically starts receiving the corrections.

If you have any further questions, please PM me. Let’s leave this thread free for the issue at hand.

Hello @cuav_le,
I was wondering if you had the time to check this issue? We have 3 C-RTK 2 we would like to fix, to output correct altitudes (both ellipsoid and msl elevation).


I haven’t done the work of adding the EGM96 height yet, get it to be supported in the next firmware update.

Thanks @cuav_le for the info. Do you have an estimated timeline for the next firmware update?