chore: remove obsolete submodule and docs
This commit is contained in:
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -1,4 +0,0 @@
|
||||
[submodule "OmniSocketGo"]
|
||||
path = OmniSocketGo
|
||||
url = https://gitea.public.snrc.site/limingjie/OmniSocketGo.git
|
||||
branch = c
|
||||
Submodule OmniSocketGo deleted from de3f5c9677
@@ -1,168 +0,0 @@
|
||||
# 天工 3.0 `joystick_bridge` 与 `/sbus_data` 证据记录
|
||||
|
||||
记录时间:2026-08-07
|
||||
|
||||
本文只区分三类结论:SDK 文档明确说明、机器人运行时直接观测、尚未证明。不能用 ROS
|
||||
节点存在某个订阅或发布端,代替对其内部算法的证明。
|
||||
|
||||
## 1. 对此前说法的证据审计
|
||||
|
||||
|此前说法|目前证据|结论|
|
||||
|---|---|---|
|
||||
|`joystick_bridge` 处理按键|它订阅 `/sbus_data`;SDK 定义 A~H 语义;实机 `bridge_config.yaml` 给出 A~H 的规则|已证明|
|
||||
|它处理“持续按住”条件|实机 YAML 配置 `a/b/c` 长按阈值分别为 `1.0/1.0/0.5 s`,并给出 `press_state` 规则|已证明厂商遥控器长按机制;与本地 xTELE 的 3 秒保护不是同一机制|
|
||||
|它进行 `/robot_state` 状态检查|运行中的节点确实订阅 `/robot_state`|只证明订阅;如何检查、检查哪些字段尚未证明|
|
||||
|它进行速度缩放和方向映射|已只读取得 `/home/ubuntu/data/param/bridge_config.yaml`,其中包含状态速度上限、偏置和速度处理流水线参数|已证明配置能力;核心算法在编译包中|
|
||||
|它发布 `/fsm_state_cmd`、`/fsm_resume_cmd`、`/stand_cmd`|运行中的 `ros2 node info /joystick_bridge` 直接列出这三个发布端|已证明发布能力;触发条件和消息内容尚未证明|
|
||||
|它有特定行走启停顺序|YAML 的 `fsm_command_bindings` 明确列出状态规则和持续速度动作|已证明配置规则;未做带运动的完整时序采样|
|
||||
|
||||
因此可以准确地说:`joystick_bridge` 是厂商 SBUS 遥控器适配器,包含按键规则、状态命令
|
||||
和速度计算配置。但二次开放文档同时提供独立的 `/hric/robot/cmd_vel` topic 接口,本地
|
||||
xTELE 桥不必伪装成 SBUS 遥控器。
|
||||
|
||||
## 2. SDK 文档证据
|
||||
|
||||
来源:`具身天工3.0+SDK+文档(26.04.x)+(1).md` 第 299~319 行。
|
||||
|
||||
文档明确规定:
|
||||
|
||||
- `/sbus_data` 类型为 `sensor_msgs/msg/Joy`;
|
||||
- `axes` 包含 12 个 `float32`,取值范围 `[-1.0, 1.0]`;
|
||||
- `buttons` 为空,不使用;
|
||||
- `/sbus_data/event` 类型为 `bodyctrl_msgs/msg/SbusData`;
|
||||
- 事件消息包含 A~H 的状态,以及 `x1/y1/x2/y2` 四个摇杆轴;
|
||||
- 四个摇杆轴范围为 `[-1.0, 1.0]`,直接透传、不滤波。
|
||||
|
||||
文档没有给出 `/sbus_data.axes[0..11]` 与 `x1/y1/x2/y2/A..H` 的逐项下标映射,
|
||||
因此不能只根据字段数量猜测 12 个下标。
|
||||
|
||||
## 3. 机器人运行时证据
|
||||
|
||||
在 Nvidia 侧加载机器人 ROS 环境后执行:
|
||||
|
||||
```bash
|
||||
ros2 node info /joystick_bridge
|
||||
ros2 param get /joystick_bridge config_file
|
||||
ros2 param get /joystick_bridge joy_topic
|
||||
ros2 topic info -v /sbus_data
|
||||
```
|
||||
|
||||
观测结果:
|
||||
|
||||
```text
|
||||
/joystick_bridge subscribers:
|
||||
/robot_state: ros2_bridge_msgs/msg/RobotState
|
||||
/sbus_data: sensor_msgs/msg/Joy
|
||||
|
||||
/joystick_bridge publishers:
|
||||
/hric/robot/cmd_vel: geometry_msgs/msg/TwistStamped
|
||||
/hric/robot/fsm_resume_cmd: std_msgs/msg/String
|
||||
/hric/robot/fsm_state_cmd: std_msgs/msg/String
|
||||
/hric/robot/stand_cmd: geometry_msgs/msg/TwistStamped
|
||||
(另有双臂、头、腰和双手控制话题)
|
||||
|
||||
config_file = /home/ubuntu/data/param/bridge_config.yaml
|
||||
joy_topic = /sbus_data
|
||||
```
|
||||
|
||||
`/sbus_data` 当前只有一个发布者 `/joystick`,QoS 为 `RELIABLE/VOLATILE`。空闲帧实测为:
|
||||
|
||||
```yaml
|
||||
axes: [-0.0, -0.0, -0.0, -0.0, -1.0, -0.0, -1.0, -0.0,
|
||||
-1.0, -1.0, -1.0, -1.0]
|
||||
buttons: []
|
||||
```
|
||||
|
||||
对应时刻 `/sbus_data/event` 的语义状态为:
|
||||
|
||||
```yaml
|
||||
button_a: -1
|
||||
button_b: -1
|
||||
button_c: -1
|
||||
button_d: -1
|
||||
button_e: -1
|
||||
button_f: 0
|
||||
button_g: 0
|
||||
button_h: -1
|
||||
x1: -0.0
|
||||
y1: -0.0
|
||||
x2: -0.0
|
||||
y2: -0.0
|
||||
```
|
||||
|
||||
这组同时采样可作为空闲状态基准,但不足以单独反推出所有按键下标和状态编码;需要读取
|
||||
`bridge_config.yaml`,或对原遥控器逐键采样。
|
||||
|
||||
## 4. 同构臂侧是否具备生成 SBUS 输入的数据
|
||||
|
||||
EAI 上 xTELE 原始流 `tcp://127.0.0.1:5003` 的一帧实测包含:
|
||||
|
||||
```text
|
||||
joystick = {'left': [-0.009, 0.012], 'right': [-0.059, 0.011]}
|
||||
button = {'left': [0, 0, 0, 0, 0], 'right': [0, 0, 0, 0, 0]}
|
||||
```
|
||||
|
||||
同一帧还包含 `button_joystick`、`button_wheel`、`scroll`、`trigger` 等输入。因此:
|
||||
|
||||
- 如果“灵巧手”指同构臂手柄:可以取得左右摇杆和实体按键原始数据,数据源足够构造
|
||||
`sensor_msgs/msg/Joy`;
|
||||
- 如果“灵巧手”指机器人 BrainCo 灵巧手:不可以。灵巧手只提供电机位置/状态和触觉等,
|
||||
不会产生遥控器摇杆与 A~H 开关数据;
|
||||
- xTELE 按键是布尔输入,而 SBUS 中含二档、三档开关语义。需要通过明确映射或本地状态机
|
||||
转换,不能把布尔数组直接当成 12 个 SBUS 轴发布。
|
||||
|
||||
## 5. 本地桥不再发布 FSM 命令
|
||||
|
||||
已从 `tg3_local_teleop.py` 删除:
|
||||
|
||||
- `std_msgs/msg/String` FSM 发布器;
|
||||
- `gotoHBWALK` 消息构造与重复发布;
|
||||
- FSM burst、间隔和等待参数。
|
||||
|
||||
当前桥只在机器人已经报告 `HBWALK/running` 且安全门通过时发布
|
||||
`/hric/robot/cmd_vel`,释放操作后仍发送限量零速度帧。
|
||||
|
||||
本地公网链路的唯一 3 秒门控现位于 EAI:左 Z + 右 C 产生 START/STOP 会话,待机不发送
|
||||
xTELE 业务帧。会话启动后,右 C + 左摇杆在机器人端即时映射到 `/hric/robot/cmd_vel`;
|
||||
松开立即零速,再次操作不重新计时。
|
||||
|
||||
部署后运行时检查 `/hric/robot/fsm_state_cmd` 只有厂商节点
|
||||
`control_forward` 与 `joystick_bridge` 两个发布者,不再包含 `tg3_local_teleop`;状态文件同时显示:
|
||||
|
||||
```text
|
||||
locomotion_fsm_publish_enabled = false
|
||||
```
|
||||
|
||||
## 6. 最终采用 direct topic,而不是模拟 `/sbus_data`
|
||||
|
||||
`twice dev.pdf` 明确规定 `/hric/robot/cmd_vel` 为
|
||||
`geometry_msgs/msg/TwistStamped`,其中 `linear.x/linear.y/angular.z` 分别控制前后、侧移和
|
||||
转向。运行中的 `/hric_topic_bridge` 也直接订阅该话题。因此本项目继续使用 direct topic,
|
||||
不增加第二个 `/sbus_data` 发布者,避免与原 `/joystick` 的约 43 Hz 数据交错。
|
||||
|
||||
实机 xmigcs `dex_config.yaml` 原先把 HBWALK 的四个速度上限全部设为零,这才是 HBWALK
|
||||
topic 无法行走的关键配置。2026-08-07 已按文档把 HBWALK 上限改为当前 NAVIGATE 同值,
|
||||
并保留原配置备份。`twice dev.pdf` 第 1 页规定半身行走 Topic 的 `linear.x` 范围为
|
||||
`[-0.8, 1.0] m/s`、`angular.z` 范围为 `[-0.8, 0.8] rad/s`;本地桥现按这组官方 Topic
|
||||
范围做前进/后退非对称限幅,不发布 `linear.y`。
|
||||
|
||||
## 7. xmigcs 配置的加载与重启边界
|
||||
|
||||
`dex_config.yaml` 只在 xmigcs 初始化时由 `robot_interface.init()` 读取,当前节点没有动态
|
||||
reload 参数、service 或 action。现场固件的 `/proc_manager/config/notify` 也不是进程
|
||||
启停接口:其回调只记录 String 内容并重新读取 proc_manager 自身的固定
|
||||
`proc_manager.json`。曾尝试向该话题发送 `CMD_STOP_PROC/CMD_START_PROC` JSON,实测
|
||||
xmigcs PID 始终为 `3269`,日志也没有任何启停记录;该用法已确认无效并从部署说明删除。
|
||||
|
||||
当前固件没有启用内部遗留 `OnRequest` 的 fd 通道,也没有单进程 ROS service、action、
|
||||
监听端口或 CLI。因此加载新 YAML 应使用厂商真实生命周期:先退出遥操,按原流程切到
|
||||
`48V Off`,由 proc_manager 停止 `rl` 与 `robot_control`,再恢复 48V 并完成原有物理启动
|
||||
动作。只有 xmigcs 出现新的 PID/启动时间,才表示新配置已经进入运行态。不要直接 kill
|
||||
xmigcs,也不要伪造 `/robotcontrol_state`。
|
||||
|
||||
2026-08-07 14:32 的实际重启结果为 PID `3125`。新日志明确打印 HBWALK 已加载
|
||||
`max_x_plus=1.2`、`max_x_minus=0.6`、`max_y=0.6`、`max_yaw=1.0`,随后完成
|
||||
Robot interface、SHM RPC 与 100 Hz 控制线程初始化,并进入 `HBWALK`。该进程会把
|
||||
Linux `comm` 名称设为 `xmigcs`,因此 `ps -C python3` 可能无输出;应使用
|
||||
`ps -C xmigcs -o pid,lstart,cmd` 或上述精确 `pgrep`。本机切断动力电源时 Ubuntu/网络也
|
||||
可能同时离线,断电期间 SSH 失败属于正常现象,应在重新上电并完成启动后检查。
|
||||
@@ -1,354 +0,0 @@
|
||||
# 天工 3.0 本地同构臂遥操部署汇报
|
||||
|
||||
日期:2026-08-06
|
||||
设备:天工 3.0(HBWALK)+ TS1P 同构臂 + BrainCo Revo2 双灵巧手
|
||||
|
||||
## 1. 最终结果
|
||||
|
||||
已实现不依赖厂商“智能驾驶舱平台”配对的本地双臂、双手遥操。运行时链路为:
|
||||
|
||||
```text
|
||||
TS1P 同构臂
|
||||
-> EAI 原厂 xTELE
|
||||
-> tcp://127.0.0.1:5003(原始关节、按键和诊断,仅 EAI 机内)
|
||||
-> tcp://127.0.0.1:5001(xTELE 处理后的双手目标,仅 EAI 机内)
|
||||
-> 发送器仅把 5001 的 hand.position 合并到 5003 原始帧
|
||||
-> tg3-omnisocket-sender
|
||||
-> OmniSocket / KCP(UDP)
|
||||
-> 175.178.116.187:14049 公网 Hub
|
||||
-> 机器人内 tg3_local_teleop 直接接收 OmniSocket
|
||||
-> /encoder_identical_joint(双臂 14 维 JointState)
|
||||
-> 原厂 freq_change_tg3_node
|
||||
-> /arm/cmd
|
||||
-> 天工 3.0 双臂
|
||||
|
||||
同一个 tg3_local_teleop
|
||||
-> /left_hand/set_motor_multi
|
||||
-> /right_hand/set_motor_multi
|
||||
-> 原厂 BrainCo Revo2 双手驱动
|
||||
```
|
||||
|
||||
机器人端不再设置单独的 `tg3-omnisocket-receiver.service`,OmniSocket 接收、校验和
|
||||
ROS 发布都在 `tg3_local_teleop` 内完成。开发电脑不参与运行链路,只保存源码和本报告。
|
||||
|
||||
## 2. 为什么采用这条链路
|
||||
|
||||
### 2.1 保留原厂 xTELE 与机器人控制栈
|
||||
|
||||
TS1P 的串口/CAN、关节标定、按键、扳机和错误状态已经由原厂 xTELE 正确处理。xTELE
|
||||
当前安装版本的核心模块是编译后的扩展,直接修改或替换会增加标定、按键兼容和设备安全
|
||||
风险,因此保留原程序及配置,不修改其源码。
|
||||
|
||||
机器人端也继续使用原厂 `freq_change_tg3_node`、`/arm/cmd`、BrainCo 驱动及其默认
|
||||
限位、电流、堵转和碰撞保护。本项目只在原厂已有输入接口之前增加网络桥和安全门控。
|
||||
|
||||
### 2.2 为什么链路中仍能看到 TCP
|
||||
|
||||
`tcp://127.0.0.1:5003` 和 `tcp://127.0.0.1:5001` 都是 xTELE 已有的本机 ZMQ
|
||||
发布接口,地址为回环地址:
|
||||
|
||||
- 数据不会离开 EAI 工控机;
|
||||
- 它不是 EAI 到机器人之间的网络传输;
|
||||
- 保留它可以避免修改编译后的 xTELE;
|
||||
- 真正跨机器、跨公网的部分使用 OmniSocket KCP/UDP。
|
||||
|
||||
如果连这段本机 TCP 也删除,就必须修改或替换原厂 xTELE,违背“不改原有代码”的约束。
|
||||
|
||||
### 2.3 为什么不直接使用原无线 UDP
|
||||
|
||||
普通点对点 UDP 适合同一局域网,但公网环境会遇到 NAT、地址变化、丢包、乱序和重传问题。
|
||||
OmniSocket 使用固定 Peer ID 经过 KCP Hub 转发,提供有序传输、丢包重传、会话注册和统计,
|
||||
因此同一套代码可通过 Wi-Fi、有线互联网运行,不要求机器人与 EAI 位于同一网段。
|
||||
|
||||
当前 Peer 配置:
|
||||
|
||||
| 项目 | 值 |
|
||||
|---|---|
|
||||
| Hub | `175.178.116.187:14049` |
|
||||
| EAI Peer ID | `tg3-009027fa8190-iarm` |
|
||||
| 机器人 Peer ID | `tg3-009027fa8190-robot` |
|
||||
| EAI 本机 xTELE 原始数据 | `tcp://127.0.0.1:5003` |
|
||||
| EAI 本机 xTELE 处理后命令 | `tcp://127.0.0.1:5001`(只合并 `hand.position`) |
|
||||
|
||||
## 3. 端到端频率
|
||||
|
||||
不同位置的“频率”含义不同,不能只用一个数表示整条链路。
|
||||
|
||||
| 环节 | 频率/策略 | 说明 |
|
||||
|---|---:|---|
|
||||
| TS1P 关节采样 `freq` | 现场约 `80~92 Hz` | xTELE JSON 自带的左右臂/CAN采样频率;本次抓帧为 `91.405 Hz`,启动最低门槛为 `30 Hz` |
|
||||
| xTELE ZMQ 发布 | 实测 `98.02 Hz` | 连续接收 500 帧耗时 5.101 秒 |
|
||||
| xTELE 处理后命令 `5001` | 现场约 `50 Hz` | 只取最新有效双手目标,最大允许年龄 `0.25 s` |
|
||||
| EAI OmniSocket 发送 | 待机 `0 Hz`,遥操约 `98~100 Hz` | Z+C 3 秒后才连接并逐帧发送;STOP 刷新后关闭 Session,待机无注册/心跳 |
|
||||
| 机器人 OmniSocket 接收 | 待机无业务帧,遥操约 `100 Hz` | 网络状况变化时会波动;待机无帧不再被判为故障 |
|
||||
| 本地桥双臂 ROS 发布 | `50 Hz` | 仅合法新会话通过启动门控后向 `/encoder_identical_joint` 发布 |
|
||||
| 本地桥双手 ROS 发布 | `50 Hz` | 与双臂共用同一次武装;BrainCo 指令同频发布 |
|
||||
| 原厂双臂频率转换 | `200 Hz` | 由原厂 `freq_change_tg3_node` 完成同步、滤波并输出 `/arm/cmd` |
|
||||
| BrainCo 状态反馈 | `30 Hz` | 原厂 `brainco_hand.yaml` 的 `publish_hz` |
|
||||
|
||||
这里的 `98~100 Hz` 是现场测量值而非硬实时保证;公网延迟、Hub 负载和系统调度都会造成
|
||||
小幅波动。控制桥以“最新帧”为准,不排队回放旧动作。
|
||||
|
||||
## 4. 数据格式
|
||||
|
||||
### 4.1 xTELE 原始 JSON
|
||||
|
||||
xTELE 每帧发布 UTF-8 JSON。现场帧的结构如下(数值仅作格式示例):
|
||||
|
||||
```json
|
||||
{
|
||||
"timestamp": 1786018731538,
|
||||
"isomorphic_arm_id": "IArm009027FA8190",
|
||||
"isomorphic_arm_type": "TS1P",
|
||||
"arm": {
|
||||
"position": {
|
||||
"left": [0.021, 0.021, 0.499, -0.153, -0.442, 0.183, 0.060],
|
||||
"right": [-0.021, -0.003, -0.683, -0.206, 0.874, 0.069, -0.160]
|
||||
}
|
||||
},
|
||||
"hand": {"position": {"left": 0.0, "right": 0.0}},
|
||||
"waist": {"position": 0.236},
|
||||
"servo_error": {
|
||||
"left": [0, 0, 0, 0, 0, 0, 0],
|
||||
"right": [0, 0, 0, 0, 0, 0, 0],
|
||||
"waist": [0]
|
||||
},
|
||||
"freq": {"left": 91.405, "right": 91.405, "waist": 91.405},
|
||||
"button": {
|
||||
"left": [0, 0, 0, 0, 0],
|
||||
"right": [0, 0, 0, 0, 0]
|
||||
},
|
||||
"trigger": {"left": 0.0, "right": 0.0},
|
||||
"joycan_error": [0, 0]
|
||||
}
|
||||
```
|
||||
|
||||
原帧还包含 `scroll`、`joystick`、`button_joystick`、`button_wheel`、`vibration_mode`、
|
||||
`total_current` 和 `total_power`。发送端保留 5003 的双臂、按键、诊断等字段,只用 5001
|
||||
同一时刻的处理结果替换 `hand.position`,并增加 `tg3_transport` 来源标记。机器人桥仅消费
|
||||
本项目所需字段:
|
||||
|
||||
- `arm.position.left/right`:左右各 7 个关节,单位为弧度;
|
||||
- `hand.position.left/right`:未选择组合手势时为 `0~1` 扳机开合量;选择手势后可为厂家
|
||||
xTELE 生成的 6 维 BrainCoRevo2 归一化目标;
|
||||
- `button.left/right`:左侧顺序以 X/Y/Z 开头,右侧以 A/B/C 开头;索引 2 即 Z/C;
|
||||
- `servo_error`、`joycan_error` 和 `freq`:启动与运行安全门控;
|
||||
- `isomorphic_arm_id/type`:设备身份校验。
|
||||
|
||||
腰、头、腿和行走数据不由本桥控制。
|
||||
|
||||
### 4.2 OmniSocket 二进制封包
|
||||
|
||||
EAI 在原 JSON 前增加 24 字节网络序头部,格式为 `!4sQQI`:
|
||||
|
||||
| 偏移 | 长度 | 类型 | 含义 |
|
||||
|---:|---:|---|---|
|
||||
| 0 | 4 | bytes | 固定魔数 `TG3A` |
|
||||
| 4 | 8 | uint64 | 单调递增序列号 |
|
||||
| 12 | 8 | uint64 | EAI 发送时间 `time.time_ns()` |
|
||||
| 20 | 4 | uint32 | 后续 JSON 字节长度 |
|
||||
| 24 | 可变 | bytes | 原始 UTF-8 JSON |
|
||||
|
||||
JSON 内的 `tg3_transport` 由 EAI sender 强制覆盖,包含协议版本 `2`、128-bit 随机
|
||||
`session_id`、会话内递增 `session_seq` 和 `session_state=start|active|stop`。START
|
||||
连续发送 50 个源帧,机器人对每个 ID 只执行一次启动安全检查;STOP 是最后一个业务帧。
|
||||
旧 ID、缺少 START 的 ACTIVE、错 ID 的 STOP 或伪造的源 metadata 均不能武装机器人。
|
||||
|
||||
单帧 JSON 上限为 1 MiB。机器人端依次检查发送 Peer、消息类型、魔数、长度、JSON
|
||||
结构、设备 ID、序列号和包龄。由于 EAI 与机器人系统时钟可能存在固定偏差,包龄使用
|
||||
“当前包原始年龄减去本会话最小年龄”的相对值;额外排队超过 `300 ms` 的包会被丢弃。
|
||||
|
||||
### 4.3 ROS 双臂格式
|
||||
|
||||
机器人桥发布 `sensor_msgs/msg/JointState`:
|
||||
|
||||
- Topic:`/encoder_identical_joint`;
|
||||
- `header.frame_id`:`tg3_local_teleop`;
|
||||
- `name`:`left_joints_0..6`、`right_joints_0..6`;
|
||||
- `position`:14 个弧度值,先左臂后右臂;
|
||||
- `velocity`:14 个零值,保持原厂位置控制路径。
|
||||
|
||||
原厂节点继续负责转换为电机 11..17、21..27 的 `/arm/cmd`。
|
||||
|
||||
### 4.4 BrainCo 双手格式
|
||||
|
||||
双手分别发布:
|
||||
|
||||
- `/left_hand/set_motor_multi`;
|
||||
- `/right_hand/set_motor_multi`;
|
||||
- 类型:`brainco_hand_msgs/msg/SetMotorMulti`;
|
||||
- `mode=5`(位置 + 期望时间);
|
||||
- `positions`:6 个 `1~1000` 位置值;
|
||||
- `durations`:6 个 `800 ms`;
|
||||
- `speeds/currents/pwms`:均为 0,由原厂位置+时间模式处理。
|
||||
|
||||
一维扳机值映射如下:
|
||||
|
||||
| 扳机 | 含义 | 六电机目标 |
|
||||
|---:|---|---|
|
||||
| `0` | 现场实测默认打开位 | `[401, 401, 51, 51, 51, 51]` |
|
||||
| `1` | 保守常规闭合抓握 | `[900, 500, 451, 520, 520, 451]` |
|
||||
|
||||
中间值线性插值。手部从机器人实测位置开始,每秒最多变化 400 个位置单位。BrainCo
|
||||
状态 `0=空闲`、`1=运动`、`2=接触/堵转或到限位`、`3=持续力` 均为原厂正常状态;
|
||||
仅状态失联或未知/非法值会触发本地停止,原厂电流、堵转和限位保护保持不变。
|
||||
|
||||
xTELE 已注册的手势组合键由工控机原程序负责短按/长按、互斥和手势编号判定。选中手势后,
|
||||
5001 的 `hand.position.left/right` 会变为 6 维数组,机器人桥直接换算为 BrainCo 的
|
||||
`1~1000` 位置值;本项目不再在机器人端复刻组合键状态机。5002 的日志、帮助、RGB/D、
|
||||
关节浮层等 `webui` 事件不发送到机器人;腰和头不接入本地桥。HBWALK 行走使用 5003
|
||||
传输的原始右 C 与左摇杆;遥操开启后按键和摇杆在下一个 50 Hz 周期即时解析并发布
|
||||
`geometry_msgs/msg/TwistStamped` 到 `/hric/robot/cmd_vel`,不再叠加第二个 3 秒计时。
|
||||
|
||||
## 5. 启停、回 Home 与安全逻辑
|
||||
|
||||
### 5.1 操作方式
|
||||
|
||||
1. 机器人进入 `HBWALK`,状态为 `running`;
|
||||
2. 两个扳机先松开;
|
||||
3. 同时长按左 Z + 右 C 3 秒,EAI 生成 START 会话并开始发送,机器人通过启动门控后
|
||||
启动双臂和双手跟随;
|
||||
4. 左扳机控制左手,右扳机控制右手,松开为张开、扣下为闭合;
|
||||
5. 行走时按住右 C 并推出左摇杆即刻响应;上下为前后、左右为转向;
|
||||
6. 松开 C 或摇杆回中立即停走,再次操作无需重新等待;
|
||||
7. 再次长按左 Z + 右 C 3 秒发送 STOP;STOP 后 EAI 不再发送 xTELE 业务数据;
|
||||
8. 停止后双臂以 `0.25 rad/s` 限速返回现场保存的 Home 姿态,手保持最后目标。
|
||||
|
||||
行走以 50 Hz 发布,死区为 0.2,二次曲线,并按官方半身行走 Topic 范围限制为前进
|
||||
`1.0 m/s`、后退 `0.8 m/s`、转向 `0.8 rad/s`;
|
||||
停止时立即发零速并补发 10 帧。已安装的 xTELE 0.1.2 没有注册右侧同手 `C+A`,所以
|
||||
本地桥也不猜测其含义、不对它执行状态切换。
|
||||
|
||||
服务随系统自动启动只代表“等待数据并监测”,不会自动武装,也不会绕过物理长按。
|
||||
|
||||
### 5.2 本地门控
|
||||
|
||||
启动前要求:
|
||||
|
||||
- 当前状态和子状态均为 `HBWALK`,运行状态为 `running`;
|
||||
- xTELE 数据新鲜,设备 ID/type 正确,采样频率不低于 30 Hz;
|
||||
- 同构臂 CAN、双臂电机反馈无错误;
|
||||
- BrainCo 双手状态反馈新鲜且完整;
|
||||
- 启动瞬间 14 个同构臂目标位于天工 3.0 文档关节范围内;
|
||||
- 没有检测到第二路云端/外部手臂或灵巧手命令源。
|
||||
|
||||
自定义关节目标限位只在启动时检查;采集/跟随期间不重复增加该限位。运行时仍持续检查
|
||||
HBWALK、数据失联、CAN/电机错误和命令源冲突,原厂默认保护没有修改。
|
||||
|
||||
首次启动时,双臂限速器从机器人实时关节位置开始,双手限速器从实时手指位置开始,
|
||||
避免第一帧直接跳到同构臂目标。
|
||||
|
||||
### 5.3 断线处理
|
||||
|
||||
- 活动会话的同构臂输入超过 `0.25 s` 未更新:立即解除武装并停止发布;
|
||||
- 活动会话超过 `2 s` 仍没有新帧才重建机器人接收进程;待机或 STOP 后无业务帧是正常状态;
|
||||
- 只有匹配的操作员 STOP 触发自动 Home,意外断网只停控;Home 继续依赖机器人反馈,
|
||||
不再依赖已经停止的 EAI 数据;
|
||||
- 公网 Hub 重启后,建议重启 EAI 发送服务以清空 KCP 旧队列:
|
||||
|
||||
```bash
|
||||
systemctl --user restart tg3-omnisocket-sender.service
|
||||
```
|
||||
|
||||
本次服务器恢复后重启发送服务,KCP 状态恢复为反馈约 6 ms、发送队列 0;机器人随后恢复
|
||||
约 100 Hz 收包并通过安全门控。
|
||||
|
||||
## 6. EAI 工控机上完成的操作
|
||||
|
||||
运行账号:`eai`
|
||||
|
||||
1. 保留原厂目录 `/home/eai/dev/sysEAI`、`xtele_main.py`、TS1P 标定和
|
||||
`/home/eai/.config/xhumanoid/xtele/default.toml`,未修改原厂控制源码;
|
||||
2. 确认系统级 `xtele-monitor.service` 已启用并运行,它调用原有
|
||||
`/home/eai/dev/sysEAI/start_xtele.sh`;
|
||||
3. 部署 OmniSocketGo Python 运行库到 `/home/eai/OmniSocketGo`;
|
||||
4. 新增 `/home/eai/tg3_omnisocket_transport/omnisocket_xtele_sender.py`:
|
||||
- 订阅 `tcp://127.0.0.1:5003` 原始帧;
|
||||
- 订阅 `tcp://127.0.0.1:5001` 处理后命令,只提取双侧 `hand.position`;
|
||||
- 在 EAI 本机用 Z+C 连续 3 秒生成唯一 START/STOP 会话;待机仍读本地数据但不上公网;
|
||||
- 保留 5003 的双臂、按键、摇杆和 CAN/舵机诊断,用 5001 的厂家手势目标覆盖双手字段;
|
||||
- 只保留最新帧;
|
||||
- 添加 `TG3A` 头部;
|
||||
- 仅在 START 到 STOP 之间发送到机器人 Peer,并写入不可伪造的 protocol/session 元数据;
|
||||
- 输出 `status.json` 统计;
|
||||
5. 新增并启用用户服务
|
||||
`/home/eai/.config/systemd/user/tg3-omnisocket-sender.service`,设置
|
||||
`Restart=always`;
|
||||
6. 服务器恢复后重启上述发送服务,清除了断线期间 KCP 积压;
|
||||
7. 删除的仅是此前由本项目写入、现已废弃的接收代理/旧服务;未删除任何原厂代码。
|
||||
|
||||
常用检查命令:
|
||||
|
||||
```bash
|
||||
systemctl status xtele-monitor.service
|
||||
systemctl --user status tg3-omnisocket-sender.service
|
||||
cat /home/eai/tg3_omnisocket_transport/status.json
|
||||
```
|
||||
|
||||
## 7. 机器人上完成的操作
|
||||
|
||||
运行账号:`nvidia`,地址:`192.168.41.2`
|
||||
|
||||
1. 部署 OmniSocketGo Python 运行库到 `/home/nvidia/OmniSocketGo`;
|
||||
2. 新增 `/home/nvidia/tg3_local_teleop`,主要文件为:
|
||||
- `tg3_local_teleop.py`:OmniSocket 接收、校验、ROS 双臂/双手发布、安全门控、
|
||||
断线看门狗和回 Home;
|
||||
- `config.toml`:Peer、频率、话题、关节范围、手部映射和 Home 姿态;
|
||||
- `run.sh`、`status.sh`、`home.sh`:运行、状态和回 Home 命令;
|
||||
- `status.json`:实时状态;
|
||||
3. 新增并启用用户服务
|
||||
`/home/nvidia/.config/systemd/user/tg3-local-teleop.service`;
|
||||
4. 将 OmniSocket 接收直接集成进 `tg3_local_teleop`,不再经过机器人本机 ZMQ/TCP
|
||||
接收代理;
|
||||
5. 删除本项目此前创建的旧 `tg3-omnisocket-receiver.service` 和无用代理代码;
|
||||
6. 接入原厂 `/encoder_identical_joint` 和 `freq_change_tg3_node` 完成双臂控制;
|
||||
7. 根据机器人实际配置 `left_hand_type/right_hand_type=brainco`,接入 BrainCo
|
||||
`/set_motor_multi` 与 `/motor_status` 完成双手控制;未修改原厂手型配置;
|
||||
8. 保存当前真实双臂姿态为 Home,而不是把 14 个关节归到电机零位;
|
||||
9. 加入服务器断线后的 2 秒进程级自动重连看门狗;
|
||||
10. 历次部署前均在未武装状态检查,旧版本备份只包含本项目文件;未删除或覆盖原厂程序。
|
||||
|
||||
常用检查命令:
|
||||
|
||||
```bash
|
||||
systemctl --user status tg3-local-teleop.service
|
||||
cat /home/nvidia/tg3_local_teleop/status.json
|
||||
|
||||
cd /home/nvidia/tg3_local_teleop
|
||||
./home.sh status
|
||||
./home.sh start
|
||||
./home.sh cancel
|
||||
```
|
||||
|
||||
`home.sh start` 会驱动机器人双臂,执行前必须确认防护、活动空间和急停。
|
||||
|
||||
## 8. 当前保留与未修改内容
|
||||
|
||||
- 原厂 xTELE、TS1P 串口/CAN、按键和标定逻辑未修改;
|
||||
- 原厂 `freq_change_tg3_node`、`/arm/cmd` 及其默认限位未修改;
|
||||
- 原厂 BrainCo 驱动、手型配置、电流/堵转/限位保护未修改;
|
||||
- 原有代码没有删除;清理范围仅限本项目早期写入的旧代理和旧服务;
|
||||
- 本地开发电脑没有部署运行服务,不是遥操链路中的单点依赖。
|
||||
|
||||
## 9. 验收结论与参考资料
|
||||
|
||||
现场已完成以下验证:
|
||||
|
||||
- 待机时 EAI 本地 `frames_received` 增长而 `frames_sent` 保持不变;START 后机器人稳定
|
||||
收到约 100 Hz 数据,STOP 后再次归零;
|
||||
- 左右 Z/C 长按启停正常,服务不会自行武装;
|
||||
- 双臂在 HBWALK 下正常跟随,停止后按限速逻辑返回保存的 Home;
|
||||
- 左右扳机分别输出 `0~1`,双灵巧手开合、限速和 BrainCo 运动状态处理正常;
|
||||
- 工控机 5001 双手语义帧已通过 OmniSocket 合并发送,实测无畸形帧、无字段丢失;
|
||||
- 服务器断开时机器人停止发布,服务器恢复并重建会话后可继续工作。
|
||||
|
||||
参考资料:
|
||||
|
||||
- 用户提供的《具身天工 3.0 + SDK + 文档(26.04.x)》;
|
||||
- 机器人已安装的 `brainco_hand_msgs`、`brainco_hand.yaml` 和 BrainCo 示例;
|
||||
- [BrainCo Hand 官方 SDK 文档](https://www.brainco-hz.com/docs/revolimb-hand/revo2/get_sdk.html);
|
||||
- `/home/eai/OmniSocketGo/README.md` 及本项目实际运行统计;
|
||||
- 本项目 `omnisocket_xtele_sender.py`、`tg3_local_teleop.py` 和 `config.toml`。
|
||||
|
||||
后续迁移步骤、IP/Peer 修改表和新机器人验收流程见
|
||||
《天工3.0本地同构臂遥操迁移部署指南.md》。
|
||||
Reference in New Issue
Block a user