Add per-point Yoshikawa manipulability to workspace analysis - #614
Open
Yuan-Xinyi wants to merge 4 commits into
Open
Add per-point Yoshikawa manipulability to workspace analysis#614Yuan-Xinyi wants to merge 4 commits into
Yuan-Xinyi wants to merge 4 commits into
Conversation
Wire the metrics module into WorkspaceAnalyzer (closing the long-standing _compute_metrics TODO) and compute true per-configuration Yoshikawa manipulability w = sqrt(det(J J^T)) from the active solver's Jacobian after every analysis mode. Scores are row-aligned with joint_configurations (and with reachable points in Cartesian/plane modes), stored in results.npz, restored on cache hits, and aggregated under metrics["manipulability"]. Computation is gated on MetricConfig.enabled_metrics and costs ~10 ms per 470 configurations on GPU. Remove ManipulabilityMetric's centroid-distance placeholder: measured on Franka it is negatively correlated with true manipulability (corr = -0.37), so consumers ranking by it preferred worse configurations. Without Jacobians or precomputed scores the metric now warns and returns no statistics instead of fabricating them. The batching test's mock robot now returns None from get_solver, faithful to Robot.get_solver with no solvers attached. Also documented in the robot-workspace context: enabling the #599 seed-selection sampler speeds Cartesian reachability analysis 3.3x at unchanged num_samples=30 while detecting slightly more reachable points (measured on Franka, 4000 identical targets), with no analyzer changes. Covered by tests/sim/motion/workspace/test_manipulability.py; the full workspace suite passes (68 passed). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Address two review findings on the manipulability integration: 1. Metric settings are deliberately not part of the results-cache key (a metric toggle must not invalidate the expensive sampling/IK work), so a cache entry written under a different metric configuration — or before manipulability existed — could be returned without scores. The cache-hit path now runs the same _apply_manipulability step as fresh analysis, recomputing scores and aggregates from the cached joint configurations in milliseconds and repairing such entries transparently. 2. The analyzer reduced Jacobians to Yoshikawa scalars and discarded them, so the default compute_isotropy=True could never produce its documented condition statistics. The chunked Jacobian sweep now also collects condition numbers (max/min singular value) when isotropy is enabled, and ManipulabilityMetric accepts them precomputed. Tests cover the repair path (an entry written with manipulability disabled is repaired by a later default-enabled hit on the same key), isotropy presence via the analyzer, and precomputed condition-number passthrough. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The repair-on-load path handled a disabled-producer entry hit by an enabled run, but not the symmetric direction: an enabled-producer entry hit by a disabled run leaked stale manipulability_scores and metrics["manipulability"] into the returned results, diverging from the fresh-analysis contract. _apply_manipulability now strips both fields when the metric is disabled, and keeps cached scores when the metric is enabled but locally not computable (they remain valid for the same joint configurations). Covered by test_cache_hit_strips_fields_when_metric_disabled, which writes a score-bearing entry first so the strip path is genuinely exercised on the hit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…config On a cache hit where the current robot has no solver, the previous branch kept both the cached scores and the producer's aggregate metrics, so the returned means/counts could reflect a different jacobian_threshold and condition statistics could be present with isotropy disabled (or stale when enabled). Cached scores are pure kinematics and stay valid, but aggregates now always go through ManipulabilityMetric under the CURRENT configuration; per-point condition numbers are not cached, so condition statistics are correctly absent on this path instead of leaking through. Covered by test_no_solver_hit_recomputes_aggregates_under_current_config: a mock no-solver robot hits an entry carrying producer aggregates from a different configuration, and the returned aggregates honour the current threshold while the stale mean_condition is removed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
yuecideng
self-requested a review
September 11, 2026 14:07
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stack
perf/workspace-batchingDescription
This PR wires true per-point Yoshikawa manipulability into workspace analysis and documents a measured, configuration-only speedup of Cartesian/plane reachability analysis via the seed-selection sampler from #599.
1. Per-point manipulability (new)
The
metrics/subpackage was never invoked by the analyzer (_compute_metricscarried aTODO), andManipulabilityMetricwithout Jacobians fell back to a centroid-distance placeholder. We measured that placeholder against ground truth on Franka (470 reachable points):The placeholder is not merely inaccurate — it is anti-correlated with true manipulability, so any consumer ranking by it preferred worse configurations. This PR:
w = sqrt(det(J J^T))from the active solver's Jacobian over the storedjoint_configurationsafter analysis (all three modes), row-aligned with the configurations and, in Cartesian/plane modes, with the reachable points;manipulability_scoresin the results dict andresults.npz, restores it on cache hits, and reports aggregates undermetrics["manipulability"](closing the_compute_metricsTODO via the metrics module);MetricConfig.enabled_metrics(defaultALL— on);ManipulabilityMetricwithout Jacobians or precomputed scores now warns and returns no statistics — fabricated numbers are worse than none;Downstream, the aligned scores enable score-weighted runtime sampling (
RobotWorkspacealready supports weights) and manipulability-aware seed re-ranking as follow-ups; both are out of scope here.2. Seed-selection speedup for Cartesian/plane analysis (documentation + measurement)
Cartesian/plane reachability runs through the solver's multi-start
get_ik, where each analyzer seed occupies slot 0 of the solver-internal multi-start — soPytorchSolverCfg.enable_seed_selection(#599) applies with zero analyzer changes. Measured on Franka, 4000 identical sampled points (fixed RNG), warm timings (compile excluded), 1 seed/point:num_samples=30, random (default)enable_seed_selection,num_samples=30enable_seed_selection,num_samples=8enable_seed_selection,num_samples=4At unchanged
num_samples=30the seeded configuration is strictly better: more reachable points detected and 3.3× faster (good seeds converge in fewer DLS iterations underearly_stopping_any_converged). The recipe and numbers are recorded in the robot-workspace context docs; analytic solvers (OPW/SRS/UR) are unaffected.Dependencies: none beyond #606.
Type of change
Screenshots
N/A
Checklist
black .command to format the code base.agent_contextrobot-workspace topic: manipulability contract, seed-selection recipe; MAP keywords)python docs/scripts/check_api_docs.py: 1853/1853)tests/sim/motion/workspace/test_manipulability.py: exact Yoshikawa on synthetic Jacobians, precomputed-score precedence, no-fabricated-statistics guard, end-to-end alignment on CobotMagic, metric gating, cache serialization round-trip)Validation
Note: one behavioural change is intentional —
ManipulabilityMetric.compute()without Jacobians/scores now returns{}with a warning instead of placeholder statistics. Given the measured anti-correlation, silent consumers of the old numbers were being misled; failing loudly is the safer contract.