OpenDroneKit

ArduPilot .waypoints (QGC WPL 110) format

The .waypoints file is the plain-text MAVLink mission format that Mission Planner, QGroundControl and MAVProxy all read: a header line and one tab-separated row per mission item. Here are the twelve columns, the row-0 rule that catches people out, and a file OpenDroneKit wrote.

Updated 2026-10-02Exporter: mission/exporters.py · examples written at 0ae10e4

Example files written by OpenDroneKit

opendronekit-example-grid.waypoints27 waypoints · 7.5 KB
sha256 0cfa8186…a011
aukerman-grid.waypointsAukerman Park grid · 41.1 KB
sha256 a303ea29…ccf6

What is a .waypoints file?

A .waypoints file is a MAVLink mission saved as text. The first line is QGC WPL 110; every following line is one mission item with twelve tab-separated columns. Mission Planner’s Save WP File and Load WP File use it, and it carries any MAVLink command, so gimbal, camera and speed commands travel with the route.

In ArduPilot, mission sequence 0 is the vehicle’s home position, not the first mission item. Whatever a file puts in row 0 is overwritten with home when the mission is loaded.

The twelve columns

ColumnMeaning (MAVLink file format)What OpenDroneKit writes
1 · INDEXSequence number from 00 = home, then 1, 2, 3…
2 · CURRENT WP1 for the current item1 on row 0, else 0
3 · COORD FRAMEMAV_FRAME: 0 = global (AMSL), 3 = global relative to home, 2 = mission (no position)3 for positions (0 for AMSL plans), 2 for commands
4 · COMMANDMAV_CMD number16, 19, 20, 21, 22, 115, 178, 203, 205, 206 (table below)
5–8 · PARAM1–4Command parameters8 decimals; NaN written as 0
9 · PARAM5 / X / LATITUDELatitude, or param 5Latitude; for DO_DIGICAM_CONTROL the shutter command (1)
10 · PARAM6 / Y / LONGITUDELongitude, or param 6Longitude
11 · PARAM7 / Z / ALTITUDEAltitude, or param 7Altitude; for DO_MOUNT_CONTROL the mount mode (2)
12 · AUTOCONTINUE1 to continue automaticallyAlways 1

Example file

Written by OpenDroneKit’s exporter for a 90 x 60 m rectangle centred on 41.30420 N, 81.75200 W (Aukerman Park, Ohio): grid template, 55 m above take-off, 8 m/s, 27 waypoints. The first lines:

QGC WPL 110
0	1	0	16	0.00000000	0.00000000	0.00000000	0.00000000	41.30393020	-81.75253872	0.000000	1
1	0	3	22	0.00000000	0.00000000	0.00000000	0.00000000	41.30393020	-81.75253872	55.000000	1
2	0	2	178	1.00000000	8.00000000	-1.00000000	0.00000000	0.00000000	0.00000000	0.000000	1
3	0	2	205	-90.00000000	0.00000000	0.00000000	0.00000000	0.00000000	0.00000000	2.000000	1
4	0	3	16	0.00000000	0.00000000	0.00000000	0.00000000	41.30393020	-81.75253872	55.000000	1
5	0	2	203	0.00000000	0.00000000	0.00000000	0.00000000	1.00000000	0.00000000	0.000000	1
6	0	2	205	-90.00000000	0.00000000	0.00000000	0.00000000	0.00000000	0.00000000	2.000000	1
7	0	3	16	0.00000000	0.00000000	0.00000000	0.00000000	41.30393020	-81.75240404	55.000000	1
8	0	2	203	0.00000000	0.00000000	0.00000000	0.00000000	1.00000000	0.00000000	0.000000	1
9	0	2	205	-90.00000000	0.00000000	0.00000000	0.00000000	0.00000000	0.00000000	2.000000	1
10	0	3	16	0.00000000	0.00000000	0.00000000	0.00000000	41.30393020	-81.75226936	55.000000	1
11	0	2	203	0.00000000	0.00000000	0.00000000	0.00000000	1.00000000	0.00000000	0.000000	1
12	0	2	205	-90.00000000	0.00000000	0.00000000	0.00000000	0.00000000	0.00000000	2.000000	1
13	0	3	16	0.00000000	0.00000000	0.00000000	0.00000000	41.30393020	-81.75213468	55.000000	1
14	0	2	203	0.00000000	0.00000000	0.00000000	0.00000000	1.00000000	0.00000000	0.000000	1
15	0	2	205	-90.00000000	0.00000000	0.00000000	0.00000000	0.00000000	0.00000000	2.000000	1
16	0	3	16	0.00000000	0.00000000	0.00000000	0.00000000	41.30393020	-81.75200000	55.000000	1
17	0	2	203	0.00000000	0.00000000	0.00000000	0.00000000	1.00000000	0.00000000	0.000000	1
18	0	2	205	-90.00000000	0.00000000	0.00000000	0.00000000	0.00000000	0.00000000	2.000000	1
19	0	3	16	0.00000000	0.00000000	0.00000000	0.00000000	41.30393020	-81.75186532	55.000000	1
20	0	2	203	0.00000000	0.00000000	0.00000000	0.00000000	1.00000000	0.00000000	0.000000	1
21	0	2	205	-90.00000000	0.00000000	0.00000000	0.00000000	0.00000000	0.00000000	2.000000	1
22	0	3	16	0.00000000	0.00000000	0.00000000	0.00000000	41.30393020	-81.75173064	55.000000	1
23	0	2	203	0.00000000	0.00000000	0.00000000	0.00000000	1.00000000	0.00000000	0.000000	1

