Files
TG3/docs/天工3.0本地同构臂遥操迁移部署指南.md
2026-08-10 13:19:03 +08:00

27 KiB
Raw Blame History

天工 3.0 本地同构臂遥操迁移部署指南

适用范围:天工 3.0(HBWALK)+ TS1P 同构臂。当前灵巧手实现适用于机器人实际配置为 BrainCo Revo2 的情况。

1. 迁移前先区分四种地址

地址/标识 示例 IP 变化时是否修改运行配置
新机器人 SSH 地址 nvidia@192.168.41.2 只影响安装、维护命令;公网 OmniSocket 运行时不使用这个地址
EAI SSH 地址/局域网 IP eai / 192.168.5.14 公网 OmniSocket 模式只影响运维;第 6 节纯 ZMQ 直连时必须写入机器人 iarm_endpoint
OmniSocket Hub 地址 175.178.116.187:14049 必须同时修改 EAI 发送服务和机器人 config.toml
OmniSocket Peer ID tg3-...-iarm/robot 每套链路必须成对匹配;换机器人时建议使用新的机器人唯一 ID

当前公网模式下,机器人从 Wi-Fi 换到有线、DHCP 地址变化或 EAI 局域网地址变化,通常都 不需要修改运行配置,只需保证两端能主动访问 Hub 的 UDP 端口。新的 SSH 地址需要更新到 运维命令或设备清单中。

config.toml 中保留的 iarm_endpoint 只在 transport="zmq" 时使用;当前 transport="omnisocket" 时它被忽略。不要因为机器人或 EAI IP 变化而修改这个字段。

2. 每次迁移必须确认或重做的项目

2.1 必须使用唯一、成对匹配的 Peer ID

推荐命名:

EAI 发送端:tg3-<机器人编号>-iarm
机器人接收端:tg3-<机器人编号>-robot

三处必须满足:

EAI --peer-id       == 机器人 omnisocket_expected_sender
EAI --target-peer   == 机器人 omnisocket_peer_id
EAI --server        == 机器人 omnisocket_server

同一台 EAI 同一时刻只应控制一台机器人。现有发送服务只有一个 --target-peer,迁移到 另一台机器人后要修改目标 Peer 并重启发送服务,不要用一套 TS1P 同时向多台机器人发指令。

2.2 新机器人必须重新保存 Home

不要把当前机器人的 home.joint_goal_rad 直接用于另一台机器人。即使型号相同,机械零位、 装配偏差和期望停放姿态也可能不同。

在新机器人上:

  1. 使用厂家认可的方法把双臂移动到希望保存的 Home;不要强行扳动上电电机;
  2. 确认本地遥操为 armed=false;
  3. 读取实测位置:
python3 -c 'import json; p="/home/nvidia/tg3_local_teleop/status.json"; print(json.load(open(p))["robot_arm_position_rad"])'
  1. 将输出的 14 个弧度值原样写入新机器人 /home/nvidia/tg3_local_teleop/config.toml 的 [home].joint_goal_rad;
  2. 重启服务后,先检查状态,再在净空和急停可用的条件下测试限速 Home。

2.3 必须确认灵巧手型号

grep -E 'left_hand_type|right_hand_type' /home/nvidia/data/param/hand_driver.yaml

只有左右都显示 brainco 时,才能直接使用当前 [hands] 配置。如果是 inspire 或其他 型号,不要启动灵巧手控制;消息类型、Topic 和关节映射不同,需要单独适配。

BrainCo 新手初次部署时应在默认打开状态记录:

python3 -c 'import json; p="/home/nvidia/tg3_local_teleop/status.json"; d=json.load(open(p)); print(d["robot_hand_positions"])'

当前打开端点约为 [400,400,50,50,50,50]。若新机器明显不同,需要按 normalized=(position-1)/999 重新计算 [hands].open_normalized。闭合端点也应从小幅、 低速测试开始确认,不能直接假设所有手的机械校准完全相同。

