Skip to content
Closed
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
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,11 @@ If the python bindings in the C++ code have changed you might need to regenerate
```shell
make stubgen
```

### To build the documentation locally
```
cd docs
sphinx-build -M html ./source/ ./build
```

docs/build/html/index.html will the final document
3 changes: 3 additions & 0 deletions docs/doc_requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pydata-sphinx-theme==0.16.1
myst-parser==4.0.1
sphinx-autodoc-typehints
132 changes: 132 additions & 0 deletions docs/docs_action_observation_flow/action_obersvation_flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Action-Observation Flow

## wrapper Hierarchy


Vertical Order:

- Top: Highest-level wrapper (first applied)

- Bottom: Base environment

Inheritance Notation:

- Use (ParentClass) next to wrapper names

Wrapping Notation

- Show ← wraps arrows between layers
<p align="center">
<img src="images/class_hierarchy.png" width="150"/>
</p>

## Flow
1. **`RelativeActionSpace(ActionWrapper).step(act)`**

- 2- Calls step function of ActionWrapper (→2)

2. **`ActionWrapper.step(act)`**
- 3. Calls `RelativeActionSpace.action(act)`
- 4. Calls `GripperWrapper.step(act)`

3. **`RelativeActionSpace.action(act)`**
- Processes action: `{"tquart": [0.01, 0, 0, 0, 0, 0, 1], "gripper": 0}`
- Operations:
- Clips action within min/max limits
- Makes action relative (current_pose + action)
- Updates `action["tquart"]`

4. **`GripperWrapper(ActObsInfoWrapper).step(act)`**
- →5. Calls `GripperWrapper.action(act)`
- →6. Calls `CameraSetWrapper.step(act)`
- →15. Calls `GripperWrapper.observation(obs)`

5. **`GripperWrapper.action(act)`**
- Uses `act["gripper"]` to open/close gripper
- Only executes if state change needed
- Deletes `"gripper"` key from action dict

6. **`CameraSetWrapper(ActObsInfoWrapper).step(act)`**
- →7. Calls `CameraSetWrapper.action(act)`
- →8. Calls `CameraSetWrapper(ActObsInfoWrapper).step(act)`
- →14. Calls `CameraSetWrapper.observation(obs)`

7. **`CameraSetWrapper.action(act)`**
- (Pass-through) Returns original action

8. **`CameraSetWrapper(ActObsInfoWrapper).step(act)`**
- →9. Calls `CameraSetWrapper.action(act)`
- →10. Calls `FR3Sim.step(act)`

9. **`CameraSetWrapper.action(act)`**
- (Pass-through) Returns original action

10. **`FR3Sim.step(act)`**
- →11. Calls `FR3Env.step(act)`
- 13. Executes:
```python
self.sim.step_until_convergence()
state = self.sim_robot.get_state()
```
- Returns observation

11. **`FR3Env.step(act)`**
- Sets new pose:
```python
self.robot.set_cartesian_position(
common.Pose(
translation=action_dict[self.tquart_key][:3],
quaternion=action_dict[self.tquart_key][3:]
)
)
```
- →12. Calls `FR3Env.get_obs()`

12. **`FR3Env.get_obs()`**
- Returns:
```python
(
tquart=np.concatenate([
self.robot.get_cartesian_position().translation(),
self.robot.get_cartesian_position().rotation_q()
]),
joints=self.robot.get_joint_position(),
xyzrpy=self.robot.get_cartesian_position().xyzrpy()
)
```
- Shapes:
- `joints`: (7,)
- `tquart`: (7,) [x,y,z, qx,qy,qz,qw]
- `xyzrpy`: (6,) [x,y,z, roll,pitch,yaw]

14. **`CameraSetWrapper.observation(obs)`**
- Adds camera data:
```python
{
...original_obs...,
"frames": {
"wrist": {
"rgb": (256,256,3),
"depth": (256,256,3)
},
"default_free": {
"wrist": {
"rgb": (256,256,3),
"depth": (256,256,3)
}
}
}
}
```

