gpue commited on
Commit
8f3af53
·
1 Parent(s): d1b2f67

Refactor UR5 environment to enhance target setting and joint control

Browse files

- Updated target position and orientation initialization to use forward kinematics from the home pose.
- Enhanced `set_target` and `set_target_orientation` methods to include an option for updating joint targets via inverse kinematics.
- Modified `set_joint_positions` to optionally update the IK target based on the new end-effector pose.
- Improved the reset logic to compute the target from the end-effector's position and orientation after initialization.

Files changed (1) hide show
  1. robots/ur5/ur5_env.py +78 -15
robots/ur5/ur5_env.py CHANGED
@@ -110,11 +110,18 @@ class UR5Env(gym.Env):
110
  arm_joint_names=self.JOINT_NAMES
111
  )
112
 
113
- # Target position for IK - matching the new home pose
114
- self._target_pos = np.array([0.4, 0.0, 0.4], dtype=np.float32)
115
- # Target orientation as Euler angles (roll, pitch, yaw) in radians
116
- # Default: gripper pointing down (-pi/2 pitch)
117
- self._target_euler = np.array([0.0, np.pi/2, 0.0], dtype=np.float32)
 
 
 
 
 
 
 
118
  # Whether to use orientation in IK (user can toggle this)
119
  self._use_orientation = True
120
  # Gripper target: Robotiq 2F-85 uses 0=open, 255=closed
@@ -125,20 +132,49 @@ class UR5Env(gym.Env):
125
  # Direct joint targets (used when control_mode is 'joint')
126
  self._joint_targets = self.DEFAULT_HOME_POSE.copy()
127
 
128
- def set_target(self, x: float, y: float, z: float):
129
- """Set target position for IK controller."""
 
 
 
 
 
130
  self._target_pos = np.array([x, y, z], dtype=np.float32)
131
  # Update mocap body position for visualization
132
  self.data.mocap_pos[0] = self._target_pos
133
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  def get_target(self):
135
  """Get current target position."""
136
  return self._target_pos.copy()
137
 
138
- def set_target_orientation(self, roll: float, pitch: float, yaw: float):
139
- """Set target orientation as Euler angles (radians)."""
 
 
 
 
 
140
  self._target_euler = np.array([roll, pitch, yaw], dtype=np.float32)
141
 
 
 
 
 
 
 
 
142
  def get_target_orientation(self):
143
  """Get target orientation as Euler angles (radians)."""
144
  return self._target_euler.copy()
@@ -168,17 +204,36 @@ class UR5Env(gym.Env):
168
  """Get current control mode."""
169
  return self._control_mode
170
 
171
- def set_joint_positions(self, positions):
172
  """Set target joint positions directly (bypasses IK).
173
 
174
  Args:
175
  positions: Array of 6 joint angles in radians
 
176
  """
177
  positions = np.array(positions, dtype=np.float32)
178
  # Clamp to joint limits
179
  positions = np.clip(positions, self.action_space.low[:6], self.action_space.high[:6])
180
  self._joint_targets = positions
181
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
  def get_joint_positions(self):
183
  """Get current joint positions."""
184
  return self.data.qpos[:6].copy()
@@ -250,13 +305,21 @@ class UR5Env(gym.Env):
250
  self.data.qpos[box_qpos_start:box_qpos_start+3] = [0.5, 0.2, 0.45]
251
  self.data.qpos[box_qpos_start+3:box_qpos_start+7] = [1, 0, 0, 0]
252
 
253
- # Reset target
254
- self._target_pos = np.array([0.4, 0.0, 0.4], dtype=np.float32)
255
- self._target_euler = np.array([0.0, np.pi/2, 0.0], dtype=np.float32) # Gripper pointing down
 
 
 
 
 
 
 
 
 
256
  self.data.mocap_pos[0] = self._target_pos
257
  self._gripper_target = 0.0 # Open gripper
258
-
259
- mujoco.mj_forward(self.model, self.data)
260
 
261
  self.steps = 0
262
 
 
110
  arm_joint_names=self.JOINT_NAMES
111
  )
112
 
113
+ # Set initial joint positions to home pose and compute FK
114
+ self.data.qpos[:6] = self.DEFAULT_HOME_POSE.copy()
115
+ self.data.ctrl[:6] = self.DEFAULT_HOME_POSE.copy()
116
+ mujoco.mj_forward(self.model, self.data)
117
+
118
+ # Target position/orientation from FK of home pose
119
+ ee_pos = self.get_end_effector_pos()
120
+ ee_quat = self.get_end_effector_quat()
121
+ self._target_pos = ee_pos.astype(np.float32)
122
+ roll, pitch, yaw = IKController.quat_to_euler(ee_quat)
123
+ self._target_euler = np.array([roll, pitch, yaw], dtype=np.float32)
124
+
125
  # Whether to use orientation in IK (user can toggle this)
126
  self._use_orientation = True
