11import logging
22from os import PathLike
3+ from typing import Type
34
45import gymnasium as gym
6+ import numpy as np
57import rcsss
8+ from gymnasium .envs .registration import EnvCreator
69from rcsss import sim
710from rcsss ._core .hw import FR3Config , IKController
811from rcsss ._core .sim import CameraType
2124 RelativeTo ,
2225)
2326from rcsss .envs .hw import FR3HW
24- from rcsss .envs .sim import CollisionGuard , FR3Sim
27+ from rcsss .envs .sim import (
28+ CollisionGuard ,
29+ FR3Sim ,
30+ FR3SimplePickUpSimSuccessWrapper ,
31+ RandomCubePos ,
32+ SimWrapper ,
33+ )
2534
2635logger = logging .getLogger (__name__ )
2736logger .setLevel (logging .INFO )
@@ -43,7 +52,9 @@ def default_fr3_hw_gripper_cfg():
4352 return gripper_cfg
4453
4554
46- def default_realsense (name2id : dict [str , str ]):
55+ def default_realsense (name2id : dict [str , str ] | None ) -> RealSenseCameraSet | None :
56+ if name2id is None :
57+ return None
4758 cameras = {name : BaseCameraConfig (identifier = id ) for name , id in name2id .items ()}
4859 cam_cfg = RealSenseSetConfig (
4960 cameras = cameras ,
@@ -132,6 +143,7 @@ def fr3_hw_env(
132143 control_mode = control_mode ,
133144 tcp_offset = rcsss .common .Pose (rcsss .common .FrankaHandTCPOffset ()),
134145 sim_gui = True ,
146+ truncate_on_collision = False ,
135147 )
136148 if max_relative_movement is not None :
137149 env = RelativeActionSpace (env , max_mov = max_relative_movement , relative_to = relative_to )
@@ -173,6 +185,7 @@ def fr3_sim_env(
173185 relative_to : RelativeTo = RelativeTo .LAST_STEP ,
174186 urdf_path : str | PathLike | None = None ,
175187 mjcf : str | PathLike = "fr3_empty_world" ,
188+ sim_wrapper : Type [SimWrapper ] | None = None ,
176189) -> gym .Env [ObsArmsGrCam , LimitedJointsRelDictType ]:
177190 """
178191 Creates a simulation environment for the FR3 robot.
@@ -190,6 +203,8 @@ def fr3_sim_env(
190203 urdf_path (str | PathLike | None): Path to the URDF file. If None, the URDF file is automatically deduced
191204 which requires a UTN compatible lab scene to be present.
192205 mjcf (str | PathLike): Path to the Mujoco scene XML file. Defaults to "fr3_empty_world".
206+ sim_wrapper (Type[SimWrapper] | None): Wrapper to be applied before the simulation wrapper. This is useful
207+ for reset management e.g. resetting objects in the scene with correct observations. Defaults to None.
193208
194209 Returns:
195210 gym.Env: The configured simulation environment for the FR3 robot.
@@ -204,15 +219,15 @@ def fr3_sim_env(
204219 robot = rcsss .sim .FR3 (simulation , "0" , ik )
205220 robot .set_parameters (robot_cfg )
206221 env : gym .Env = FR3Env (robot , control_mode )
207- env = FR3Sim (env , simulation )
222+ env = FR3Sim (env , simulation , sim_wrapper )
208223
209224 if camera_set_cfg is not None :
210225 camera_set = SimCameraSet (simulation , camera_set_cfg )
211226 env = CameraSetWrapper (env , camera_set , include_depth = True )
212227
213228 if gripper_cfg is not None :
214229 gripper = sim .FrankaHand (simulation , "0" , gripper_cfg )
215- env = GripperWrapper (env , gripper , binary = False )
230+ env = GripperWrapper (env , gripper , binary = True )
216231
217232 if collision_guard :
218233 env = CollisionGuard .env_from_xml_paths (
@@ -224,8 +239,85 @@ def fr3_sim_env(
224239 control_mode = control_mode ,
225240 tcp_offset = rcsss .common .Pose (rcsss .common .FrankaHandTCPOffset ()),
226241 sim_gui = True ,
242+ truncate_on_collision = True ,
227243 )
228244 if max_relative_movement is not None :
229245 env = RelativeActionSpace (env , max_mov = max_relative_movement , relative_to = relative_to )
230246
231247 return env
248+
249+
250+ class FR3Real (EnvCreator ):
251+ def __call__ ( # type: ignore
252+ self ,
253+ robot_ip : str ,
254+ control_mode : str = "xyzrpy" ,
255+ delta_actions : bool = True ,
256+ camera_config : dict [str , str ] | None = None ,
257+ gripper : bool = True ,
258+ ) -> gym .Env :
259+ camera_set = default_realsense (camera_config )
260+ return fr3_hw_env (
261+ ip = robot_ip ,
262+ camera_set = camera_set ,
263+ control_mode = (
264+ ControlMode .CARTESIAN_TRPY
265+ if control_mode == "xyzrpy"
266+ else ControlMode .JOINTS if control_mode == "joints" else ControlMode .CARTESIAN_TQuart
267+ ),
268+ robot_cfg = default_fr3_hw_robot_cfg (),
269+ collision_guard = None ,
270+ gripper_cfg = default_fr3_hw_gripper_cfg () if gripper else None ,
271+ max_relative_movement = (0.2 , np .deg2rad (45 )) if delta_actions else None ,
272+ relative_to = RelativeTo .LAST_STEP ,
273+ )
274+
275+
276+ class FR3SimplePickUpSim (EnvCreator ):
277+ def __call__ ( # type: ignore
278+ self ,
279+ render_mode : str = "human" ,
280+ control_mode : str = "xyzrpy" ,
281+ resolution : tuple [int , int ] | None = None ,
282+ frame_rate : int = 10 ,
283+ delta_actions : bool = True ,
284+ ) -> gym .Env :
285+ if resolution is None :
286+ resolution = (256 , 256 )
287+
288+ cameras = {
289+ "wrist" : SimCameraConfig (identifier = "eye-in-hand_0" , type = int (CameraType .fixed )),
290+ "bird_eye" : SimCameraConfig (identifier = "bird-eye-cam" , type = int (CameraType .fixed )),
291+ "side" : SimCameraConfig (identifier = "side_view" , type = int (CameraType .fixed )),
292+ "right_side" : SimCameraConfig (identifier = "right_side" , type = int (CameraType .fixed )),
293+ "left_side" : SimCameraConfig (identifier = "left_side" , type = int (CameraType .fixed )),
294+ "front" : SimCameraConfig (identifier = "front" , type = int (CameraType .fixed )),
295+ }
296+
297+ camera_cfg = SimCameraSetConfig (
298+ cameras = cameras ,
299+ resolution_width = resolution [0 ],
300+ resolution_height = resolution [1 ],
301+ frame_rate = frame_rate ,
302+ physical_units = True ,
303+ )
304+ env_rel = fr3_sim_env (
305+ control_mode = (
306+ ControlMode .CARTESIAN_TRPY
307+ if control_mode == "xyzrpy"
308+ else ControlMode .JOINTS if control_mode == "joints" else ControlMode .CARTESIAN_TQuart
309+ ),
310+ robot_cfg = default_fr3_sim_robot_cfg (),
311+ collision_guard = False ,
312+ gripper_cfg = default_fr3_sim_gripper_cfg (),
313+ camera_set_cfg = camera_cfg ,
314+ max_relative_movement = (0.2 , np .deg2rad (45 )) if delta_actions else None ,
315+ relative_to = RelativeTo .LAST_STEP ,
316+ mjcf = "fr3_simple_pick_up" ,
317+ sim_wrapper = RandomCubePos ,
318+ )
319+ env_rel = FR3SimplePickUpSimSuccessWrapper (env_rel )
320+ if render_mode == "human" :
321+ env_rel .get_wrapper_attr ("sim" ).open_gui ()
322+
323+ return env_rel
0 commit comments