Module 4/5 · Weeks 10–12 · 27 h

Automated flight in SITL and the field

UAT 304 UAS Mission Planning and Autonomous Flight

About 90 minDraft, awaiting reviewLast updated 28 September 2026

Lesson

By the end of this module you will be able to

  1. Progress automated missions from simulation to the field in stages
  2. Compare each leg's flight time with the plan and find the cause of large differences
  3. Explain each type of ArduPilot failsafe and configure it for the mission
  4. Test the response to abnormal events in SITL before real flight

Prerequisites: UAT 304 Modules 1–3 · UAT 206 Module 5 (control experiments in SITL)

Why this matters

An automated mission that passes in SITL is not guaranteed to pass in the field, where wind, GNSS signals and real links differ from the simulator. The drone knowledge base’s unit on a training plan from remote control to simulated missions practises step by step with observation criteria and log files, and its unit on the flight-skills path links simulator to field with pre- and post-flight checklists. This module focuses on two things: checking that the mission went to plan and testing that the system responds to abnormal events as intended.

Training progression

  1. SITL with the same mission as the real flight, testing every failsafe
  2. Real flight in open ground at lower height and range than the plan, with the pilot ready to take control
  3. The full real mission, with an observer
  4. Review the log of every sortie before flying the next

Comparing flight time with the plan

Example 1 Which leg took unusually long?

Sortie 1 from Module 3 flies at 8 m/s and hovers 60 seconds at each point to take images. Actual times are read from the log as the time to reach each waypoint (simulated values). The team investigates any leg more than 20% slower than planned.

import math

pts = {"H": (0, 0), "P1": (420, 150), "P2": (900, -200), "P10": (1100, -900)}
legs = [("H", "P1"), ("P1", "P2"), ("P2", "P10"), ("P10", "H")]
actual_s = [118, 138, 170, 245]                  # seconds per leg from the log, including the hold at the end point
SPEED, HOLD = 8.0, 60
for (a, b), act in zip(legs, actual_s):
    d = math.dist(pts[a], pts[b])
    plan = d / SPEED + (HOLD if b != "H" else 0)
    diff = (act - plan) / plan
    flag = "  <- investigate" if diff > 0.20 else ""
    print(f"{a:>3}->{b:<3} {d:5.0f} m  plan {plan:5.1f} s  actual {act:3d} s  {diff:+.0%}{flag}")
  H->P1    446 m  plan 115.7 s  actual 118 s  +2%
 P1->P2    594 m  plan 134.3 s  actual 138 s  +3%
 P2->P10   728 m  plan 151.0 s  actual 170 s  +13%
P10->H    1421 m  plan 177.7 s  actual 245 s  +38%  <- investigate

The last leg, from P10 back to take-off, is much slower than planned while the others are close to plan. Possible causes are a headwind, or RTL using a different speed from the mission speed. Check wind direction and speed in the log before concluding. This information makes the energy plan for the next sortie more accurate.

Paired bars for four legs: grey bars for planned time and blue bars for actual time; for the P10 to H leg the actual bar is pink and clearly taller than the plan
Figure 1 Leg times against the plan

ArduPilot failsafes

The ArduPilot documentation describes each failsafe separately:

  • RC loss FS_THR_ENABLE, for example 1 = RTL (land if there is no GPS) and 3 = land. To let an automated mission continue, use bit 0 of FS_OPTIONS (the old value 2 was removed from Copter 4.0)
  • GCS link loss FS_GCS_ENABLE acts when no signal is received for longer than FS_GCS_TIMEOUT (5 seconds by default), and bit 1 of FS_OPTIONS lets the mission continue
  • Battery BATT_FS_LOW_ACT and BATT_FS_CRT_ACT, for example 2 = RTL and 1 = land. They take no action if the vehicle is already in RTL or Land, and cannot be reset until reboot
  • EKF acts when two of the compass, position and velocity variances exceed FS_EKF_THRESH (0.8 by default) for 1 second; the default FS_EKF_ACTION is land

The documentation does not state a priority when several failsafes occur at once, so the team must test in SITL with the firmware version actually used. The following example is a teaching model using the rule “the safer action wins” to practise thinking ahead; it is not ArduPilot’s internal logic.

Example 2 Stepping through events with the configured values (teaching model)

