DocsTutorials
A mission in Python
Write a mission with the Python API that reads the drone's state, flies to points, follows a path and always lands.
In this tutorial you write a mission with the Python API, one piece at a time. It reads the drone's state, flies to points and along a path, stops a flight halfway, and lands whatever happens.
Before you start
- You've done Fly by hand. You know how to start the drone and what its parts do.
- The drone is running. Start it from the Quickstart project folder and leave it running for the whole tutorial. The scripts go in the same folder.
./launch_as2.bashRun every script from a second terminal, with python3 <script>.py, or with
pixi run python3 <script>.py on Pixi.
Connect and read the state
DroneInterface connects to one drone by its namespace. Start with a script that only reads:
import rclpy
from as2_python_api.drone_interface import DroneInterface
rclpy.init()
drone = DroneInterface(drone_id="drone0")
print("Info:", drone.info)
print("Position:", drone.position)
print("Orientation:", drone.orientation)
print("Speed:", drone.speed)
drone.shutdown()
rclpy.shutdown()Info: {'connected': True, 'armed': False, 'offboard': False, 'state': 0, 'yaw_mode': 0, 'control_mode': 0}
Position: [0.0, 0.0, 0.0]
Orientation: [0.0, 0.0, 0.0]
Speed: [0.0, 0.0, 0.0]infocomes from the platform.stateis the platform status, where 0 is disarmed, 1 landed and 3 flying. The rest are listed under PlatformStatus.positionis[x, y, z]in metres andorientationis[roll, pitch, yaw]in radians, both in theearthframe.speedis[vx, vy, vz]in m/s.- The values update in the background while the script runs, so read them again whenever you need them.
Always end with shutdown(), which closes the connection to the drone.
Take off and land
Create my_mission.py. The flight goes in a function of its own, so the end of the script can land
the drone whatever happens inside it:
import time
import rclpy
from as2_python_api.drone_interface import DroneInterface
def fly(drone: DroneInterface) -> None:
"""Fly the mission. Raises an error if a behavior fails."""
if not drone.arm() or not drone.offboard():
raise RuntimeError("Couldn't arm or switch to offboard")
if not drone.takeoff(height=1.5, speed=0.5):
raise RuntimeError("Take off failed")
rclpy.init()
drone = DroneInterface(drone_id="drone0")
try:
fly(drone)
finally:
# Whatever happened, land and hand control back
drone.land(speed=0.5)
drone.manual()
drone.shutdown()
rclpy.shutdown()arm()starts the motors andoffboard()hands control of the drone to Aerostack2. Both returnTruewhen they succeed.takeoff()andland()each run a behavior and wait for it to end. They returnTrueif it succeeded.tryandfinallymake the script land even whenflyraises an error, like a behavior that fails.manual()then hands control back to the platform.
Run it. The drone climbs to 1.5 m, then lands.
Fly to points
Add two flights at the end of fly:
# Fly to a point, keeping the heading the drone has now
drone.go_to(2.0, 0.0, 1.5, speed=1.0)
# Fly to the next one facing where it's going
drone.go_to.go_to_point_path_facing([2.0, 2.0, 1.5], speed=1.0)go_to takes the point in metres in earth and a speed in m/s. By default the drone keeps its
heading. The helpers on drone.go_to choose another way to turn:
| Call | Heading |
|---|---|
go_to(x, y, z, speed) | Kept as it is |
go_to.go_to_point_path_facing(point, speed) | Turned toward the point |
go_to.go_to_point_with_yaw(point, speed, angle) | Turned to angle, in radians |
Follow a path
follow_path flies through a list of points without stopping at each one. Add it after the go-tos:
# Follow a path through several points without stopping at each one
path = [[0.0, 2.0, 2.0], [-2.0, 2.0, 2.0], [-2.0, 0.0, 1.5]]
drone.follow_path.follow_path_with_path_facing(path, speed=1.0)The drone faces along the path as it flies. follow_path_with_keep_yaw and follow_path_with_yaw
keep the heading or fix it instead.
Don't wait
Every behavior call waits until the behavior ends, unless you pass wait=False. Then it returns
right away, and the script can watch the drone and change its mind. Add a flight toward a point
10 m away, and stop it after three seconds:
# Start a long flight without waiting, and stop it after three seconds
drone.go_to(10.0, 0.0, 1.5, speed=1.0, wait=False)
start = time.time()
while time.time() - start < 3.0:
x, y, z = drone.position
print(f"Flying, at x={x:.2f} y={y:.2f} z={z:.2f}")
time.sleep(0.5)
drone.go_to.stop()
x, y, z = drone.position
print(f"Stopped at x={x:.2f} y={y:.2f} z={z:.2f}")
drone.go_to(0.0, 0.0, 1.5, speed=1.0)stop() ends the behavior, and the drone hovers where it is. The behavior also has pause(),
resume() and modify(), and its status tells you whether it's running. The last go-to brings
the drone back above the origin, and then finally lands it.
Run the whole mission
import time
import rclpy
from as2_python_api.drone_interface import DroneInterface
def fly(drone: DroneInterface) -> None:
"""Fly the mission. Raises an error if a behavior fails."""
if not drone.arm() or not drone.offboard():
raise RuntimeError("Couldn't arm or switch to offboard")
if not drone.takeoff(height=1.5, speed=0.5):
raise RuntimeError("Take off failed")
# Fly to a point, keeping the heading the drone has now
drone.go_to(2.0, 0.0, 1.5, speed=1.0)
# Fly to the next one facing where it's going
drone.go_to.go_to_point_path_facing([2.0, 2.0, 1.5], speed=1.0)
# Follow a path through several points without stopping at each one
path = [[0.0, 2.0, 2.0], [-2.0, 2.0, 2.0], [-2.0, 0.0, 1.5]]
drone.follow_path.follow_path_with_path_facing(path, speed=1.0)
# Start a long flight without waiting, and stop it after three seconds
drone.go_to(10.0, 0.0, 1.5, speed=1.0, wait=False)
start = time.time()
while time.time() - start < 3.0:
x, y, z = drone.position
print(f"Flying, at x={x:.2f} y={y:.2f} z={z:.2f}")
time.sleep(0.5)
drone.go_to.stop()
x, y, z = drone.position
print(f"Stopped at x={x:.2f} y={y:.2f} z={z:.2f}")
drone.go_to(0.0, 0.0, 1.5, speed=1.0)
rclpy.init()
drone = DroneInterface(drone_id="drone0")
try:
fly(drone)
finally:
# Whatever happened, land and hand control back
drone.land(speed=0.5)
drone.manual()
drone.shutdown()
rclpy.shutdown()The flight takes about half a minute. While the drone flies toward the far point, the script prints its position:
Flying, at x=-2.00 y=0.08 z=1.53
Flying, at x=-1.73 y=0.04 z=1.50
Flying, at x=-1.18 y=0.03 z=1.50
...
Stopped at x=1.48 y=0.01 z=1.50Next steps
Last updated on November 3, 2026