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
Binary file added assets/robots/yam/assets/model2.stl
Binary file not shown.
Binary file added assets/robots/yam/assets/model2__10.stl
Binary file not shown.
Binary file added assets/robots/yam/assets/model2__11.stl
Binary file not shown.
Binary file added assets/robots/yam/assets/model2__12.stl
Binary file not shown.
Binary file added assets/robots/yam/assets/model2__13.stl
Binary file not shown.
Binary file added assets/robots/yam/assets/model2__14.stl
Binary file not shown.
Binary file added assets/robots/yam/assets/model2__15.stl
Binary file not shown.
Binary file added assets/robots/yam/assets/model2__16.stl
Binary file not shown.
Binary file added assets/robots/yam/assets/model2__17.stl
Binary file not shown.
Binary file added assets/robots/yam/assets/model2__2.stl
Binary file not shown.
Binary file added assets/robots/yam/assets/model2__3.stl
Binary file not shown.
Binary file added assets/robots/yam/assets/model2__4.stl
Binary file not shown.
Binary file added assets/robots/yam/assets/model2__5.stl
Binary file not shown.
Binary file added assets/robots/yam/assets/model2__6.stl
Binary file not shown.
Binary file added assets/robots/yam/assets/model2__7.stl
Binary file not shown.
Binary file added assets/robots/yam/assets/model2__8.stl
Binary file not shown.
Binary file added assets/robots/yam/assets/model2__9.stl
Binary file not shown.
202 changes: 202 additions & 0 deletions assets/robots/yam/yam.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
<!-- Kinematics, joint limits and gripper stroke match the i2rt yam v1 arm with the
linear_4310 gripper (i2rt/robot_models/arm/yam/v1 and gripper/linear_4310). -->
<mujoco model="yam">
<compiler angle="radian" meshdir="assets"/>

<option integrator="implicitfast"/>

<default>
<default class="yam">
<position inheritrange="1"/>
<joint frictionloss="0.1" axis="0 0 1"/>
<default class="dm4340">
<joint armature="0.032"/>
<position kp="40" kv="2.5" forcerange="-28 28"/>
</default>
<default class="dm4310">
<joint armature="0.0018"/>
<position kp="10" kv="1" forcerange="-10 10"/>
</default>
<default class="visual">
<geom type="mesh" contype="0" conaffinity="0" density="0" group="2" material="black"/>
</default>
<default class="collision">
<geom group="3" type="capsule"/>
<default class="sphere_collision">
<geom size="0.0006 0 0" type="sphere" rgba="1 0 0 1"/>
</default>
</default>
<default class="finger">
<joint type="slide" armature="0.1" frictionloss="0.1"/>
<position ctrlrange="0.0 0.0475" kp="100" kv="10" inheritrange="0"/>
</default>
</default>
</default>

<asset>
<material name="black" rgba="0.25 0.25 0.25 1"/>
<material name="white" rgba="0.9 0.9 0.9 1"/>

<mesh file="model2.stl"/>
<mesh file="model2__2.stl"/>
<mesh file="model2__3.stl"/>
<mesh file="model2__4.stl"/>
<mesh file="model2__5.stl"/>
<mesh file="model2__6.stl"/>
<mesh file="model2__7.stl"/>
<mesh file="model2__8.stl"/>
<mesh file="model2__9.stl"/>
<mesh file="model2__10.stl"/>
<mesh file="model2__11.stl"/>
<mesh file="model2__12.stl"/>
<mesh file="model2__13.stl"/>
<mesh file="model2__14.stl"/>
<mesh file="model2__15.stl"/>
<mesh file="model2__16.stl"/>
<mesh file="model2__17.stl"/>
</asset>

