# Saqr — Auto-start on boot How to auto-start `saqr.robot.bridge` on every boot of the Unitree G1 (Jetson), via `systemd` + `scripts/start_saqr.sh`. --- ## Files involved | File | Role | |------|------| | `~/Saqr/saqr/robot/bridge.py` | The bridge process (DDS + TTS + R2+X/R2+Y trigger loop). Entry point: `python -m saqr.robot.bridge`. | | `~/Saqr/scripts/start_saqr.sh` | Bash launcher: sources conda, activates `marcus`, `cd ~/Saqr`, exec the bridge with the production flags. | | `~/Saqr/scripts/saqr-bridge.service` | systemd unit that runs `start_saqr.sh` as user `unitree` on every boot, restarts on failure, logs to journalctl. | --- ## One-time install Run these on the robot: ```bash # 1. Make sure the launcher is executable. chmod +x ~/Saqr/scripts/start_saqr.sh # 2. Install the systemd unit system-wide so it starts at BOOT # (not just at login). sudo cp ~/Saqr/scripts/saqr-bridge.service /etc/systemd/system/ sudo systemctl daemon-reload # 3. Enable + start it now. sudo systemctl enable --now saqr-bridge # 4. Verify it came up. sudo systemctl status saqr-bridge ``` You should hear **"Saqr is running. Press R2 plus X to start."** on the robot speaker within ~10 seconds. From then on, every reboot auto-starts the bridge — no terminal needed. --- ## Daily commands ```bash journalctl -u saqr-bridge -f # follow live log sudo systemctl restart saqr-bridge sudo systemctl stop saqr-bridge sudo systemctl start saqr-bridge sudo systemctl disable saqr-bridge # stop auto-starting at boot sudo systemctl enable saqr-bridge journalctl -u saqr-bridge -n 100 --no-pager # last 100 lines journalctl -u saqr-bridge -b # only this boot's logs ``` --- ## ⚠️ Don't run two bridges at once Once the systemd service is enabled, the bridge is **already running** in the background. If you also run `scripts/start_saqr.sh` in a terminal you'll have two bridges fighting over the same DDS clients (`R2+X pressed -> start saqr` followed immediately by `start ignored — saqr already running`). Pick one mode: ```bash # Production: let systemd own the bridge. sudo systemctl start saqr-bridge journalctl -u saqr-bridge -f # Dev / debugging: stop the systemd one first. sudo systemctl stop saqr-bridge ~/Saqr/scripts/start_saqr.sh ``` --- ## Quick reboot test ```bash sudo reboot ssh unitree@192.168.123.164 sudo systemctl status saqr-bridge # should be "active (running)" journalctl -u saqr-bridge -n 50 # includes the "Saqr is running" TTS ``` --- ## Updating the bridge / launcher / unit ```bash # If you changed start_saqr.sh or anything in saqr/: sudo systemctl restart saqr-bridge # If you changed saqr-bridge.service itself: sudo cp ~/Saqr/scripts/saqr-bridge.service /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl restart saqr-bridge ``` --- ## Configuration overrides `start_saqr.sh` reads its config from environment variables, so you can override any of them without editing the script. Defaults: | Variable | Default | Meaning | |---------------|----------------------|---------| | `SAQR_DIR` | *(parent of `scripts/`)* | Project root on the robot. | | `CONDA_ROOT` | `$HOME/miniconda3` | Miniconda install path. | | `CONDA_ENV` | `marcus` | Conda env with `unitree_sdk2py`, `ultralytics`, `pyrealsense2`. | | `DDS_IFACE` | `eth0` | DDS network interface. | | `SAQR_SOURCE` | `realsense` | `--source` passed to saqr. | | `STREAM_PORT` | `8080` | MJPEG stream port (`-- --stream $STREAM_PORT`). | To override permanently in systemd, add `Environment=` lines to `/etc/systemd/system/saqr-bridge.service`: ```ini Environment=SAQR_SOURCE=/dev/video2 Environment=STREAM_PORT=9090 ``` Then `sudo systemctl daemon-reload && sudo systemctl restart saqr-bridge`. --- ## Troubleshooting ### Service won't start ```bash sudo systemctl status saqr-bridge journalctl -u saqr-bridge -n 100 --no-pager ``` Common causes: - `scripts/start_saqr.sh` not executable → `chmod +x ~/Saqr/scripts/start_saqr.sh` - conda env name wrong → check `CONDA_ENV` - `saqr` package not installed → `cd ~/Saqr && pip install -e .` - `unitree_sdk2py` missing in the env → run `scripts/start_saqr.sh` by hand to see the import error - DDS interface wrong → set `DDS_IFACE=enp...` if the G1 isn't on `eth0` ### "No device connected" when pressing R2+X The RealSense USB hiccup. The bridge stays alive and announces **"Camera not connected. Please plug in the camera and try again."** — just unplug/replug the camera and press R2+X again. If it persists, fall back to the V4L2 path by editing the systemd unit: ```bash sudo systemctl edit saqr-bridge # add: [Service] Environment=SAQR_SOURCE=/dev/video2 # save, then: sudo systemctl restart saqr-bridge ``` ### Bridge is running twice ```bash ps -ef | grep "saqr.robot.bridge" sudo systemctl restart saqr-bridge ```