Skip to content

Commit 7e7446c

Browse files
committed
fix(config): corrected config extension form cpp base
- corrected config extension by using normal python classes and not dataclasses - added unpack type hinting type kwargs for base classes - added auto generated typed dict file for base config class types that come from cpp
1 parent be422ff commit 7e7446c

8 files changed

Lines changed: 241 additions & 72 deletions

File tree

Makefile

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@ stubgen:
3030
find ./python -not -path "./python/rcs/_core/*" -name '*.pyi' -delete
3131
find ./python/rcs/_core -name '*.pyi' -print | xargs sed -i 's/tuple\[typing\.Literal\[\([0-9]\+\)\], typing\.Literal\[1\]\]/tuple\[typing\.Literal[\1]\]/g'
3232
find ./python/rcs/_core -name '*.pyi' -print | xargs sed -i 's/tuple\[\([M|N]\), typing\.Literal\[1\]\]/tuple\[\1\]/g'
33-
ruff check --fix python/rcs/_core
34-
isort python/rcs/_core
35-
black python/rcs/_core
33+
python scripts/generate_common_typing.py
34+
ruff check --fix python/rcs/_core python/rcs/common_typing.py
35+
isort python/rcs/_core python/rcs/common_typing.py
36+
black python/rcs/_core python/rcs/common_typing.py
3637

3738
# Python
3839
pycheckformat:

extensions/rcs_robotiq2f85/src/rcs_robotiq2f85/hw.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
1-
from dataclasses import dataclass
2-
31
from rcs._core.common import Gripper, GripperConfig, GripperState
42
from Robotiq2F85Driver.Robotiq2F85Driver import GripperStatus, Robotiq2F85Driver
53

64

7-
@dataclass(kw_only=True)
85
class RobotiQ2F85GripperConfig(GripperConfig):
9-
serial_number: str
10-
"""Get the serial number with `udevadm info -a -n /dev/ttyUSB0 | grep serial`, make sure you have read/write permissions to the port."""
11-
speed: float = 100
12-
"""Speed in mm/s. Must be between 20 and 150 mm/s."""
13-
force: float = 50
14-
"""Force in N. Must be between 20 and 235 N."""
15-
async_control: bool = True
16-
"""If True, gripper commands return immediately without waiting for the movement to complete.
17-
A new command interrupts any ongoing movement."""
18-
19-
20-
@dataclass(kw_only=True)
21-
class RobotiQ2F85GripperState(GripperState):
22-
state: GripperStatus
236

24-
def __post_init__(self):
7+
def __init__(self, serial_number: str, speed: float = 100, force: float = 50, async_control: bool = True) -> None:
8+
"""
9+
Args:
10+
serial_number: Get the serial number with `udevadm info -a -n /dev/ttyUSB0 | grep serial`, make sure you have read/write permissions to the port.
11+
speed: Speed in mm/s. Must be between 20 and 150 mm/s.
12+
force: Force in N. Must be between 20 and 235 N.
13+
async_control: If True, gripper commands return immediately without waiting for the movement to complete. A new command interrupts any ongoing movement.
14+
"""
15+
super().__init__()
16+
self.serial_number = serial_number
17+
self.speed = speed
18+
self.force = force
19+
self.async_control = async_control
20+
21+
22+
class RobotiQ2F85GripperState(GripperState):
23+
def __init__(self, state: GripperStatus) -> None:
2524
super().__init__()
25+
self.state = state
2626

2727

2828
class RobotiQ2F85Gripper(Gripper):

extensions/rcs_so101/src/rcs_so101/hw.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,30 @@
11
import threading
22
import typing
3-
from dataclasses import dataclass
43
from pathlib import Path
54

65
import numpy as np
76
from lerobot.robots import make_robot_from_config
87
from lerobot.robots.so101_follower.config_so101_follower import SO101FollowerConfig
98
from lerobot.robots.so101_follower.so101_follower import SO101Follower
9+
from rcs.common_typing import RobotConfigKwargs
1010
from rcs.utils import SimpleFrameRate
1111

