Browse Source
Phase 4: DDS bridge debugging, GR00T-WBC real robot prep, Vision Pro telepresence research
Phase 4: DDS bridge debugging, GR00T-WBC real robot prep, Vision Pro telepresence research
- Diagnosed DDS multicast blocked by UFW firewall on GB10 (root cause) - Confirmed DDS active inside robot (342 pkts/4s from locomotion computer) - Documented SSH credentials (unitree@192.168.123.164, pw: 123) - Created real robot launch script and DDS test script - Researched Vision Pro integration paths (xr_teleoperate WebXR, VisionProTeleop native) - Documented GR00T-WBC decoupled architecture and CONTROL_GOAL_TOPIC integration point - Added CURRENT-STATE.md handoff document for session continuity - Updated networking-comms, open-questions, motion-retargeting, learning-and-ai context files Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>master
12 changed files with 733 additions and 7 deletions
-
3CLAUDE.md
-
145CURRENT-STATE.md
-
45context/gb10-offboard-compute.md
-
40context/learning-and-ai.md
-
28context/motion-retargeting.md
-
37context/networking-comms.md
-
99context/open-questions.md
-
32context/whole-body-control.md
-
108phases/phase-3-groot-wbc-deployment.md
-
71reference/glossary.yaml
-
98scripts/dds_test.py
-
34scripts/launch_real.sh
@ -0,0 +1,145 @@ |
|||
# Current State — 2026-02-15 |
|||
|
|||
Handoff document for continuing work from another machine. |
|||
|
|||
--- |
|||
|
|||
## What's Working |
|||
|
|||
### MuJoCo Playground RL Training (Complete) |
|||
- **Location:** GB10 (`~/mujoco_training/`) |
|||
- **Result:** 200M-step locomotion policy trained. Reward: -6.4 → +12.1 |
|||
- **Time:** 3:08:37, ~17.9K steps/sec on Blackwell GPU |
|||
- **Checkpoint:** `~/mujoco_training/checkpoints/G1JoystickFlatTerrain-20260215-090148-full/params.pkl` |
|||
- **Scripts:** `train_g1.py`, `play_g1.py` (untested), `monitor.sh` |
|||
|
|||
### GR00T-WBC Simulation (Complete) |
|||
- **Location:** GB10 (`~/GR00T-WholeBodyControl/`) |
|||
- **Status:** Walking robot in MuJoCo sim, keyboard controlled (w/s/a/d), 50 Hz, 3.5ms/iter |
|||
- **Launch:** `./launch_sim.sh` or `python3 run_g1_control_loop.py` |
|||
- **Viz:** NoMachine virtual desktop or web MJPEG viewer (`launch_with_web_viewer.py`) |
|||
|
|||
### Network Bridge GB10 ↔ G1 (90% — needs final verification) |
|||
- **GB10 IP:** 10.0.0.68 (primary) + 192.168.123.100/24 (secondary on enP7s7) |
|||
- **Ping:** <1ms to 192.168.123.161 (locomotion) and .164 (Jetson) |
|||
- **DDS confirmed alive inside robot:** 342 multicast packets/4s from locomotion computer |
|||
- **Root cause found:** UFW firewall was blocking incoming DDS multicast |
|||
- **Fix applied:** User disabled UFW (`sudo ufw disable`) |
|||
- **NOT YET VERIFIED:** Robot was disconnected before we could confirm rt/lowstate data flows end-to-end |
|||
|
|||
--- |
|||
|
|||
## What's Next (In Priority Order) |
|||
|
|||
### 1. Verify DDS Connection (5 min) |
|||
When robot is reconnected to the network: |
|||
```bash |
|||
# On GB10: |
|||
sudo ip addr add 192.168.123.100/24 dev enP7s7 # if not persistent |
|||
sudo ufw status # confirm disabled or allows 192.168.123.0/24 |
|||
cd ~/GR00T-WholeBodyControl && source .venv/bin/activate |
|||
python3 /tmp/dds_test.py |
|||
``` |
|||
This tests ping → DDS multicast → SDK rt/lowstate in sequence. |
|||
|
|||
### 2. Test GR00T-WBC on Real Robot (30 min) |
|||
Once DDS works: |
|||
1. Put robot on harness/stand |
|||
2. Enter debug mode: L2+R2 on wireless remote while robot is in damping state |
|||
3. Launch: `./launch_real.sh` (runs `--interface real`, auto-detects enP7s7) |
|||
4. Keyboard: `]` = enable walk, `w/s` = fwd/back, `a/d` = strafe, `q/e` = rotate |
|||
5. **WARNING:** No wireless remote control under GR00T-WBC — keyboard only |
|||
|
|||
### 3. Install xr_teleoperate for Vision Pro (1-2 hrs) |
|||
Fastest path to telepresence — Vision Pro connects via Safari (WebXR), no app needed: |
|||
```bash |
|||
# On GB10: |
|||
cd ~ && git clone https://github.com/unitreerobotics/xr_teleoperate.git |
|||
# Follow their install instructions (needs Pinocchio, TeleVuer) |
|||
# Generate SSL certs for Vision Pro HTTPS connection |
|||
# Vision Pro opens: https://<gb10-ip>:8012 |
|||
``` |
|||
**Limitation:** xr_teleoperate bypasses GR00T-WBC and uses the stock controller for legs. |
|||
|
|||
### 4. Build VisionProTeleop → GR00T-WBC Bridge (2-4 hrs) |
|||
Higher quality path — native visionOS app with RL-based balance: |
|||
1. Install VisionProTeleop's "Tracking Streamer" app on Vision Pro (App Store) |
|||
2. `pip install avp_stream` on GB10 |
|||
3. Write bridge (~100-200 lines Python): `avp_stream` → wrist poses → Pinocchio IK → `ControlPolicy/upper_body_pose` ROS2 topic |
|||
4. Run alongside GR00T-WBC control loop |
|||
|
|||
### 5. Unified WBC Training (Saved for Later) |
|||
Plan at `plans/eager-shimmying-raccoon.md`. Trains a policy that handles walking + arbitrary arm poses + balance simultaneously. ~400M steps, ~5.5 hrs on GB10. |
|||
|
|||
--- |
|||
|
|||
## Key Architecture: GR00T-WBC |
|||
|
|||
``` |
|||
LOWER BODY (12 DOF legs) UPPER BODY (17 DOF waist+arms) |
|||
RL neural network (ONNX) Open-loop interpolation |
|||
Balance.onnx / Walk.onnx Targets from external source |
|||
Auto-switches based on Receives via ROS2 topic: |
|||
velocity command magnitude "ControlPolicy/upper_body_pose" |
|||
\ / |
|||
--> Merged 29-DOF joint positions --> DDS rt/lowcmd --> Motors |
|||
``` |
|||
|
|||
**Integration point for ANY telepresence/mocap system:** Publish to `ControlPolicy/upper_body_pose` ROS2 topic with: |
|||
- `target_upper_body_pose`: 17 joint angles (3 waist + 7 left arm + 7 right arm) |
|||
- `navigate_cmd`: `[vx, vy, wz]` velocity command (optional, overrides keyboard) |
|||
|
|||
--- |
|||
|
|||
## Vision Pro Telepresence Options |
|||
|
|||
| Path | What | Needs App? | Uses GR00T-WBC? | Status | |
|||
|------|------|:---:|:---:|--------| |
|||
| xr_teleoperate | WebXR via Safari | No | No (stock SDK) | Not yet installed | |
|||
| VisionProTeleop | Native visionOS app (MIT) | Yes (App Store) | Yes (via bridge) | Not yet installed | |
|||
| iPhone streamer | Socket.IO replication | Custom app | Yes (built-in) | Protocol documented | |
|||
|
|||
**User has:** Apple Vision Pro + Meta Quest 3 |
|||
**Decision:** Vision Pro selected as primary device |
|||
|
|||
--- |
|||
|
|||
## Files on GB10 |
|||
|
|||
| File | Purpose | |
|||
|------|---------| |
|||
| `~/GR00T-WholeBodyControl/` | GR00T-WBC (patched for aarch64) | |
|||
| `~/GR00T-WholeBodyControl/launch_real.sh` | Real robot launcher (`--interface real`) | |
|||
| `~/GR00T-WholeBodyControl/launch_sim.sh` | Simulation launcher | |
|||
| `~/GR00T-WholeBodyControl/launch_with_web_viewer.py` | Sim + MJPEG web viewer | |
|||
| `~/GR00T-WholeBodyControl/gr00t_wbc/.../g1_29dof_gear_wbc_real.yaml` | Config copy with INTERFACE=enP7s7 | |
|||
| `~/mujoco_training/train_g1.py` | MuJoCo Playground RL training | |
|||
| `~/mujoco_training/play_g1.py` | Policy visualization (untested) | |
|||
| `~/mujoco_training/checkpoints/...full/params.pkl` | Trained locomotion policy | |
|||
| `/tmp/dds_test.py` | Quick DDS connectivity test | |
|||
| `/tmp/keysender.py` | ROS keyboard publisher for remote terminals | |
|||
|
|||
--- |
|||
|
|||
## Credentials & Network |
|||
|
|||
| Target | Address | User | Password | |
|||
|--------|---------|------|----------| |
|||
| GB10 | 10.0.0.68 | mitchaiet | (SSH key) | |
|||
| G1 Jetson | 192.168.123.164 | unitree | 123 | |
|||
| G1 Locomotion | 192.168.123.161 | — | Not SSH-accessible | |
|||
|
|||
**GB10 interface:** enP7s7 (primary: 10.0.0.68 DHCP, secondary: 192.168.123.100/24 manual) |
|||
**DDS:** Domain 0, CycloneDDS 0.10.2, `ChannelFactoryInitialize(0, "enP7s7")` |
|||
**Firewall:** UFW was disabled. May need re-disabling after reboot. |
|||
|
|||
--- |
|||
|
|||
## Context System Updates Made This Session |
|||
|
|||
- `context/networking-comms.md` — Added §6: GB10 ↔ G1 DDS bridge (topology, setup, debugging findings, SSH creds) |
|||
- `context/open-questions.md` — Updated DDS relay question, updated Vision Pro mocap question, added "Vision Pro Telepresence Integration (Phase 5)" section, documented wireless remote answer |
|||
- `context/motion-retargeting.md` — Added §6: Apple Vision Pro telepresence paths (xr_teleoperate, VisionProTeleop, GR00T-WBC integration point) |
|||
- `context/learning-and-ai.md` — §8 MuJoCo Playground pipeline (added in prior session, still current) |
|||
- `CLAUDE.md` — Added Phase 4 to history |
|||
- `plans/eager-shimmying-raccoon.md` — Unified WBC training plan (from prior session, still current) |
|||
@ -0,0 +1,108 @@ |
|||
# Phase 3: GR00T-WBC Deployment on GB10 |
|||
|
|||
**Date:** 2026-02-14 |
|||
**Goal:** Deploy and validate GR00T-WBC whole-body control framework on Dell Pro Max GB10 for G1 humanoid simulation |
|||
|
|||
--- |
|||
|
|||
## Summary |
|||
|
|||
Successfully deployed NVIDIA's GR00T-WholeBodyControl on the GB10 (aarch64, Ubuntu 24.04, Blackwell GPU). Identified and fixed 4 critical blockers. Achieved working simulation with walking robot controlled via keyboard. Established remote visualization via NoMachine and web-based MJPEG streaming. |
|||
|
|||
## Key Achievements |
|||
|
|||
1. **GR00T-WBC running in simulation** — Both Balance and Walk ONNX policies loaded and executing at 50 Hz |
|||
2. **Walking robot** — WASD keyboard control verified: forward, backward, strafe, rotate |
|||
3. **Performance validated** — 3.5 ms/iteration (17.5% of 20ms budget) in sync mode |
|||
4. **Remote visualization** — NoMachine virtual desktop + web MJPEG viewer |
|||
5. **4 critical bugs identified and fixed** on aarch64 platform |
|||
|
|||
## Critical Fixes |
|||
|
|||
### Fix 1: CycloneDDS aarch64 Buffer Overflow (ROOT CAUSE) |
|||
- **File:** `unitree_sdk2py/core/channel_config.py` |
|||
- **Problem:** `<Tracing>` XML section triggers glibc FORTIFY_SOURCE buffer overflow specifically on ARM64 |
|||
- **Discovery:** Isolated via `Domain(0)` (works) vs `Domain(0, config_with_tracing)` (crashes) vs `Domain(0, config_without_tracing)` (works) |
|||
- **Fix:** Remove `<Tracing>` section from both `ChannelConfigHasInterface` and `ChannelConfigAutoDetermine` |
|||
- **Impact:** Without this fix, nothing in the Unitree SDK works on aarch64 |
|||
|
|||
### Fix 2: ROS2 Python Package Path |
|||
- **File:** `.venv/lib/python3.12/site-packages/ros2.pth` (created) |
|||
- **Problem:** ROS2 packages at `/opt/ros/jazzy/lib/python3.12/site-packages/` not visible in venv |
|||
- **Fix:** Create `.pth` file with that path |
|||
- **Impact:** sensor_msgs, std_msgs, rclpy all accessible |
|||
|
|||
### Fix 3: ROS2 Shared Library Path |
|||
- **Problem:** rclpy native libraries (librcl_action.so etc.) not found |
|||
- **Fix:** `export LD_LIBRARY_PATH=/opt/ros/jazzy/lib:$LD_LIBRARY_PATH` |
|||
|
|||
### Fix 4: Sync Mode Sim Thread Check |
|||
- **File:** `run_g1_control_loop.py` line 211 |
|||
- **Problem:** Code checks `env.sim.sim_thread.is_alive()` but in sync mode no thread exists |
|||
- **Fix:** Add `not config.sim_sync_mode` guard to the check |
|||
|
|||
## Architecture Findings |
|||
|
|||
### Pre-trained ONNX Policies |
|||
- **Balance:** 516-dim obs → 15-dim action (lower body joint targets) |
|||
- **Walk:** Same dimensions, velocity-conditioned locomotion |
|||
- **Training:** PPO in Isaac Lab, domain randomization, zero-shot sim-to-real (exact recipe not published) |
|||
- **Not mocap-based:** Command-conditioned (velocity tracking), not motion imitation |
|||
|
|||
### Keyboard Control Architecture |
|||
- `KeyboardDispatcher` (raw) uses `sshkeyboard` library — fails in remote terminals |
|||
- `ROSKeyboardDispatcher` subscribes to `/keyboard_input` topic — works via separate publisher |
|||
- Dispatchers call `handle_keyboard_button()` on registered listeners (policy, env, e-stop) |
|||
- Walk policy: `]`=enable, `w/s`=fwd/back (+/-0.2 m/s per press), `a/d`=strafe, `q/e`=rotate, `z`=zero |
|||
|
|||
### Visualization Challenges (Headless GB10) |
|||
Attempted 5 approaches for remote visualization: |
|||
|
|||
| Approach | Result | Issue | |
|||
|----------|--------|-------| |
|||
| x11vnc on physical display :0 | Black screen | No monitor connected, GPU output disabled | |
|||
| x11vnc on Xvfb :99 | Static frame | OpenGL renders to own framebuffer, x11vnc reads X11 pixmap | |
|||
| NoMachine physical shadow | Black screen | Shadowing black physical display | |
|||
| NoMachine virtual desktop | Works but GLFW freezes | GLFW passive viewer thread stalls after seconds | |
|||
| Web MJPEG streaming | Best solution | Offscreen renderer → JPEG → HTTP, no X11 dependency | |
|||
|
|||
### DDS/ROS2 Coexistence |
|||
- CycloneDDS system (0.10.4) and ROS2 (0.10.5) are ABI-incompatible |
|||
- FastRTPS is the default RMW in ROS2 Jazzy — avoids CycloneDDS version conflict |
|||
- Second ChannelFactory init from BaseSimulator fails gracefully (try/except) |
|||
- `CYCLONEDDS_URI` environment variable controls Unitree SDK's DDS config |
|||
|
|||
## Software Installed on GB10 |
|||
|
|||
| Package | Purpose | |
|||
|---------|---------| |
|||
| GR00T-WBC | Whole-body control framework | |
|||
| NoMachine 9.3.7 | Remote desktop (NX protocol) | |
|||
| Sunshine 2025.924 | Game streaming (NVENC) — installed but Moonlight client unstable | |
|||
| x11vnc | VNC server — limited use (can't capture OpenGL) | |
|||
| Xvfb | Virtual framebuffer for headless rendering | |
|||
| openbox | Lightweight window manager for Xvfb | |
|||
|
|||
## Files Created/Modified on GB10 |
|||
|
|||
| File | Action | Purpose | |
|||
|------|--------|---------| |
|||
| `channel_config.py` | Modified | Removed Tracing XML (buffer overflow fix) | |
|||
| `.venv/.../ros2.pth` | Created | ROS2 Python path | |
|||
| `run_g1_control_loop.py` | Modified | Sync mode sim thread guard | |
|||
| `launch_sim.sh` | Created | Convenience launcher | |
|||
| `launch_with_web_viewer.py` | Created | Launcher with web MJPEG streaming | |
|||
| `web_viewer.py` | Created | MuJoCo offscreen → MJPEG HTTP server | |
|||
| `/tmp/keysender.py` | Created | ROS keyboard publisher for remote control | |
|||
| `/etc/gdm3/custom.conf` | Modified | Auto-login enabled | |
|||
| `/etc/x11vnc.pass` | Modified | VNC password set | |
|||
| Firewall (ufw) | Modified | Opened ports 5900, 4000, 47984-47990, 8080 | |
|||
|
|||
## Next Steps |
|||
|
|||
1. **Get web viewer working** — test `launch_with_web_viewer.py` for smooth browser-based visualization |
|||
2. **Connect mocap** — webcam → pose estimation → upper body teleop commands |
|||
3. **Network bridge to G1** — connect GB10 to robot's 192.168.123.0/24 subnet |
|||
4. **Deploy to real robot** — switch `--interface sim` to `--interface real` |
|||
5. **Push recovery testing** — benchmark stock vs. GR00T-WBC push robustness |
|||
6. **Custom RL training** — use Isaac Lab to train custom policies with perturbation curriculum |
|||
@ -0,0 +1,98 @@ |
|||
#!/usr/bin/env python3 |
|||
"""Quick DDS connectivity test for G1 robot. |
|||
Run this on the GB10 after connecting the robot to the network. |
|||
Usage: python3 dds_test.py [interface_name] |
|||
""" |
|||
import sys |
|||
import time |
|||
import os |
|||
import subprocess |
|||
import socket |
|||
import struct |
|||
|
|||
def main(): |
|||
# Auto-detect or use provided interface |
|||
iface = sys.argv[1] if len(sys.argv) > 1 else None |
|||
if iface is None: |
|||
result = subprocess.run(['ip', '-o', '-4', 'addr', 'show'], capture_output=True, text=True) |
|||
for line in result.stdout.splitlines(): |
|||
if '192.168.123' in line: |
|||
iface = line.split()[1] |
|||
break |
|||
|
|||
if iface is None: |
|||
print('ERROR: No interface with 192.168.123.x found. Add one with:') |
|||
print(' sudo ip addr add 192.168.123.100/24 dev <interface>') |
|||
sys.exit(1) |
|||
|
|||
# Get our IP on that interface |
|||
result = subprocess.run(['ip', '-o', '-4', 'addr', 'show', iface], capture_output=True, text=True) |
|||
our_ip = None |
|||
for word in result.stdout.split(): |
|||
if '192.168.123' in word: |
|||
our_ip = word.split('/')[0] |
|||
break |
|||
|
|||
print(f'[1/4] Interface: {iface} ({our_ip})', flush=True) |
|||
|
|||
# Step 1: Ping test |
|||
print('[2/4] Ping test...', flush=True) |
|||
for ip in ['192.168.123.161', '192.168.123.164']: |
|||
r = subprocess.run(['ping', '-c', '1', '-W', '1', ip], capture_output=True, text=True) |
|||
status = 'OK' if r.returncode == 0 else 'FAIL' |
|||
print(f' {ip}: {status}', flush=True) |
|||
|
|||
# Step 2: Multicast receive test |
|||
print('[3/4] DDS multicast discovery (5s)...', flush=True) |
|||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) |
|||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) |
|||
sock.bind(('', 7400)) |
|||
mreq = struct.pack('4s4s', socket.inet_aton('239.255.0.1'), socket.inet_aton(our_ip)) |
|||
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) |
|||
sock.settimeout(1.0) |
|||
count = 0 |
|||
sources = set() |
|||
start = time.time() |
|||
while time.time() - start < 5: |
|||
try: |
|||
data, addr = sock.recvfrom(4096) |
|||
count += 1 |
|||
sources.add(addr[0]) |
|||
except socket.timeout: |
|||
pass |
|||
sock.close() |
|||
robot_sources = {s for s in sources if s.startswith('192.168.123')} |
|||
print(f' {count} packets from {sources}', flush=True) |
|||
if robot_sources: |
|||
print(f' Robot DDS discovered: {robot_sources}', flush=True) |
|||
else: |
|||
print(' WARNING: No DDS multicast from robot!', flush=True) |
|||
print(' Check: sudo ufw disable OR sudo ufw allow from 192.168.123.0/24', flush=True) |
|||
sys.exit(1) |
|||
|
|||
# Step 3: SDK subscriber test |
|||
print('[4/4] Unitree SDK rt/lowstate test (8s)...', flush=True) |
|||
try: |
|||
sys.path.insert(0, '/home/mitchaiet/GR00T-WholeBodyControl/.venv/lib/python3.12/site-packages') |
|||
from unitree_sdk2py.core.channel import ChannelFactoryInitialize, ChannelSubscriber |
|||
from unitree_sdk2py.idl.unitree_hg.msg.dds_ import LowState_ |
|||
ChannelFactoryInitialize(0, iface) |
|||
sub = ChannelSubscriber('rt/lowstate', LowState_) |
|||
sub.Init() |
|||
for i in range(16): |
|||
msg = sub.Read() |
|||
if msg is not None: |
|||
gyro = msg.imu_state.gyroscope |
|||
print(f' GOT rt/lowstate! IMU gyro: [{gyro[0]:.4f}, {gyro[1]:.4f}, {gyro[2]:.4f}]', flush=True) |
|||
print(f' Motor states: {len(msg.motor_state)} joints', flush=True) |
|||
print('\n=== ALL TESTS PASSED ===', flush=True) |
|||
os._exit(0) |
|||
time.sleep(0.5) |
|||
print(' FAIL: No data on rt/lowstate after 8s', flush=True) |
|||
print(' DDS discovery works but topic data not received', flush=True) |
|||
except Exception as e: |
|||
print(f' SDK error: {e}', flush=True) |
|||
os._exit(1) |
|||
|
|||
if __name__ == '__main__': |
|||
main() |
|||
@ -0,0 +1,34 @@ |
|||
#!/bin/bash |
|||
# Launch GR00T-WBC on real G1 robot via GB10 |
|||
# Prerequisites: |
|||
# 1. Robot powered on and connected via Ethernet (192.168.123.0/24 subnet) |
|||
# 2. GB10 has 192.168.123.100/24 on enP7s7: sudo ip addr add 192.168.123.100/24 dev enP7s7 |
|||
# 3. UFW disabled or allows traffic from 192.168.123.0/24 |
|||
# 4. Robot in debug mode (L2+R2 while in damping state on harness) for motor control |
|||
|
|||
set -e |
|||
cd ~/GR00T-WholeBodyControl |
|||
source .venv/bin/activate |
|||
|
|||
echo "=== GR00T-WBC Real Robot Launch ===" |
|||
echo "" |
|||
echo "[1/2] Checking network..." |
|||
if ping -c 1 -W 1 192.168.123.161 > /dev/null 2>&1; then |
|||
echo " Locomotion computer (192.168.123.161): OK" |
|||
else |
|||
echo " ERROR: Cannot reach 192.168.123.161" |
|||
echo " Fix: sudo ip addr add 192.168.123.100/24 dev enP7s7" |
|||
exit 1 |
|||
fi |
|||
|
|||
echo "[2/2] Launching GR00T-WBC (real mode)..." |
|||
echo " --interface real (auto-detects enP7s7 via 192.168.123.x)" |
|||
echo " Controls: ] = enable walk, w/s = fwd/back, a/d = strafe, q/e = rotate, z = zero" |
|||
echo " WARNING: Robot must be on harness + debug mode (L2+R2) before enabling walk!" |
|||
echo "" |
|||
|
|||
export LD_LIBRARY_PATH=/opt/ros/jazzy/lib:$LD_LIBRARY_PATH |
|||
|
|||
python3 gr00t_wbc/control/main/teleop/run_g1_control_loop.py \ |
|||
--interface real \ |
|||
"$@" |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue