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
| Column | Meaning (MAVLink file format) | What OpenDroneKit writes |
|---|---|---|
| 1 · INDEX | Sequence number from 0 | 0 = home, then 1, 2, 3… |
| 2 · CURRENT WP | 1 for the current item | 1 on row 0, else 0 |
| 3 · COORD FRAME | MAV_FRAME: 0 = global (AMSL), 3 = global relative to home, 2 = mission (no position) | 3 for positions (0 for AMSL plans), 2 for commands |
| 4 · COMMAND | MAV_CMD number | 16, 19, 20, 21, 22, 115, 178, 203, 205, 206 (table below) |
| 5–8 · PARAM1–4 | Command parameters | 8 decimals; NaN written as 0 |
| 9 · PARAM5 / X / LATITUDE | Latitude, or param 5 | Latitude; for DO_DIGICAM_CONTROL the shutter command (1) |
| 10 · PARAM6 / Y / LONGITUDE | Longitude, or param 6 | Longitude |
| 11 · PARAM7 / Z / ALTITUDE | Altitude, or param 7 | Altitude; for DO_MOUNT_CONTROL the mount mode (2) |
| 12 · AUTOCONTINUE | 1 to continue automatically | Always 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 1The 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_CMD | Name | Used for |
|---|---|---|
| 16 | NAV_WAYPOINT | A viewpoint (home row too) |
| 19 | NAV_LOITER_TIME | A viewpoint with a hold |
| 20 | NAV_RETURN_TO_LAUNCH | End of mission |
| 21 | NAV_LAND | End of mission when the plan lands in place |
| 22 | NAV_TAKEOFF | First item after home |
| 115 | CONDITION_YAW | Locked heading before a viewpoint |
| 178 | DO_CHANGE_SPEED | Planned speed |
| 203 | DO_DIGICAM_CONTROL | Take the photo |
| 205 | DO_MOUNT_CONTROL | Gimbal pitch (superseded in MAVLink by the gimbal manager, still accepted) |
| 206 | DO_SET_CAM_TRIGG_DIST | Distance-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_CONTROLfor 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?
- Mission Planner: in the Plan screen, use Load WP File.
- QGroundControl: open the file from the Plan view’s file menu.
- 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
- MAVLink: file formats (QGC WPL)
- MAVLink: mission protocol (sequence 0 is home in ArduPilot)
- ArduPilot Copter: mission command list
- Mission Planner: planning a mission with waypoints
- OpenDroneKit exporter source (mission/exporters.py at 1ef6351)
Other formats: QGC .plan · DJI WPML · Litchi CSV. Missions come from the mission templates; see mission planning.