Skip to main content

phyz_diff/rollout/
mod.rs

1//! Differentiable rollouts: exact parameter and contact-surface adjoints.
2//!
3//! Re-exported by the umbrella crate as `phyz::diff`.
4//!
5//! One backward pass of the discrete trajectory adjoint yields, for a
6//! semi-implicit Euler rollout with a final-state objective:
7//!
8//! 1. **`dJ/dπ`** per body — the 10 spatial-inertia scalars
9//!    `[m, cx, cy, cz, Ixx, Iyy, Izz, Ixy, Ixz, Iyz]`, exact (dual-number
10//!    lanes through a scalar-generic ABA; no finite differences). This is
11//!    the parameter sensitivity `StepJacobians` never covered.
12//! 2. **`∂J/∂x`** per collision-mesh vertex under the differentiable
13//!    per-vertex ground-penalty contact model — the cotangent a CAD-side
14//!    surface pullback (vcad's `surface_gradient`) consumes.
15//!
16//! See [`step`] and [`adjoint`] for the forward-model and contract details.
17//!
18//! # Which adjoint to use
19//!
20//! The contact model here is the module's **own** differentiable per-vertex
21//! ground-penalty law — *not* the convex solve the forward simulator
22//! (`phyz::Simulator::step_with_contacts`) integrates. It exists for the
23//! vcad surface-gradient seam (`∂J/∂vertex`), which needs a smooth force per
24//! vertex. For gradients of the physics the engine actually runs — state,
25//! control and inertia channels through the convex contact solve — use
26//! [`crate::contact_adjoint`] instead; its gradients match a finite
27//! difference of the real forward path, and this module's do not (measured:
28//! ~94% error on a box-drop mass gradient, `phyz`'s `diff_convex_contact.rs`
29//! gate).
30
31pub mod adjoint;
32pub mod step;
33
34pub use adjoint::{
35    AdjointGradients, AdjointRollout, ContactSetup, FinalStateObjective, adjoint_rollout_gradient,
36    rollout_objective,
37};
38pub use step::{
39    CollisionMesh, DofLayout, GroundContact, N_INERTIA_PARAMS, inertia_params, joint_nq,
40};