Skip to content

Docker Setup

Container images

Container Image Purpose
iros2026_system zhangjicmu/ubuntu24_ros:system_simulation Challenge simulator + ROS 2
xiao_hei_ai_module Built from docker/Dockerfile Python VLM responder + ROS node
xiao_hei_perception Built from perception/Dockerfile YOLO-World + SAM 2.1 detection sidecar

Compose files

File Use case
docker/compose.yml Single unified stack. Profile-gated perception (only starts under --profile perception).
docker/compose_scene_gemini.yml The submission stack: sim + perception sidecar + scene_gemini node, Gemini env wired.
docker/run The entry point. Takes the responder as its first argument and selects the matching compose file, profile and prerequisites.

Driving the stack

The first argument picks the responder; the wrapper handles compose file / profile selection and prerequisite validation. No environment variables:

docker/run dummy        up -d   # system + ai_module
docker/run perception   up -d   # + perception sidecar (YOLO-World + SAM 2.1)
docker/run scene_gemini up -d   # submission stack: + Gemini (key from ./.env)

All other args pass through verbatim: docker/run logs -f ai_module, docker/run down, docker/run build ai_module.

Scene selection (any responder)

Setting XIAO_HEI_SCENE_DIR_HOST to an extracted scene directory makes the wrapper layer compose.scene.yml, which bind-mounts <dir>/environment/ over the sim's prebaked Unity environment. The same mechanism works for any responder — handy for testing a specific scene without docker cp.

SCENES=/path/to/CMU-VLN-Challenge-data/unity_env_models
unzip -oq $SCENES/arabic_room.zip -d $SCENES/                # one-time
export XIAO_HEI_SCENE_DIR_HOST=$SCENES/arabic_room
docker/run perception up -d              # sim loads arabic_room

Building

# Build the ai_module image (always installs the lightweight `perception`
# extra — httpx + pillow + pycocotools — so the same image serves both
# responders).
docker/run build ai_module

The Dockerfile extends zhangjicmu/ubuntu24_ros:ai_module, installs python3-pip, then editable-installs this repo into the system Python 3.12.

Architecture: why sidecars

When XIAO_HEI_RESPONDER=perception, the wrapper activates the matching compose profile, which brings up a sidecar container alongside system + ai_module. The ai_module calls it over HTTP — no CUDA dependencies are installed in the ai_module image, which avoids pip/apt conflicts with the ROS base.

Responder Sidecar Image
perception perception on :8001 xiao-hei/perception:latest (built from perception/Dockerfile, based on ultralytics/ultralytics:8.4.72)
scene_gemini perception on :8001, plus the Gemini API over HTTPS same sidecar image; reasoning runs in the cloud, so no local inference server

See Perception Sidecar for the YOLO-World + SAM 2.1 setup specifically.

Publishing for submission

docker tag xiao-hei/ai_module:latest <your-dockerhub-user>/xiao-hei-ai-module:latest
docker push <your-dockerhub-user>/xiao-hei-ai-module:latest

Dropping into the challenge repo

In CMU-VLN-Challenge-2026/docker/compose.yml, replace the ai_module: block:

ai_module:
  image: <your-dockerhub-user>/xiao-hei-ai-module:latest
  container_name: iros2026_ai_module
  network_mode: host
  environment:
    - RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
  stdin_open: true
  tty: true

Troubleshooting

Symptom Likely cause Fix
ai_module blocks at startup waiting on the sidecar sidecar not started or weights still downloading Check docker logs xiao_hei_perception
ai_module crash-loops on scene_gemini invalid/missing XIAO_HEI_GEMINI_API_KEYwarmup() validates it at boot Export a valid key before up
Subscription count: 0 DDS mismatch Verify RMW_IMPLEMENTATION=rmw_cyclonedds_cpp on both containers
Echo returns nothing VOLATILE QoS + late subscriber Run echo before publishing