Sanad_Package_2/NEW_ROBOT_SETUP.md

3.7 KiB

Setting up P2 (Premium Communication) on a NEW G1

Same shape as P1's NEW_ROBOT_SETUP — 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)

rsync -az --exclude __pycache__ \
  Project/Packages/Sanad_Package_2 \
  unitree@<NEWROBOT>:~/sanad_deploy/

2. Build on the robot

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):

# 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

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://<NEWROBOT>: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

./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 audiobuiltin needs the Unitree SDK (default build) + eth0 to the G1; fallback SANAD_AUDIO_PROFILE=plugged (USB/Anker).
  • docker compose build fails on buildxDOCKER_BUILDKIT=0 docker build -t sanad-p2:latest .