diff --git a/.github/workflows/build_wheels.yaml b/.github/workflows/build_wheels.yaml
index 59b98f57..393c31e8 100644
--- a/.github/workflows/build_wheels.yaml
+++ b/.github/workflows/build_wheels.yaml
@@ -7,20 +7,23 @@ on:
jobs:
build_core_wheels:
- name: Build core wheels
- runs-on: ubuntu-latest
+ name: Build core wheels on ${{ matrix.os }}
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ os:
+ - ubuntu-latest
+ - macos-14
steps:
- uses: actions/checkout@v4
- name: Build core wheels
uses: pypa/cibuildwheel@v2.22.0
- env:
- CIBW_ARCHS_LINUX: x86_64
- CIBW_BUILD: cp311-* cp312-* cp313-*
- uses: actions/upload-artifact@v4
with:
- name: core-wheels
+ name: core-wheels-${{ matrix.os }}
path: ./wheelhouse/*.whl
build_cpp_extension_wheels:
@@ -33,15 +36,15 @@ jobs:
extension:
- rcs_fr3
- rcs_panda
- - rcs_robotics_library
- rcs_so101
steps:
- uses: actions/checkout@v4
+ # extensions are built on linux, so they need the linux core wheels
- uses: actions/download-artifact@v4
with:
- name: core-wheels
+ name: core-wheels-ubuntu-latest
path: dist/core
- name: Install root Debian dependencies
@@ -81,7 +84,6 @@ jobs:
extension:
- rcs_realsense
- rcs_robotiq2f85
- - rcs_tacto
- rcs_ur5e
- rcs_usb_cam
- rcs_xarm7
@@ -90,9 +92,10 @@ jobs:
steps:
- uses: actions/checkout@v4
+ # extensions are built on linux, so they need the linux core wheels
- uses: actions/download-artifact@v4
with:
- name: core-wheels
+ name: core-wheels-ubuntu-latest
path: dist/core
- name: Install root Debian dependencies
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 6a2379a5..eb6bea24 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -129,7 +129,6 @@ jobs:
extension:
- rcs_fr3
- rcs_panda
- - rcs_robotics_library
- rcs_so101
runs-on: ubuntu-latest
steps:
diff --git a/.gitignore b/.gitignore
index ace8e6a5..ad434e17 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,4 +24,4 @@ docs/_build
CLAUDE.md
uv.lock
*.parquet
-
+wheelhouse
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9c21dfa5..80d6e253 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,77 @@
+## v0.7.3 (2026-10-06)
+
+### Feat
+
+- **yam**: is grasped property
+- **YAM**: force limiter for YAM gripper
+- **sim**: current gl context for mac
+- mac os compilation support
+- **wrappers**: gripper prev action obs and threshold
+- **scenes**: add zed cameras to droid setup
+- new droid camera mount
+- added droid zed wrist mount
+- added zed2i
+- **scenes**: add empty world droid
+- add single fr3 mount mesh
+- **sim**: adds configureable kp and kv gains for sim robots
+- **extensions**: robotiq cli for serials
+- **extensions**: robotiq bump
+- **franka**: approach before controller start
+- **franka**: add policy_rate config option
+- add tquat_flange to robot observation
+- add flange in sim
+- **interface**: add get_cartesian_flange_position
+- **franka**: add get_cartesian_flange_position method
+- **franka**: tcp offset defaults to desk
+- **zed**: added intrinsics cli command
+- **fr3/panda**: config for collision values
+- **fr3/panda**: add max torque values to config
+- **cli**: camera episode video export
+- **yaml**: teleop example with cameras
+- **yam**: dual arm support
+- **yam**: add quest teleop
+- yam example
+- **extension**: initial yam implementation
+- **sim**: yam integration
+- **franka**: pd coefficients in controllers
+- **franka**: torque safety limit per joint
+- **extension**: taxim integration (#319)
+- **franka**: added droid setup config
+
+### Fix
+
+- **YAM**: YAM gripper set normalize with uses force
+- joint limits in fr3, xarm and so101
+- **wrappers**: always send arm commands instead of skipping near-identical ones
+- allow only positive frame rate
+- **hw**: move rate limit to bottom of stack
+- viewer process as deamon to avoid open gui on program close
+- **wrappers**: binary prev action obs wrong location
+- reset in storage wrapper to pass seed and options
+- **sim**: added solref and solimp for cubes
+- **assets**: zed2i fovy
+- **scenes**: robot frame objects automatically get grav comp prefix
+- **sim**: zed2i camera rotation
+- **ik**: tcp offset applied correctly in pin forward
+- **scenes**: mutation of q_home in empty world fr3
+- **examples**: added policy rate to for low level pd controller in franka examples
+- pybind pure override
+- virtual get_cartesian_flange_position
+- **franka**: reset also returns franka state
+- **franka**: desk ignore realtime control
+- **teleop**: increase quest reqd frequency to avoid alias effect
+- **yam**: ruckig version
+- **yam**: async
+- **franka cli**: untangle home and gripper
+- **zed**: remove hidden realsense dependency
+- **example**: remove thread for sim inference
+- **config**: single arm robot compatible with teleop
+
+### Refactor
+
+- remove unused robotics library extension and urdf assets
+- **franka**: use thread safe value class
+
## v0.7.2 (2026-06-24)
### Fix
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a9d48a8b..bc18ee7e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.5)
project(
rcs
LANGUAGES C CXX
- VERSION 0.7.2
+ VERSION 0.7.3
DESCRIPTION "Robot Control Stack Library"
)
diff --git a/Makefile b/Makefile
index a8f89c3f..655fe690 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,14 @@
PYSRC = python
CPPSRC = src
COMPILE_MODE = Release
+WHEELHOUSE = wheelhouse
+CORE_WHEELHOUSE = ${WHEELHOUSE}/core
+PY_EXT_WHEELHOUSE = ${WHEELHOUSE}/py_extensions
+CPP_EXT_WHEELHOUSE = ${WHEELHOUSE}/cpp_extensions
+PY_EXTENSIONS ?= rcs_realsense rcs_robotiq2f85 rcs_ur5e rcs_usb_cam rcs_xarm7 rcs_zed
+CPP_EXTENSIONS ?= rcs_fr3 rcs_panda rcs_so101
+# set to pypi to publish to the real index
+PYPI_REPOSITORY ?= testpypi
LINT_EXCLUDE_RUFF = --exclude examples/teleop/SimPublisher
LINT_EXCLUDE_MYPY = 'build|examples/teleop/SimPublisher|examples/inference/franka.py'
@@ -68,4 +76,34 @@ bump:
commit:
cz commit
-.PHONY: cppcheckformat cppformat cpplint gcccompile clangcompile stubgen pycheckformat pyformat pylint ruff mypy pytest bump commit
+buildcorewheels:
+ rm -rf ${CORE_WHEELHOUSE}
+ cibuildwheel --platform auto --output-dir ${CORE_WHEELHOUSE} .
+ twine check ${CORE_WHEELHOUSE}/*.whl
+
+uploadcorewheels:
+ twine upload --repository ${PYPI_REPOSITORY} ${CORE_WHEELHOUSE}/*.whl
+
+buildpyextensionwheels:
+ rm -rf ${PY_EXT_WHEELHOUSE}
+ for ext in ${PY_EXTENSIONS}; do \
+ uv build --wheel --out-dir ${PY_EXT_WHEELHOUSE} extensions/$$ext || exit 1; \
+ done
+ twine check ${PY_EXT_WHEELHOUSE}/*.whl
+
+uploadpyextensionwheels:
+ twine upload --repository ${PYPI_REPOSITORY} ${PY_EXT_WHEELHOUSE}/*.whl
+
+buildcppextensionwheels:
+ rm -rf ${CPP_EXT_WHEELHOUSE}
+ rm -rf dist/core && mkdir -p dist/core
+ cp ${CORE_WHEELHOUSE}/*.whl dist/core/
+ for ext in ${CPP_EXTENSIONS}; do \
+ cibuildwheel --platform auto --output-dir ${CPP_EXT_WHEELHOUSE} extensions/$$ext || exit 1; \
+ done
+ twine check ${CPP_EXT_WHEELHOUSE}/*.whl
+
+uploadcppextensionwheels:
+ twine upload --repository ${PYPI_REPOSITORY} ${CPP_EXT_WHEELHOUSE}/*.whl
+
+.PHONY: cppcheckformat cppformat cpplint gcccompile clangcompile stubgen pycheckformat pyformat pylint ruff mypy pytest bump commit buildcorewheels uploadcorewheels buildpyextensionwheels uploadpyextensionwheels buildcppextensionwheels uploadcppextensionwheels
diff --git a/assets/robots/fr3/fr3.urdf b/assets/robots/fr3/fr3.urdf
deleted file mode 100644
index c2a869e8..00000000
--- a/assets/robots/fr3/fr3.urdf
+++ /dev/null
@@ -1,276 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/assets/robots/fr3/fr3.xml b/assets/robots/fr3/fr3.xml
index 1e7d892d..409bb62b 100644
--- a/assets/robots/fr3/fr3.xml
+++ b/assets/robots/fr3/fr3.xml
@@ -80,13 +80,13 @@
-
+
-
+
@@ -99,14 +99,14 @@
-
+
-
@@ -115,7 +115,7 @@
-
@@ -129,7 +129,7 @@
-
diff --git a/assets/robots/so101/so101.urdf b/assets/robots/so101/so101.urdf
deleted file mode 100644
index 5dd02d24..00000000
--- a/assets/robots/so101/so101.urdf
+++ /dev/null
@@ -1,460 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- transmission_interface/SimpleTransmission
-
- hardware_interface/PositionJointInterface
-
-
- hardware_interface/PositionJointInterface
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
- transmission_interface/SimpleTransmission
-
- hardware_interface/PositionJointInterface
-
-
- hardware_interface/PositionJointInterface
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
- transmission_interface/SimpleTransmission
-
- hardware_interface/PositionJointInterface
-
-
- hardware_interface/PositionJointInterface
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- transmission_interface/SimpleTransmission
-
- hardware_interface/PositionJointInterface
-
-
- hardware_interface/PositionJointInterface
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
- transmission_interface/SimpleTransmission
-
- hardware_interface/PositionJointInterface
-
-
- hardware_interface/PositionJointInterface
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
- transmission_interface/SimpleTransmission
-
- hardware_interface/PositionJointInterface
-
-
- hardware_interface/PositionJointInterface
- 1
-
-
-
-
\ No newline at end of file
diff --git a/assets/robots/so101/so101.xml b/assets/robots/so101/so101.xml
index b5bb31d1..efd1109f 100644
--- a/assets/robots/so101/so101.xml
+++ b/assets/robots/so101/so101.xml
@@ -82,7 +82,7 @@
-
+
@@ -147,7 +147,7 @@
-
+
diff --git a/assets/robots/ur5e/ur5e.urdf b/assets/robots/ur5e/ur5e.urdf
deleted file mode 100644
index 7925a88c..00000000
--- a/assets/robots/ur5e/ur5e.urdf
+++ /dev/null
@@ -1,360 +0,0 @@
-
-
-
-
-
-
-
-
-
- transmission_interface/SimpleTransmission
-
- hardware_interface/PositionJointInterface
-
-
- 1
-
-
-
- transmission_interface/SimpleTransmission
-
- hardware_interface/PositionJointInterface
-
-
- 1
-
-
-
- transmission_interface/SimpleTransmission
-
- hardware_interface/PositionJointInterface
-
-
- 1
-
-
-
- transmission_interface/SimpleTransmission
-
- hardware_interface/PositionJointInterface
-
-
- 1
-
-
-
- transmission_interface/SimpleTransmission
-
- hardware_interface/PositionJointInterface
-
-
- 1
-
-
-
- transmission_interface/SimpleTransmission
-
- hardware_interface/PositionJointInterface
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/docs/development/cpp_extension.md b/docs/development/cpp_extension.md
index 42deac43..df89c0ff 100644
--- a/docs/development/cpp_extension.md
+++ b/docs/development/cpp_extension.md
@@ -55,4 +55,3 @@ rcs_mycppext/
## Examples
- **rcs_fr3**: Implements the driver for the Franka Research 3 robot in C++ using `libfranka`.
-- **rcs_robotics_library**: Wraps the Robotics Library (RL) for kinematics and path planning.
diff --git a/docs/extensions/index.md b/docs/extensions/index.md
index 89964125..a576bdad 100644
--- a/docs/extensions/index.md
+++ b/docs/extensions/index.md
@@ -14,7 +14,6 @@ rcs_yam
rcs_realsense
rcs_usb_cam
rcs_tacto
-rcs_robotics_library
rcs_robotiq2f85
rcs_zed
```
diff --git a/docs/extensions/overview.md b/docs/extensions/overview.md
index f33539cb..5b286ecf 100644
--- a/docs/extensions/overview.md
+++ b/docs/extensions/overview.md
@@ -43,7 +43,6 @@ RCS comes with several supported extensions:
- **rcs_realsense**: Support for Intel RealSense cameras.
- **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_robotiq2f85**: Integration with the Robotiq 2F-85 Gripper.
## Creating Extensions
diff --git a/docs/extensions/rcs_robotics_library.md b/docs/extensions/rcs_robotics_library.md
deleted file mode 100644
index 92dd54dd..00000000
--- a/docs/extensions/rcs_robotics_library.md
+++ /dev/null
@@ -1,17 +0,0 @@
-# RCS Robotics Library Extension
-
-This extension provides integration with the [Robotics Library (RL)](https://www.roboticslibrary.org/) for kinematics and path planning.
-
-## Installation
-
-```shell
-sudo apt install $(cat extensions/rcs_robotics_library/debian_deps.txt)
-pip install rcs-robotics-library
-```
-
-For local development from this repository:
-
-```shell
-pip install -ve . --no-build-isolation
-pip install -ve extensions/rcs_robotics_library --no-build-isolation
-```
diff --git a/extensions/rcs_fr3/CMakeLists.txt b/extensions/rcs_fr3/CMakeLists.txt
index c64a92eb..b5365fcb 100644
--- a/extensions/rcs_fr3/CMakeLists.txt
+++ b/extensions/rcs_fr3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.24)
project(
rcs_fr3
LANGUAGES C CXX
- VERSION 0.7.2
+ VERSION 0.7.3
DESCRIPTION "RCS Libfranka integration"
)
diff --git a/extensions/rcs_fr3/pyproject.toml b/extensions/rcs_fr3/pyproject.toml
index dd29b836..a53e9bf1 100644
--- a/extensions/rcs_fr3/pyproject.toml
+++ b/extensions/rcs_fr3/pyproject.toml
@@ -8,15 +8,15 @@ requires = [
"cmake",
"ninja",
"pin==3.7.0",
- "rcs-core>=0.7.2",
+ "rcs-core>=0.7.3",
]
build-backend = "scikit_build_core.build"
[project]
name = "rcs_fr3"
-version = "0.7.2"
+version = "0.7.3"
description = "RCS libfranka integration"
-dependencies = ["rcs-core>=0.7.2", "frankik"]
+dependencies = ["rcs-core>=0.7.3", "frankik"]
readme = "README.md"
license = "AGPL-3.0-or-later"
maintainers = [{ name = "Tobias Juelg", email = "tobias.juelg@utn.de" }]
@@ -24,6 +24,14 @@ authors = [{ name = "Tobias Juelg", email = "tobias.juelg@utn.de" }]
requires-python = ">=3.11"
+[dependency-groups]
+build_deps = [
+ "pin==3.7.0",
+ "cmeel-urdfdom<5",
+ "cmeel-tinyxml2<11",
+ "scikit-build-core>=0.3.3",
+]
+
[tool.scikit-build]
build.verbose = true
build.targets = ["_core"]
@@ -33,7 +41,15 @@ wheel.packages = ["src/rcs_fr3"]
install.components = ["python_package"]
[tool.cibuildwheel]
-skip = ["cp314*", "*-musllinux*"]
+build = ["cp311-*", "cp312-*", "cp313-*"]
+skip = ["*-musllinux*"]
+before-build = "pip install --upgrade pip && pip install --group {package}/pyproject.toml:build_deps cmake ninja && pip install --no-index --no-deps --find-links {project}/dist/core rcs-core"
+build-frontend = { name = "pip", args = ["--no-build-isolation"] }
+environment = { SKBUILD_BUILD_DIR = "/tmp/rcs-build/{wheel_tag}" }
+
+[tool.cibuildwheel.linux]
+archs = ["x86_64"]
+manylinux-x86_64-image = "manylinux_2_28"
repair-wheel-command = "auditwheel repair -w {dest_dir} {wheel} --exclude librcs.so --exclude libpinocchio_default.so.3.7.0 --exclude libpinocchio_parsers.so.3.7.0"
[tool.black]
diff --git a/extensions/rcs_fr3/src/hw/Franka.h b/extensions/rcs_fr3/src/hw/Franka.h
index 410ffe8c..7d875f9a 100644
--- a/extensions/rcs_fr3/src/hw/Franka.h
+++ b/extensions/rcs_fr3/src/hw/Franka.h
@@ -80,10 +80,10 @@ struct FrankaConfig : common::RobotConfig {
Eigen::Matrix joint_limits =
(Eigen::Matrix(2, 7) <<
// low 7‐tuple
- -2.3093,
- -1.5133, -2.4937, -2.7478, -2.4800, 0.8521, -2.6895,
+ -2.3476,
+ -1.5454, -2.4937, -2.7714, -2.5100, 0.7773, -2.7045,
// high 7‐tuple
- 2.3093, 1.5133, 2.4937, -0.4461, 2.4800, 4.2094, 2.6895)
+ 2.3476, 1.5454, 2.4937, -0.4226, 2.5100, 4.2841, 2.7045)
.finished();
};
diff --git a/extensions/rcs_fr3/src/rcs_fr3/_core/__init__.pyi b/extensions/rcs_fr3/src/rcs_fr3/_core/__init__.pyi
index 78b6b4cc..72a3c964 100644
--- a/extensions/rcs_fr3/src/rcs_fr3/_core/__init__.pyi
+++ b/extensions/rcs_fr3/src/rcs_fr3/_core/__init__.pyi
@@ -16,4 +16,4 @@ from __future__ import annotations
from . import hw
__all__: list[str] = ["hw"]
-__version__: str = "0.7.2"
+__version__: str = "0.7.3"
diff --git a/extensions/rcs_fr3/src/rcs_fr3/creators.py b/extensions/rcs_fr3/src/rcs_fr3/creators.py
index e9804164..36e4f3f9 100644
--- a/extensions/rcs_fr3/src/rcs_fr3/creators.py
+++ b/extensions/rcs_fr3/src/rcs_fr3/creators.py
@@ -7,7 +7,12 @@
import rcs.hand.tilburg_hand
from frankik import FrankaKinematics
from rcs._core.common import BaseCameraConfig, Gripper, GripperConfig, Kinematics, Pose
-from rcs.camera.hw import DummyCalibrationStrategy, HardwareCamera, HardwareCameraSet
+from rcs.camera.hw import (
+ CalibrationStrategy,
+ DummyCalibrationStrategy,
+ HardwareCamera,
+ HardwareCameraSet,
+)
from rcs.envs.base import (
CameraSetWrapper,
ControlMode,
@@ -62,8 +67,6 @@ class HardwareCameraCreatorConfig:
def _create_realsense_camera(cfg: HardwareCameraCreatorConfig) -> HardwareCamera:
try:
- from rcs.camera.hw import CalibrationStrategy
-
# from rcs_realsense.calibration import FR3BaseArucoCalibration
from rcs_realsense.camera import RealSenseCameraSet
except ImportError as e:
@@ -81,7 +84,6 @@ def _create_realsense_camera(cfg: HardwareCameraCreatorConfig) -> HardwareCamera
def _create_zed_camera(cfg: HardwareCameraCreatorConfig) -> HardwareCamera:
try:
- from rcs.camera.hw import CalibrationStrategy
from rcs_zed.camera import ZEDCameraSet
except ImportError as e:
msg = "ZED camera support requires the `rcs_zed` extension to be installed."
diff --git a/extensions/rcs_panda/CMakeLists.txt b/extensions/rcs_panda/CMakeLists.txt
index 0f7c061f..63731d07 100644
--- a/extensions/rcs_panda/CMakeLists.txt
+++ b/extensions/rcs_panda/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.24)
project(
rcs_panda
LANGUAGES C CXX
- VERSION 0.7.2
+ VERSION 0.7.3
DESCRIPTION "RCS Libfranka integration"
)
diff --git a/extensions/rcs_panda/pyproject.toml b/extensions/rcs_panda/pyproject.toml
index 6622a6f1..8d24c488 100644
--- a/extensions/rcs_panda/pyproject.toml
+++ b/extensions/rcs_panda/pyproject.toml
@@ -7,15 +7,15 @@ requires = [
"pybind11",
"cmake",
"ninja",
- "rcs-core>=0.7.2",
+ "rcs-core>=0.7.3",
]
build-backend = "scikit_build_core.build"
[project]
name = "rcs_panda"
-version = "0.7.2"
+version = "0.7.3"
description = "RCS libfranka integration"
-dependencies = ["rcs-core>=0.7.2"]
+dependencies = ["rcs-core>=0.7.3"]
readme = "README.md"
license = "AGPL-3.0-or-later"
maintainers = [{ name = "Tobias Juelg", email = "tobias.juelg@utn.de" }]
@@ -23,6 +23,14 @@ authors = [{ name = "Tobias Juelg", email = "tobias.juelg@utn.de" }]
requires-python = ">=3.11"
+[dependency-groups]
+build_deps = [
+ "pin==3.7.0",
+ "cmeel-urdfdom<5",
+ "cmeel-tinyxml2<11",
+ "scikit-build-core>=0.3.3",
+]
+
[tool.scikit-build]
build.verbose = true
build.targets = ["_core"]
@@ -32,7 +40,15 @@ wheel.packages = ["src/rcs_panda"]
install.components = ["python_package"]
[tool.cibuildwheel]
-skip = ["cp314*", "*-musllinux*"]
+build = ["cp311-*", "cp312-*", "cp313-*"]
+skip = ["*-musllinux*"]
+before-build = "pip install --upgrade pip && pip install --group {package}/pyproject.toml:build_deps cmake ninja && pip install --no-index --no-deps --find-links {project}/dist/core rcs-core"
+build-frontend = { name = "pip", args = ["--no-build-isolation"] }
+environment = { SKBUILD_BUILD_DIR = "/tmp/rcs-build/{wheel_tag}" }
+
+[tool.cibuildwheel.linux]
+archs = ["x86_64"]
+manylinux-x86_64-image = "manylinux_2_28"
repair-wheel-command = "auditwheel repair -w {dest_dir} {wheel} --exclude librcs.so --exclude libpinocchio_default.so.3.7.0 --exclude libpinocchio_parsers.so.3.7.0"
[tool.black]
diff --git a/extensions/rcs_panda/src/rcs_panda/_core/__init__.pyi b/extensions/rcs_panda/src/rcs_panda/_core/__init__.pyi
index 78b6b4cc..72a3c964 100644
--- a/extensions/rcs_panda/src/rcs_panda/_core/__init__.pyi
+++ b/extensions/rcs_panda/src/rcs_panda/_core/__init__.pyi
@@ -16,4 +16,4 @@ from __future__ import annotations
from . import hw
__all__: list[str] = ["hw"]
-__version__: str = "0.7.2"
+__version__: str = "0.7.3"
diff --git a/extensions/rcs_panda/src/rcs_panda/creators.py b/extensions/rcs_panda/src/rcs_panda/creators.py
index cf2e09d6..28bace5a 100644
--- a/extensions/rcs_panda/src/rcs_panda/creators.py
+++ b/extensions/rcs_panda/src/rcs_panda/creators.py
@@ -5,7 +5,12 @@
import gymnasium as gym
import rcs.hand.tilburg_hand
from rcs._core.common import BaseCameraConfig, Gripper, GripperConfig, GripperType
-from rcs.camera.hw import DummyCalibrationStrategy, HardwareCamera, HardwareCameraSet
+from rcs.camera.hw import (
+ CalibrationStrategy,
+ DummyCalibrationStrategy,
+ HardwareCamera,
+ HardwareCameraSet,
+)
from rcs.envs.base import (
CameraSetWrapper,
ControlMode,
@@ -38,7 +43,6 @@ class HardwareCameraCreatorConfig:
def _create_realsense_camera(cfg: HardwareCameraCreatorConfig) -> HardwareCamera:
try:
- from rcs.camera.hw import CalibrationStrategy
# from rcs_realsense.calibration import FR3BaseArucoCalibration
from rcs_realsense.camera import RealSenseCameraSet
diff --git a/extensions/rcs_realsense/pyproject.toml b/extensions/rcs_realsense/pyproject.toml
index e093495c..63574b1f 100644
--- a/extensions/rcs_realsense/pyproject.toml
+++ b/extensions/rcs_realsense/pyproject.toml
@@ -4,12 +4,12 @@ build-backend = "setuptools.build_meta"
[project]
name = "rcs_realsense"
-version = "0.7.2"
+version = "0.7.3"
description = "RCS realsense module"
readme = "README.md"
license = "AGPL-3.0-or-later"
dependencies = [
- "rcs-core>=0.7.2",
+ "rcs-core>=0.7.3",
"pyrealsense2~=2.55.1",
"pupil_apriltags",
"diskcache",
diff --git a/extensions/rcs_realsense/src/rcs_realsense/__init__.py b/extensions/rcs_realsense/src/rcs_realsense/__init__.py
index bc8c296f..4910b9ec 100644
--- a/extensions/rcs_realsense/src/rcs_realsense/__init__.py
+++ b/extensions/rcs_realsense/src/rcs_realsense/__init__.py
@@ -1 +1 @@
-__version__ = "0.7.2"
+__version__ = "0.7.3"
diff --git a/extensions/rcs_robotics_library/CMakeLists.txt b/extensions/rcs_robotics_library/CMakeLists.txt
deleted file mode 100644
index e27f0940..00000000
--- a/extensions/rcs_robotics_library/CMakeLists.txt
+++ /dev/null
@@ -1,64 +0,0 @@
-cmake_minimum_required(VERSION 3.19)
-
-project(
- rcs_fr3
- LANGUAGES C CXX
- VERSION 0.7.2
- DESCRIPTION "RCS robotics library integration"
-)
-
-set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
-
-set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) # Allow us to set options for subprojects
-
-cmake_policy(SET CMP0048 NEW) # Set version in project
-# Allow target properties affecting visibility during linking in static libraries
-set(CMAKE_POLICY_DEFAULT_CMP0063 NEW)
-cmake_policy(SET CMP0072 NEW) # Use GLVND instead of legacy libGL.so
-cmake_policy(SET CMP0135 NEW) # Use timestamp of file extraction not download
-cmake_policy(SET CMP0140 NEW) # Check return arguments
-
-set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
-set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
-set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
-
-set(CMAKE_CXX_STANDARD 20)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-set(CMAKE_CXX_EXTENSIONS OFF)
-set(CMAKE_POLICY_VERSION_MINIMUM 3.5)
-
-set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
-
-set(BUILD_SHARED_LIBS OFF)
-set(CMAKE_POSITION_INDEPENDENT_CODE ON)
-
-set(RL_BUILD_DEMOS OFF)
-set(RL_BUILD_RL_SG OFF)
-set(RL_BUILD_TESTS OFF)
-set(RL_BUILD_EXTRAS OFF)
-set(BUILD_PYTHON_INTERFACE OFF)
-set(BUILD_DOCUMENTATION OFF)
-
-include(FetchContent)
-
-find_package(Eigen3 REQUIRED)
-find_package(Python3 COMPONENTS Interpreter Development.Module REQUIRED)
-find_package(pinocchio REQUIRED)
-find_package(rcs REQUIRED)
-
-FetchContent_Declare(rl
- GIT_REPOSITORY https://github.com/roboticslibrary/rl.git
- GIT_TAG 0b3797215345a1d37903634095361233d190b2e6
- GIT_PROGRESS TRUE
- EXCLUDE_FROM_ALL
-)
-FetchContent_Declare(pybind11
- GIT_REPOSITORY https://github.com/pybind/pybind11.git
- GIT_TAG v2.13.4
- GIT_PROGRESS TRUE
- EXCLUDE_FROM_ALL
-)
-
-FetchContent_MakeAvailable(rl pybind11)
-
-add_subdirectory(src)
diff --git a/extensions/rcs_robotics_library/Makefile b/extensions/rcs_robotics_library/Makefile
deleted file mode 100644
index 858bd6c9..00000000
--- a/extensions/rcs_robotics_library/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-PYSRC = src
-CPPSRC = src
-COMPILE_MODE = Release
-
-# CPP
-cppcheckformat:
- clang-format --dry-run -Werror -i $(shell find ${CPPSRC} -name '*.cpp' -o -name '*.cc' -o -name '*.h')
-
-cppformat:
- clang-format -Werror -i $(shell find ${CPPSRC} -name '*.cpp' -o -name '*.cc' -o -name '*.h')
-
-cpplint:
- clang-tidy -p=build --warnings-as-errors='*' $(shell find ${CPPSRC} -name '*.cpp' -o -name '*.cc' -name '*.h')
-
-# import errors
-# clang-tidy -p=build --warnings-as-errors='*' $(shell find extensions/rcs_fr3/src -name '*.cpp' -o -name '*.cc' -name '*.h')
-
-gcccompile:
- cmake -DCMAKE_BUILD_TYPE=${COMPILE_MODE} -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -B build -G Ninja
- cmake --build build --target _core
-
-clangcompile:
- cmake -DCMAKE_BUILD_TYPE=${COMPILE_MODE} -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -B build -G Ninja
- cmake --build build --target _core
-
-# Auto generation of CPP binding stub files
-stubgen:
- pybind11-stubgen -o src --numpy-array-use-type-var rcs_robotics_library
- find ./src -name '*.pyi' -print | xargs sed -i '1s/^/# ATTENTION: auto generated from C++ code, use `make stubgen` to update!\n/'
- find ./src -not -path "./src/rcs_robotics_library/_core/*" -name '*.pyi' -delete
- find ./src/rcs_robotics_library/_core -name '*.pyi' -print | xargs sed -i 's/tuple\[typing\.Literal\[\([0-9]\+\)\], typing\.Literal\[1\]\]/tuple\[typing\.Literal[\1]\]/g'
- find ./src/rcs_robotics_library/_core -name '*.pyi' -print | xargs sed -i 's/tuple\[\([M|N]\), typing\.Literal\[1\]\]/tuple\[\1\]/g'
- ruff check --fix src/rcs_robotics_library/_core
- isort src/rcs_robotics_library/_core
- black src/rcs_robotics_library/_core
-
-
-
-.PHONY: cppcheckformat cppformat cpplint gcccompile clangcompile stubgen
diff --git a/extensions/rcs_robotics_library/README.md b/extensions/rcs_robotics_library/README.md
deleted file mode 100644
index 600e55a6..00000000
--- a/extensions/rcs_robotics_library/README.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# RCS Robotics Library Extension
-
-Integration with the [Robotics Library (RL)](https://www.roboticslibrary.org/) for kinematics and path planning.
-
-This extension depends on [`rcs-core`](https://pypi.org/project/rcs-core/).
-Documentation:
-
-## Installation
-
-Install the Debian dependencies first:
-
-```shell
-sudo apt install $(cat debian_deps.txt)
-```
-
-Install from PyPI:
-
-```shell
-pip install rcs-robotics-library
-```
-
-Warning: plain `pip install rcs-robotics-library` will install the published `rcs-core` dependency from PyPI.
-
-Install from a local checkout for development:
-
-```shell
-pip install -ve . --no-build-isolation
-```
-
-If you want this extension to use your local RCS checkout instead of the published `rcs-core` package, first install the main package from the repository root:
-
-```shell
-pip install -ve . --no-build-isolation
-pip install -ve extensions/rcs_robotics_library --no-build-isolation
-```
-
-## Usage
-
-```python
-from rcs_robotics_library import rl
-```
diff --git a/extensions/rcs_robotics_library/cmake/Findpinocchio.cmake b/extensions/rcs_robotics_library/cmake/Findpinocchio.cmake
deleted file mode 100644
index fcefcf5c..00000000
--- a/extensions/rcs_robotics_library/cmake/Findpinocchio.cmake
+++ /dev/null
@@ -1,68 +0,0 @@
-if (NOT pinocchio_FOUND)
- if (NOT Python3_FOUND)
- set(pinocchio_FOUND FALSE)
- if (pinocchio_FIND_REQUIRED)
- message(FATAL_ERROR "Could not find pinocchio. Please install pinocchio using pip.")
- endif()
- return()
- endif()
-
- # Check if the include directory exists
- cmake_path(APPEND Python3_SITELIB cmeel.prefix include OUTPUT_VARIABLE pinocchio_INCLUDE_DIRS)
- if (NOT EXISTS ${pinocchio_INCLUDE_DIRS})
- set(pinocchio_FOUND FALSE)
- if (pinocchio_FIND_REQUIRED)
- message(FATAL_ERROR "Could not find pinocchio. Please install pinocchio using pip.")
- endif()
- return()
- endif()
-
- # Check if the library file exists
- cmake_path(APPEND Python3_SITELIB cmeel.prefix lib libpinocchio_default.so OUTPUT_VARIABLE pinocchio_library_path)
- if (NOT EXISTS ${pinocchio_library_path})
- set(pinocchio_FOUND FALSE)
- if (pinocchio_FIND_REQUIRED)
- message(FATAL_ERROR "Could not find pinocchio. Please install pinocchio using pip.")
- endif()
- return()
- endif()
-
- # Check if the library file exists
- cmake_path(APPEND Python3_SITELIB cmeel.prefix lib libpinocchio_parsers.so OUTPUT_VARIABLE pinocchio_parsers_path)
- if (NOT EXISTS ${pinocchio_parsers_path})
- set(pinocchio_FOUND FALSE)
- if (pinocchio_FIND_REQUIRED)
- message(FATAL_ERROR "Could not find pinocchio parsers path. Please install pinocchio using pip.")
- endif()
- return()
- endif()
-
- # Extract version from the library filename
- file(GLOB pinocchio_dist_info "${Python3_SITELIB}/pin-*.dist-info")
- cmake_path(GET pinocchio_dist_info FILENAME pinocchio_library_filename)
- string(REPLACE "pin-" "" pinocchio_VERSION "${pinocchio_library_filename}")
- string(REPLACE ".dist-info" "" pinocchio_VERSION "${pinocchio_VERSION}")
-
- # Create the imported target
- add_library(pinocchio::pinocchio SHARED IMPORTED)
- target_include_directories(pinocchio::pinocchio INTERFACE ${pinocchio_INCLUDE_DIRS})
- set_target_properties(pinocchio::pinocchio
- PROPERTIES
- IMPORTED_LOCATION "${pinocchio_library_path}"
- )
-
- add_library(pinocchio::parsers SHARED IMPORTED)
- target_include_directories(pinocchio::parsers INTERFACE ${pinocchio_INCLUDE_DIRS})
- set_target_properties(pinocchio::parsers
- PROPERTIES
- IMPORTED_LOCATION "${pinocchio_parsers_path}"
- )
-
- add_library(pinocchio::all INTERFACE IMPORTED)
- set_target_properties(pinocchio::all
- PROPERTIES
- INTERFACE_LINK_LIBRARIES "pinocchio::pinocchio;pinocchio::parsers"
- )
- set(pinocchio_FOUND TRUE)
-
-endif()
diff --git a/extensions/rcs_robotics_library/cmake/Findrcs.cmake b/extensions/rcs_robotics_library/cmake/Findrcs.cmake
deleted file mode 100644
index bd89b83e..00000000
--- a/extensions/rcs_robotics_library/cmake/Findrcs.cmake
+++ /dev/null
@@ -1,46 +0,0 @@
-if (NOT rcs_FOUND)
- if (NOT Python3_FOUND)
- set(rcs_FOUND FALSE)
- if (rcs_FIND_REQUIRED)
- message(FATAL_ERROR "Could not find rcs. Please install rcs-core using pip.")
- endif()
- return()
- endif()
-
- # Check if the include directory exists
- cmake_path(APPEND Python3_SITELIB rcs include OUTPUT_VARIABLE rcs_INCLUDE_DIRS)
- if (NOT EXISTS ${rcs_INCLUDE_DIRS})
- set(rcs_FOUND FALSE)
- if (rcs_FIND_REQUIRED)
- message(FATAL_ERROR "Could not find rcs. Please install rcs-core using pip.")
- endif()
- return()
- endif()
-
- # Check if the library file exists
- cmake_path(APPEND Python3_SITELIB rcs OUTPUT_VARIABLE rcs_library_path)
- file(GLOB rcs_library_path "${rcs_library_path}/librcs.so")
- if (NOT EXISTS ${rcs_library_path})
- set(rcs_FOUND FALSE)
- if (rcs_FIND_REQUIRED)
- message(FATAL_ERROR "Could not find rcs. Please install rcs-core using pip.")
- endif()
- return()
- endif()
-
- # Extract version from the library filename
- # file(GLOB rcs_dist_info "${Python3_SITELIB}/rcs-*.dist-info")
- # cmake_path(GET rcs_dist_info FILENAME rcs_library_filename)
- # string(REPLACE "rcs-" "" rcs_VERSION "${rcs_library_filename}")
- # string(REPLACE ".dist-info" "" rcs_VERSION "${rcs_VERSION}")
-
- # Create the imported target
- add_library(rcs SHARED IMPORTED)
- target_include_directories(rcs INTERFACE ${rcs_INCLUDE_DIRS})
- set_target_properties(
- rcs
- PROPERTIES
- IMPORTED_LOCATION "${rcs_library_path}"
- )
- set(rcs_FOUND TRUE)
-endif()
diff --git a/extensions/rcs_robotics_library/debian_deps.txt b/extensions/rcs_robotics_library/debian_deps.txt
deleted file mode 100644
index c8c23b8b..00000000
--- a/extensions/rcs_robotics_library/debian_deps.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-libxslt-dev
-libcoin-dev
-libccd-dev
-libboost-all-dev
-liblzma-dev
-libxml2-dev
-libxslt1-dev
-libeigen3-dev
\ No newline at end of file
diff --git a/extensions/rcs_robotics_library/pyproject.toml b/extensions/rcs_robotics_library/pyproject.toml
deleted file mode 100644
index fd214b2d..00000000
--- a/extensions/rcs_robotics_library/pyproject.toml
+++ /dev/null
@@ -1,46 +0,0 @@
-[build-system]
-requires = [
- "build",
- "wheel",
- "setuptools>=45",
- "scikit-build-core>=0.3.3",
- "pybind11",
- "cmake",
- "ninja",
- "rcs-core>=0.7.2",
-]
-build-backend = "scikit_build_core.build"
-
-[project]
-name = "rcs_robotics_library"
-version = "0.7.2"
-description = "RCS robotics library integration"
-readme = "README.md"
-license = "AGPL-3.0-or-later"
-dependencies = ["rcs-core>=0.7.2"]
-maintainers = [{ name = "Tobias Juelg", email = "tobias.juelg@utn.de" }]
-authors = [
- { name = "Tobias Juelg", email = "tobias.juelg@utn.de" },
- { name = "Pierre Krack", email = "pierre.krack@utn.de" },
-]
-requires-python = ">=3.11"
-
-
-[tool.scikit-build]
-build.verbose = true
-build.targets = ["_core"]
-logging.level = "INFO"
-build-dir = "build"
-wheel.packages = ["src/rcs_robotics_library"]
-install.components = ["python_package"]
-
-[tool.cibuildwheel]
-skip = ["cp314*", "*-musllinux*"]
-repair-wheel-command = "auditwheel repair -w {dest_dir} {wheel} --exclude librcs.so --exclude libpinocchio_default.so.3.7.0 --exclude libpinocchio_parsers.so.3.7.0"
-
-[tool.black]
-line-length = 120
-target-version = ["py310"]
-
-[tool.isort]
-profile = "black"
diff --git a/extensions/rcs_robotics_library/src/CMakeLists.txt b/extensions/rcs_robotics_library/src/CMakeLists.txt
deleted file mode 100644
index a458c164..00000000
--- a/extensions/rcs_robotics_library/src/CMakeLists.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-target_include_directories(rcs INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
-add_subdirectory(pybind)
diff --git a/extensions/rcs_robotics_library/src/pybind/CMakeLists.txt b/extensions/rcs_robotics_library/src/pybind/CMakeLists.txt
deleted file mode 100644
index 09d0acae..00000000
--- a/extensions/rcs_robotics_library/src/pybind/CMakeLists.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-pybind11_add_module(_core MODULE rcs.cpp)
-target_link_libraries(_core PRIVATE rcs mdl pinocchio::all)
-target_compile_definitions(_core PRIVATE VERSION_INFO=${PROJECT_VERSION})
-
-set_target_properties(_core PROPERTIES
- INSTALL_RPATH "$ORIGIN;$ORIGIN/../rcs;$ORIGIN/../cmeel.prefix/lib"
- INTERPROCEDURAL_OPTIMIZATION TRUE
-)
-
-# in pip
-install(TARGETS _core DESTINATION rcs_robotics_library COMPONENT python_package)
diff --git a/extensions/rcs_robotics_library/src/pybind/RL.h b/extensions/rcs_robotics_library/src/pybind/RL.h
deleted file mode 100644
index 71c8e11b..00000000
--- a/extensions/rcs_robotics_library/src/pybind/RL.h
+++ /dev/null
@@ -1,76 +0,0 @@
-#ifndef RCS_RL_H
-#define RCS_RL_H
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-
-namespace rcs {
-namespace robotics_library {
-
-class RoboticsLibraryIK : public rcs::common::Kinematics {
- private:
- const int random_restarts = 0;
- const double eps = 1e-3;
- struct {
- std::shared_ptr mdl;
- std::shared_ptr kin;
- std::shared_ptr ik;
- } rl_data;
-
- public:
- RoboticsLibraryIK(const std::string& urdf_path, size_t max_duration_ms = 300)
- : rl_data() {
- this->rl_data.mdl = rl::mdl::UrdfFactory().create(urdf_path);
- this->rl_data.kin =
- std::dynamic_pointer_cast(this->rl_data.mdl);
- this->rl_data.ik = std::make_shared(
- this->rl_data.kin.get());
- this->rl_data.ik->setRandomRestarts(this->random_restarts);
- this->rl_data.ik->setEpsilon(this->eps);
- this->rl_data.ik->setDuration(std::chrono::milliseconds(max_duration_ms));
- }
- std::optional inverse(
- const rcs::common::Pose& pose, const rcs::common::VectorXd& q0,
- const rcs::common::Pose& tcp_offset =
- rcs::common::Pose::Identity()) override {
- // pose is assumed to be in the robots coordinate frame
- this->rl_data.kin->setPosition(q0);
- this->rl_data.kin->forwardPosition();
- rcs::common::Pose new_pose = pose * tcp_offset.inverse();
-
- this->rl_data.ik->addGoal(new_pose.affine_matrix(), 0);
- bool success = this->rl_data.ik->solve();
- if (success) {
- // is this forward needed and is it mabye possible to call
- // this on the model?
- this->rl_data.kin->forwardPosition();
- return this->rl_data.kin->getPosition();
- } else {
- return std::nullopt;
- }
- }
- rcs::common::Pose forward(const rcs::common::VectorXd& q0,
- const rcs::common::Pose& tcp_offset) override {
- // pose is assumed to be in the robots coordinate frame
- this->rl_data.kin->setPosition(q0);
- this->rl_data.kin->forwardPosition();
- rcs::common::Pose pose = this->rl_data.kin->getOperationalPosition(0);
- // apply the tcp offset
- return pose * tcp_offset.inverse();
- }
-};
-
-} // namespace robotics_library
-} // namespace rcs
-
-#endif // RCS_RL_H
diff --git a/extensions/rcs_robotics_library/src/pybind/rcs.cpp b/extensions/rcs_robotics_library/src/pybind/rcs.cpp
deleted file mode 100644
index 094daab7..00000000
--- a/extensions/rcs_robotics_library/src/pybind/rcs.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-
-#include
-
-#include "RL.h"
-#include "rcs/Kinematics.h"
-#include "rl/mdl/UrdfFactory.h"
-
-// TODO: define exceptions
-
-#define STRINGIFY(x) #x
-#define MACRO_STRINGIFY(x) STRINGIFY(x)
-
-namespace py = pybind11;
-
-PYBIND11_MODULE(_core, m) {
- m.doc() = R"pbdoc(
- Robot Control Stack Python Bindings
- -----------------------
-
- .. currentmodule:: _core
-
- .. autosummary::
- :toctree: _generate
-
- )pbdoc";
-#ifdef VERSION_INFO
- m.attr("__version__") = MACRO_STRINGIFY(VERSION_INFO);
-#else
- m.attr("__version__") = "dev";
-#endif
-
- // HARDWARE MODULE
- auto rl = m.def_submodule("rl", "rcs robotics library module");
-
- py::object kinematics =
- (py::object)py::module_::import("rcs").attr("common").attr("Kinematics");
- py::class_>(
- rl, "RoboticsLibraryIK", kinematics)
- .def(py::init(), py::arg("urdf_path"),
- py::arg("max_duration_ms") = 300);
-}
diff --git a/extensions/rcs_robotics_library/src/rcs_robotics_library/__init__.py b/extensions/rcs_robotics_library/src/rcs_robotics_library/__init__.py
deleted file mode 100644
index ff5f354a..00000000
--- a/extensions/rcs_robotics_library/src/rcs_robotics_library/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from rcs_robotics_library._core import __version__, rl
-
-__all__ = [
- "rl",
- "__version__",
-]
diff --git a/extensions/rcs_robotics_library/src/rcs_robotics_library/_core/__init__.pyi b/extensions/rcs_robotics_library/src/rcs_robotics_library/_core/__init__.pyi
deleted file mode 100644
index d574dd50..00000000
--- a/extensions/rcs_robotics_library/src/rcs_robotics_library/_core/__init__.pyi
+++ /dev/null
@@ -1,19 +0,0 @@
-# ATTENTION: auto generated from C++ code, use `make stubgen` to update!
-"""
-
- Robot Control Stack Python Bindings
- -----------------------
-
- .. currentmodule:: _core
-
- .. autosummary::
- :toctree: _generate
-
-
-"""
-from __future__ import annotations
-
-from . import rl
-
-__all__: list[str] = ["rl"]
-__version__: str = "0.7.2"
diff --git a/extensions/rcs_robotics_library/src/rcs_robotics_library/_core/rl.pyi b/extensions/rcs_robotics_library/src/rcs_robotics_library/_core/rl.pyi
deleted file mode 100644
index d0001745..00000000
--- a/extensions/rcs_robotics_library/src/rcs_robotics_library/_core/rl.pyi
+++ /dev/null
@@ -1,12 +0,0 @@
-# ATTENTION: auto generated from C++ code, use `make stubgen` to update!
-"""
-rcs robotics library module
-"""
-from __future__ import annotations
-
-import rcs._core.common
-
-__all__: list[str] = ["RoboticsLibraryIK"]
-
-class RoboticsLibraryIK(rcs._core.common.Kinematics):
- def __init__(self, urdf_path: str, max_duration_ms: int = 300) -> None: ...
diff --git a/extensions/rcs_robotiq2f85/pyproject.toml b/extensions/rcs_robotiq2f85/pyproject.toml
index 02b02c22..d042108b 100644
--- a/extensions/rcs_robotiq2f85/pyproject.toml
+++ b/extensions/rcs_robotiq2f85/pyproject.toml
@@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta"
[project]
name = "rcs_robotiq2f85"
-version = "0.7.2"
+version = "0.7.3"
description="RCS RobotiQ module"
dependencies = [
- "rcs-core>=0.7.2",
+ "rcs-core>=0.7.3",
"robotiq2f==0.2.0",
"typer~=0.9",
]
diff --git a/extensions/rcs_robotiq2f85/src/rcs_robotiq2f85/__init__.py b/extensions/rcs_robotiq2f85/src/rcs_robotiq2f85/__init__.py
index bc8c296f..4910b9ec 100644
--- a/extensions/rcs_robotiq2f85/src/rcs_robotiq2f85/__init__.py
+++ b/extensions/rcs_robotiq2f85/src/rcs_robotiq2f85/__init__.py
@@ -1 +1 @@
-__version__ = "0.7.2"
+__version__ = "0.7.3"
diff --git a/extensions/rcs_so101/CMakeLists.txt b/extensions/rcs_so101/CMakeLists.txt
index 472128ef..40bae400 100644
--- a/extensions/rcs_so101/CMakeLists.txt
+++ b/extensions/rcs_so101/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.19)
project(
rcs_so101
LANGUAGES C CXX
- VERSION 0.7.2
+ VERSION 0.7.3
DESCRIPTION "RCS so101 ik"
)
diff --git a/extensions/rcs_so101/pyproject.toml b/extensions/rcs_so101/pyproject.toml
index 33b71daf..97497f3f 100644
--- a/extensions/rcs_so101/pyproject.toml
+++ b/extensions/rcs_so101/pyproject.toml
@@ -7,21 +7,29 @@ requires = [
"pybind11",
"cmake",
"ninja",
- "rcs-core>=0.7.2",
+ "rcs-core>=0.7.3",
]
build-backend = "scikit_build_core.build"
[project]
name = "rcs_so101"
-version = "0.7.2"
+version = "0.7.3"
description = "RCS SO101 module"
-dependencies = ["rcs-core>=0.7.2", "lerobot==0.3.3"]
+dependencies = ["rcs-core>=0.7.3", "lerobot==0.3.3"]
readme = "README.md"
license = "AGPL-3.0-or-later"
maintainers = [{ name = "Tobias Juelg", email = "tobias.juelg@utn.de" }]
authors = [{ name = "Tobias Juelg", email = "tobias.juelg@utn.de" }]
requires-python = ">=3.11"
+[dependency-groups]
+build_deps = [
+ "pin==3.7.0",
+ "cmeel-urdfdom<5",
+ "cmeel-tinyxml2<11",
+ "scikit-build-core>=0.3.3",
+]
+
[tool.scikit-build]
build.verbose = true
build.targets = ["_core"]
@@ -31,7 +39,15 @@ wheel.packages = ["src/rcs_so101"]
install.components = ["python_package"]
[tool.cibuildwheel]
-skip = ["cp314*", "*-musllinux*"]
+build = ["cp311-*", "cp312-*", "cp313-*"]
+skip = ["*-musllinux*"]
+before-build = "pip install --upgrade pip && pip install --group {package}/pyproject.toml:build_deps cmake ninja && pip install --no-index --no-deps --find-links {project}/dist/core rcs-core"
+build-frontend = { name = "pip", args = ["--no-build-isolation"] }
+environment = { SKBUILD_BUILD_DIR = "/tmp/rcs-build/{wheel_tag}" }
+
+[tool.cibuildwheel.linux]
+archs = ["x86_64"]
+manylinux-x86_64-image = "manylinux_2_28"
repair-wheel-command = "auditwheel repair -w {dest_dir} {wheel} --exclude librcs.so --exclude libpinocchio_default.so.3.7.0 --exclude libpinocchio_parsers.so.3.7.0"
[tool.black]
diff --git a/extensions/rcs_so101/src/rcs_so101/_core/__init__.pyi b/extensions/rcs_so101/src/rcs_so101/_core/__init__.pyi
index 1baf0df9..7276f647 100644
--- a/extensions/rcs_so101/src/rcs_so101/_core/__init__.pyi
+++ b/extensions/rcs_so101/src/rcs_so101/_core/__init__.pyi
@@ -16,4 +16,4 @@ from __future__ import annotations
from . import so101_ik
__all__: list[str] = ["so101_ik"]
-__version__: str = "0.7.2"
+__version__: str = "0.7.3"
diff --git a/extensions/rcs_so101/src/rcs_so101/creators.py b/extensions/rcs_so101/src/rcs_so101/creators.py
index 696da475..7381b497 100644
--- a/extensions/rcs_so101/src/rcs_so101/creators.py
+++ b/extensions/rcs_so101/src/rcs_so101/creators.py
@@ -4,7 +4,7 @@
import gymnasium as gym
from rcs._core.common import BaseCameraConfig
-from rcs.camera.hw import HardwareCamera, HardwareCameraSet
+from rcs.camera.hw import CalibrationStrategy, HardwareCamera, HardwareCameraSet
from rcs.envs.base import (
CameraSetWrapper,
ControlMode,
@@ -32,7 +32,6 @@ class HardwareCameraCreatorConfig:
def _create_realsense_camera(cfg: HardwareCameraCreatorConfig) -> HardwareCamera:
try:
- from rcs.camera.hw import CalibrationStrategy
from rcs_realsense.calibration import FR3BaseArucoCalibration
from rcs_realsense.camera import RealSenseCameraSet
except ImportError as e:
diff --git a/extensions/rcs_tacto/README.md b/extensions/rcs_tacto/README.md
index b48e0414..a9902aca 100644
--- a/extensions/rcs_tacto/README.md
+++ b/extensions/rcs_tacto/README.md
@@ -7,13 +7,9 @@ Documentation:
## Installation
-Install from PyPI:
-
-```shell
-pip install rcs-tacto
-```
-
-Warning: plain `pip install rcs-tacto` will install the published `rcs-core` dependency from PyPI.
+`mujoco-tacto` is not published on PyPI, so it is pinned as a direct git reference in
+`pyproject.toml`. As a consequence this extension is installable from a checkout but cannot be
+published to PyPI, and it is not part of the wheel build workflow.
Install from a local checkout:
diff --git a/extensions/rcs_tacto/pyproject.toml b/extensions/rcs_tacto/pyproject.toml
index 576b67ea..5abca0a5 100644
--- a/extensions/rcs_tacto/pyproject.toml
+++ b/extensions/rcs_tacto/pyproject.toml
@@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta"
[project]
name = "rcs_tacto"
-version = "0.7.2"
+version = "0.7.3"
description = "RCS integration of tacto"
dependencies = [
- "rcs-core>=0.7.2",
+ "rcs-core>=0.7.3",
"omegaconf",
"mujoco-tacto@git+https://github.com/utn-air/mujoco-tacto.git@main",
]
diff --git a/extensions/rcs_tacto/src/rcs_tacto/__init__.py b/extensions/rcs_tacto/src/rcs_tacto/__init__.py
index bc8c296f..4910b9ec 100644
--- a/extensions/rcs_tacto/src/rcs_tacto/__init__.py
+++ b/extensions/rcs_tacto/src/rcs_tacto/__init__.py
@@ -1 +1 @@
-__version__ = "0.7.2"
+__version__ = "0.7.3"
diff --git a/extensions/rcs_taxim/pyproject.toml b/extensions/rcs_taxim/pyproject.toml
index 15e7a6e6..fbff8682 100644
--- a/extensions/rcs_taxim/pyproject.toml
+++ b/extensions/rcs_taxim/pyproject.toml
@@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta"
[project]
name = "rcs_taxim"
-version = "0.7.2"
+version = "0.7.3"
description = "RCS integration of mujoco-taxim"
dependencies = [
- "rcs>=0.7.2",
+ "rcs-core>=0.7.3",
"omegaconf",
"mujoco-taxim@git+https://github.com/utn-air/mujoco-taxim.git@norm2tex",
]
diff --git a/extensions/rcs_taxim/src/rcs_taxim/__init__.py b/extensions/rcs_taxim/src/rcs_taxim/__init__.py
index bc8c296f..4910b9ec 100644
--- a/extensions/rcs_taxim/src/rcs_taxim/__init__.py
+++ b/extensions/rcs_taxim/src/rcs_taxim/__init__.py
@@ -1 +1 @@
-__version__ = "0.7.2"
+__version__ = "0.7.3"
diff --git a/extensions/rcs_ur5e/pyproject.toml b/extensions/rcs_ur5e/pyproject.toml
index 497530cd..fee72473 100644
--- a/extensions/rcs_ur5e/pyproject.toml
+++ b/extensions/rcs_ur5e/pyproject.toml
@@ -4,9 +4,9 @@ build-backend = "setuptools.build_meta"
[project]
name = "rcs_ur5e"
-version = "0.7.2"
+version = "0.7.3"
description = "RCS UR5e module"
-dependencies = ["rcs-core>=0.7.2", "ur_rtde==1.6.1"]
+dependencies = ["rcs-core>=0.7.3", "ur_rtde==1.6.1"]
readme = "README.md"
license = "AGPL-3.0-or-later"
maintainers = [
diff --git a/extensions/rcs_ur5e/src/rcs_ur5e/__init__.py b/extensions/rcs_ur5e/src/rcs_ur5e/__init__.py
index deee221c..fa1c54b7 100644
--- a/extensions/rcs_ur5e/src/rcs_ur5e/__init__.py
+++ b/extensions/rcs_ur5e/src/rcs_ur5e/__init__.py
@@ -1,6 +1,6 @@
from rcs_ur5e import configs, creators, hw
-__version__ = "0.7.2"
+__version__ = "0.7.3"
__all__ = [
"configs",
diff --git a/extensions/rcs_ur5e/src/rcs_ur5e/creators.py b/extensions/rcs_ur5e/src/rcs_ur5e/creators.py
index 70d984f4..f89f3880 100644
--- a/extensions/rcs_ur5e/src/rcs_ur5e/creators.py
+++ b/extensions/rcs_ur5e/src/rcs_ur5e/creators.py
@@ -4,7 +4,7 @@
import gymnasium as gym
from rcs._core.common import BaseCameraConfig, Gripper, GripperConfig
-from rcs.camera.hw import HardwareCamera, HardwareCameraSet
+from rcs.camera.hw import CalibrationStrategy, HardwareCamera, HardwareCameraSet
from rcs.envs.base import (
CameraSetWrapper,
ControlMode,
@@ -33,7 +33,6 @@ class HardwareCameraCreatorConfig:
def _create_realsense_camera(cfg: HardwareCameraCreatorConfig) -> HardwareCamera:
try:
- from rcs.camera.hw import CalibrationStrategy
from rcs_realsense.calibration import FR3BaseArucoCalibration
from rcs_realsense.camera import RealSenseCameraSet
except ImportError as e:
diff --git a/extensions/rcs_usb_cam/pyproject.toml b/extensions/rcs_usb_cam/pyproject.toml
index a78c3852..33e14d95 100644
--- a/extensions/rcs_usb_cam/pyproject.toml
+++ b/extensions/rcs_usb_cam/pyproject.toml
@@ -4,11 +4,11 @@ build-backend = "setuptools.build_meta"
[project]
name = "rcs_usb_cam"
-version = "0.7.2"
+version = "0.7.3"
description = "RCS USB Camera module"
readme = "README.md"
license = "AGPL-3.0-or-later"
-dependencies = ["rcs-core>=0.7.2", "opencv-python~=4.10.0"]
+dependencies = ["rcs-core>=0.7.3", "opencv-python~=4.10.0"]
maintainers = [
{ name = "Tobias Juelg", email = "tobias.juelg@utn.de" },
{ name = "Seongjin Bien", email = "seongjin.bien@utn.de" },
diff --git a/extensions/rcs_xarm7/pyproject.toml b/extensions/rcs_xarm7/pyproject.toml
index 3671b0ba..066425f1 100644
--- a/extensions/rcs_xarm7/pyproject.toml
+++ b/extensions/rcs_xarm7/pyproject.toml
@@ -4,9 +4,9 @@ build-backend = "setuptools.build_meta"
[project]
name = "rcs_xarm7"
-version = "0.7.2"
+version = "0.7.3"
description = "RCS xArm7 module"
-dependencies = ["rcs-core>=0.7.2", "xarm-python-sdk==1.17.0"]
+dependencies = ["rcs-core>=0.7.3", "xarm-python-sdk==1.17.0"]
readme = "README.md"
license = "AGPL-3.0-or-later"
maintainers = [
diff --git a/extensions/rcs_xarm7/src/rcs_xarm7/__init__.py b/extensions/rcs_xarm7/src/rcs_xarm7/__init__.py
index aea67f74..06fe62cc 100644
--- a/extensions/rcs_xarm7/src/rcs_xarm7/__init__.py
+++ b/extensions/rcs_xarm7/src/rcs_xarm7/__init__.py
@@ -1,6 +1,6 @@
from rcs_xarm7 import configs, creators, hw
-__version__ = "0.7.2"
+__version__ = "0.7.3"
__all__ = [
"configs",
diff --git a/extensions/rcs_xarm7/src/rcs_xarm7/creators.py b/extensions/rcs_xarm7/src/rcs_xarm7/creators.py
index 42ea2ecd..a4edb2be 100644
--- a/extensions/rcs_xarm7/src/rcs_xarm7/creators.py
+++ b/extensions/rcs_xarm7/src/rcs_xarm7/creators.py
@@ -6,7 +6,7 @@
import gymnasium as gym
from rcs._core.common import BaseCameraConfig
-from rcs.camera.hw import HardwareCamera, HardwareCameraSet
+from rcs.camera.hw import CalibrationStrategy, HardwareCamera, HardwareCameraSet
from rcs.envs.base import (
CameraSetWrapper,
ControlMode,
@@ -36,7 +36,6 @@ class HardwareCameraCreatorConfig:
def _create_realsense_camera(cfg: HardwareCameraCreatorConfig) -> HardwareCamera:
try:
- from rcs.camera.hw import CalibrationStrategy
from rcs_realsense.calibration import FR3BaseArucoCalibration
from rcs_realsense.camera import RealSenseCameraSet
except ImportError as e:
diff --git a/extensions/rcs_yam/pyproject.toml b/extensions/rcs_yam/pyproject.toml
index 3295c872..30b321fe 100644
--- a/extensions/rcs_yam/pyproject.toml
+++ b/extensions/rcs_yam/pyproject.toml
@@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta"
[project]
name = "rcs_yam"
-version = "0.7.2"
+version = "0.7.3"
description = "RCS YAM module"
dependencies = [
- "rcs-core>=0.7.2",
+ "rcs-core>=0.7.3",
# i2rt is not published on PyPI, so it is pinned to a commit of the upstream repository.
# A direct reference makes this project unpublishable to PyPI, see README.md.
"i2rt @ git+https://github.com/i2rt-robotics/i2rt@main", # tested commit: b9d8704c593aee4ef129d644f881564b8f2c4f6b
diff --git a/extensions/rcs_yam/src/rcs_yam/__init__.py b/extensions/rcs_yam/src/rcs_yam/__init__.py
index f8ffe7a2..d33f4a65 100644
--- a/extensions/rcs_yam/src/rcs_yam/__init__.py
+++ b/extensions/rcs_yam/src/rcs_yam/__init__.py
@@ -1,6 +1,6 @@
from rcs_yam import configs, creators, hw
-__version__ = "0.7.2"
+__version__ = "0.7.3"
__all__ = [
"configs",
diff --git a/extensions/rcs_yam/src/rcs_yam/configs.py b/extensions/rcs_yam/src/rcs_yam/configs.py
index c1b134fd..2d7a6f13 100644
--- a/extensions/rcs_yam/src/rcs_yam/configs.py
+++ b/extensions/rcs_yam/src/rcs_yam/configs.py
@@ -13,6 +13,9 @@
class DefaultYamHardwareEnv(RCSYamConfigEnvCreator):
channel = "can0"
+ # in N, <=0 turns off the limit
+ # 50 N is the default from YAM
+ gripper_force = 50.0
def config(self) -> YamHardwareEnvCreatorConfig:
robot_type = RobotType("Yam")
@@ -20,6 +23,7 @@ def config(self) -> YamHardwareEnvCreatorConfig:
robot_cfg = YamConfig(
channel=self.channel,
gripper_type_id="linear_4310",
+ gripper_force=self.gripper_force,
async_control=False,
robot_type=robot_type,
kinematic_model_path=rcs.ROBOTS[robot_type].mjcf_model_path,
@@ -45,9 +49,12 @@ def config(self) -> YamHardwareEnvCreatorConfig:
class DefaultYamDualMultiHardwareEnv(RCSYamMultiConfigEnvCreator):
left_channel = "can0"
right_channel = "can1"
+ # in N, <=0 turns off the limit
+ gripper_force = 50
def config(self) -> YamMultiHardwareEnvCreatorConfig:
base = DefaultYamHardwareEnv()
+ base.gripper_force = self.gripper_force
base.channel = self.left_channel
left_cfg = base.config()
diff --git a/extensions/rcs_yam/src/rcs_yam/creators.py b/extensions/rcs_yam/src/rcs_yam/creators.py
index b38823b8..aa42554a 100644
--- a/extensions/rcs_yam/src/rcs_yam/creators.py
+++ b/extensions/rcs_yam/src/rcs_yam/creators.py
@@ -4,7 +4,12 @@
import gymnasium as gym
from rcs._core.common import BaseCameraConfig, GripperConfig
-from rcs.camera.hw import DummyCalibrationStrategy, HardwareCamera, HardwareCameraSet
+from rcs.camera.hw import (
+ CalibrationStrategy,
+ DummyCalibrationStrategy,
+ HardwareCamera,
+ HardwareCameraSet,
+)
from rcs.envs.base import (
CameraSetWrapper,
ControlMode,
@@ -34,7 +39,6 @@ class HardwareCameraCreatorConfig:
def _create_realsense_camera(cfg: HardwareCameraCreatorConfig) -> HardwareCamera:
try:
- from rcs.camera.hw import CalibrationStrategy
from rcs_realsense.camera import RealSenseCameraSet
except ImportError as e:
msg = "RealSense camera support requires the `rcs_realsense` extension to be installed."
diff --git a/extensions/rcs_yam/src/rcs_yam/hw.py b/extensions/rcs_yam/src/rcs_yam/hw.py
index 24063733..3142b471 100644
--- a/extensions/rcs_yam/src/rcs_yam/hw.py
+++ b/extensions/rcs_yam/src/rcs_yam/hw.py
@@ -10,10 +10,40 @@
import typing
import numpy as np
+from i2rt.robots.get_robot import get_yam_robot
+from i2rt.robots.utils import ArmType, GripperForceLimiter, GripperType
from rcs.common_typing import RobotConfigKwargs
from rcs import common
+# Torque in Nm i2rt feeds forward to break the stiction of the gripper screw (utils.py:648). It
+# adds no grip force, but a cap below it leaves the fingers unable to move at all.
+I2RT_FRICTION_COMPENSATION = 0.3
+
+I2RT_DEFAULT_GRIPPER_FORCE = 50.0
+
+SHUT_FORCE = 1.0
+
+GRASP_WIDTH_TOLERANCE = 0.02
+GRASP_EFFORT_THRESHOLD = 0.5
+
+
+class YamGripperForceLimiter(GripperForceLimiter):
+ def __init__(
+ self,
+ *args: typing.Any,
+ friction_compensation: float = I2RT_FRICTION_COMPENSATION,
+ **kwargs: typing.Any,
+ ):
+ super().__init__(*args, **kwargs)
+ self.friction_compensation = friction_compensation
+
+ def update(self, gripper_state: dict[str, float]) -> float: # type: ignore[override]
+ cap = float(self.gripper_force_torque_map(current_angle=gripper_state["current_qpos"]))
+ slack = (cap + self.friction_compensation) / self._kp
+ measured = gripper_state["current_qpos"]
+ return float(np.clip(gripper_state["target_qpos"], measured - slack, measured + slack))
+
class YamConfig(common.RobotConfig):
"""Configuration of a single YAM arm on one CAN bus."""
@@ -33,6 +63,8 @@ def __init__(
max_joint_velocity: float = 0.5,
move_home_duration: float = 2.0,
gripper_limits_override: np.ndarray | None = None,
+ gripper_force: float | None = None,
+ gripper_friction_compensation: float = I2RT_FRICTION_COMPENSATION,
**kwargs: typing.Unpack[RobotConfigKwargs],
):
super().__init__(**kwargs)
@@ -56,6 +88,12 @@ def __init__(
self.move_home_duration = move_home_duration
# If set, skips the calibration run that would otherwise drive the fingers to both stops.
self.gripper_limits_override = gripper_limits_override
+ # Force in newtons the fingers close and hold with. None keeps the i2rt default of 50 N, a
+ # value <= 0 disables limiting and the gripper squeezes at full kp.
+ self.gripper_force = gripper_force
+ # To measure it for an arm, command a close at a negligible `gripper_force` and raise this
+ # until the fingers just start to move.
+ self.gripper_friction_compensation = gripper_friction_compensation
class Yam(common.Robot):
@@ -65,21 +103,22 @@ class Yam(common.Robot):
def __init__(self, cfg: YamConfig, ik: common.Kinematics):
super().__init__()
- from i2rt.robots.get_robot import get_yam_robot
- from i2rt.robots.utils import ArmType, GripperType
-
self._closed = True
self.ik = ik
self._config = cfg
self._dof = int(cfg.dof)
+ self._arm_type = ArmType.from_string_name(cfg.arm_type_id)
+ self._gripper_type = GripperType.from_string_name(cfg.gripper_type_id)
self._robot = get_yam_robot(
channel=cfg.channel,
- arm_type=ArmType.from_string_name(cfg.arm_type_id),
- gripper_type=GripperType.from_string_name(cfg.gripper_type_id),
+ arm_type=self._arm_type,
+ gripper_type=self._gripper_type,
gripper_limits_override=cfg.gripper_limits_override,
)
self._closed = False
self._has_gripper = self._robot.num_dofs() > self._dof
+ if cfg.gripper_force is not None:
+ self.set_gripper_force(cfg.gripper_force)
self._lock = threading.Lock()
# Seeding the target from the measured state avoids a jump on the first partial command.
self._target = np.asarray(self._robot.get_joint_pos(), dtype=np.float64).copy()
@@ -120,6 +159,17 @@ def get_gripper_width(self) -> float:
self._assert_gripper()
return float(np.asarray(self._robot.get_joint_pos(), dtype=np.float64)[self._dof])
+ def get_gripper_effort(self) -> float:
+ """Torque in Nm the gripper motor currently applies, useful to watch a grasp stall."""
+ self._assert_gripper()
+ return float(self._robot.get_observations()["gripper_eff"][0])
+
+ def get_commanded_gripper_width(self) -> float:
+ """Normalized width the fingers are travelling towards, as last written to the target."""
+ self._assert_gripper()
+ with self._lock:
+ return float(self._target[self._dof])
+
def get_cartesian_position(self) -> common.Pose:
# `Kinematics.forward` applies the inverse of the offset it is handed, so the TCP is composed
# here instead, to match the pose `SimRobot::get_cartesian_position` reports in simulation.
@@ -143,6 +193,24 @@ def set_gripper_width(self, width: float) -> None:
self._assert_gripper()
self._command(gripper=float(np.clip(width, 0.0, 1.0)))
+ def set_gripper_force(self, force: float, friction_compensation: float | None = None) -> None:
+ """Set the force in newtons the fingers close and hold with, <= 0 disables limiting."""
+ self._assert_gripper()
+ if friction_compensation is None:
+ friction_compensation = self._config.gripper_friction_compensation
+ if force > 0:
+ gripper_index = self._robot._gripper_index
+ self._robot._gripper_force_limiter = YamGripperForceLimiter(
+ max_force=force,
+ gripper_type=self._gripper_type,
+ arm_type=self._arm_type,
+ kp=float(self._robot._kp[gripper_index]),
+ friction_compensation=friction_compensation,
+ )
+ self._robot._limit_gripper_force = force
+ self._config.gripper_force = force
+ self._config.gripper_friction_compensation = friction_compensation
+
def move_home(self) -> None:
if self._config.q_home is None:
msg = "No home position configured."
@@ -209,27 +277,50 @@ def __init__(self, cfg: common.GripperConfig, robot: Yam):
super().__init__()
self._cfg = cfg
self._robot = robot
+ self._state = common.GripperState()
def get_config(self) -> common.GripperConfig:
return self._cfg
+ def get_state(self) -> common.GripperState:
+ return self._state
+
+ def is_grasped(self) -> bool:
+ """True while an object holds the fingers short of the width they are closing to."""
+ short_of_target = self.get_normalized_width() - self._robot.get_commanded_gripper_width()
+ if short_of_target <= GRASP_WIDTH_TOLERANCE:
+ return False
+ return abs(self._robot.get_gripper_effort()) > GRASP_EFFORT_THRESHOLD
+
def get_normalized_width(self) -> float:
return self._robot.get_gripper_width()
def set_normalized_width(self, width: float, force: float = 0) -> None:
+ """Move the fingers to `width`, 0 is closed and 1 is open, force in newtons."""
if not (0 <= width <= 1):
msg = f"Width must be between 0 and 1, got {width}."
raise ValueError(msg)
+ if force < 0:
+ msg = f"Force must be positive, got {force}. Turn limiting off with `Yam.set_gripper_force`."
+ raise ValueError(msg)
+ if force == 0:
+ self._robot.set_gripper_force(I2RT_DEFAULT_GRIPPER_FORCE)
+ else:
+ self._robot.set_gripper_force(force)
self._robot.set_gripper_width(width)
def open(self) -> None:
self.set_normalized_width(1.0)
def grasp(self) -> None:
+ """Close the fingers at the force the arm is configured with."""
+ force = self._robot.get_config().gripper_force
+ self._robot.set_gripper_force(I2RT_DEFAULT_GRIPPER_FORCE if force is None else force)
self.set_normalized_width(0.0)
def shut(self) -> None:
- self.set_normalized_width(0.0)
+ """Close the fingers without gripping."""
+ self.set_normalized_width(0.0, force=SHUT_FORCE)
def reset(self) -> None:
self.open()
diff --git a/extensions/rcs_zed/pyproject.toml b/extensions/rcs_zed/pyproject.toml
index 2ed6d4b9..b2683fb8 100644
--- a/extensions/rcs_zed/pyproject.toml
+++ b/extensions/rcs_zed/pyproject.toml
@@ -4,12 +4,12 @@ build-backend = "setuptools.build_meta"
[project]
name = "rcs_zed"
-version = "0.7.2"
+version = "0.7.3"
description = "RCS ZED camera module"
readme = "README.md"
license = "AGPL-3.0-or-later"
dependencies = [
- "rcs-core>=0.7.2",
+ "rcs-core>=0.7.3",
"opencv-python~=4.10.0",
"typer~=0.9",
]
diff --git a/include/rcs/Robot.h b/include/rcs/Robot.h
index 6186314f..cf33b36d 100644
--- a/include/rcs/Robot.h
+++ b/include/rcs/Robot.h
@@ -61,10 +61,10 @@ struct RobotConfig {
Eigen::Matrix joint_limits =
(Eigen::Matrix(2, 7) <<
// low 7‐tuple
- -2.3093,
- -1.5133, -2.4937, -2.7478, -2.4800, 0.8521, -2.6895,
+ -2.3476,
+ -1.5454, -2.4937, -2.7714, -2.5100, 0.7773, -2.7045,
// high 7‐tuple
- 2.3093, 1.5133, 2.4937, -0.4461, 2.4800, 4.2094, 2.6895)
+ 2.3476, 1.5454, 2.4937, -0.4226, 2.5100, 4.2841, 2.7045)
.finished();
virtual ~RobotConfig() {};
};
diff --git a/pyproject.toml b/pyproject.toml
index 21f28587..2079ea41 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -14,7 +14,7 @@ build-backend = "scikit_build_core.build"
[project]
name = "rcs_core"
-version = "0.7.2"
+version = "0.7.3"
description = "A lean, ROS-free sim-to-real framework for training and deploying Vision-Language-Action (VLA) models and RL agents. Native MuJoCo Gymnasium wrappers with synchronous execution for Franka, UR5e, xArm, and SO101."
dependencies = [
"websockets>=11.0",
@@ -72,6 +72,8 @@ dev = [
"clang-tidy",
"ninja",
"cmake",
+ "cibuildwheel==2.22.0",
+ "twine~=6.0",
]
build_deps = [
"mujoco==3.10.0",
@@ -82,11 +84,20 @@ build_deps = [
]
[tool.cibuildwheel]
-skip = ["cp314*", "*-musllinux*"]
-# Install X11 headers needed to compile GLFW
-before-all = "yum install -y libXi-devel libXcursor-devel libXinerama-devel libXrandr-devel glfw-devel"
-# Exclude MuJoCo AND Pinocchio from being bundled.
-repair-wheel-command = "auditwheel repair -w {dest_dir} {wheel} --exclude libmujoco.so.* --exclude libpinocchio_default.so.3.7.0 --exclude libpinocchio_parsers.so.3.7.0"
+build = ["cp311-*", "cp312-*", "cp313-*"]
+skip = ["*-musllinux*"]
+before-build = "pip install --upgrade pip && pip install --group {package}/pyproject.toml:build_deps wheel setuptools cmake ninja"
+environment = { SKBUILD_BUILD_DIR = "/tmp/rcs-build/{wheel_tag}" }
+
+[tool.cibuildwheel.linux]
+archs = ["x86_64"]
+manylinux-x86_64-image = "manylinux_2_28"
+before-all = "yum install -y epel-release && yum install -y libXi-devel libXcursor-devel libXinerama-devel libXrandr-devel glfw-devel"
+repair-wheel-command = "auditwheel repair -w {dest_dir} {wheel} --exclude libmujoco.so.3.10.0 --exclude libpinocchio_default.so.3.7.0 --exclude libpinocchio_parsers.so.3.7.0"
+
+[tool.cibuildwheel.macos]
+archs = ["arm64"]
+repair-wheel-command = "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel} --exclude libmujoco --exclude libpinocchio"
[tool.scikit-build]
build.verbose = true
@@ -187,7 +198,6 @@ version_files = [
"extensions/rcs_fr3/CMakeLists.txt:VERSION",
"extensions/rcs_fr3/src/rcs_fr3/_core/__init__.pyi:__version__",
"extensions/rcs_fr3/pyproject.toml:version",
- # The line below updates the dependency string "rcs>=x.y.z"
"extensions/rcs_fr3/pyproject.toml:\"rcs-core>=(.*)\"",
# --- Panda Extension ---
@@ -196,12 +206,6 @@ version_files = [
"extensions/rcs_panda/pyproject.toml:version",
"extensions/rcs_panda/pyproject.toml:\"rcs-core>=(.*)\"",
- # --- Robotics Library ---
- "extensions/rcs_robotics_library/CMakeLists.txt:VERSION",
- "extensions/rcs_robotics_library/src/rcs_robotics_library/_core/__init__.pyi:__version__",
- "extensions/rcs_robotics_library/pyproject.toml:version",
- "extensions/rcs_robotics_library/pyproject.toml:\"rcs-core>=(.*)\"",
-
# --- SO101 ---
"extensions/rcs_so101/CMakeLists.txt:VERSION",
"extensions/rcs_so101/src/rcs_so101/_core/__init__.pyi:__version__",
diff --git a/python/rcs/__init__.py b/python/rcs/__init__.py
index cf7fe01c..d8ed06a9 100644
--- a/python/rcs/__init__.py
+++ b/python/rcs/__init__.py
@@ -110,8 +110,8 @@ class RobotMetaConfig:
q_home=np.array([0.0, -np.pi / 4, 0.0, -3 * np.pi / 4, 0.0, np.pi / 2, 0.0]),
joint_limits=np.array(
[
- [-2.3093, -1.5133, -2.4937, -2.7478, -2.4800, 0.8521, -2.6895],
- [2.3093, 1.5133, 2.4937, -0.4461, 2.4800, 4.2094, 2.6895],
+ [-2.3476, -1.5454, -2.4937, -2.7714, -2.5100, 0.7773, -2.7045],
+ [2.3476, 1.5454, 2.4937, -0.4226, 2.5100, 4.2841, 2.7045],
]
),
),
@@ -148,8 +148,8 @@ class RobotMetaConfig:
q_home=np.array([0, -45.0 / 180.0 * np.pi, 0, 15.0 / 180.0 * np.pi, 0, -25.0 / 180.0 * np.pi, 0]),
joint_limits=np.array(
[
- [-2 * np.pi, -2.094395, -2 * np.pi, -3.92699, -2 * np.pi, -np.pi, -2 * np.pi],
- [2 * np.pi, 2.059488, 2 * np.pi, 0.191986, 2 * np.pi, 1.692969, 2 * np.pi],
+ [-2 * np.pi, -2.059488, -2 * np.pi, -0.191986, -2 * np.pi, -1.692969, -2 * np.pi],
+ [2 * np.pi, 2.094395, 2 * np.pi, 3.92699, 2 * np.pi, np.pi, 2 * np.pi],
]
),
),
diff --git a/python/rcs/_core/__init__.pyi b/python/rcs/_core/__init__.pyi
index 5a27ade9..bc3a20fd 100644
--- a/python/rcs/_core/__init__.pyi
+++ b/python/rcs/_core/__init__.pyi
@@ -16,4 +16,4 @@ from __future__ import annotations
from . import common, sim
__all__: list[str] = ["common", "sim"]
-__version__: str = "0.7.2"
+__version__: str = "0.7.3"
diff --git a/python/rcs/envs/base.py b/python/rcs/envs/base.py
index 20b9ebcd..0d1b6261 100644
--- a/python/rcs/envs/base.py
+++ b/python/rcs/envs/base.py
@@ -219,7 +219,11 @@ def __init__(self, frequency: float | None = None) -> None:
None disables rate limiting.
"""
super().__init__()
- assert frequency is not None and frequency > 0, "frequency must be set to a positive value"
+ if frequency is None:
+ _logger.warning(
+ "No control frequency set: steps are not rate limited and may command the robot "
+ "faster than it can handle, which can damage the hardware."
+ )
self.frame_rate = SimpleFrameRate(frequency, "Hardware Loop")
def step(self, action: dict[str, Any]) -> tuple[dict[str, Any], float, bool, bool, dict]:
@@ -350,7 +354,6 @@ def __init__(self, env, robot: common.Robot, control_mode: ControlMode, home_on_
self.joints_key = get_space_keys(JointsDictType)[0]
self.trpy_key = get_space_keys(TRPYDictType)[0]
self.tquat_key = get_space_keys(TQuatDictType)[0]
- self.prev_action: dict | None = None
def get_unwrapped_control_mode(self, idx: int) -> ControlMode:
"""Returns the unwrapped control mode at a certain index. 0 is the base control mode, -1 the last."""
@@ -395,29 +398,17 @@ def action(self, action: dict[str, Any]) -> dict[str, Any]:
):
msg = "Given type is not matching control mode!"
raise RuntimeError(msg)
- last_action = self.prev_action
- self.prev_action = copy.deepcopy(action)
-
# shallow copy
action = dict(action)
- if self.get_base_control_mode() == ControlMode.JOINTS and (
- last_action is None
- or not np.allclose(action[self.joints_key], last_action[self.joints_key], atol=1e-03, rtol=0)
- ):
+ if self.get_base_control_mode() == ControlMode.JOINTS:
self.robot.set_joint_position(action[self.joints_key])
action.pop(self.joints_key)
- elif self.get_base_control_mode() == ControlMode.CARTESIAN_TRPY and (
- last_action is None
- or not np.allclose(action[self.trpy_key], last_action[self.trpy_key], atol=1e-03, rtol=0)
- ):
+ elif self.get_base_control_mode() == ControlMode.CARTESIAN_TRPY:
self.robot.set_cartesian_position(
common.Pose(translation=action[self.trpy_key][:3], rpy_vector=action[self.trpy_key][3:])
)
action.pop(self.trpy_key)
- elif self.get_base_control_mode() == ControlMode.CARTESIAN_TQuat and (
- last_action is None
- or not np.allclose(action[self.tquat_key], last_action[self.tquat_key], atol=1e-03, rtol=0)
- ):
+ elif self.get_base_control_mode() == ControlMode.CARTESIAN_TQuat:
self.robot.set_cartesian_position(
common.Pose(translation=action[self.tquat_key][:3], quaternion=action[self.tquat_key][3:])
)
@@ -432,7 +423,6 @@ def observation(self, observation: dict, info: dict[str, Any]) -> tuple[dict[str
def reset(
self, *, seed: int | None = None, options: dict[str, Any] | None = None
) -> tuple[dict[str, Any], dict[str, Any]]:
- self.prev_action = None
self.robot.reset()
if self.home_on_reset:
exception = True
diff --git a/python/rcs/envs/scenes.py b/python/rcs/envs/scenes.py
index 6cedeae3..16ca88f9 100644
--- a/python/rcs/envs/scenes.py
+++ b/python/rcs/envs/scenes.py
@@ -354,7 +354,6 @@ def create_env_from_model(self, cfg: SimEnvCreatorConfig, mjmodel: MjModel) -> g
kinematic_model_path,
attachment_site,
)
- # ik = rcs_robotics_library._core.rl.RoboticsLibraryIK(cfg.robot_cfgs[lead_robot_name].kinematic_model_path)
env = self.add_robot_env(prefixed_cfg, robot_name, env, simulation, ik)
if prefixed_cfg.gripper_cfgs is not None:
diff --git a/python/rcs/utils.py b/python/rcs/utils.py
index 506ee18f..18b33edc 100644
--- a/python/rcs/utils.py
+++ b/python/rcs/utils.py
@@ -18,10 +18,13 @@ def __init__(self, frame_rate: float | None, loop_name: str = "SimpleFrameRate")
It allows you to call it in a loop, and it will sleep the necessary time to maintain the desired frame rate.
Args:
- frame_rate (float): The desired frame rate in frames per second.
+ frame_rate (float): The desired frame rate in frames per second (Hz).
"""
self.t: float | None = None
self._last_print: float | None = None
+ assert (
+ frame_rate is None or frame_rate > 0
+ ), "frame_rate must be set to a positive value representing frames per second (Hz)"
self.frame_rate = frame_rate
self.loop_name = loop_name