The GPS_INPUT Message (#232)
Overview
The GPS_INPUT message (ID 232) is the mechanism used to inject high-precision Android location data into ArduPilot. Unlike standard GPS modules which communicate via NMEA over a serial wire, this MAVLink message allows your phone to act as a "Virtual GPS" sensor.
Packet Structure
The payload consists of 63 bytes. While it looks like a standard GPS packet, how you fill it determines if the drone flies stable or oscillates.
C Struct Definition
typedef struct __mavlink_gps_input_t {
uint64_t time_usec; /*< [us] Timestamp (UNIX Epoch or Boot time) */
uint32_t time_week_ms; /*< [ms] GPS time of week */
int32_t lat; /*< [degE7] Latitude */
int32_t lon; /*< [degE7] Longitude */
float alt; /*< [m] Altitude (MSL) */
float hdop; /*< [m] GPS HDOP */
float vdop; /*< [m] GPS VDOP */
float vn; /*< [m/s] GPS velocity in N direction */
float ve; /*< [m/s] GPS velocity in E direction */
float vd; /*< [m/s] GPS velocity in D direction */
float speed_accuracy; /*< [m/s] GPS speed accuracy */
float horiz_accuracy; /*< [m] GPS horizontal accuracy */
float vert_accuracy; /*< [m] GPS vertical accuracy */
uint16_t ignore_flags; /*< Bitmap of fields to ignore */
uint16_t time_week; /*< GPS week number */
uint8_t gps_id; /*< ID of the GPS for multiple GPS inputs */
uint8_t fix_type; /*< 0-1: no fix, 2: 2D fix, 3: 3D fix */
uint8_t satellites_visible;/*< Number of satellites visible */
uint16_t yaw; /*< [cdeg] Yaw of vehicle relative to True North */
} mavlink_gps_input_t;
Advanced Logic: Jitter & Latency
Android is not a Real-Time OS. A measurement taken at $T=0$ might not be sent until $T=200ms$.
- The "Rewind" Effect: If you provide a valid
time_weekandtime_week_ms, ArduPilot applies Jitter Correction. It uses these fields to calculate a "lag-compensated" timestamp. The EKF3 can then "rewind" its state history to fuse the measurement at the exact moment it was captured, rather than where the drone is "now." - Accuracy Weighting: The
horiz_accuracyfield directly scales the Observation Noise in the Kalman Filter. If your phone reports a 2.0m accuracy, ArduPilot trusts its own IMU more. If you report 0.5m, it will aggressively snap the drone to the phone's coordinates.
Handling GPS Time in Android
Android Location objects use Unix Epoch (ms since 1970). You must convert this to the GPS Epoch (ms since Jan 6, 1980) and account for leap seconds:
$$t_{gps} = t_{unix} - 315,964,800,000 + 18,000$$
(Note: 18,000ms is the leap second offset as of 2024)
Source Code Reference
- ArduPilot Handler:
libraries/AP_GPS/AP_GPS_MAV.cpp- SeeAP_GPS_MAV::handle_msgfor how the EKF ingests this data.