1212
from rcs import common
1313

1414

15-
@dataclass(kw_only=True)
1615
class SO101Config(common.RobotConfig):
17-
id: str = "follower"
18-
port: str = "/dev/ttyACM0"
19-
calibration_dir: str = "."
16+
17+
def __init__(
18+
self,
19+
id: str = "follower",
20+
port: str = "/dev/ttyACM0",
21+
calibration_dir: str = ".",
22+
**kwargs: typing.Unpack[RobotConfigKwargs],
23+
):
24+
super().__init__(**kwargs)
25+
self.id = id
26+
self.port = port
27+
self.calibration_dir = calibration_dir
2028

2129

2230
class SO101(common.Robot):

extensions/rcs_ur5e/src/rcs_ur5e/hw.py

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,38 +5,45 @@
55
import multiprocessing as mp
66
import time
77
import typing
8-
from dataclasses import dataclass
98
from enum import IntEnum
109
from multiprocessing.shared_memory import SharedMemory
1110

1211
import numpy as np
1312
import rtde_control
1413
import rtde_receive
14+
from rcs.common_typing import RobotConfigKwargs
1515
from rcs_ur5e import robotiq_gripper
1616

17-
import rcs
1817
from rcs import common
1918

2019

21-
@dataclass(kw_only=True)
2220
class UR5eConfig(common.RobotConfig):
23-
ip: str
2421

25-
# Kinematics Setup
26-
robot_type: common.RobotType = common.RobotType.UR5e
27-
kinematic_model_path = rcs.scenes["ur5e_empty_world"].mjcf_robot
28-
attachment_site = "attachment_site"
29-
30-
# Robot movement parameters
31-
max_velocity: float = 1.0
32-
max_acceleration: float = 1.0
33-
async_control: bool = True
34-
max_servo_joint_step: float = 0.15
35-
max_servo_cartesian_step: float = 0.01
36-
37-
# UR Controller parameters, change with caution
38-
lookahead_time: float = 0.05
39-
gain: float = 500.0
22+
def __init__(
23+
self,
24+
ip: str,
25+
max_velocity: float = 1.0,
26+
max_acceleration: float = 1.0,
27+
async_control: bool = True,
28+
max_servo_joint_step: float = 0.15,
29+
max_servo_cartesian_step: float = 0.01,
30+
lookahead_time: float = 0.05,
31+
gain: float = 500.0,
32+
**kwargs: typing.Unpack[RobotConfigKwargs],
33+
):
34+
super().__init__(**kwargs)
35+
self.robot_platform = common.RobotPlatform.HARDWARE
36+
self.robot_type = common.RobotType.UR5e
37+
self.ip = ip
38+
# Robot movement parameters
39+
self.max_velocity = max_velocity
40+
self.max_acceleration = max_acceleration
41+
self.async_control = async_control
42+
self.max_servo_joint_step = max_servo_joint_step
43+
self.max_servo_cartesian_step = max_servo_cartesian_step
44+
# UR Controller parameters, change with caution
45+
self.lookahead_time = lookahead_time
46+
self.gain = gain
4047

