Tutorial
Create a Plan
A plan is one YAML file in plans/ that describes everything a launch should
bring up: which commands run, in which packages’ containers, arranged in tmux
windows and panes. airfield project up <plan> turns it into a running
session; airfield project down <plan> tears it down.
Plans need tmux and tmuxinator on the host; airfield doctor checks for
both.
1. Write the plan
Create plans/navstack.yaml:
name: navstack
pre_window: export MAP=speedway
windows:
- name: main
layout: main-vertical
panes:
- package: camera_driver
cmd: ros2 run image_processor image_node
- package: base_driver
cmd: ros2 run motor_driver motor_node
- package: base_driver
cmd: ros2 run joystick joystick_node
- package: nav_stack
cmd: ros2 launch nav_stack navigation.launch.py
namemust match how you’ll invoke it (airfield project up navstack).pre_windowis executed in every pane before its command, which makes it the place for session-wide environment. A per-windowpre_windowis also supported.- Each window has a
name, an optional tmuxlayout(defaultmain-vertical), and a list ofpanes.
2. Choose pane forms
Panes come in three forms:
panes:
# 1. A package pane: cmd runs inside that package's container
- package: base_driver
cmd: ros2 run motor_driver motor_node
# 2. A plain host command
- htop
# 3. A bare shell pane (null), handy for debugging alongside the nodes
-
A package pane is rendered as
airfield package cmd <package> -- bash -lc "<cmd>", so the command executes
inside the container with ROS and the workspace already sourced. Shell
syntax like &&, pipes, and loops runs inside the container too. Because the
command is raw shell, it addresses the wrapped ROS packages directly
(ros2 run <ros_package> <executable>), not the Airfield package name.
The same package may appear in any number of panes: each pane gets its own container from the package’s single image.
3. Launch it
airfield project up navstack
This renders the plan to .airfield/navstack.tmuxinator.yml and starts the
tmux session. Useful variants:
airfield project up # list available plans
airfield project up navstack --inspect # print the generated config only
airfield project up navstack --no-launch # write the config without starting
airfield project up navstack --output custom.yml
The first pane that needs an unbuilt package triggers the in-container
colcon build (see the Overview for how first-run builds
and the shared workspace interact); later panes reuse the result.
4. Tear it down
airfield project down navstack
Killing the session signals each pane’s Airfield process, which stops its own
container, so a plain down leaves no orphans (the
Runtime & Environment page explains the teardown mechanics).
Running airfield project down
with no name tears down every running session that matches a plan. After a
hard crash (power loss, SIGKILL) where containers had no chance to stop:
airfield project down --prune
This force-removes all airfield-run-* containers on the host.
5. Sequential launches with liftoff
A plan may also carry a simple package list:
name: smoke-test
packages:
- base_driver
- nav_stack
airfield project liftoff smoke-test runs each package’s default run
command one after another, blocking until each exits. That suits smoke tests
and scripted checks rather than interactive development. (project up also
accepts this form and gives each package its own window.) For anything
interactive, prefer windows: panes with project up.