You should choose a unique ROS_DOMAIN_ID.
# ROS_DOMAIN_ID: The domain ID is used to segment the network in order to avoid interference
# between different groups of computers running ROS 2 on the same local area network.
# Machines with different domain IDs will not talk, nor interfere, with each other.
# see https://docs.ros.org/en/rolling/Concepts/About-Domain-ID.html
# Simply choose a domain ID between 0 and 101, inclusive.
export ROS_DOMAIN_ID=53
See About different ROS 2 DDS/RTPS vendors in the ROS 2 docs.
export RMW_IMPLEMENTATION="rmw_fastrtps_cpp"
Low-level DDS config: See dds.
Please refer to the 👉 Using VSCode and JetBrains IDEs (CLion, PyCharm) with ROS 👈.
Useful Bash aliases for your .bashrc
:
alias ws-clean='rm -rf build/ install/ log/ .env'
alias ws-clean-all='rm -rf build/ install/ log/ .env .vscode/ python.local.sh compile_commands.json'
alias g='source /opt/ros/galactic/setup.bash'
alias h='source /opt/ros/humble/setup.bash'
alias h='source /opt/ros/rolling/setup.bash'
# `s` as an alias for ROS 2 and ROS 1 compatible sourcing of setup.bash
s() {
if [[ -f install/setup.bash ]]; then
source install/setup.bash
return 0
fi
if [[ -f devel/setup.bash ]]; then
source devel/setup.bash
return 0
fi
echo "No setup.bash found!" 1>&2
return 1
}
# `sl` as an alias for ROS 2 and ROS 1 compatible sourcing of setup_local.bash
sl() {
if [[ -f install/setup_local.bash ]]; then
source install/setup_local.bash
return 0
fi
if [[ -f devel/setup_local.bash ]]; then
source devel/setup_local.bash
return 0
fi
echo "No setup_local.bash found!" 1>&2
return 1
}
ROS relies heavily on the environment variables. Sourcing the setup files of the workspaces change different environment variables which affect both build and runtime.
A lot of these environment variables are actually ordered list of paths (directories) with items separated using :
.
Order of the directories in which they are specified determines their priority during search (the order in which they
are examined, where the first dir specified is examined first).
Some of the most important env variables modified by ROS setup files include:
PATH
– affects where binaries are looked forLD_LIBRARY_PATH
(Linux),DYLD_LIBRARY_PATH
(macOS) – dynamic linker path which affects where the for the dynamic librariesPYTHONPATH
– affects where Python looks for modules (how imports are resolved)CMAKE_PREFIX_PATH
– affects where CMake looks for packages when resolving any dependenciesAMENT_PREFIX_PATH
COLCON_PREFIX_PATH
When sourcing a workspace, new paths get prepended to the current ones. That's how overlays work.
Most importantly, the environment variables that are set during a build affects the results and the resulting setup file. That's the reason why you always have to use separate terminal for building the workspace.
Always use at least two (clean) terminals.
One for building the workspace (where you source only the ROS 2 or different relevant underlay).
The other one(s) for sourcing the built workspace and running the nodes.
This way you can prevent polluting the environment (changing environment variables) of the build terminal by the built sourced workspace and prevent serious issues.
If build keeps failing (or even time to time), it might be good to clean all build artifacts and perform a clean build:
# clean build artifacts
rm -rf build/ install/ log/
# do a clean build (append any arguments you want)
colcon build
I recommend creating an alias for rm -rf build/ install/ log/
, see Aliases.
Instead of having to type long arguments over and over (such
as --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON --no-warn-unused-cli
), you can use
colcon mixin with
the default colcon mixin repository.
If you've never used colcon mixins before, you'll have to do an initial set up:
# 1. install colcon mixin plugin via apt
sudo apt install python3-colcon-mixin
# or via pip
python3 -m pip install -U colcon-mixin
# 2. add default mixins repository and download the mixins from it
# see https://github.com/colcon/colcon-mixin-repository/
colcon mixin add default https://raw.githubusercontent.com/colcon/colcon-mixin-repository/master/index.yaml
colcon mixin update default
Then, you can use for example the compile-commands
(which expands
to --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=ON --no-warn-unused-cli
) mixin like this:
colcon build --mixin compile-commands
Another useful set of mixins are debug
, rel-with-deb-info
, and release
, which are shortcuts
for --cmake-args -DCMAKE_BUILD_TYPE=Debug/RelWithDebInfo/Release
, respectively.
colcon can autocomplete packages' names for --packages-up-to
, --packages-select
, and similar in shell
(Bash and zsh). This is very helpful because it is hard to remember (and type correctly) the long package names. The
instructions for enabling it can be
found here.
Or you can copy and paste the following snippet into your ~/.bashrc
. Apart from enabling the autocompletion, it
configures few other useful things:
# see https://colcon.readthedocs.io/en/released/user/installation.html#enable-completion
if [[ -f /usr/share/colcon_argcomplete/hook/colcon-argcomplete.bash ]]; then
source /usr/share/colcon_argcomplete/hook/colcon-argcomplete.bash
fi
# see https://colcon.readthedocs.io/en/released/user/installation.html#quick-directory-changes
if [[ -f /usr/share/colcon_cd/function/colcon_cd.sh ]]; then
source /usr/share/colcon_cd/function/colcon_cd.sh
fi
# disable colcon desktop notifications by default (system-wide)
# see https://github.com/colcon/colcon-notification/issues/31
# also note:
# /usr/lib/python3/dist-packages/colcon_core/entry_point.py:152:
# UserWarning: The environment variable 'COLCON_EXTENSION_BLACKLIST' has been deprecated,
# use 'COLCON_EXTENSION_BLOCKLIST' instead
export COLCON_EXTENSION_BLOCKLIST="colcon_core.event_handler.desktop_notification"
colcon list | column -t
If you specify the --topological-order
option, the packages will be ordered topologically (breadth-first) by their
mutual dependency relationships. The first listed package will be the one that does not have any dependencies on the
packages in the current workspace, while the last one might be (but does not have to be) dependent on all packages in
the current workspace.
Additionally, you can also specify any package selection arguments (such as --packages-up-to
, --packages-select
) to
filter the output.
You can even visualize the dependency graph (which must be a DAG in order for the workspace to be buildable)
using colcon graph
.
👉 See the great article Using Multiple Workspaces in colcon docs.
Workspaces can be stacked on top of each other. Then, they are called overlays or underlays according to their respective mutual relationships.
Consider the following example:
workspace A
└── workspace B
└── workspace C
The workspace A is the bottom-most workspace. It's an underlay of workspaces B and C.
The workspace B is an overlay of the workspace A. All packages from workspace A are available in workspace B as well. If the workspace B has some packages with the same names as in workspace A, workspace B's packages take precedence and override those from workspace A. However, overriding the packages might not behave correctly in all situations.
Analogically, all packages from workspace A and workspace B are available in top-most workspace C.
The process of overlaying is done by sourcing the underlay's setup file when building its overlay. In our case, we would do the following to create the workspace C:
- Build terminal for workspace A in its root dir:
colcon build
- Build terminal for workspace B in its root dir:
source path/to/workspace_A/install/setup.bash colcon build
- Build terminal for workspace C in its root dir:
source path/to/workspace_B/install/setup.bash colcon build
- Run terminal for workspace C in its root dir:
source path/to/workspace_C/install/setup.bash # here we can access and run everything from all of the workspaces
TODO: I have some tips and tricks about the following topics I need to write up:
- DDS
- distributed discovery vs centralized registry
- QoS, when different settings are not compatible and how it affects the system (communication not working)
- ros2 CLI appears to not work → restarting ros2 daemon
- organizing and using external code and packages
- apt packages
- sources-only packages
- vcstool and related tools
- warn about colcon --symlink-install behavior
- pure Python packages
- files vs. directories
- added and removed files
- speeding up colcon build using
--packages-select
(or--packages-up-to
) - apt
apt list --installed
apt list --installed | grep -i ros
dpkg -L <package name>
sudo dpkg -r --force-depends ros-rolling-tracetools
- handling parameters at scale (using asterisk
*
in params files) - index.ros.org