Skip to content

Commit e4fc8a7

Browse files
committed
Merge pull request #149 from personalrobotics/bugfix/simplify_retimer
Bugfix: SimplifyTrajectory calls in retimer
2 parents 035d6f3 + 6b7a65a commit e4fc8a7

File tree

4 files changed

+36
-21
lines changed

4 files changed

+36
-21
lines changed

src/prpy/base/robot.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -459,8 +459,7 @@ def ExecuteTrajectory(self, traj, defer=False, timeout=None, period=0.01, **kwar
459459

460460
# Verify that the trajectory is timed by checking whether the first
461461
# waypoint has a valid deltatime value.
462-
cspec = traj.GetConfigurationSpecification()
463-
if cspec.ExtractDeltaTime(traj.GetWaypoint(0)) is None:
462+
if not util.IsTimedTrajectory(traj):
464463
raise ValueError('Trajectory cannot be executed, it is not timed.')
465464

466465
# Verify that the trajectory has non-zero duration.

src/prpy/planning/mac_smoother.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2929
# POSSIBILITY OF SUCH DAMAGE.
3030

31-
from ..util import CopyTrajectory, SimplifyTrajectory, SetTrajectoryTags
31+
from ..util import (CopyTrajectory, SimplifyTrajectory, SetTrajectoryTags,
32+
IsTimedTrajectory)
3233
from base import (BasePlanner, PlanningError, PlanningMethod,
3334
UnsupportedPlanningError, Tags)
3435
from openravepy import (Planner, PlannerStatus, RaveCreatePlanner,
@@ -45,7 +46,7 @@ def __init__(self):
4546
'Unable to create PrSplineMacBlender planner. Is or_pr_spline'
4647
' installed and in your OPENRAVE_PLUGIN path?'
4748
)
48-
49+
4950
self.retimer = RaveCreatePlanner(self.env, 'PrSplineMacTimer')
5051
if self.retimer is None:
5152
raise UnsupportedPlanningError(
@@ -59,7 +60,10 @@ def RetimeTrajectory(self, robot, path):
5960
# necessary for two reasons: (1) the input trajectory may be in another
6061
# environment and/or (2) the retimer modifies the trajectory in-place.
6162
output_traj = CopyTrajectory(path, env=self.env)
62-
output_traj = SimplifyTrajectory(output_traj, robot)
63+
64+
# Remove co-linear waypoints.
65+
if not IsTimedTrajectory(output_traj):
66+
output_traj = SimplifyTrajectory(output_traj, robot)
6367

6468
# Blend the piecewise-linear input trajectory. The blender outputs a
6569
# collision-free path, consisting of piecewise-linear segments and

src/prpy/planning/retimer.py

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,13 @@
2828
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2929
# POSSIBILITY OF SUCH DAMAGE.
3030

31-
import logging, numpy, openravepy, os, tempfile
32-
from ..util import CopyTrajectory, SimplifyTrajectory, HasAffineDOFs
33-
from base import BasePlanner, PlanningError, PlanningMethod, UnsupportedPlanningError
34-
from openravepy import PlannerStatus
31+
import logging
32+
import openravepy
33+
from ..util import (CreatePlannerParametersString, CopyTrajectory,
34+
SimplifyTrajectory, HasAffineDOFs, IsTimedTrajectory)
35+
from base import (BasePlanner, PlanningError, PlanningMethod,
36+
UnsupportedPlanningError)
37+
from openravepy import PlannerStatus, Planner
3538

3639
logger = logging.getLogger(__name__)
3740

@@ -56,11 +59,8 @@ def __str__(self):
5659

5760
@PlanningMethod
5861
def RetimeTrajectory(self, robot, path, options=None, **kw_args):
59-
from ..util import (CreatePlannerParametersString, CopyTrajectory,
60-
SimplifyTrajectory, HasAffineDOFs)
6162
from openravepy import CollisionOptions, CollisionOptionsStateSaver
6263
from copy import deepcopy
63-
from openravepy import Planner
6464

6565
# Validate the input path.
6666
cspec = path.GetConfigurationSpecification()
@@ -91,11 +91,12 @@ def RetimeTrajectory(self, robot, path, options=None, **kw_args):
9191
# Copy the input trajectory into the planning environment. This is
9292
# necessary for two reasons: (1) the input trajectory may be in another
9393
# environment and/or (2) the retimer modifies the trajectory in-place.
94-
input_path = CopyTrajectory(path, env=self.env)
94+
output_traj = CopyTrajectory(path, env=self.env)
9595

9696
# Remove co-linear waypoints. Some of the default OpenRAVE retimers do
9797
# not perform this check internally (e.g. ParabolicTrajectoryRetimer).
98-
output_traj = SimplifyTrajectory(input_path, robot)
98+
if not IsTimedTrajectory(output_traj):
99+
output_traj = SimplifyTrajectory(output_traj, robot)
99100

100101
# Only collision check the active DOFs.
101102
dof_indices, _ = cspec.ExtractUsedIndices(robot)
@@ -104,13 +105,12 @@ def RetimeTrajectory(self, robot, path, options=None, **kw_args):
104105
# Compute the timing. This happens in-place.
105106
self.planner.InitPlan(None, params_str)
106107

107-
108108
with CollisionOptionsStateSaver(self.env.GetCollisionChecker(),
109109
CollisionOptions.ActiveDOFs):
110110
status = self.planner.PlanPath(output_traj, releasegil=True)
111111

112-
if status not in [ PlannerStatus.HasSolution,
113-
PlannerStatus.InterruptedWithSolution ]:
112+
if status not in [PlannerStatus.HasSolution,
113+
PlannerStatus.InterruptedWithSolution]:
114114
raise PlanningError(
115115
'Retimer returned with status {:s}.'.format(str(status)))
116116

@@ -182,8 +182,6 @@ def RetimeTrajectory(self, robot, path, **kw_args):
182182
if not found:
183183
raise UnsupportedPlanningError('OpenRAVEAffineRetimer only supports untimed paths with affine DOFs. Found group: %s' % group.name)
184184

185-
186-
187185
# Copy the input trajectory into the planning environment. This is
188186
# necessary for two reasons: (1) the input trajectory may be in another
189187
# environment and/or (2) the retimer modifies the trajectory in-place.
@@ -197,8 +195,8 @@ def RetimeTrajectory(self, robot, path, **kw_args):
197195
status = RetimeTrajectory(output_traj, max_velocities, max_accelerations,
198196
False)
199197

200-
if status not in [ PlannerStatus.HasSolution,
201-
PlannerStatus.InterruptedWithSolution ]:
198+
if status not in [PlannerStatus.HasSolution,
199+
PlannerStatus.InterruptedWithSolution]:
202200
raise PlanningError('Retimer returned with status {0:s}.'.format(
203201
str(status)))
204202

src/prpy/util.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,3 +735,17 @@ def IsAtTrajectoryStart(robot, trajectory):
735735

736736
# If all joints match, return True.
737737
return True
738+
739+
740+
def IsTimedTrajectory(trajectory):
741+
"""
742+
Returns True if the trajectory is timed.
743+
744+
This function checks whether a trajectory has a valid `deltatime` group,
745+
indicating that it is a timed trajectory.
746+
747+
@param trajectory: an OpenRAVE trajectory
748+
@returns: True if the trajectory is timed, False otherwise
749+
"""
750+
cspec = trajectory.GetConfigurationSpecification()
751+
return cspec.ExtractDeltaTime(trajectory.GetWaypoint(0)) is not None

0 commit comments

Comments
 (0)