Module 3/5 · Weeks 7–9 · 27 h

Route and waypoint planning

UAT 304 UAS Mission Planning and Autonomous Flight

About 85 minDraft, awaiting reviewLast updated 28 September 2026

Lesson

By the end of this module you will be able to

  1. Order inspection points with the nearest-neighbour method and improve the order with 2-opt
  2. Split a route into sorties within the battery limit
  3. Set waypoint altitude and speed to suit the task
  4. Check the route against restricted areas and obstacles before upload

Prerequisites: UAT 304 Modules 1–2 · UAT 312 Module 1 (mission planning)

Why this matters

UAT 312 covered back-and-forth survey lanes for mapping. Another common kind of job is point inspection, such as checking poles, water tanks or several flood-risk points across an area. The order in which the points are visited sets the total distance, time and number of sorties. The drone knowledge base’s unit on survey flight planning links GSD, image overlap, flight lines and terrain, and its QGroundControl unit shows how to place waypoints and export a mission. The course case is a municipal operations centre using a multirotor to inspect its area. The numbers are hypothetical.

Ordering the inspection points

The problem “visit every point and return home by the shortest route” is the travelling salesman problem, which is hard to solve exactly when there are many points. In practice, heuristics are used. Nearest neighbour repeatedly chooses the closest unvisited point; it is fast but often leaves crossing lines. 2-opt (Croes, 1958) tries reversing a section of the route and keeps the change if the route gets shorter, repeating until no reversal helps.

Example 1 Ordering 10 inspection points

Coordinates are metres east and north of the take-off point H.

import math

pts = {"H": (0, 0), "P1": (420, 150), "P2": (900, -200), "P3": (1300, 400), "P4": (700, 800),
       "P5": (250, 1100), "P6": (-300, 900), "P7": (-600, 300), "P8": (-400, -500),
       "P9": (300, -700), "P10": (1100, -900)}

def dist(a, b):
    return math.dist(pts[a], pts[b])

def length(route):
    return sum(dist(route[i], route[i + 1]) for i in range(len(route) - 1))

left, route = [k for k in pts if k != "H"], ["H"]
while left:                                    # nearest neighbour
    nxt = min(left, key=lambda k: dist(route[-1], k))
    route.append(nxt)
    left.remove(nxt)
route.append("H")
print(f"nearest neighbour: {length(route):.0f} m  {'-'.join(route)}")

improved = True
while improved:                                # 2-opt
    improved = False
    for i in range(1, len(route) - 2):
        for j in range(i + 1, len(route) - 1):
            cand = route[:i] + route[i:j + 1][::-1] + route[j + 1:]
            if length(cand) < length(route) - 1e-9:
                route, improved = cand, True
print(f"after 2-opt:       {length(route):.0f} m  {'-'.join(route)}")
nearest neighbour: 8078 m  H-P1-P2-P3-P4-P5-P6-P7-P8-P9-P10-H
after 2-opt:       7916 m  H-P1-P2-P10-P3-P4-P5-P6-P7-P8-P9-H

2-opt moves P10 to follow P2, which is close to it, instead of leaving it as the last point with a long flight home. The total distance falls only slightly in this case, but with more or more scattered points the difference is usually larger. Neither method guarantees the best answer, but both are fast enough for field work.

A map of 10 inspection points around take-off point H: a grey dashed nearest-neighbour route ending with a flight home from P10, and a solid blue route after 2-opt that flies from P2 to P10 and then to P3
Figure 1 Nearest-neighbour route and the route after 2-opt

Splitting into sorties

One battery gives limited flight. When the route is too long, it must be split into sorties, each starting and ending at the take-off point. The maximum distance per sortie must already allow for the RTL and wind reserves covered in UAT 312.

Example 2 Splitting the route by distance per sortie

The drone can fly at most 3,500 m per sortie after reserves. Use the order from Example 1 and add points in order until the limit would be exceeded.

import math

pts = {"H": (0, 0), "P1": (420, 150), "P2": (900, -200), "P3": (1300, 400), "P4": (700, 800),
       "P5": (250, 1100), "P6": (-300, 900), "P7": (-600, 300), "P8": (-400, -500),
       "P9": (300, -700), "P10": (1100, -900)}
order = ["P1", "P2", "P10", "P3", "P4", "P5", "P6", "P7", "P8", "P9"]   # from Example 1
L_MAX = 3500                                   # m per sortie

def length(route):
    return sum(math.dist(pts[route[i]], pts[route[i + 1]]) for i in range(len(route) - 1))

