Add finite-difference tests for the _impl VFI constraint Jacobians - #15
Merged
Conversation
Complements tests/test_finite_difference.py (which checks the raw dqrobotics distance/plane Jacobians) by validating, by central finite differences, the wrapper Jacobians defined in _impl.py that build the NeedleController VFI rows: - rotation_axis_jacobian == d/dq of Ad(r(q), a) (vector-valued) - J_phi_z == d/dq of <n, Ad(r(q), k_)> - normal_dot_product_jacobian == d/dq of <n, Ad(r(q), a)> - J_dot_product_safe == d/dh[cos(phi_safe(h))] * Jh (and exactly zero in the saturated regions h <= h_min / h >= h_max) - phi_z_constraint_W == d/dq of [dot_product_safe(h(q)) - phi_z(q)] - insertion_J_D_safe == d/dq of tan^2(angle) * d_plane(q)^2 - insertion_W == d/dq of [D(q) - D_safe(q)] - needle_jacobian == every stacked row (radius / plane / normal / insertion / angular) is the FD gradient of its matching constraint scalar, with the correct sign and row order. The insertion tests place the needle tip at h_mid = (h_min + h_max)/2 above the vessel plane so the depth-dependent phi_z row sits in the linear (non-saturated) region and is differentiable. Pure-Python dqrobotics only (no compiled _core required). Co-authored-by: openhands <openhands@all-hands.dev>
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.
Adds
tests/test_impl_finite_difference.py, which validates — by central finite differences — the wrapper Jacobians defined inmarinholab/working/needlemanipulation/_impl.pythat build theNeedleControllerVFI constraint rows. This complements the existingtests/test_finite_difference.py, which checks the rawdqroboticsdistance/plane Jacobians.This PR was created by an AI agent (OpenHands) on behalf of the user.
What's validated
Each
_implJacobian is checked against the scalar (or vector) quantity its docstring/name says it differentiates:rotation_axis_jacobiand/dqofAd(r(q), a)(vector-valued, 4×4)J_phi_zd/dqof⟨n, Ad(r(q), k_)⟩normal_dot_product_jacobiand/dqof⟨n, Ad(r(q), a)⟩J_dot_product_safed/dh[cos(phi_safe(h))] · Jh(and exactly zero in the saturated regionsh ≤ h_min/h ≥ h_max)phi_z_constraint_Wd/dqof[dot_product_safe(h(q)) − phi_z(q)]insertion_J_D_safed/dqoftan²(angle)·d_plane(q)²insertion_Wd/dqof[D(q) − D_safe(q)](squared point-to-line minus the safe band)needle_jacobianAll errors are at FD precision (
≤ ~5e-9).Note on the insertion geometry
_implplaces the depth-dependentphi_z(angular) insertion constraint in the linear, non-saturated region only forh_min < h < h_max, wherehis the needle tip's signed distance to the vessel plane. To keep that row differentiable, the tests build the vessel-0 geometry at module scope so the tip (the frame position at the base config) sits exactly ath_mid = (h_min + h_max)/2, plus a small in-plane lateral offset so the tip is not on the vessel line (keeping both the point-to-line and plane gradients non-degenerate). Thephi_*/h_*constants mirror the values hard-coded inneedle_jacobian/needle_w.Scope
dqroboticsonly — no compiled_corerequired (works under the mock fallback too).tests/test_impl_finite_difference.py(11 tests).pytest: 23 passed (12 existing + 11 new).pyright: 0 errors.Co-authored-by: openhands <openhands@all-hands.dev>