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
22 changes: 22 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,28 @@ jobs:
- name: Ensure all unittests(pytest) are passing
run: xvfb-run make pytest

pythonpackage-macos:
runs-on: macos-14
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: "pip"
- name: upgrade pip
run: pip install --upgrade pip
- name: Install building dependencies
run: python -m pip install --group build_deps
- name: Install wheel
run: python -m pip install wheel
- name: Build and install rcs-core
run: python -m pip install -ve . --no-build-isolation
- name: Import smoke test
run: python -c "import rcs; from rcs import _core; import rcs.sim.sim; print('rcs-core import OK on macOS')"

check-paths:
runs-on: ubuntu-latest
outputs:
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ if __name__ == "__main__":
> **Note:** This and other examples can be found in the [`examples/`]() folder.

## 🛠️ Installation
* *Platform support: The core package `rcs-core` (MuJoCo simulation + Python API) is supported on **Linux and macOS** (Apple Silicon / arm64). The hardware extensions are **Linux only**.*
* *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
Expand Down Expand Up @@ -170,6 +171,8 @@ export RCS_PREFIX=/path/to/rcs-assets

RCS supports various hardware extensions to seamlessly connect your policies to the real world (e.g., FR3, xArm7, YAM, RealSense). These are located in the `extensions` directory.

> **Note:** Hardware extensions are supported on **Linux only**. On macOS you can use the core `rcs-core` package for simulation, but the hardware extensions are not supported.

To install a specific robot extension (example for Franka FR3):

