Aerostack2

DocsConcepts

Architecture

The layers of Aerostack2, how a drone's software is organized, and how components are swapped.

Authored by
  • @alvgaona

Aerostack2 organizes the software of an aerial robot in layers, and each layer builds on the ones below it. A mission calls behaviors, behaviors rely on estimation and control, and those talk to the drone through its platform. A set of common interfaces runs through all of them.

  1. ApplicationsWhat you build
    Example projectsYour application
  2. Mission controlHow missions are written and monitored
  3. BehaviorsSkills the drone can perform
  4. Robotics functionsEstimation, control and mapping
  5. Platforms and sensorsThe link to the simulator or the real drone
Common interfaces
Messages, topic names and frames shared by every layer
Aerostack2 layers. Select an item to read more about it.

The layers

Common interfaces

The message types in as2_msgs, the standard topic names in as2_core and a shared set of TF frames let every component talk to every other one without knowing who's on the other side. A controller doesn't know whether its commands go to Gazebo or to a PX4 autopilot; it publishes on actuator_command/* and the platform takes them from there. Communication channels lists them.

Platforms and sensors

An aerial platform connects Aerostack2 to one kind of drone. It turns Aerostack2 commands into what the autopilot or simulator understands, and publishes the drone's state and sensor data back. Sensor drivers, such as the RealSense and USB camera interfaces, do the same for sensors that aren't part of the platform.

Changing from simulation to a real drone means changing the platform. Everything above it stays the same.

Robotics functions

The essential functions of an autonomous drone:

  • The state estimator works out where the drone is.
  • The motion controller turns where the drone should go into commands for the platform.
  • The map server builds occupancy maps, and geozones restrict where the drone may fly.

Behaviors

A behavior is a skill with a uniform interface, such as taking off, going to a point, following a path or pointing a gimbal. You start it with a goal, follow its progress, and can pause, resume, change or stop it. Behaviors hide how a task is done, so a mission asks for "land" the same way whether landing means descending slowly or centering on a visual marker.

Mission control

A mission decides which behaviors run and when. You can write it as a Python script with the Python API, as a behavior tree, or as a JSON mission for the mission interpreter. You can also fly by hand with keyboard teleoperation. User interfaces such as the alphanumeric viewer and RViz show what the drone is doing.

Applications

At the top are the applications built from all of the above. The example projects are complete applications for simulators and real drones, and a good starting point for your own.

One drone, one namespace

Each drone runs its own copy of the stack under a ROS 2 namespace, such as drone0. Every topic, service and action lives under that namespace, so the motion references of drone0 are published on /drone0/motion_reference/pose.

To fly several drones, start one stack per drone with a different namespace. Missions, behavior trees and user interfaces pick a drone by its namespace, which is why the Python API takes a drone_id:

drone = DroneInterface(drone_id="drone0")

Tools that watch several drones, like RViz and the alphanumeric viewer, usually run apart from the drones, on a ground station.

Swap components with plugins

Most components are a fixed ROS 2 node that loads its algorithm as a plugin. The node handles the standard interface; the plugin does the work. You choose the plugin in the configuration, without recompiling anything.

For example, the Quickstart project picks a ground-truth state estimator and a position-based take-off:

config/config.yaml
/**:
  state_estimator:
    ros__parameters:
      plugin_name: "ground_truth"
  TakeoffBehavior:
    ros__parameters:
      takeoff_plugin_name: "takeoff_plugin_position"

The motion controller works the same way and is chosen at launch, for example with plugin_name:=pid_speed_controller. The plugins page lists what's available.

Last updated on November 3, 2026

On this page

Last updated on November 3, 2026