2.4 确认机器人软件接口

至少确认以下 Topic/消息仍存在:

/hric/robot/rl_state
/freq_change/arm_status
/encoder_identical_joint
/left_hand/set_motor_multi
/right_hand/set_motor_multi
/left_hand/motor_status
/right_hand/motor_status
/hric/robot/cmd_vel

若新机器人不是天工 3.0、SDK 版本接口有变化、不是 14 维双臂或不是 BrainCo Revo2,先停止 部署并适配,不要仅靠修改 IP 强行运行。

3. 场景 A:保留当前 EAI,只换机器人

这是推荐迁移方式。EAI 上的 xTELE、OmniSocketGo 和发送脚本不需要重新安装。

3.1 准备变量

以下变量只用于本次终端命令,不写入服务:

export TG3_NEW_ROBOT_IP=192.168.41.XX
export TG3_NEW_ROBOT_PEER=tg3-<新机器人编号>-robot
export TG3_IARM_PEER=tg3-<新机器人编号>-iarm
export TG3_HUB_ADDR=175.178.116.187:14049

不要使用旧机器人和新机器人相同的 Robot Peer ID。如果 EAI Peer ID 也随机器人编号更换, 机器人 omnisocket_expected_sender 必须同步更新。

3.2 在新机器人原生编译 OmniSocket Python 扩展

开发机上的 OmniSocket 扩展是 x86_64,而天工 3.0 机器人是 aarch64,不能复制已编译的 .so。传输源码时排除已有二进制,在机器人上重新编译:

ssh nvidia@"${TG3_NEW_ROBOT_IP}" 'mkdir -p /home/nvidia/OmniSocketGo'

rsync -av \
  --exclude=.git \
  --exclude=bin \
  --exclude=python/build \
  --exclude='python/omnisocket/_omnisocket*.so' \
  /home/ps/Desktop/OmniSocketGo/ \
  nvidia@"${TG3_NEW_ROBOT_IP}":/home/nvidia/OmniSocketGo/

ssh nvidia@"${TG3_NEW_ROBOT_IP}" \
  'cd /home/nvidia/OmniSocketGo && make python-ext'

验证扩展架构和导入:

ssh nvidia@"${TG3_NEW_ROBOT_IP}" \
  'uname -m; find /home/nvidia/OmniSocketGo/python -name "_omnisocket*.so" -print'

ssh nvidia@"${TG3_NEW_ROBOT_IP}" \
  'PYTHONPATH=/home/nvidia/OmniSocketGo/python python3 -c "from omnisocket import Session; print(Session)"'

预期机器人架构为 aarch64,扩展文件名包含 aarch64 和机器人实际 Python 版本。

3.3 部署机器人桥,但暂不启动

rsync -av \
  --exclude=__pycache__ \
  --exclude=status.json \
  /home/ps/Downloads/TG3/tg3_local_teleop/ \
  nvidia@"${TG3_NEW_ROBOT_IP}":/home/nvidia/tg3_local_teleop/

ssh nvidia@"${TG3_NEW_ROBOT_IP}" \
  'mkdir -p /home/nvidia/.config/systemd/user && cp /home/nvidia/tg3_local_teleop/tg3-local-teleop.service /home/nvidia/.config/systemd/user/'

此时不要立即长按启动。先编辑新机器人:

ssh nvidia@"${TG3_NEW_ROBOT_IP}"
nano /home/nvidia/tg3_local_teleop/config.toml

必须检查的字段:

[network]
transport = "omnisocket"
omnisocket_server = "175.178.116.187:14049"       # TG3_HUB_ADDR
omnisocket_peer_id = "tg3-<新机器人编号>-robot" # TG3_NEW_ROBOT_PEER
omnisocket_expected_sender = "tg3-<新机器人编号>-iarm" # TG3_IARM_PEER
expected_iarm_id = "IArm009027FA8190"             # 若仍用当前 TS1P,可保持
expected_iarm_type = "TS1P"