```shell
Expand Down
28 changes: 24 additions & 4 deletions cmake/FindMuJoCo.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,35 @@ if (NOT MuJoCo_FOUND)
return()
endif()

file(GLOB mujoco_library_path "${MUJOCO_PATH}/libmujoco.so.*")
if (NOT mujoco_library_path)
set(_mujoco_library_globs)
if (APPLE)
list(APPEND _mujoco_library_globs "${MUJOCO_PATH}/libmujoco.*.dylib")
elseif (WIN32)
list(APPEND _mujoco_library_globs "${MUJOCO_PATH}/mujoco.dll")
list(APPEND _mujoco_library_globs "${MUJOCO_PATH}/bin/mujoco.dll")
else()
list(APPEND _mujoco_library_globs "${MUJOCO_PATH}/libmujoco.so.*")
endif()

file(GLOB mujoco_library_paths LIST_DIRECTORIES FALSE ${_mujoco_library_globs})
list(LENGTH mujoco_library_paths _mujoco_library_count)
if (_mujoco_library_count EQUAL 0)
set(MuJoCo_FOUND FALSE)
if (MuJoCo_FIND_REQUIRED)
message(FATAL_ERROR "Could not find MuJoCo. Please install MuJoCo using pip 4.")
message(FATAL_ERROR "Could not find MuJoCo shared library. Searched: ${_mujoco_library_globs}")
endif()
return()
endif()
list(GET mujoco_library_paths 0 mujoco_library_path)

# Extract version from the library filename
cmake_path(GET mujoco_library_path FILENAME mujoco_library_filename)
string(REPLACE "libmujoco.so." "" MuJoCo_VERSION "${mujoco_library_filename}")
set(MuJoCo_VERSION "")
if (mujoco_library_filename MATCHES "^libmujoco\\.so\\.(.+)$")
set(MuJoCo_VERSION "${CMAKE_MATCH_1}")
elseif (mujoco_library_filename MATCHES "^libmujoco\\.(.+)\\.dylib$")
set(MuJoCo_VERSION "${CMAKE_MATCH_1}")
endif()

# Create the imported target
add_library(MuJoCo::MuJoCo SHARED IMPORTED)
Expand All @@ -59,6 +76,9 @@ if (NOT MuJoCo_FOUND)
PROPERTIES
IMPORTED_LOCATION "${mujoco_library_path}"
)
if (APPLE)
set_target_properties(MuJoCo::MuJoCo PROPERTIES IMPORTED_NO_SONAME TRUE)
endif()

set(MuJoCo_FOUND TRUE)
endif()
35 changes: 27 additions & 8 deletions cmake/Findpinocchio.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,44 @@ if (NOT pinocchio_FOUND)
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})
cmake_path(APPEND Python3_SITELIB cmeel.prefix lib OUTPUT_VARIABLE pinocchio_LIBRARY_DIR)

set(_pinocchio_default_globs)
set(_pinocchio_parsers_globs)
if (APPLE)
list(APPEND _pinocchio_default_globs "${pinocchio_LIBRARY_DIR}/libpinocchio_default*.dylib")
list(APPEND _pinocchio_parsers_globs "${pinocchio_LIBRARY_DIR}/libpinocchio_parsers*.dylib")
elseif (WIN32)
list(APPEND _pinocchio_default_globs "${pinocchio_LIBRARY_DIR}/pinocchio_default*.dll")
list(APPEND _pinocchio_default_globs "${pinocchio_LIBRARY_DIR}/libpinocchio_default*.dll")
list(APPEND _pinocchio_parsers_globs "${pinocchio_LIBRARY_DIR}/pinocchio_parsers*.dll")
list(APPEND _pinocchio_parsers_globs "${pinocchio_LIBRARY_DIR}/libpinocchio_parsers*.dll")
else()
list(APPEND _pinocchio_default_globs "${pinocchio_LIBRARY_DIR}/libpinocchio_default.so*")
list(APPEND _pinocchio_parsers_globs "${pinocchio_LIBRARY_DIR}/libpinocchio_parsers.so*")
endif()

file(GLOB pinocchio_library_paths LIST_DIRECTORIES FALSE ${_pinocchio_default_globs})
list(LENGTH pinocchio_library_paths _pinocchio_library_count)
if (_pinocchio_library_count EQUAL 0)
set(pinocchio_FOUND FALSE)
if (pinocchio_FIND_REQUIRED)
message(FATAL_ERROR "Could not find pinocchio. Please install pinocchio using pip.")
message(FATAL_ERROR "Could not find pinocchio library. Searched: ${_pinocchio_default_globs}")
endif()
return()
endif()
list(GET pinocchio_library_paths 0 pinocchio_library_path)

# 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})
file(GLOB pinocchio_parsers_paths LIST_DIRECTORIES FALSE ${_pinocchio_parsers_globs})
list(LENGTH pinocchio_parsers_paths _pinocchio_parsers_count)
if (_pinocchio_parsers_count EQUAL 0)
set(pinocchio_FOUND FALSE)
if (pinocchio_FIND_REQUIRED)
message(FATAL_ERROR "Could not find pinocchio parsers path. Please install pinocchio using pip.")
message(FATAL_ERROR "Could not find pinocchio parsers library. Searched: ${_pinocchio_parsers_globs}")
endif()
return()
endif()
list(GET pinocchio_parsers_paths 0 pinocchio_parsers_path)

# Extract version from the library filename
file(GLOB pinocchio_dist_info "${Python3_SITELIB}/pin-*.dist-info")
Expand Down
6 changes: 6 additions & 0 deletions docs/extensions/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

RCS is designed to be modular. Core functionality is kept minimal, while specific hardware support and additional features are provided through **extensions**.

```{note}
Extensions are supported on **Linux only**. The core `rcs-core` package (MuJoCo
simulation + Python API) also runs on macOS (Apple Silicon / arm64), but the
hardware extensions are not supported there.
```

## What is an Extension?

An extension is a separate Python package that integrates with RCS. Extensions can provide:
Expand Down
6 changes: 6 additions & 0 deletions docs/getting_started/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@

We build and test RCS on the latest Debian and on the latest Ubuntu LTS.

```{note}
**Platform support:** The core package `rcs-core` (MuJoCo simulation + Python API)
is supported on **Linux and macOS** (Apple Silicon / arm64). The hardware
extensions are **Linux only**.
```

### Prerequisites

1. Install the system dependencies:
Expand Down
5 changes: 3 additions & 2 deletions include/rcs/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ Eigen::Matrix<double, N, M, Eigen::ColMajor> array2eigen(
Eigen::Matrix<double, N, M, Eigen::ColMajor> matrix(array.data());
return matrix;
}
void bootstrap_egl(std::uintptr_t fn_addr, std::uintptr_t display,
std::uintptr_t context);
void bootstrap_egl_context(std::uintptr_t fn_addr, std::uintptr_t display,
std::uintptr_t context);
void bootstrap_gl_context();
void ensure_current();

/***
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ dependencies = [
"tilburg-hand",
"digit-interface",
"pyopengl>=3.1.9",
"ompl>=1.7.0",
"ompl>=1.7.0; sys_platform == 'linux'",
"rpyc~=6.0.2",
"pyarrow",
"simplejpeg",
Expand Down
3 changes: 2 additions & 1 deletion python/rcs/_core/common.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,8 @@ def FrankaHandTCPOffset() -> numpy.ndarray[tuple[typing.Literal[4], typing.Liter
def IdentityRotMatrix() -> numpy.ndarray[tuple[typing.Literal[3], typing.Literal[3]], numpy.dtype[numpy.float64]]: ...
def IdentityRotQuatVec() -> numpy.ndarray[tuple[typing.Literal[4]], numpy.dtype[numpy.float64]]: ...
def IdentityTranslation() -> numpy.ndarray[tuple[typing.Literal[3]], numpy.dtype[numpy.float64]]: ...
def _bootstrap_egl(fn_addr: int, display: int, context: int) -> None: ...
def _bootstrap_egl_context(fn_addr: int, display: int, context: int) -> None: ...
def _bootstrap_gl_context() -> None: ...

HARDWARE: RobotPlatform # value = <RobotPlatform.HARDWARE: 1>
LATERAL_GRASP: GraspType # value = <GraspType.LATERAL_GRASP: 2>
Expand Down
4 changes: 2 additions & 2 deletions python/rcs/camera/sim.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from rcs._core.sim import SimCameraConfig
from rcs._core.sim import SimCameraSet as _SimCameraSet
from rcs.camera.interface import BaseCameraSet, CameraFrame, DataFrame, Frame, FrameSet
from rcs.sim import egl_bootstrap
from rcs.sim import render_context_bootstrap

from rcs import sim

Expand All @@ -32,7 +32,7 @@ def __init__(
self.cameras = cameras
self.physical_units = physical_units

egl_bootstrap.require("simulation camera rendering")
render_context_bootstrap.require("simulation camera rendering")
super().__init__(simulation, cameras, render_on_demand=render_on_demand)
self._sim: sim.Sim

Expand Down
64 changes: 0 additions & 64 deletions python/rcs/sim/egl_bootstrap.py

This file was deleted.

Loading
Loading