Skip to content

Commit da1f46b

Browse files
committed
feat(robotiq): async support and config
- added config with force, speed and async option - added close method to close serial properly - rename class to reflect 2f85 type (hard coded 85mm width)
1 parent 1b7d83b commit da1f46b

3 files changed

Lines changed: 55 additions & 10 deletions

File tree

extensions/rcs_robotiq2f85/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ version = "0.6.3"
88
description="RCS RobotiQ module"
99
dependencies = [
1010
"rcs>=0.6.3",
11-
"2f85-python-driver @ git+https://github.com/PhilNad/2f85-python-driver.git",
11+
"2f85-python-driver @ git+https://github.com/RobotControlStack/2f85-python-driver.git",
1212
]
1313
readme = "README.md"
1414
maintainers = [
Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,36 @@
1-
from rcs._core.common import Gripper
2-
from Robotiq2F85Driver.Robotiq2F85Driver import Robotiq2F85Driver
1+
from dataclasses import dataclass
32

3+
from rcs._core.common import Gripper, GripperConfig, GripperState
4+
from Robotiq2F85Driver.Robotiq2F85Driver import GripperStatus, Robotiq2F85Driver
45

5-
class RobotiQGripper(Gripper):
6-
def __init__(self, serial_number):
6+
7+
@dataclass
8+
class RobotiQ2F85GripperConfig(GripperConfig):
9+
speed: float = 100
10+
"""Speed in mm/s. Must be between 20 and 150 mm/s."""
11+
force: float = 50
12+
"""Force in N. Must be between 20 and 235 N."""
13+
async_control: bool = True
14+
"""If True, gripper commands return immediately without waiting for the movement to complete.
15+
A new command interrupts any ongoing movement."""
16+
17+
18+
@dataclass(kw_only=True)
19+
class RobotiQ2F85GripperState(GripperState):
20+
state: GripperStatus
21+
22+
def __post_init__(self):
23+
super().__init__()
24+
25+
26+
class RobotiQ2F85Gripper(Gripper):
27+
def __init__(self, serial_number: str, cfg: RobotiQ2F85GripperConfig):
28+
"""
29+
serial_number:
30+
Get the serial number with `udevadm info -a -n /dev/ttyUSB0 | grep serial`, make sure you have read/write permissions to the port.
31+
"""
732
super().__init__()
33+
self._cfg: RobotiQ2F85GripperConfig = cfg
834
self.gripper = Robotiq2F85Driver(serial_number=serial_number)
935

1036
def get_normalized_width(self) -> float:
@@ -15,7 +41,7 @@ def grasp(self) -> None:
1541
"""
1642
Close the gripper to grasp an object.
1743
"""
18-
self.set_normalized_width(0.0)
44+
self.set_normalized_width(0.0, force=self._cfg.force)
1945

2046
def open(self) -> None:
2147
"""
@@ -26,18 +52,35 @@ def open(self) -> None:
2652
def reset(self) -> None:
2753
self.gripper.reset()
2854

29-
def set_normalized_width(self, width: float, _: float = 0) -> None:
55+
def set_normalized_width(self, width: float, force: float = 0) -> None:
3056
"""
3157
Set the gripper width to a normalized value between 0 and 1.
3258
"""
3359
if not (0 <= width <= 1):
3460
msg = f"Width must be between 0 and 1, got {width}."
3561
raise ValueError(msg)
3662
abs_width = width * 85
37-
self.gripper.go_to(opening=float(abs_width), speed=150.0, force=30.0)
63+
self.gripper.go_to(
64+
opening=float(abs_width),
65+
speed=self._cfg.speed,
66+
force=force if force != 0 else self._cfg.force,
67+
blocking_call=not self._cfg.async_control,
68+
)
3869

3970
def shut(self) -> None:
4071
"""
4172
Close the gripper.
4273
"""
4374
self.set_normalized_width(0.0)
75+
76+
def close(self) -> None:
77+
self.gripper.client.serial.close()
78+
79+
def get_config(self) -> GripperConfig:
80+
return self._cfg
81+
82+
def set_config(self, cfg: RobotiQ2F85GripperConfig) -> None:
83+
self._cfg = cfg
84+
85+
def get_state(self) -> GripperState:
86+
return RobotiQ2F85GripperState(state=self.gripper.read_status())

src/pybind/rcs.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -373,8 +373,10 @@ PYBIND11_MODULE(_core, m) {
373373
.def_readwrite("robot_platform",
374374
&rcs::common::RobotConfig::robot_platform);
375375
py::class_<rcs::common::RobotState>(common, "RobotState").def(py::init<>());
376-
py::class_<rcs::common::GripperConfig>(common, "GripperConfig").def(py::init<>());
377-
py::class_<rcs::common::GripperState>(common, "GripperState").def(py::init<>());
376+
py::class_<rcs::common::GripperConfig>(common, "GripperConfig")
377+
.def(py::init<>());
378+
py::class_<rcs::common::GripperState>(common, "GripperState")
379+
.def(py::init<>());
378380
py::enum_<rcs::common::GraspType>(common, "GraspType")
379381
.value("POWER_GRASP", rcs::common::GraspType::POWER_GRASP)
380382
.value("PRECISION_GRASP", rcs::common::GraspType::PRECISION_GRASP)

0 commit comments

Comments
 (0)