MAVLINKGPS

Solving the "N" Value

Calculating Geoid Undulation on Android

To send valid MSL altitude to ArduPilot, we must solve for $N$ (Geoid Undulation) locally on the phone.

1. Legacy Approach: NMEA Parsing

Older Android devices expose raw NMEA sentences ($GPGGA) via OnNmeaMessageListener.

  • The Fix: The $GPGGA sentence contains the MSL altitude directly (calculated by the GNSS chip's firmware).
  • The Problem: Not all phones expose NMEA, and parsing strings at 10Hz is CPU intensive.

2. The GeographicLib Approach (EGM96)

We embed a compressed binary grid of the EGM96 (Earth Gravitational Model 1996) dataset within the app.

  • Input: Latitude, Longitude (from Android Location).
  • Process: Look up the N-value from the grid using bilinear interpolation.
  • Output: $N$ (in meters).
  • Calculation: Altitude_MAVLink = Location.getAltitude() - N

This guarantees consistent altitude regardless of the phone manufacturer's GNSS implementation.

3. Android 14: AltitudeConverter

API Level 34 introduced android.location.altitude.AltitudeConverter.

  • Feature: A native system class that adds MSL altitude to a Location object.
  • Mechanism: It presumably uses a system-level Geoid model (likely EGM2008 or similar) to perform the conversion efficiently.
  • Adoption: MAVLink GPS uses this API when available, falling back to our internal EGM96 grid for older devices.

Why Accuracy Matters

An error of 5 meters in X/Y is annoying. An error of 5 meters in Z (Altitude) causes a crash.
By ensuring the N-value is subtracted correctly before the data hits the wire, we ensure the drone's barometer and the GPS agree on where "Zero" is.

Source Code Reference