Pair a nominal and a retimed NMG arm in the benchmark - #715
Yuan-Xinyi wants to merge 3 commits into
Conversation
|
Follow-up to the same change, from review on #715. - `--nmg-onnx-path`, `--nmg-pos-eps` and `--nmg-rot-eps` updated only the row literally named `nmg`. The paired `nmg_retimed` row kept a null checkpoint, so its availability check skipped it and the comparison this change exists to run never ran. The overrides now apply to every `nmg_onnx` row, which also keeps the pair's tolerances identical so the comparison does not measure a tolerance difference alongside the timing one. - State in BENCHMARK_DESIGN that retiming constrains velocity and acceleration only. The suites also set a jerk limit and the metrics validate against it, so a retimed row can still exceed jerk. That is a real result about the policy's path, which retiming cannot smooth, not a gap in the guarantee. Refs #684 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
74e9afd to
13329ba
Compare
|
Both findings were valid; fixed in 1. CLI overrides reached only the 2. Jerk is validated but not retimed against — fixed in the docs. Correct: TOPPRA constrains velocity and acceleration, while the suites also state a jerk limit that the metrics check. BENCHMARK_DESIGN now says so explicitly, and frames a jerk failure as a real result about the policy's path — which retiming cannot smooth, only stretch in time — rather than a gap in the velocity and acceleration guarantee. |
eb1d377 to
ff8a48e
Compare
Follow-up to the same change, from review on #715. - `--nmg-onnx-path`, `--nmg-pos-eps` and `--nmg-rot-eps` updated only the row literally named `nmg`. The paired `nmg_retimed` row kept a null checkpoint, so its availability check skipped it and the comparison this change exists to run never ran. The overrides now apply to every `nmg_onnx` row, which also keeps the pair's tolerances identical so the comparison does not measure a tolerance difference alongside the timing one. - State in BENCHMARK_DESIGN that retiming constrains velocity and acceleration only. The suites also set a jerk limit and the metrics validate against it, so a retimed row can still exceed jerk. That is a real result about the policy's path, which retiming cannot smooth, not a gap in the guarantee. Refs #684 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
13329ba to
05f1456
Compare
| "unconstrained while reporting the result as limit-respecting." | ||
| ) | ||
| return { | ||
| "velocity": velocity.detach().cpu().tolist(), |
There was a problem hiding this comment.
When the NMG row runs with retime: true, this passes a one-dimensional list of velocity limits to TOPPRA. The shared adapter turns scalar limits into lower/upper-bound pairs but passes lists through unchanged. TOPPRA cannot construct the velocity constraint, so the retimed arm returns failed trajectories instead of producing the paired comparison.
| "velocity": velocity.detach().cpu().tolist(), | |
| "velocity": [ | |
| [-limit, limit] for limit in velocity.detach().cpu().tolist() | |
| ], |
Prompt To Fix With AI
This is a comment left during a code review.
Path: scripts/benchmark/motion_generation/planners/nmg_onnx.py
Line: 117
Comment:
**Retimed arm cannot solve**
When the NMG row runs with `retime: true`, this passes a one-dimensional list of velocity limits to TOPPRA. The shared adapter turns scalar limits into lower/upper-bound pairs but passes lists through unchanged. TOPPRA cannot construct the velocity constraint, so the retimed arm returns failed trajectories instead of producing the paired comparison.
```suggestion
"velocity": [
[-limit, limit] for limit in velocity.detach().cpu().tolist()
],
```
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Follow-up to the same change, from review on #715. - `--nmg-onnx-path`, `--nmg-pos-eps` and `--nmg-rot-eps` updated only the row literally named `nmg`. The paired `nmg_retimed` row kept a null checkpoint, so its availability check skipped it and the comparison this change exists to run never ran. The overrides now apply to every `nmg_onnx` row, which also keeps the pair's tolerances identical so the comparison does not measure a tolerance difference alongside the timing one. - State in BENCHMARK_DESIGN that retiming constrains velocity and acceleration only. The suites also set a jerk limit and the metrics validate against it, so a retimed row can still exceed jerk. That is a real result about the policy's path, which retiming cannot smooth, not a gap in the guarantee. Refs #684 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
05f1456 to
3ba04de
Compare
Follow-up to the same change, from review on #715. - `--nmg-onnx-path`, `--nmg-pos-eps` and `--nmg-rot-eps` updated only the row literally named `nmg`. The paired `nmg_retimed` row kept a null checkpoint, so its availability check skipped it and the comparison this change exists to run never ran. The overrides now apply to every `nmg_onnx` row, which also keeps the pair's tolerances identical so the comparison does not measure a tolerance difference alongside the timing one. - State in BENCHMARK_DESIGN that retiming constrains velocity and acceleration only. The suites also set a jerk limit and the metrics validate against it, so a retimed row can still exceed jerk. That is a real result about the policy's path, which retiming cannot smooth, not a gap in the guarantee. Refs #684 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
3ba04de to
f2d519d
Compare
Follow-up to the same change, from review on #715. - `--nmg-onnx-path`, `--nmg-pos-eps` and `--nmg-rot-eps` updated only the row literally named `nmg`. The paired `nmg_retimed` row kept a null checkpoint, so its availability check skipped it and the comparison this change exists to run never ran. The overrides now apply to every `nmg_onnx` row, which also keeps the pair's tolerances identical so the comparison does not measure a tolerance difference alongside the timing one. - State in BENCHMARK_DESIGN that retiming constrains velocity and acceleration only. The suites also set a jerk limit and the metrics validate against it, so a retimed row can still exceed jerk. That is a real result about the policy's path, which retiming cannot smooth, not a gap in the guarantee. Refs #684 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
f2d519d to
b0fcaa1
Compare
Measuring dynamic limits and being able to retime a rollout do not by themselves answer whether retiming helps: nothing ran the same policy both ways over the same cases. This adds that arm. - Add a `retime` option to the NMG adapter. It forwards `NeuralPlannerCfg.constraints` and reports `native_timing=True`, since the row now solves a duration instead of assuming one. - Resolve those constraints from the sources the metrics validate against: velocity from `robot.get_qvel_limits()` and acceleration from the suite protocol, which `PlannerContext` now carries. A row that retimed against limits of its own choosing could satisfy them trivially, so the two must read from one place. Retiming with no protocol acceleration limit is an explicit error rather than a silent fallback. - Add `nmg_retimed` to the free-space suites, identical to `nmg` apart from `retime`, and assert that equality in tests so the pair cannot drift into measuring a configuration difference. The two rows share a path and differ only in timing, so the comparison reads directly off the report: the nominal row publishes its peaks and utilizations without a validity verdict, the retimed row carries both. Refs #684 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Follow-up to the same change, from review on #715. - `--nmg-onnx-path`, `--nmg-pos-eps` and `--nmg-rot-eps` updated only the row literally named `nmg`. The paired `nmg_retimed` row kept a null checkpoint, so its availability check skipped it and the comparison this change exists to run never ran. The overrides now apply to every `nmg_onnx` row, which also keeps the pair's tolerances identical so the comparison does not measure a tolerance difference alongside the timing one. - State in BENCHMARK_DESIGN that retiming constrains velocity and acceleration only. The suites also set a jerk limit and the metrics validate against it, so a retimed row can still exceed jerk. That is a real result about the policy's path, which retiming cannot smooth, not a gap in the guarantee. Refs #684 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A measured run showed the simulator reporting the float32 maximum for every joint velocity limit, so the retimed arm was constrained only by acceleration while still reporting itself as limit-respecting. Its low peak velocities came entirely from the 10 rad/s^2 acceleration bound, not from any velocity limit. Resolve the limit through the same helper the metrics use, preferring `protocol.joint_velocity_limit_rad_s` and rejecting a placeholder asset value, and raise when neither source supplies one. Retiming that silently leaves a constrained quantity unconstrained is worse than refusing to run. Refs #684 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
43eb4fd to
2025015
Compare
b0fcaa1 to
9379987
Compare
| num_joints = int(self.spec.config.get("num_arm_joints", 7)) | ||
| asset_limits = self.context.robot.get_qvel_limits( | ||
| name=self.context.control_part | ||
| )[0][:num_joints] |
There was a problem hiding this comment.
The constrains of each env should be the same, right?
Stack
main← Replace external TOPPRA with differentiable CPU/CUDA retiming #724 ← Measure dynamic limits and mark nominal timing in the NMG benchmark #713 ← Retime NMG rollouts under joint velocity and acceleration limits #714 ← Pair a nominal and a retimed NMG arm in the benchmark #715xinyi/nmg-toppra-retimingDescription
#713 measures dynamic limits and #714 lets NMG retime its rollout, but nothing yet runs the same policy both ways over the same cases. This PR adds that arm, which is the thing that actually answers "does retiming help, and what does it cost".
What changed:
retimeoption on the NMG adapter. It forwardsNeuralPlannerCfg.constraintsand reportsnative_timing=True, since the row now solves a duration instead of assuming one.robot.get_qvel_limits(), acceleration from the suite protocol, whichPlannerContextnow carries. A row that retimed against limits of its own choosing would satisfy them trivially, so both must read from one place. Retiming with no protocol acceleration limit raises rather than falling back silently.nmg_retimedin the free-space suites, identical tonmgapart fromretime. A test asserts that equality, so the pair cannot drift into measuring a configuration difference as well as a timing one.The two rows share a path and differ only in timing, so the comparison reads straight off
report.md: the nominal row publishes its peaks and utilizations with no validity verdict, the retimed row carries both plus a comparable duration.Both rows ship
enabled: falsewithonnx_model_path: null, matching the existing NMG row — no policy checkpoint is committed, so this changes no default run.Dependencies: none beyond the layers below.
Refs #684
Type of change
Measured evidence
Real NMG checkpoint (
swa3.onnx, K=5) on Franka FR3, on this stack with #724's backend. Both rows plan the same 9 free-space cases at W=1/3/5 from the same seeds, differing only byretime.nmgnmg_retimedPer case, acceleration limit utilization (1.0 = exactly at the limit):
nmgnmg_retimedTwo things a summary rate hides:
So the pair measures duration and some planning latency traded for executability, not accuracy. Latency is noisy on this machine (the nominal arm alone ranges 43–295 ms per case); retiming adds roughly 30–130 ms per plan at B=1.
A defect the run found
The first attempt produced a retimed arm bounded only by acceleration: the simulator reports the float32 maximum for every joint velocity limit, so retiming was constraining a quantity it then reported as respected. Fixed in
9379987e— retiming resolves its limits through the same helper the metrics use and refuses to run when neither the asset nor the protocol supplies a usable one.Not covered
Nine cases, one suite, one batch size (B=1, so the held-tail effect #726 fixes does not appear here), one checkpoint, one robot. Enough to show the pair runs and what it trades; not a leaderboard result.
Limit utilization for both arms over all nine measured cases, log scale, 1.0 = exactly at the limit. Every nominal case is outside both limits; every retimed case is under them, with acceleration at 0.998–1.000 throughout.
Validation
Proportional to the change, which is confined to the benchmark package and its tests:
python -m pytest tests/benchmark/motion_generation/ tests/sim/motion/planners/test_neural_planner.py— 163 passed, 1 skipped.black .— clean.python docs/scripts/check_api_docs.py— 2315/2315. No public API changed.context.py affectedreportsmotion-planningandsimulation-system, but only through the lower layers' files; this layer's own diff is entirely underscripts/benchmark/, which no context topic registers.BENCHMARK_DESIGN.mdsection 3.3 is updated here to describe the paired arm and why its limits are shared.Checklist
black .command to format the code base.python docs/scripts/check_api_docs.py), if applicable🤖 Generated with Claude Code