Add geometric FEP IK for Franka on CPU and CUDA - #662
Conversation
|
|
Thanks for the implementation. I reviewed the FEP solver against the existing 1. Reuse of
|
|
Thanks for the detailed review. Addressed in e0740eb:
Franka retains |
|
| q1 | q2 | q3 | q4 | q5 | q6 | q7 | Yoshikawa | |
|---|---|---|---|---|---|---|---|---|
| previous solution | -0.3943 | -0.5013 | 0.3615 | -1.6325 | 0.1860 | 2.4989 | 0.0 | 0.065584950149 |
| returned | 2.7409 | 0.5068 | -2.7745 | -1.6347 | 0.1909 | 2.4970 | 0.0 | 0.065585106611 |
The two scores differ by 2.4e-6 in relative terms, which is rounding, but argmax takes the second one and the command jumps 3.135 rad on q1 and 3.136 rad on q3 in a single control step.
The same tie also makes the result depend on an unrelated knob. On CUDA, changing only batch_size from the default to 7 changes the selected solution for 173 of 2000 random reachable targets, with joint deltas up to 5.53 rad, while the relative manipulability gap on those rows has a median of 5e-7.
redundancy_search limits the flip to the retained candidate pool, 0.45 rad on the same circle, and max_joint_step=0.04 clamps it to 0.0398 rad. The default fixed-q7 path has no such bound.
Suggestion
Break the tie with the weighted seed distance the slots are already ordered by: keep the incumbent slot unless a later one beats it by a relative tolerance, rather than taking a bare argmax. A note in the docstring that manipulability selection is not intended for sequential motion would also help, since the docs currently present it next to the "pass the previous solution as the next seed" guidance.
test_manipulability_ranks_valid_retained_candidates recomputes argmax the same way the implementation does, so it mirrors the behavior instead of pinning the property and cannot catch this.
Everything else checked out
Running the branch locally on an RTX 4090:
pytest tests/sim/motion/solvers/test_fep_solver.py --run-gpu: 122 passedblack --checkon the five touched files,docs/scripts/check_api_docs.pyat 2180/2180, andcontext.py checkall pass- CPU and CUDA return bit-identical joints for both fixed-q7 and search
max_joint_stepshowed zero violations at 0.02, 0.05 and 0.2- chunked and unchunked results match for nearest and for search
- over 4000 random reachable targets: known-q7 and search both at 100% success, max position error 4.6e-6 m
Yuan-Xinyi
left a comment
There was a problem hiding this comment.
approved only with minor suggestions
|
Thanks for the detailed report and reproduction. Confirmed and fixed in The bare
A candidate with materially higher manipulability still wins. The seed-distance rule only applies to numerically equivalent scores. I also replaced the previous Using the full reproduction above: |
Description
Add
FEPSolverandFEPSolverCfgfor Franka-compatible arms, using geometric screw-axis reconstruction. CPU and CUDA share the same Warp implementation, with geometry and fixed transforms extracted and validated from the URDF. FEP remains opt-in; Franka keeps its existing Pytorch solver default.ik_solution_selection="nearest"|"manipulability"using the shared Yoshikawa metric. Near-equal manipulability scores use weighted seed distance as a deterministic continuity tie-break. Reject numericalnum_samplesexplicitly; q7 search has separate semantics. Preserve Robot IK result shapes and runtime limit synchronization.Dependencies: no new package dependencies.
Related issue: N/A.
Validation:
git diff --check, and agent-context checks passed.--radius 0.15 --redundancy-search --headless --max-steps 301): all 301 targets solved; maximum IK error 0.0002 mm, mean/max physical tracking error 0.671/1.911 mm.Known limitations:
Type of change
Screenshots
N/A. Run
python -m examples.sim.motion.solvers.fep_solver --device cuda --radius 0.15 --redundancy-searchto view the target circle and actual TCP trajectory.fep_solver-2026-09-20_17.30.30.mp4
Checklist
black .command to format the code base.python docs/scripts/check_api_docs.py), if applicable.