From 3c707e612e49c9d4c3e4295749249660cc7f3572 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20J=C3=BClg?= Date: Fri, 28 Nov 2025 01:07:48 +0100 Subject: [PATCH 1/4] feat: add robotiq --- extensions/rcs_robotiq/pyproject.toml | 21 +++++++++ .../rcs_robotiq/src/rcs_robotiq/__init__.py | 0 extensions/rcs_robotiq/src/rcs_robotiq/hw.py | 46 +++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 extensions/rcs_robotiq/pyproject.toml create mode 100644 extensions/rcs_robotiq/src/rcs_robotiq/__init__.py create mode 100644 extensions/rcs_robotiq/src/rcs_robotiq/hw.py diff --git a/extensions/rcs_robotiq/pyproject.toml b/extensions/rcs_robotiq/pyproject.toml new file mode 100644 index 00000000..efb6b78b --- /dev/null +++ b/extensions/rcs_robotiq/pyproject.toml @@ -0,0 +1,21 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[project] +name = "rcs_robotiq" +version = "0.5.2" +description="RCS RobotiQ module" +dependencies = [ + "rcs>=0.5.0", + "2f85-python-driver @ git+https://github.com/PhilNad/2f85-python-driver.git", +] +readme = "README.md" +maintainers = [ + { name = "Tobias Jülg", email = "tobias.juelg@utn.de" }, +] +authors = [ + { name = "Tobias Jülg", email = "tobias.juelg@utn.de" }, +] +requires-python = ">=3.10" +license = { text = "AGPL-3.0-or-later" } diff --git a/extensions/rcs_robotiq/src/rcs_robotiq/__init__.py b/extensions/rcs_robotiq/src/rcs_robotiq/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/extensions/rcs_robotiq/src/rcs_robotiq/hw.py b/extensions/rcs_robotiq/src/rcs_robotiq/hw.py new file mode 100644 index 00000000..477b6f99 --- /dev/null +++ b/extensions/rcs_robotiq/src/rcs_robotiq/hw.py @@ -0,0 +1,46 @@ + + +from rcs._core.common import Gripper +from Robotiq2F85Driver import Robotiq2F85Driver + + +class RobotiQGripper(Gripper): + def __init__(self, serial_number): + self.gripper = Robotiq2F85Driver(serial_number=serial_number) + + def get_normalized_width(self) -> float: + # value between 0 and 1 (0 is closed) + return (85 - self.gripper.opening()) / 85 + + def grasp(self) -> None: + """ + Close the gripper to grasp an object. + """ + self.set_normalized_width(0.0) + + def open(self) -> None: + """ + Open the gripper to its maximum width. + """ + self.set_normalized_width(1.0) + + def reset(self) -> None: + self.gripper.reset() + + def set_normalized_width(self, width: float, _: float = 0) -> None: + """ + Set the gripper width to a normalized value between 0 and 1. + """ + if not (0 <= width <= 1): + msg = f"Width must be between 0 and 1, got {width}." + raise ValueError(msg) + abs_width = (1 - width) * 85 + # print(f"Setting gripper width to {width:.2f} (absolute: {abs_width:.2f})") + self.gripper.move(int(abs_width), int(self.gripper._max_speed), int(self.gripper._max_force)) + self.gripper.go_to(opening=int(abs_width), speed=150, force=30) + + def shut(self) -> None: + """ + Close the gripper. + """ + self.set_normalized_width(0.0) \ No newline at end of file From 322f562e7ae6f4a3c715ff24d540173bb4c43c22 Mon Sep 17 00:00:00 2001 From: nisarganc Date: Wed, 18 Feb 2026 18:10:04 +0100 Subject: [PATCH 2/4] fix(robotiq): usage of the python lib - added docs - fixed: opening/closing definition, usage of the robotiq python lib --- docs/extensions/index.md | 1 + docs/extensions/overview.md | 1 + docs/extensions/rcs_robotiq.md | 29 +++++++++++++++++++ extensions/rcs_robotiq/README.md | 28 ++++++++++++++++++ extensions/rcs_robotiq/src/rcs_robotiq/hw.py | 16 ++++------ .../src/rcs_so101/_core/__init__.pyi | 13 +++++---- 6 files changed, 72 insertions(+), 16 deletions(-) create mode 100644 docs/extensions/rcs_robotiq.md create mode 100644 extensions/rcs_robotiq/README.md diff --git a/docs/extensions/index.md b/docs/extensions/index.md index f72ce7e7..eebcac71 100644 --- a/docs/extensions/index.md +++ b/docs/extensions/index.md @@ -12,4 +12,5 @@ rcs_realsense rcs_usb_cam rcs_tacto rcs_robotics_library +rcs_robotiq ``` diff --git a/docs/extensions/overview.md b/docs/extensions/overview.md index efe3138f..2253da54 100644 --- a/docs/extensions/overview.md +++ b/docs/extensions/overview.md @@ -30,6 +30,7 @@ RCS comes with several supported extensions: - **rcs_usb_cam**: Support for generic USB webcams. - **rcs_tacto**: Integration with the Tacto tactile sensor simulator. - **rcs_robotics_library**: Integration with the Robotics Library (RL). +- **rcs_robotiq**: Integration with the Robotiq 2F-85 Gripper. ## Creating Extensions diff --git a/docs/extensions/rcs_robotiq.md b/docs/extensions/rcs_robotiq.md new file mode 100644 index 00000000..0e7a3445 --- /dev/null +++ b/docs/extensions/rcs_robotiq.md @@ -0,0 +1,29 @@ +# RCS Robotiq Extension + +This extension provides support for Robotiq 2F-85 Gripper in RCS. + +## Installation + +```shell +pip install -ve extensions/rcs_robotiq +``` + +Get the serial number of the gripper with this command: +```shell +udevadm info -a -n /dev/ttyUSB0 | grep serial +``` + +Provide the necessary permission: +```shell +chmod 777 /dev/ttyUSB0 +``` + +## Usage +```python +from rcs_robotiq import RobotiQGripper + +gripper = RobotiQGripper('') +gripper.reset() +gripper.shut() +print(gripper.get_normalized_width()) +``` diff --git a/extensions/rcs_robotiq/README.md b/extensions/rcs_robotiq/README.md new file mode 100644 index 00000000..73c8c5e5 --- /dev/null +++ b/extensions/rcs_robotiq/README.md @@ -0,0 +1,28 @@ +# RCS Robotiq Gripper Hardware Extension +Extension to use the Robotiq 2F-85 Gripper with rcs. + +## Installation +```shell +pip install -ve . +``` + +Get the serial number of the gripper with this command: +```shell +udevadm info -a -n /dev/ttyUSB0 | grep serial +``` + +Provide the necessary permission: +```shell +chmod 777 /dev/ttyUSB0 +``` + +## Usage +```python +from rcs_robotiq import RobotiQGripper + +gripper = RobotiQGripper('') +gripper.reset() +gripper.shut() +print(gripper.get_normalized_width()) +``` + diff --git a/extensions/rcs_robotiq/src/rcs_robotiq/hw.py b/extensions/rcs_robotiq/src/rcs_robotiq/hw.py index 477b6f99..0c9327e2 100644 --- a/extensions/rcs_robotiq/src/rcs_robotiq/hw.py +++ b/extensions/rcs_robotiq/src/rcs_robotiq/hw.py @@ -1,16 +1,14 @@ - - from rcs._core.common import Gripper -from Robotiq2F85Driver import Robotiq2F85Driver +from Robotiq2F85Driver.Robotiq2F85Driver import Robotiq2F85Driver -class RobotiQGripper(Gripper): +class RobotiQGripper: def __init__(self, serial_number): self.gripper = Robotiq2F85Driver(serial_number=serial_number) def get_normalized_width(self) -> float: # value between 0 and 1 (0 is closed) - return (85 - self.gripper.opening()) / 85 + return self.gripper.opening / 85 def grasp(self) -> None: """ @@ -34,13 +32,11 @@ def set_normalized_width(self, width: float, _: float = 0) -> None: if not (0 <= width <= 1): msg = f"Width must be between 0 and 1, got {width}." raise ValueError(msg) - abs_width = (1 - width) * 85 - # print(f"Setting gripper width to {width:.2f} (absolute: {abs_width:.2f})") - self.gripper.move(int(abs_width), int(self.gripper._max_speed), int(self.gripper._max_force)) - self.gripper.go_to(opening=int(abs_width), speed=150, force=30) + abs_width = width * 85 + self.gripper.go_to(opening=float(abs_width), speed=150.0, force=30.0) def shut(self) -> None: """ Close the gripper. """ - self.set_normalized_width(0.0) \ No newline at end of file + self.set_normalized_width(0.0) diff --git a/extensions/rcs_so101/src/rcs_so101/_core/__init__.pyi b/extensions/rcs_so101/src/rcs_so101/_core/__init__.pyi index 5449de25..6341f7bc 100644 --- a/extensions/rcs_so101/src/rcs_so101/_core/__init__.pyi +++ b/extensions/rcs_so101/src/rcs_so101/_core/__init__.pyi @@ -1,16 +1,17 @@ # ATTENTION: auto generated from C++ code, use `make stubgen` to update! """ - Robot Control Stack Python Bindings - ----------------------- +Robot Control Stack Python Bindings +----------------------- - .. currentmodule:: _core +.. currentmodule:: _core + +.. autosummary:: + :toctree: _generate - .. autosummary:: - :toctree: _generate - """ + from __future__ import annotations from . import so101_ik From c74036881dfcf3584d1e92e3586ed73971371783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20J=C3=BClg?= Date: Wed, 18 Feb 2026 20:17:11 +0100 Subject: [PATCH 3/4] chore(robotiq): readd gripper inheritance --- extensions/rcs_robotiq/src/rcs_robotiq/hw.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/rcs_robotiq/src/rcs_robotiq/hw.py b/extensions/rcs_robotiq/src/rcs_robotiq/hw.py index 0c9327e2..0e256899 100644 --- a/extensions/rcs_robotiq/src/rcs_robotiq/hw.py +++ b/extensions/rcs_robotiq/src/rcs_robotiq/hw.py @@ -2,8 +2,9 @@ from Robotiq2F85Driver.Robotiq2F85Driver import Robotiq2F85Driver -class RobotiQGripper: +class RobotiQGripper(Gripper): def __init__(self, serial_number): + super().__init__() self.gripper = Robotiq2F85Driver(serial_number=serial_number) def get_normalized_width(self) -> float: From 89c7d81f688850aa94c263b4f09ed804ad793abd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20J=C3=BClg?= Date: Wed, 18 Feb 2026 22:01:13 +0100 Subject: [PATCH 4/4] chore(robotiq): rename, ci and version - rename rcs_robotiq to rcs_robotiq2f85 - added version bump to robotiq - added robotiq to pipeline --- .github/workflows/ci.yaml | 2 +- docs/extensions/index.md | 2 +- docs/extensions/overview.md | 2 +- .../{rcs_robotiq.md => rcs_robotiq2f85.md} | 6 +++--- extensions/rcs_robotiq/src/rcs_robotiq/__init__.py | 0 .../{rcs_robotiq => rcs_robotiq2f85}/README.md | 4 ++-- .../{rcs_robotiq => rcs_robotiq2f85}/pyproject.toml | 6 +++--- .../rcs_robotiq2f85/src/rcs_robotiq2f45/__init__.py | 1 + .../src/rcs_robotiq2f45}/hw.py | 0 .../rcs_so101/src/rcs_so101/_core/__init__.pyi | 13 ++++++------- pyproject.toml | 4 ++++ 11 files changed, 22 insertions(+), 18 deletions(-) rename docs/extensions/{rcs_robotiq.md => rcs_robotiq2f85.md} (78%) delete mode 100644 extensions/rcs_robotiq/src/rcs_robotiq/__init__.py rename extensions/{rcs_robotiq => rcs_robotiq2f85}/README.md (82%) rename extensions/{rcs_robotiq => rcs_robotiq2f85}/pyproject.toml (88%) create mode 100644 extensions/rcs_robotiq2f85/src/rcs_robotiq2f45/__init__.py rename extensions/{rcs_robotiq/src/rcs_robotiq => rcs_robotiq2f85/src/rcs_robotiq2f45}/hw.py (100%) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index a719caac..609b2596 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -71,7 +71,7 @@ jobs: # Python extensions - rcs_xarm7 - rcs_realsense - # - rcs_robotiq + - rcs_robotiq2f85 - rcs_tacto - rcs_usb_cam runs-on: ubuntu-latest diff --git a/docs/extensions/index.md b/docs/extensions/index.md index eebcac71..58c0391e 100644 --- a/docs/extensions/index.md +++ b/docs/extensions/index.md @@ -12,5 +12,5 @@ rcs_realsense rcs_usb_cam rcs_tacto rcs_robotics_library -rcs_robotiq +rcs_robotiq2f85 ``` diff --git a/docs/extensions/overview.md b/docs/extensions/overview.md index 2253da54..84334d4e 100644 --- a/docs/extensions/overview.md +++ b/docs/extensions/overview.md @@ -30,7 +30,7 @@ RCS comes with several supported extensions: - **rcs_usb_cam**: Support for generic USB webcams. - **rcs_tacto**: Integration with the Tacto tactile sensor simulator. - **rcs_robotics_library**: Integration with the Robotics Library (RL). -- **rcs_robotiq**: Integration with the Robotiq 2F-85 Gripper. +- **rcs_robotiq2f85**: Integration with the Robotiq 2F-85 Gripper. ## Creating Extensions diff --git a/docs/extensions/rcs_robotiq.md b/docs/extensions/rcs_robotiq2f85.md similarity index 78% rename from docs/extensions/rcs_robotiq.md rename to docs/extensions/rcs_robotiq2f85.md index 0e7a3445..de0334e8 100644 --- a/docs/extensions/rcs_robotiq.md +++ b/docs/extensions/rcs_robotiq2f85.md @@ -1,11 +1,11 @@ -# RCS Robotiq Extension +# RCS Robotiq2F85 Extension This extension provides support for Robotiq 2F-85 Gripper in RCS. ## Installation ```shell -pip install -ve extensions/rcs_robotiq +pip install -ve extensions/rcs_robotiq2f85 ``` Get the serial number of the gripper with this command: @@ -20,7 +20,7 @@ chmod 777 /dev/ttyUSB0 ## Usage ```python -from rcs_robotiq import RobotiQGripper +from rcs_robotiq2f85 import RobotiQGripper gripper = RobotiQGripper('') gripper.reset() diff --git a/extensions/rcs_robotiq/src/rcs_robotiq/__init__.py b/extensions/rcs_robotiq/src/rcs_robotiq/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/extensions/rcs_robotiq/README.md b/extensions/rcs_robotiq2f85/README.md similarity index 82% rename from extensions/rcs_robotiq/README.md rename to extensions/rcs_robotiq2f85/README.md index 73c8c5e5..baa44c9c 100644 --- a/extensions/rcs_robotiq/README.md +++ b/extensions/rcs_robotiq2f85/README.md @@ -1,4 +1,4 @@ -# RCS Robotiq Gripper Hardware Extension +# RCS Robotiq 2F-85 Gripper Hardware Extension Extension to use the Robotiq 2F-85 Gripper with rcs. ## Installation @@ -18,7 +18,7 @@ chmod 777 /dev/ttyUSB0 ## Usage ```python -from rcs_robotiq import RobotiQGripper +from rcs_robotiq2f85 import RobotiQGripper gripper = RobotiQGripper('') gripper.reset() diff --git a/extensions/rcs_robotiq/pyproject.toml b/extensions/rcs_robotiq2f85/pyproject.toml similarity index 88% rename from extensions/rcs_robotiq/pyproject.toml rename to extensions/rcs_robotiq2f85/pyproject.toml index efb6b78b..9d7b4958 100644 --- a/extensions/rcs_robotiq/pyproject.toml +++ b/extensions/rcs_robotiq2f85/pyproject.toml @@ -3,11 +3,11 @@ requires = ["setuptools"] build-backend = "setuptools.build_meta" [project] -name = "rcs_robotiq" -version = "0.5.2" +name = "rcs_robotiq2f85" +version = "0.6.2" description="RCS RobotiQ module" dependencies = [ - "rcs>=0.5.0", + "rcs>=0.6.2", "2f85-python-driver @ git+https://github.com/PhilNad/2f85-python-driver.git", ] readme = "README.md" diff --git a/extensions/rcs_robotiq2f85/src/rcs_robotiq2f45/__init__.py b/extensions/rcs_robotiq2f85/src/rcs_robotiq2f45/__init__.py new file mode 100644 index 00000000..22049ab2 --- /dev/null +++ b/extensions/rcs_robotiq2f85/src/rcs_robotiq2f45/__init__.py @@ -0,0 +1 @@ +__version__ = "0.6.2" diff --git a/extensions/rcs_robotiq/src/rcs_robotiq/hw.py b/extensions/rcs_robotiq2f85/src/rcs_robotiq2f45/hw.py similarity index 100% rename from extensions/rcs_robotiq/src/rcs_robotiq/hw.py rename to extensions/rcs_robotiq2f85/src/rcs_robotiq2f45/hw.py diff --git a/extensions/rcs_so101/src/rcs_so101/_core/__init__.pyi b/extensions/rcs_so101/src/rcs_so101/_core/__init__.pyi index 4d29bc86..e8cea8bb 100644 --- a/extensions/rcs_so101/src/rcs_so101/_core/__init__.pyi +++ b/extensions/rcs_so101/src/rcs_so101/_core/__init__.pyi @@ -1,17 +1,16 @@ # ATTENTION: auto generated from C++ code, use `make stubgen` to update! """ -Robot Control Stack Python Bindings ------------------------ + Robot Control Stack Python Bindings + ----------------------- -.. currentmodule:: _core - -.. autosummary:: - :toctree: _generate + .. currentmodule:: _core + .. autosummary:: + :toctree: _generate + """ - from __future__ import annotations from . import so101_ik diff --git a/pyproject.toml b/pyproject.toml index 094f8195..97bab848 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -214,4 +214,8 @@ version_files = [ "extensions/rcs_tacto/pyproject.toml:version", "extensions/rcs_tacto/src/rcs_tacto/__init__.py:__version__", "extensions/rcs_tacto/pyproject.toml:\"rcs>=(.*)\"", + + "extensions/rcs_robotiq2f85/pyproject.toml:version", + "extensions/rcs_robotiq2f85/src/rcs_robotiq2f85/__init__.py:__version__", + "extensions/rcs_robotiq2f85/pyproject.toml:\"rcs>=(.*)\"", ]