34
34
import time
35
35
from base import BasePlanner , PlanningError , PlanningMethod
36
36
import prpy .util
37
+ from enum import Enum
37
38
38
39
logger = logging .getLogger ('planning' )
39
40
40
41
42
+ class Status (Enum ):
43
+ '''
44
+ TERMINATE - stop, exit gracefully, and return current trajectory
45
+ CACHE_AND_CONTINUE - save the current trajectory and CONTINUE.
46
+ return the saved trajectory if Exception.
47
+ CONTINUE - keep going
48
+ '''
49
+ TERMINATE = - 1
50
+ CACHE_AND_CONTINUE = 0
51
+ CONTINUE = 1
52
+
53
+
41
54
class VectorFieldPlanner (BasePlanner ):
42
55
def __init__ (self ):
43
56
super (VectorFieldPlanner , self ).__init__ ()
@@ -72,8 +85,8 @@ def CloseEnough():
72
85
manip .GetEndEffectorTransform (),
73
86
goal_pose )
74
87
if pose_error < pose_error_tol :
75
- return True
76
- return False
88
+ return Status . TERMINATE
89
+ return Status . CONTINUE
77
90
78
91
return self .FollowVectorField (robot , vf_geodesic ,
79
92
CloseEnough , timelimit )
@@ -118,8 +131,6 @@ def PlanToEndEffectorOffset(self, robot, direction, distance,
118
131
119
132
manip = robot .GetActiveManipulator ()
120
133
Tstart = manip .GetEndEffectorTransform ()
121
- # This is a list simply because of Python scoping madness
122
- distance_moved = [0.0 ]
123
134
124
135
def vf_straightline ():
125
136
twist = prpy .util .GeodesicTwist (manip .GetEndEffectorTransform (),
@@ -138,32 +149,22 @@ def TerminateMove():
138
149
error = prpy .util .GeodesicError (Tstart , Tnow )
139
150
if numpy .fabs (error [3 ]) > angular_tolerance :
140
151
raise PlanningError ('Deviated from orientation constraint.' )
141
- distance_moved [ 0 ] = numpy .dot (error [0 :3 ], direction )
152
+ distance_moved = numpy .dot (error [0 :3 ], direction )
142
153
position_deviation = numpy .linalg .norm (error [0 :3 ] -
143
- distance_moved [ 0 ] * direction )
154
+ distance_moved * direction )
144
155
if position_deviation > position_tolerance :
145
156
raise PlanningError ('Deviated from straight line constraint.' )
146
157
147
- print distance_moved [0 ], max_distance , position_deviation
158
+ if distance_moved > distance :
159
+ return Status .CACHE_AND_CONTINUE
148
160
149
- if distance_moved [0 ] > max_distance :
150
- return True
151
- return False
161
+ if distance_moved > max_distance :
162
+ return Status .TERMINATE
152
163
153
- try :
154
- traj = self .FollowVectorField (robot , vf_straightline ,
155
- TerminateMove , timelimit )
156
- except PlanningError as e :
157
- # Throw an error if we haven't reached the minimum distance.
158
- print distance_moved [0 ]
159
- if distance_moved [0 ] < distance :
160
- raise
161
- # Otherwise we'll gracefully terminate.
162
- else :
163
- logger .warning ('Terminated early at distance %f < %f: %s' ,
164
- distance_moved [0 ], max_distance , e .message )
164
+ return Status .CONTINUE
165
165
166
- return traj
166
+ return self .FollowVectorField (robot , vf_straightline ,
167
+ TerminateMove , timelimit )
167
168
168
169
@PlanningMethod
169
170
def FollowVectorField (self , robot , fn_vectorfield , fn_terminate ,
@@ -182,47 +183,65 @@ def FollowVectorField(self, robot, fn_vectorfield, fn_terminate,
182
183
"""
183
184
start_time = time .time ()
184
185
185
- with robot :
186
- manip = robot .GetActiveManipulator ()
187
- robot .SetActiveDOFs (manip .GetArmIndices ())
188
- # Populate joint positions and joint velocities
189
- cspec = manip .GetArmConfigurationSpecification ('quadratic' )
190
- cspec .AddDerivativeGroups (1 , False )
191
- cspec .AddDeltaTimeGroup ()
192
- cspec .ResetGroupOffsets ()
193
- qtraj = openravepy .RaveCreateTrajectory (self .env ,
194
- 'GenericTrajectory' )
195
- qtraj .Init (cspec )
196
-
197
- dqout = robot .GetActiveDOFVelocities ()
198
- dt = min (robot .GetDOFResolutions ()/ robot .GetDOFVelocityLimits ())
199
- while True :
200
- # Check for a timeout.
201
- current_time = time .time ()
202
- if (timelimit is not None and
203
- current_time - start_time > timelimit ):
204
- raise PlanningError ('Reached time limit.' )
205
-
206
- # Check for collisions.
207
- if self .env .CheckCollision (robot ):
208
- raise PlanningError ('Encountered collision.' )
209
- if robot .CheckSelfCollision ():
210
- raise PlanningError ('Encountered self-collision.' )
211
-
212
- # Add to trajectory
213
- waypoint = []
214
- q_curr = robot .GetActiveDOFValues ()
215
- waypoint .append (q_curr ) # joint position
216
- waypoint .append (dqout ) # joint velocity
217
- waypoint .append ([dt ]) # delta time
218
- waypoint = numpy .concatenate (waypoint )
219
- qtraj .Insert (qtraj .GetNumWaypoints (), waypoint )
220
- dqout = fn_vectorfield ()
221
- if (numpy .linalg .norm (dqout ) < dq_tol ):
222
- raise PlanningError ('Local minimum, unable to progress' )
223
- if fn_terminate ():
224
- break
225
- qnew = q_curr + dqout * dt
226
- robot .SetActiveDOFValues (qnew )
186
+ try :
187
+ with robot :
188
+ manip = robot .GetActiveManipulator ()
189
+ robot .SetActiveDOFs (manip .GetArmIndices ())
190
+ # Populate joint positions and joint velocities
191
+ cspec = manip .GetArmConfigurationSpecification ('quadratic' )
192
+ cspec .AddDerivativeGroups (1 , False )
193
+ cspec .AddDeltaTimeGroup ()
194
+ cspec .ResetGroupOffsets ()
195
+ qtraj = openravepy .RaveCreateTrajectory (self .env ,
196
+ 'GenericTrajectory' )
197
+ qtraj .Init (cspec )
198
+ cached_traj = None
199
+
200
+ dqout = robot .GetActiveDOFVelocities ()
201
+ dt = min (robot .GetDOFResolutions () /
202
+ robot .GetDOFVelocityLimits ())
203
+ while True :
204
+ # Check for a timeout.
205
+ current_time = time .time ()
206
+ if (timelimit is not None and
207
+ current_time - start_time > timelimit ):
208
+ raise PlanningError ('Reached time limit.' )
209
+
210
+ # Check for collisions.
211
+ if self .env .CheckCollision (robot ):
212
+ raise PlanningError ('Encountered collision.' )
213
+ if robot .CheckSelfCollision ():
214
+ raise PlanningError ('Encountered self-collision.' )
215
+
216
+ # Add to trajectory
217
+ waypoint = []
218
+ q_curr = robot .GetActiveDOFValues ()
219
+ waypoint .append (q_curr ) # joint position
220
+ waypoint .append (dqout ) # joint velocity
221
+ waypoint .append ([dt ]) # delta time
222
+ waypoint = numpy .concatenate (waypoint )
223
+ qtraj .Insert (qtraj .GetNumWaypoints (), waypoint )
224
+ dqout = fn_vectorfield ()
225
+ if (numpy .linalg .norm (dqout ) < dq_tol ):
226
+ raise PlanningError ('Local minimum, \
227
+ unable to progress' )
228
+
229
+ status = fn_terminate ()
230
+
231
+ if status == Status .CACHE_AND_CONTINUE :
232
+ cached_traj = prpy .util .CopyTrajectory (qtraj )
233
+
234
+ if status == Status .TERMINATE :
235
+ break
236
+
237
+ qnew = q_curr + dqout * dt
238
+ robot .SetActiveDOFValues (qnew )
239
+
240
+ except PlanningError as e :
241
+ if cached_traj is not None :
242
+ logger .warning ('Terminated early: %s' , e .message )
243
+ return cached_traj
244
+ else :
245
+ raise
227
246
228
247
return qtraj
0 commit comments