Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions .github/workflows/build_wheels.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
name: Build and Publish Wheels

on:
workflow_dispatch:
release:
types: [published]

jobs:
build_core_wheels:
name: Build core wheels
runs-on: ubuntu-latest
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
path: ./wheelhouse/*.whl

build_cpp_extension_wheels:
name: Build C++ extension wheels for ${{ matrix.extension }}
needs: [build_core_wheels]
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
extension:
- rcs_fr3
- rcs_panda
- rcs_robotics_library
- rcs_so101

steps:
- uses: actions/checkout@v4

- uses: actions/download-artifact@v4
with:
name: core-wheels
path: dist/core

- name: Install root Debian dependencies
run: |
sudo apt-get update
sudo xargs -a debian_deps.txt apt-get install -y

- name: Install extension Debian dependencies
run: |
deps_file="extensions/${{ matrix.extension }}/debian_deps.txt"
if [ -f "${deps_file}" ]; then
sudo xargs -a "${deps_file}" apt-get install -y
fi

- name: Build C++ extension wheels
uses: pypa/cibuildwheel@v2.22.0
env:
CIBW_ARCHS_LINUX: x86_64
CIBW_BUILD: cp311-* cp312-* cp313-*
PIP_FIND_LINKS: /project/dist/core
with:
package-dir: extensions/${{ matrix.extension }}
output-dir: extensions/${{ matrix.extension }}/wheelhouse

- uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.extension }}
path: extensions/${{ matrix.extension }}/wheelhouse/*.whl

build_python_extension_wheels:
name: Build pure Python wheel for ${{ matrix.extension }}
needs: [build_core_wheels]
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
extension:
- rcs_realsense
- rcs_robotiq2f85
- rcs_tacto
- rcs_ur5e
- rcs_usb_cam
- rcs_xarm7
- rcs_zed

steps:
- uses: actions/checkout@v4

- uses: actions/download-artifact@v4
with:
name: core-wheels
path: dist/core

- name: Install root Debian dependencies
run: |
sudo apt-get update
sudo xargs -a debian_deps.txt apt-get install -y

- name: Install extension Debian dependencies
run: |
deps_file="extensions/${{ matrix.extension }}/debian_deps.txt"
if [ -f "${deps_file}" ]; then
sudo xargs -a "${deps_file}" apt-get install -y
fi

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: pip

- name: Build pure Python wheel
env:
PIP_FIND_LINKS: ${{ github.workspace }}/dist/core
run: |
python -m pip install --upgrade pip
python -m pip install build
python -m build --wheel "extensions/${{ matrix.extension }}"

- uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.extension }}
path: extensions/${{ matrix.extension }}/dist/*.whl

upload_pypi:
needs: [build_core_wheels, build_cpp_extension_wheels, build_python_extension_wheels]
runs-on: ubuntu-latest
if: github.event_name == 'release' && github.event.action == 'published'
environment: pypi
permissions:
id-token: write
steps:
- uses: actions/download-artifact@v4
with:
pattern: "*wheels*"
merge-multiple: true
path: dist

- uses: pypa/gh-action-pypi-publish@release/v1
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ jobs:
- name: Install RCS
run: pip install -ve . --group dev
- name: Install extension
run: pip install -ve extensions/${{ matrix.extension }}
run: pip install -ve extensions/${{ matrix.extension }} --no-build-isolation
- name: Check that stub files are up-to-date
run: make -C extensions/${{ matrix.extension }} stubgen && git diff --exit-code
- name: Check clang format
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## v0.7.2 (2026-06-24)

### Fix

- **egl**: fail fast when rendering is requested without egl
- **pypi**: pin compatible pinocchio runtime deps
- sim reset (#314)

## v0.7.1 (2026-06-02)

### Feat
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.5)
project(
rcs
LANGUAGES C CXX
VERSION 0.7.1
VERSION 0.7.2
DESCRIPTION "Robot Control Stack Library"
)

Expand Down
30 changes: 22 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,18 +122,21 @@ if __name__ == "__main__":
> **Note:** This and other examples can be found in the [`examples/`]() folder.

## 🛠️ Installation
* *For Python >3.11: The `rcs_realsense` extension won't work due to the `pyrealsense2` version RCS utilizes.*
* *For Python >3.12: The `ompl` python module is currently not available on PyPI. If OMPL is not used, it is safe to remove this dependency in `pyproject.toml`.*
### Via PyPI/pip

```shell
pip install rcs-core
```

### From Source

Make sure that common build tools (i.e., `build-essential`) and a C++ compiler like `gcc` or `clang` are installed on your system/conda/docker.

*RCS works best in Python 3.11, and all extensions have been tested to work in 3.11.*

* *For Python >3.11: The `rcs_realsense` extension won't work due to the `pyrealsense2` version RCS utilizes.*
* *For Python >3.12: The `ompl` python module is currently not available on PyPI. If OMPL is not used, it is safe to remove this dependency in `pyproject.toml`.*

```shell

# clone repository
git clone https://github.com/RobotControlStack/robot-control-stack.git
cd robot-control-stack
Expand All @@ -148,13 +151,20 @@ pip install 'pip>=25.1'
pip install --group build_deps

# install rcs
pip install -ve .

pip install -ve . --no-build-isolation
```

### Via PyPI/pip

*Coming soon...*
### RCS Asset Cache

RCS resolves its asset directory from the `RCS_PREFIX` environment variable. When it is unset, RCS defaults to `~/.rcs`.

On import, RCS checks whether that path exists. If it does not, it downloads the matching asset archive from GitHub into that location automatically.

```shell
export RCS_PREFIX=/path/to/rcs-assets
```


## 🦾 Hardware Extensions

Expand All @@ -164,6 +174,9 @@ To install a specific robot extension (example for Franka FR3):

```shell
sudo apt install $(cat extensions/rcs_fr3/debian_deps.txt)
pip install rcs-fr3

# or install it locally
pip install -ve extensions/rcs_fr3
```

Expand All @@ -183,6 +196,7 @@ For full documentation, including advanced installation, modular usage, and API
Useful quick-reference pages:
- **[RCS Conventions](https://robotcontrolstack.org/user_guide/conventions)** for quaternion order, frames, Euler angles, and gripper semantics
- **[Sim Scene Configuration](https://robotcontrolstack.org/user_guide/scene_configuration)** for `SimEnvCreatorConfig`, scene frames, and example setup patterns
- **[libfranka Version Info](https://robotcontrolstack.org/extensions/libfranka_versions)** for the currently pinned `rcs_fr3` and `rcs_panda` `libfranka` versions and local-install guidance

## 🤝 Contribution

Expand Down
3 changes: 3 additions & 0 deletions docs/extensions/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
:maxdepth: 2

overview
libfranka_versions
rcs_fr3
rcs_panda
rcs_xarm7
rcs_ur5e
rcs_so101
rcs_realsense
rcs_usb_cam
rcs_tacto
rcs_robotics_library
rcs_robotiq2f85
rcs_zed
```
18 changes: 18 additions & 0 deletions docs/extensions/libfranka_versions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# libfranka Versions

This page documents the `libfranka` version currently pinned by the RCS Franka extensions in their CMake configuration.

## `rcs_fr3`

- Current `libfranka` version: `0.20.3`
- CMake source: [extensions/rcs_fr3/CMakeLists.txt](https://github.com/RobotControlStack/robot-control-stack/blob/main/extensions/rcs_fr3/CMakeLists.txt)
- Note: this information reflects the current CMake pin and may become outdated if the version is bumped in a future change.

When installing `rcs-fr3` from PyPI, this `libfranka` version is fixed by the published package. If you need to change the `libfranka` version, use a local source install and update the CMake configuration there.

## `rcs_panda`

- Current `libfranka` version: `0.9.2`
- CMake source: [extensions/rcs_panda/CMakeLists.txt](https://github.com/RobotControlStack/robot-control-stack/blob/main/extensions/rcs_panda/CMakeLists.txt)

When installing `rcs-panda` from PyPI, this `libfranka` version is fixed by the published package. If you need to change the `libfranka` version, use a local source install and update the CMake configuration there.
11 changes: 9 additions & 2 deletions docs/extensions/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,17 @@ An extension is a separate Python package that integrates with RCS. Extensions c

## Installing Extensions

Extensions are typically installed via `pip`.
Extensions are typically installed from PyPI.

```shell
pip install -ve extensions/rcs_fr3
pip install rcs-fr3
```

For local development from a checkout of this repository, first install RCS itself from the repository root and then install the extension via its path:

```shell
pip install -ve . --no-build-isolation
pip install -ve extensions/rcs_fr3 --no-build-isolation
```

## Available Extensions
Expand Down
60 changes: 25 additions & 35 deletions docs/extensions/rcs_fr3.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@ This extension provides support for the Franka Research 3 (FR3) robot in RCS.
## Installation

```shell
# from root directory
sudo apt install $(cat extensions/rcs_fr3/debian_deps.txt)
pip install -ve extensions/rcs_fr3
pip install rcs-fr3
```

For local development from this repository:

```shell
pip install -ve . --no-build-isolation
pip install -ve extensions/rcs_fr3 --no-build-isolation
```

### Configuration
Expand All @@ -22,41 +28,25 @@ DESK_PASSWORD=...
## Usage

```python
import rcs_fr3
from rcs_fr3._core import hw
from rcs_fr3.desk import FCI, ContextManager, Desk, load_creds_franka_desk
import rcs
import numpy as np

ROBOT_IP = "172.16.0.2" # Replace with your robot IP

user, pw = load_creds_franka_desk()
with FCI(Desk(ROBOT_IP, user, pw), unlock=False, lock_when_done=False):
robot_meta = rcs.ROBOTS[rcs.common.RobotType.FR3]
ik = rcs.common.Pin(robot_meta.mjcf_model_path, robot_meta.attachment_site)

# Configure Robot
robot = hw.Franka(ROBOT_IP, ik)
robot_cfg = hw.FR3Config()
robot_cfg.tcp_offset = rcs.common.Pose(rcs.common.FrankaHandTCPOffset())
robot.set_config(robot_cfg)

# Configure Gripper
gripper_cfg_hw = hw.FHConfig()
gripper_cfg_hw.epsilon_inner = gripper_cfg_hw.epsilon_outer = 0.1
gripper_cfg_hw.speed = 0.1
gripper_cfg_hw.force = 30
gripper = hw.FrankaHand(ROBOT_IP, gripper_cfg_hw)

# Move Robot
robot.set_cartesian_position(
robot.get_cartesian_position() * rcs.common.Pose(translation=np.array([0.05, 0, 0]))
)

# Grasp
gripper.grasp()
from rcs.envs.base import ControlMode, RelativeTo
from rcs_fr3.configs import DefaultFR3HardwareEnv

env_creator = DefaultFR3HardwareEnv()
env_creator.ip = "192.168.101.1"

cfg = env_creator.config()
cfg.control_mode = ControlMode.CARTESIAN_TQuat
cfg.camera_cfgs = None
cfg.max_relative_movement = 0.5
cfg.relative_to = RelativeTo.LAST_STEP

env = env_creator.create_env(cfg)
obs, info = env.reset()
print(env.get_wrapper_attr("robot").get_cartesian_position())
```

For a maintained example, see `examples/fr3/fr3_env_cartesian_control.py`.

## CLI

The extension defines useful commands to handle the FR3 robot without the need to use the Desk Website.
Expand Down
Loading
Loading