Skip to content

Commit ec1a1e5

Browse files
committed
Fixed clear_motor_control() for better reset() ; small refactoring for clipping qpos in BulletManipulator
1 parent cb6bcbc commit ec1a1e5

File tree

3 files changed

+53
-45
lines changed

3 files changed

+53
-45
lines changed

dedo/data/robots/fetch/fetch.urdf

+5-5
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@
9292
<damping value="30000"/>
9393
</contact>
9494
</link>
95-
<joint name="r_wheel_joint" type="continuous">
95+
<joint name="r_wheel_joint" type="fixed">
9696
<origin rpy="-6.123E-17 0 0" xyz="0.0012914 -0.18738 0.055325" />
9797
<parent link="base_link" />
9898
<child link="r_wheel_link" />
@@ -127,7 +127,7 @@
127127
</contact>
128128

129129
</link>
130-
<joint name="l_wheel_joint" type="continuous">
130+
<joint name="l_wheel_joint" type="fixed">
131131
<origin rpy="-6.123E-17 0 0" xyz="0.0012914 0.18738 0.055325" />
132132
<parent link="base_link" />
133133
<child link="l_wheel_link" />
@@ -155,7 +155,7 @@
155155
</geometry>
156156
</collision>
157157
</link>
158-
<joint name="torso_lift_joint" type="prismatic">
158+
<joint name="torso_lift_joint" type="fixed">
159159
<origin rpy="-6.123E-17 0 0" xyz="-0.086875 0 0.37743" />
160160
<parent link="base_link" />
161161
<child link="torso_lift_link" />
@@ -186,7 +186,7 @@
186186
</geometry>
187187
</collision>
188188
</link>
189-
<joint name="head_pan_joint" type="revolute">
189+
<joint name="head_pan_joint" type="fixed">
190190
<origin rpy="0 0 0" xyz="0.053125 0 0.603001417713939" />
191191
<parent link="torso_lift_link" />
192192
<child link="head_pan_link" />
@@ -214,7 +214,7 @@
214214
</geometry>
215215
</collision>
216216
</link>
217-
<joint name="head_tilt_joint" type="revolute">
217+
<joint name="head_tilt_joint" type="fixed">
218218
<origin rpy="0 0.2617993877991494 0" xyz="0.14253 0 0.057999" />
219219
<parent link="head_pan_link" />
220220
<child link="head_tilt_link" />

dedo/envs/deform_robot_env.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,9 @@ def do_action(self, action, unscaled=False):
111111
tgt_qpos = self.robot.ee_pos_to_qpos(**tgt_kwargs)
112112
n_slack = 1 # use > 1 if robot has trouble reaching the pose
113113
sub_i = 0
114-
ee_th = 0.01
114+
max_diff = 0.02
115115
diff = self.robot.get_qpos() - tgt_qpos
116-
while (diff > ee_th).any():
116+
while (np.abs(diff) > max_diff).any():
117117
self.robot.move_to_qpos(
118118
tgt_qpos, mode=pybullet.POSITION_CONTROL, kp=0.1, kd=1.0)
119119
self.sim.stepSimulation()

dedo/utils/bullet_manipulator.py

