DocsGetting Started
Quickstart
Fly a simulated drone with a short Python mission in about ten minutes.
In this guide you start a simulated drone and fly it around a square with a Python script. It uses the multirotor simulator, a lightweight simulator that doesn't need Gazebo, and the ready-made multirotor simulator project.
Before you start
- Aerostack2 is installed. Any method in Installation
works. Keep the environment sourced in each terminal you open, or use
pixi runas shown below. - tmux and tmuxinator are installed. The project uses them to start every component in its own terminal pane. The Docker images already include them.
sudo apt install tmux tmuxinatorFly your first mission
Get the project
git clone https://github.com/aerostack2/project_as2_multirotor_simulator.git
cd project_as2_multirotor_simulatorA project holds the configuration files, launch scripts and missions for one application. Every Aerostack2 example is organized this way.
Start the drone
./launch_as2.bashWith Pixi, the first run downloads and builds the environment for the project, so it takes a while.
This opens a tmux session called drone0 with one window per group of components:
| Window | What runs there |
|---|---|
platform | The multirotor simulator, acting as the drone's aerial platform |
basics_robotics_functions | The state estimator and the motion controller |
behaviors | Take off, land, go to, follow path, trajectory generation and gimbal behaviors |
mission_execution | The behavior tree runner, used by mission_behavior_tree.py |
mission_monitoring | The alphanumeric viewer, which shows the drone's state |
You land on mission_monitoring. Press Ctrl-b followed by a window number to look at the
others.
Open the ground station (optional)
In a second terminal, from the project folder:
./launch_ground_station.bashThis opens RViz, where you can watch the drone move.
Run the mission
In another terminal, from the project folder:
python3 mission.pyThe drone arms, takes off to 1 m and flies around a 4 × 4 m square twice. On the second lap it turns to face the direction it's flying. Then it lands. The script reports each step as it goes:
Running mission for drone drone0
Start mission
Arm
Arm success: True
Offboard
Offboard success: True
Take Off
Take Off success: True
Run mission
Go to with keep yaw [-2.0, 2.0, 1.0]
Go to success: True
...
Land
Land success: True
Manual
Manual success: True
Clean exitWhat the mission does
Without the printing and error checks, mission.py comes down to this:
import rclpy
from as2_python_api.drone_interface import DroneInterface
rclpy.init()
drone = DroneInterface(drone_id="drone0")
drone.arm()
drone.offboard()
drone.takeoff(height=1.0, speed=1.0)
square = [[-2.0, 2.0, 1.0], [-2.0, -2.0, 1.0], [2.0, -2.0, 1.0], [2.0, 2.0, 1.0]]
for point in square:
drone.go_to.go_to_point(point, speed=1.0)
drone.land(speed=0.5)
drone.manual()
drone.shutdown()
rclpy.shutdown()DroneInterfaceconnects to the drone running under thedrone0namespace.arm()starts the motors, andoffboard()hands control of the drone to Aerostack2.takeoff(),go_to.go_to_point()andland()each run a behavior. They wait until the behavior finishes and returnTrueif it succeeded.- Points are
[x, y, z]in metres, in the drone'searthframe. The drone starts at the origin. manual()hands control back to the platform, andshutdown()closes the connection.
Try changing the points or the speeds, then run the mission again. The drone stack doesn't need restarting between runs.
Next steps
The project includes more missions. Run them the same way as mission.py:
| Mission | What it shows |
|---|---|
mission_behavior_tree.py | Starts the behavior tree in trees/square.xml, which the drone loaded at launch, and flies a 3 × 3 m square |
mission_interpreter.py | A mission written as JSON and run by the mission interpreter |
mission_gps.py | Flying to GPS coordinates instead of local positions |
mission_swarm.py | Several drones at once. Start the drones with ./launch_as2.bash -m and the ground station with ./launch_ground_station.bash -m first |
Last updated on November 3, 2026