Files
ros_contorl/scripts/rdk_gripper.py
T
arm_dev 6edb8d39ab chore: 框架科学优化前的完整基线
在开始'设备契约层 + 目录重构 + 通止规装配'改造之前,先钉住当前可运行状态,
使后续任何删除/重构都可回退。

本基线包含:
- 现有 ROS 2 工作区全部源码(arm_application / arm_control / arm_bringup 等)
- 官方 flexiv_ros2 栈(含 flexiv_hardware / flexiv_controllers 等符号链接)
- 设备契约层 src/arm_interfaces(新增,46 项单测通过)
- devices/ 设备选型与品牌清单(新增)
- scripts/gen_site_example.py 与由它生成的 config/site.example.yaml

按 .gitignore 排除:build/ / install/ / log/ / config/site.yaml / 模型权重二进制。
2026-09-23 10:53:06 +08:00

208 lines
6.7 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""Control Studio device GripperDahuan / GripperDahuanModbus via Flexiv RDK.
Must run under RDK Python (rdk_py310). Uses a *lite* RDK instance so it can
share the robot with run_real.sh (ros2_control holds the normal RDK).
The controller talks RS485 itself (its own /dev/ttyUSB0), not the IPC serial.
/home/cc/rdk_py310/bin/python ~/ros2/scripts/rdk_gripper.py --list
/home/cc/rdk_py310/bin/python ~/ros2/scripts/rdk_gripper.py status
/home/cc/rdk_py310/bin/python ~/ros2/scripts/rdk_gripper.py init
/home/cc/rdk_py310/bin/python ~/ros2/scripts/rdk_gripper.py open
/home/cc/rdk_py310/bin/python ~/ros2/scripts/rdk_gripper.py close
"""
from __future__ import annotations
import argparse
import sys
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "scripts"))
from rdk_switch_tool import _iface_ipv4s # noqa: E402
def connect_lite(sn: str, iface: str = ""):
import flexivrdk
ips = _iface_ipv4s(iface)
if ips:
try:
return flexivrdk.Robot(sn, ips, True, True)
except TypeError:
pass
except RuntimeError as exc:
msg = str(exc).lower()
if "whitelist" not in msg and "filtered out" not in msg:
raise
return flexivrdk.Robot(sn, [], True, True)
def _fmt_params(p) -> str:
return (
f"width=[{p.min_width:.4f},{p.max_width:.4f}] m "
f"vel=[{p.min_vel:.4f},{p.max_vel:.4f}] m/s "
f"force=[{p.min_force:.1f},{p.max_force:.1f}] N"
)
def _fmt_states(s) -> str:
return f"width={s.width:.4f} m force={s.force:.2f} N moving={s.is_moving}"
def _clamp(val: float, lo: float, hi: float) -> float:
if lo > hi:
lo, hi = hi, lo
return max(lo, min(hi, val))
def _move(grip, params, width: float, vel: float, force: float) -> None:
vmin = float(params.min_vel)
vmax = float(params.max_vel)
if vmax <= 0:
vmax = 0.05
# Move velocity cannot be 0 (RDK).
vel = _clamp(vel, max(vmin, 1e-4), vmax)
force = _clamp(force, float(params.min_force), float(params.max_force))
width = _clamp(width, float(params.min_width), float(params.max_width))
print(f"Move width={width:.4f} m vel={vel:.4f} m/s force={force:.1f} N")
grip.Move(width, vel, force)
def main() -> int:
ap = argparse.ArgumentParser(description="Flexiv RDK gripper (GripperDahuanModbus)")
ap.add_argument("--sn", default="")
ap.add_argument("--iface", default="")
ap.add_argument("--device", default="", help="Studio Device name")
ap.add_argument("--force-n", type=float, default=0.0, help="force limit [N]; 0=mid")
ap.add_argument("--vel", type=float, default=0.0, help="speed [m/s]; 0=half max")
ap.add_argument(
"cmd",
nargs="?",
default="status",
choices=["list", "status", "init", "open", "close", "pos", "enable"],
)
ap.add_argument("value", nargs="?", default="", help="pos: meters or 0–1000")
args = ap.parse_args()
sys.path.insert(0, str(ROOT / "scripts" / "lib"))
from export_site_env import load_site, resolve_robot # type: ignore
data = load_site()
robot_cfg = resolve_robot(data)
g = data.get("gripper") or {}
sn = (args.sn or robot_cfg.get("sn") or "").strip()
iface = (args.iface or robot_cfg.get("iface") or "").strip()
device = (args.device or g.get("device_name") or "GripperDahuanModbus").strip()
if not sn:
print("ERROR: robot SN missing", file=sys.stderr)
return 2
import flexivrdk
print(f"=== RDK lite gripper SN={sn} device={device} iface={iface or 'auto'} ===")
robot = connect_lite(sn, iface)
dev = flexivrdk.Device(robot)
names = list(dev.list() or [])
if args.cmd == "list":
print("Studio devices:")
for n in names:
try:
en = dev.enabled(n)
cn = dev.connected(n)
except Exception:
en, cn = "?", "?"
mark = " <--" if n == device else ""
print(f" {n}: enabled={en} connected={cn}{mark}")
return 0
if device not in names:
print(
f"ERROR: device {device!r} not in Studio pool.\n available: {', '.join(names)}",
file=sys.stderr,
)
return 1
print(
f" Studio: enabled={dev.enabled(device)} connected={dev.connected(device)}"
)
if not dev.connected(device):
print(
"WARN: connected=False — 控制器自己的 /dev/ttyUSB0 没接到爪。\n"
" USB–RS485 要插 Flexiv 机箱 USB(不是工控机),A/B + 24V 到 PGEA。\n"
" 或用法兰工具口 485(腕部白绿+/绿-)。"
)
grip = flexivrdk.Gripper(robot)
if args.cmd in ("enable", "status", "init", "open", "close", "pos"):
try:
grip.Enable(device)
print(f"Enable [{device}] OK")
except Exception as exc:
print(f"ERROR: Enable failed: {exc}", file=sys.stderr)
return 1
params = grip.params()
print(" params:", _fmt_params(params))
print(" states:", _fmt_states(grip.states()))
force = float(args.force_n or g.get("force_n") or 0.0)
if force <= 0:
force = 0.5 * (float(params.min_force) + float(params.max_force))
vel = float(args.vel or g.get("vel_mps") or 0.0)
if vel <= 0:
vel = 0.5 * float(params.max_vel)
if args.cmd in ("enable", "status"):
if not dev.connected(device):
return 2
return 0
if args.cmd == "init":
print("Init (fingers home, ~10 s) …")
grip.Init()
time.sleep(2.0)
print(" states:", _fmt_states(grip.states()))
return 0
if args.cmd == "open":
_move(grip, params, float(params.max_width), vel, force)
time.sleep(0.4)
print(" states:", _fmt_states(grip.states()))
return 0
if args.cmd == "close":
_move(grip, params, float(params.min_width), vel, force)
time.sleep(0.4)
print(" states:", _fmt_states(grip.states()))
return 0
if args.cmd == "pos":
if args.value == "":
print("usage: pos <meters|0-1000>", file=sys.stderr)
return 2
raw = float(args.value)
if raw > 1.5:
span = float(params.max_width) - float(params.min_width)
width = float(params.min_width) + (raw / 1000.0) * span
else:
width = raw
_move(grip, params, width, vel, force)
time.sleep(0.4)
print(" states:", _fmt_states(grip.states()))
return 0
return 0
if __name__ == "__main__":
try:
raise SystemExit(main())
except Exception as exc:
print(f"ERROR: {exc}", file=sys.stderr)
raise SystemExit(1)