17 KiB
天工 3.0 本地同构臂遥操迁移部署指南
适用范围:天工 3.0(HBWALK)+ TS1P 同构臂。当前灵巧手实现适用于机器人实际配置为 BrainCo Revo2 的情况。
1. 迁移前先区分四种地址
| 地址/标识 | 示例 | IP 变化时是否修改运行配置 |
|---|---|---|
| 新机器人 SSH 地址 | nvidia@192.168.41.2 |
只影响安装、维护命令;公网 OmniSocket 运行时不使用这个地址 |
| EAI SSH 地址/别名 | eai |
只影响安装、维护命令;xTELE 使用本机回环地址,不依赖 EAI 局域网 IP |
| 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 直接用于另一台机器人。即使型号相同,机械零位、
装配偏差和期望停放姿态也可能不同。
在新机器人上:
- 使用厂家认可的方法把双臂移动到希望保存的 Home;不要强行扳动上电电机;
- 确认本地遥操为
armed=false; - 读取实测位置:
python3 -c 'import json; p="/home/nvidia/tg3_local_teleop/status.json"; print(json.load(open(p))["robot_arm_position_rad"])'
- 将输出的 14 个弧度值原样写入新机器人
/home/nvidia/tg3_local_teleop/config.toml的[home].joint_goal_rad; - 重启服务后,先检查状态,再在净空和急停可用的条件下测试限速 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、核对手部打开位,并按第 6 节进行现场验收。
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。
修改后按顺序重启:
- Hub;
- EAI
tg3-omnisocket-sender.service; - 机器人接收端。2 秒业务帧看门狗只在活动会话内生效,待机不会反复重启。
6. 新机器人首次现场验收顺序
全程确认防护、活动空间、急停和 HBWALK 状态。
- 服务启动后保持未武装;在 EAI 状态中确认本地接收计数增长而公网发送计数不增长;
- 不武装时分别扣左右扳机,在 EAI 本地数据中确认左右值独立从 0 到 1;
- 确认左右手物理默认打开位和
robot_hand_states正常; - 把 TS1P 双臂摆到与机器人当前位置尽量接近的安全姿态;
- 松开两个扳机,长按左 Z + 右 C 3 秒启动;
- 先做小幅单关节跟随,再逐渐扩大动作;
- 分别小幅扣左右扳机,验证双手方向、范围和限速;
- 保持右摇杆回中,连续长按右 B 3 秒,确认右手以
400 units/s限速进入厂商 “单食指”姿态;松开至少 0.5 秒后再次长按 3 秒,确认退出并恢复正常右手跟随; - 先停止并确认
armed=false,按飞书指南逐个选择其他手势组合键;检查 EAIstatus.json的command_frames_accepted增长,并在 EAI 本机 5001 抓帧确认处理后的hand.position为六维数组;待机不会构包,command_hand_merges此时不应增长; - 再次武装后检查
command_hand_merges增长和机器人iarm_hand_position为六维, 再只做小幅动作,逐个验证所需的其他组合手势方向和限速; - 保持右 C,把左摇杆小幅向前推出死区,确认下一个 50 Hz 周期立即响应;松 C,确认 立即零速停止。再次按 C/推杆也应立即响应,不再等待 3 秒;
- 保持左 Z,把右摇杆小幅横推,确认机器人原地转向;松开任一输入应立即清零角速度;
- 再次长按 Z+C 停止,观察双臂限速回到新机器人保存的 Home;
- 测试 Hub 短暂断线:应在 0.25 秒后停止发布,恢复后先确认未武装,再重新长按启动;
- 记录最终 Peer ID、Hub、SSH 地址、Home、行走限速、手部端点和单食指姿态到该机器人的设备档案。
迁移时确认目标机提供 /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 范围。
7. 常见问题
机器人 SSH IP 变了,需要改 config.toml 吗?
公网 OmniSocket 模式不需要。只修改 SSH 命令中的地址。运行时机器人主动连接 Hub。
EAI IP 变了,需要改 tcp://127.0.0.1:5003/5001 吗?
不需要。127.0.0.1 永远表示 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 自由度映射,需要 单独实现适配后再部署。
8. 迁移时真正需要修改的最小清单
同一 EAI、同一 TS1P、同一 Hub、换一台同配置 BrainCo 天工 3.0 时,最少修改:
- EAI service 的
--target-peer; - 若更换 EAI Peer ID,同时修改 EAI
--peer-id和机器人omnisocket_expected_sender; - 机器人
omnisocket_peer_id; - 新机器人
[home].joint_goal_rad; - 核对并按实测修正
[hands].open_normalized; - SSH 命令中的新机器人 IP。
Hub IP/端口变化时,额外同时修改 EAI --server 和机器人 omnisocket_server。