+46-38
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,18 @@ def __init__(self, sim, robot_desc_file, ee_joint_name, ee_link_name,
120120
assert(len(self.info.left_arm_jids_lst)==len(left_rest_arm_qpos))
121121
self.rest_qpos[self.info.left_arm_jids_lst] = left_rest_arm_qpos[:]
122122
self.reset()
123+
self.default_ik_args = {
124+
'lowerLimits': self.info.joint_minpos.tolist(),
125+
'upperLimits': self.info.joint_maxpos.tolist(),
126+
'jointRanges': (self.info.joint_maxpos -
127+
self.info.joint_minpos).tolist(),
128+
'restPoses': self.rest_qpos.tolist(),
129+
# Note that large num iterations could slow down compute enough
130+
# s.t. visualizer shows differences in rate of following traj.
131+
'maxNumIterations': 500,
132+
'residualThreshold': 0.005,
133+
# solver=pybullet.IK_SDLS,
134+
}
123135
ee_pos, ee_ori, *_ = self.get_ee_pos_ori_vel()
124136
print('Initialized robot ee at pos', ee_pos,
125137
'euler ori', sin_cos_to_theta(ee_ori),
@@ -148,6 +160,9 @@ def load_robot(self, robot_path, ee_joint_name, ee_link_name,
148160
pybullet.getJointInfo(robot_id, j)
149161
jname = jname.decode("utf-8")
150162
link_name = link_name.decode("utf-8")
163+
# take care of continuous joints
164+
if jhighlim < jlowlim:
165+
jlowlim, jhighlim = -np.pi, np.pi
151166
# print('load jname', jname, 'jtype', jtype, 'link_name', link_name)
152167
if jtype in [pybullet.JOINT_REVOLUTE, pybullet.JOINT_PRISMATIC]:
153168
joint_ids.append(j)
@@ -198,7 +213,7 @@ def reset(self):
198213
self.reset_to_qpos(self.rest_qpos)
199214

200215
def reset_to_qpos(self, qpos):
201-
qpos = np.clip(qpos, self.info.joint_minpos, self.info.joint_maxpos)
216+
qpos = self.clip_qpos(qpos)
202217
for jid in range(self.info.dof):
203218
self.sim.resetJointState(
204219
bodyUniqueId=self.info.robot_id,
@@ -212,7 +227,7 @@ def clear_motor_control(self):
212227
# torque control values this way are hard to reproduce.
213228
self.sim.setJointMotorControlArray(
214229
self.info.robot_id, self.info.joint_ids.tolist(),
215-
pybullet.VELOCITY_CONTROL, forces=[0]*self.info.dof)
230+
pybullet.VELOCITY_CONTROL, targetVelocities=[0]*self.info.dof)
216231
self.sim.setJointMotorControlArray(
217232
self.info.robot_id, self.info.joint_ids.tolist(),
218233
pybullet.TORQUE_CONTROL, forces=[0]*self.info.dof)
@@ -281,18 +296,8 @@ def _ee_pos_to_qpos_raw(self, ee_pos, ee_ori=None, fing_dist=0.0,
281296
qpos = pybullet.calculateInverseKinematics(
282297
self.info.robot_id, self.info.ee_link_id,
283298
targetPosition=ee_pos.tolist(), targetOrientation=ee_quat,
284-
lowerLimits=self.info.joint_minpos.tolist(),
285-
upperLimits=self.info.joint_maxpos.tolist(),
286-
jointRanges=(self.info.joint_maxpos-self.info.joint_minpos).tolist(),
287-
restPoses=self.rest_qpos.tolist(),
288-
maxNumIterations=500, residualThreshold=0.005)
289-
# solver=pybullet.IK_SDLS,
290-
# maxNumIterations=1000, residualThreshold=0.0001)
291-
# Note that large num iterations could slow down the compute enough
292-
# s.t. visualizer shows differences in rate of following traj.
299+
**self.default_ik_args)
293300
qpos = np.array(qpos)
294-
if debug:
295-
print('_ee_pos_to_qpos_raw() qpos from IK', qpos)
296301
for jid in self.info.finger_jids_lst:
297302
qpos[jid] = np.clip( # finger info (not set by IK)
298303
fing_dist/2.0, self.info.joint_minpos[jid],
@@ -308,12 +313,7 @@ def _ee_pos_to_qpos_raw(self, ee_pos, ee_ori=None, fing_dist=0.0,
308313
left_qpos = np.array(pybullet.calculateInverseKinematics(
309314
self.info.robot_id, self.info.left_ee_link_id,
310315
left_ee_pos.tolist(), left_ee_quat,
311-
lowerLimits=self.info.joint_minpos.tolist(),
312-
upperLimits=self.info.joint_maxpos.tolist(),
313-
jointRanges=(self.info.joint_maxpos -
314-
self.info.joint_minpos).tolist(),
315-
restPoses=self.rest_qpos.tolist(),
316-
maxNumIterations=500, residualThreshold=0.005))
316+
**self.default_ik_args))
317317
else:
318318
left_qpos = self.get_qpos()
319319
qpos[self.info.left_arm_jids_lst] = \
@@ -323,7 +323,7 @@ def _ee_pos_to_qpos_raw(self, ee_pos, ee_ori=None, fing_dist=0.0,
323323
left_fing_dist/2.0, self.info.joint_minpos[jid],
324324
self.info.joint_maxpos[jid])
325325
# IK will find solutions outside of joint limits, so clip.
326-
# qpos = np.clip(qpos, self.info.joint_minpos, self.info.joint_maxpos)
326+
qpos = self.clip_qpos(qpos)
327327
return qpos
328328

329329
def move_to_qpos(self, tgt_qpos, mode, kp=None, kd=None):
@@ -373,8 +373,7 @@ def move_to_qposvel(self, tgt_qpos, tgt_qvel, mode, kp, kd):
373373
pybullet.PD_CONTROL])
374374
kps = kp if type(kp)==list else [kp]*self.info.dof
375375
kds = kd if type(kd)==list else [kd]*self.info.dof
376-
rbt_tgt_qpos = np.clip(
377-
tgt_qpos, self.info.joint_minpos, self.info.joint_maxpos)
376+
rbt_tgt_qpos = self.clip_qpos(tgt_qpos)
378377
rbt_tgt_qvel = np.clip(
379378
tgt_qvel, -1.0*self.info.joint_maxvel, self.info.joint_maxvel)
380379
# PD example: https://github.com/bulletphysics/bullet3/issues/2152
@@ -412,7 +411,7 @@ def move_to_qposvel(self, tgt_qpos, tgt_qvel, mode, kp, kd):
412411
positionGains=kps, # e.g. 100.0
413412
velocityGains=kds, # e.g. 10.0
414413
forces=self.info.joint_maxforce.tolist()) # see docs page 22
415-
# self.obey_joint_limits()
414+
self.obey_joint_limits()
416415

