Development Workflow
This page describes how to organize your code, build and test it, debug it in the two ROS domains, and contribute changes to the CPM Lab.
Where to Put Your Code
Your own planner or tool belongs in your own workspace on top of the CPM Lab installation. You do not need to change or rebuild the CPM Lab:
mkdir -p ~/planner_ws/src
# create or clone your packages in ~/planner_ws/src
cd ~/planner_ws
source /opt/ros/jazzy/setup.bash # Debian installation
# or: source <path-to-ros2-workspace>/install/setup.bash # source build
colcon build --symlink-install
source install/setup.bash
The order of the source commands matters: your workspace is an overlay on top of the CPM Lab, so its packages
are found first. Source the overlay in every terminal in which you start the lab or your planner. The control flow only
lists planners that are installed in the environment it was started in.
Changes to the CPM Lab itself, e.g. a bug fix in the vehicle controller, require a source build, see Building from Source. The workspace also builds and runs in Docker, from the terminal or in the VS Code dev container, see Developing in Docker.
Working with the CPM Lab Repository
The workspace repository ros2-workspace-lab contains the meta package cpm_lab and includes all other packages
as git submodules in src/:
Submodule |
Packages |
|---|---|
|
Bridge and control flow |
|
Message and service definitions |
|
Experiment recorder and |
|
Motion planners, including the example planner |
|
IPS and |
|
Map server, maps and Lanelet2 extensions |
|
Vehicle controller and simulation |
|
Control Center and RViz plugins |
Common commands:
# Clone with all submodules
git clone --recursive git@git.rwth-aachen.de:CPM/Project/Lab/ros2/workspaces/ros2-workspace-lab.git
# Update the workspace and check out the submodule commits it references
git pull
git submodule update --init --recursive
# Show the commit of every submodule
git submodule status
A submodule is a separate repository. A change usually touches one or more submodules and the workspace, and every
repository gets a branch of the same name from dev:
# 1. In the workspace: a feature branch from dev
git switch dev && git pull && git submodule update --init --recursive
git switch -c feature/my-change
# 2. In every submodule you change: the same branch from its dev
cd src/mid-level-controller
git switch dev && git pull
git switch -c feature/my-change
# edit, build, test, commit and push inside the submodule
git push -u origin feature/my-change
# 3. In the workspace: record the new submodule commit on the feature branch
cd ../..
git add src/mid-level-controller
git commit -m "Update mid-level-controller"
git push -u origin feature/my-change
After git submodule update the submodules are in detached HEAD state. Switch to a branch before you commit.
Submodule pointers are updated together with the feature branch of the workspace. Merge the merge requests in this order:
Merge the merge request of every submodule into its
dev.In the workspace feature branch, point each changed submodule to the merged commit on its
dev(git -C src/<submodule> switch dev && git -C src/<submodule> pull, thengit add src/<submodule>and commit).Merge the workspace feature branch into the workspace
dev. Its pipeline builds and tests exactly the submodule commits recorded in it.
The workspace dev therefore always references submodule commits that are on the dev branch of their
repository, never commits of feature branches. Do not update submodule pointers directly on dev. The release later
points the submodules to the released commits on main, see Releasing the CPM Lab.
Building
make build # whole workspace
colcon build --packages-select <package> # one package
colcon build --packages-up-to <package> # one package and its dependencies
make simulation # without the IPS, for computers without pylon
Testing
Most packages contain unit tests and the standard ROS2 linters (flake8, pep257, cpplint, uncrustify). Run them before you push, the same way the CI does:
make test PACKAGES="<package> ..." # build if needed, colcon test, print the results
make test # all packages, like the CI job run_gtest
Keep the logic of your code separate from the ROS interface, so it can be tested without running ROS. The example
planner shows this with path_utils.py, see Your First Motion Planner.
See Testing and CI for the CI jobs of every repository and how to reproduce them in the dev container.
Debugging
Mind the domain. A terminal only sees the nodes of its own ROS_DOMAIN_ID. Log messages of your planner are only
visible in domain 1, the vehicles in domain 21, see Understanding the Domain IDs.
export ROS_DOMAIN_ID=1
# Is my planner running and connected?
ros2 node list
ros2 topic info /planner/command --verbose
# Are the states arriving and how often?
ros2 topic hz /planner/vehicle_states
# What does my planner send?
ros2 topic echo /planner/command --once
# Graph of nodes and topics
rqt_graph
# Log output of all nodes
ros2 run rqt_console rqt_console
Useful techniques:
Start your planner as external planner in its own terminal while developing, so you see its output and can restart it without restarting the lab, see Your First Motion Planner.
Record your experiments and evaluate them with
cpm_eval, or replay them withros2 bag play, see Evaluation Metrics and Own Analyses.If Start never becomes available after deploying, follow the Deploy Checks.
QoS mismatches are a common reason for missing messages.
ros2 topic info <topic> --verboseshows the QoS of all publishers and subscribers.
Contributing
Changes to the CPM Lab are welcome. Please:
Follow the Style Guide.
Add or update tests for your change.
Add an entry to the
Forthcomingsection of theCHANGELOG.rstof every package you changed, see Releasing the CPM Lab.Push a branch and open a merge request into
devin the repository of the submodule and in the workspace, see above.mainonly receives releases.Do not change messages or services without need, see Changing Messages and Services.
Update the documentation in the same change, see Maintaining the Documentation.
All contributions are licensed under the MIT license.