# TG3 OmniSocket 同构臂传输代理 链路: ```text EAI xTELE tcp://127.0.0.1:5003(原始帧) + tcp://127.0.0.1:5001(处理后的双手目标) -> 仅将 5001 hand.position 合并到 5003 -> tg3-omnisocket-sender -> KCP Hub 175.178.116.187:14049 -> tg3_local_teleop(直接 OmniSocket Session) ``` 不走公网时仍保留这条完整 sender/receiver 链路,只把 Hub 放到 EAI 本机:sender 的 `--server` 使用 `127.0.0.1:14049`,机器人 `omnisocket_server` 使用机器人可达的 EAI 局域网地址(当前为 `192.168.5.14:14049`),双方 Peer ID 不变。EAI 运行 `tg3-omnisocket-hub.service`,其 `kcpserver` 监听 UDP `0.0.0.0:14049`。 完整构建、切换、验证和回公网步骤见迁移部署指南第 6 节。纯 ZMQ 直连不是推荐主链路。 Peer ID: - 工控机:`tg3-009027fa8190-iarm` - 机器人:`tg3-009027fa8190-robot` EAI 的业务发送程序是 `omnisocket_xtele_sender.py`。它以 5003 最新帧为基础,保留双臂、 Z+C 按键及诊断字段;若 5001 的双侧 `hand.position` 在 250 ms 内有效,则合并厂家 xTELE 已处理的标量或六维 BrainCoRevo2 目标。5002 的界面事件和腰、头、腿、行走、 底盘命令不会进入机器人双臂桥。 右侧原始按键顺序是 `A/B/C`。按住右 `B` 时,sender 仍合并 5001 的左手 目标,但保留 5003 的原始右手开合量,不用 xTELE 处理后的右手目标覆盖。 这样右 B 的自定义双手长按手势还未满 1 秒时,原厂 B 处理不会让右手提前动作。 松开 B 并连续稳定释放 `0.5 s` 后,还要等新鲜 5001 右手目标连续至少 `0.25 s` 恢复到按键前基线或当前 5003 原始开合量,才恢复双侧合并;无法确认时持续使用原始 右手值,防止释放沿后的锁存/延迟目标漏入。 5001 目标的时间戳也必须不晚于当前 5003 原始帧;若两个本机 ZMQ socket 的轮询顺序 暂时颠倒,该 processed 目标会等到对应或更新的原始帧到达后才可合并。 `tg3_transport.processed_hand_sides` 记录本帧实际合并 的侧;右 B 抑制生效时还会设置 `processed_right_hand_suppressed_by_b=true`。 公网业务数据由 EAI 本地会话门控:服务启动后仍持续读取本机 5003/5001,但不发送 xTELE 帧;连续长按左 Z + 右 C 3 秒后才生成新的 128-bit `session_id` 并开始发送。 再次长按 3 秒时发送最后一帧 `stop`,等待有界 KCP 刷新后关闭 OmniSocket Session; 之后 `frames_sent/bytes_sent` 不再增长,待机既没有 xTELE 业务帧,也没有该 sender 的 底层注册/心跳。即使 Hub 离线,sender 仍持续读取本机 xTELE 并保持会话关闭。Z+C 满 3 秒后先进入 `START_PENDING`,后台连接不会阻塞本机按键采样;本次长按只尝试连接一次。 若 Hub 未启动,本次连接失败且不会发出业务帧;若机器人 Peer 不存在或首帧发送失败, 机器人不会收到控制数据且 sender 在收到错误后立即关闭。这次请求都必须稳定松开后再做 一次新的 3 秒长按;Hub 稍后恢复不会让旧请求自行启动。 任一键松开、按键数据畸形或 5003 失联也会立即取消 pending。连接成功后还必须看到两帧 时间戳最终递增且仍按住 Z+C 的新鲜 5003 数据,才发送第一帧 START,连接前排队的旧 动作不会被续发。 活动期间若 KCP 反馈超过 `500 ms` 未更新,或 `snd_queue+snd_buffer` 超过 100 帧,sender 立即作废会话并关闭 Session,从源头丢弃待发队列,防止网络恢复后回放旧动作。 5003 的源时间戳在活动期间也必须持续推进;允许相邻毫秒值短暂重复,但超过 `250 ms` 不再推进、时间戳倒退、持续畸形 JSON 或超长帧都会立即作废会话。操作员 STOP 无论最终 业务帧能否编码或发送,EAI 都会在本地关闭 Session,机器人端由输入超时保护停止并回 Home。 每个业务 JSON 的 `tg3_transport` 由 sender 强制覆盖,不能由 5003 输入伪造: ```json { "protocol_version": 2, "session_id": "32位十六进制随机值", "session_seq": 1, "session_state": "start | active | stop", "stop_reason": "operator" } ``` 当前用户服务将 `start` 连续发送 500 个源帧,避免接收端只取最新帧时错过唯一启动事件;机器人对同一 `session_id` 只做一次启动安全检查。`stop` 是该会话最后一个业务帧。服务重启、源数据 失联或网络错误都会使会话失效,恢复后必须先松开组合键,再重新长按 3 秒;pending 和 活动会话都不会自动重试或自动恢复。 `tg3_local_teleop` 内部直接拒绝非预期发送端、 乱序、格式错误以及相对本次连接最低包龄额外排队超过 300 ms 的数据;相对包龄会消除 两端系统时钟的固定偏差。机器人侧不再以 250 ms 公网输入间隔解除遥操。 机器人直接在 `tg3_local_teleop` 中接收 OmniSocket 数据,不再安装或运行单独的 `tg3-omnisocket-receiver.service`,也不再经过机器人本机 ZMQ 接收代理。