Add batched trapezoidal and Double-S trajectory planning - #566
Add batched trapezoidal and Double-S trajectory planning#566chase6305 wants to merge 11 commits into
Conversation
Greptile SummaryThe PR adds batched trapezoidal and Double-S trajectory planning across Torch and Warp, plus continuous OPW path IK and Cartesian trajectory tutorials. The latest periodic-equivalent fix can still classify a full-turn boundary clamp as continuous.
Confidence Score: 4/5The PR is not yet safe to merge because continuous OPW selection can return a valid path containing an abrupt full-revolution joint step. The replacement periodic-equivalent logic clamps an unavailable seed-nearest turn to a valid boundary and marks it continuous, while the robot API returns that path without any later jump guard. Files Needing Attention: embodichain/utils/warp/kinematics/opw_solver.py, embodichain/lab/sim/objects/robot.py
|
| Filename | Overview |
|---|---|
| embodichain/utils/warp/kinematics/opw_solver.py | Adds periodic-equivalent continuous branch selection, but the boundary clamp can preserve the previously reported full-revolution discontinuity. |
| embodichain/lab/sim/solvers/opw_solver.py | Adds the OPW continuous-path selection wrapper. |
| embodichain/lab/sim/objects/robot.py | Adds continuous batched IK dispatch and returns the selected OPW path without subsequent continuity validation. |
| embodichain/lab/sim/planners/trapezoidal_planner.py | Introduces batched trapezoidal and Double-S profile construction, sampling, constraints, and backend selection. |
| embodichain/utils/warp/kinematics/trapezoidal_warp.py | Implements Warp kernels for scalar profile construction, evaluation, and batched joint composition. |
| embodichain/lab/sim/planners/motion_generator.py | Registers the new planner and maps MotionGenerator limits and sampling options into its plan options. |
Sequence Diagram
sequenceDiagram
participant Robot
participant OPW as OPW candidate generator
participant Selector as Continuous selector
Robot->>OPW: Generate all IK candidates
OPW-->>Selector: Limit-valid analytical candidates
loop Each path sample
Selector->>Selector: Use previous selected state as seed
Selector->>Selector: Find seed-nearest periodic turn
Selector->>Selector: Clamp turn into valid interval
Selector->>Selector: Select nearest candidate and commit
end
Selector-->>Robot: Per-sample validity and joint path
Prompt To Fix All With AI
### Issue 1
embodichain/utils/warp/kinematics/opw_solver.py:60-67
**Boundary clamp breaks continuity**
When the seed-nearest periodic turn lies outside the safety-adjusted joint range, `nearest_equivalent_in_limit` clamps it to a boundary turn and returns it as valid. The selector therefore marks an abrupt approximately 2π joint-position step as continuous, causing extreme commanded motion and invalid trajectory derivatives.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (10): Last reviewed commit: "fix: accept valid periodic OPW equivalen..." | Re-trigger Greptile
There was a problem hiding this comment.
Pull request overview
This PR introduces a new batched trajectory-planning capability (trapezoidal and jerk-limited Double‑S profiles) with Torch and Warp backends, integrates it into the existing MotionGenerator planner registry, and extends Cartesian straight-line planning with continuous batched IK path solving (notably for OPW via Warp).
Changes:
- Add
TrapezoidalPlanner(+ Warp backend) with constraint projection, synchronized multi-joint timing, and sampling (fixed-count / fixed-time). - Add continuous batched Cartesian path IK support (
Robot.compute_ik_path()andOPWSolver.get_ik_path()), plus tutorial + benchmark scripts. - Add comprehensive tests and update docs + agent context references.
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/utils/test_opw_path_kernel.py | Adds a unit test validating OPW Warp path branch continuity selection. |
| tests/sim/planners/test_trapezoidal_planner.py | Adds extensive correctness/golden tests for trapezoidal and Double‑S planning across Torch/Warp. |
| tests/lab/scripts/test_trapezoidal_planner_tutorial.py | Tests tutorial utilities (Cartesian line planning, derivatives, plotting, replay behavior). |
| scripts/tutorials/sim/trapezoidal_profile.py | Adds a minimal scalar profile plotting example (no simulation). |
| scripts/tutorials/sim/trapezoidal_planner.py | Adds a full tutorial: joint + Cartesian planning, plotting diagnostics, and replay timing. |
| scripts/benchmark/motion_generation/trapezoidal_planner.py | Adds a reproducible Torch/Warp benchmark harness and markdown report output. |
| embodichain/utils/warp/kinematics/opw_solver.py | Adds a Warp kernel to select a temporally continuous OPW IK branch over a pose path. |
| embodichain/lab/sim/solvers/opw_solver.py | Adds OPWSolver.get_ik_path() to solve and continuously select an entire pose path in Warp. |
| embodichain/lab/sim/planners/trapezoidal_warp.py | Implements Warp profile construction and sampling kernels for the trapezoidal planner. |
| embodichain/lab/sim/planners/trapezoidal_planner.py | Adds the core batched trapezoidal/Double‑S planner (Torch reference + Warp dispatch). |
| embodichain/lab/sim/planners/motion_generator.py | Registers the new planner type and adds plan-options resolution for trapezoidal sampling. |
| embodichain/lab/sim/planners/init.py | Exports the new planner from the planners package. |
| embodichain/lab/sim/objects/robot.py | Adds Robot.compute_ik_path() for continuous pose-path IK through solver interfaces. |
| docs/source/overview/sim/solvers/opw_solver.md | Documents OPW whole-path IK behavior and kernels. |
| docs/source/api_reference/public_api.rst | Adds trapezoidal planner module to the public API autosummary list. |
| docs/source/api_reference/embodichain/embodichain.lab.sim.planners.rst | Adds API docs section and usage example for TrapezoidalPlanner. |
| agent_context/topics/motion-planning/motion-planning.md | Updates project context docs with the new planner and tutorial details. |
| agent_context/topics/ik-solvers/ik-solvers.md | Documents OPW whole-path IK behavior in the IK solvers overview. |
| agent_context/MAP.yaml | Extends motion-planning topic source-of-truth list with new modules/scripts. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 19 out of 19 changed files in this pull request and generated no new comments.
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
embodichain/lab/sim/objects/robot.py:1117
compute_ik_path()validates only the batch dimension/ndim forpose_tensor, but not the trailing matrix shape(4, 4)it promises in the docstring/error message. This can allow invalid inputs through and then fail later insidetorch.matmul/torch.inversewith a less clear error.
if pose_tensor.ndim != 4 or pose_tensor.shape[0] != batch_size:
raise ValueError("pose must have shape (B, N, 4, 4).")
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 19 out of 19 changed files in this pull request and generated no new comments.
Suppressed comments (3)
Previously missed (2) — in code that hasn't changed since the last review.
embodichain/utils/warp/kinematics/opw_solver.py:533
- The kernel loops are hard-coded to 8 candidates and 6 joints (see
for candidate in range(8)/for joint in range(6)), but these parameter comments suggest a variableN_SOL/DOF. Please update the comments to reflect the fixed OPW sizes to avoid misleading future callers.
This issue also appears on line 537 of the same file.
full_ik_result: wp.array(dtype=float, ndim=4), # [B, N, N_SOL, DOF]
full_ik_valid: wp.array(dtype=int, ndim=3), # [B, N, N_SOL]
initial_seed: wp.array(dtype=float, ndim=2), # [B, DOF]
embodichain/lab/sim/planners/trapezoidal_warp.py:347
compose_profile_samples_warp()validates dtypes but not that all input tensors share the same device. If a caller accidentally mixes CPU/CUDA tensors, Warp will fail later with a less actionable error; adding an explicit device check here makes the public helper more robust (and matches the checks inbuild_profile_warp()).
)
if any(tensor.dtype != torch.float32 for tensor in tensors):
raise ValueError("The Warp trajectory backend requires float32 tensors.")
batch_size, sample_count = times.shape
embodichain/utils/warp/kinematics/opw_solver.py:538
path_resultis always 6-DOF (the kernel useswp_vec6flimits/weights and loopsfor joint in range(6)), but the comment saysDOF. Align this with the fixed OPW DOF to keep the signature self-documenting.
path_result: wp.array(dtype=float, ndim=3), # [B, N, DOF]
path_valid: wp.array(dtype=int, ndim=2), # [B, N]
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 19 out of 19 changed files in this pull request and generated no new comments.
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
embodichain/lab/sim/objects/robot.py:1117
compute_ik_path()validates only the batch dimension and rank forpose, but not the trailing matrix shape. If a caller passes(B, N, 7)or(B, N, 3, 4)the error message claims(B, N, 4, 4)yet the check passes and the subsequentmatmul/inversewill fail with a less clear runtime error. Tighten the shape check to includepose_tensor.shape[-2:] == (4, 4).
if pose_tensor.ndim != 4 or pose_tensor.shape[0] != batch_size:
raise ValueError("pose must have shape (B, N, 4, 4).")
Review against the current
|
| @@ -0,0 +1,134 @@ | |||
| # ---------------------------------------------------------------------------- | |||
There was a problem hiding this comment.
Should we standardlize this script as a reusable tool for motion generator @chase6305 ?
Description
This PR adds a batched trajectory planner supporting trapezoidal velocity and jerk-limited seven-phase Double-S motion profiles.
The planner supports both Torch and NVIDIA Warp backends and integrates with the existing MotionGenerator interface. The Warp backend parallelizes scalar profile construction, phase evaluation, and batched joint trajectory
composition.
It also adds Cartesian straight-line trajectory planning for the simulation tutorial. Cartesian distance is time-parameterized before IK, ensuring the requested end-effector path follows the configured velocity, acceleration, and
jerk constraints.
For OPW-based robots, the complete Cartesian pose path is now solved through a batched Warp path-IK interface:
This avoids launching OPW IK separately for every trajectory sample while preserving joint-path continuity.
Additional changes include:
Add TrapezoidalPlanner, TrapezoidalPlannerCfg, and TrapezoidalPlanOptions.
Support scalar and per-joint velocity, acceleration, and jerk limits.
Support synchronized multi-joint motion.
Support triangular fallback for short trapezoidal moves.
Support seven-phase Double-S profiles without display filtering.
Support fixed-count and fixed-time trajectory sampling.
Support optional minimum-duration scaling.
Support redundant collinear waypoint compression.
Add explicit torch, warp, and auto backend selection.
Add continuous Cartesian path IK through Robot.compute_ik_path().
Add batched OPW path solving through OPWSolver.get_ik_path().
Compute Cartesian joint velocity and acceleration using the path time law and differential kinematics rather than numerical time differentiation.
Add simulation replay using the planned trajectory timing.
Add diagnostic plots for:
Add standalone profile and simulation tutorials.
Add a reproducible Torch/Warp trajectory-planner benchmark.
Update motion-planning, solver, and API documentation.
Motivation and context:
The existing trajectory-planning examples primarily relied on TOPPRA and did not provide a lightweight, natively batched implementation for trapezoidal or jerk-limited motion profiles.
Cartesian trajectories also require the time law to be applied in Cartesian space before IK. Applying joint-space timing after independently sampled IK can distort the requested end-effector path and produce inconsistent
derivatives.
This change provides a maintainable trajectory-planning implementation suitable for both CPU execution and large batched CUDA workloads, while keeping Torch as the reference and fallback backend.
Dependencies:
Fixes #
Type of change
Screenshots
traj_joint_1-2026-09-02_14.44.00.mp4
traj_cartesian_1-2026-09-02_14.46.48.mp4
Validation
The following focused validation was completed: