Skip to content

Commit 4942a96

Browse files
author
Michael Koval
committed
Documented ExecutePath and ExecuteTrajectory.
1 parent 32ab8a2 commit 4942a96

File tree

1 file changed

+62
-32
lines changed

1 file changed

+62
-32
lines changed

src/prpy/base/robot.py

Lines changed: 62 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,8 @@ def do_postprocess():
269269
'Setting robot "%s" DOFs %s as active for post-processing.',
270270
cloned_robot.GetName(), list(dof_indices))
271271

272+
# TODO: Handle a affine DOF trajectories for the base.
273+
272274
# Directly compute a timing of smooth trajectories.
273275
if smooth:
274276
logger.warning(
@@ -309,51 +311,74 @@ def do_postprocess():
309311
else:
310312
return do_postprocess()
311313

312-
def ExecutePath(self, path, simplify=True, smooth=True, defer=False,
313-
timeout=1., **kwargs):
314-
315-
logger.debug('Begin ExecutePath')
316-
317-
def do_execute(path, simplify, smooth, timeout, **kwargs):
318-
319-
with Clone(self.GetEnv()) as cloned_env:
320-
traj_dofs = util.GetTrajectoryIndices(path)
321-
cloned_env.Cloned(self).SetActiveDOFs(traj_dofs)
322-
cloned_robot = cloned_env.Cloned(self)
314+
def ExecutePath(self, path, defer=False, executor=None, **kwargs):
315+
""" Post-process and execute an un-timed path.
323316
324-
if simplify:
325-
path = self.simplifier.ShortcutPath(cloned_robot, path, defer=False,
326-
timeout=timeout, **kwargs)
317+
This method calls PostProcessPath, then passes the result to
318+
ExecuteTrajectory. Any extra **kwargs are forwarded to both of these
319+
methods. This function returns the timed trajectory that was executed
320+
on the robot.
327321
328-
retimer = self.smoother if smooth else self.retimer
329-
cloned_timed_traj = retimer.RetimeTrajectory(cloned_robot, path, defer=False, **kwargs)
322+
@param path OpenRAVE trajectory representing an un-timed path
323+
@param defer execute asynchronously and return a future
324+
@param executor if defer = True, which executor to use
325+
@param **kwargs forwarded to PostProcessPath and ExecuteTrajectory
326+
@return timed trajectory executed on the robot
327+
"""
330328

331-
# Copy the trajectory back to the original environment.
332-
from ..util import CopyTrajectory
333-
timed_traj = CopyTrajectory(cloned_timed_traj, env=self.GetEnv())
329+
def do_execute():
330+
logger.debug('Post-processing path to compute a timed trajectory.')
331+
traj = self.PostProcessPath(path, defer=False, **kwargs)
334332

335-
return self.ExecuteTrajectory(timed_traj, defer=False, **kwargs)
333+
logger.debug('Executing timed trajectory.')
334+
return self.ExecuteTrajectory(traj, defer=False, **kwargs)
336335

337336
if defer:
338337
from trollius.executor import get_default_executor
339338
from trollius.futures import wrap_future
340339

341-
executor = kwargs.get('executor') or get_default_executor()
342-
return wrap_future(
343-
executor.submit(do_execute,
344-
path, simplify=simplify, smooth=smooth, timeout=timeout,
345-
**kwargs
346-
)
347-
)
340+
if executor is None:
341+
executor = get_default_executor()
342+
343+
return wrap_future(executor.submit(do_execute))
348344
else:
349-
return do_execute(path, simplify=simplify, smooth=smooth,
350-
timeout=timeout, **kwargs)
345+
return do_execute()
346+
347+
def ExecuteTrajectory(self, traj, defer=False, timeout=None, period=0.01):
348+
""" Executes a time trajectory on the robot.
349+
350+
This function directly executes a timed OpenRAVE trajectory on the
351+
robot. If you have a geometric path, such as those returned by a
352+
geometric motion planner, you should first time the path using
353+
PostProcessPath. Alternatively, you could use the ExecutePath helper
354+
function to time and execute the path in one function call.
355+
356+
If timeout = None (the default), this function does not return until
357+
execution has finished. Termination occurs if the trajectory is
358+
successfully executed or if a fault occurs (in this case, an exception
359+
will be raised). If timeout is a float (including timeout = 0), this
360+
function will return None once the timeout has ellapsed, even if the
361+
trajectory is still being executed.
362+
363+
NOTE: We suggest that you either use timeout=None or defer=True. If
364+
trajectory execution times out, there is no way to tell whether
365+
execution was successful or not. Other values of timeout are only
366+
supported for legacy reasons.
367+
368+
This function returns the trajectory that was actually executed on the
369+
robot, including controller error. If this is not available, the input
370+
trajectory will be returned instead.
371+
372+
@param traj timed OpenRAVE trajectory to be executed
373+
@param defer execute asynchronously and return a trajectory Future
374+
@param timeout maximum time to wait for execution to finish
375+
@param period poll rate, in seconds, for checking trajectory status
376+
@return trajectory executed on the robot
377+
"""
351378

352-
def ExecuteTrajectory(self, traj, defer=False, timeout=None, period=0.01, **kw_args):
353379
# TODO: Verify that the trajectory is timed.
354380
# TODO: Check if this trajectory contains the base.
355381

356-
logger.debug('Begin ExecuteTrajectory')
357382
needs_base = util.HasAffineDOFs(traj.GetConfigurationSpecification())
358383

359384
self.GetController().SetPath(traj)
@@ -366,8 +391,13 @@ def ExecuteTrajectory(self, traj, defer=False, timeout=None, period=0.01, **kw_a
366391
]
367392

368393
if needs_base:
369-
if hasattr(self, 'base') and hasattr(self.base, 'controller'):
394+
if (hasattr(self, 'base') and hasattr(self.base, 'controller')
395+
and self.base.controller is not None):
370396
active_controllers.append(self.base.controller)
397+
else:
398+
logger.warning(
399+
'Trajectory includes the base, but no base controller is'
400+
' available. Is self.base.controller set?')
371401

372402
if defer:
373403
import time

0 commit comments

Comments
 (0)