[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
