# Saqr — Auto-start on boot How to make `saqr_g1_bridge.py` run automatically on every boot of the Unitree G1 (Jetson), via `systemd` + `start_saqr.sh`. --- ## Files involved | File | Role | |------|------| | `~/Saqr/saqr_g1_bridge.py` | The bridge process (DDS + TTS + R2+X/R2+Y trigger loop). | | `~/Saqr/start_saqr.sh` | Bash launcher: sources conda, activates `marcus`, `cd ~/Saqr`, exec the bridge with the right flags. | | `~/Saqr/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/start_saqr.sh # 2. Install the systemd unit system-wide so it starts at BOOT # (not just at login). sudo cp ~/Saqr/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 # Follow the live bridge log (replaces the terminal you used to ssh into). journalctl -u saqr-bridge -f # Stop / start / restart on demand. sudo systemctl restart saqr-bridge sudo systemctl stop saqr-bridge sudo systemctl start saqr-bridge # Disable auto-start at boot (the service stays installed). sudo systemctl disable saqr-bridge # Re-enable auto-start at boot. sudo systemctl enable saqr-bridge # Show the most recent 100 log lines (e.g. after a reboot). journalctl -u saqr-bridge -n 100 --no-pager # Show only this boot's logs. journalctl -u saqr-bridge -b ``` --- ## ⚠️ 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 `./start_saqr.sh` in a terminal you'll have two bridges fighting over the same DDS clients (you'll see lines like `R2+X pressed -> start saqr` immediately followed by `start ignored — saqr already running`, because both bridges react to the same wireless-remote events). 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, then run by hand. sudo systemctl stop saqr-bridge ~/Saqr/start_saqr.sh ``` --- ## Quick reboot test ```bash sudo reboot # After the robot is back up: ssh unitree@192.168.123.164 sudo systemctl status saqr-bridge # should be "active (running)" journalctl -u saqr-bridge -n 50 # boot log including the # "Saqr is running" TTS line ``` --- ## Updating the bridge / launcher / unit After editing any of the three files: ```bash # If you changed start_saqr.sh or saqr_g1_bridge.py: sudo systemctl restart saqr-bridge # If you changed saqr-bridge.service itself: sudo cp ~/Saqr/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` | `$HOME/Saqr` | Where `saqr_g1_bridge.py` lives. | | `CONDA_ROOT` | `$HOME/miniconda3` | Miniconda install path. | | `CONDA_ENV` | `marcus` | Conda env that has `unitree_sdk2py`, `ultralytics`, `pyrealsense2`. | | `DDS_IFACE` | `eth0` | DDS network interface for the G1. | | `SAQR_SOURCE` | `realsense` | `--source` passed to saqr (`realsense` / `/dev/video2` / `0`). | | `STREAM_PORT` | `8080` | MJPEG stream port (`-- --stream $STREAM_PORT`). | To override permanently in the systemd service, add `Environment=` lines to `/etc/systemd/system/saqr-bridge.service` and run `sudo systemctl daemon-reload && sudo systemctl restart saqr-bridge`. Example: ```ini Environment=SAQR_SOURCE=/dev/video2 Environment=STREAM_PORT=9090 ``` --- ## Troubleshooting ### Service won't start ```bash sudo systemctl status saqr-bridge journalctl -u saqr-bridge -n 100 --no-pager ``` Common causes: - `start_saqr.sh` not executable → `chmod +x ~/Saqr/start_saqr.sh` - conda env name wrong → check `CONDA_ENV` - `unitree_sdk2py` missing in the env → run `~/Saqr/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: ```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_g1_bridge # If you see two python processes, kill the manual one and let systemd own it: sudo systemctl restart saqr-bridge ```