sorties, cur = [], ["H"]
for p in order:
    if length(cur + [p, "H"]) <= L_MAX:
        cur.append(p)
    else:
        sorties.append(cur + ["H"])
        cur = ["H", p]
sorties.append(cur + ["H"])
for k, s in enumerate(sorties, 1):
    print(f"sortie {k}: {'-'.join(s):<20} {length(s):5.0f} m")
print(f"{len(sorties)} sorties, total {sum(length(s) for s in sorties):.0f} m")
sortie 1: H-P1-P2-P10-H         3189 m
sortie 2: H-P3-P4-H             3144 m
sortie 3: H-P5-P6-P7-H          3055 m
sortie 4: H-P8-P9-H             2130 m
4 sorties, total 11518 m

Splitting increases the total distance because the drone must return to the take-off point several times. This in-order split is simple but not optimal. To seriously reduce the number of sorties or the total distance, use vehicle routing methods, which consider the split and the order together.

The same map split into four coloured sorties: sortie 1 H P1 P2 P10, sortie 2 H P3 P4, sortie 3 H P5 P6 P7 and sortie 4 H P8 P9, each starting and ending at H
Figure 2 The route split into four sorties

Setting waypoints

  • Altitude must state whether it is relative to the take-off point, to sea level, or to the ground below the drone (terrain following). On sloping ground, altitude relative to take-off can bring the drone too close to the ground or obstacles
  • Speed in ArduPilot Copter 4.6 is set with WPNAV_SPEED in cm/s, but version 4.7 renames it WP_SPD in m/s, and it can be changed during a mission with the DO_CHANGE_SPEED command. Choose speed to suit the task: stills at an inspection point may need a hover, while flight between points uses an energy-efficient speed
  • Actions at a point, such as turning the camera, taking a photo or waiting, need time added to the flight-time estimate
  • Check before upload with a program as in UAT 301 Module 3: altitude, boundaries and the final command

Module lab

Lab: planning a point-inspection route on campus

  1. Choose 8–12 inspection points on campus, read their coordinates from a map and convert them to metres from the take-off point
  2. Order them with Example 1 and compare with an order the team chooses by eye
  3. Split into sorties with Example 2 using the training drone’s real range after reserves
  4. Plan the mission in QGroundControl, set altitude, speed and actions at each point, and save a .plan file
  5. Fly it in SITL and compare the real time and distance with the calculation

Common mistakes

Watch out

  • Ordering points by their numbers instead of by distance
  • Not keeping an energy reserve when splitting sorties
  • Using altitude relative to take-off on sloping ground
  • Forgetting the time spent taking photos at each point
  • Believing a heuristic always gives the best answer

Summary

  • Visiting every point by the shortest route is the travelling salesman problem; use nearest neighbour and improve with 2-opt
  • Long routes are split into sorties, each within the battery’s range after reserves
  • Set waypoint altitude, speed and actions to suit the task and terrain
  • Check the plan with a program before every upload

Check your understanding

  1. What is the distance from A (0,0) to B (300,400)?
  2. Route H-A-B-H is 2,000 m and H-B-A-H is 1,800 m. Which should be chosen?
  3. How does 2-opt improve a route?
  4. A route is 7,900 m and each sortie can fly 3,500 m. What is the minimum number of sorties (ignoring the extra return distance)?
  5. Why is altitude relative to take-off dangerous on sloping ground?
Answers
  1. m
  2. H-B-A-H, because it is shorter
  3. It reverses a section of the route and keeps the change if the route gets shorter, repeating until no reversal helps
  4. sorties, although in practice more are usually needed because every sortie must return to the take-off point
  5. The ground may rise along the way, so a drone holding altitude relative to take-off gets close to the ground or obstacles

Key formulas

Route length
Condition for each sortie

Key references

  1. Croes, G. A. (1958). A method for solving traveling-salesman problems. Operations Research, 6(6), 791–812. link
  2. QGroundControl. QGroundControl user guide. link
  3. QGroundControl Dev Team. Plan file format. QGroundControl developer guide. link
  4. ArduPilot Dev Team. Mission command list. ArduPilot Copter documentation. link
  5. ArduPilot Dev Team. Parameter list (Copter stable V4.6.3). ArduPilot Copter documentation. link
  6. ArduPilot Dev Team. Parameter list (Copter stable V4.7.1). ArduPilot Copter documentation. link

Further reading

Study the assigned knowledge units in advance, review media and take the module quiz

In class / field

Lab or field practice from worksheets with a safety checklist

Learning evidence: Checked worksheets and quiz results

Module quiz

This is a formative self-check, not a graded exam

Knowledge domain: Surveying, mapping and geoinformatics · Mission planning, flight and simulation