[home]
joint_goal_rad = [ ...新机器人实测的 14 个 Home 值... ]

还要检查:

  • [hands] 是否与新机器人的真实手型相符;
  • [hands].right_b_point_pose_normalized 是否适用于新 BrainCo 手的校准;首次只在净空、 急停可用且低速限制生效时测试;
  • [control].joint_lower_rad/joint_upper_rad 是否仍适用于同型号和当前 SDK;
  • run.sh、service 内的用户名和路径是否仍为 /home/nvidia;
  • ROS 安装路径是否仍有 /opt/ros/jazzy、/home/nvidia/xos 或 /opt/robot_tele_server/install。

3.4 修改 EAI 的目标 Peer

编辑:

ssh eai
nano /home/eai/.config/systemd/user/tg3-omnisocket-sender.service

修改 ExecStart 中:

--server      <TG3_HUB_ADDR>
--peer-id     <TG3_IARM_PEER>
--target-peer <TG3_NEW_ROBOT_PEER>

不要修改:

--zmq-endpoint tcp://127.0.0.1:5003
--cmd-zmq-endpoint tcp://127.0.0.1:5001
--cmd-max-age-s 0.25

应用 EAI 配置:

systemctl --user daemon-reload
systemctl --user restart tg3-omnisocket-sender.service
systemctl --user status tg3-omnisocket-sender.service --no-pager
cat /home/eai/tg3_omnisocket_transport/status.json

3.5 启动新机器人监测服务

ssh nvidia@"${TG3_NEW_ROBOT_IP}" \
  'systemctl --user daemon-reload && systemctl --user enable --now tg3-local-teleop.service'

先观察,不要长按武装:

ssh nvidia@"${TG3_NEW_ROBOT_IP}" \
  'sleep 5; cat /home/nvidia/tg3_local_teleop/status.json'

必须看到:

mode = active-capable
armed = false
returning_home = false
operator_session_state = inactive(尚未有首帧时也可为空闲)
iarm_transport_status.connected = true
foreign_source_seen = false
foreign_hand_source_seen = false

待机时 EAI 的 frames_received 应持续增长,但 frames_sent/bytes_sent 不增长;机器人 iarm_age_s 为空或逐渐变旧属于预期。身份、频率和扳机原始值先在 EAI 本机检查,完整 启动门控在 START 首帧到达机器人后执行。

然后再保存新 Home、核对手部打开位,并按第 7 节进行现场验收。

4. 场景 B:EAI 工控机也更换

新 EAI 除场景 A 的机器人步骤外,还要完成以下内容。

4.1 原厂 xTELE 必须先独立正常

先按 TS1P 厂家方法完成串口、CAN、关节方向、偏置和 Home 标定,确认 xTELE 能在 EAI 本机持续发布:

tcp://127.0.0.1:5003  原始关节、按键和诊断帧
tcp://127.0.0.1:5001  xTELE 处理后的控制帧(组合手势需要)

若 5003 正常而 5001 不存在,双臂、Z+C 和摇杆仍能收到原始数据,但飞书指南中的手势组合键 不会生成 BrainCo 六维目标。迁移时必须同时检查两个端口。

不要把旧 EAI 的串口设备路径和关节偏置盲目复制到不同硬件。只有同一套 TS1P 搬到新 工控机且串口设备一致时,才可参考旧配置。

4.2 在新 EAI 原生编译 OmniSocket 扩展

新 EAI 当前通常是 x86_64,但仍应在目标机本地构建,以匹配其 Python 版本:

rsync -av \
  --exclude=.git \
  --exclude=bin \
  --exclude=python/build \
  --exclude='python/omnisocket/_omnisocket*.so' \
  /home/ps/Desktop/OmniSocketGo/ \
  <新EAI用户>@<新EAI地址>:/home/<新EAI用户>/OmniSocketGo/

