Skip to content

Commit 024df2c

Browse files
committed
refactor: Flexible dof and robot meta config
- VectorXd type for flexible joint spaces - adapted gym spaces to be dof independent - robot meta config struct to describe meta configs of robot such as dofs - robot platform enum moved to cpp part
1 parent 501f24e commit 024df2c

File tree

22 files changed

+310
-141
lines changed

22 files changed

+310
-141
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ Checkout the python examples that we provide in [python/examples](python/example
3636
All of these examples work both in the MuJoCo simulation as well as on your hardware FR3.
3737
Just switch between the following settings in the example script
3838
```python
39-
ROBOT_INSTANCE = RobotInstance.SIMULATION
40-
# ROBOT_INSTANCE = RobotInstance.HARDWARE
39+
ROBOT_INSTANCE = RobotPlatform.SIMULATION
40+
# ROBOT_INSTANCE = RobotPlatform.HARDWARE
4141
```
4242
and add your robot credentials to a `.env` file like this:
4343
```env

python/examples/env_cartesian_control.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import logging
22

3+
from rcsss._core.common import RobotPlatform
34
from rcsss.control.fr3_desk import FCI, ContextManager, Desk, load_creds_fr3_desk
4-
from rcsss.envs.base import ControlMode, RelativeTo, RobotInstance
5+
from rcsss.envs.base import ControlMode, RelativeTo
56
from rcsss.envs.creators import RCSFR3EnvCreator, RCSSimEnvCreator
67
from rcsss.envs.utils import (
78
default_fr3_hw_gripper_cfg,
@@ -15,7 +16,7 @@
1516
logger.setLevel(logging.INFO)
1617

1718
ROBOT_IP = "192.168.101.1"
18-
ROBOT_INSTANCE = RobotInstance.SIMULATION
19+
ROBOT_INSTANCE = RobotPlatform.SIMULATION
1920

2021

2122
"""
@@ -43,14 +44,14 @@
4344

4445
def main():
4546
context_manger: ContextManager
46-
if ROBOT_INSTANCE == RobotInstance.HARDWARE:
47+
if ROBOT_INSTANCE == RobotPlatform.HARDWARE:
4748
user, pw = load_creds_fr3_desk()
4849
context_manger = FCI(Desk(ROBOT_IP, user, pw), unlock=False, lock_when_done=False)
4950
else:
5051
context_manger = ContextManager()
5152

5253
with context_manger:
53-
if ROBOT_INSTANCE == RobotInstance.HARDWARE:
54+
if ROBOT_INSTANCE == RobotPlatform.HARDWARE:
5455
env_rel = RCSFR3EnvCreator()(
5556
ip=ROBOT_IP,
5657
control_mode=ControlMode.CARTESIAN_TQuat,

python/examples/env_joint_control.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import logging
22

33
import numpy as np
4+
from rcsss._core.common import RobotPlatform
45
from rcsss.control.fr3_desk import FCI, ContextManager, Desk, load_creds_fr3_desk
5-
from rcsss.envs.base import ControlMode, RelativeTo, RobotInstance
6+
from rcsss.envs.base import ControlMode, RelativeTo
67
from rcsss.envs.creators import RCSFR3EnvCreator, RCSSimEnvCreator
78
from rcsss.envs.utils import (
89
default_fr3_hw_gripper_cfg,
@@ -16,7 +17,7 @@
1617
logger.setLevel(logging.INFO)
1718

1819
ROBOT_IP = "192.168.101.1"
19-
ROBOT_INSTANCE = RobotInstance.SIMULATION
20+
ROBOT_INSTANCE = RobotPlatform.SIMULATION
2021

2122

2223
"""
@@ -44,14 +45,14 @@
4445

4546
def main():
4647
context_manger: FCI | ContextManager
47-
if ROBOT_INSTANCE == RobotInstance.HARDWARE:
48+
if ROBOT_INSTANCE == RobotPlatform.HARDWARE:
4849
user, pw = load_creds_fr3_desk()
4950
context_manger = FCI(Desk(ROBOT_IP, user, pw), unlock=False, lock_when_done=False)
5051
else:
5152
context_manger = ContextManager()
5253
with context_manger:
5354

54-
if ROBOT_INSTANCE == RobotInstance.HARDWARE:
55+
if ROBOT_INSTANCE == RobotPlatform.HARDWARE:
5556
env_rel = RCSFR3EnvCreator()(
5657
ip=ROBOT_IP,
5758
control_mode=ControlMode.JOINTS,

python/examples/fr3.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
import numpy as np
55
import rcsss
66
from rcsss import sim
7+
from rcsss._core.common import RobotPlatform
78
from rcsss._core.hw import FR3Config, IKSolver
89
from rcsss._core.sim import CameraType
910
from rcsss.camera.sim import SimCameraConfig, SimCameraSet, SimCameraSetConfig
1011
from rcsss.control.fr3_desk import FCI, ContextManager, Desk, load_creds_fr3_desk
11-
from rcsss.envs.base import RobotInstance
1212
from rcsss.envs.creators import get_urdf_path
1313

1414
ROBOT_IP = "192.168.101.1"
15-
ROBOT_INSTANCE = RobotInstance.SIMULATION
15+
ROBOT_INSTANCE = RobotPlatform.SIMULATION
1616
# replace this with a path to a robot urdf file if you dont have the utn models
1717
URDF_PATH = None
1818

@@ -55,7 +55,7 @@ def main():
5555
logger.error("This pip package was not built with the UTN lab models, aborting.")
5656
sys.exit()
5757
context_manger: FCI | ContextManager
58-
if ROBOT_INSTANCE == RobotInstance.HARDWARE:
58+
if ROBOT_INSTANCE == RobotPlatform.HARDWARE:
5959
user, pw = load_creds_fr3_desk()
6060
context_manger = FCI(Desk(ROBOT_IP, user, pw), unlock=False, lock_when_done=False)
6161
else:
@@ -64,7 +64,7 @@ def main():
6464
with context_manger:
6565
robot: rcsss.common.Robot
6666
gripper: rcsss.common.Gripper
67-
if ROBOT_INSTANCE == RobotInstance.SIMULATION:
67+
if ROBOT_INSTANCE == RobotPlatform.SIMULATION:
6868
simulation = sim.Sim(rcsss.scenes["fr3_empty_world"])
6969
urdf_path = get_urdf_path(URDF_PATH, allow_none_if_not_found=False)
7070
assert urdf_path is not None
@@ -107,15 +107,15 @@ def main():
107107
# move to home position and open gripper
108108
robot.move_home()
109109
gripper.open()
110-
if ROBOT_INSTANCE == RobotInstance.SIMULATION:
110+
if ROBOT_INSTANCE == RobotPlatform.SIMULATION:
111111
simulation.step_until_convergence()
112112
logger.info("Robot is in home position, gripper is open")
113113

114114
# 5cm in x direction
115115
robot.set_cartesian_position(
116116
robot.get_cartesian_position() * rcsss.common.Pose(translation=np.array([0.05, 0, 0]))
117117
)
118-
if ROBOT_INSTANCE == RobotInstance.SIMULATION:
118+
if ROBOT_INSTANCE == RobotPlatform.SIMULATION:
119119
simulation.step_until_convergence()
120120
logger.debug(f"IK success: {robot.get_state().ik_success}") # type: ignore
121121
logger.debug(f"sim converged: {simulation.is_converged()}")
@@ -124,7 +124,7 @@ def main():
124124
robot.set_cartesian_position(
125125
robot.get_cartesian_position() * rcsss.common.Pose(translation=np.array([0, 0.05, 0]))
126126
)
127-
if ROBOT_INSTANCE == RobotInstance.SIMULATION:
127+
if ROBOT_INSTANCE == RobotPlatform.SIMULATION:
128128
simulation.step_until_convergence()
129129
logger.debug(f"IK success: {robot.get_state().ik_success}") # type: ignore
130130
logger.debug(f"sim converged: {simulation.is_converged()}")
@@ -133,7 +133,7 @@ def main():
133133
robot.set_cartesian_position(
134134
robot.get_cartesian_position() * rcsss.common.Pose(translation=np.array([0, 0, 0.05]))
135135
)
136-
if ROBOT_INSTANCE == RobotInstance.SIMULATION:
136+
if ROBOT_INSTANCE == RobotPlatform.SIMULATION:
137137
simulation.step_until_convergence()
138138
logger.debug(f"IK success: {robot.get_state().ik_success}") # type: ignore
139139
logger.debug(f"sim converged: {simulation.is_converged()}")
@@ -143,12 +143,12 @@ def main():
143143
translation=np.array([0, 0, 0]), rpy=rcsss.common.RPY(roll=0, pitch=-np.deg2rad(90), yaw=-np.deg2rad(90))
144144
)
145145
robot.set_cartesian_position(new_pose)
146-
if ROBOT_INSTANCE == RobotInstance.SIMULATION:
146+
if ROBOT_INSTANCE == RobotPlatform.SIMULATION:
147147
simulation.step_until_convergence()
148148
logger.debug(f"IK success: {robot.get_state().ik_success}") # type: ignore
149149
logger.debug(f"sim converged: {simulation.is_converged()}")
150150

151-
if ROBOT_INSTANCE == RobotInstance.HARDWARE:
151+
if ROBOT_INSTANCE == RobotPlatform.HARDWARE:
152152
input(
153153
"hold an object 25cm in front of the gripper, the robot is going to grasp it, press enter when you are ready"
154154
)
@@ -157,37 +157,37 @@ def main():
157157
robot.set_cartesian_position(
158158
robot.get_cartesian_position() * rcsss.common.Pose(translation=np.array([0, 0, 0.25]))
159159
)
160-
if ROBOT_INSTANCE == RobotInstance.SIMULATION:
160+
if ROBOT_INSTANCE == RobotPlatform.SIMULATION:
161161
simulation.step_until_convergence()
162162
logger.debug(f"IK success: {robot.get_state().ik_success}") # type: ignore
163163
logger.debug(f"sim converged: {simulation.is_converged()}")
164164

165165
# grasp the object
166166
gripper.grasp()
167-
if ROBOT_INSTANCE == RobotInstance.SIMULATION:
167+
if ROBOT_INSTANCE == RobotPlatform.SIMULATION:
168168
simulation.step_until_convergence()
169169
logger.debug(f"sim converged: {simulation.is_converged()}")
170170

171171
# move 25cm backward
172172
robot.set_cartesian_position(
173173
robot.get_cartesian_position() * rcsss.common.Pose(translation=np.array([0, 0, -0.25]))
174174
)
175-
if ROBOT_INSTANCE == RobotInstance.SIMULATION:
175+
if ROBOT_INSTANCE == RobotPlatform.SIMULATION:
176176
simulation.step_until_convergence()
177177
logger.debug(f"IK success: {robot.get_state().ik_success}") # type: ignore
178178
logger.debug(f"sim converged: {simulation.is_converged()}")
179179

180-
if ROBOT_INSTANCE == RobotInstance.HARDWARE:
180+
if ROBOT_INSTANCE == RobotPlatform.HARDWARE:
181181
input("gripper is going to be open, press enter when you are ready")
182182

183183
# open gripper
184184
gripper.open()
185-
if ROBOT_INSTANCE == RobotInstance.SIMULATION:
185+
if ROBOT_INSTANCE == RobotPlatform.SIMULATION:
186186
simulation.step_until_convergence()
187187

188188
# move back to home position
189189
robot.move_home()
190-
if ROBOT_INSTANCE == RobotInstance.SIMULATION:
190+
if ROBOT_INSTANCE == RobotPlatform.SIMULATION:
191191
simulation.step_until_convergence()
192192

193193

python/rcsss/_core/common.pyi

Lines changed: 88 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ import numpy
1010
import pybind11_stubgen.typing_ext
1111

1212
__all__ = [
13+
"FR3",
1314
"FrankaHandTCPOffset",
1415
"Gripper",
1516
"GripperConfig",
1617
"GripperState",
18+
"HARDWARE",
1719
"IK",
1820
"IdentityRotMatrix",
1921
"IdentityRotQuatVec",
@@ -22,8 +24,16 @@ __all__ = [
2224
"RPY",
2325
"Robot",
2426
"RobotConfig",
27+
"RobotMetaConfig",
28+
"RobotPlatform",
2529
"RobotState",
30+
"RobotType",
31+
"SIMULATION",
32+
"UR5e",
33+
"robots_meta_config",
2634
]
35+
M = typing.TypeVar("M", bound=int)
36+
N = typing.TypeVar("N", bound=int)
2737

2838
class Gripper:
2939
def get_normalized_width(self) -> float: ...
@@ -45,8 +55,8 @@ class GripperState:
4555
class IK:
4656
def __init__(self, urdf_path: str, max_duration_ms: int = 300) -> None: ...
4757
def ik(
48-
self, pose: Pose, q0: numpy.ndarray[typing.Literal[7], numpy.dtype[numpy.float64]], tcp_offset: Pose = ...
49-
) -> numpy.ndarray[typing.Literal[7], numpy.dtype[numpy.float64]] | None: ...
58+
self, pose: Pose, q0: numpy.ndarray[M, numpy.dtype[numpy.float64]], tcp_offset: Pose = ...
59+
) -> numpy.ndarray[M, numpy.dtype[numpy.float64]] | None: ...
5060

5161
class Pose:
5262
def __getstate__(self) -> typing.Annotated[list[float], pybind11_stubgen.typing_ext.FixedSize(16)]: ...
@@ -127,23 +137,96 @@ class Robot:
127137
def get_base_pose_in_world_coordinates(self) -> Pose: ...
128138
def get_cartesian_position(self) -> Pose: ...
129139
def get_ik(self) -> IK | None: ...
130-
def get_joint_position(self) -> numpy.ndarray[typing.Literal[7], numpy.dtype[numpy.float64]]: ...
140+
def get_joint_position(self) -> numpy.ndarray[M, numpy.dtype[numpy.float64]]: ...
131141
def get_parameters(self) -> RobotConfig: ...
132142
def get_state(self) -> RobotState: ...
133143
def move_home(self) -> None: ...
134144
def reset(self) -> None: ...
135145
def set_cartesian_position(self, pose: Pose) -> None: ...
136-
def set_joint_position(self, q: numpy.ndarray[typing.Literal[7], numpy.dtype[numpy.float64]]) -> None: ...
146+
def set_joint_position(self, q: numpy.ndarray[M, numpy.dtype[numpy.float64]]) -> None: ...
137147
def to_pose_in_robot_coordinates(self, pose_in_world_coordinates: Pose) -> Pose: ...
138148
def to_pose_in_world_coordinates(self, pose_in_robot_coordinates: Pose) -> Pose: ...
139149

140150
class RobotConfig:
141-
pass
151+
robot_platform: RobotPlatform
152+
robot_type: RobotType
153+
154+
class RobotMetaConfig:
155+
@property
156+
def dof(self) -> int: ...
157+
@property
158+
def joint_limits(self) -> numpy.ndarray[tuple[typing.Literal[2], N], numpy.dtype[numpy.float64]]: ...
159+
@property
160+
def q_home(self) -> numpy.ndarray[M, numpy.dtype[numpy.float64]]: ...
161+
162+
class RobotPlatform:
163+
"""
164+
Members:
165+
166+
HARDWARE
167+
168+
SIMULATION
169+
"""
170+
171+
HARDWARE: typing.ClassVar[RobotPlatform] # value = <RobotPlatform.HARDWARE: 1>
172+
SIMULATION: typing.ClassVar[RobotPlatform] # value = <RobotPlatform.SIMULATION: 0>
173+
__members__: typing.ClassVar[
174+
dict[str, RobotPlatform]
175+
] # value = {'HARDWARE': <RobotPlatform.HARDWARE: 1>, 'SIMULATION': <RobotPlatform.SIMULATION: 0>}
176+
def __eq__(self, other: typing.Any) -> bool: ...
177+
def __getstate__(self) -> int: ...
178+
def __hash__(self) -> int: ...
179+
def __index__(self) -> int: ...
180+
def __init__(self, value: int) -> None: ...
181+
def __int__(self) -> int: ...
182+
def __ne__(self, other: typing.Any) -> bool: ...
183+
def __repr__(self) -> str: ...
184+
def __setstate__(self, state: int) -> None: ...
185+
def __str__(self) -> str: ...
186+
@property
187+
def name(self) -> str: ...
188+
@property
189+
def value(self) -> int: ...
142190

143191
class RobotState:
144192
pass
145193

194+
class RobotType:
195+
"""
196+
Members:
197+
198+
FR3
199+
200+
UR5e
201+
"""
202+
203+
FR3: typing.ClassVar[RobotType] # value = <RobotType.FR3: 0>
204+
UR5e: typing.ClassVar[RobotType] # value = <RobotType.UR5e: 1>
205+
__members__: typing.ClassVar[
206+
dict[str, RobotType]
207+
] # value = {'FR3': <RobotType.FR3: 0>, 'UR5e': <RobotType.UR5e: 1>}
208+
def __eq__(self, other: typing.Any) -> bool: ...
209+
def __getstate__(self) -> int: ...
210+
def __hash__(self) -> int: ...
211+
def __index__(self) -> int: ...
212+
def __init__(self, value: int) -> None: ...
213+
def __int__(self) -> int: ...
214+
def __ne__(self, other: typing.Any) -> bool: ...
215+
def __repr__(self) -> str: ...
216+
def __setstate__(self, state: int) -> None: ...
217+
def __str__(self) -> str: ...
218+
@property
219+
def name(self) -> str: ...
220+
@property
221+
def value(self) -> int: ...
222+
146223
def FrankaHandTCPOffset() -> numpy.ndarray[tuple[typing.Literal[4], typing.Literal[4]], numpy.dtype[numpy.float64]]: ...
147224
def IdentityRotMatrix() -> numpy.ndarray[tuple[typing.Literal[3], typing.Literal[3]], numpy.dtype[numpy.float64]]: ...
148225
def IdentityRotQuatVec() -> numpy.ndarray[typing.Literal[4], numpy.dtype[numpy.float64]]: ...
149226
def IdentityTranslation() -> numpy.ndarray[typing.Literal[3], numpy.dtype[numpy.float64]]: ...
227+
def robots_meta_config(robot_type: RobotType) -> RobotMetaConfig: ...
228+
229+
FR3: RobotType # value = <RobotType.FR3: 0>
230+
HARDWARE: RobotPlatform # value = <RobotPlatform.HARDWARE: 1>
231+
SIMULATION: RobotPlatform # value = <RobotPlatform.SIMULATION: 0>
232+
UR5e: RobotType # value = <RobotType.UR5e: 1>

python/rcsss/_core/sim.pyi

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ class SimRobot(rcsss._core.common.Robot):
144144
) -> None: ...
145145
def get_parameters(self) -> SimRobotConfig: ...
146146
def get_state(self) -> SimRobotState: ...
147-
def set_joints_hard(self, q: numpy.ndarray[typing.Literal[7], numpy.dtype[numpy.float64]]) -> None: ...
147+
def set_joints_hard(self, q: numpy.ndarray[M, numpy.dtype[numpy.float64]]) -> None: ...
148148
def set_parameters(self, cfg: SimRobotConfig) -> bool: ...
149149

150150
class SimRobotConfig(rcsss._core.common.RobotConfig):
@@ -168,9 +168,9 @@ class SimRobotState(rcsss._core.common.RobotState):
168168
@property
169169
def is_moving(self) -> bool: ...
170170
@property
171-
def previous_angles(self) -> numpy.ndarray[typing.Literal[7], numpy.dtype[numpy.float64]]: ...
171+
def previous_angles(self) -> numpy.ndarray[M, numpy.dtype[numpy.float64]]: ...
172172
@property
173-
def target_angles(self) -> numpy.ndarray[typing.Literal[7], numpy.dtype[numpy.float64]]: ...
173+
def target_angles(self) -> numpy.ndarray[M, numpy.dtype[numpy.float64]]: ...
174174

175175
def open_gui_window(uuid: str) -> None: ...
176176

0 commit comments

Comments
 (0)