@@ -120,6 +120,18 @@ def __init__(self, sim, robot_desc_file, ee_joint_name, ee_link_name,
120
120
assert (len (self .info .left_arm_jids_lst )== len (left_rest_arm_qpos ))
121
121
self .rest_qpos [self .info .left_arm_jids_lst ] = left_rest_arm_qpos [:]
122
122
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
+ }
123
135
ee_pos , ee_ori , * _ = self .get_ee_pos_ori_vel ()
124
136
print ('Initialized robot ee at pos' , ee_pos ,
125
137
'euler ori' , sin_cos_to_theta (ee_ori ),
@@ -148,6 +160,9 @@ def load_robot(self, robot_path, ee_joint_name, ee_link_name,
148
160
pybullet .getJointInfo (robot_id , j )
149
161
jname = jname .decode ("utf-8" )
150
162
link_name = link_name .decode ("utf-8" )
163
+ # take care of continuous joints
164
+ if jhighlim < jlowlim :
165
+ jlowlim , jhighlim = - np .pi , np .pi
151
166
# print('load jname', jname, 'jtype', jtype, 'link_name', link_name)
152
167
if jtype in [pybullet .JOINT_REVOLUTE , pybullet .JOINT_PRISMATIC ]:
153
168
joint_ids .append (j )
@@ -198,7 +213,7 @@ def reset(self):
198
213
self .reset_to_qpos (self .rest_qpos )
199
214
200
215
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 )
202
217
for jid in range (self .info .dof ):
203
218
self .sim .resetJointState (
204
219
bodyUniqueId = self .info .robot_id ,
@@ -212,7 +227,7 @@ def clear_motor_control(self):
212
227
# torque control values this way are hard to reproduce.
213
228
self .sim .setJointMotorControlArray (
214
229
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 )
216
231
self .sim .setJointMotorControlArray (
217
232
self .info .robot_id , self .info .joint_ids .tolist (),
218
233
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,
281
296
qpos = pybullet .calculateInverseKinematics (
282
297
self .info .robot_id , self .info .ee_link_id ,
283
298
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 )
293
300
qpos = np .array (qpos )
294
- if debug :
295
- print ('_ee_pos_to_qpos_raw() qpos from IK' , qpos )
296
301
for jid in self .info .finger_jids_lst :
297
302
qpos [jid ] = np .clip ( # finger info (not set by IK)
298
303
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,
308
313
left_qpos = np .array (pybullet .calculateInverseKinematics (
309
314
self .info .robot_id , self .info .left_ee_link_id ,
310
315
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 ))
317
317
else :
318
318
left_qpos = self .get_qpos ()
319
319
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,
323
323
left_fing_dist / 2.0 , self .info .joint_minpos [jid ],
324
324
self .info .joint_maxpos [jid ])
325
325
# 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 )
327
327
return qpos
328
328
329
329
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):
373
373
pybullet .PD_CONTROL ])
374
374
kps = kp if type (kp )== list else [kp ]* self .info .dof
375
375
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 )
378
377
rbt_tgt_qvel = np .clip (
379
378
tgt_qvel , - 1.0 * self .info .joint_maxvel , self .info .joint_maxvel )
380
379
# 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):
412
411
positionGains = kps , # e.g. 100.0
413
412
velocityGains = kds , # e.g. 10.0
414
413
forces = self .info .joint_maxforce .tolist ()) # see docs page 22
415
- # self.obey_joint_limits()
414
+ self .obey_joint_limits ()
416
415
417
416
def move_to_ee_pos (self , tgt_ee_pos , tgt_ee_quat = None , fing_dist = 0.0 ,
418
417
left_ee_pos = None , left_ee_quat = None , left_fing_dist = 0.0 ,
@@ -511,25 +510,34 @@ def inverse_dynamics(self, des_acc):
511
510
self .info .robot_id , qpos .tolist (), qvel .tolist (), des_acc .tolist ())
512
511
return np .array (torques )
513
512
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 )
516
518
for jid in range (self .info .dof ):
517
- jpos = qpos [jid ]; jvel = 0 ; ok = True
519
+ jpos = qpos [jid ]
518
520
if jpos < self .info .joint_minpos [jid ]:
519
- jpos = self .info .joint_minpos [jid ]; ok = False
521
+ jpos = self .info .joint_minpos [jid ]
520
522
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 ):
530
528
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())
533
541
534
542
def ee_pos_to_qpos (self , ee_pos , ee_ori , fing_dist , left_ee_pos = None ,
535
543
left_ee_ori = None , left_fing_dist = 0.0 , debug = False ):
0 commit comments