feat: package TG3 TS1P OmniSocket teleoperation

This commit is contained in:
2026-08-07 16:13:41 +08:00
commit 57e582e1d7
24 changed files with 4055 additions and 0 deletions

View File

@@ -0,0 +1,132 @@
#!/usr/bin/env python3
"""Offline tests for the EAI teleoperation session gate."""
from __future__ import annotations
import importlib.util
import json
from pathlib import Path
from types import ModuleType, SimpleNamespace
import sys
import unittest
fake_omnisocket = ModuleType("omnisocket")
fake_omnisocket.CONTROL_DEFAULTS = {}
fake_omnisocket.MSG_TYPE_ERROR = 5
fake_omnisocket.Session = object
sys.modules.setdefault("omnisocket", fake_omnisocket)
module_path = Path(__file__).with_name("omnisocket_xtele_sender.py")
spec = importlib.util.spec_from_file_location("omnisocket_xtele_sender", module_path)
assert spec is not None and spec.loader is not None
sender_module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(sender_module)
XteleSender = sender_module.XteleSender
def buttons(pressed: bool) -> dict[str, object]:
return {
"button": {
"left": [False, False, pressed],
"right": [False, False, pressed],
},
"hand": {"position": {"left": 0.0, "right": 0.0}},
}
class SessionGateTest(unittest.TestCase):
def setUp(self) -> None:
args = SimpleNamespace(
start_stop_hold_s=3.0,
start_marker_frames=50,
source_timeout_s=0.25,
max_feedback_age_ms=500.0,
max_pending_frames=100,
)
self.sender = XteleSender(args)
def test_start_and_stop_each_require_a_new_continuous_hold(self) -> None:
# Boot requires a release, so a button held across service restart
# cannot start a session.
self.assertIsNone(self.sender._update_teleop_gate(0.0, buttons(True)))
self.assertIsNone(self.sender._update_teleop_gate(0.1, buttons(False)))
self.assertIsNone(self.sender._update_teleop_gate(1.0, buttons(True)))
self.assertIsNone(self.sender._update_teleop_gate(3.99, buttons(True)))
self.assertEqual(
self.sender._update_teleop_gate(4.01, buttons(True)), "start"
)
first_id = self.sender.teleop_session_id
self.assertTrue(self.sender.teleop_active)
self.assertIsNotNone(first_id)
# Keeping the same hold cannot immediately toggle the new session off.
self.assertIsNone(self.sender._update_teleop_gate(8.0, buttons(True)))
self.assertTrue(self.sender.teleop_active)
self.assertIsNone(self.sender._update_teleop_gate(8.1, buttons(False)))
self.assertIsNone(self.sender._update_teleop_gate(9.0, buttons(True)))
self.assertIsNone(self.sender._update_teleop_gate(11.99, buttons(True)))
self.assertEqual(
self.sender._update_teleop_gate(12.01, buttons(True)), "stop"
)
self.assertFalse(self.sender.teleop_active)
self.assertEqual(self.sender.teleop_session_id, first_id)
def test_releasing_during_hold_resets_the_timer(self) -> None:
self.sender._update_teleop_gate(0.0, buttons(False))
self.sender._update_teleop_gate(1.0, buttons(True))
self.sender._update_teleop_gate(2.0, buttons(False))
self.sender._update_teleop_gate(3.0, buttons(True))
self.assertIsNone(self.sender._update_teleop_gate(5.9, buttons(True)))
self.assertEqual(
self.sender._update_teleop_gate(6.01, buttons(True)), "start"
)
def test_transport_metadata_is_overwritten(self) -> None:
data = buttons(False)
data["tg3_transport"] = {
"protocol_version": 999,
"session_id": "forged",
"session_state": "stop",
}
payload, merged = self.sender._build_payload(
data,
None,
"a" * 32,
7,
"start",
)
self.assertFalse(merged)
metadata = json.loads(payload)["tg3_transport"]
self.assertEqual(metadata["protocol_version"], 2)
self.assertEqual(metadata["session_id"], "a" * 32)
self.assertEqual(metadata["session_seq"], 7)
self.assertEqual(metadata["session_state"], "start")
def test_stale_or_backlogged_transport_is_rejected(self) -> None:
class FakeSession:
def __init__(self, feedback_age: int, pending: int) -> None:
self.feedback_age = feedback_age
self.pending = pending
def stats(self) -> dict[str, int]:
return {"connected": 1, "registered": 1}
def kcp_stats(self) -> dict[str, int]:
return {
"snd_queue": self.pending,
"snd_buffer": 0,
"last_feedback_age_ms": self.feedback_age,
}
self.sender.session_connected_at = 0.0
self.sender.session = FakeSession(600, 0)
self.assertIn("feedback stale", self.sender._session_unhealthy_reason())
self.sender.session = FakeSession(1, 101)
self.assertIn("pending queue", self.sender._session_unhealthy_reason())
if __name__ == "__main__":
unittest.main()