[Unit] Description=SaltyBot ROS2 Full Stack (perception + navigation + SLAM) Documentation=https://gitea.vayrette.com/seb/saltylab-firmware # # Launches: saltybot_bringup full_stack.launch.py (indoor mode by default) # enable_bridge:=false — ESP32-S3 serial bridge is managed by saltybot-esp32-serial.service # # Stack launched (t=0s → t=17s): # t= 0s robot_description (URDF + TF) # t= 2s RPLIDAR A1M8 + RealSense D435i # t= 3s LIDAR obstacle avoidance # t= 4s 4× IMX219 CSI cameras (optional) # t= 4s UWB driver # t= 5s Audio pipeline (wake word + STT + TTS) # t= 6s RTAB-Map SLAM (indoor) / GPS nav (outdoor) # t= 6s YOLOv8n person + object detection (TensorRT) # t= 7s Autonomous docking # t= 9s Person follower # t=14s Nav2 navigation stack # t=17s rosbridge WebSocket (ws://0.0.0.0:9090) # # Hard deps: can-bringup (Here4 GPS topics), esp32-serial (VESC telemetry) After=network-online.target can-bringup.service saltybot-esp32-serial.service saltybot-here4.service Wants=can-bringup.service saltybot-esp32-serial.service saltybot-here4.service [Service] Type=simple User=orin Group=orin Environment="ROS_DOMAIN_ID=42" Environment="ROS_DISTRO=humble" Environment="SALTYBOT_WS=/opt/saltybot/jetson/ros2_ws/install" # enable_bridge:=false — ESP32 serial bridge runs as its own service (saltybot-esp32-serial) # mode can be overridden via environment: Environment="SALTYBOT_MODE=outdoor" ExecStart=/opt/saltybot/scripts/ros2-launch.sh \ saltybot_bringup full_stack.launch.py \ enable_bridge:=false \ mode:=${SALTYBOT_MODE:-indoor} Restart=on-failure RestartSec=10s StartLimitInterval=120s StartLimitBurst=3 TimeoutStartSec=120s TimeoutStopSec=30s # ROS2 launch spawns many child processes; kill them on stop KillMode=control-group # Logging StandardOutput=journal StandardError=journal SyslogIdentifier=saltybot-ros2 [Install] WantedBy=saltybot.target