127
  # Gripper target: Robotiq 2F-85 uses 0=open, 255=closed
 
132
  # Direct joint targets (used when control_mode is 'joint')
133
  self._joint_targets = self.DEFAULT_HOME_POSE.copy()
134
 
135
+ def set_target(self, x: float, y: float, z: float, update_joint_targets=True):
136
+ """Set target position for IK controller.
137
+
138
+ Args:
139
+ x, y, z: Target position in meters
140
+ update_joint_targets: If True, compute IK and update joint targets
141
+ """
142
  self._target_pos = np.array([x, y, z], dtype=np.float32)
143
  # Update mocap body position for visualization
144
  self.data.mocap_pos[0] = self._target_pos
145
 
146
+ # Update joint targets via IK
147
+ if update_joint_targets:
148
+ if self._use_orientation:
149
+ target_quat = IKController.euler_to_quat(
150
+ self._target_euler[0], self._target_euler[1], self._target_euler[2]
151
+ )
152
+ self._joint_targets = self.controller.compute_ik_with_orientation(
153
+ self._target_pos, target_quat
154
+ )
155
+ else:
156
+ self._joint_targets = self.controller.compute_ik(self._target_pos)
157
+
158
  def get_target(self):
159
  """Get current target position."""
160
  return self._target_pos.copy()
161
 
162
+ def set_target_orientation(self, roll: float, pitch: float, yaw: float, update_joint_targets=True):
163
+ """Set target orientation as Euler angles (radians).
164
+
165
+ Args:
166
+ roll, pitch, yaw: Target orientation in radians
167
+ update_joint_targets: If True, compute IK and update joint targets
168
+ """
169
  self._target_euler = np.array([roll, pitch, yaw], dtype=np.float32)
170
 
171
+ # Update joint targets via IK
172
+ if update_joint_targets and self._use_orientation:
173
+ target_quat = IKController.euler_to_quat(roll, pitch, yaw)
174
+ self._joint_targets = self.controller.compute_ik_with_orientation(
175
+ self._target_pos, target_quat
176
+ )
177
+
178
  def get_target_orientation(self):
179
  """Get target orientation as Euler angles (radians)."""
180
  return self._target_euler.copy()
 
204
  """Get current control mode."""
205
  return self._control_mode
206
 
207
+ def set_joint_positions(self, positions, update_ik_target=True):
208
  """Set target joint positions directly (bypasses IK).
209
 
210
  Args:
211
  positions: Array of 6 joint angles in radians
212
+ update_ik_target: If True, update IK target to match new EE pose
213
  """
214
  positions = np.array(positions, dtype=np.float32)
215
  # Clamp to joint limits
216
  positions = np.clip(positions, self.action_space.low[:6], self.action_space.high[:6])
217
  self._joint_targets = positions
218
 
219
+ # Update IK target to match the FK of new joint positions
220
+ if update_ik_target:
221
+ # Temporarily set joints to compute FK
222
+ old_qpos = self.data.qpos[:6].copy()
223
+ self.data.qpos[:6] = positions
224
+ mujoco.mj_forward(self.model, self.data)
225
+
226
+ # Get EE pose from FK
227
+ ee_pos = self.get_end_effector_pos()
228
+ ee_quat = self.get_end_effector_quat()
229
+ self._target_pos = ee_pos.astype(np.float32)
230
+ roll, pitch, yaw = IKController.quat_to_euler(ee_quat)
231
+ self._target_euler = np.array([roll, pitch, yaw], dtype=np.float32)
232
+ self.data.mocap_pos[0] = self._target_pos
233
+
234
+ # Restore original qpos (simulation will move towards target)
235
+ self.data.qpos[:6] = old_qpos
236
+
237
  def get_joint_positions(self):
238
  """Get current joint positions."""
239
  return self.data.qpos[:6].copy()
 
305
  self.data.qpos[box_qpos_start:box_qpos_start+3] = [0.5, 0.2, 0.45]
306
  self.data.qpos[box_qpos_start+3:box_qpos_start+7] = [1, 0, 0, 0]
307
 
308
+ # Compute forward kinematics to get EE pose from home joints
309
+ mujoco.mj_forward(self.model, self.data)
310
+
311
+ # Set target to current EE position (computed from FK)
312
+ ee_pos = self.get_end_effector_pos()
313
+ ee_quat = self.get_end_effector_quat()
314
+ self._target_pos = ee_pos.astype(np.float32)
315
+
316
+ # Convert EE quaternion to euler for target orientation
317
+ roll, pitch, yaw = IKController.quat_to_euler(ee_quat)
318
+ self._target_euler = np.array([roll, pitch, yaw], dtype=np.float32)
319
+
320
  self.data.mocap_pos[0] = self._target_pos
321
  self._gripper_target = 0.0 # Open gripper
322
+ self._joint_targets = self.DEFAULT_HOME_POSE.copy()
 
323
 
324
  self.steps = 0
325