15. **`GripperWrapper.observation(obs)`**
- Adds gripper state:
```python
{
...previous_data...,
"gripper": float
}
```
# Sequence Diagram
![image](images/sequence_diagram.png)

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file added docs/source/_templates/.gitkeep
Empty file.
37 changes: 37 additions & 0 deletions docs/source/architecture/rcs_architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Robot Control Stack architecture
<p align="center">
<img src="../_static/images/rcs_overview_of_layered_architecture.png" />
</p>

A core contribution of RCS is a simple yet versatile
architecture that allows for easy extension and customization.
The architecture is organized in multiple layers that represent
increasing levels of abstraction from platform-specific implementation details.
While lower layers are implemented in
C++, higher layers are implemented in Python or provide
bindings for Python. Rapid prototyping and performance-
critical code are therefore supported equally well.
RCS uses [MuJoCo](https://ieeexplore.ieee.org/document/6386109) as its simulator and the [Robotics
Library](https://ieeexplore.ieee.org/document/8202232) for inverse kinematics. There is support for
Franka robots through the native library provided by the
manufacturer. New robot types can be added by implementing a small set of API functions.
Both the simulation and the actual hardware share a unified interface for a
seamless transition between the two. Adding sensors and
actuators to the simulation is managed through a frequency-
based callback mechanism that interfaces with the global
simulation loop.

At the most abstract level, RCS implements an easy-to-use
[Gymnasium-style API](https://arxiv.org/abs/2407.17032). This interface is not only widely
used in reinforcement learning but also enables the flexible
composition of environment wrappers for adding features.

For example, the collision checker depicted in the above figure is
implemented as a wrapper that checks motion commands
in simulation and filters them to prevent collisions.

```{toctree}
:maxdepth: 1

wrappers.md
```
33 changes: 33 additions & 0 deletions docs/source/architecture/wrappers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Wrappers

```
Note:
This content has not yet been proof read!
```

[Wrappers](https://www.gymlibrary.dev/api/wrappers/) are a convenient way to modify an existing environment without having to alter the underlying code directly.
RCS offers the following wrappers that add functionality in a layered manner.

1. FR3Env

This is the basic Joint Gym Environment for Franka Research 3.

2. FR3Sim

This wraps the basic FR3Env with the MuJoCo simulation.

3. CameraSetWrapper

This is an observation wrapper, that takes the observation from its parent environment and add rgbd information.

4. GripperWrapper

This is an observation wrapper, that takes the observation from its parent environment and add gripper_state(whether open or close) information.

5. CollisionGuard

This wrapper is used for safety from collisions. Before executing the action, this collision guard executes the action in simulation in a sub-collision environment to ensure there is no collision, after that the action will be executed on the parent environment. In case of collision, the user can decide whether to truncate the episode.

6. RelativeActionSpace

This wrapper clips the actions based on pre-defined maximum limits and steps the clipped actions on the parent environment.
28 changes: 28 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information

project = 'RCS'
copyright = '2025, UTN'
author = 'UTN'
release = 'v0.3.1'

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

extensions = ["myst_parser", 'sphinx.ext.napoleon', "sphinx_autodoc_typehints"]

templates_path = ['_templates']
exclude_patterns = []



# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output

html_theme = 'pydata_sphinx_theme'
html_static_path = ['_static']
32 changes: 32 additions & 0 deletions docs/source/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<!-- RCS documentation master file, created by
sphinx-quickstart on Mon Mar 3 14:47:32 2025.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
-->

# RCS documentation

<p align="center">
<img src="./_static/images/rcs.png" />
</p>


No matter whether it is in simulation or in the
lab – setting up robotics experiments is challenging, especially
if they target both types of deployments. While a plethora of
different robotics software frameworks exist, they usually make
a trade-off between complexity and versatility. Drawing from
this rich ecosystem, Robot Control Stack (RCS) is a
robotics software stack that is designed to resolve this conflict by
combining established robotics tools and frameworks through
a lightweight multi-layered API that unifies simulation and
real-world robot control.


```{toctree}
:maxdepth: 1

user_guide/user_guide.md
```


55 changes: 55 additions & 0 deletions docs/source/models/custom_grippers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Custom Grippers

Custom grippers can be used with RCS by following the instructions below.
## How to add a custom gripper
An example custom gripper is available for reference [here](https://gitos.rrze.fau.de/utn-machine-intelligence/lab/models/-/tree/main/grippers/digit_hand/obj?ref_type=heads) **(only if you have access to the RCS models repo)**

The adjustment to fr3_0.xml and fr3_common.xml can be found [here](https://gitos.rrze.fau.de/utn-machine-intelligence/lab/models/-/tree/main/scenes/fr3_simple_pick_up_digit_hand?ref_type=heads) **(only if you have access to the RCS models repo)**

### Step1: export obj files
If the gripper is downloaded from somewhere convert it to .obj file.
Make sure that the x, y, z axis of the default gripper and the custom gripper are the same. In case they are different, later the slide joint axis might have to be adjusted. This can be done by visualing the coordinate axis, by dragging the obj files in onshape.
### Step2: convert obj to mjcf
**Note:** First ensure that the file_names dont have space in their names

**e.g** rename <Digit Stub Full.mtl> to <Digit_Stub_Full.mtl> in three places(obj file, mtl file, mtl file reference inside the obj file)

A python package for converting obj files to mjcf files is available [here](https://pypi.org/project/obj2mjcf/0.0.3/).
After installing it, use the following command to do the required conversion.



```shell
obj2mjcf --obj-dir <obj_dir_name> --save-mjcf
```


### Step3: verify in mujoco viewer
With the above two steps, the conversion should be successful, you should be able to view the standalone grippers in mujco with the following commands

```shell
python -m mujoco.viewer
```


after opening the mujoco viewer you can drag the converted scene and visualise it.

### Step4: Adding the gripper to the lab or fr3_empty_world scenes
The following steps need to be followed:
1. in fr3_common, the mesh should be renamed to the new gripper
2. in fr3_0 and fr3_1 and all the robots, the fingers’ geom must be adjusted for material and if there are name changes
3. physics parameters should be adjusted empirically..
e.g. new collision meshes specific to the gripper added, friction parameters adjustment

## step5: update the tcp offset
add the correct tcp_offset value to the following to fr3_common.xml


```
<custom>
<numeric
name="tcp_offset"
data="0 0 0.0466"
/>
</custom>
```
7 changes: 7 additions & 0 deletions docs/source/source_code/fr3_sim.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# rcsss.envs.factories

```{eval-rst}
.. automodule:: rcsss.envs.factories
:members:
:show-inheritance:
```
12 changes: 12 additions & 0 deletions docs/source/source_code/rcs_api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# RCS API

We are still in the process of documenting all of the functions.

Subpackages:

```{toctree}
:titlesonly:
:maxdepth: 1

fr3_sim.md
```
2 changes: 1 addition & 1 deletion python/rcsss/envs/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ def fr3_sim_env(
relative_to (RelativeTo): Specifies whether the movement is relative to a configured origin or the last step.
urdf_path (str | PathLike | None): Path to the URDF file. If None, the URDF file is automatically deduced
which requires a UTN compatible lab scene to be present.
mjcf (str | PathLike): Path to the Mujoco scene XML file. Defaults to "fr3_empty_world".
mjcf (str | PathLike): Path to the MuJoCo scene XML file. Defaults to "fr3_empty_world".
sim_wrapper (Type[SimWrapper] | None): Wrapper to be applied before the simulation wrapper. This is useful
for reset management e.g. resetting objects in the scene with correct observations. Defaults to None.

Expand Down