The full Aukerman Park files in the table above come from the run shown on the homepage: the public OpenDroneMap survey, 152 waypoints at 55 m, generated 2026-09-29. Every file’s SHA-256 is listed so a copy can be checked.

What OpenDroneKit writes

OpenDroneKit (export_qgc_wpl, development branch) writes a home row at index 0 and the take-off at index 1, then the same command stream as the .plan export: speed, gimbal, optional yaw, waypoint or timed hold, camera trigger, and return-to-launch. The example below loads, saves and reloads through pymavlink’s MAVWPLoader with all 85 items identical.

MAV_CMDNameUsed for
16NAV_WAYPOINTA viewpoint (home row too)
19NAV_LOITER_TIMEA viewpoint with a hold
20NAV_RETURN_TO_LAUNCHEnd of mission
21NAV_LANDEnd of mission when the plan lands in place
22NAV_TAKEOFFFirst item after home
115CONDITION_YAWLocked heading before a viewpoint
178DO_CHANGE_SPEEDPlanned speed
203DO_DIGICAM_CONTROLTake the photo
205DO_MOUNT_CONTROLGimbal pitch (superseded in MAVLink by the gimbal manager, still accepted)
206DO_SET_CAM_TRIGG_DISTDistance-triggered capture, on and off

Known issues

Checked against the format’s reference and the exporter code on 2026-10-02. Listed here rather than hidden, so you can correct a file before you fly it.

  • No defect was found in the development-branch exporter against the MAVLink file format. It uses DO_MOUNT_CONTROL for the gimbal, which MAVLink marks as superseded by the gimbal-manager commands but which ArduPilot still accepts. The public main branch has two real defects, listed below; simulator testing against ArduPilot found the first one after every mock-based test had passed.

Public main versus the development branch

The example files were written by the development branch (0ae10e4), which is ahead of the public main you get from a source install (1ef6351). On main:

  • Public main writes the takeoff as row 0. ArduPilot and Mission Planner reserve sequence 0 for home and overwrite it, so the takeoff is lost on load; the integration branch writes a home row 0 and the takeoff at row 1.
  • Public main emits no DO_CHANGE_SPEED item, so the planned speed never reaches the autopilot; the integration branch adds one after the takeoff.
  • Public main always writes altitudes relative to home; the integration branch writes absolute altitude (frame 0) for AMSL plans.

How do I import it into Mission Planner?

  1. Mission Planner: in the Plan screen, use Load WP File.
  2. QGroundControl: open the file from the Plan view’s file menu.
  3. Confirm that row 1 is the take-off and that gimbal and camera items are present, then write the mission.

Pitfalls

  • Row 0 is home. A file whose first row is the take-off loses it in ArduPilot.
  • Frame 3 altitudes are relative to home; frame 0 altitudes are above mean sea level. Mixing them in one file is legal and easy to get wrong.
  • Commands that carry no position (frame 2) still have twelve columns; their latitude/longitude slots hold command parameters.
  • ArduPilot acts on DO_MOUNT_CONTROL only with a gimbal enabled, and on DO_DIGICAM_CONTROL and DO_SET_CAM_TRIGG_DIST only with a camera enabled.

References

Other formats: QGC .plan · DJI WPML · Litchi CSV. Missions come from the mission templates; see mission planning.