Fly a manoeuvre as one step program
Flown one wait_until per step, a manoeuvre costs a round trip per step, and at speedup N each round trip is N times its length in sim seconds. fly_steps takes the round trips out: each step applies its actions in the tick it starts, waits on one condition, and the next step starts in the tick that one settled.
Arm, then send the program
Section titled “Arm, then send the program”A program cannot arm or upload a mission, because both need round trips with retries. Arm with the arm tool first:
arm(session_id, mode="QLOITER")
fly_steps(session_id, steps=[ {"label": "climb", "rc": {3: 2000}, "until": "altitude", "value": 5}, {"label": "hover", "rc": {3: 1500}, "until": "sim_time", "value": 20, "relative": True}, {"label": "land", "mode": "QLAND", "until": "disarmed", "timeout_s": 120},])The result, from the stock quadplane in a steady 6 m/s wind, snapshots trimmed:
{ "status": "done", "current": null, "error": null, "steps": [ { "index": 0, "label": "climb", "reason": "met", "t_start_s": 50.723, "t_end_s": 54.072, "snapshot": { "height_m": 5.01, "mode": "QLOITER" } }, { "index": 1, "label": "hover", "reason": "met", "t_start_s": 54.072, "t_end_s": 74.121, "snapshot": { "height_m": 7.33, "mode": "QLOITER" } }, { "index": 2, "label": "land", "reason": "met", "t_start_s": 74.121, "t_end_s": 94.922, "snapshot": { "height_m": 0.0, "mode": "QLAND", "armed": false } } ]}Each step’s t_start_s is the previous step’s t_end_s to the millisecond: no gap, no matter how slowly the caller reads. The hover’s relative: true counts from the tick the climb ended, so it is exactly 20 sim seconds long.
Write steps that do what you mean
Section titled “Write steps that do what you mean”- Validate first, fly second. Every step is checked before anything runs: mode names against the vehicle’s mode table, channels, PWM, values, the speedup range. One bad step rejects the program with its index and
nothing was run. - A step without
untilends in the tick its actions apply. Use it to set several things at once, then wait in the next step. - Modes are not confirmed. A step’s
modeis sent once. If the rest of the program depends on it, make the next step{"until": "mode", "value": "QLAND"}. - Timeouts default to 60 sim seconds, or the wait plus 60 for
timeand relativesim_time. A landing usually needs more; settimeout_s. on_timeout: "continue"turns a timeout into a recorded result instead of a failure, for a step you only want to bound.windis an action too.{"wind": {"speed_mps": 8, "gusts": "dryden", "seed": 3}}starts a gust front as a step begins;{"wind": {"speed_mps": 0}}calms it.
The full field list is on Step, wind and mission fields.
Follow a long program
Section titled “Follow a long program”fly_steps returns within about 85 s. A longer program keeps flying in the server, and the call comes back with status: "running", the steps settled so far and the index of the current one:
steps_status(session_id) # waits up to about 85 s for the program to endsteps_status(session_id, wait=False) # answers at onceLoop on steps_status until status is done, failed or aborted. On a session opened with idle_speedup, a running program keeps the sim at full speed whether or not a call is waiting on it, and the idle speed applies once it ends.
failed means a step timed out with on_timeout: "stop" or SITL died; error says which, and the last step result carries the snapshot from that tick.
Stop it
Section titled “Stop it”abort_steps(session_id)The program stops after the current tick. RC stays as the last step left it, so a climbing vehicle keeps climbing. Set the throttle or a mode next:
abort_steps(session_id)set_mode(session_id, "QLAND")