Sanad_Package_2/NEW_ROBOT_SETUP.md

81 lines
3.7 KiB
Markdown

# Setting up P2 (Premium Communication) on a NEW G1
Same shape as P1's [NEW_ROBOT_SETUP](../Sanad_Package_1/NEW_ROBOT_SETUP.md) —
self-contained, build on the robot, sign a per-robot license — with **three P2
deltas**: the license must **entitle P2**, the **LED mask** needs BLE, and the
port is **:8012**.
## 0. Prerequisites (same as P1) + mask
- Docker on the Jetson; your user in the `docker` group.
- eth0 linked to the G1 (chest audio + arm over DDS).
- **BLE "Shining Mask"** powered, in range, and **freed from the phone app**
(BLE allows one central at a time). The host BlueZ stack must be up
(`systemctl status bluetooth`).
## 1. Copy the package (self-contained — only this folder)
```bash
rsync -az --exclude __pycache__ \
Project/Packages/Sanad_Package_2 \
unitree@<NEWROBOT>:~/sanad_deploy/
```
## 2. Build on the robot
```bash
cd ~/sanad_deploy/Sanad_Package_2
docker compose build # or: DOCKER_BUILDKIT=0 docker build -t sanad-p2:latest .
```
Builds the vendored SanadV3 engine + the chest-audio Unitree SDK (full CycloneDDS
+ idlc, `cyclonedds==0.10.2`) + `bleak==0.22.3` + Pillow. First build is a few
minutes.
## 3. License THIS robot — must entitle **P2**
The bundled `license/sanad.lic.example` entitles P1+P2+P3 for demo. For a real
delivery, sign a license for the robot (vendor side, private key off-robot):
```bash
# claims.json — set packages.P2=true (+ the features it sells)
# "packages": {"P1": false, "P2": true, "P3": false, "P4": false},
# "features": {"multilingual": true, "voice_command_motion": true, "lipsync": true, "mask": true}
python licensing/sign_license.py sign --key licensing/privkey.ed25519 \
--in claims.json --out sanad.lic
scp sanad.lic unitree@<NEWROBOT>:~/sanad_deploy/Sanad_Package_2/license/sanad.lic
```
Fingerprint binding (`SANAD_LICENSE_BIND=1`) works exactly as P1 — read the
fingerprint with `PYTHONPATH=vendor python3 -c 'from sanad_pkg import license as L; print(L.machine_fingerprint())'`,
put it in claims, and **uncomment the `/etc/machine-id` mount** in `docker-compose.yml`.
## 4. Configure `.env` and run
```bash
cd ~/sanad_deploy/Sanad_Package_2 && cp .env.example .env # edit license/audio/mask
docker compose up -d
docker compose logs -f # expect "[P2] entitled — lang=<multilingual> … port=8012"
```
Dashboard: **http://&lt;NEWROBOT&gt;:8012**. Optional pin the mask MAC:
`SANAD_MASK_ADDRESS=XX:XX:…` in `.env`.
## 5. First-use (per customer)
Open `:8012`: paste the **Gemini API key** (keyless ship) → set the **Persona**
(bilingual prompt = multilingual) → **Mask** tab connect + lip-sync test → enable
**Live-voice** for arm gestures (default OFF) → **Start** and talk.
## 6. Verify
```bash
./test_p2.sh <NEWROBOT>:8012 # expect all PASS
curl http://<NEWROBOT>:8012/api/package # license.valid + packages.P2=true + features
curl http://<NEWROBOT>:8012/api/mask/status
```
## 7. Auto-run on boot
`sudo systemctl enable docker` (compose already `restart: unless-stopped`), or a
systemd unit as in P1's guide (WorkingDirectory `…/Sanad_Package_2`, `docker
compose up`/`down`).
### Troubleshooting
- **Container exits "not licensed"** — your license doesn't entitle P2; re-sign
with `packages.P2=true` (the bundled example already does).
- **Mask won't connect** — free it from the phone app; confirm host `bluetooth`
service up; check `/var/run/dbus` is mounted + `NET_ADMIN`; `bleak==0.22.3`
(3.x fails on BlueZ 5.53). `/api/mask/status` shows `lib_available`/`connected`.
- **No chest audio** — `builtin` needs the Unitree SDK (default build) + eth0 to
the G1; fallback `SANAD_AUDIO_PROFILE=plugged` (USB/Anker).
- **`docker compose build` fails on buildx** — `DOCKER_BUILDKIT=0 docker build -t sanad-p2:latest .`