Files
ros_contorl/docs/GRIPPER.md
arm_dev 561d7da21f 首轮顺时针进孔改回 10°/s,空回固定做 4 轮。
首轮咬合的顺时针进孔又走了接口上限,螺纹还没咬住就转完了。这一段改回读
extreme_speed_deg_s(现场 10°/s)。首轮逆时针出孔,以及空回每一轮的正反转,
仍走 0.90 rad/s 上限。

空回原先只做一轮。首轮咬合结束后,张开、微抬、逆时针、按本轮实测上抬降回、
合爪、顺时针这一整段固定重复 UNWIND_ROUNDS=4。抬和降留在轮内,下降量用这一轮
记住的上抬,不用上一轮的数。日志打空回第 i/4 轮;某一轮没走完就停,后面不再做。

10:40 合爪命令已经发到话题,节点被 Serial.flush/tcdrain 堵住 120s 才执行,
流水线 8s 时手指还停在 pos=400,第 2–4 轮没开始。发送改成等发送缓冲排空,
0.25s 排不空就失败返回,不再调用 tcdrain。同一次开合状态没跟上再发一次。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-20 11:40:57 +08:00

4.8 KiB
Raw Permalink Blame History

大寰夹爪(PGEA + RGI)

两只爪都走工控机 USB–RS485 + 官方 Modbus RTU,不走 Flexiv Gripper / Studio GripperDahuanModbus。示教器里关掉对应设备,避免抢总线。run_real.sh 保持 load_gripper:=false。

臂 型号 串口 脚本
左 89 PGEA-100-20-W 平行 /dev/ttyUSB0 run_gripper.sh --arm 89
右 91 RGI-100-30-O-S-M1 旋转 /dev/ttyUSB1 run_gripper.sh --arm 91

端口、行程、力/速写在 site.yaml:robots[].gripper(每臂)+ 全局 gripper / gripper.parallel / gripper.rotary。双爪 ROS 节点读 robots[] 两侧。不要改包内 Python 默认值。

源码:src/arm_application/arm_application/dh_official.py、dual_gripper.py、dh_pgea.py。消息:arm_msgs(不要往官方 flexiv_msgs 塞自定义夹爪类型)。

命令行

# 左臂平行爪
bash ~/ros2/scripts/run_gripper.sh --arm 89 --cli probe
bash ~/ros2/scripts/run_gripper.sh --arm 89 --cli init    # 写 0xA5 回零;已经 initialized 也会再做一次
bash ~/ros2/scripts/run_gripper.sh --arm 89 --cli open
bash ~/ros2/scripts/run_gripper.sh --arm 89 --cli close
bash ~/ros2/scripts/run_gripper.sh --arm 89 --cli pos 500 # 0=合 1000=开(‰)

# 右臂旋转爪
bash ~/ros2/scripts/run_gripper.sh --arm 91 --cli open
bash ~/ros2/scripts/run_gripper.sh --arm 91 --cli close
bash ~/ros2/scripts/run_gripper.sh --arm 91 --cli rotate 90
bash ~/ros2/scripts/run_gripper.sh --arm 91 --cli revolutions 2

PGEA 力/速:gripper.force_pct(最低 20)speed_pct open_position close_position。RGI 不要 auto_init: true(robots[] 里已关)。

平行爪的 --cli 在驱动没跑时会先把节点拉起来,再把命令发到 /gripper/ctrl。auto_init 仍用这一臂在 site.yaml 里的值(现场 false,不写 0xA5,不回零)。串口被别的进程占着时,报的是占用。

ROS 节点

单爪:

bash ~/ros2/scripts/run_gripper.sh --arm 89    # /gripper/open /gripper/close
bash ~/ros2/scripts/run_gripper.sh --arm 91    # dual_gripper 仅 right

双爪同时:

bash ~/ros2/scripts/run_dual_gripper.sh
名称 类型
/dual_gripper_driver/left/command arm_msgs/msg/GripperCommand
/dual_gripper_driver/right/command 同上
/dual_gripper_driver/left/status arm_msgs/msg/GripperStatus
/dual_gripper_driver/right/status 同上
/dual_gripper_driver/left/execute arm_msgs/srv/GripperExecute
/dual_gripper_driver/right/execute 同上

command 字段:init open close move;右爪另有 rotate rotate_by rotate_revolutions home_rotation。

ros2 service call /dual_gripper_driver/left/execute arm_msgs/srv/GripperExecute \
  "{command: {command: 'open', wait_complete: true, timeout: 10.0}}"
ros2 service call /dual_gripper_driver/right/execute arm_msgs/srv/GripperExecute \
  "{command: {command: 'rotate', position: 90.0, wait_complete: true, timeout: 10.0}}"

USB 未插齐时节点仍可起来(allow_offline:=true),对应侧 status.error_msg 会写连接失败。

/gripper/states 的离线帧

data 是 6 个元素: [initialized, grip_state, position, target_pos, target_force, online]。

online=0 表示这一帧没读到总线,前 5 个是上一次读到的值,不是现在的状态。老节点只发 5 个元素(那时它只在读成功时才发),5 元素帧按有效帧处理。

读 0x0201 无应答时节点照样发离线帧,/gripper/joint_states 不发:关节状态没有离线位,宁可不发,也不要把上一次的开口当成现在的。

流水线 _wait_gripper 只认有效帧;超时没等到有效帧时报「读不到状态(只有离线帧,Modbus 无应答),不是夹爪没张开」,不能再报成「夹爪没到位」——2026-10-20 读 0x0201 一连 264 次无应答,实测在张开后停住、微抬没有下发,日志却只写「未到位」。

串口 EIO(USB 掉线)抛 DhPgeaBusError,节点先关串口再重开(1 秒最多一次),不再整进程带 traceback 退出。没有应答(DhPgeaError)先继续重试;连续 BUS_REOPEN_AFTER_FAILURES=30 拍都读不到也重开一次——2026-10-20 那次就是写有回显、读一直无应答,重启节点立刻恢复,说明坏的是串口会话。

发送不再调用 Serial.flush()(底层是 tcdrain)。USB 串口不收数据时这个调用不看写超时。2026-10-20 10:40 合爪命令已经发布,节点被它堵住 120s 才打出 ctrl pos=0,流水线 8s 时状态还是 grip=1 pos=400,这一轮就停了。现在发送缓冲在 timeout_s(0.25s)内排不空就失败返回;流水线对同一次开合再发一次命令。

用户需在 dialout:sudo usermod -aG dialout $USER。