OpenDroneKit

Litchi CSV mission format

A Litchi mission CSV is one header row and one row per waypoint, 46 columns wide. This page explains every column, shows a file OpenDroneKit wrote, and lists what goes wrong on import.

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

Example files written by OpenDroneKit

opendronekit-example-grid.csv27 waypoints · 4.4 KB
sha256 a4a1852d…7917
aukerman-grid_part1of2.csvAukerman Park grid · 14.6 KB
sha256 650281d0…f4f5
aukerman-grid_part2of2.csvAukerman Park grid · 8.1 KB
sha256 a2e04f37…9510

What is a Litchi CSV file?

A Litchi CSV is a plain comma-separated file that Litchi Mission Hub imports as a waypoint mission. Each row is one waypoint: position, altitude, heading, gimbal pitch, up to fifteen actions to perform there, and the speed to fly the next leg. Mission Hub imports CSV, KML and Litchi’s own mission files and exports CSV, so the format is the usual way to move a mission between Litchi and other planners.

There is no formal published specification. The column meanings below come from the third-party reference at litchiutilities.com, which matches the codes quoted from Litchi support on the PhantomPilots forum, and from Litchi’s own help pages for the limits.

Every column

ColumnMeaning (per the references)What OpenDroneKit writes
latitude, longitudeWGS84 decimal degrees8 decimals
altitude(m)Metres; reference set by altitudemodePlanned altitude, relative to take-off
heading(deg)Aircraft heading at the waypoint, 0 to 360Planned yaw
curvesize(m)Turn radius when flying curved turnsAlways 0.2
rotationdir0 = clockwise (default), 1 = counter-clockwiseAlways 0
gimbalmode0 = disabled, 1 = focus point of interest, 2 = interpolateAlways 2
gimbalpitchanglePitch when gimbalmode is 2; −90 (down) to about 20Planned gimbal pitch
actiontype1..15, actionparam1..15−1 none · 0 stay for (ms) · 1 take photo · 2 start recording · 3 stop recording · 4 rotate aircraft (deg) · 5 tilt camera (deg)1 with the hold in ms for a dwell, then 5,0 for a capture. Both codes are wrong; see known issues
altitudemode0 = above take-off, 1 = above ground0
speed(m/s)Leg speed; 0 = mission's global speed. Litchi's cruise limit is 15 m/sPlanned speed, capped at 15
poi_latitude, poi_longitude, poi_altitude(m), poi_altitudemodePoint of interest for that waypointAlways 0 (none)
photo_timeintervalTake a photo every N seconds on the legAlways 0
photo_distintervalTake a photo every N metres on the legSpacing when the plan captures by distance, else 0

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:

latitude,longitude,altitude(m),heading(deg),curvesize(m),rotationdir,gimbalmode,gimbalpitchangle,actiontype1,actionparam1,actiontype2,actionparam2,actiontype3,actionparam3,actiontype4,actionparam4,actiontype5,actionparam5,actiontype6,actionparam6,actiontype7,actionparam7,actiontype8,actionparam8,actiontype9,actionparam9,actiontype10,actionparam10,actiontype11,actionparam11,actiontype12,actionparam12,actiontype13,actionparam13,actiontype14,actionparam14,actiontype15,actionparam15,altitudemode,speed(m/s),poi_latitude,poi_longitude,poi_altitude(m),poi_altitudemode,photo_timeinterval,photo_distinterval
41.30393020,-81.75253872,55.00,90.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0
41.30393020,-81.75240404,55.00,90.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0
41.30393020,-81.75226936,55.00,90.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0
41.30393020,-81.75213468,55.00,90.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0
41.30393020,-81.75200000,55.00,90.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0
41.30393020,-81.75186532,55.00,90.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0
41.30393020,-81.75173064,55.00,90.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0
41.30393020,-81.75159596,55.00,90.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0
41.30393830,-81.75147744,55.00,90.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0
41.30415410,-81.75147744,55.00,270.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0
41.30415268,-81.75159596,55.00,270.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0
41.30415268,-81.75173064,55.00,270.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0
41.30415268,-81.75186532,55.00,270.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0
41.30415268,-81.75200000,55.00,270.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0
41.30415268,-81.75213468,55.00,270.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0
41.30415268,-81.75226936,55.00,270.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0
41.30415268,-81.75240404,55.00,270.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0
41.30415268,-81.75253872,55.00,270.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0
41.30437516,-81.75253872,55.00,90.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0
41.30437516,-81.75240404,55.00,90.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0
41.30437516,-81.75226936,55.00,90.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0
41.30437516,-81.75213468,55.00,90.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0
41.30437516,-81.75200000,55.00,90.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0
41.30437516,-81.75186532,55.00,90.0,0.2,0,2,-90.0,5,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,-1,0,0,8.00,0,0,0,0,0,0

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’s exporter (export_litchi_csv) writes one row per planned viewpoint with its gimbal pitch and heading, and the plan’s altitudes as above take-off (mode 0), because terrain following is already folded into them; mode 1 would make Litchi add its own terrain offset on top.

On the development branch, a plan longer than 99 waypoints is written as consecutive parts (mission_part1of2.csv, mission_part2of2.csv), each starting where the previous one ended. The Aukerman Park grid below (152 waypoints) is an example: 99 rows, then 53.

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.

  • Action codes are off by one. The exporter writes 5,0 for “take photo” and 1,<ms> for “stay for”. In Litchi’s numbering 1 is take photo, 5 is tilt camera and 0 is stay for. As written, every planned photo becomes “tilt camera to 0°” (level) and every hold becomes a photo. This is present on public main and on the development branch. Until it is fixed, edit the actions in Mission Hub after import, or replace 5,0 with 1,0 in the file.
  • The 99-waypoint split rests on an old limit. Litchi raised the per-mission limit to 10,000 waypoints in May 2022; aircraft whose firmware is limited to 99 are flown in chained blocks. Splitting is harmless, but no longer required on current aircraft.

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 every waypoint into one file; the development branch splits plans into parts of at most 99 waypoints, which aircraft whose firmware is limited to 99 waypoints need.
  • Public main writes altitudemode 1 (above ground), which makes Litchi add its own terrain offset to the planned altitudes; the integration branch writes 0 (relative to take-off).
  • Public main writes 5 m/s for every waypoint unless a per-point speed is set; the integration branch writes the plan's cruise speed, capped at 15 m/s.

How do I import it into Litchi Mission Hub?

  1. Open Litchi Mission Hub in a browser and sign in.
  2. Use the Missions menu’s import option and select the .csv file (one part at a time for a split plan).
  3. Check the first waypoint, the altitudes and the actions in the waypoint panel, then save the mission.
  4. Open the saved mission in the Litchi app on the device that flies the aircraft.

Pitfalls

  • Litchi requires 0.6 m to 1999 m (3D distance) between consecutive waypoints; very dense plans can violate the lower bound.
  • altitudemode 1 (above ground) uses Litchi’s own elevation data. Mixing it with altitudes already corrected for terrain double-counts the terrain.
  • Unused action slots must still be present as -1,0 pairs if any row uses actions; the column count must match the header on every row.
  • Litchi caps cruise speed at 15 m/s; higher values in the file are not flown.

References

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