1101 lines
41 KiB
Markdown
1101 lines
41 KiB
Markdown
# 天工 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` | 公网模式只影响运维;第 6 节本地 OmniSocket Hub 模式下,机器人必须连接该局域网 IP |
|
||
| OmniSocket Hub 地址 | `175.178.116.187:14049` | 公网模式两端使用公网地址;本地模式 EAI sender 用回环地址、机器人用 EAI 局域网地址 |
|
||
| 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
|
||
|
||
推荐命名:
|
||
|
||
```text
|
||
EAI 发送端:tg3-<机器人编号>-iarm
|
||
机器人接收端:tg3-<机器人编号>-robot
|
||
```
|
||
|
||
三处必须满足:
|
||
|
||
```text
|
||
EAI --peer-id == 机器人 omnisocket_expected_sender
|
||
EAI --target-peer == 机器人 omnisocket_peer_id
|
||
公网模式:EAI --server == 机器人 omnisocket_server
|
||
```
|
||
|
||
第 6 节本地 Hub 模式是地址表示的例外:EAI 用 `127.0.0.1:14049`,机器人用
|
||
`<EAI局域网IP>:14049`,两者必须指向同一个 EAI 本机 Hub 进程。
|
||
|
||
同一台 EAI 同一时刻只应控制一台机器人。现有发送服务只有一个 `--target-peer`,迁移到
|
||
另一台机器人后要修改目标 Peer 并重启发送服务,不要用一套 TS1P 同时向多台机器人发指令。
|
||
|
||
### 2.2 新机器人必须重新保存 Home
|
||
|
||
不要把当前机器人的 `home.joint_goal_rad` 直接用于另一台机器人。即使型号相同,机械零位、
|
||
装配偏差和期望停放姿态也可能不同。
|
||
|
||
在新机器人上:
|
||
|
||
1. 使用厂家认可的方法把双臂移动到希望保存的 Home;不要强行扳动上电电机;
|
||
2. 确认本地遥操为 `armed=false`;
|
||
3. 读取实测位置:
|
||
|
||
```bash
|
||
python3 -c 'import json; p="/home/nvidia/tg3_local_teleop/status.json"; print(json.load(open(p))["robot_arm_position_rad"])'
|
||
```
|
||
|
||
4. 将输出的 14 个弧度值原样写入新机器人
|
||
`/home/nvidia/tg3_local_teleop/config.toml` 的 `[home].joint_goal_rad`;
|
||
5. 重启服务后,先检查状态,再在净空和急停可用的条件下测试限速 Home。
|
||
|
||
### 2.3 必须确认灵巧手型号
|
||
|
||
```bash
|
||
grep -E 'left_hand_type|right_hand_type' /home/nvidia/data/param/hand_driver.yaml
|
||
```
|
||
|
||
只有左右都显示 `brainco` 时,才能直接使用当前 `[hands]` 配置。如果是 `inspire` 或其他
|
||
型号,不要启动灵巧手控制;消息类型、Topic 和关节映射不同,需要单独适配。
|
||
|
||
BrainCo 新手初次部署时应在默认打开状态记录:
|
||
|
||
```bash
|
||
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/消息仍存在:
|
||
|
||
```text
|
||
/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 准备变量
|
||
|
||
以下变量只用于本次终端命令,不写入服务:
|
||
|
||
```bash
|
||
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`。传输源码时排除已有二进制,在机器人上重新编译:
|
||
|
||
```bash
|
||
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'
|
||
```
|
||
|
||
验证扩展架构和导入:
|
||
|
||
```bash
|
||
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 部署机器人桥,但暂不启动
|
||
|
||
```bash
|
||
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/'
|
||
```
|
||
|
||
此时不要立即长按启动。先编辑新机器人:
|
||
|
||
```bash
|
||
ssh nvidia@"${TG3_NEW_ROBOT_IP}"
|
||
nano /home/nvidia/tg3_local_teleop/config.toml
|
||
```
|
||
|
||
必须检查的字段:
|
||
|
||
```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
|
||
|
||
编辑:
|
||
|
||
```bash
|
||
ssh eai
|
||
nano /home/eai/.config/systemd/user/tg3-omnisocket-sender.service
|
||
```
|
||
|
||
修改 `ExecStart` 中:
|
||
|
||
```text
|
||
--server <TG3_HUB_ADDR>
|
||
--peer-id <TG3_IARM_PEER>
|
||
--target-peer <TG3_NEW_ROBOT_PEER>
|
||
```
|
||
|
||
不要修改:
|
||
|
||
```text
|
||
--zmq-endpoint tcp://127.0.0.1:5003
|
||
--cmd-zmq-endpoint tcp://127.0.0.1:5001
|
||
--cmd-max-age-s 0.25
|
||
```
|
||
|
||
应用 EAI 配置:
|
||
|
||
```bash
|
||
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 启动新机器人监测服务
|
||
|
||
```bash
|
||
ssh nvidia@"${TG3_NEW_ROBOT_IP}" \
|
||
'systemctl --user daemon-reload && systemctl --user enable --now tg3-local-teleop.service'
|
||
```
|
||
|
||
先观察,不要长按武装:
|
||
|
||
```bash
|
||
ssh nvidia@"${TG3_NEW_ROBOT_IP}" \
|
||
'sleep 5; cat /home/nvidia/tg3_local_teleop/status.json'
|
||
```
|
||
|
||
必须看到:
|
||
|
||
```text
|
||
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、核对手部打开位,并按第 8 节进行现场验收。
|
||
|
||
## 4. 场景 B:EAI 工控机也更换
|
||
|
||
新 EAI 除场景 A 的机器人步骤外,还要完成以下内容。
|
||
|
||
### 4.1 原厂 xTELE 必须先独立正常
|
||
|
||
先按 TS1P 厂家方法完成串口、CAN、关节方向、偏置和 Home 标定,确认 xTELE 能在 EAI
|
||
本机持续发布:
|
||
|
||
```text
|
||
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 版本:
|
||
|
||
```bash
|
||
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,并保持原厂目录不变:
|
||
|
||
```text
|
||
/home/eai/tg3_omnisocket_transport/
|
||
omnisocket_xtele_sender.py
|
||
tg3-omnisocket-sender.service
|
||
tg3-omnisocket-hub.service # 仅局域网本地 Hub 模式需要
|
||
README.md
|
||
```
|
||
|
||
在新 EAI 创建对应用户服务,修改所有 `/home/eai` 为新用户真实目录,并设置:
|
||
|
||
```text
|
||
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:
|
||
|
||
```bash
|
||
sudo loginctl enable-linger <新EAI用户>
|
||
```
|
||
|
||
机器人用户服务同理,是否需要 linger 取决于机器人系统是否会自动创建 `nvidia` 用户会话。
|
||
|
||
## 5. Hub IP 或端口变化时修改哪里
|
||
|
||
假设新 Hub 为 `203.0.113.10:15000`:
|
||
|
||
### EAI
|
||
|
||
修改:
|
||
|
||
```text
|
||
/home/eai/.config/systemd/user/tg3-omnisocket-sender.service
|
||
```
|
||
|
||
把:
|
||
|
||
```text
|
||
--server 175.178.116.187:14049
|
||
```
|
||
|
||
改为:
|
||
|
||
```text
|
||
--server 203.0.113.10:15000
|
||
```
|
||
|
||
### 机器人
|
||
|
||
修改:
|
||
|
||
```text
|
||
/home/nvidia/tg3_local_teleop/config.toml
|
||
```
|
||
|
||
把:
|
||
|
||
```toml
|
||
omnisocket_server = "175.178.116.187:14049"
|
||
```
|
||
|
||
改为:
|
||
|
||
```toml
|
||
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:局域网本地 OmniSocket Hub(推荐)
|
||
|
||
这里的“本地链路”仍使用现有 OmniSocket sender 和机器人 receiver,只把公网 Hub
|
||
替换成运行在 EAI 工控机上的局域网 KCP Hub:
|
||
|
||
```text
|
||
TS1P
|
||
-> EAI xTELE 127.0.0.1:5003 + 127.0.0.1:5001
|
||
-> tg3-omnisocket-sender(合并双手目标、Z+C session 门控)
|
||
-> EAI 本机 kcpserver Hub,127.0.0.1:14049
|
||
-> 同一可信局域网 UDP/KCP
|
||
-> 机器人从 <EAI局域网IP>:14049 接收
|
||
-> tg3_local_teleop,transport="omnisocket"
|
||
```
|
||
|
||
公网服务器可以完全关闭。该方案保留 5001 六维手势合并、Peer 路由、session ID、
|
||
START/ACTIVE/STOP、晚包过滤和现有断线处理,比第 7 节纯 ZMQ 回退更完整。
|
||
|
||
### 6.1 本地与公网配置映射
|
||
|
||
当前现场局域网地址:
|
||
|
||
```text
|
||
EAI Wi-Fi: 192.168.5.14
|
||
机器人 Nvidia wlan0:192.168.5.15
|
||
本地 Hub UDP 端口: 14049
|
||
```
|
||
|
||
两端填写的地址不同,但实际指向同一个 EAI Hub:
|
||
|
||
| 配置位置 | 公网模式 | 本地 Hub 模式 |
|
||
|---|---|---|
|
||
| EAI sender `--server` | `175.178.116.187:14049` | `127.0.0.1:14049` |
|
||
| 机器人 `omnisocket_server` | `175.178.116.187:14049` | `192.168.5.14:14049` |
|
||
| 机器人 `network.transport` | `omnisocket` | `omnisocket`,不要改成 `zmq` |
|
||
| EAI/机器人 Peer ID | 当前成对 ID | 完全保持不变 |
|
||
| 5003+5001 合并和右 B 抑制 | 保留 | 保留 |
|
||
|
||
EAI sender 使用回环地址,避免 EAI 自己向 Hub 的数据绕行 Wi-Fi;机器人使用 EAI 的真实
|
||
局域网地址。Hub 必须监听 `0.0.0.0:14049` 才能同时接收回环和局域网客户端。若把 Hub
|
||
只绑定到 `192.168.5.14:14049`,EAI sender 也必须改用该地址,不能再写
|
||
`127.0.0.1:14049`。
|
||
|
||
### 6.2 在 EAI 准备完整 OmniSocketGo 和 kcpserver
|
||
|
||
本地 Hub 必须是独立的 `kcpserver -mode hub` 进程。Python `omnisocket.Session` 只有
|
||
客户端 API,现有 sender 进程不能兼任 Hub;也不要使用 `-mode relay`,relay 仍需要另一个
|
||
远端 Hub。
|
||
|
||
固定使用已验证提交:
|
||
|
||
```text
|
||
de3f5c96779dbe1571c10feb22fc7f2331b6b222
|
||
```
|
||
|
||
当前 EAI 的 `/home/eai/OmniSocketGo` 是为了 Python 扩展裁剪过的副本,缺少 `cmd/` 和
|
||
`bin/kcpserver`,不能直接启动 Hub。应直接从上述提交导出干净源码,避免把本机
|
||
OmniSocketGo 工作区中未提交的实验改动带到 EAI:
|
||
|
||
```bash
|
||
git -C /home/ps/Desktop/OmniSocketGo \
|
||
archive de3f5c96779dbe1571c10feb22fc7f2331b6b222 \
|
||
| ssh eai 'mkdir -p /home/eai/OmniSocketGo && tar -x -C /home/eai/OmniSocketGo'
|
||
|
||
ssh eai 'cd /home/eai/OmniSocketGo && make bin/kcpserver'
|
||
ssh eai '/home/eai/OmniSocketGo/bin/kcpserver --help'
|
||
```
|
||
|
||
如果执行命令的开发机没有该 Git 仓库,先从项目根 README 中的 Gitea 地址 clone,
|
||
然后用 `git archive <固定提交>` 导出;不要复制其他平台已编译的 `.so` 或 `bin/`。
|
||
|
||
新 EAI 还需按第 4 节执行 `make python-ext`。当前 EAI 已具备 gcc、make 和 build-essential;
|
||
`kcpserver` 本身只依赖系统 libc,不需要 Go 运行时或 FFmpeg。
|
||
|
||
### 6.3 为本地 Hub 创建用户服务
|
||
|
||
项目已提供模板:
|
||
|
||
```text
|
||
tg3_omnisocket_transport/tg3-omnisocket-hub.service
|
||
```
|
||
|
||
把它安装到 EAI:
|
||
|
||
```text
|
||
/home/eai/.config/systemd/user/tg3-omnisocket-hub.service
|
||
```
|
||
|
||
用户名不是 `eai` 时同步修改模板中的路径。模板内容:
|
||
|
||
```ini
|
||
[Unit]
|
||
Description=TG3 local OmniSocket KCP hub
|
||
|
||
[Service]
|
||
Type=simple
|
||
WorkingDirectory=/home/eai/OmniSocketGo
|
||
ExecStart=/home/eai/OmniSocketGo/bin/kcpserver -mode hub -listen 0.0.0.0:14049
|
||
Restart=always
|
||
RestartSec=1
|
||
KillSignal=SIGTERM
|
||
TimeoutStopSec=5
|
||
|
||
[Install]
|
||
WantedBy=default.target
|
||
```
|
||
|
||
在部署机的 TG3 项目根目录执行,直接把模板安装到 EAI 用户服务目录:
|
||
|
||
```bash
|
||
ssh eai 'mkdir -p /home/eai/.config/systemd/user'
|
||
scp tg3_omnisocket_transport/tg3-omnisocket-hub.service \
|
||
eai:/home/eai/.config/systemd/user/tg3-omnisocket-hub.service
|
||
```
|
||
|
||
默认不要开启 latency、packet-debug 或 session-stats 日志,避免长期高频写盘。然后登录 EAI,
|
||
在 `eai` 用户会话中加载并启动:
|
||
|
||
```bash
|
||
systemctl --user daemon-reload
|
||
systemctl --user enable --now tg3-omnisocket-hub.service
|
||
systemctl --user --no-pager status tg3-omnisocket-hub.service
|
||
ss -lunp | grep ':14049'
|
||
```
|
||
|
||
应看到 UDP `0.0.0.0:14049`。若希望 EAI 未图形登录也能自动运行用户服务,需要管理员执行:
|
||
|
||
```bash
|
||
sudo loginctl enable-linger eai
|
||
```
|
||
|
||
### 6.4 Wi-Fi、有线和防火墙
|
||
|
||
机器人必须能访问 EAI 的本地 Hub:
|
||
|
||
```bash
|
||
# 在机器人执行
|
||
ping -c 3 192.168.5.14
|
||
```
|
||
|
||
当前 Wi-Fi 已确认机器人 `192.168.5.15` 能到达 EAI `192.168.5.14`,但无线 RTT 仍会有
|
||
波动。有线直连时应使用未被厂家占用的网卡建立独立静态网段,例如 EAI
|
||
`192.168.50.1/24`、机器人 `192.168.50.2/24`,机器人配置相应写成
|
||
`192.168.50.1:14049`。不要修改 Ubuntu `192.168.41.1` 与 Nvidia
|
||
`192.168.41.2` 之间的厂家内部链路。
|
||
|
||
KCP 使用 UDP,不是 TCP。不要开放 TCP 14049,也不需要让机器人访问 EAI 的 5001/5003;
|
||
这两个 xTELE 端口只由同机 sender 通过回环地址读取。若 EAI 启用 UFW,Wi-Fi 当前可限制为:
|
||
|
||
```bash
|
||
sudo ufw status verbose
|
||
sudo ufw allow in on wlp172s0 from 192.168.5.15 to any port 14049 proto udp
|
||
```
|
||
|
||
有线时把网卡名和机器人地址替换成现场值。还应检查现有 UFW/云网关规则,确认没有更宽的
|
||
UDP 14049 放行规则覆盖上述限制。OmniSocket Peer ID 不是密码或加密认证;Hub 只应监听隔离、
|
||
可信的控制网,不要做公网端口映射。
|
||
|
||
### 6.5 从公网安全切换到本地 Hub
|
||
|
||
1. 先用 Z+C 3 秒正常 STOP,等待自动 Home 完成,在机器人确认 `armed=false`、
|
||
`returning_home=false`;
|
||
2. 确认 EAI 本地 Hub 已经 `active` 且 UDP 14049 正在监听;
|
||
3. 停止 EAI sender,防止修改期间创建会话:
|
||
|
||
```bash
|
||
systemctl --user stop tg3-omnisocket-sender.service
|
||
```
|
||
|
||
4. 在 EAI 直接修改 sender 地址:
|
||
|
||
```bash
|
||
sed -i -E 's#--server [^ ]+#--server 127.0.0.1:14049#' \
|
||
/home/eai/.config/systemd/user/tg3-omnisocket-sender.service
|
||
grep -oE -- '--server [^ ]+' \
|
||
/home/eai/.config/systemd/user/tg3-omnisocket-sender.service
|
||
```
|
||
|
||
`--peer-id`、`--target-peer`、5003/5001、所有超时和按键参数都保持不变。
|
||
|
||
5. 在机器人直接修改 Hub 地址(有线时替换为实际 EAI 地址):
|
||
|
||
```bash
|
||
sed -i 's#^omnisocket_server = ".*"$#omnisocket_server = "192.168.5.14:14049"#' \
|
||
/home/nvidia/tg3_local_teleop/config.toml
|
||
grep -nE '^(transport|omnisocket_server) *=' \
|
||
/home/nvidia/tg3_local_teleop/config.toml
|
||
```
|
||
|
||
Peer ID、`expected_iarm_id`、Home、手部、行走和厂家保护都不要改。`iarm_endpoint` 在
|
||
OmniSocket 模式不使用;检查输出应为 `transport = "omnisocket"`。
|
||
|
||
6. 按“本地 Hub → 机器人 receiver → EAI sender”的顺序应用:
|
||
|
||
```bash
|
||
# EAI:Hub 已在运行
|
||
systemctl --user is-active tg3-omnisocket-hub.service
|
||
|
||
# 机器人
|
||
systemctl --user restart tg3-local-teleop.service
|
||
|
||
# EAI
|
||
systemctl --user daemon-reload
|
||
systemctl --user restart tg3-omnisocket-sender.service
|
||
```
|
||
|
||
服务启动只进入待机,不会自动武装;仍需新的 Z+C 3 秒 START。
|
||
|
||
### 6.6 切换后验证
|
||
|
||
EAI Hub:
|
||
|
||
```bash
|
||
systemctl --user is-active tg3-omnisocket-hub.service
|
||
ss -lunp | grep ':14049'
|
||
```
|
||
|
||
机器人待机状态应看到:
|
||
|
||
```text
|
||
armed = false
|
||
iarm_transport = omnisocket
|
||
iarm_endpoint = omnisocket://192.168.5.14:14049/tg3-009027fa8190-robot
|
||
iarm_transport_status.connected = true
|
||
iarm_transport_status.registered = true
|
||
foreign_source_seen = false
|
||
foreign_hand_source_seen = false
|
||
```
|
||
|
||
EAI sender 待机时仍持续读取本机 5003/5001,但应为:
|
||
|
||
```text
|
||
teleop_active = false
|
||
application_data_sending = false
|
||
connected = 0
|
||
frames_sent 不增长
|
||
```
|
||
|
||
然后按第 8 节从小幅双臂、扳机、右 B、其他 5001 手势到行走逐项验收。由于 sender 与
|
||
机器人仍走原来的 OmniSocket 协议,操作按键和数据格式不变。
|
||
|
||
### 6.7 本地 Hub 的断线与重启行为
|
||
|
||
- EAI sender 活动期间仍检查 KCP feedback、发送队列和本机 5003 时间戳;异常会作废
|
||
session,必须松开后重新 Z+C;
|
||
- 机器人仍拒绝错误 Peer、乱序和相对基线额外排队超过 300 ms 的包;
|
||
- 按现场要求删除的 0.25 秒输入陈旧解除不会恢复;活动会话连续约 2 秒收不到帧时,机器人
|
||
OmniSocket 看门狗重启我们自己的桥并停止发布;
|
||
- 意外断网不会自动 Home,只有收到匹配的操作员 STOP 才自动回 Home;
|
||
- 本地 Hub 重启后,机器人在空闲时最多可能等待 30 秒刷新注册。最确定的恢复顺序是先
|
||
重启 Hub,再重启 `tg3-local-teleop.service`,确认 registered 后重新长按 START;
|
||
- 无线本地链路去掉了公网排队,但 Wi-Fi 本身仍可能抖动;正式运行优先使用隔离有线网。
|
||
|
||
### 6.8 恢复公网 Hub
|
||
|
||
先正常 STOP、完成 Home,并确认公网 Hub 已启动。停止 EAI sender,然后分别执行:
|
||
|
||
```bash
|
||
# EAI
|
||
sed -i -E 's#--server [^ ]+#--server 175.178.116.187:14049#' \
|
||
/home/eai/.config/systemd/user/tg3-omnisocket-sender.service
|
||
|
||
# 机器人
|
||
sed -i 's#^omnisocket_server = ".*"$#omnisocket_server = "175.178.116.187:14049"#' \
|
||
/home/nvidia/tg3_local_teleop/config.toml
|
||
```
|
||
|
||
然后先重启机器人 receiver,再重启 EAI sender:
|
||
|
||
```bash
|
||
# 机器人
|
||
systemctl --user restart tg3-local-teleop.service
|
||
|
||
# EAI
|
||
systemctl --user daemon-reload
|
||
systemctl --user restart tg3-omnisocket-sender.service
|
||
systemctl --user disable --now tg3-omnisocket-hub.service
|
||
```
|
||
|
||
本地 Hub 文件可以保留。确认机器人已注册公网 Hub 且 `armed=false` 后,才做新的 Z+C 3 秒
|
||
START。
|
||
|
||
## 7. 备选:完全不经过 Hub 的局域网 ZMQ 直连(当前仅 monitor-only)
|
||
|
||
这一路径不启动公网或本地 OmniSocket Hub,也不经过
|
||
`tg3-omnisocket-sender.service`:
|
||
|
||
```text
|
||
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。
|
||
|
||
### 7.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 检查地址和监听:
|
||
|
||
```bash
|
||
ip -br -4 address
|
||
ss -lntp | grep -E ':(5001|5003)\b'
|
||
```
|
||
|
||
若 5003 只显示 `127.0.0.1:5003`,机器人不能直接连接。应按厂家 xTELE 配置修改监听地址,
|
||
不要用公网端口转发代替局域网隔离。
|
||
|
||
从机器人检查到 EAI 的路由;把示例 IP 换成实际 EAI 局域网 IP:
|
||
|
||
```bash
|
||
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:
|
||
|
||
```bash
|
||
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` 之间的厂家内部链路。
|
||
|
||
### 7.2 切换前停止公网链路
|
||
|
||
先用正常 Z+C 3 秒 STOP 结束当前遥操,等待自动 Home 完成,并在机器人确认:
|
||
|
||
```bash
|
||
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:
|
||
|
||
```bash
|
||
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` 不再是运行状态依据。
|
||
|
||
### 7.3 修改机器人配置
|
||
|
||
在机器人编辑:
|
||
|
||
```text
|
||
/home/nvidia/tg3_local_teleop/config.toml
|
||
```
|
||
|
||
只修改以下字段:
|
||
|
||
```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` 只能先排除最危险的
|
||
持续速度输出,仍不足以让双臂和手安全投用;配置阶段先设置:
|
||
|
||
```toml
|
||
[locomotion]
|
||
enabled = false
|
||
```
|
||
|
||
这会禁用我们桥发布的 HBWALK 速度。完成第 7.5 节所述本地断流保护之前,双臂、手和
|
||
行走都只能做无发布监测,不能长按 Z+C 武装。
|
||
|
||
不要立即启动带 `--allow-publish` 的 systemd 服务。先停止并暂时禁用我们自己的机器人桥,
|
||
然后以前台、无 `--allow-publish` 的监测模式运行 30 秒:
|
||
|
||
```bash
|
||
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`,先停掉,避免同时启动第二个桥实例。
|
||
|
||
状态至少应满足:
|
||
|
||
```text
|
||
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 秒后也可能被当成新的启动请求。
|
||
|
||
### 7.4 直连模式下协议字段与功能差异
|
||
|
||
下表说明数据和代码路径是否存在,不代表当前版本已经允许运动。第 7.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”直连。
|
||
|
||
### 7.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` 不能证明数据仍然新鲜。
|
||
|
||
所以当前纯直连配置只能按第 7.3 节以 monitor-only 验证链路。正式启用前必须实现仅作用于
|
||
`transport="zmq"` 的断流门控,至少满足:
|
||
|
||
1. 陈旧样本不得继续 Z+C 或右 B 计时;
|
||
2. 已武装时陈旧输入必须立即发布零速、解除双臂/手发布并锁定为需要重新松开、长按;
|
||
3. 网络恢复不得自动恢复原 armed 会话;
|
||
4. 阈值应作为 ZMQ 专用配置经现场验证,不能把已删除的通用 0.25 秒门控悄悄加回来;
|
||
5. 完成断网、拔线、xTELE 停止和恢复的无运动测试后,才能重新启用
|
||
`tg3-local-teleop.service --allow-publish`,行走还需单独验证零速帧。
|
||
|
||
这不是厂家默认保护的变化;厂家关节限位、电机、碰撞和手部保护仍保持原样。
|
||
|
||
### 7.6 从纯直连恢复公网 OmniSocket
|
||
|
||
先正常 STOP、完成 Home 并保持 Z+C 松开,然后把机器人恢复为:
|
||
|
||
```toml
|
||
[network]
|
||
transport = "omnisocket"
|
||
|
||
[locomotion]
|
||
enabled = true # 仅在现场仍需要并已确认安全时恢复
|
||
```
|
||
|
||
确认保留的 `omnisocket_server`、双方 Peer ID 仍匹配。按“先机器人接收端、后 EAI
|
||
sender”的顺序恢复:
|
||
|
||
```bash
|
||
# 机器人
|
||
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 前发送业务数据。
|
||
|
||
## 8. 新机器人首次现场验收顺序
|
||
|
||
全程确认防护、活动空间、急停和 HBWALK 状态。
|
||
纯 ZMQ 当前版本若尚未完成第 7.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 断线:EAI sender 的 KCP
|
||
反馈超时约为 500 ms,触发后会作废 session;机器人若持续约 2 秒收不到活动帧,会另行
|
||
重建我们的接收桥。不应期待断线后透明续控;恢复后先确认未武装,稳定松开 Z+C 后再重新长按
|
||
启动。纯 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 范围。
|
||
|
||
## 9. 常见问题
|
||
|
||
### 机器人 SSH IP 变了,需要改 `config.toml` 吗?
|
||
|
||
公网 OmniSocket 模式不需要。只修改 SSH 命令中的地址。运行时机器人主动连接 Hub。
|
||
|
||
### EAI IP 变了,需要改 `tcp://127.0.0.1:5003/5001` 吗?
|
||
|
||
公网 OmniSocket sender 不需要修改:`127.0.0.1` 永远表示 EAI 本机,和网卡地址无关。
|
||
第 6 节本地 OmniSocket Hub 模式下,EAI sender 仍使用 `127.0.0.1:14049`,但机器人
|
||
`omnisocket_server` 使用 EAI 局域网地址;EAI 地址变化时只改机器人这一项并重启桥。
|
||
第 7 节纯 ZMQ 直连同理需要修改机器人 `iarm_endpoint`。
|
||
|
||
### 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 自由度映射,需要
|
||
单独实现适配后再部署。
|
||
|
||
## 10. 迁移时真正需要修改的最小清单
|
||
|
||
同一 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`。
|
||
|
||
从公网切换为第 6 节本地 OmniSocket Hub 时,最少需要:
|
||
|
||
1. 在 EAI 部署固定提交的完整 OmniSocketGo 并编译 `bin/kcpserver`;
|
||
2. 启用 `tg3-omnisocket-hub.service`,监听 UDP `0.0.0.0:14049`;
|
||
3. 把 EAI sender `--server` 改为 `127.0.0.1:14049`;
|
||
4. 保持机器人 `transport="omnisocket"`,把 `omnisocket_server` 改为
|
||
`<EAI局域网IP>:14049`;
|
||
5. Peer ID、5003/5001、Home、手部与行走配置全部保持不变;
|
||
6. 防火墙只允许机器人局域网地址访问 EAI UDP 14049。
|
||
|
||
完全不经过 Hub、切换为第 7 节纯 ZMQ 直连时,最少修改机器人
|
||
`network.transport="zmq"`、`network.iarm_endpoint="tcp://<EAI局域网IP>:5003"`,并在
|
||
当前没有直连断流门控的版本中设置 `locomotion.enabled=false`,同时停用 EAI 的
|
||
`tg3-omnisocket-sender.service`,并仅以机器人 monitor-only 模式验证;完成第 7.5 节的
|
||
ZMQ 专用断流门控前不得启用运动发布。
|
||
|
||
## 11. 数采部署与迁移
|
||
|
||
数采是本项目新增功能,不调用 `/bag_record/control/notify`,也不停止或修改 Ubuntu 厂家
|
||
`record_bag_node`。Nvidia 独立录制,PS 本机负责把完成数据同步到:
|
||
|
||
```text
|
||
/home/ps/Desktop/TG3_TS1P_OmniSocket_Teleop/Data_Get
|
||
```
|
||
|
||
### 11.1 机器人 Nvidia
|
||
|
||
部署 `tg3_local_teleop/` 全目录,至少必须包含:
|
||
|
||
```text
|
||
tg3_local_teleop.py
|
||
data_collection.py
|
||
data_recorder_protocol.py
|
||
data_recorder_node.py
|
||
config.toml
|
||
run.sh
|
||
run_data_recorder.sh
|
||
wait_ros_ready.sh
|
||
tg3-local-teleop.service
|
||
tg3-data-recorder.service
|
||
ros2_py/
|
||
```
|
||
|
||
目标路径固定为 `/home/nvidia/tg3_local_teleop`。先按原项目步骤构建 `ros2_py`,再安装:
|
||
|
||
```bash
|
||
mkdir -p ~/.config/systemd/user
|
||
cp /home/nvidia/tg3_local_teleop/tg3-data-recorder.service \
|
||
/home/nvidia/tg3_local_teleop/tg3-local-teleop.service \
|
||
~/.config/systemd/user/
|
||
systemctl --user daemon-reload
|
||
systemctl --user enable --now tg3-data-recorder.service
|
||
systemctl --user restart tg3-local-teleop.service
|
||
```
|
||
|
||
录制脚本必须能依次加载 `/opt/ros/jazzy`、`/home/nvidia/xos`、
|
||
`/opt/robot_tele_server/install` 和本项目 `ros2_py/install`;否则自定义消息可能无法解码。
|
||
还需 Python 3 的 PyYAML(Ubuntu 包 `python3-yaml`)解析 rosbag metadata。
|
||
迁移时在 `config.toml [data_collection]` 核对 `base_directory`、20 GiB 余量、30 分钟上限、
|
||
明确 topic 白名单和 required topics。不要改成 `ros2 bag record -a`,相机/点云需另行估算
|
||
带宽和磁盘后再加入。
|
||
|
||
### 11.2 PS 本机
|
||
|
||
项目需包含 `tg3_data_collection/` 和 `Data_Get/`。确认到新 Nvidia 的免密 SSH 后安装:
|
||
|
||
```bash
|
||
ssh -o BatchMode=yes nvidia@192.168.41.2 true
|
||
mkdir -p ~/.config/systemd/user
|
||
cp tg3_data_collection/tg3-data-get-sync.service ~/.config/systemd/user/
|
||
systemctl --user daemon-reload
|
||
systemctl --user enable --now tg3-data-get-sync.service
|
||
```
|
||
|
||
机器人 SSH IP 改变时,只改同步 unit;最简命令(替换两个地址)是:
|
||
|
||
```bash
|
||
sed -i 's/nvidia@旧IP/nvidia@新IP/g' \
|
||
~/.config/systemd/user/tg3-data-get-sync.service
|
||
systemctl --user daemon-reload
|
||
systemctl --user restart tg3-data-get-sync.service
|
||
```
|
||
|
||
这不修改 OmniSocket Hub、Peer ID 或机器人 `config.toml`。若 PS 用户名/项目路径改变,
|
||
同时修改 unit 的 `WorkingDirectory`、脚本路径和 `--destination`。
|
||
|
||
### 11.3 操作与验收
|
||
|
||
1. 保持 L3 松开,长按 Z+C 3 秒正常开启遥操;
|
||
2. 左摇杆按下(L3)连续 1 秒开始数采;该键是 `button_joystick.left`,不是 X/Y/Z;
|
||
3. 松开 L3 至少 0.5 秒,再长按 1 秒结束;或正常 Z+C 结束遥操自动收尾;
|
||
4. 查看 Nvidia `/tg3/data_collection/status`,必须先到 `ready`,不能从 `active/` 取数据;
|
||
recorder 会同时要求 required topics 有实时发布者且最终消息计数大于零;
|
||
5. 查看本机 `Data_Get/sync_status.json`,最终目录必须有 `READY`、`manifest.json`、
|
||
`bag/metadata.yaml` 和非空 `*.mcap`;
|
||
6. 执行 `ros2 bag info <episode>/bag` 并确认所需 topic 有消息;
|
||
7. 断开 PS 网络再采一条,确认 Nvidia 保留数据;恢复网络后应续传且 SHA-256 通过。
|
||
|
||
每个新会话先要求 L3 稳定松开 0.5 秒,同一次持续按压只切换一次。数采故障不得解除
|
||
遥操或延迟 STOP/Home;桥心跳中断超过 3 秒时 recorder 会自行 SIGINT 收尾。机器人
|
||
`ready/` 不自动删除,确认本机和外部备份后才按具体 episode 清理。
|