ssh <新EAI用户>@<新EAI地址> \
  'cd /home/<新EAI用户>/OmniSocketGo && make python-ext'

将当前 EAI 的自有发送目录复制到新 EAI,并保持原厂目录不变:

/home/eai/tg3_omnisocket_transport/
  omnisocket_xtele_sender.py
  README.md

在新 EAI 创建对应用户服务,修改所有 /home/eai 为新用户真实目录,并设置:

Environment=PYTHONPATH=/home/<新EAI用户>/OmniSocketGo/python
--server <Hub IP:Port>
--peer-id <EAI Peer ID>
--target-peer <机器人 Peer ID>
--zmq-endpoint tcp://127.0.0.1:5003
--cmd-zmq-endpoint tcp://127.0.0.1:5001
--cmd-max-age-s 0.25
--source-timeout-s 0.25
--start-stop-hold-s 3.0
--combo-release-s 0.5
--start-marker-frames 500
--max-feedback-age-ms 500
--max-pending-frames 100
Restart=always

如果希望用户级服务在没有图形登录时也随开机运行,需要由管理员为实际账号开启 linger:

sudo loginctl enable-linger <新EAI用户>

机器人用户服务同理,是否需要 linger 取决于机器人系统是否会自动创建 nvidia 用户会话。

5. Hub IP 或端口变化时修改哪里

假设新 Hub 为 203.0.113.10:15000:

EAI

修改:

/home/eai/.config/systemd/user/tg3-omnisocket-sender.service

把:

--server 175.178.116.187:14049

改为:

--server 203.0.113.10:15000

机器人

修改:

/home/nvidia/tg3_local_teleop/config.toml

把:

omnisocket_server = "175.178.116.187:14049"

改为:

omnisocket_server = "203.0.113.10:15000"

Hub/防火墙

  • KCP Hub 应监听 0.0.0.0:15000;
  • 云安全组和主机防火墙应允许对应 UDP 端口;
  • 不要只开放同端口的 TCP;当前跨公网控制使用 UDP/KCP。

修改后按顺序重启:

  1. Hub;
  2. EAI tg3-omnisocket-sender.service;
  3. 机器人接收端。2 秒业务帧看门狗只在活动会话内生效,待机不会反复重启。

6. 场景 C:完全不经过 Hub 的局域网 ZMQ 直连

这一路径不启动公网或本地 OmniSocket Hub,也不经过 tg3-omnisocket-sender.service:

TS1P
  -> EAI xTELE tcp://0.0.0.0:5003(原始 JSON)
  -> 同一可信局域网内的 TCP/ZMQ
  -> 机器人 tg3_local_teleop,network.transport="zmq"
  -> /encoder_identical_joint、BrainCo 手和 /hric/robot/cmd_vel

这里的“本地”是机器人直接订阅 EAI 的局域网地址,不是把 tcp://127.0.0.1:5003 原样写到机器人。机器人配置中的 127.0.0.1 会指向机器人自身, 无法访问 EAI。

6.1 适用条件和网络检查

  • EAI 与机器人必须在同一可信 Wi-Fi、有线路由可达网段,或使用两端静态地址的直连网线;
  • EAI 地址应固定,至少配置 DHCP 保留;地址变化后必须同步修改机器人 network.iarm_endpoint;
  • 只需机器人访问 EAI 的 TCP 5003。不要把 5003 暴露到公网,防火墙应只允许机器人地址;
  • xTELE 必须监听非回环地址。当前 EAI 实测为 0.0.0.0:5003 和 0.0.0.0:5001;新工控机仍需重新检查;
  • ZMQ/TCP 直连没有 OmniSocket 的 Peer ID、包龄过滤或身份认证,只应在隔离、可信的控制网 使用。

在 EAI 检查地址和监听:

ip -br -4 address
ss -lntp | grep -E ':(5001|5003)\b'

