Repository navigation
T-111: SO-100 manipulator dynamics via Featherstone ABA (3rd real robot) - #7
Merged
Merged
Conversation
Makes "compile a calibrated robot" true for the zoo's first *manipulator*.
Zoo status: 3 of 4 robots now end-to-end (cartpole, crazyflie, so100).
Why it's different: a manipulator's forward dynamics need M(q)^-1, which the
lowering coverage table has no solve for. The lowerable route is Featherstone's
Articulated Body Algorithm — O(n) forward dynamics using only spatial matmuls
and scalar reciprocals 1/D_i, no matrix inverse.
- jaxility/zoo/so100/_dynamics.py: the ABA (spatial [angular;linear] algebra),
spatial tree sourced from the calibrated Robot so calibration propagates.
- so100 __init__: _dynamics_factory returns (f, (12,), (6,)); flip the entry to
a real dynamics factory.
- Lowering (jax_to_casadi.py): three general completeness fixes that unblock
rigid-body dynamics (and any matrix-heavy JAX fn), each with capability tests:
* broadcast_in_dim: rank-1 -> rank-2 row/col promotion, and scalar -> vector
materialization (a scalar feeding a matmul must be a real column, not a
scalar-multiply).
* dot_general: lift numpy constants; dispatch on contracting dims so a 1D.1D
inner product lowers to a.T @ b (scalar), not a 6x6.
* add/sub/mul/div: broadcast non-scalar shapes (outer products u[:,None] *
u[None,:]).
- Verified: ABA matches MJX functional_dynamics to ~1e-5 (manipulator grade),
lowers to CasADi (== JAX to 9e-13), calibration propagates.
Fidelity is manipulator-grade, NOT ULP: an independent ABA and MuJoCo's cinert
CRB diverge ~1e-6 on this featherweight arm (distal inertias ~1e-5) -- a
deterministic representational floor, not a bug. 1e-4 test bound. so100's WBC
OCP template is a T-024 follow-on, so `jaxility build so100` fails structurally
(like crazyflie) until it lands. Doc-drift: CLAIMS/KNOWN_GAPS/README + zoo tests.
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.
Makes "compile a calibrated robot" true for the zoo's first manipulator. Zoo status: 3 of 4 robots now end-to-end (cartpole, crazyflie, so100).
Why it's different
A manipulator's forward dynamics need
M(q)⁻¹, which the lowering coverage table has no solve for. The lowerable route is Featherstone's Articulated Body Algorithm — O(n) forward dynamics using only spatial matmuls and scalar reciprocals1/D_i, never forming a matrix inverse.What
jaxility/zoo/so100/_dynamics.py— the ABA (spatial[angular;linear]algebra); the spatial tree (transforms, axes, per-link mass/com/inertia) is read from the calibrated Robot so calibration propagates.__init__—_dynamics_factoryreturns(f, (12,), (6,)); the entry is now a real dynamics factory.jax_to_casadi.py) — three general completeness fixes that unblock rigid-body dynamics (and any matrix-heavy JAX fn), each with capability tests:broadcast_in_dim: rank-1→rank-2 row/col promotion + scalar→vector materialization (a scalar feeding a matmul must be a real column, not a scalar-multiply).dot_general: lift numpy constants; dispatch on contracting dims so a 1D·1D inner product lowers toaᵀ @ b(scalar), not a 6×6.add/sub/mul/div: broadcast non-scalar shapes (outer productsu[:,None] * u[None,:]).Verified
ABA matches MJX
functional_dynamicsto ~1e-5 (manipulator grade), lowers to CasADi (== JAXto 9e-13), calibration propagates. Full unit suite green (520 passed).Honest fidelity note
so100 is validated to manipulator grade, not ULP. An independent ABA and MuJoCo's internal
cinertCRB diverge ~1e-6 on this featherweight arm (distal inertias ~1e-5) — a deterministic representational floor, not a bug or round-off (established by an exhaustive debugging pass: FK exact 1e-16, com-Jacobian gravity exact 5e-17, longdouble-invariant). Tested at a1e-4bound.so100's WBC OCP template is a T-024 follow-on, so
jaxility build so100fails structurally (like crazyflie) until it lands. Doc-drift: CLAIMS / KNOWN_GAPS / README + zoo tests updated.🤖 Generated with Claude Code