3030# Support for non uniform noise in sensor readings
3131# Support for noisy actions + separate noise_scale for sensor and actuator
3232# rename pos/vel to act/delta_act
33+ # Improve space definitions
34+ # sim_id: ID of the sensor/actuator in the sim
35+ # act_id: ID of the sensor/actuator in the robot_config (hardware) space ==> Rename to hdr_id (robot_config unified different hardware into a single unified hardware space)
36+ # hdr_id: ID of the sensor/actuator in the hardware space (e.g. dynamixel) ==> Rename to adr (This is the address that is used to communicate with the hardware. It is not necessarily the same as the act_id or sim_id.)
3337
3438# NOTE/ GOOD PRACTICES ===========================
3539# nq should be nv
@@ -229,7 +233,14 @@ def hardware_get_sensors(self):
229233
230234
231235 # apply controls to hardware
232- def hardware_apply_controls (self , control , is_reset = False ):
236+ def hardware_apply_controls (self , control , space = 'hdr' , is_reset = False ):
237+ """
238+ control: control vector in hdr or sim space
239+ space: 'hdr' or 'sim' (defaults to 'hdr' as represented in robot_config)
240+ is_reset: if True, reset the hardware to the control values
241+ """
242+
243+ act_id = - 1 # IDs as per the config order
233244 for name , device in self .robot_config .items ():
234245 if 'actuator' in device .keys () and len (device ['actuator' ])> 0 :
235246 if device ['interface' ]['type' ] == 'dynamixel' :
@@ -239,8 +250,10 @@ def hardware_apply_controls(self, control, is_reset=False):
239250 pwm_ctrl = []
240251 pwm_ids = []
241252 for actuator in device ['actuator' ]:
253+ act_id += 1
254+ ctrl = control [actuator ['sim_id' ]] if space == 'sim' else control [act_id ]
242255 # calibrate
243- calib_ctrl = control [ actuator [ 'sim_id' ]] * actuator ['scale' ]+ actuator ['offset' ]
256+ calib_ctrl = ctrl * actuator ['scale' ]+ actuator ['offset' ]
244257 if actuator ['mode' ] == 'Position' :
245258 pos_ids .append (actuator ['hdr_id' ])
246259 pos_ctrl .append (calib_ctrl )
@@ -249,34 +262,26 @@ def hardware_apply_controls(self, control, is_reset=False):
249262 pwm_ctrl .append (calib_ctrl )
250263 else :
251264 print ("ERROR: Mode not found" )
252- raise NotImplemented
265+ raise NotImplementedError ( f"ERROR: Actuator mode { actuator [ 'mode' ] } not found" )
253266 # send controls
254267 if pos_ids :
255268 device ['robot' ].set_des_pos (pos_ids , pos_ctrl )
256269 if pwm_ids :
257270 device ['robot' ].set_des_pwm (pwm_ids , pwm_ctrl )
258271
259- elif device ['interface' ]['type' ] == 'franka' :
260- franka_des_pos = []
261- for actuator in device ['actuator' ]:
262- # calibrate
263- franka_des_pos .append (control [actuator ['sim_id' ]]* actuator ['scale' ]+ actuator ['offset' ])
264- if is_reset :
265- device ['robot' ].reset (franka_des_pos )
266- else :
267- device ['robot' ].apply_commands (franka_des_pos )
268-
269- elif device ['interface' ]['type' ] == 'robotiq' :
270- robotiq_des_pos = []
272+ elif device ['interface' ]['type' ] in ['franka' , 'robotiq' ]:
273+ des_pos = []
271274 for actuator in device ['actuator' ]:
275+ act_id += 1
276+ ctrl = control [actuator ['sim_id' ]] if space == 'sim' else control [act_id ]
272277 # calibrate
273- robotiq_des_pos .append (control [ actuator [ 'sim_id' ]] * actuator ['scale' ]+ actuator ['offset' ])
278+ des_pos .append (ctrl * actuator ['scale' ]+ actuator ['offset' ])
274279 if is_reset :
275- device ['robot' ].reset (robotiq_des_pos [ 0 ] )
280+ device ['robot' ].reset (des_pos )
276281 else :
277- device ['robot' ].apply_commands (robotiq_des_pos [ 0 ] )
282+ device ['robot' ].apply_commands (des_pos )
278283 else :
279- raise NotImplemented ("ERROR: interface not found" )
284+ raise NotImplementedError ("ERROR: interface not found" )
280285
281286
282287 # close hardware
@@ -561,7 +566,7 @@ def normalize_actions(self, controls, out_space='sim', unnormalize=False):
561566 Recover actions from unit space to absolute space; if unnormalize==True
562567 in_space for controls has to be 'sim'
563568 """
564- act_id = - 1
569+ act_id = - 1 # IDs as per the config order
565570 controls_out = controls .copy ()
566571 for name , device in self .robot_config .items ():
567572 if name == "default_robot" :
@@ -614,7 +619,7 @@ def process_actuator(self, controls, step_duration,
614619 """
615620 # last_obs = self.get_sensor_from_cache(-1)
616621 processed_controls = controls .copy ()
617- act_id = - 1
622+ act_id = - 1 # IDs as per the config order
618623 for name , device in self .robot_config .items ():
619624 if name == "default_robot" :
620625 if self ._act_mode == "pos" :
@@ -685,7 +690,7 @@ def step(self, ctrl_desired, step_duration, ctrl_normalized=True, realTimeSim=Fa
685690
686691 # Send controls to the robot
687692 if self .is_hardware :
688- self .hardware_apply_controls (ctrl_feasible )
693+ self .hardware_apply_controls (ctrl_feasible , space = robot_type )
689694 if render_cbk :
690695 render_cbk ()
691696 else :
0 commit comments