3
3
# Copyright (c) 2015, Carnegie Mellon University
4
4
# All rights reserved.
5
5
# Authors: Siddhartha Srinivasa <siddh@cs.cmu.edu>
6
+ # Authors: Michael Koval <mkoval@cs.cmu.edu>
7
+ # Authors: David Butterworth <dbworth@cmu.edu>
6
8
#
7
9
# Redistribution and use in source and binary forms, with or without
8
10
# modification, are permitted provided that the following conditions are met:
@@ -79,9 +81,13 @@ def __init__(self):
79
81
def __str__ (self ):
80
82
return 'VectorFieldPlanner'
81
83
84
+
85
+
82
86
@PlanningMethod
83
87
def PlanToEndEffectorPose (self , robot , goal_pose , timelimit = 5.0 ,
84
- pose_error_tol = 0.01 , ** kw_args ):
88
+ pose_error_tol = 0.01 ,
89
+ integration_interval = 10.0 ,
90
+ ** kw_args ):
85
91
"""
86
92
Plan to an end effector pose by following a geodesic loss function
87
93
in SE(3) via an optimized Jacobian.
@@ -90,6 +96,7 @@ def PlanToEndEffectorPose(self, robot, goal_pose, timelimit=5.0,
90
96
@param goal_pose desired end-effector pose
91
97
@param timelimit time limit before giving up
92
98
@param pose_error_tol in meters
99
+ @param integration_interval The time interval to integrate over
93
100
@return traj
94
101
"""
95
102
manip = robot .GetActiveManipulator ()
@@ -122,7 +129,6 @@ def CloseEnough():
122
129
return Status .TERMINATE
123
130
return Status .CONTINUE
124
131
125
- integration_interval = 10.0
126
132
traj = self .FollowVectorField (robot , vf_geodesic , CloseEnough ,
127
133
integration_interval ,
128
134
timelimit ,
@@ -138,6 +144,7 @@ def PlanToEndEffectorOffset(self, robot, direction, distance,
138
144
max_distance = None , timelimit = 5.0 ,
139
145
position_tolerance = 0.01 ,
140
146
angular_tolerance = 0.15 ,
147
+ integration_interval = 10.0 ,
141
148
** kw_args ):
142
149
"""
143
150
Plan to a desired end-effector offset with move-hand-straight
@@ -150,6 +157,7 @@ def PlanToEndEffectorOffset(self, robot, direction, distance,
150
157
@param timelimit timeout in seconds
151
158
@param position_tolerance constraint tolerance in meters
152
159
@param angular_tolerance constraint tolerance in radians
160
+ @param integration_interval The time interval to integrate over
153
161
@return traj
154
162
"""
155
163
if distance < 0 :
@@ -219,7 +227,6 @@ def TerminateMove():
219
227
220
228
return Status .CONTINUE
221
229
222
- integration_interval = 10.0
223
230
return self .FollowVectorField (robot , vf_straightline , TerminateMove ,
224
231
integration_interval ,
225
232
timelimit ,
@@ -231,9 +238,10 @@ def PlanWorkspacePath(self, robot, traj,
231
238
timelimit = 5.0 ,
232
239
position_tolerance = 0.01 ,
233
240
angular_tolerance = 0.15 ,
234
- goal_pose_tol = 0.01 ,
241
+ t_step = 0.001 ,
235
242
Kp_ff = None ,
236
243
Kp_e = None ,
244
+ integration_interval = 10.0 ,
237
245
** kw_args ):
238
246
"""
239
247
Plan a configuration space path given a workspace path.
@@ -246,7 +254,9 @@ def PlanWorkspacePath(self, robot, traj,
246
254
@param float timelimit: Max planning time (seconds).
247
255
@param float position_tolerance: Constraint tolerance (meters).
248
256
@param float angular_tolerance: Constraint tolerance (radians).
249
- @param float goal_pose_tol: Goal tolerance (meters).
257
+ @param float t_step: Time step to find vector tanget to current
258
+ position on the trajectory, using finite
259
+ differences.
250
260
@param numpy.array Kp_ff: Feed-forward gain.
251
261
A 1x6 vector, where first 3 elements
252
262
affect the translational velocity,
@@ -257,37 +267,33 @@ def PlanWorkspacePath(self, robot, traj,
257
267
affect the translational velocity,
258
268
the last 3 elements affect the
259
269
rotational velocity.
270
+ @param integration_interval The time interval to integrate over.
260
271
261
272
@return openravepy.Trajectory qtraj: Configuration space path.
262
273
"""
263
274
264
- if not util .IsTrajectoryTypeIkParameterization (traj ):
275
+ if not util .IsTrajectoryTypeIkParameterizationTransform6D (traj ):
265
276
raise ValueError ("Trajectory is not a workspace trajectory, it "
266
277
"must have configuration specification of "
267
278
"openravepy.IkParameterizationType.Transform6D" )
268
279
269
- # if IsTimedTrajectory(traj):
270
- # raise ValueError("PlanWorkspacePath expected an un-timed "
271
- # "trajectory.")
280
+ if util . IsTimedTrajectory (traj ):
281
+ raise ValueError ("PlanWorkspacePath expected an un-timed "
282
+ "trajectory." )
272
283
273
284
if position_tolerance < 0.0 :
274
285
raise ValueError ('Position tolerance must be non-negative.' )
275
286
elif angular_tolerance < 0.0 :
276
287
raise ValueError ('Angular tolerance must be non-negative.' )
277
- elif goal_pose_tol < 0.0 :
278
- raise ValueError ('Goal-pose tolerance must be non-negative.' )
279
288
280
- #
281
- #
282
- # ADD ComputeGeodesicUnitTiming()
283
- #
284
- #
289
+ # Time the trajectory based on its distance
290
+ traj = util .ComputeGeodesicUnitTiming (traj , env = None , alpha = 1.0 )
285
291
286
292
# Set the default gains
287
293
if Kp_ff == None :
288
- Kp_ff = numpy .array ([1.0 ,1.0 ,1.0 ,1.0 ,1.0 ,1.0 ])
294
+ Kp_ff = 0.4 * numpy .array ([1.0 ,1.0 ,1.0 ,1.0 ,1.0 ,1.0 ])
289
295
if Kp_e == None :
290
- Kp_e = numpy .array ([1.0 ,1.0 ,1.0 ,1.0 ,1.0 ,1.0 ])
296
+ Kp_e = 1.0 * numpy .array ([1.0 ,1.0 ,1.0 ,1.0 ,1.0 ,1.0 ])
291
297
292
298
manip = robot .GetActiveManipulator ()
293
299
Tstart = manip .GetEndEffectorTransform ()
@@ -306,19 +312,31 @@ def vf_path():
306
312
# the the closest point
307
313
(_ ,t ,_ ) = util .GetMinDistanceBetweenTransformAndWorkspaceTraj (
308
314
T_ee_actual ,
309
- traj )
315
+ traj ,
316
+ 0.0005 )
310
317
# Get the desired end-effector transform from
311
318
# the goal trajectory
312
- t_step = 0.2
313
319
desired_T_ee = openravepy .matrixFromPose (traj .Sample (t )[0 :7 ])
320
+
321
+ # Get the next end-effector transform, using finite-differences
314
322
pose_ee_next = traj .Sample (t + t_step )[0 :7 ]
315
323
desired_T_ee_next = openravepy .matrixFromPose (pose_ee_next )
316
324
325
+ # Get the translation tangent to current position
326
+ tangent_vec = desired_T_ee_next [0 :3 ,3 ] - desired_T_ee [0 :3 ,3 ]
327
+ # Get the translational error
328
+ position_error_vec = desired_T_ee [0 :3 ,3 ] - T_ee_actual [0 :3 ,3 ]
329
+ # Get the translational error perpendicular to the path
330
+ tangent_trans_error = position_error_vec - \
331
+ numpy .dot (position_error_vec , util .NormalizeVector (tangent_vec ))
332
+ tangent_trans_error = numpy .nan_to_num (tangent_trans_error )
333
+
317
334
# The twist between the actual end-effector position and
318
335
# where it should be on the goal trajectory
319
336
# (the error term)
320
337
twist_perpendicular = util .GeodesicTwist (T_ee_actual ,
321
338
desired_T_ee )
339
+ twist_perpendicular [0 :3 ] = tangent_trans_error
322
340
323
341
# The twist tangent to where the end-effector should be
324
342
# on the goal trajectory
@@ -355,16 +373,31 @@ def TerminateMove():
355
373
# the the closest point
356
374
(_ ,t ,_ ) = util .GetMinDistanceBetweenTransformAndWorkspaceTraj (
357
375
T_ee_curr ,
358
- traj )
376
+ traj ,
377
+ 0.0005 )
359
378
# Get the desired end-effector transform from
360
379
# the goal trajectory
361
- T_ee_desired = openravepy .matrixFromPose (traj .Sample (t )[0 :7 ])
380
+ desired_T_ee = openravepy .matrixFromPose (traj .Sample (t )[0 :7 ])
381
+
382
+ # Get the position vector tangent to the trajectory,
383
+ # using finite-differences
384
+ pose_ee_next = traj .Sample (t + t_step )[0 :7 ]
385
+ desired_T_ee_next = openravepy .matrixFromPose (pose_ee_next )
386
+ tangent_vec = desired_T_ee_next [0 :3 ,3 ] - desired_T_ee [0 :3 ,3 ]
362
387
363
388
# Calculate error between current end-effector pose
364
389
# and where we should be on the goal trajectory
365
- geodesic_error = util .GeodesicError (T_ee_desired , T_ee_curr )
390
+ geodesic_error = util .GeodesicError (desired_T_ee , T_ee_curr )
366
391
orientation_error = geodesic_error [3 ]
367
- position_error = geodesic_error [0 :3 ]
392
+ position_error_vec = geodesic_error [0 :3 ]
393
+
394
+ # Use only the translation error that is perpendicular
395
+ # to our current position
396
+ tangent_trans_error = position_error_vec - \
397
+ numpy .dot (position_error_vec , util .NormalizeVector (tangent_vec ))
398
+ tangent_trans_error = numpy .nan_to_num (tangent_trans_error )
399
+
400
+ position_error = tangent_trans_error
368
401
369
402
if numpy .fabs (orientation_error ) > angular_tolerance :
370
403
raise ConstraintViolationPlanningError (
@@ -376,14 +409,15 @@ def TerminateMove():
376
409
'Deviated from straight line constraint.' )
377
410
378
411
# Check if we have reached the end of the goal trajectory
379
- dist_to_goal = util .GetGeodesicDistanceBetweenTransforms (T_ee_curr ,
380
- T_ee_goal )
381
- if numpy .fabs (dist_to_goal ) <= goal_pose_tol :
412
+ error_to_goal = util .GeodesicError (T_ee_curr , T_ee_goal )
413
+ goal_orientation_error = error_to_goal [3 ] # radians
414
+ goal_position_error = error_to_goal [0 :3 ] # x,y,z
415
+ if ((numpy .fabs (goal_orientation_error ) < angular_tolerance ) and
416
+ (numpy .linalg .norm (goal_position_error ) < position_tolerance )):
382
417
return Status .CACHE_AND_TERMINATE
383
418
384
419
return Status .CONTINUE
385
420
386
- integration_interval = 10.0
387
421
return self .FollowVectorField (robot , vf_path , TerminateMove ,
388
422
integration_interval ,
389
423
timelimit , ** kw_args )
@@ -458,8 +492,9 @@ def fn_status_callback(t, q):
458
492
configuration. This is called multiple times at DOF
459
493
resolution in order to check along the entire length of the
460
494
trajectory.
461
- Note: Currently this is called after each integration time
462
- step, which means we are doing more checks than required.
495
+ Note: This is called by fn_callback, which is currently
496
+ called after each integration time step, which means we are
497
+ doing more checks than required.
463
498
"""
464
499
if time .time () - time_start >= timelimit :
465
500
raise TimeLimitError ()
0 commit comments