417416
def move_to_ee_pos(self, tgt_ee_pos, tgt_ee_quat=None, fing_dist=0.0,
418417
left_ee_pos=None, left_ee_quat=None, left_fing_dist=0.0,
@@ -511,25 +510,34 @@ def inverse_dynamics(self, des_acc):
511510
self.info.robot_id, qpos.tolist(), qvel.tolist(), des_acc.tolist())
512511
return np.array(torques)
513512

514-
def obey_joint_limits(self):
515-
qpos = self.get_qpos()
513+
def clip_qpos(self, qpos):
514+
if ((qpos>=self.info.joint_minpos).all() and
515+
(qpos<=self.info.joint_maxpos).all()):
516+
return qpos
517+
clipped_qpos = np.copy(qpos)
516518
for jid in range(self.info.dof):
517-
jpos = qpos[jid]; jvel = 0; ok = True
519+
jpos = qpos[jid]
518520
if jpos < self.info.joint_minpos[jid]:
519-
jpos = self.info.joint_minpos[jid]; ok = False
521+
jpos = self.info.joint_minpos[jid]
520522
if jpos > self.info.joint_maxpos[jid]:
521-
jpos = self.info.joint_maxpos[jid]; ok = False
522-
if not ok:
523-
if self.debug:
524-
print('fixing joint', self.info.joint_ids[jid],
525-
'from pos', qpos[jid], 'to', jpos)
526-
self.sim.resetJointState(
527-
bodyUniqueId=self.info.robot_id,
528-
jointIndex=self.info.joint_ids[jid],
529-
targetValue=jpos, targetVelocity=jvel)
523+
jpos = self.info.joint_maxpos[jid]
524+
clipped_qpos[jid] = jpos
525+
return clipped_qpos
526+
527+
def obey_joint_limits(self):
530528
qpos = self.get_qpos()
531-
assert((qpos>=self.info.joint_minpos).all())
532-
assert((qpos<=self.info.joint_maxpos).all())
529+
clipped_qpos = self.clip_qpos(qpos)
530+
neq_ids = np.nonzero(qpos - clipped_qpos)[0]
531+
for jid in neq_ids:
532+
if self.debug:
533+
print('fix jid', jid, qpos[jid], '->', clipped_qpos[jid])
534+
self.sim.resetJointState(
535+
bodyUniqueId=self.info.robot_id,
536+
jointIndex=self.info.joint_ids[jid],
537+
targetValue=clipped_qpos[jid], targetVelocity=0)
538+
# qpos = self.get_qpos()
539+
# assert((qpos>=self.info.joint_minpos).all())
540+
# assert((qpos<=self.info.joint_maxpos).all())
533541

534542
def ee_pos_to_qpos(self, ee_pos, ee_ori, fing_dist, left_ee_pos=None,
535543
left_ee_ori=None, left_fing_dist=0.0, debug=False):

0 commit comments

Comments
 (0)