This folder provides a practical example of how to build one Docker image with ROS2 handlers and run a multi-sensor deployment with three containers:
- UMX IMU
- Livox Gen2 LiDAR
- RoboSense LiDAR
The layout is intended as a reference you can adapt, not a mandatory template.
- How to build a single image that includes all sensor handlers.
- How to run one container per sensor.
- How to compose deployment modes with multiple
docker composefiles. - How to define shared runtime values once and reuse them with YAML anchors.
build.py: helper to build the Docker image.Dockerfile: main installation logic.run_docker_container.sh: helper to run the example inautomaticormanualmode.docker_compose_base.yaml: base services, mounts, and common runtime environment.docker_compose_mode_automatic.yaml: automatic launch commands.docker_compose_mode_manual.yaml: manual mode (bashin each container).docker_compose_gui.yaml: optional GUI fragment, added only whenDISPLAYis available.
The deployment is created by combining compose files:
- Base compose:
docker_compose_base.yaml - Mode compose:
docker_compose_mode_automatic.yamlordocker_compose_mode_manual.yaml - Optional GUI compose:
docker_compose_gui.yaml
In this example, up to three compose files are chained (base + mode + optional gui) so users can experiment with different run styles.
run_docker_container.sh assembles these files automatically.
docker_compose_base.yaml defines shared values in x-common-environment:
NAMESPACE=multisensorROBOT_NAME=robotROS_DOMAIN_ID=11- ROS2 logging variables (
RCUTILS_*)
Edit the anchor if you want different common defaults.
The same compose file defines sensor-specific values directly in each service:
umx_srvc:UM_MODEL=7PARAMS_FILE=/tmp/params.yaml
livox_gen2_srvc:PARAMS_FILE=/tmp/params.yaml
robosense_srvc:CONFIG_FILE=/tmp/config.yaml
Those runtime values are coupled to the files mounted in each service (./*.yaml/./*.json -> /tmp/...).
Note on naming:
PARAMS_FILEis used for a YAML file that follows the ROS2 parameters convention (parameters declared underros__parameters).CONFIG_FILE(for example inrobosense_srvc) is used for a sensor vendor configuration YAML that does not follow ROS2 parameter-file conventions; it is simply a YAML file in the format required by that vendor driver.
Build image:
python example_multi_sensor/build.py ubuntu:24.04 jazzy multi_sensor:jazzyRun automatic mode:
cd example_multi_sensor
./run_docker_container.sh multi_sensor:jazzy automaticRun manual mode:
./run_docker_container.sh multi_sensor:jazzy manualIn manual mode, connect to each container and launch the sensor explicitly:
UMX:
docker compose exec -it umx_srvc bash
ros2 launch umx_bringup sensor.launch.pyLivox Gen2:
docker compose exec -it livox_gen2_srvc bash
ros2 launch livox_ros_driver2 sensor.launch.pyRoboSense:
docker compose exec -it robosense_srvc bash
ros2 launch rslidar_sdk sensor.launch.pyIf DISPLAY is present on the host, run_docker_container.sh adds docker_compose_gui.yaml and runs:
xhost +local:If DISPLAY is not set, the deployment runs headless.
Note on the scope of these example files:
run_docker_container.shand the split compose files (docker_compose_mode_automatic.yaml,docker_compose_mode_manual.yaml,docker_compose_gui.yaml) are intended for testing and experimentation.- In production, the typical approach is to define your own compose setup with your final sensor configuration, startup command, and GUI settings (if needed).
- In that case, you usually do not need
run_docker_container.shor a split byautomatic/manual/guimodes.