<worldbody>
<light name="spotlight" mode="targetbodycom" target="link_6" pos="0 0 1"/>
<body name="arm" childclass="yam">
<geom class="visual" pos="0 0 -0.0006" quat="1 0 0 1" mesh="model2"/>
<geom class="collision" size="0.033 0.01" pos="0.0 0.0 0.026" quat="1 0 0 0"/>
<body name="link_1" pos="0 0 0.068" quat="1 0 0 1">
<inertial pos="-0.00192861 -0.00795735 0.0208176" quat="0.297851 0.642634 0.360045 0.607185" mass="0.12415"
diaginertia="0.000180751 0.000145532 5.89179e-05"/>
<joint name="joint1" range="-2.61799 3.14159" class="dm4340"/>
<geom class="visual" pos="5.26159e-07 2.34355e-07 -0.0632" quat="1 0 0 0" mesh="model2__2"/>
<body name="link_2" pos="2.5e-05 -0.02 0.0455" quat="1 1 1 1" gravcomp="1">
<inertial pos="0.132008 2.10599e-06 0.000293073" quat="1 1 1 1" mass="1.24434"
diaginertia="0.0121902 0.0121318 0.000683304"/>
<joint name="joint2" range="0 3.66519" class="dm4340"/>
<geom class="visual" pos="0.0199992 -0.1041 -2.44738e-05" quat="1 -1 -1 -1" mesh="model2__3"/>
<geom class="visual" pos="0.0199992 -0.1041 -2.44738e-05" quat="1 -1 -1 -1" mesh="model2__4"/>
<geom class="visual" pos="0.0199992 -0.1041 -2.44738e-05" quat="1 -1 -1 -1" mesh="model2__5"
material="white"/>
<geom class="collision" size="0.032 0.11" pos="0.13 0 0" quat="1 0 1 0"/>
<geom class="collision" size="0.033 0.02" pos="0 0.0 0" quat="1 0 0 0"/>
<geom class="collision" size="0.033 0.025" pos="0.265 0 0" quat="1 0 0 0"/>
<body name="link_3" pos="0.264 0 0" quat="0 1 0 0" gravcomp="1">
<inertial pos="-0.121816 -0.054846 -0.000111108" quat="1 1 1 1" mass="0.853698"
diaginertia="0.00699732 0.00696112 0.000788244"/>
<joint name="joint3" range="0 3.14159" class="dm4340"/>
<geom class="visual" pos="-0.244001 0.104101 2.44738e-05" quat="1 1 1 -1" mesh="model2__6"/>
<geom class="visual" pos="-0.244001 0.104101 2.44738e-05" quat="1 1 1 -1" mesh="model2__7"/>
<geom class="visual" pos="-0.244001 0.104101 2.44738e-05" quat="1 1 1 -1" mesh="model2__8"
material="white"/>
<geom class="visual" pos="-0.244001 0.104101 2.44738e-05" quat="1 1 1 -1" mesh="model2__9"/>
<geom class="collision" size="0.034 0.12" pos="-0.14 -0.06 0.0" quat="1 0 1 0"/>
<geom class="collision" size="0.034 0.015" pos="-0.24 -0.06 0.0" quat="1 0 0 0"/>
<body name="link_4" pos="-0.245 -0.06 0" quat="1 0 0 0" gravcomp="1">
<inertial pos="-0.0769778 -0.0527104 0.000154878" quat="0.667 0.667 -0.236 -0.236" mass="0.463511"
diaginertia="0.000791532 0.000744733 0.000282116"/>
<joint name="joint4" range="-1.69297 1.5708" class="dm4310"/>
<geom class="visual" pos="0.00100023 0.164101 2.44738e-05" quat="1 1 1 -1" mesh="model2__10"/>
<geom class="collision" size="0.03 0.015" pos="-0.073 -0.06 0.0" quat="1 1 0 0"/>
<body name="link_5" pos="-0.074 -0.0395 2.5e-05" quat="1 -1 1 1" gravcomp="1">
<inertial pos="3.64861e-05 0.00025665 0.0353526" quat="1 0 0 0" mass="0.350962"
diaginertia="0.000197802 0.0001775 0.000147402"/>
<joint name="joint5" range="-1.5708 1.5708" class="dm4310"/>
<geom class="visual" pos="0 -0.0749971 0.203601" quat="1.32679e-06 1 0 0" mesh="model2__11"/>
<geom class="collision" size="0.030 0.015" pos="0 0.025 0.0395" quat="1 1 0 0"/>
<body name="link_6" pos="0 0.0353 0.0395" quat="1 -1 0 0" gravcomp="1">
<inertial pos="-0.000217767 7.37059e-05 0.0270545" quat="1 1 0 0" mass="0.367476"
diaginertia="0.000265958 0.000242686 0.000227409"/>
<joint name="joint6" range="-2.0944 2.0944" class="dm4310"/>
<geom class="visual" pos="0 -0.164101 -0.110597" quat="1 -1 0 0" mesh="model2__12"/>
<geom class="visual" pos="0 -0.164101 -0.110597" quat="1 -1 0 0" mesh="model2__13"/>
<geom class="collision" size="0.01 0.035" pos="0 0.039 0.052" quat="1 0 1 0"/>
<geom class="collision" size="0.030 0.005" pos="0 0.0 0.03" quat="1 0 0 1"/>
<geom class="collision" size="0.01 0.035" pos="0 -0.039 0.052" quat="1 0 1 0"/>
<site name="tcp_site" pos="0 0 0" quat="1 0 0 -1" size="0.005" rgba="1 0 0 1" group="4"/>
<site name="grasp_site" pos="0 0 0.1347" quat="1 0 0 -1" size="0.005" rgba="0 1 0 1" group="4"/>
<body name="link_left_finger" pos="-0.037 0.0392 0.0605" quat="1 0 1 0" gravcomp="1">
<inertial pos="-0.0192995 -0.0365902 0.039774" quat="0.757351 0.568898 -0.3199 0.0" mass="0.118"
diaginertia="0.000159084 0.000154909 4.63655e-05"/>
<joint class="finger" name="left_finger" range="0 0.0475"/>
<geom class="visual" pos="0.171097 -0.203301 0.037" quat="1 -1 -1 -1" mesh="model2__14"/>
<geom class="visual" pos="0.171097 -0.203301 0.037" quat="1 -1 -1 -1" mesh="model2__15"/>
<body name="lf_rot" quat="1 -1 -1 1" pos="0.0 -0.0392 0.037" gravcomp="1">
<geom class="collision" size="0.01 0.03" pos="0.0 -0.02 0.012" quat="1 0 1 0"
rgba="0.381493 0.492734 0.780446 1"/>
<geom class="collision" size="0.01 0.02" pos="-0.02 -0.01 0.032" quat="1 0 2.5 0"
rgba="0.381493 0.492734 0.780446 1"/>
<body name="lf_down" quat="1 0 0 0" pos="-0.044 0.0 0.0" gravcomp="1">
<geom class="collision" size="0.01 0.01" pos="0.0 -0.020 0.012" quat="1 -0.1 0 0"
rgba="0.381493 0.492734 0.780446 1"/>
<geom class="collision" size="0.003 0.022" pos="0.005 -0.014 0.04" quat="1 -0.2 0 0"
rgba="0.381493 0.492734 0.780446 1"/>
<geom class="collision" size="0.003 0.022" pos="-0.005 -0.014 0.04" quat="1 -0.2 0 0"
rgba="0.381493 0.492734 0.780446 1"/>
<geom class="collision" type="box" size="0.006 0.002 0.04" pos="0 -0.0024 0.046" quat="1 0 0 0"
rgba="0.381493 0.492734 0.780446 1"/>
<geom class="collision" type="box" size="0.006 0.002 0.039" pos="0.027 -0.0024 0.053"
quat="1 0 2.5 0" rgba="0.381493 0.492734 0.780446 1"/>
<geom class="sphere_collision" pos="0.003 -0.0004 0.078"/>
<geom class="sphere_collision" pos="-0.003 -0.0004 0.078"/>
<geom class="sphere_collision" pos="0.003 -0.0004 0.07"/>
<geom class="sphere_collision" pos="-0.003 -0.0004 0.07"/>
<geom class="sphere_collision" pos="0.003 -0.0004 0.06"/>
<geom class="sphere_collision" pos="-0.003 -0.0004 0.06"/>
</body>
</body>
</body>
<body name="link_right_finger" pos="0.037 -0.0392 0.0605" quat="1 0 1 0" gravcomp="1">
<inertial pos="-0.0192995 0.0365902 -0.039774" quat="-0.757351 0.568898 -0.3199 0" mass="0.118"
diaginertia="0.000159084 0.000154909 4.63655e-05"/>
<joint class="finger" name="right_finger" range="-0.0475 0"/>
<geom class="visual" pos="0.171097 -0.124901 -0.037" quat="1 -1 -1 -1" mesh="model2__16"/>
<geom class="visual" pos="0.171097 -0.124901 -0.037" quat="1 -1 -1 -1" mesh="model2__17"/>
<body name="rf_rot" quat="1 1 -1 -1" pos="0.0 0.0392 -0.037" gravcomp="1">
<geom class="collision" size="0.01 0.03" pos="0.0 -0.02 0.012" quat="1 0 1 0"
rgba="0.381493 0.492734 0.780446 1"/>
<geom class="collision" size="0.01 0.02" pos="0.02 -0.01 0.032" quat="1 0 -2.5 0"
rgba="0.381493 0.492734 0.780446 1"/>
<body name="rf_down" quat="1 0 0 0" pos="0.044 0.0 0.0" gravcomp="1">
<geom class="collision" size="0.01 0.01" pos="0.0 -0.020 0.012" quat="1 -0.1 0 0"
rgba="0.381493 0.492734 0.780446 1"/>
<geom class="collision" size="0.003 0.022" pos="0.005 -0.014 0.04" quat="1 -0.2 0 0"
rgba="0.381493 0.492734 0.780446 1"/>
<geom class="collision" size="0.003 0.022" pos="-0.005 -0.014 0.04" quat="1 -0.2 0 0"
rgba="0.381493 0.492734 0.780446 1"/>
<geom class="collision" type="box" size="0.006 0.002 0.04" pos="0 -0.0024 0.046" quat="1 0 0 0"
rgba="0.381493 0.492734 0.780446 1"/>
<geom class="collision" type="box" size="0.006 0.002 0.039" pos="-0.027 -0.0024 0.053"
quat="1 0 -2.5 0" rgba="0.381493 0.492734 0.780446 1"/>
<geom class="sphere_collision" pos="0.003 -0.0004 0.078"/>
<geom class="sphere_collision" pos="-0.003 -0.0004 0.078"/>
<geom class="sphere_collision" pos="0.003 -0.0004 0.07"/>
<geom class="sphere_collision" pos="-0.003 -0.0004 0.07"/>
<geom class="sphere_collision" pos="0.003 -0.0004 0.06"/>
<geom class="sphere_collision" pos="-0.003 -0.0004 0.06"/>
</body>
</body>
</body>
</body>
</body>
</body>
</body>
</body>
</body>
</body>
</worldbody>

