@@ -36,6 +36,17 @@ class RewardConfig:
3636 reset_z_threshold : float = 0.125 # metres
3737
3838
39+ @dataclass
40+ class obs_cfg :
41+ obs_dict = {
42+ "dof_pos_norm" : 16 ,
43+ "targets" : 16 ,
44+ "ball_pos" : 3 ,
45+ } # 'obs_name': dim
46+ actor_obs = ["dof_pos_norm" , "targets" , "ball_pos" ]
47+ num_lag_steps : int = 3
48+
49+
3950@dataclass
4051class DomainRandConfig :
4152 # Small random perturbation added to each joint at reset (rad).
@@ -53,6 +64,7 @@ class AllegroRotationCfg(AllegroBaseCfg):
5364 max_episode_seconds : float = 20.0 # same as HORA
5465 reward_config : RewardConfig = field (default_factory = RewardConfig )
5566 domain_rand : DomainRandConfig = field (default_factory = DomainRandConfig )
67+ obs_config : obs_cfg = field (default_factory = obs_cfg )
5668
5769 # World-frame unit vector around which to reward rotation.
5870 # Default (+z) = counterclockwise when viewed from above.
@@ -96,10 +108,27 @@ def __init__(self, cfg: AllegroRotationCfg, num_envs: int = 1, backend_type: str
96108 # ── Spaces ──────────────────────────────────────────────────────
97109
98110 def _init_obs_space (self ):
99- # Last 3 timesteps of [dof_pos_norm(16) + targets(16) + ball_pos(3)] = 3 * 35 = 105
111+ obs_cfg = self ._cfg .obs_config
112+ num_obs_per_step = sum (obs_cfg .obs_dict .values ())
113+ num_obs = obs_cfg .num_lag_steps * num_obs_per_step
100114 self ._observation_space = gym .spaces .Box (
101- low = - np .inf , high = np .inf , shape = (105 ,), dtype = float
115+ low = - np .inf , high = np .inf , shape = (num_obs ,), dtype = float
102116 )
117+ self .actor_indices = self ._get_actor_indices ()
118+
119+ def _get_actor_indices (self ):
120+ s = 0
121+ indices = []
122+ for i in self ._cfg .obs_config .actor_obs :
123+ s = 0
124+ for k , v in self ._cfg .obs_config .obs_dict .items ():
125+ if k == i :
126+ for q in range (s , s + v ):
127+ indices .append (q )
128+ s += v
129+ break
130+ s += v
131+ return indices
103132
104133 @property
105134 def observation_space (self ) -> gym .spaces .Box :
@@ -212,7 +241,15 @@ def update_state(self, state: NpEnvState) -> NpEnvState:
212241 current_obs = np .concatenate ([dof_pos_norm , targets , ball_pos ], axis = 1 ) # (N, 35)
213242
214243 obs_lag_history = state .info .get (
215- "obs_lag_history" , np .zeros ((self ._num_envs , 3 , 35 ), dtype = self ._np_dtype )
244+ "obs_lag_history" ,
245+ np .zeros (
246+ (
247+ self ._num_envs ,
248+ self ._cfg .obs_config .num_lag_steps ,
249+ sum (self ._cfg .obs_config .obs_dict .values ()),
250+ ),
251+ dtype = self ._np_dtype ,
252+ ),
216253 )
217254 obs_lag_history [:, :- 1 ] = obs_lag_history [:, 1 :]
218255 obs_lag_history [:, - 1 ] = current_obs
@@ -249,8 +286,11 @@ def _compute_rewards(self, state: NpEnvState) -> tuple:
249286
250287 def _get_obs (self , info : dict ) -> np .ndarray :
251288 """Extract observation from info. Pure function - does not modify state."""
289+ num_obs_per_step = sum (self ._cfg .obs_config .obs_dict .values ())
290+ num_lag_steps = self ._cfg .obs_config .num_lag_steps
252291 obs_lag_history = info .get (
253- "obs_lag_history" , np .zeros ((self ._num_envs , 3 , 35 ), dtype = self ._np_dtype )
292+ "obs_lag_history" ,
293+ np .zeros ((self ._num_envs , num_lag_steps , num_obs_per_step ), dtype = self ._np_dtype ),
254294 )
255295 num_envs = obs_lag_history .shape [0 ]
256296 return np .asarray (obs_lag_history .reshape (num_envs , - 1 ))
@@ -323,8 +363,13 @@ def reset(self, env_indices: np.ndarray) -> Tuple[np.ndarray, np.ndarray, dict]:
323363 [dof_pos_norm , init_ctrl , ball_pos_f32 ], axis = 1
324364 ) # (num_reset, 35)
325365 obs_lag_history = np .broadcast_to (
326- init_obs [:, None , :], (num_reset , 3 , 35 )
327- ).copy () # (num_reset, 3, 35)
366+ init_obs [:, None , :],
367+ (
368+ num_reset ,
369+ self ._cfg .obs_config .num_lag_steps ,
370+ sum (self ._cfg .obs_config .obs_dict .values ()),
371+ ),
372+ ).copy () # (num_reset, num_lag_steps, num_obs_per_step)
328373
329374 info = {
330375 "current_actions" : np .zeros ((num_reset , self ._num_action ), dtype = self ._np_dtype ),
0 commit comments