Tutorial
Create a New Package
Use an Airfield package for one buildable and runnable robotics component. Packages can live inside an Airfield project or stand alone.
1. Create a package inside a project
From an Airfield project root:
airfield package init nav_stack
This creates:
packages/nav_stack/
airfield.yaml
src/
README.md
.dockerignore
.gitignore
The package inherits the project’s ROS distribution unless you pass
--ros-distro.
2. Create a standalone package
For a package outside a project:
mkdir nav_stack
cd nav_stack
airfield package init .
Standalone packages resolve dependency manifests from their own
dependencies/<target-device>/ and dependencies/xplatform/ folders first,
then fall back to the shared packages repository.
When a local manifest should be shared with other packages, check and upstream
it with airfield package dependencies check . and
airfield package dependencies upstream .; see
Manage Dependencies.
3. Edit package metadata
Open airfield.yaml:
kind: package
name: nav_stack
dependencies:
- tqdm
source_path: src
ros_distro: jazzy
run:
list-packages: ros2 pkg list
Core fields:
namecontrols the package identifier and the Docker image name (airfield-pkg-<name>).dependencieslists what the container needs beyond the package’s ownpackage.xmlfiles, which Airfield reads on every build. An entry may carry a version constraint (tqdm>=1.0). It resolves to a dependency manifest such astqdm.yamlif one exists. Otherwise it can name a peer package underpackages/, whose source is then mounted and built from source alongside this one, which is how shared message packages are usually handled. Failing both, the name is translated the way rosdep translates it (nav2_msgstoros-<distro>-nav2-msgs,eigentolibeigen3-dev). See Manage Dependencies.source_pathis the source folder mounted into the runtime container. Usesrc(the default) when the folder holds one or more ROS packages, or.when the package root itself is the ROS package.ros_distroselects the ROS base image.rundefines named commands forairfield package run. Two names have extra meaning:defaultis whatairfield project runandliftoffexecute, andtestis whatproject run --testexecutes.
Optional fields:
base_imageoverrides the container base image (e.g.osrf/ros:jazzy-desktop); otherwise the project default or the ROS distro default applies.devicespasses host devices into the container (e.g./dev/ttyACM0); missing devices are skipped with a warning rather than failing the run.group_addadds supplementary groups (e.g."20"for dialout) so nodes can open serial ports and similar hardware.colcon_argsappends extra arguments to the automaticcolcon buildrun on first start (e.g.--cmake-args -DCMAKE_BUILD_TYPE=Release).default_workdirchanges the working directory forrun/shell/cmd. Relative paths resolve against the mounted source; absolute paths are used as-is.skip_dependencieslistspackage.xmlentries to leave out of the image, for an upstream package whosepackage.xmlnames something the image does not need.
4. Wrap one ROS package, or several
On the first container start, Airfield runs
colcon build --packages-up-to <name>, so the Airfield package’s name must
match a colcon package in its source tree. If no colcon package matches the
name, the automatic build silently does nothing, and the run command fails
later with missing executables. When the names cannot match (a config-only
tool package, for instance), that is fine: there is simply nothing to build.
- One ROS package (the common case): wrap it with
source_path: .and the names match automatically. - Several ROS packages in one container: put them side by side under
src/and add a small ROS metapackage named after the Airfield package that depends on the others. Building the metapackage then builds the whole bundle. The Overview shows this layout in detail.
5. Build the package
airfield package build nav_stack --target-device x86_64
Inside a standalone package root, use . for the current package:
airfield package build . --target-device x86_64
6. Run package workflows
List configured run commands:
airfield package run nav_stack
Run a configured command:
airfield package run nav_stack list-packages
Open an interactive package container:
airfield package shell nav_stack
Run an ad hoc command in the package container:
airfield package cmd nav_stack -- ros2 pkg list
Inside the package’s folder, the package name can be omitted; Airfield detects it from the working directory.
7. Wrap an existing ROS package
For a ROS package that already has package.xml:
airfield package init --path /path/to/existing_ros_package --ros-distro jazzy
Airfield reads the ROS package name from package.xml, writes airfield.yaml
with source_path: . and an empty dependencies: list, and leaves the ROS
source files untouched.
The list is empty on purpose. The package’s dependencies stay in
package.xml, which Airfield reads again on every build, so there is no
second copy to keep up to date. The command prints how each entry will be
installed:
- an entry with a manifest, or a peer package in the project, uses that;
- any other entry is translated with rosdep’s lookup table (
eigenbecomeslibeigen3-dev). A name the table does not have is tried under its conventional apt name, and the command lists those separately, since such a name may have no apt package. If one does not, add a manifest for it; see Manage Dependencies.