若 5003 只显示 127.0.0.1:5003,机器人不能直接连接。应按厂家 xTELE 配置修改监听地址, 不要用公网端口转发代替局域网隔离。

从机器人检查到 EAI 的路由;把示例 IP 换成实际 EAI 局域网 IP:

ping -c 3 192.168.5.14
python3 -c 'import socket; s=socket.create_connection(("192.168.5.14",5003),2); s.close(); print("TCP 5003 OK")'

上面的 TCP 检查只证明端口可达。还应在机器人实际订阅一帧 ZMQ JSON:

python3 - <<'PY'
import json
import zmq

context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.setsockopt(zmq.SUBSCRIBE, b"")
socket.connect("tcp://192.168.5.14:5003")
if socket.poll(3000) == 0:
    raise SystemExit("3 秒内未收到 xTELE 5003 数据")
data = json.loads(socket.recv())
print(data.get("isomorphic_arm_id"), data.get("isomorphic_arm_type"), data.get("freq"))
socket.close()
context.term()
PY

Wi-Fi 和有线的配置方法相同,iarm_endpoint 始终填写“机器人能够访问到的 EAI 地址”。 不要因为使用机器人内部 SSH 地址 192.168.41.2,就把它误写成 EAI 地址。

当前现场 Wi-Fi 已验证为 EAI 192.168.5.14、机器人 Nvidia wlan0 192.168.5.15。若改用直连网线,应选择双方确认未被厂家系统占用的物理网卡,配置一个 独立静态网段,例如 EAI 192.168.50.1/24、机器人 192.168.50.2/24,随后把 iarm_endpoint 改为 tcp://192.168.50.1:5003。网卡名必须现场确认;不要改动机器人 Ubuntu 192.168.41.1 与 Nvidia 192.168.41.2 之间的厂家内部链路。

6.2 切换前停止公网链路

先用正常 Z+C 3 秒 STOP 结束当前遥操,等待自动 Home 完成,并在机器人确认:

python3 -c 'import json; d=json.load(open("/home/nvidia/tg3_local_teleop/status.json")); print({k:d.get(k) for k in ("armed","returning_home","home_status")})'

必须看到 armed=false 且 returning_home=false。然后在 EAI 停止并禁用公网 sender:

systemctl --user disable --now tg3-omnisocket-sender.service
systemctl --user is-active tg3-omnisocket-sender.service

第二条应输出 inactive。不要删除 sender、OmniSocketGo 或原来的 service;保留它们用于 回切公网模式。纯 ZMQ 模式下 EAI 的 sender status.json 不再是运行状态依据。

6.3 修改机器人配置

在机器人编辑:

/home/nvidia/tg3_local_teleop/config.toml

只修改以下字段:

[network]
transport = "zmq"
iarm_endpoint = "tcp://192.168.5.14:5003" # 改成实际 EAI 局域网 IP

omnisocket_server、omnisocket_peer_id 和 omnisocket_expected_sender 可以保留,ZMQ 模式不会读取它们,回切公网时仍可继续使用。expected_iarm_id 和 expected_iarm_type 仍会检查,换 TS1P 时必须同步修改真实设备 ID。

当前版本在纯 ZMQ 断流时会保留最后一帧。locomotion.enabled=false 只能先排除最危险的 持续速度输出,仍不足以让双臂和手安全投用;配置阶段先设置:

[locomotion]
enabled = false

这会禁用我们桥发布的 HBWALK 速度。完成第 6.5 节所述本地断流保护之前,双臂、手和 行走都只能做无发布监测,不能长按 Z+C 武装。

不要立即启动带 --allow-publish 的 systemd 服务。先停止并暂时禁用我们自己的机器人桥, 然后以前台、无 --allow-publish 的监测模式运行 30 秒:

systemctl --user disable --now tg3-local-teleop.service
cd /home/nvidia/tg3_local_teleop
./run.sh --duration 30
/home/nvidia/tg3_local_teleop/status.sh

