# 单摄像头控制左手 O6 + G20 使用说明 本文面向第一次使用本系统的操作者。系统通过一个摄像头识别真人左手, 同时控制两台左手灵巧手: - G20:连接 `can0`,接收 20 维关节命令。 - O6:连接 `can1`,接收 6 维关节命令。 摄像头节点会先提取一套统一的人手特征,再分别转换成适合 O6 和 G20 的 `0–255` 控制值。两台手不会共用同一个命令话题。 ## 1. 当前启动命令 ```bash cd /home/lxp/projects/linkerhand_retarget_ros2 source .venv/bin/activate source /opt/ros/jazzy/setup.bash source install/setup.bash ros2 launch camera_retarget_l20 teleop_o6_g20_left.launch.py \ motor_speed:=250 \ ema_alpha:=0.55 \ max_step:=24.0 \ command_deadband:=3.0 ``` 启动成功后,终端应显示 O6、G20 分别连接 `can1`、`can0`,并弹出摄像头 画面。刚启动时画面显示 `PREVIEW ONLY`,表示只计算预览命令,实体手还不会 跟随摄像头运动。 > 启动双手 launch 前,不要再单独启动其他 `linker_hand_sdk` 进程,否则同一 > CAN 设备可能被多个驱动同时访问。 ## 2. 正确操作流程 把真人左手完整放进画面,尽量保持掌心朝向摄像头,避免手指互相遮挡。看到 画面显示 `hand=OK` 后,依次完成 `C → F → P → E`。 ### C:完全张开标定 1. 单击一下摄像头窗口,确保键盘输入作用于该窗口。 2. 真人左手完全张开,五指伸直。 3. 大拇指自然向外展开,不要贴住食指。 4. 按一次 `C`,继续保持姿态不动。 5. 等待画面标定进度完成,或终端出现 `Open calibration complete`。 这一步记录各手指的张开零点、指尖张开距离和侧摆零点。 ### F:正常握拳标定 1. 四指完全弯曲,做一个正常握拳动作。 2. 大拇指也要按照自然握拳方式收拢,不要单独留在外面。 3. 按一次 `F`,保持姿态不动,直到终端出现 `Fist calibration complete`。 这一步记录四指和大拇指的完整弯曲范围。只弯曲四指、大拇指保持伸直,会导致 后续正常握拳时大拇指闭合不足。 ### P:拇指和食指捏合标定 1. 张开中指、无名指和小指,减少遮挡。 2. 让大拇指指尖与食指指尖真正接触,形成清晰的“OK”手势。 3. 接触后按一次 `P`,保持稳定,直到终端出现 `Pinch calibration complete`。 这一步标定拇指对掌以及指尖接触距离。标定时不是“接近”,而是两个指尖确实 接触。 每次标定需要稳定保持约 1.5 秒并取得至少 30 帧有效数据,最长等待 8 秒。 某一步失败时不会覆盖之前的有效结果,重新摆好对应姿态再按一次该键即可。 ### E:启用实体手控制 完成 C、F、P 后,把真人左手稳定放在画面中并按 `E`。画面变为红色 `REAL CONTROL` 后,O6 和 G20 才会开始跟随真人手运动。 启用需要同时满足: - C、F、P 三项标定均已完成; - 摄像头稳定识别到左手; - O6 和 G20 两个驱动均在线; - 两个命令话题都有订阅者,状态数据均正常。 ## 3. 运行期间的按键 | 按键 | 功能 | |---|---| | `C` | 重新标定完全张开姿态 | | `F` | 重新标定正常握拳姿态 | | `P` | 重新标定拇指与食指捏合姿态 | | `E` | 启用 O6 + G20 实体控制 | | `D` | 关闭实体控制,保持最后一个命令位置 | | `Q` / `Esc` | 退出摄像头节点 | 开始任何一次重新标定都会自动退出实体控制。标定完成后需要重新按 `E`。 ## 4. 安全操作 - 首次按 `E` 前,确保两台灵巧手周围没有人体、线缆或易损物品。 - 调试时先慢速移动真人手,不要突然快速握拳。 - 摄像头跟踪丢失超过约 0.35 秒时,系统会向在线设备发送张开姿态并自动解除 实体控制。 - 任一路驱动状态异常或超时时,系统会发送张开姿态并统一解除控制。 - 需要立即停止跟随时按 `D`。 - 正常结束程序时,先让真人手张开,确认两台实体手已经张开,再按 `D`,最后 在启动终端按 `Ctrl+C`。 - 每次重启摄像头节点后,C、F、P 标定都需要重新执行,不会加载上次标定。 ## 5. 没有摄像头窗口时的终端操作 另开一个终端并加载环境: ```bash cd /home/lxp/projects/linkerhand_retarget_ros2 source .venv/bin/activate source /opt/ros/jazzy/setup.bash source install/setup.bash ``` 然后可以通过服务完成同样的操作: ```bash # C:完全张开 ros2 service call /camera_o6_g20_retarget/calibrate_open \ std_srvs/srv/Trigger "{}" # F:正常握拳 ros2 service call /camera_o6_g20_retarget/calibrate_fist \ std_srvs/srv/Trigger "{}" # P:拇指与食指指尖接触 ros2 service call /camera_o6_g20_retarget/calibrate_pinch \ std_srvs/srv/Trigger "{}" # E:启用实体控制 ros2 service call /camera_o6_g20_retarget/enable \ std_srvs/srv/SetBool "{data: true}" # D:关闭实体控制 ros2 service call /camera_o6_g20_retarget/enable \ std_srvs/srv/SetBool "{data: false}" ``` 服务返回成功只表示“标定采集已经开始”,仍需继续保持姿态,直到状态话题或 启动终端报告标定完成。 ## 6. 状态、预览和控制话题 ```text /o6/cb_left_hand_control_cmd O6 六维实体命令 /o6/cb_left_hand_state O6 状态 /g20/cb_left_hand_control_cmd G20 二十维实体命令 /g20/cb_left_hand_state G20 状态 /camera_o6_g20_retarget/o6/target_joint_cmd O6 命令预览 /camera_o6_g20_retarget/g20/target_joint_cmd G20 命令预览 /camera_o6_g20_retarget/status 系统状态 /camera_o6_g20_retarget/debug 映射调试数据 ``` 常用检查命令: ```bash ros2 topic echo /camera_o6_g20_retarget/status ros2 topic echo /camera_o6_g20_retarget/debug ros2 topic echo /camera_o6_g20_retarget/o6/target_joint_cmd ros2 topic echo /camera_o6_g20_retarget/g20/target_joint_cmd ``` `target_joint_cmd` 在 `PREVIEW ONLY` 状态下也会发布,因此可以先观察映射值, 确认合理后再按 `E`。 ## 7. 当前启动参数的含义 | 参数 | 当前值 | 作用 | |---|---:|---| | `motor_speed` | 250 | 灵巧手内部电机速度,数值越大,电机允许的运动速度越高 | | `ema_alpha` | 0.55 | 映射平滑系数;增大响应更快,减小更平滑 | | `max_step` | 24 | 每一帧单个命令允许变化的最大值 | | `command_deadband` | 3 | 小于该范围的变化不发送,用于抑制轻微抖动 | 这些参数只影响响应速度和平滑程度,不改变 C/F/P 标定数据和型号端点配置。 ## 8. 常见问题 ### 按键没有反应 先用鼠标单击摄像头窗口,再按键。键盘焦点在终端或其他窗口时,摄像头程序 收不到按键。也可以直接使用第 5 节的 ROS 服务。 ### P 标定一直失败 - 确认已经先完成 C 和 F; - 大拇指与食指指尖必须真正接触; - 掌心尽量正对摄像头,避免指尖被手掌遮挡; - 中指、无名指和小指保持张开; - 按 P 后保持 1.5 秒以上,不要移动手腕。 ### 按 E 后实体手不动 查看启动终端的警告以及状态话题: ```bash ros2 topic echo /camera_o6_g20_retarget/status ``` 重点检查是否仍提示 `needs_open_calibration`、`needs_fist_calibration`、 `needs_pinch_calibration`、`state_missing` 或 `command_subscriber_missing`。 ### O6 和 G20 动作存在差异 这是正常现象。O6 只有 6 路命令,没有四指独立侧摆;G20 使用 20 维命令, 可以映射更多弯曲和侧摆自由度。因此两台手表现应当语义一致,但不会做到每个 机械关节完全相同。 ### 动作仍有轻微抖动 可以先保持当前电机速度,只增加平滑或死区,例如: ```bash ros2 launch camera_retarget_l20 teleop_o6_g20_left.launch.py \ motor_speed:=250 \ ema_alpha:=0.45 \ max_step:=20.0 \ command_deadband:=4.0 ``` 这会更稳定,但会增加少量跟随延迟。