Aerostack2

DocsConcepts

Missions

The three ways to write an Aerostack2 mission, with the same flight written in each.

Authored by
  • @alvgaona

A mission decides which behaviors run and in what order. Aerostack2 offers three ways to write one, and all of them call the same behaviors underneath.

WayWritten asGood for
Python APIA Python scriptMost missions, anything with logic, loops or several drones
Behavior treeAn XML fileReactive missions that wait for events, and editing missions visually
Mission interpreterA JSON planMissions sent at run time, for example from a ground station

The same mission three ways

A drone takes off to 1 m, flies two sides of a square and lands.

mission.py
import rclpy
from as2_python_api.drone_interface import DroneInterface

rclpy.init()
drone = DroneInterface(drone_id="drone0", use_sim_time=True)

drone.arm()
drone.offboard()
drone.takeoff(height=1.0, speed=0.5)
drone.go_to(3.0, 0.0, 1.0, speed=1.0)
drone.go_to(3.0, 3.0, 1.0, speed=1.0)
drone.land(speed=0.5)

drone.shutdown()
rclpy.shutdown()
python3 mission.py

The Quickstart project has all three, ready to run against the simulator.

Python API

DroneInterface connects to one drone by its namespace and gives it a method for each behavior, plus arm, offboard, manual and the drone's state:

print(drone.position, drone.orientation, drone.speed)

Each behavior call waits until the behavior ends, unless you pass wait=False. Then the mission can do other work and pause, resume, modify or stop the behavior, as shown under Behaviors in a mission.

Take off, land, go to and follow path are loaded with the interface. Other behaviors are loaded as modules by name, and your own modules are found through the AS2_MODULES_PATH environment variable:

drone.load_module("follow_reference")
drone.follow_reference(...)

A script can create one DroneInterface per drone to fly several drones together.

Behavior trees

as2_behavior_tree runs a tree written for BehaviorTree.CPP 4. Each behavior is an action node, and the tree decides what runs next from what succeeds or fails. You can draw and edit trees in Groot, and set groot_logger:=true at launch to watch the tree run.

NodeKindWhat it does
Arm, Disarm, OffboardActionArm, disarm and switch to offboard.
TakeOff, Land, GoTo, FollowPathActionRun the motion behaviors.
GoToGps, SetOrigin, GetOrigin, GpsToCartesianActionFly to GPS coordinates and manage the GPS origin.
SendEvent, EchoActionPublish an event, or print a value for debugging.
IsFlyingConditionSucceeds while the drone is flying.
WaitForEventDecoratorWaits for a message on a topic before running its child.
WaitForAlertDecoratorWaits for an alert on a topic, usually alert_event, before running its child.

A tree starts as soon as it's launched. To hold it until you're ready, wrap the start in a WaitForEvent on a topic like start, and publish an empty string there when it's time to fly. WaitForAlert is also how a tree reacts to the alerts the platform doesn't act on yet, like landing on an emergency land request.

Mission interpreter

The mission interpreter runs a plan written in JSON. Each item names a behavior by its Python API module, like takeoff or go_to, and gives its arguments. The interpreter can pause, resume and stop the plan, jump to an item, and take a new or modified plan while it runs.

It also runs on its own with ros2 run as2_python_api mission_executor. It then takes plans on the mission_update topic and reports progress on mission_status. That's how a ground station sends missions to a drone while it flies.

Last updated on November 3, 2026

On this page

Last updated on November 3, 2026