Path Shortcutting
Paths produced by sampling-based planners such as RRT are collision-free but rarely efficient. Because the tree grows by random extension, the resulting path tends to wander, with unnecessary corners and detours that a more direct route would avoid. Path shortcutting is a fast post-processing step that smooths such a path without re-running the planner.
RoboPlan provides the PathShortcutter class (in roboplan/include/roboplan/core/path_utils.hpp), which shortens a JointPath using random shortcutting.
Each iteration of the shortcutter:
Samples two configurations at random along the current path.
Checks whether they can be connected by a straight, collision-free segment in configuration space.
If so, splices in that direct connection, discarding the intervening waypoints (the “corner” being cut).
Repeatedly cutting corners this way monotonically shortens the path while keeping it collision-free. Because corner-cutting introduces new interpolated vertices, a deterministic redundant-vertex removal pass is interleaved periodically (and run once at the end) to collapse vertices whose neighbors have become directly connectable, preventing an accumulation of unhelpful micro-segments.
This implementation follows Section 3.5.3 of Motion Planning in Higher Dimensions.
The shortcutter is configured through PathShortcuttingOptions:
Parameter |
Description |
Default |
|---|---|---|
|
Joint group to shortcut |
“” |
|
Collision-check step size and minimum separation in a shortcut |
0.05 |
|
Maximum number of random sampling iterations |
100 |
|
Random seed ( |
0 |
|
Stop early after this many consecutive iterations with no
shortcut applied ( |
20 |
|
Cadence (in iterations) of the redundant-vertex removal pass |
20 |
Applying the shortcutter to a path is a single call:
from roboplan.core import PathShortcutter, PathShortcuttingOptions
options = PathShortcuttingOptions(
group_name="arm",
max_step_size=0.05,
max_iters=100,
)
shortcutter = PathShortcutter(scene, options)
# `path` is a JointPath, e.g. the output of rrt.plan(...).
shortened_path = shortcutter.shortcut(path)
The shortened path is itself a collision-free JointPath, ready to be timed into a smooth trajectory with Trajectory Generation.