Port JacobianVerifier to solver/datagen/jacobian.py #3

Closed
opened 2026-02-02 19:32:18 +00:00 by forbes · 0 comments
Owner

Summary

Move JacobianVerifier class from data/synthetic/pebble-game.py (L375-902) into solver/datagen/jacobian.py.

Class overview

Builds the constraint Jacobian matrix for numerical rank verification. The pebble game gives a combinatorial necessary condition for rigidity; the Jacobian provides the sufficient condition by detecting geometric degeneracies (e.g., parallel revolute axes creating hidden dependencies).

The generalized velocity vector for n bodies is v = [v1_x, v1_y, v1_z, w1_x, w1_y, w1_z, ..., vn_x, ..., wn_z]. Each scalar constraint contributes one row to J such that dC_i/dt = J_i @ v = 0.

Methods to port

  • __init__(bodies) — sets up body index mapping, empty Jacobian
  • _body_cols(body_id) — column range for a body in J
  • add_joint_constraints(joint) — dispatches to per-type builder
  • _make_row() — zero row of width 6*n_bodies
  • _skew(v) — skew-symmetric matrix for cross product
  • Joint builders (one per JointType):
    • _build_ball (3 rows), _build_fixed (6), _build_revolute (5)
    • _build_cylindrical (4), _build_slider (5), _build_planar (3)
    • _build_distance (1), _build_parallel (3), _build_perpendicular (1)
    • _build_universal (4), _build_screw (5)
  • _perpendicular_pair(axis) — generates orthogonal basis
  • get_jacobian() — returns full J matrix
  • numerical_rank(tol) — SVD-based rank
  • find_dependencies(tol) — incremental rank check to identify redundant rows

Requirements

  • Import types from solver.datagen.types (RigidBody, Joint, JointType)
  • Full type annotations
  • Preserve Jacobian derivation docstrings (Chappuis reference)
  • No behavioral changes
  • __all__ = ["JacobianVerifier"]

Depends on

  • #1 (shared types)
## Summary Move `JacobianVerifier` class from `data/synthetic/pebble-game.py` (L375-902) into `solver/datagen/jacobian.py`. ## Class overview Builds the constraint Jacobian matrix for numerical rank verification. The pebble game gives a combinatorial necessary condition for rigidity; the Jacobian provides the sufficient condition by detecting geometric degeneracies (e.g., parallel revolute axes creating hidden dependencies). The generalized velocity vector for n bodies is `v = [v1_x, v1_y, v1_z, w1_x, w1_y, w1_z, ..., vn_x, ..., wn_z]`. Each scalar constraint contributes one row to J such that `dC_i/dt = J_i @ v = 0`. ## Methods to port - `__init__(bodies)` — sets up body index mapping, empty Jacobian - `_body_cols(body_id)` — column range for a body in J - `add_joint_constraints(joint)` — dispatches to per-type builder - `_make_row()` — zero row of width 6*n_bodies - `_skew(v)` — skew-symmetric matrix for cross product - Joint builders (one per JointType): - `_build_ball` (3 rows), `_build_fixed` (6), `_build_revolute` (5) - `_build_cylindrical` (4), `_build_slider` (5), `_build_planar` (3) - `_build_distance` (1), `_build_parallel` (3), `_build_perpendicular` (1) - `_build_universal` (4), `_build_screw` (5) - `_perpendicular_pair(axis)` — generates orthogonal basis - `get_jacobian()` — returns full J matrix - `numerical_rank(tol)` — SVD-based rank - `find_dependencies(tol)` — incremental rank check to identify redundant rows ## Requirements - [ ] Import types from `solver.datagen.types` (RigidBody, Joint, JointType) - [ ] Full type annotations - [ ] Preserve Jacobian derivation docstrings (Chappuis reference) - [ ] No behavioral changes - [ ] `__all__ = ["JacobianVerifier"]` ## Depends on - #1 (shared types)
forbes added the phase:1port labels 2026-02-02 19:32:18 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: kindred/solver#3