Skip to main content
rcs logo

A lean, ROS-free Sim-to-Real framework for training and deploying Vision-Language-Action (VLA) models and Reinforcement Learning (RL) agents.

Documentation Paper Release License CI Status


Robot Control Stack (RCS) is a flexible, native Gymnasium wrapper-based robot control interface designed specifically for modern robot learning and Vision-Language-Action (VLA) models.

It completely unifies MuJoCo simulation and real-world physical robot control into a single, seamless API. Currently, RCS natively supports five robots out-of-the-box: Franka FR3/Panda, xArm7, UR5e, SO101, and I2RT YAM.

RCS Demo

🚀 Why use Robot Control Stack?

Traditional robotics middleware (like ROS/ROS2) and complex motion planning pipelines (like MoveIt or standard ros2_control) are built for asynchronous, distributed systems. This often becomes a massive bottleneck when attempting to train modern, synchronous machine learning models.

RCS is built differently:

  • Zero ROS Overhead: No complex message-passing, middleware, or network configuration required. Run natively in Python with a lightweight C++ backend.
  • Frictionless Sim-to-Real: Train your Reinforcement Learning or VLA policies in our MuJoCo Gymnasium wrapper, and deploy the exact same code directly to physical hardware.
  • Synchronous Execution: Optimized specifically for the highly parallelized, synchronous data collection required by modern ML workflows.
  • Ready-to-Use Apps: Ships with pre-built applications for data collection via teleoperation and remote model inference via vlagents. See the teleoperation guide, and inference guide.

🧩 Wrapper-Based Architecture

RCS utilizes a highly modular, wrapper-based architecture, allowing you to easily stack capabilities (cameras, grippers, action spaces) as needed.

rcs architecture diagram

💻 Example: Composing your Environment

Flexibly compose your Gymnasium environment to fit your exact training needs. For common environment compositions, factory functions such as rcs.envs.creators.SimEnvCreator are provided.

from time import sleep

import gymnasium as gym
import numpy as np
from rcs._core.sim import SimConfig
from rcs.camera.sim import SimCameraSet
from rcs.envs.base import (
    CameraSetWrapper,
    ControlMode,
    CoverWrapper,
    GripperWrapper,
    RelativeActionSpace,
    RelativeTo,
    RobotWrapper,
    SimEnv,
)
from rcs.envs.configs import EmptyWorldFR3
from rcs.envs.sim import GripperWrapperSim, RobotSimWrapper

import rcs
from rcs import sim

if __name__ == "__main__":
    # default configs
    scene = EmptyWorldFR3()
    cfg = scene.prefixed_cfg(scene.config())
    fr3 = scene.lead_robot_name(cfg)

    robot_cfg = cfg.robot_cfgs[fr3]
    gripper_cfg = cfg.gripper_cfgs[fr3]  # type: ignore
    camera_cfgs = cfg.camera_cfgs
    sim_cfg = SimConfig(
        realtime=True,
        async_control=True,
        frequency=1,  # in Hz (1 sec delay)
    )
    mjmodel = scene.create_model(cfg)
    kinematic_model_path, attachment_site = scene.kinematics_cfg(cfg)[fr3]

    simulation = sim.Sim(mjmodel, sim_cfg)
    ik = rcs.common.Pin(
        kinematic_model_path,
        attachment_site,
    )

    # base env
    robot = rcs.sim.SimRobot(simulation, ik, robot_cfg)
    env: gym.Env = SimEnv(simulation)
    env = RobotWrapper(env, robot, ControlMode.CARTESIAN_TQuat)

    # gripper
    gripper = sim.SimGripper(simulation, gripper_cfg)
    env = GripperWrapper(env, gripper)

    env = RobotSimWrapper(env)
    env = GripperWrapperSim(env)

    # camera
    camera_set = SimCameraSet(simulation, camera_cfgs, physical_units=True, render_on_demand=True)  # type: ignore
    env = CameraSetWrapper(env, camera_set, include_depth=True)  # type: ignore

    # relative actions bounded by 10cm translation and 10 degree rotation
    env = RelativeActionSpace(env, max_mov=(0.1, np.deg2rad(10)), relative_to=RelativeTo.LAST_STEP)
    env = CoverWrapper(env)

    env.get_wrapper_attr("sim").open_gui()
    # wait for gui to open
    sleep(1)
    env.reset()

    # access low level robot api to get current cartesian position
    print(env.get_wrapper_attr("robot").get_cartesian_position())

    for _ in range(10):
        # move 1cm in x direction (forward) and close gripper
        act = {"tquat": [0.01, 0, 0, 0, 0, 0, 1], "gripper": [0]}
        obs, reward, terminated, truncated, info = env.step(act)
        print(obs)

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

pip install rcs-core

From Source

Make sure that common build tools (i.e., build-essential), python headers 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.

# clone repository
git clone https://github.com/RobotControlStack/robot-control-stack.git
cd robot-control-stack

# setup environment
conda create -n rcs python=3.11
conda activate rcs
conda install -c conda-forge urdfdom urdfdom_headers glfw

# or sudo apt install $(cat debian_deps.txt)
pip install 'pip>=25.1'
pip install --group build_deps

# install rcs
pip install -ve . --no-build-isolation

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.

export RCS_PREFIX=/path/to/rcs-assets

🦾 Hardware Extensions

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):

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

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

For a full list of extensions and detailed documentation, visit robotcontrolstack.org/extensions.

