@@ -40,8 +40,8 @@ def reset_obstacles_with_individual_ranges(
4040
4141 Walls are positioned at fixed locations based on their configuration ratios. Obstacles
4242 are randomly placed within their designated zones, with the number of active obstacles
43- determined by the curriculum difficulty level. Inactive obstacles are moved far below
44- the scene (-1000m in Z) to effectively remove them from the environment .
43+ determined by the curriculum difficulty level. Inactive obstacles are parked at distinct
44+ locations far below the scene to avoid overlapping collision geometry .
4545
4646 The curriculum scaling works as:
4747 num_obstacles = min + (difficulty / max_difficulty) * (max - min)
@@ -70,9 +70,9 @@ def reset_obstacles_with_individual_ranges(
7070 """
7171 obstacles : RigidObjectCollection = env .scene [asset_cfg .name ]
7272
73- num_objects = obstacles .num_objects
73+ num_objects = obstacles .num_bodies
7474 num_envs = len (env_ids )
75- object_names = obstacles .object_names
75+ object_names = obstacles .body_names
7676
7777 # Get difficulty levels per environment
7878 if use_curriculum :
@@ -101,89 +101,84 @@ def reset_obstacles_with_individual_ranges(
101101 wall_names = list (wall_configs .keys ())
102102 obstacle_types = list (obstacle_configs .values ())
103103 env_size_t = torch .tensor (env_size , device = env .device )
104-
105- # place walls
106- for wall_name , wall_cfg in wall_configs .items ():
107- if wall_name in object_names :
108- wall_idx = object_names .index (wall_name )
109-
110- min_ratio = torch .tensor (wall_cfg .center_ratio_min , device = env .device )
111- max_ratio = torch .tensor (wall_cfg .center_ratio_max , device = env .device )
112-
113- if torch .allclose (min_ratio , max_ratio ):
114- center_ratios = min_ratio .unsqueeze (0 ).repeat (num_envs , 1 )
115- else :
116- ratios = torch .rand (num_envs , 3 , device = env .device )
117- center_ratios = ratios * (max_ratio - min_ratio ) + min_ratio
118-
119- positions = (center_ratios - 0.5 ) * env_size_t
120- positions [:, 2 ] += ground_offset
121- positions += env .scene .env_origins [env_ids ]
122-
123- all_poses [:, wall_idx , 0 :3 ] = positions
124- all_poses [:, wall_idx , 3 :7 ] = torch .tensor ([1.0 , 0.0 , 0.0 , 0.0 ], device = env .device ).repeat (num_envs , 1 )
104+ identity_quat = torch .tensor ([0.0 , 0.0 , 0.0 , 1.0 ], device = env .device )
105+ all_poses [..., 3 :7 ] = identity_quat
106+
107+ # Place walls
108+ wall_entries = [(object_names .index (name ), cfg ) for name , cfg in wall_configs .items () if name in object_names ]
109+ if wall_entries :
110+ wall_indices = [entry [0 ] for entry in wall_entries ]
111+ wall_min_ratios = torch .tensor (
112+ [entry [1 ].center_ratio_min for entry in wall_entries ], dtype = torch .float32 , device = env .device
113+ )
114+ wall_max_ratios = torch .tensor (
115+ [entry [1 ].center_ratio_max for entry in wall_entries ], dtype = torch .float32 , device = env .device
116+ )
117+ wall_center_ratios = wall_min_ratios .unsqueeze (0 ).expand (num_envs , - 1 , - 1 ).clone ()
118+ variable_wall_indices = [
119+ i
120+ for i , (_ , wall_cfg ) in enumerate (wall_entries )
121+ if wall_cfg .center_ratio_min != wall_cfg .center_ratio_max
122+ ]
123+ if variable_wall_indices :
124+ wall_ratios = torch .rand (num_envs , len (variable_wall_indices ), 3 , device = env .device )
125+ wall_center_ratios [:, variable_wall_indices ] = (
126+ wall_ratios
127+ * (wall_max_ratios [variable_wall_indices ] - wall_min_ratios [variable_wall_indices ])
128+ + wall_min_ratios [variable_wall_indices ]
129+ )
130+ wall_positions = (wall_center_ratios - 0.5 ) * env_size_t
131+ wall_positions [..., 2 ] += ground_offset
132+ wall_positions += env .scene .env_origins [env_ids ].unsqueeze (1 )
133+ all_poses [:, wall_indices , 0 :3 ] = wall_positions
125134
126135 # Get obstacle indices
127136 obstacle_indices = [idx for idx , name in enumerate (object_names ) if name not in wall_names ]
128137
129138 if len (obstacle_indices ) == 0 :
130- obstacles .write_object_pose_to_sim ( all_poses , env_ids = env_ids )
131- obstacles .write_object_velocity_to_sim ( all_velocities , env_ids = env_ids )
139+ obstacles .write_body_pose_to_sim_index ( body_poses = all_poses , env_ids = env_ids )
140+ obstacles .write_body_com_velocity_to_sim_index ( body_velocities = all_velocities , env_ids = env_ids )
132141 return
133142
134- # Determine which obstacles are active per env
135- active_masks = torch .zeros (num_envs , len (obstacle_indices ), dtype = torch .bool , device = env .device )
136- for env_idx in range (num_envs ):
137- num_active = obstacles_per_env [env_idx ].item ()
138- perm = torch .randperm (len (obstacle_indices ), device = env .device )[:num_active ]
139- active_masks [env_idx , perm ] = True
140-
141- # place obstacles
142- for obj_list_idx in range (len (obstacle_indices )):
143- obj_idx = obstacle_indices [obj_list_idx ]
144-
145- # Which envs need this obstacle?
146- envs_need_obstacle = active_masks [:, obj_list_idx ]
147-
148- if not envs_need_obstacle .any ():
149- # Move all to -1000
150- all_poses [:, obj_idx , 0 :3 ] = env .scene .env_origins [env_ids ] + torch .tensor (
151- [0.0 , 0.0 , - 1000.0 ], device = env .device
152- )
153- all_poses [:, obj_idx , 3 :7 ] = torch .tensor ([1.0 , 0.0 , 0.0 , 0.0 ], device = env .device )
154- continue
155-
156- # Get obstacle config
157- config_idx = obj_list_idx % len (obstacle_types )
158- obs_cfg = obstacle_types [config_idx ]
159-
160- min_ratio = torch .tensor (obs_cfg .center_ratio_min , device = env .device )
161- max_ratio = torch .tensor (obs_cfg .center_ratio_max , device = env .device )
162-
163- # sample object positions
164- num_active_envs = envs_need_obstacle .sum ().item ()
165- ratios = torch .rand (num_active_envs , 3 , device = env .device )
166- positions = (ratios * (max_ratio - min_ratio ) + min_ratio - 0.5 ) * env_size_t
167- positions [:, 2 ] += ground_offset
168-
169- # Add env origins
170- active_env_indices = torch .where (envs_need_obstacle )[0 ]
171- positions += env .scene .env_origins [env_ids [active_env_indices ]]
172-
173- # Generate quaternions
174- quats = math_utils .random_orientation (num_envs , device = env .device )
175-
176- # Write poses
177- all_poses [envs_need_obstacle , obj_idx , 0 :3 ] = positions
178- all_poses [envs_need_obstacle , obj_idx , 3 :7 ] = quats [envs_need_obstacle ]
179-
180- # Move inactive obstacles far away
181- inactive = ~ envs_need_obstacle
182- all_poses [inactive , obj_idx , 0 :3 ] = env .scene .env_origins [env_ids [inactive ]] + torch .tensor (
183- [0.0 , 0.0 , - 1000.0 ], device = env .device
184- )
185- all_poses [inactive , obj_idx , 3 :7 ] = torch .tensor ([1.0 , 0.0 , 0.0 , 0.0 ], device = env .device )
143+ num_obstacles = len (obstacle_indices )
144+
145+ # Select the requested number of unique obstacles per environment
146+ random_order = torch .argsort (torch .rand (num_envs , num_obstacles , device = env .device ), dim = 1 )
147+ active_by_rank = torch .arange (num_obstacles , device = env .device ).unsqueeze (0 ) < obstacles_per_env .unsqueeze (1 )
148+ active_masks = torch .zeros (num_envs , num_obstacles , dtype = torch .bool , device = env .device )
149+ active_masks .scatter_ (1 , random_order , active_by_rank )
150+
151+ # Sample every obstacle in one operation.
152+ obstacle_min_ratios = torch .tensor (
153+ [obstacle_types [i % len (obstacle_types )].center_ratio_min for i in range (num_obstacles )],
154+ dtype = torch .float32 ,
155+ device = env .device ,
156+ )
157+ obstacle_max_ratios = torch .tensor (
158+ [obstacle_types [i % len (obstacle_types )].center_ratio_max for i in range (num_obstacles )],
159+ dtype = torch .float32 ,
160+ device = env .device ,
161+ )
162+ obstacle_ratios = torch .rand (num_envs , num_obstacles , 3 , device = env .device )
163+ obstacle_positions = (
164+ obstacle_ratios * (obstacle_max_ratios - obstacle_min_ratios ) + obstacle_min_ratios - 0.5
165+ ) * env_size_t
166+ obstacle_positions [..., 2 ] += ground_offset
167+ obstacle_positions += env .scene .env_origins [env_ids ].unsqueeze (1 )
168+
169+ # Inactive samples are discarded
170+ inactive_positions = env .scene .env_origins [env_ids ].unsqueeze (1 ).expand (- 1 , num_obstacles , - 1 ).clone ()
171+ inactive_positions [..., 2 ] += - 1000.0 - 5.0 * torch .arange (num_obstacles , device = env .device )
172+ obstacle_positions = torch .where (active_masks .unsqueeze (- 1 ), obstacle_positions , inactive_positions )
173+
174+ obstacle_quats = math_utils .random_orientation (num_envs * num_obstacles , device = env .device ).view (
175+ num_envs , num_obstacles , 4
176+ )
177+ obstacle_quats = torch .where (active_masks .unsqueeze (- 1 ), obstacle_quats , identity_quat )
178+
179+ all_poses [:, obstacle_indices , 0 :3 ] = obstacle_positions
180+ all_poses [:, obstacle_indices , 3 :7 ] = obstacle_quats
186181
187182 # Write to sim
188- obstacles .write_object_pose_to_sim ( all_poses , env_ids = env_ids )
189- obstacles .write_object_velocity_to_sim ( all_velocities , env_ids = env_ids )
183+ obstacles .write_body_pose_to_sim_index ( body_poses = all_poses , env_ids = env_ids )
184+ obstacles .write_body_com_velocity_to_sim_index ( body_velocities = all_velocities , env_ids = env_ids )
0 commit comments