# Robot Modifications Log — Pre-Wipe Snapshot **Date:** 2026-02-17 **Purpose:** Document all changes made to the robot before resetting to clean upstream code. --- ## 1. xr_teleoperate (~/xr_teleoperate on robot) **Upstream:** https://github.com/unitreerobotics/xr_teleoperate.git **Robot commit:** 9fadc51 (upstream HEAD) ### Modified files (tracked, dirty): #### teleop/teleop_hand_and_arm.py - Added `import numpy as np` at top - Added `--avp-ip` argparse flag (Vision Pro IP for avp_stream bypass) - Added `--debug` argparse flag (enables per-frame file logging) - Added `teleop_logger` import and `setup_teleop_logging()` call - Added conditional: if `--avp-ip` given, uses `AVPStreamWrapper` instead of `TeleVuerWrapper` - Added per-frame IK debug logging block (writes to `/tmp/teleop_debug_*.log`) - Added `[IK_DBG]` print every 30 frames (sol_q, cur_q, delta) #### teleop/robot_control/robot_arm_ik.py - **IK cost function:** zeroed rotation cost (`0 * self.rotation_cost`) for position-only mode — applied to ALL 4 IK classes (G1_29, G1_23, H1_2, H1) - Added `self.last_solve_info = {}` dict to all 4 classes - Added solve info capture in try/except blocks (status, raw_sol, cost on success; status, error on fail) ### Untracked files (our additions): - `teleop/avp_stream_wrapper.py` — Drop-in AVPStream wrapper using gRPC (Tracking Streamer app). Full coordinate transform pipeline matching TeleVuerWrapper. - `teleop/teleop_logger.py` — Debug logging utility (setup_teleop_logging, fmt_arr, fmt_pos, fmt_rpy, rot_to_euler) - `teleop/rotation_diagnostic.py` — Diagnostic script for rotation analysis - `teleop/test_avp_stream.py` — Test script for avp_stream connectivity - `teleop/robot_control/robot_arm_ik.py.bak_debug` — Backup before debug changes - `teleop/teleop_hand_and_arm.py.bak_debug` — Backup before debug changes --- ## 2. vuer package (~/miniforge3/envs/tv/lib/python3.10/site-packages/vuer/) **Package:** vuer 0.0.60 (pip install) **Upstream:** https://github.com/vuer-ai/vuer ### Patches applied (with .bak backups): #### base_protocol.py (aiohttp, NOT vuer) **File:** `~/miniforge3/envs/tv/lib/python3.10/site-packages/aiohttp/base_protocol.py` **Bug:** `assert self._paused` in `resume_writing()` crashes on SSL WebSocket connections (aiohttp 3.10.5, Python 3.10, aarch64) **Fix:** Changed line 36 from `assert self._paused` to `if not self._paused: return` **Backup:** `.bak` exists #### chunk-Dd3xtWba.js (Vuer client JS bundle) **File:** `~/miniforge3/envs/tv/lib/python3.10/site-packages/vuer/client_build/assets/chunks/chunk-Dd3xtWba.js` **Bug:** `getSocketURI()` uses `window.location.hostname` (no port) for HTTPS case, causing WebSocket to connect to port 443 instead of 8012 **Fix:** Changed `wss://${window.location.hostname}` to `wss://${window.location.host}` **Backup:** `.bak` exists #### index.html (Vuer client) **File:** `~/miniforge3/envs/tv/lib/python3.10/site-packages/vuer/client_build/index.html` **Change:** Added `?cb=1771359809` cache-busting to all JS/CSS references **Backup:** `.bak` exists #### server.py (Vuer server) **File:** `~/miniforge3/envs/tv/lib/python3.10/site-packages/vuer/server.py` **Change:** Added request logging line at start of `socket_index()`: `print(f"[REQ] {request.method} {request.path_qs} upgrade=...")` **Backup:** No .bak (logging only, can be dropped) --- ## 3. Current Issue (at time of wipe) WebSocket connects then immediately disconnects in pass-through mode. 3 connect/disconnect cycles (react-use-websocket retries 3x then gives up). User sees hands (client-side WebXR) but no data flows to robot. Root cause investigation was in progress — examining Vuer's `downlink()` handler in `server.py` lines 597-670. The `downlink()` handler: 1. Creates a VuerProxy session 2. Calls `self.bound_fn(vuer_proxy)` which returns a generator 3. Calls `await generator.__anext__()` to get the first server event 4. Enters `async for msg in ws:` loop to process incoming client messages 5. When client stops sending → "websocket is now disconnected" **Hypothesis:** The pass-through handler pushes `Hands(stream=True)` then sleeps forever. The Vuer server's downlink expects the `socket_handler` (set by `@app.add_handler`) to be an async generator that yields events. If the handler is a plain async function (not a generator), the `hasattr(generator, "__anext__")` check may fail, causing it to call `next(generator)` on a coroutine, which could raise TypeError silently. --- ## 4. Key Findings to Preserve 1. **Vuer JS WebSocket port bug** — MUST fix in any vuer version used with HTTPS on non-443 port 2. **aiohttp SSL assertion bug** — MUST fix for aiohttp 3.10.5 on aarch64 3. **display-mode pass-through** is required when Vision Pro can't reach robot's internal network (192.168.123.164) for WebRTC 4. **IK rotation cost = 0** was set for position-only tracking during debugging — should be restored to original values once rotation corrections are working 5. **avp_stream_wrapper.py** is a complete working wrapper for the native Tracking Streamer pipeline (gRPC, port 12345) — should be committed as a proper feature