run.sh 只有显式收到 --allow-publish 才能发布;上述命令应显示 mode=monitor-only。如果 systemd 服务仍为 active,先停掉,避免同时启动第二个桥实例。

状态至少应满足:

iarm_transport = zmq
iarm_endpoint = tcp://<EAI局域网IP>:5003
iarm_transport_status.frames_accepted 持续增长
iarm_id = 当前 TS1P ID
iarm_frequency_hz 左右均高于 30 Hz
armed = false
foreign_source_seen = false
mode = monitor-only

不要只看 iarm_transport_status.connected:当前 ZMQ 接收器收到过首帧后会保持该布尔值, 判断链路是否仍在更新要连续观察 frames_accepted 和 iarm_age_s。

服务重启和检查期间必须保持 Z+C 完全松开。ZMQ 回退门控在机器人端计时,若服务启动时 已经按住 Z+C,连续 3 秒后也可能被当成新的启动请求。

6.4 直连模式下协议字段与功能差异

下表说明数据和代码路径是否存在,不代表当前版本已经允许运动。第 6.5 节的 ZMQ 断流门控 完成前,所有运动项都保持 monitor-only。

功能 纯 ZMQ 直连的数据/代码情况
双臂 14 关节、启动限位和 ROS 状态门控 字段与代码路径保留;当前禁止武装
左右扳机 BrainCo 手控 5003 原始 hand.position 存在;当前禁止武装
右 B 长按 1 秒单食指 5003 原始 B 键存在;当前禁止武装
Z+C 长按 3 秒启动/停止、STOP 后限速 Home 改由机器人本地计时;断流可锁存按键,当前禁止武装
C + 左摇杆行走、Z + 右摇杆转向 代码路径存在;当前必须 enabled=false
xTELE 5001 处理后的其他六维组合手势 不保留;机器人只订阅 5003
OmniSocket session ID、Peer 校验、300 ms 晚包过滤 不使用
公网 Hub、EAI OmniSocket sender 不需要

若必须完整保留 5001 组合手势,不能只把机器人指向 5003。需要另行实现一个 EAI 本地 5003+5001 合并代理,或在局域网内运行 OmniSocket Hub;后者不经过公网,但仍属于本地 Hub 模式,不是本节的“完全无 Hub”直连。

6.5 当前版本的断流风险

此前按现场要求删除了机器人桥“输入陈旧超过 0.25 秒立即解除遥操”的自定义门控;而 omnisocket_restart_after_stale_s=2.0 只在 transport="omnisocket" 时生效。 因此纯 ZMQ 模式断网后:

  • 最后一帧双臂和手目标仍会以桥的周期重复发布;
  • 如果行走仍启用且最后一帧是非零速度组合,非零 /hric/robot/cmd_vel 也会持续发布;
  • 如果最后一帧仍按住 Z+C,本地 3 秒计时会在没有新数据时继续,可能在断网后武装或停止;
  • 网络恢复后会直接继续当前 armed 会话,不要求重新 Z+C;
  • connected=true 不能证明数据仍然新鲜。

所以当前纯直连配置只能按第 6.3 节以 monitor-only 验证链路。正式启用前必须实现仅作用于 transport="zmq" 的断流门控,至少满足:

  1. 陈旧样本不得继续 Z+C 或右 B 计时;
  2. 已武装时陈旧输入必须立即发布零速、解除双臂/手发布并锁定为需要重新松开、长按;
  3. 网络恢复不得自动恢复原 armed 会话;
  4. 阈值应作为 ZMQ 专用配置经现场验证,不能把已删除的通用 0.25 秒门控悄悄加回来;
  5. 完成断网、拔线、xTELE 停止和恢复的无运动测试后,才能重新启用 tg3-local-teleop.service --allow-publish,行走还需单独验证零速帧。

