- Dockerfile.social: social-bot container with faster-whisper, llama-cpp-python (CUDA), piper-tts, insightface, pyannote.audio, OpenWakeWord, pyaudio - scripts/convert_models.sh: TRT FP16 conversion for SCRFD-10GF, ArcFace-R100, ECAPA-TDNN; CTranslate2 setup for Whisper; Piper voice download; benchmark suite - config/asound.conf: ALSA USB mic (card1) + USB speaker (card2) config - models/README.md: version-pinned model table, /models/ layout, perf targets - systemd/: saltybot-social.service + saltybot.target + install_systemd.sh - docker-compose.yml: saltybot-social service with GPU, audio device passthrough, NVMe volume mounts for /models and /social_db Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
363 lines
11 KiB
YAML
363 lines
11 KiB
YAML
version: "3.8"
|
|
|
|
# Jetson Orin Nano Super — ROS2 Humble SLAM stack
|
|
# Run with: docker compose up -d
|
|
# Requires: NVIDIA Container Toolkit (JetPack 6) on host
|
|
|
|
services:
|
|
|
|
# ── Core ROS2 + SLAM node ─────────────────────────────────────────────────
|
|
saltybot-ros2:
|
|
image: saltybot/ros2-humble:jetson-orin
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
container_name: saltybot-ros2
|
|
restart: unless-stopped
|
|
runtime: nvidia
|
|
privileged: false
|
|
network_mode: host
|
|
environment:
|
|
- NVIDIA_VISIBLE_DEVICES=all
|
|
- NVIDIA_DRIVER_CAPABILITIES=all
|
|
- RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
|
|
- ROS_DOMAIN_ID=42
|
|
- DISPLAY=${DISPLAY:-:0}
|
|
volumes:
|
|
- /tmp/.X11-unix:/tmp/.X11-unix:rw
|
|
- ./ros2_ws/src:/ros2_ws/src:rw
|
|
- /mnt/nvme/saltybot/maps:/maps
|
|
- /mnt/nvme/saltybot:/data:rw
|
|
- ./config:/config:ro
|
|
devices:
|
|
- /dev/rplidar:/dev/rplidar
|
|
- /dev/stm32-bridge:/dev/stm32-bridge
|
|
- /dev/bus/usb:/dev/bus/usb
|
|
- /dev/i2c-7:/dev/i2c-7
|
|
- /dev/video0:/dev/video0
|
|
- /dev/video2:/dev/video2
|
|
- /dev/video4:/dev/video4
|
|
- /dev/video6:/dev/video6
|
|
command: >
|
|
bash -c "
|
|
source /opt/ros/humble/setup.bash &&
|
|
ros2 launch saltybot_bringup slam_rtabmap.launch.py
|
|
"
|
|
|
|
# ── RPLIDAR driver node ────────────────────────────────────────────────────
|
|
rplidar:
|
|
image: saltybot/ros2-humble:jetson-orin
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
container_name: saltybot-rplidar
|
|
restart: unless-stopped
|
|
runtime: nvidia
|
|
network_mode: host
|
|
environment:
|
|
- ROS_DOMAIN_ID=42
|
|
- RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
|
|
devices:
|
|
- /dev/rplidar:/dev/rplidar
|
|
command: >
|
|
bash -c "
|
|
source /opt/ros/humble/setup.bash &&
|
|
ros2 launch rplidar_ros rplidar_a1_launch.py
|
|
serial_port:=/dev/rplidar
|
|
frame_id:=laser
|
|
"
|
|
|
|
# ── RealSense D435i driver node ────────────────────────────────────────────
|
|
realsense:
|
|
image: saltybot/ros2-humble:jetson-orin
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
container_name: saltybot-realsense
|
|
restart: unless-stopped
|
|
runtime: nvidia
|
|
network_mode: host
|
|
environment:
|
|
- ROS_DOMAIN_ID=42
|
|
- RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
|
|
devices:
|
|
- /dev/bus/usb:/dev/bus/usb
|
|
volumes:
|
|
- /dev:/dev
|
|
command: >
|
|
bash -c "
|
|
source /opt/ros/humble/setup.bash &&
|
|
ros2 launch realsense2_camera rs_launch.py
|
|
enable_color:=true
|
|
enable_depth:=true
|
|
enable_gyro:=true
|
|
enable_accel:=true
|
|
unite_imu_method:=linear_interpolation
|
|
depth_module.profile:=640x480x30
|
|
rgb_camera.profile:=640x480x30
|
|
"
|
|
|
|
# ── STM32 bridge node (bidirectional serial<->ROS2) ────────────────────────
|
|
stm32-bridge:
|
|
image: saltybot/ros2-humble:jetson-orin
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
container_name: saltybot-stm32-bridge
|
|
restart: unless-stopped
|
|
runtime: nvidia
|
|
network_mode: host
|
|
environment:
|
|
- ROS_DOMAIN_ID=42
|
|
- RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
|
|
devices:
|
|
- /dev/stm32-bridge:/dev/stm32-bridge
|
|
command: >
|
|
bash -c "
|
|
source /opt/ros/humble/setup.bash &&
|
|
ros2 launch saltybot_bridge bridge.launch.py
|
|
mode:=bidirectional
|
|
serial_port:=/dev/stm32-bridge
|
|
"
|
|
|
|
# ── 4x IMX219 CSI cameras ──────────────────────────────────────────────────
|
|
csi-cameras:
|
|
image: saltybot/ros2-humble:jetson-orin
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
container_name: saltybot-csi-cameras
|
|
restart: unless-stopped
|
|
runtime: nvidia
|
|
network_mode: host
|
|
privileged: true
|
|
environment:
|
|
- ROS_DOMAIN_ID=42
|
|
- RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
|
|
- NVIDIA_VISIBLE_DEVICES=all
|
|
- NVIDIA_DRIVER_CAPABILITIES=all
|
|
devices:
|
|
- /dev/video0:/dev/video0
|
|
- /dev/video2:/dev/video2
|
|
- /dev/video4:/dev/video4
|
|
- /dev/video6:/dev/video6
|
|
command: >
|
|
bash -c "
|
|
source /opt/ros/humble/setup.bash &&
|
|
ros2 launch saltybot_cameras csi_cameras.launch.py
|
|
width:=640
|
|
height:=480
|
|
fps:=30
|
|
"
|
|
|
|
# ── Surround vision — 360 bird's-eye view + Nav2 camera obstacle layer ─────
|
|
saltybot-surround:
|
|
image: saltybot/ros2-humble:jetson-orin
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
container_name: saltybot-surround
|
|
restart: unless-stopped
|
|
runtime: nvidia
|
|
network_mode: host
|
|
depends_on:
|
|
- csi-cameras
|
|
environment:
|
|
- NVIDIA_VISIBLE_DEVICES=all
|
|
- NVIDIA_DRIVER_CAPABILITIES=all
|
|
- RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
|
|
- ROS_DOMAIN_ID=42
|
|
volumes:
|
|
- ./ros2_ws/src:/ros2_ws/src:rw
|
|
- ./config:/config:ro
|
|
command: >
|
|
bash -c "
|
|
source /opt/ros/humble/setup.bash &&
|
|
source /ros2_ws/install/local_setup.bash 2>/dev/null || true &&
|
|
ros2 launch saltybot_surround surround_vision.launch.py
|
|
start_cameras:=false
|
|
camera_height:=0.30
|
|
publish_rate:=5.0
|
|
"
|
|
|
|
# ── rosbridge WebSocket server — ws://jetson:9090 ──────────────────────────
|
|
rosbridge:
|
|
image: saltybot/ros2-humble:jetson-orin
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
container_name: saltybot-rosbridge
|
|
restart: unless-stopped
|
|
runtime: nvidia
|
|
network_mode: host
|
|
depends_on:
|
|
- saltybot-ros2
|
|
- stm32-bridge
|
|
- csi-cameras
|
|
environment:
|
|
- ROS_DOMAIN_ID=42
|
|
- RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
|
|
volumes:
|
|
- ./ros2_ws/src:/ros2_ws/src:rw
|
|
- ./config:/config:ro
|
|
command: >
|
|
bash -c "
|
|
source /opt/ros/humble/setup.bash &&
|
|
source /ros2_ws/install/local_setup.bash 2>/dev/null || true &&
|
|
ros2 launch saltybot_bringup rosbridge.launch.py
|
|
"
|
|
|
|
|
|
# -- Remote e-stop bridge (MQTT over 4G -> STM32 CDC) ----------------------
|
|
# Subscribes to saltybot/estop MQTT topic. {"kill":true} -> 'E\r\n' to STM32.
|
|
# Cellular watchdog: 5s MQTT drop in AUTO mode -> 'F\r\n' (ESTOP_CELLULAR_TIMEOUT).
|
|
remote-estop:
|
|
image: saltybot/ros2-humble:jetson-orin
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
container_name: saltybot-remote-estop
|
|
restart: unless-stopped
|
|
runtime: nvidia
|
|
network_mode: host
|
|
depends_on:
|
|
- stm32-bridge
|
|
environment:
|
|
- ROS_DOMAIN_ID=42
|
|
- RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
|
|
devices:
|
|
- /dev/stm32-bridge:/dev/stm32-bridge
|
|
volumes:
|
|
- ./ros2_ws/src:/ros2_ws/src:rw
|
|
- ./config:/config:ro
|
|
command: >
|
|
bash -c "
|
|
source /opt/ros/humble/setup.bash &&
|
|
source /ros2_ws/install/local_setup.bash 2>/dev/null || true &&
|
|
pip install paho-mqtt --quiet 2>/dev/null || true &&
|
|
ros2 launch saltybot_bridge remote_estop.launch.py
|
|
"
|
|
|
|
# ── Nav2 autonomous navigation stack ──────────────────────────────────────
|
|
saltybot-nav2:
|
|
image: saltybot/ros2-humble:jetson-orin
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
container_name: saltybot-nav2
|
|
restart: unless-stopped
|
|
runtime: nvidia
|
|
network_mode: host
|
|
depends_on:
|
|
- saltybot-ros2
|
|
environment:
|
|
- NVIDIA_VISIBLE_DEVICES=all
|
|
- NVIDIA_DRIVER_CAPABILITIES=all
|
|
- RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
|
|
- ROS_DOMAIN_ID=42
|
|
volumes:
|
|
- ./ros2_ws/src:/ros2_ws/src:rw
|
|
- ./config:/config:ro
|
|
command: >
|
|
bash -c "
|
|
source /opt/ros/humble/setup.bash &&
|
|
source /ros2_ws/install/local_setup.bash 2>/dev/null || true &&
|
|
ros2 launch saltybot_bringup nav2.launch.py
|
|
"
|
|
|
|
# ── Outdoor navigation — OSM routing + GPS waypoints + geofence ───────────
|
|
# Start only for outdoor missions. Usage:
|
|
# ros2 param set /osm_router goal_lat 37.7749
|
|
# ros2 param set /osm_router goal_lon -122.4194
|
|
# ros2 service call /outdoor/plan_route std_srvs/srv/Trigger '{}'
|
|
# ros2 service call /outdoor/start_navigation std_srvs/srv/Trigger '{}'
|
|
saltybot-outdoor:
|
|
image: saltybot/ros2-humble:jetson-orin
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
container_name: saltybot-outdoor
|
|
restart: unless-stopped
|
|
runtime: nvidia
|
|
network_mode: host
|
|
depends_on:
|
|
- saltybot-nav2
|
|
environment:
|
|
- NVIDIA_VISIBLE_DEVICES=all
|
|
- NVIDIA_DRIVER_CAPABILITIES=all
|
|
- RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
|
|
- ROS_DOMAIN_ID=42
|
|
volumes:
|
|
- ./ros2_ws/src:/ros2_ws/src:rw
|
|
- ./config:/config:ro
|
|
- /mnt/nvme/saltybot/osm_cache:/data/osm_cache:rw
|
|
devices:
|
|
- /dev/sim7600:/dev/sim7600
|
|
command: >
|
|
bash -c "
|
|
source /opt/ros/humble/setup.bash &&
|
|
source /ros2_ws/install/local_setup.bash 2>/dev/null || true &&
|
|
ros2 launch saltybot_outdoor outdoor_nav.launch.py
|
|
use_rtk:=false
|
|
fence_active:=true
|
|
"
|
|
|
|
# ── Social-bot AI stack (speech + LLM + TTS + face recognition) ─────────────
|
|
# Issue #88: Orin dev environment for social-bot
|
|
# Start: docker compose up -d saltybot-social
|
|
# Logs: docker compose logs -f saltybot-social
|
|
saltybot-social:
|
|
image: saltybot/social:latest
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile.social
|
|
container_name: saltybot-social
|
|
restart: unless-stopped
|
|
runtime: nvidia
|
|
network_mode: host
|
|
depends_on:
|
|
- stm32-bridge
|
|
environment:
|
|
- NVIDIA_VISIBLE_DEVICES=all
|
|
- NVIDIA_DRIVER_CAPABILITIES=all,audio
|
|
- ROS_DOMAIN_ID=42
|
|
- RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
|
|
- MODEL_DIR=/models
|
|
- PIPER_VOICE_DIR=/models/piper
|
|
- LLAMA_N_GPU_LAYERS=20
|
|
# Audio device routing (override if mic/speaker cards differ)
|
|
- ALSA_MIC_CARD=1
|
|
- ALSA_SPEAKER_CARD=2
|
|
volumes:
|
|
- ./ros2_ws/src:/ros2_ws/src:rw
|
|
- ./config:/config:ro
|
|
# Persistent model storage on NVMe (survives container restarts)
|
|
- /mnt/nvme/saltybot/models:/models:rw
|
|
# Enrollment database (face embeddings, voice prints, conversation history)
|
|
- /mnt/nvme/saltybot/social_db:/social_db:rw
|
|
# SOUL.md personality file
|
|
- /mnt/nvme/saltybot/soul:/soul:ro
|
|
devices:
|
|
# USB mic array (ReSpeaker 2-Mic / 4-Mic or compatible)
|
|
- /dev/snd:/dev/snd
|
|
# USB webcam / face camera (optional, RealSense preferred)
|
|
- /dev/bus/usb:/dev/bus/usb
|
|
group_add:
|
|
- audio
|
|
cap_add:
|
|
- SYS_NICE # allow real-time thread priority for audio
|
|
ulimits:
|
|
rtprio: 95
|
|
memlock: -1
|
|
command: >
|
|
bash -c "
|
|
source /opt/ros/humble/setup.bash &&
|
|
source /ros2_ws/install/local_setup.bash 2>/dev/null || true &&
|
|
ros2 launch saltybot_social social_bot.launch.py
|
|
"
|
|
|
|
|
|
volumes:
|
|
saltybot-maps:
|
|
driver: local
|