[Unit] Description=SanadV3 full stack (dashboard :8001 + web_nav3 nav :8765 + rosbridge :9090) After=network-online.target sound.target Wants=network-online.target StartLimitIntervalSec=0 [Service] Type=simple User=unitree Group=unitree WorkingDirectory=/home/unitree/Sanadv3 # Runtime env (systemd does NOT source ~/.bashrc, so set what the stack needs). Environment=USER=unitree Environment=HOME=/home/unitree Environment=PYTHONUNBUFFERED=1 Environment=XDG_RUNTIME_DIR=/run/user/1000 Environment=PULSE_SERVER=unix:/run/user/1000/pulse/native # Pin the voice child to Sanadv3 (replaces the old ~/.bashrc SANAD_LIVE_SCRIPT). Environment=SANAD_LIVE_SCRIPT=/home/unitree/Sanadv3/voice/sanad_voice.py # start_all.sh self-activates conda (gemini_sdk for dashboard, g1_lidar for # web_nav3), supervises both, and has a SIGTERM cleanup trap. ExecStart=/bin/bash /home/unitree/Sanadv3/shell_scripts/start_all.sh # Let start_all.sh's trap tear its children down on stop, then SIGKILL stragglers. KillMode=mixed TimeoutStopSec=30 Restart=always RestartSec=5s [Install] WantedBy=multi-user.target