这不是厂家默认保护的变化;厂家关节限位、电机、碰撞和手部保护仍保持原样。

6.6 从纯直连恢复公网 OmniSocket

先正常 STOP、完成 Home 并保持 Z+C 松开,然后把机器人恢复为:

[network]
transport = "omnisocket"

[locomotion]
enabled = true # 仅在现场仍需要并已确认安全时恢复

确认保留的 omnisocket_server、双方 Peer ID 仍匹配。按“先机器人接收端、后 EAI sender”的顺序恢复:

# 机器人
systemctl --user enable --now tg3-local-teleop.service

# EAI
systemctl --user enable --now tg3-omnisocket-sender.service

机器人先确认 armed=false、iarm_transport=omnisocket;EAI 待机时仍只读本地 5003/5001,不会在新的 Z+C 3 秒 START 前发送业务数据。

7. 新机器人首次现场验收顺序

全程确认防护、活动空间、急停和 HBWALK 状态。 纯 ZMQ 当前版本若尚未完成第 6.5 节断流门控,只执行下面第 1~4 步的 monitor-only 检查, 不得执行第 5 步及后续任何武装或运动测试;完成并验证断流门控后才能继续。

  1. OmniSocket 模式:服务启动后保持未武装,在 EAI sender 状态中确认本地接收计数增长而 公网发送计数不增长;纯 ZMQ 模式:sender 已停用,应在机器人 monitor-only 状态中确认 frames_accepted 持续增长、iarm_age_s 接近 0,不读取旧的 EAI sender status.json;
  2. 不武装时分别扣左右扳机,在 EAI 本地数据中确认左右值独立从 0 到 1;
  3. 确认左右手物理默认打开位和 robot_hand_states 正常;
  4. 把 TS1P 双臂摆到与机器人当前位置尽量接近的安全姿态;
  5. 松开两个扳机,长按左 Z + 右 C 3 秒启动;
  6. 先做小幅单关节跟随,再逐渐扩大动作;
  7. 分别小幅扣左右扳机,验证双手方向、范围和限速;
  8. 保持右摇杆回中,连续长按右 B 1 秒,确认右手以 400 units/s 限速进入厂商 “单食指”姿态;松开至少 0.5 秒后再次长按 1 秒,确认退出并恢复正常右手跟随;
  9. 仅在 OmniSocket/5001 合并模式下:先停止并确认 armed=false,按飞书指南逐个选择 其他手势组合键;检查 EAI status.json 的 command_frames_accepted 增长,并在 EAI 本机 5001 抓帧确认处理后的 hand.position 为六维数组;待机不会构包,command_hand_merges 此时不应增长;
  10. 仅在 OmniSocket/5001 合并模式下:再次武装后检查 command_hand_merges 增长和机器人 iarm_hand_position 为六维, 再只做小幅动作,逐个验证所需的其他组合手势方向和限速;
  11. 仅在 [locomotion].enabled=true 且相应链路断流保护已经验证后:保持右 C,把左摇杆 小幅向前推出死区,确认下一个 50 Hz 周期立即响应;松 C,确认 立即零速停止。再次按 C/推杆也应立即响应,不再等待 3 秒;
  12. 在同一行走前提下,保持左 Z,把右摇杆小幅横推,确认机器人原地转向;松开任一输入 应立即清零角速度;
  13. 再次长按 Z+C 停止,观察双臂限速回到新机器人保存的 Home;
  14. 仅在 OmniSocket 模式测试 Hub 短暂断线:短于 2 秒不应解除会话;持续约 2 秒无帧会 重建机器人接收进程,恢复后先确认未武装,再重新长按启动;纯 ZMQ 模式在完成本地 断流门控前禁止做运动中的断链测试;
  15. 记录 SSH 地址、Home、行走限速、手部端点和单食指姿态到设备档案;OmniSocket 模式 另记 Peer ID/Hub,纯 ZMQ 模式改记 EAI 固定局域网 IP、TCP 5003 防火墙范围和断流门控参数。

