File size: 16,482 Bytes
700dd75 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 | # PICO VR Whole-body Teleop
Full whole-body teleoperation using PICO VR headset and controllers. To teleop, use the option `--input-type zmq_manager` during deployment. The `zmq_manager` input type switches between a **planner mode** (locomotion commands via ZMQ) and a **streamed motion mode** (full-body SMPL poses from PICO).
## SONIC Low Latency
The sequence below shows 3-point VR teleoperation with SONIC Low Latency,
including whole-body tracking and a successful ground pickup.
```{image} ../_static/sonic_low_latency_demo.gif
:alt: SONIC Low Latency whole-body teleoperation and ground pickup
:width: 640px
:align: center
```
```{admonition} Isaac Teleop / CloudXR Scope
:class: note
The same `zmq_manager` workflow can also drive the headset through Isaac Teleop / CloudXR by launching `gear_sonic/scripts/pico_manager_thread_server.py --input-source isaac-teleop`. The streamer hosts the CloudXR runtime in-process via `isaacteleop[cloudxr]` β no separate publisher container required. That path is currently supported only for **G1 with a Thor backpack**; a regular G1 setup is not supported yet.
```
```{admonition} Safety Warning
:class: danger
Whole-body teleoperation involves fast, agile motions. **Always** maintain a clear safety zone and keep a safety operator at the keyboard ready to trigger an emergency stop (**`O`** in the C++ terminal, or **A+B+X+Y** on the PICO controllers).
You **must wear tight-fitting pants or leggings** to guarantee line-of-sight for the foot trackers β loose or baggy clothing can make tracking fail unpredictably and may result in dangerous motion.
```
```{video} ../_static/teleop/teleop_session_overview.mp4
:width: 100%
```
*Video: End-to-end teleoperation walkthrough β PICO calibration, policy engagement, and the robot balancing independently. See the [Teleoperation Guide](../user_guide/teleoperation.md) for detailed best practices.*
## Prerequisites
1. **Completed the [Quick Start](../getting_started/quickstart.md)** β you can run the sim2sim loop (includes [installing the deployment](../getting_started/installation_deploy.md) and [downloading model checkpoints](../getting_started/download_models.md)).
2. **Completed the [VR Teleop Setup](../getting_started/vr_teleop_setup.md)** β `.venv_teleop` is ready. For the default path, PICO hardware is installed, calibrated, and connected. For Isaac Teleop / CloudXR, the `isaacteleop[cloudxr]` package is also installed (handled by `install_pico.sh`) and the headset connects to the in-process CloudXR runtime β see [Isaac Teleop Setup](isaac_teleop_publisher_setup.md).
---
## Step-by-Step: Teleop in SIM
Run **three terminals** to teleoperate the simulated robot.
### Terminal 1 β Launch virtual robot in MuJoCo Simulator
From the **repo root**:
```bash
# bash install_scripts/install_pico.sh
source .venv_teleop/bin/activate
python gear_sonic/scripts/run_sim_loop.py
```
### Terminal 2 β C++ Deployment
From `gear_sonic_deploy/`:
```bash
cd gear_sonic_deploy
source scripts/setup_env.sh
./deploy.sh --input-type zmq_manager sim
# Wait until you see "Init done"
```
**Isaac Teleop / CloudXR alternative** (**G1 + Thor backpack only**) β run the C++ deployment from the project's ROS2 docker container instead of bare metal:
```bash
cd gear_sonic_deploy
export TensorRT_ROOT=$HOME/TensorRT # only if not already in ~/.bashrc
./docker/run-ros2-dev.sh
# inside the container (setup_env.sh is sourced automatically):
just build # first run only
./deploy.sh --input-type zmq_manager sim
# Wait until you see "Init done"
```
See [Installation (Deployment) β Docker (ROS2 Development Environment)](../getting_started/installation_deploy.md) for details on `run-ros2-dev.sh` and `TensorRT_ROOT`.
```{note}
The `--zmq-host` flag defaults to `localhost`, which is correct when both C++ deployment scripts and teleop scripts (Terminal 3) run on the same machine. If the teleop script runs on a different machine, pass `--zmq-host <IP-of-teleop-machine>`.
```
### Terminal 3 β PICO Teleop Streamer
From the **repo root**:
```bash
source .venv_teleop/bin/activate
# With full visualization (recommended for first run):
python gear_sonic/scripts/pico_manager_thread_server.py --manager \
--vis_vr3pt --vis_smpl
# Without visualization (for headless / onboard practice):
# python gear_sonic/scripts/pico_manager_thread_server.py --manager
```
**Isaac Teleop / CloudXR alternative** (**G1 + Thor backpack only**) β connects the headset over CloudXR (no XRoboToolKit PC service required); the streamer launches the CloudXR runtime in-process via `isaacteleop[cloudxr]`:
```bash
source .venv_teleop/bin/activate
python gear_sonic/scripts/pico_manager_thread_server.py --manager \
--input-source isaac-teleop
# If running offboard with a display, add visualization:
# --vis_vr3pt --vis_smpl
```
When you turn on the visualization, wait for a window to pop up showing a Unitree G1 mesh with all joints at the default angles. If no window shows up on the default PICO path, double-check the PICO's XRoboToolKit IP configuration in the [VR Teleop Setup](../getting_started/vr_teleop_setup.md). If you are using Isaac Teleop instead, verify the headset is connected to the in-process CloudXR runtime β see [Isaac Teleop Setup](isaac_teleop_publisher_setup.md) for connection steps.
### Your First Teleop Session
1. **Assume the calibration pose** β stand upright, feet together, upper arms at your sides, forearms bent 90Β° forward (L-shape at each elbow), palms inward. See [Calibration Pose](#calibration-pose) for details.
2. Press **A + B + X + Y** simultaneously to engage the control policy and run the initial full calibration (`CALIB_FULL`).
3. Align your arms with the robot's current pose, then press **A + X** to enter full-body SMPL teleop (**POSE** mode). Move your arms and legs β the robot follows.
4. Press **A + X** again to fall back to **PLANNER** (idle) mode.
5. Press **A + B + X + Y** again to stop the robot.
<figure style="margin: 1em 0;">
<video width="100%" autoplay loop muted playsinline style="border-radius: 8px;">
<source src="../_static/teleop_calib/basic_flow_web.mp4" type="video/mp4">
</video>
<figcaption style="text-align: center; font-style: italic; margin-top: 0.5em;">Basic whole-body teleop workflow: calibration pose β engage β POSE mode β PLANNER idle β stop.</figcaption>
</figure>
---
(pico-controls)=
## Complete PICO Controls
### Modes & Calibration
The system has **4 operating modes** and **2 calibration types**.
**Modes:**
| Mode | Encoder | Description |
|---|---|---|
| **OFF** | -- | Policy not running. Stand in [calibration pose](#calibration-pose), then press **A+B+X+Y** to start policy. |
| **POSE** | SMPL | Whole-body teleop β streaming the SMPL pose from PICO to the C++ deployment side. Your motion will directly map to the robot .|
| **PLANNER** | G1 | Locomotion planner active; upper body controller by planner. Joysticks control direction and heading in walking and running modes. |
| **PLANNER_FROZEN_UPPER** | G1 | Planner locomotion; upper body frozen at last POSE snapshot. |
| **VR_3PT** | TELEOP | Planner locomotion; upper body follows VR 3-point tracking (head + 2 hands). Depends on non-IK-based VR 3-point calibration. |
**Calibration types** (non-IK workflow for minimal latency):
| Type | What Is Calibrated | When Triggered |
|---|---|---|
| **CALIB_FULL** | Head + both wrists against **all-zero** reference pose. | Once on first **A+B+X+Y** (startup). |
| **CALIB** | Both wrists only against the **current robot pose**. | Each switch into VR_3PT via **Left Stick Click**. |
### State Machine
There are 4 modes and 2 control chains. Each chain forms a triangle: **A+X** (or **B+Y**) returns to POSE from *both* the planner node and its VR_3PT sub-mode.
```text
ββββββββββββββββββββββββββββββββββββββββ
β A+B+X+Y (any mode) βββΊ OFF β
ββββββββββββββββββββββββββββββββββββββββ
Startup:
OFF ββ(A+B+X+Y)βββΊ PLANNER ββ(A+X)βββΊ POSE
CALIB_FULL
Chain 1 β G1 encoder listens to planner-generated full-body motion: PLANNER
PLANNER βββ L-Stick (+CALIB) βββΊ VR_3PT
β² β ββββββββ L-Stick βββββββββ β
β β β
βA+X βA+X A+X β
β βΌ βΌ
ββ POSE ββββββββββββββββββββββββββββ
Chain 2 β G1 encoder listens to planner-generated lower-body motion: PLANNER_FROZEN_UPPER
PLANNER_FROZEN_UPPER ββ L-Stick (+CALIB) βββΊ VR_3PT
β² β βββββββββ L-Stick ββββββββββ β
β β β
βB+Y βB+Y B+Y β
β βΌ βΌ
βββ POSE βββββββββββββββββββββββββββββββββ
```
```{admonition} DANGER β Mode-Switching Safety
:class: danger
**Before switching into POSE or VR_3PT**, always align your body with the robot's current pose first!!
- **POSE:** The robot instantly snaps to your physical pose. A large mismatch causes sudden, aggressive motion.
- **VR_3PT:** A misaligned calibration produces erratic, dangerous motion as soon as you move your arms. Check more info at section [per-switch-calib](#per-switch-calib)
```
(calibration-pose)=
### VR_3PT Calibration Hint
The `VR_3PT` mode depends on accurate calibration. Two calibration events occur:
#### One-time `CALIB_FULL` (head + wrists)
Before pressing **A + B + X + Y** for the first time, you **must** stand in the robot's **all-zero reference pose**. The system captures your PICO body-tracking frame as the zero-reference for all subsequent motion mapping.
**The reference pose:**
1. **Stand upright**, feet together, looking straight forward.
2. **Upper arms** hang straight down, close to your torso.
3. **Forearms** bent 90Β° forward (L-shape at each elbow), palms facing inward.
```{tip}
Launch the teleop script with `--vis_vr3pt` to see the robot's reference pose in a visualization window. Match your body to it before pressing the start combo.
```
(per-switch-calib)=
#### Per-switch `CALIB` (wrists only)
Each time you enter `VR_3PT` via **Left Stick Click**, the system re-calibrates both wrists against the robot's **current** pose. Always align your arms with the robot before clicking.
Below is an example of **bad calibration practice** β transitioning into VR_3PT without aligning your arms to the robot's current pose. The robot may not jump immediately, but will exhibit erratic and dangerous motion as soon as you move.
<figure style="margin: 1em 0;">
<video width="100%" autoplay loop muted playsinline style="border-radius: 8px;">
<source src="../_static/teleop_calib/BAD_Calib_VR3PT_web.mp4" type="video/mp4">
</video>
<figcaption style="text-align: center; font-style: italic; margin-top: 0.5em;">Bad practice: entering VR_3PT without arm alignment causes erratic, unsafe motion.</figcaption>
</figure>
```{admonition} DANGER β Mode-Switching Safety
:class: danger
**Before switching into POSE or VR_3PT**, always align your body with the robot's current pose first.
**Recovery from bad VR_3PT calibration:**
1. Freeze the upper body β switch back via **Left Stick Click**.
2. Re-align your arms with the robot's current (possibly distorted) pose.
3. Switch to **POSE** mode (**A+X**) to reset.
```
Below is the **recovery procedure** β if you accidentally enter a badly calibrated VR_3PT state, freeze the upper body (Left Stick Click back), then switch to POSE mode (A+X) to reset safely.
<figure style="margin: 1em 0;">
<video width="100%" autoplay loop muted playsinline style="border-radius: 8px;">
<source src="../_static/teleop_calib/BAD_Calib_VR3PT_recover_web.mp4" type="video/mp4">
</video>
<figcaption style="text-align: center; font-style: italic; margin-top: 0.5em;">Recovery from bad VR_3PT calibration: freeze upper body β re-align β switch to POSE mode.</figcaption>
</figure>
### Quick-Start Cheatsheet
| Action | Button | Notes |
|---|---|---|
| **Start / Stop policy** | **A+B+X+Y** | First press: engage + CALIB_FULL. Again: emergency stop β OFF. |
| **Toggle POSE** | **A+X** | Switches between PLANNER β POSE. OR from VR_3PT (entered via PLANNER) β POSE. |
| **Toggle PLANNER_FROZEN_UPPER** | **B+Y** | Switches between POSE β PLANNER_FROZEN_UPPER. OR from VR_3PT (entered via PLANNER_FROZEN_UPPER) β POSE. |
| **Toggle VR_3PT** | **Left Stick Click** | From any Planner mode β VR_3PT (triggers CALIB). Click again to return. |
| **Hand grasp** | **Trigger** (per hand) | Controls the corresponding hand's grasp. |
### Joystick Controls (Planner Modes)
Active in **PLANNER**, **PLANNER_FROZEN_UPPER**, and **VR_3PT**:
| Input | Function |
|---|---|
| **Left Stick** | Move direction (forward / backward / strafe) |
| **Right Stick (horizontal)** | Yaw / heading (continuous accumulation) |
| **A + B** | Next locomotion mode |
| **X + Y** | Previous locomotion mode |
**Locomotion modes** (cycled via A+B / X+Y):
| ID | Mode |
|---|---|
| 0 | Idle [DEFAULT] |
| 1 | Slow Walk |
| 2 | Walk |
| 3 | Run |
| 4 | Squat |
| 5 | Kneel (two legs) |
| 6 | Kneel |
| 7 | Lying face-down |
| 8 | Crawling |
| 9β16 | Boxing variants (idle, walk, punches, hooks) |
| 17 | Forward Jump |
| 18 | Stealth Walk |
| 19 | Injured Walk |
---
## Emergency Stop
| Method | Action |
|---|---|
| **PICO controllers** | Press **A+B+X+Y** simultaneously β OFF |
| **Keyboard** (C++ terminal) | Press **`O`** for immediate stop |
---
## Step-by-Step: Teleop on Real Robot
```{admonition} Safety Warning
:class: danger
Only proceed once you can smoothly control the robot in simulation and are comfortable with emergency stops. **Terminate any running `run_sim_loop.py` process first** β simultaneous sim and real instances will conflict.
```
The real-robot workflow uses **two terminals** (no MuJoCo simulator).
### Terminal 1 β C++ Deployment (Real Robot)
From `gear_sonic_deploy/`:
```bash
cd gear_sonic_deploy
source scripts/setup_env.sh
# 'real' auto-detects the robot network interface (192.168.123.x).
# If auto-detection fails, pass the G1's IP directly:
# ./deploy.sh --input-type zmq_manager <G1-IP>
./deploy.sh --input-type zmq_manager real
# Wait until you see "Init done"
```
**Isaac Teleop / CloudXR alternative** (**G1 + Thor backpack only**) β run the C++ deployment from the project's ROS2 docker container instead of bare metal:
```bash
cd gear_sonic_deploy
export TensorRT_ROOT=$HOME/TensorRT # only if not already in ~/.bashrc
./docker/run-ros2-dev.sh
# inside the container (setup_env.sh is sourced automatically):
just build # first run only
./deploy.sh --input-type zmq_manager real
# Wait until you see "Init done"
```
```{note}
If the teleop script (Terminal 2) runs on a different machine, add `--zmq-host <IP-of-teleop-machine>` so the C++ side knows where the ZMQ publisher is.
```
### Terminal 2 β PICO Teleop Streamer
From the **repo root**:
```bash
# bash install_scripts/install_pico.sh
source .venv_teleop/bin/activate
python gear_sonic/scripts/pico_manager_thread_server.py --manager
# If running offboard with a display, add visualization:
# --vis_vr3pt --vis_smpl
```
**Isaac Teleop / CloudXR alternative** (**G1 + Thor backpack only**) β in-process CloudXR runtime via `isaacteleop[cloudxr]`, no XRoboToolKit PC service required:
```bash
source .venv_teleop/bin/activate
python gear_sonic/scripts/pico_manager_thread_server.py --manager --input-source isaac-teleop
```
```{note}
Update the IP in the PICO's XRoboToolKit app to match this machine before starting the default PICO path. For Isaac Teleop, make sure the headset is connected to the in-process CloudXR runtime β see [Isaac Teleop Setup](isaac_teleop_publisher_setup.md).
```
Follow the same start sequence: calibration pose β **A+B+X+Y** β **A+X** for POSE mode. See [Complete PICO Controls](#pico-controls) for all available commands.
|