⚠️ Troubleshooting & FAQ

  • License error or group argument not found during installation? Make sure you are using a pip version >=25.1 and setuptools version >=45.
  • Dependency error during installation? Make sure you are using Python 3.11. RCS extensions currently do not support 3.12+ due to OMPL and RealSense dependencies.
  • Simulation is running too slow? Check that you have enable on-demand rendering: SimCameraSet(..., render_on_demand=True) to render camera frames only once per step. Resolution and number of cameras in the scene has a large impact on simulation speed. Make sure to use a decent GPU when rendering is enabled.

📚 Documentation

For full documentation, including advanced installation, modular usage, and API references, please visit: 👉 robotcontrolstack.org

Useful quick-reference pages:

  • RCS Conventions for quaternion order, frames, Euler angles, and gripper semantics
  • Sim Scene Configuration for SimEnvCreatorConfig, scene frames, and example setup patterns
  • Apps for the teleoperation and inference example entry points
  • libfranka Version Info for the currently pinned rcs_fr3 and rcs_panda libfranka versions and local-install guidance

🤝 Contribution

We welcome contributions from the robotics and ML community! For contribution guidelines, please check out robotcontrolstack.org/contributing.

📝 Citation

If you find RCS useful for your academic work please consider citing it:

@inproceedings{juelg2026robotcontrolstack,
  title={{Robot Control Stack}: {A} Lean Ecosystem for Robot Learning at Scale}, 
  author={Tobias J{\"u}lg and Pierre Krack and Seongjin Bien and Yannik Blei and Khaled Gamal and Ken Nakahara and Johannes Hechtl and Roberto Calandra and Wolfram Burgard and Florian Walter},
  year={2026},
  booktitle={Proc.~of the IEEE Int.~Conf.~on Robotics \& Automation (ICRA)},
  note={Accepted for publication.}
}

For more scientific information and supplementary videos, visit the paper website.

License

The RCS source code is licensed under AGPL-3.0. A small subset of redistributed third-party robot and sensor assets under assets/ keeps its original upstream license; the applicable notices are collected in THIRD_PARTY_ASSET_LICENSES.md.

Metadata

Release files for rcs-core 0.7.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for rcs-core 0.7.3
File
rcs_core-0.7.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details
rcs_core-0.7.3-cp313-cp313-macosx_11_0_arm64.whl CPython 3.13 CPython 3.13 macOS 11.0+ ARM64 Details
rcs_core-0.7.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details
rcs_core-0.7.3-cp312-cp312-macosx_11_0_arm64.whl CPython 3.12 CPython 3.12 macOS 11.0+ ARM64 Details
rcs_core-0.7.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details
rcs_core-0.7.3-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details

Total release size: 3.9 MB

Release files / rcs_core-0.7.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL rcs_core-0.7.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 715.2 kB
Tags CPython 3.13 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
067209ababf1f723deb70fc8e30d5f8841b4d013f5de711102ab79012a637758
BLAKE2b-256 checksum
How to use checksums
e220080fe22f04f15fb37d279f43d90d93fead1bf7e3d3dddcf34d961864d65b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.15

Release files / rcs_core-0.7.3-cp313-cp313-macosx_11_0_arm64.whl

Download URL rcs_core-0.7.3-cp313-cp313-macosx_11_0_arm64.whl
Size 575.7 kB
Tags CPython 3.13 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
a71b9afab900cbbdba54f6f364a7ecb01d2e55f85718f1bc6672d82b994a593e
BLAKE2b-256 checksum
How to use checksums
bfb9852540fb4f5627d84fea970e10f42aed0b9d4b3ce2ca60a2bc128238a0da
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.15

Release files / rcs_core-0.7.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL rcs_core-0.7.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 714.6 kB
Tags CPython 3.12 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
a19a650651263448afa47f2dd4053f89918cef22303bf36e34e8d6373c7e5433
BLAKE2b-256 checksum
How to use checksums
fd88a485f8a7f5479329535e2c38debb164440cf72e23908dc7e9cf8cd0ca8a0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.15

Release files / rcs_core-0.7.3-cp312-cp312-macosx_11_0_arm64.whl

Download URL rcs_core-0.7.3-cp312-cp312-macosx_11_0_arm64.whl
Size 575.6 kB
Tags CPython 3.12 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
a9ab108f3f2e086237a5c46f53270168c12eb80d67ee5c0d719b95a9fbf784b6
BLAKE2b-256 checksum
How to use checksums
bd9d7a8c9a6e6114162c46219300d16fbb7b25ea11c31505f8f67461f22ddadf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.15

Release files / rcs_core-0.7.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL rcs_core-0.7.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 717.0 kB
Tags CPython 3.11 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
00e71c7357ed1ce35945773694fa79481b6449fb7993490b916e4093bdfcfa79
BLAKE2b-256 checksum
How to use checksums
1e0ad607afd976829d9292d96c34b3ba2a389957239ea082e34f2efbeae01e40
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.15

Release files / rcs_core-0.7.3-cp311-cp311-macosx_11_0_arm64.whl

Download URL rcs_core-0.7.3-cp311-cp311-macosx_11_0_arm64.whl
Size 573.7 kB
Tags CPython 3.11 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
d36e0614fbd1be7ae7d7ed0ec62202d00ffbcc350f2e9a5bf348ab7e777e120b
BLAKE2b-256 checksum
How to use checksums
cbec3eb0595b70b8c1c1a8944161ca7c12f5b4349e16f654f07110c2ac97c1e4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.15

Release history Release notifications | RSS feed

This release

0.7.3 This release

6 release files

0.7.2

3 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page