params = {"FS_GCS_CONTINUE_AUTO": True, "BATT_FS_LOW_ACT": "RTL", "BATT_FS_CRT_ACT": "LAND", "FS_EKF_ACTION": "LAND"}
events = [(300, "GCS link lost"), (420, "GCS link restored"), (540, "battery low"), (600, "EKF variance high")]
RANK = {"AUTO": 0, "RTL": 1, "LAND": 2}         # higher is more conservative (model assumption)

mode = "AUTO"
for t, ev in events:
    want = mode
    if ev == "GCS link lost":
        want = "AUTO" if params["FS_GCS_CONTINUE_AUTO"] else "RTL"
    elif ev == "battery low":
        want = params["BATT_FS_LOW_ACT"]
    elif ev == "EKF variance high":
        want = params["FS_EKF_ACTION"]
    new = want if RANK[want] >= RANK[mode] else mode
    print(f"t={t:>3}s {ev:<20} requested {want:<4} -> mode {new}")
    mode = new
t=300s GCS link lost        requested AUTO -> mode AUTO
t=420s GCS link restored    requested AUTO -> mode AUTO
t=540s battery low          requested RTL  -> mode RTL
t=600s EKF variance high    requested LAND -> mode LAND

A short GCS link drop does not stop the mission, because it is set to continue. But when the battery is low the aircraft returns to launch, and when the EKF goes wrong on the way back it lands where it is, which could be in the middle of the flooded area. The team must know in advance that this outcome is possible and prepare a recovery team. Before the real job, test the same sequence of events in SITL to see whether the result matches expectations.

A state diagram with three boxes, AUTO, RTL and LAND: an arrow from AUTO to RTL labelled battery low, an arrow from RTL to LAND labelled EKF failsafe or battery critical, and a loop on AUTO labelled GCS link lost when set to continue
Figure 2 Mission states under failsafe events (teaching model)

Module lab

Lab: from SITL to the field

  1. Upload the mission from Module 3 in SITL, record the log and compare times with Example 1
  2. Test in SITL: cut the GCS link, turn off the RC transmitter, lower the simulated battery voltage and simulate GPS loss, recording each result
  3. Compare the results with the model in Example 2; if they differ, trust SITL and correct the team’s model
  4. Fly stage 2 of the progression for real under the instructor’s supervision
  5. Review the log before moving on to the full mission

Common mistakes

Watch out

  • Jumping straight from SITL to the full mission
  • Not testing failsafes in SITL with the values to be used for real
  • Guessing the failsafe order instead of testing it
  • Using parameter meanings from old firmware versions
  • Not reviewing the log before the next sortie

Summary

  • Progress from SITL to limited field flight and only then to the full mission
  • Compare each leg’s time with the plan to find anomalies and refine the energy plan
  • ArduPilot failsafes are separate by type, each with a configurable action, and the documentation does not state an order when they occur together
  • Always test the sequence of events in SITL before the real job

Check your understanding

  1. A leg of 800 m at 8 m/s with a 60-second hover has what planned time?
  2. Plan 100 s, actual 130 s. What is the relative difference?
  3. In current Copter versions, what must be set for the mission to continue when RC is lost?
  4. Does the battery failsafe act if the aircraft is already in RTL?
  5. Why test the failsafe sequence in SITL?
Answers
  1. s
  2. Bit 0 of FS_OPTIONS
  3. No
  4. The documentation does not state the order when several events occur together, and the result depends on the firmware version and settings

Key formulas

Planned leg time
Relative difference

Key references

  1. ArduPilot Dev Team. SITL simulator (software in the loop). link
  2. ArduPilot Dev Team. Radio failsafe. ArduPilot Copter documentation. link
  3. ArduPilot Dev Team. Battery failsafe. ArduPilot Copter documentation. link
  4. ArduPilot Dev Team. GCS failsafe. ArduPilot Copter documentation. link
  5. ArduPilot Dev Team. EKF failsafe. ArduPilot Copter documentation. link
  6. ArduPilot Dev Team. Parameter list (Copter stable V4.6.3). ArduPilot Copter documentation. link
  7. ArduPilot Dev Team. Onboard message log messages. 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: Mission planning, flight and simulation · Control, autopilot and navigation · Law, safety and risk