<equality>
<joint joint1="left_finger" joint2="right_finger" polycoef="0 -1 0 0 0"/>
</equality>

<actuator>
<position name="joint1" joint="joint1" class="dm4340"/>
<position name="joint2" joint="joint2" class="dm4340"/>
<position name="joint3" joint="joint3" class="dm4340"/>
<position name="joint4" joint="joint4" class="dm4310" kp="20" kv=".5"/>
<position name="joint5" joint="joint5" class="dm4310"/>
<position name="joint6" joint="joint6" class="dm4310"/>
<position class="finger" name="gripper" joint="left_finger"/>
</actuator>

<keyframe>
<key name="home" qpos="0 1.047 1.047 0 0 0 0 0" ctrl="0 1.047 1.047 0 0 0 0"/>
</keyframe>
</mujoco>
1 change: 1 addition & 0 deletions docs/extensions/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ rcs_panda
rcs_xarm7
rcs_ur5e
rcs_so101
rcs_yam
rcs_realsense
rcs_usb_cam
rcs_tacto
Expand Down
1 change: 1 addition & 0 deletions docs/extensions/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ RCS comes with several supported extensions:
- **rcs_xarm7**: Support for the xArm7 robot.
- **rcs_ur5e**: Support for the UR5e robot.
- **rcs_so101**: Support for the SO101 robot.
- **rcs_yam**: Support for the I2RT YAM arm.
- **rcs_realsense**: Support for Intel RealSense cameras.
- **rcs_usb_cam**: Support for generic USB webcams.
- **rcs_tacto**: Integration with the Tacto tactile sensor simulator.
Expand Down
60 changes: 60 additions & 0 deletions docs/extensions/rcs_yam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# RCS YAM Extension

