This repository was initialized by the create-ros-app template. This template is a everything-but-the-robot-code starter for ROS projects. It includes a Dockerfile for building ROS packages, a GitHub Actions workflow for linting and autoformatting, and many other goodies.
This documentation walks through the features of the template, and how to use them.
Make sure to follow the Post-Set-Up Guide after setting up the template before diving into the features below!
Here's a quick guide on the features of this template
-
Linting and autoformatting for python (ruff), C++ (clangformat), bash (shellcheck)
Relevant Scripts:
poetry run lint --help
You may need to run
poetry lock
andpoetry install
before running the above command. -
Easily build ROS apps in an out-of-the box containerized environment, with helper scripts under the
docker/
directory.Relevant Scripts:
# Run a profile specified under `launch-profiles/` docker/launch <profile> # Run and enter a new ROS container without executing anything docker/run # Enter a currently running ROS container to poke around docker/exec # Rebuild and restart the ROS nodes in the container, useful for fast development docker/reload-ros-nodes
More usage examples for the above scripts are documented at the top of the script files.
-
Create a new package: It's recommended to just start by developing with the example package that comes with the template after generation. Once you're familiar with development with the template and want to create a second package, you can follow the steps under Adding a New Package.
-
Add new dependencies:
- System dependencies: can be added under
docker/Dockerfile
, under theinstall-packages
section. - Python dependencies: can be added under
pkgs/<package_name>/pyproject.toml
. Runpoetry lock
after. - ROS dependencies: can be added under
pkgs/<package_name>/package.xml
. - ROS Git dependencies: If you need to add a ROS package that isn't available in the ROS package index, you can add it as a git dependency in the
docker/Dockerfile
under theAdd Git ROS2 Packages
section.
After any changes, the container will automatically re-build on the next launch.
- System dependencies: can be added under
-
Save persistent data: The
/robot/persistent
directory is mounted to.docker_volumes/ros-nodes/
on your local machine. Save data there to persist across container runs, and to view it in your file manager. -
Look at logs: Logs are available at
http://localhost/
after runningdocker/launch <profile>
. -
Create a new Launch Profile:
- Add a directory under
docker/launch-profiles/
- Add a
launching.py
file that launches your ROS nodes inside your new profile directory - Fill out the
launching.py
file with the nodes you want to launch. - The directory you created will be mounted under
/robot/launch-profile/
at launch. This is a great place to store configuration files, URDFs, and other specifics for your launch profile.
- Add a directory under
The /robot
directory is where your source code lives after building the container.
You can find your:
pkgs/
directorybuild/
,install/
from the colcon build
A directory pointing towards the launch profile chosen in docker/launch <launch profile>
is mounted under /robot/launch-profile/
.
For saving persistent data, /robot/persistent
is mounted to .docker_volumes/ros-nodes/
on your local machine.
This is a great place to save any serialized data, databases, etc. For static configuration,
it's recommended to use the launch-profile
directory.
In the Dockerfile
, there's a section for adding ROS packages that aren't available in
the ROS package index. These are added as git dependencies. The ros-git-deps/
directory is where these packages are cloned to, and built.
The packages directory contains all the packages that are used in the project. Each package is added in the Dockerfile
, and any new packages should be added there as well.
Each python package is made up of:
- A
resource
directory, which is a colcon requirement - A
package.xml
file, which is a colcon requirement - A
pyproject.toml
, because this project uses colcon-poetry-ros to install project dependencies. Most ROS python packages usesetup.py
, but by using this plugin, we can use a modern python tool called Poetry to manage dependencies. - A directory for code
- A directory for tests
As (arbitrary) best practice, the example node uses a test directory that follows the following structure
package_name/
├── package_name/
│ ├── __init__.py
│ ├── node.py
├── package_name_test/
│ ├── unit/
│ │ ├── test_node.py
│ ├── integration/
│ │ ├── test_node.py
Essentially, tests exist in a parallel directory to the package, and are split into unit
and integration
tests. The directories within unit
and integration
mirror the structure of the package itself, except that module names are prefixed with test_
.
The template will generate a message package for you with an ExampleAction
, ExampleService
, and ExampleMessage
. You can add more messages by adding them to the msg
directory and updating the CMakeLists.txt
and package.xml
files.
This can be used as a place for you to store your messages used just for this project. It follows standard ROS2 message package structure.
This project uses poetry for linting, and has some code for running linting and autoformatting under .github/lint
.
Run poetry install
then enter the shell via poetry shell
to get access to the linting tool.
This project is based on a template, upstream changes can be found on the template repository.
A tool called cruft
will alert you when there are upstream changes, and help you merge those in.
This directory contains scripts for building and running the Docker container. Look at the Fancy Features section for more information on how to use these scripts.
As for the structure:
docker/
├── grafana/ # Stores Grafana provisioning configuration
├── promtail/ # Stores Promtail provisioning configuration
├── utils/ # Contains utility scripts for building or running inside the Docker container
│ ├── environment/ # Scripts for use during Dockerfile build
│ ├── runtime/ # Helper for use when using the docker container
Feel free to edit as you like, but it's recommended to stick to editing within the sections
blocked off by #######
.
The Dockerfile will need to be edited in two places for each new ROS package you add:
- Copying in the
package.xml
- Copying in the
pyproject.toml
andpoetry.lock
There's also a location for adding new apt
dependencies. It's recommended that ROS package
dependencies are added through package.xml
if they are available.
This file holds environment variables that are used by the docker build and launch scripts.
Most variables can safely be edited.
This directory is automatically created the first time you run docker/launch
. It holds persistent state across runs for containers.
For example, if you enter your container via docker/run
and save a file under /robot/persistent/
, that file will be available the next time you run docker/run
. It will also (by default) exist in your local machine under .docker_volumes/ros-nodes/
.
The /robot/persistent
directory is intended for you, the developer, to use. So have at it!
The .gitattributes
file is used to configure common binary file formats that are used in
robots such that git uses Large File Storage (LFS) to store them. It also specified certain
line endings so that docker support works on windows.
It's recommended to start by developing with the example package that comes with the template after generation. Once you're familiar with development with the template and want to create a second package, you can follow the steps below:
- Create a new package directory under
pkgs/
- Add a
package.xml
file to the package directory, follow the standard ROS2 package.xml format - Create a pyproject.toml file. Follow the example in the
example_package
directory. - Create a
resource
directory in the package directory, with an empty file in it called{your package name}
- Create a directory for your code in the package directory, and it's recommended to create a
{your_package_name}_test
directory as well. - Add a few things to the Dockerfile:
- Under the
Add package.xml's of each package
section, copy thepackage.xml
file into the container - Under the
Add pyproject.toml's of each package
section, copy thepyproject.toml
file into the container
- Under the
You should be good to go! Next time you run docker/launch
, your new package will be built and available in the container.