1
1
from __future__ import annotations
2
2
import math
3
3
import torch
4
- from dataclasses import MISSING
5
4
from collections .abc import Sequence
6
5
7
6
import omni .isaac .lab .sim as sim_utils
8
- import omni .isaac .lab .utils .math as math_utils
9
7
from omni .isaac .lab .actuators .actuator_cfg import ImplicitActuatorCfg
10
8
from omni .isaac .lab .markers import VisualizationMarkersCfg , VisualizationMarkers
11
9
from omni .isaac .lab .assets import Articulation , DeformableObject , ArticulationCfg , DeformableObjectCfg , RigidObjectCfg , RigidObject
12
10
from omni .isaac .lab .envs import DirectRLEnv , DirectRLEnvCfg
13
11
from omni .isaac .lab .scene import InteractiveSceneCfg
14
12
from omni .isaac .lab .sim import SimulationCfg
15
- from omni .isaac .lab .sim .spawners .from_files import GroundPlaneCfg , spawn_ground_plane , UsdFileCfg
13
+ from omni .isaac .lab .sim .spawners .from_files import GroundPlaneCfg , spawn_ground_plane
16
14
from omni .isaac .lab .utils import configclass
15
+ from omni .isaac .lab .utils .math import subtract_frame_transforms
17
16
18
17
from omni .isaac .lab .utils .assets import ISAAC_NUCLEUS_DIR
19
- from omni .isaac .lab_assets .franka import FRANKA_PANDA_CFG
20
18
21
19
CUBE_SIZE = 0.1
22
- CUBE_X_MIN , CUBE_X_MAX = 0.0 , 1.0
23
- CUBE_Y_MIN , CUBE_Y_MAX = - 0.45 , 0.45
20
+ SPAWN_X_BOUNDS = (0.05 , 0.90 )
21
+ SPAWN_Y_BOUNDS = (- 0.42 , 0.42 )
22
+ SPAWN_Z_LEVEL = 1.0
24
23
25
24
# TODO: Edit GPU settings for softbody contact buffer size
26
25
# TODO: mess with deformable object settings
27
- # TODO: Make sure cube spawns on table
28
26
# TODO: Add some way to detect if cube is in container
29
27
30
- def get_robot () -> ArticulationCfg :
31
- return ArticulationCfg (
28
+ @configclass
29
+ class DeformableCubeEnvCfg (DirectRLEnvCfg ):
30
+ num_envs = 4
31
+ env_spacing = 3.0
32
+ dt = 1 / 120
33
+ observation_space = 15
34
+ action_space = 9
35
+ state_space = 0
36
+ action_scale = 7.5
37
+
38
+ # env
39
+ decimation = 1
40
+ episode_length_s = 5.0
41
+
42
+ # simulation
43
+ sim : SimulationCfg = SimulationCfg (dt = dt , render_interval = decimation )
44
+ scene : InteractiveSceneCfg = InteractiveSceneCfg (
45
+ num_envs = num_envs ,
46
+ env_spacing = env_spacing ,
47
+ replicate_physics = False ,
48
+ )
49
+
50
+ # entities
51
+ table_cfg : RigidObjectCfg = RigidObjectCfg (
52
+ prim_path = "/World/envs/env_.*/Table" ,
53
+ spawn = sim_utils .UsdFileCfg (
54
+ usd_path = f"{ ISAAC_NUCLEUS_DIR } /Props/Mounts/SeattleLabTable/table_instanceable.usd" ,
55
+ rigid_props = sim_utils .RigidBodyPropertiesCfg (
56
+ disable_gravity = False ,
57
+ ),
58
+ collision_props = sim_utils .CollisionPropertiesCfg (
59
+ collision_enabled = True ,
60
+ ),
61
+ ),
62
+ init_state = RigidObjectCfg .InitialStateCfg (
63
+ pos = (0.5 , 0.0 , 1.0 ),
64
+ rot = (0.707 , 0.0 , 0.0 , 0.707 )
65
+ ),
66
+ )
67
+
68
+ robot_cfg : ArticulationCfg = ArticulationCfg (
32
69
prim_path = "/World/envs/env_.*/Robot" ,
33
70
spawn = sim_utils .UsdFileCfg (
34
71
usd_path = f"{ ISAAC_NUCLEUS_DIR } /Robots/Franka/franka_instanceable.usd" ,
@@ -80,8 +117,7 @@ def get_robot() -> ArticulationCfg:
80
117
},
81
118
)
82
119
83
- def get_object () -> DeformableObjectCfg :
84
- return DeformableObjectCfg (
120
+ object_cfg : DeformableObjectCfg = DeformableObjectCfg (
85
121
prim_path = "/World/envs/env_.*/Cube" ,
86
122
spawn = sim_utils .MeshCuboidCfg (
87
123
size = (CUBE_SIZE , CUBE_SIZE , CUBE_SIZE ),
@@ -97,12 +133,11 @@ def get_object() -> DeformableObjectCfg:
97
133
youngs_modulus = 1e5
98
134
),
99
135
),
100
- init_state = DeformableObjectCfg .InitialStateCfg (pos = (0.0 , 0.0 , 1.0 + CUBE_SIZE / 1.9 )),
136
+ init_state = DeformableObjectCfg .InitialStateCfg (pos = (0.0 , 0.0 , SPAWN_Z_LEVEL + CUBE_SIZE / 1.9 )),
101
137
debug_vis = True ,
102
138
)
103
139
104
- def get_container () -> RigidObjectCfg :
105
- return RigidObjectCfg (
140
+ container_cfg : RigidObjectCfg = RigidObjectCfg (
106
141
prim_path = "/World/envs/env_.*/Container" ,
107
142
spawn = sim_utils .UsdFileCfg (
108
143
usd_path = f"{ ISAAC_NUCLEUS_DIR } /Props/KLT_Bin/small_KLT_visual_collision.usd" ,
@@ -121,52 +156,6 @@ def get_container() -> RigidObjectCfg:
121
156
),
122
157
)
123
158
124
- def get_table () -> RigidObjectCfg :
125
- return RigidObjectCfg (
126
- prim_path = "/World/envs/env_.*/Table" ,
127
- spawn = sim_utils .UsdFileCfg (
128
- usd_path = f"{ ISAAC_NUCLEUS_DIR } /Props/Mounts/SeattleLabTable/table_instanceable.usd" ,
129
- rigid_props = sim_utils .RigidBodyPropertiesCfg (
130
- disable_gravity = False ,
131
- ),
132
- collision_props = sim_utils .CollisionPropertiesCfg (
133
- collision_enabled = True ,
134
- ),
135
- ),
136
- init_state = RigidObjectCfg .InitialStateCfg (
137
- pos = (0.5 , 0.0 , 1.0 ),
138
- rot = (0.707 , 0.0 , 0.0 , 0.707 )
139
- ),
140
- )
141
-
142
-
143
- @configclass
144
- class DeformableCubeEnvCfg (DirectRLEnvCfg ):
145
- num_envs = 32
146
- env_spacing = 3.0
147
- dt = 1 / 120
148
- observation_space = 15
149
- action_space = 9
150
- state_space = 0
151
- action_scale = 7.5
152
-
153
- # env
154
- decimation = 1
155
- episode_length_s = 5.0
156
-
157
- # simulation
158
- sim : SimulationCfg = SimulationCfg (dt = dt , render_interval = decimation )
159
- scene : InteractiveSceneCfg = InteractiveSceneCfg (
160
- num_envs = num_envs ,
161
- env_spacing = env_spacing ,
162
- replicate_physics = False ,
163
- )
164
-
165
- # entities
166
- table_cfg : RigidObjectCfg = get_table ()
167
- robot_cfg : ArticulationCfg = get_robot ()
168
- object_cfg : DeformableObjectCfg = get_object ()
169
- container_cfg : RigidObjectCfg = get_container ()
170
159
171
160
# markers
172
161
table_markers_cfg : VisualizationMarkersCfg = VisualizationMarkersCfg (
@@ -191,14 +180,22 @@ class DeformableCubeEnvCfg(DirectRLEnvCfg):
191
180
}
192
181
)
193
182
194
- def draw_markers (markers : VisualizationMarkers , origins : torch .Tensor ):
183
+
184
+ # draws frame markers to bound the region where objects can spawn
185
+ def draw_spawn_bounds (
186
+ markers : VisualizationMarkers ,
187
+ origins : torch .Tensor ,
188
+ x_bounds : tuple [float , float ],
189
+ y_bounds : tuple [float , float ],
190
+ z_val : float
191
+ ):
195
192
N_envs = origins .shape [0 ]
196
193
197
- # table corner markers
198
- bottom_left_T = torch .tensor ([0.0 , 0.45 , 1.0 ], device = origins .device ).reshape (1 , - 1 )
199
- bottom_right_T = torch .tensor ([0.0 , - 0.45 , 1.0 ], device = origins .device ).reshape (1 , - 1 )
200
- top_left_T = torch .tensor ([1.0 , 0.45 , 1.0 ], device = origins .device ).reshape (1 , - 1 )
201
- top_right_T = torch .tensor ([1.0 , - 0.45 , 1.0 ], device = origins .device ).reshape (1 , - 1 )
194
+ # spawn corner markers
195
+ bottom_left_T = torch .tensor ([x_bounds [ 0 ], y_bounds [ 1 ], z_val ], device = origins .device ).reshape (1 , - 1 )
196
+ bottom_right_T = torch .tensor ([x_bounds [ 0 ], y_bounds [ 0 ], z_val ], device = origins .device ).reshape (1 , - 1 )
197
+ top_left_T = torch .tensor ([x_bounds [ 1 ], y_bounds [ 1 ], z_val ], device = origins .device ).reshape (1 , - 1 )
198
+ top_right_T = torch .tensor ([x_bounds [ 1 ], y_bounds [ 0 ], z_val ], device = origins .device ).reshape (1 , - 1 )
202
199
203
200
bottom_left , bottom_right , top_left , top_right = origins .clone ().repeat (4 , 1 ).reshape (4 , - 1 , 3 ).unbind (0 )
204
201
bottom_left += bottom_left_T
@@ -223,9 +220,6 @@ class DeformableCubeEnv(DirectRLEnv):
223
220
224
221
def __init__ (self , cfg : DeformableCubeEnvCfg , render_mode : str | None = None , ** kwargs ):
225
222
super ().__init__ (cfg , render_mode , ** kwargs )
226
-
227
- self .dt = self .cfg .sim .dt * self .cfg .decimation
228
-
229
223
self .robot_dof_lower_limits = self .robot .data .soft_joint_pos_limits [0 , :, 0 ].to (device = self .device )
230
224
self .robot_dof_upper_limits = self .robot .data .soft_joint_pos_limits [0 , :, 1 ].to (device = self .device )
231
225
@@ -236,14 +230,19 @@ def __init__(self, cfg: DeformableCubeEnvCfg, render_mode: str | None = None, **
236
230
237
231
def _setup_scene (self ):
238
232
self .robot = Articulation (self .cfg .robot_cfg )
233
+ self .scene .articulations ["robot" ] = self .robot
234
+
239
235
self .object = DeformableObject (self .cfg .object_cfg )
240
236
self .container = RigidObject (self .cfg .container_cfg )
237
+
241
238
self .table = RigidObject (self .cfg .table_cfg )
242
239
self .table_markers = VisualizationMarkers (self .cfg .table_markers_cfg )
243
- self .scene .articulations ["robot" ] = self .robot
240
+ draw_spawn_bounds (
241
+ self .table_markers , self .scene .env_origins ,
242
+ SPAWN_X_BOUNDS , SPAWN_Y_BOUNDS , SPAWN_Z_LEVEL
243
+ )
244
244
245
245
spawn_ground_plane (prim_path = "/World/ground" , cfg = GroundPlaneCfg ())
246
- draw_markers (self .table_markers , self .scene .env_origins )
247
246
248
247
# clone, filter, and replicate
249
248
self .scene .clone_environments (copy_from_source = False )
@@ -255,20 +254,30 @@ def _setup_scene(self):
255
254
256
255
def _pre_physics_step (self , actions : torch .Tensor ) -> None :
257
256
self .actions = actions .clone ().clamp (- 1.0 , 1.0 )
258
- targets = self .robot_dof_targets + self .robot_dof_speed_scales * self .dt * self .actions * self .cfg .action_scale
257
+ targets = self .robot_dof_targets + self .robot_dof_speed_scales * self .step_dt * self .actions * self .cfg .action_scale
259
258
self .robot_dof_targets [:] = torch .clamp (targets , self .robot_dof_lower_limits , self .robot_dof_upper_limits )
260
259
261
260
def _apply_action (self ) -> None :
262
261
self .robot .set_joint_position_target (self .robot_dof_targets )
263
262
264
263
def _get_observations (self ) -> dict :
265
- pass
264
+ joint_pos_rel = (self .robot .data .joint_pos - self .robot .data .default_joint_pos ).clone ()
265
+ joint_vel_rel = (self .robot .data .joint_vel - self .robot .data .default_joint_vel ).clone ()
266
+ object_pos , object_quat = subtract_frame_transforms (
267
+ self .robot .data .root_link_state_w [:, :3 ],
268
+ self .robot .data .root_link_state_w [:, 3 :7 ],
269
+ self .object .data .root_pos_w
270
+ )
271
+ container_pos = self .container .data .root_link_pos_w .clone ()
272
+ last_action = self .actions .clone ()
273
+ print (joint_pos_rel .shape , joint_vel_rel .shape , object_pos .shape , object_quat .shape , container_pos .shape , last_action .shape )
266
274
267
275
def _get_rewards (self ) -> torch .Tensor :
268
276
pass
269
277
270
278
def _get_dones (self ) -> tuple [torch .Tensor , torch .Tensor ]:
271
- out_of_bounds = torch .full ((self .cfg .num_envs ,), fill_value = False , dtype = bool )
279
+ self .object .update (self .step_dt )
280
+ out_of_bounds = self .object .data .root_pos_w [:, - 1 ] < 0.5 # if object falls
272
281
time_out = self .episode_length_buf >= self .max_episode_length - 1
273
282
return out_of_bounds , time_out
274
283
@@ -278,8 +287,8 @@ def _reset_idx(self, env_ids: Sequence[int] | None):
278
287
279
288
# reset objects
280
289
x_offset , y_offset = torch .rand (2 , len (env_ids ), 1 , device = self .device )
281
- x_offset = x_offset * (CUBE_X_MAX - CUBE_X_MIN ) + CUBE_X_MIN
282
- y_offset = y_offset * (CUBE_Y_MAX - CUBE_Y_MIN ) + CUBE_Y_MIN
290
+ x_offset = x_offset * (SPAWN_X_BOUNDS [ 1 ] - SPAWN_X_BOUNDS [ 0 ] ) + SPAWN_X_BOUNDS [ 0 ]
291
+ y_offset = y_offset * (SPAWN_Y_BOUNDS [ 1 ] - SPAWN_Y_BOUNDS [ 0 ] ) + SPAWN_Y_BOUNDS [ 0 ]
283
292
pos_t = torch .cat ([x_offset , y_offset , torch .zeros_like (x_offset )], dim = - 1 )
284
293
285
294
quat_t = torch .zeros (len (env_ids ), 4 , device = self .device )
@@ -294,10 +303,4 @@ def _reset_idx(self, env_ids: Sequence[int] | None):
294
303
# reset robots
295
304
joint_pos = self .robot .data .default_joint_pos [env_ids ]
296
305
joint_vel = torch .zeros_like (joint_pos )
297
- # self.robot.set_joint_position_target(joint_pos, env_ids=env_ids)
298
- self .robot .write_joint_state_to_sim (position = joint_pos , velocity = joint_vel , env_ids = env_ids )
299
-
300
- # reset containers
301
- # container_pose = self.container.data.default_root_state[env_ids, :]
302
- # container_pose[:, :3] += self.scene.env_origins
303
- # self.container.write_root_state_to_sim(container_pose, env_ids)
306
+ self .robot .write_joint_state_to_sim (position = joint_pos , velocity = joint_vel , env_ids = env_ids )
0 commit comments