@@ -157,6 +157,7 @@ def ServoTo(manipulator, target, duration, timeStep=0.05, collisionChecking=True
157
157
158
158
if not inCollision :
159
159
for i in range (1 ,steps ):
160
+ import time
160
161
manipulator .Servo (velocities )
161
162
time .sleep (timeStep )
162
163
manipulator .Servo ([0 ] * len (manipulator .GetArmIndices ()))
@@ -223,7 +224,8 @@ def ClearTrajectoryStatus(manipulator):
223
224
manipulator .controller .SendCommand ('ClearStatus' )
224
225
225
226
def MoveUntilTouch (manipulator , direction , distance , max_distance = None ,
226
- max_force = 5.0 , max_torque = None , ignore_collisions = None , ** kw_args ):
227
+ max_force = 5.0 , max_torque = None , ignore_collisions = None ,
228
+ velocity_limit_scale = 0.25 , ** kw_args ):
227
229
"""Execute a straight move-until-touch action.
228
230
This action stops when a sufficient force is is felt or the manipulator
229
231
moves the maximum distance. The motion is considered successful if the
@@ -235,100 +237,123 @@ def MoveUntilTouch(manipulator, direction, distance, max_distance=None,
235
237
@param max_distance maximum distance in meters
236
238
@param max_force maximum force in Newtons
237
239
@param max_torque maximum torque in Newton-Meters
238
- @param ignore_collisions collisions with these objects are ignored when planning the path, e.g. the object you think you will touch
240
+ @param ignore_collisions collisions with these objects are ignored when
241
+ planning the path, e.g. the object you think you will touch
242
+ @param velocity_limit_scale A multiplier to use to scale velocity limits
243
+ when executing MoveUntilTouch ( < 1 in most cases).
239
244
@param **kw_args planner parameters
240
245
@return felt_force flag indicating whether we felt a force.
241
246
"""
247
+ from contextlib import nested
248
+ from openravepy import CollisionReport , KinBody , Robot , RaveCreateTrajectory
249
+ from ..planning .exceptions import CollisionPlanningError
242
250
251
+ delta_t = 0.01
252
+
253
+ robot = manipulator .GetRobot ()
254
+ env = robot .GetEnv ()
255
+ dof_indices = manipulator .GetArmIndices ()
256
+
257
+ direction = numpy .array (direction , dtype = 'float' )
258
+
259
+ # Default argument values.
243
260
if max_distance is None :
244
261
max_distance = 1.
245
262
warnings .warn (
246
263
'MoveUntilTouch now requires the "max_distance" argument.'
247
264
' This will be an error in the future.' ,
248
265
DeprecationWarning )
249
266
250
- # TODO: Is ignore_collisions a list of names or KinBody pointers?
251
267
if max_torque is None :
252
- max_torque = numpy .array ([100.0 , 100.0 , 100.0 ])
253
-
254
- ignore_col_obj_oldstate = []
268
+ max_torque = numpy .array ([100.0 , 100.0 , 100.0 ])
269
+
255
270
if ignore_collisions is None :
256
271
ignore_collisions = []
257
272
258
- for ignore_col_with in ignore_collisions :
259
- ignore_col_obj_oldstate .append (ignore_col_with .IsEnabled ())
260
- ignore_col_with .Enable (False )
261
-
262
- with manipulator .GetRobot ().GetEnv ():
263
- manipulator .GetRobot ().GetController ().SimulationStep (0 )
264
-
273
+ with env :
265
274
# Compute the expected force direction in the hand frame.
266
- direction = numpy .array (direction )
267
275
hand_pose = manipulator .GetEndEffectorTransform ()
268
276
force_direction = numpy .dot (hand_pose [0 :3 , 0 :3 ].T , - direction )
269
277
270
- with manipulator .GetRobot ():
271
- old_active_manipulator = manipulator .GetRobot ().GetActiveManipulator ()
272
- manipulator .SetActive ()
273
- traj = manipulator .PlanToEndEffectorOffset (direction , distance , max_distance = max_distance ,
274
- execute = False , ** kw_args )
278
+ # Disable the KinBodies listed in ignore_collisions. We backup the
279
+ # "enabled" state of all KinBodies so we can restore them later.
280
+ body_savers = [
281
+ body .CreateKinBodyStateSaver () for body in ignore_collisions ]
282
+ robot_saver = robot .CreateRobotStateSaver (
283
+ Robot .SaveParameters .ActiveDOF
284
+ | Robot .SaveParameters .ActiveManipulator
285
+ | Robot .SaveParameters .LinkTransformation )
275
286
276
- collided_with_obj = False
277
- try :
278
- if not manipulator .simulated :
279
- manipulator .SetTrajectoryExecutionOptions (traj , stop_on_ft = True ,
280
- force_direction = force_direction , force_magnitude = max_force ,
281
- torque = max_torque )
287
+ with robot_saver , nested (* body_savers ) as f :
288
+ manipulator .SetActive ()
289
+ robot_cspec = robot .GetActiveConfigurationSpecification ()
282
290
283
- manipulator . hand . TareForceTorqueSensor ()
284
- manipulator . GetRobot (). ExecutePath ( traj )
291
+ for body in ignore_collisions :
292
+ body . Enable ( False )
285
293
286
- for (ignore_col_with , oldstate ) in zip (ignore_collisions , ignore_col_obj_oldstate ):
287
- ignore_col_with .Enable (oldstate )
288
- else :
294
+ path = robot .PlanToEndEffectorOffset (direction = direction ,
295
+ distance = distance , max_distance = max_distance , ** kw_args )
289
296
290
- traj = manipulator .GetRobot ().PostProcessPath (traj )
291
-
292
- traj_duration = traj .GetDuration ()
293
- delta_t = 0.01
294
-
295
- traj_config_spec = traj .GetConfigurationSpecification ()
296
- new_traj = openravepy .RaveCreateTrajectory (manipulator .GetRobot ().GetEnv (), '' )
297
- new_traj .Init (traj_config_spec )
298
-
299
- for (ignore_col_with , oldstate ) in zip (ignore_collisions , ignore_col_obj_oldstate ):
300
- ignore_col_with .Enable (oldstate )
301
-
302
- with manipulator .GetRobot ():
303
- manipulator .SetActive ()
304
- waypoint_ind = 0
305
- for t in numpy .arange (0 , traj_duration , delta_t ):
306
- traj_sample = traj .Sample (t )
307
-
308
- waypoint = traj_config_spec .ExtractJointValues (traj_sample , manipulator .GetRobot (), manipulator .GetArmIndices ())
309
- manipulator .SetDOFValues (waypoint )
310
-
311
- # Check collision with each body on the robot
312
- for body in manipulator .GetRobot ().GetEnv ().GetBodies ():
313
- if manipulator .GetRobot ().GetEnv ().CheckCollision (manipulator .GetRobot (), body ):
314
- collided_with_obj = True
315
- break
316
- if collided_with_obj :
317
- break
318
- else :
319
- #set timing on new sampled waypoint
320
- if waypoint_ind == 0 :
321
- traj_config_spec .InsertDeltaTime (traj_sample , 0. )
322
- else :
323
- traj_config_spec .InsertDeltaTime (traj_sample , delta_t )
324
-
325
- new_traj .Insert (int (waypoint_ind ), traj_sample )
326
- waypoint_ind += 1
327
-
328
-
329
- manipulator .GetRobot ().ExecuteTrajectory (new_traj )
330
-
331
- return collided_with_obj
332
- # Trajectory is aborted by OWD because we felt a force.
333
- except exceptions .TrajectoryAborted :
334
- return True
297
+ # Execute on the real robot by tagging the trajectory with options that
298
+ # tell the controller to stop on force/torque input.
299
+ if not manipulator .simulated :
300
+ manipulator .SetTrajectoryExecutionOptions (path , stop_on_ft = True ,
301
+ force_direction = force_direction , force_magnitude = max_force ,
302
+ torque = max_torque )
303
+
304
+ manipulator .hand .TareForceTorqueSensor ()
305
+
306
+ try :
307
+ with robot .CreateRobotStateSaver (Robot .SaveParameters .JointMaxVelocityAndAcceleration ):
308
+ vl = robot .GetDOFVelocityLimits ()
309
+ manipulator .SetVelocityLimits (velocity_limit_scale * vl , 0.5 )
310
+ robot .ExecutePath (path )
311
+ return False
312
+ except exceptions .TrajectoryAborted as e :
313
+ logger .warn ('MoveUntilTouch aborted: %s' , str (e ))
314
+ return True
315
+ # Forward-simulate the motion until it hits an object.
316
+ else :
317
+ traj = robot .PostProcessPath (path )
318
+ is_collision = False
319
+
320
+ traj_cspec = traj .GetConfigurationSpecification ()
321
+ new_traj = RaveCreateTrajectory (env , '' )
322
+ new_traj .Init (traj_cspec )
323
+
324
+ robot_saver = robot .CreateRobotStateSaver (
325
+ Robot .SaveParameters .LinkTransformation )
326
+
327
+ with env , robot_saver :
328
+ for t in numpy .arange (0 , traj .GetDuration (), delta_t ):
329
+ waypoint = traj .Sample (t )
330
+
331
+ dof_values = robot_cspec .ExtractJointValues (
332
+ waypoint , robot , dof_indices , 0 )
333
+ manipulator .SetDOFValues (dof_values )
334
+
335
+ # Terminate if we detect collision with the environment.
336
+ report = CollisionReport ()
337
+ if env .CheckCollision (robot , report = report ):
338
+ logger .info ('Terminated from collision: %s' ,
339
+ str (CollisionPlanningError .FromReport (report )))
340
+ is_collision = True
341
+ break
342
+ elif robot .CheckSelfCollision (report = report ):
343
+ logger .info ('Terminated from self-collision: %s' ,
344
+ str (CollisionPlanningError .FromReport (report )))
345
+ is_collision = True
346
+ break
347
+
348
+ # Build the output trajectory that stops in contact.
349
+ if new_traj .GetNumWaypoints () == 0 :
350
+ traj_cspec .InsertDeltaTime (waypoint , 0. )
351
+ else :
352
+ traj_cspec .InsertDeltaTime (waypoint , delta_t )
353
+
354
+ new_traj .Insert (new_traj .GetNumWaypoints (), waypoint )
355
+
356
+ if new_traj .GetNumWaypoints () > 0 :
357
+ robot .ExecuteTrajectory (new_traj )
358
+
359
+ return is_collision
0 commit comments