4148
def to_dict(self) -> dict[str, typing.Any]:
4249
return {
@@ -55,13 +62,11 @@ def from_dict(self, data: dict[str, typing.Any]) -> None:
5562
for key, value in data.items():
5663
setattr(self, key, value)
5764

58-
def __post_init__(self):
59-
super().__init__()
6065

61-
62-
@dataclass(kw_only=True)
6366
class RobotiQGripperConfig(common.GripperConfig):
64-
ip: str
67+
def __init__(self, ip: str):
68+
super().__init__()
69+
self.ip = ip
6570

6671

6772
# Define the shared memory

extensions/rcs_xarm7/src/rcs_xarm7/hw.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,30 @@
11
import typing
2-
from dataclasses import dataclass, field
32
from typing import List
43

54
import numpy as np
5+
from rcs.common_typing import RobotConfigKwargs
66
from xarm.wrapper import XArmAPI
77

88
from rcs import common
99

1010

11-
@dataclass(kw_only=True)
1211
class XArm7Config(common.RobotConfig):
13-
ip: str
14-
payload_weight: float = 0.624
15-
payload_tcp: List[float] = field(default_factory=lambda: [-4.15, 5.24, 76.38])
16-
async_control: bool = False
17-
use_internal_ik: bool = True
1812

19-
def __post_init__(self):
20-
super().__init__()
13+
def __init__(
14+
self,
15+
ip: str,
16+
payload_weight: float = 0.624,
17+
payload_tcp: List[float] | None = None,
18+
async_control: bool = False,
19+
use_internal_ik: bool = True,
20+
**kwargs: typing.Unpack[RobotConfigKwargs],
21+
):
22+
super().__init__(**kwargs)
23+
self.ip = ip
24+
self.payload_weight = payload_weight
25+
self.payload_tcp = payload_tcp if payload_tcp is not None else [-4.15, 5.24, 76.38]
26+
self.async_control = async_control
27+
self.use_internal_ik = use_internal_ik
2128

2229

2330
class XArm7(common.Robot):

python/rcs/common_typing.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# ATTENTION: auto generated from C++ stub files, use `make stubgen` to update!
2+
"""TypedDict helpers generated from `python/rcs/_core/common.pyi`."""
3+
from __future__ import annotations
4+
5+
from typing import TypedDict
6+
7+
from rcs._core import common
8+
9+
__all__ = ["BaseCameraConfigKwargs", "RobotConfigKwargs"]
10+
11+
12+
class BaseCameraConfigKwargs(TypedDict, total=False):
13+
identifier: str
14+
frame_rate: int
15+
resolution_width: int
16+
resolution_height: int
17+
18+
19+
class RobotConfigKwargs(TypedDict, total=False):
20+
robot_type: common.RobotType
21+
robot_platform: common.RobotPlatform
22+
tcp_offset: common.Pose
23+
attachment_site: str
24+
kinematic_model_path: str

python/rcs/hand/tilburg_hand.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import copy
22
import logging
33
import typing
4-
from dataclasses import dataclass
54
from time import sleep
65

76
import numpy as np
@@ -15,27 +14,30 @@
1514
logger.disabled = False
1615

1716

18-
@dataclass(kw_only=True)
1917
class THConfig(common.HandConfig):
2018
"""Config for the Tilburg hand"""
2119

22-
calibration_file: str | None = None
23-
grasp_percentage: float = 1.0
24-
control_unit: Unit = Unit.NORMALIZED
25-
hand_orientation: str = "right"
26-
grasp_type: common.GraspType = common.GraspType.POWER_GRASP
27-
28-
def __post_init__(self):
29-
# 👇 satisfy pybind11 by actually calling the C++ constructor
20+
def __init__(
21+
self,
22+
calibration_file: str | None = None,
23+
grasp_percentage: float = 1.0,
24+
control_unit: Unit = Unit.NORMALIZED,
25+
hand_orientation: str = "right",
26+
grasp_type: common.GraspType = common.GraspType.POWER_GRASP,
27+
) -> None:
3028
super().__init__()
29+
self.calibration_file = calibration_file
30+
self.grasp_percentage = grasp_percentage
31+
self.control_unit = control_unit
32+
self.hand_orientation = hand_orientation
33+
self.grasp_type = grasp_type
3134

3235

33-
@dataclass
3436
class TilburgHandState(common.HandState):
35-
joint_positions: Vec18Type
3637

37-
def __post_init__(self):
38+
def __init__(self, joint_positions: Vec18Type) -> None:
3839
super().__init__()
40+
self.joint_positions = joint_positions
3941

4042

4143
class TilburgHand(common.Hand):

0 commit comments

Comments
 (0)