迁移时确认目标机提供 /hric/robot/cmd_vel(geometry_msgs/msg/TwistStamped),并保持 locomotion.command_topic 与目标固件一致。行走限速、死区、曲线和方向符号均在机器人 config.toml 的 [locomotion] 中调整。当前天工 3.0 按二次开放文档的半身行走 Topic 范围配置:max_forward_m_s=1.0、max_reverse_m_s=0.8、 max_angular_rad_s=0.8;迁移到不同型号或固件时应重新核对其官方 Topic 范围。

8. 常见问题

机器人 SSH IP 变了,需要改 config.toml 吗?

公网 OmniSocket 模式不需要。只修改 SSH 命令中的地址。运行时机器人主动连接 Hub。

EAI IP 变了,需要改 tcp://127.0.0.1:5003/5001 吗?

公网 OmniSocket sender 不需要修改:127.0.0.1 永远表示 EAI 本机,和网卡地址无关。 但第 6 节纯 ZMQ 直连时,机器人 iarm_endpoint 使用 EAI 局域网地址;该地址变化就必须 修改并重启机器人桥。

Hub 没启动时已经长按了 Z+C,服务器恢复后怎么办?

本次长按只做一次后台连接检测。Hub 未启动、机器人 Peer 不存在或首帧发送失败时, teleop_start_pending 会回到 false;Hub 离线时没有业务帧发出,Peer/发送错误时机器人 不会收到控制数据。旧请求不会在服务器稍后恢复 时自动重试。稳定松开 Z+C 至少 0.5 秒,待 Hub 与机器人接收端就绪后重新长按 3 秒即可。 后台检测期间 sender 仍持续读取 5003,因此松键不会因连接等待而漏掉。活动会话断网同样 按故障关闭处理,必须稳定松开后重新长按。

只改机器人 Peer,不改 EAI 可以吗?

不可以。EAI 的 --target-peer 必须等于机器人的 omnisocket_peer_id,机器人 omnisocket_expected_sender 必须等于 EAI 的 --peer-id。

可以直接复制当前机器人的整个 OmniSocketGo 目录吗?

只有目标机器架构和 Python ABI 完全一致时才可能复用。更稳妥的方式是复制源码并在目标 机器执行 make python-ext。EAI 的 x86_64 .so 绝对不能用于 aarch64 机器人。

可以复用当前 Home 吗?

不建议。Home 是现场机器人真实反馈值,不是型号固定常数。每台机器人都应重新保存。

新机器人是因时手,可以直接改 Topic 吗?

不可以。当前桥导入并发布 BrainCo 消息,因时手是不同消息类型和 13 自由度映射,需要 单独实现适配后再部署。

9. 迁移时真正需要修改的最小清单

同一 EAI、同一 TS1P、同一 Hub、换一台同配置 BrainCo 天工 3.0 时,最少修改:

  1. EAI service 的 --target-peer;
  2. 若更换 EAI Peer ID,同时修改 EAI --peer-id 和机器人 omnisocket_expected_sender;
  3. 机器人 omnisocket_peer_id;
  4. 新机器人 [home].joint_goal_rad;
  5. 核对并按实测修正 [hands].open_normalized;
  6. SSH 命令中的新机器人 IP。

Hub IP/端口变化时,额外同时修改 EAI --server 和机器人 omnisocket_server。

完全不经过 Hub、切换为第 6 节纯 ZMQ 直连时,最少修改机器人 network.transport="zmq"、network.iarm_endpoint="tcp://<EAI局域网IP>:5003",并在 当前没有直连断流门控的版本中设置 locomotion.enabled=false,同时停用 EAI 的 tg3-omnisocket-sender.service,并仅以机器人 monitor-only 模式验证;完成第 6.5 节的 ZMQ 专用断流门控前不得启用运动发布。