The runtime is split into three containers with one shared ROS 2 graph:
┌──────────────────────────────┐ /oak/left|right/image_raw
│ Brain container │─────────────────────────────┐
│ Brain + OAK-D camera + V2X │ │
└──────────────────────────────┘ ▼
┌─────────────────────────┐
│ Isaac Visual SLAM repo │
│ Visual SLAM + adapter │
└───────────┬─────────────┘
│
/visual_slam/tracking/odometry
▼
┌──────────────────────────────┐ sensor topics ┌──────────────────────┐
│ Vehicle/firmware ROS topics │─────────────────────►│ Localization │
│ encoder, car IMU, GPS │ │ local/global EKF, BEV │
└──────────────────────────────┘ │ map matching, planner │
└──────────────────────┘
Brain is the only container that opens the OAK-D device. Isaac ROS does not launch a camera and does not receive USB camera access; it consumes the already-published Brain topics. Localization also consumes ROS topics only.
All containers use --network host and the same ROS_DOMAIN_ID (default 0),
so no ROS bridge or port forwarding is required.
Install Docker on the host. For the Isaac container, install NVIDIA Container
Toolkit and the official NVIDIA Isaac ROS development image first. The default
local base image is isaac_ros_dev-aarch64:latest.
Then build all vehicle images once with Compose:
cd ~/BFMC_2027/Containers_UniPD_DriveOps
./build_all.shIf you are already inside Containers_UniPD_DriveOps, run ./build_all.sh.
This performs the expensive ROS dependency installation and colcon build
inside the images once. Starting the stack does not reinstall anything.
If the Isaac base image uses another name or distro, set these before building:
ISAAC_ROS_BASE_IMAGE=<local-isaac-image> \
ISAAC_ROS_DISTRO=<jazzy-or-humble> \
./build_all.shThe Brain and Localization images are ROS 2 Jazzy images. Keep their ROS distro aligned with the Isaac image where possible.
Start all three services in the background from one terminal:
cd ~/BFMC_2027/Containers_UniPD_DriveOps
./up.sh normalFor an unknown/random starting node:
./up.sh randomView all service output with ./logs.sh and stop the vehicle stack with
./down.sh.
The Compose file is for the physical vehicle. It uses host networking for the ROS 2 graph, privileged access for Brain's OAK-D/vehicle hardware, and the NVIDIA runtime only for Isaac Visual SLAM.
Sensor enable/disable remains code-controlled, as requested. Edit the constants in:
Localization_UniPD-DriveOps/src/bfmc_global_localization/launch/bfmc_localization.launch.py
Then rebuild the Localization image. The current defaults are wheel odometry, car IMU, external Isaac visual odometry, and GPS enabled. The camera/SLAM producer is not duplicated in Localization.
Isaac is configured for stereo tracking because the current Brain OAK node
publishes stereo images and calibration but does not currently publish
/oak/imu/data. To enable Isaac visual-inertial mode, edit:
Isaac_Visual_SLAM_UniPD-DriveOps/container/launch/bfmc_visual_slam.launch.py
Set tracking_mode to 1, add the OAK IMU remap, rebuild the Isaac image, and
run again.
Brain /oak/left/image_raw + /oak/right/image_raw
→ Isaac /visual_slam/tracking/odometry
→ Isaac adapter /visual_odom_planar
→ Localization local EKF /odometry/local
→ Localization global EKF /odometry/global
→ Brain fused pose input
Map matching consumes Brain’s /oak/rgb/image_raw and
/oak/rgb/camera_info; it does not start a second camera node.