This extension provides support for the I2RT YAM arm in RCS, built on the
[i2rt](https://github.com/i2rt-robotics/i2rt) Python driver.

## Installation

`i2rt` is not published on PyPI and is pinned as a direct git reference, so this extension is
installed from a checkout:

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

Bring up the CAN interface of the arm before use:

```shell
sudo ip link set can0 up type can bitrate 1000000
```

## Usage

```python
from rcs.envs.base import ControlMode
from rcs_yam.configs import DefaultYamHardwareEnv

env_creator = DefaultYamHardwareEnv()
env_creator.channel = "can0"

cfg = env_creator.config()
cfg.control_mode = ControlMode.JOINTS
cfg.robot_cfg.async_control = False

env = env_creator.create_env(cfg)
obs, info = env.reset()
```

## Sync and async control

The i2rt driver runs its PD control loop in a background thread. With
`YamConfig.async_control=True` the RCS setters return as soon as the target is handed over, with
`async_control=False` they poll the measured state until the target is reached or the timeout hits.
`move_home` interpolates the motion and always blocks.

## Notes

- Arm and gripper share one motor chain, since i2rt exposes the gripper motor as the last entry of
the arm's chain. The gripper is created from the same robot instance.
- The `linear_4310` gripper calibrates on startup and drives the fingers to both end stops unless
`gripper_limits_override` is set.
- There is no compliant force control and no trajectory generation in the driver. Targets further
than `max_joint_step` away are ramped rather than sent as a step.
- The simulated counterpart is registered as `rcs/yam` in core RCS and shares the kinematics, joint
limits and gripper stroke of the hardware.

See `extensions/rcs_yam/README.md` for the full extension documentation and
`extensions/rcs_yam/src/rcs_yam/scripts/test_robot.py` for a bring-up script. For a maintained
example, see `examples/yam/yam_env_cartesian_control.py`, which moves the TCP forward and backward in
synchronous Cartesian mode in simulation or on hardware.
8 changes: 8 additions & 0 deletions examples/teleop/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ Note that dual arm is only supported for a aloha like setup where the robot face
9. Start the teleoperation script [`franka.py`](franka.py) and enjoy.


## Teleoperation of a YAM with Meta Quest 3
[`yam.py`](yam.py) is the same setup for a single [YAM](https://robotcontrolstack.org/extensions/rcs_yam) arm.
Follow the quest steps above, they are identical, and align the coordinate axis to the arm base (x front, y left, z up).
The arm follows the right controller, so keep `ROBOT_NAME = "right"` unless you also change the controller mapping.
1. install the [YAM extension](https://robotcontrolstack.org/extensions/rcs_yam) and bring up its CAN interface (`sudo ip link set can0 up type can bitrate 1000000`)
2. go to [`yam.py`](yam.py), set `ROBOT_INSTANCE = RobotPlatform.HARDWARE` and set `CAN_CHANNEL` to your interface, or keep `RobotPlatform.SIMULATION` to try it in sim first
3. to record RealSense cameras, install the [RealSense extension](https://robotcontrolstack.org/extensions/rcs_realsense) and put your camera serial numbers (`rs-enumerate-devices -s`) into `CAMERA_DICT`, or set it to `None` to run without cameras

## Teleoperation with Franka GELLO Duo
Teleoperate your Franka Duo using the [Franka GELLO Duo](https://franka.de/de-de/product-prototypes).
Install dependencies via
Expand Down
1 change: 1 addition & 0 deletions examples/teleop/franka.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
simulation=ROBOT_INSTANCE == RobotPlatform.SIMULATION,
switched_left_right=False,
display_cameras=False,
read_frequency=90,
)
# config = GelloConfig(
# arms={
Expand Down
Loading
Loading