Repository navigation
docs: the vehicle plant in port-Hamiltonian form, a whitepaper for GRL-SNAM - #137
Merged
Merged
Conversation
…L-SNAM docs/vehicle-ph-plant.tex and its PDF (21 pages): the dynamic single-track vehicle that GRL-SNAM's controller drives, written as a port-Hamiltonian system on se(2)* at every tire slip, for researchers who want to check it. - The pH form: H = 1/2 v^T M v, the Lie-Poisson J(p), the tires' secant dissipation R (PSD sliding or not), the axle forces as the port with y = G^T v, why steering is not a power port, the speed floor's f_eps and grade as booked power lines, and tangent against secant. - The discrete step's per-step energy books (residual second order per step) and the live plant, cvc::physics::dyn_bike_plant. - The learned plant cvc::ph: RFF Matern GP levels, Cholesky SPD factors, the Lie-IMEX step, E[dH] with the noise power, the rollout objective; the EKF-ELBO stage is pending. - The navigator's per-step energy identity, its two checks, and context and projection work at each tick. - GRL-SNAM's side: the torch twins and their parity tiers, what is not twinned yet, and how a rollout or trainer can use the plant and its books. - A validation table: test, what it shows, tolerance, measured value and commit, measured on libcvc c1f104c0 (nav/ph/physics as in v3.7.1) and on GRL-SNAM 0e21085. Built with pdflatex (three passes, no warnings).
transfix
added a commit
that referenced
this pull request
Oct 28, 2026
…t slip in its wheel's frame (#138) Two commits, for Joe to review before merging: 1. a torch twin of libcvc's single-track vehicle in port-Hamiltonian form, with its per-step energy books; 2. `dyn_bike`'s front slip moved into its wheel's frame, following libcvc. They sit beside `dyn_plant` in `grl_snam/dyn_bike.py`. The whitepaper (#137, `docs/vehicle-ph-plant.tex` §8.2–8.3 and §10) lists the twin as missing. **1. The pH twin** (held to libcvc's `DynBikePH.Golden`, transfix/libcvc#848). New in `grl_snam/dyn_bike.py`, mirroring libcvc's `dyn_ph_*` in `cvc/nav/detail/dyn_bike.h`: - `dyn_ph_parts_at`: everything the form is built from at a state: - the axle forces (the port); - the tires' lateral forces and secant stiffnesses; - `u`, `sg`, `uf` and `Dx`; - the vectors `n_f`, `n_r`, `t_f`, `t_r`. - `dyn_ph_rates_at`: the power balance dH/dt = supplied − dissipated + floor + grade. - `dyn_ph_hamiltonian`: ½ vᵀMv. - `dyn_plant_books`: `dyn_plant`'s step, unchanged, plus its books: - the trapezoid of the rates between the step's start (with the actuators' outputs δ₁, a₁) and the twist the step reached before its limiters; - `limiter`: dH across the speed clamp and the low-speed blend; - `residual`: the rest. - `dyn_plant(..., with_free=True)` also returns the pre-limiter twist (libcvc's `dyn_step_free`). - `dyn_plant`'s step 2 moves into `_axles`, which the parts share. `tests/test_dyn_bike_ph_parity.py` checks the twin against `dyn_bike_ph_golden.json`, double tier, 1e-9 relative, on eight Humvee cases. Each case checks: - the parts and the rates; - one step's next state, pre-limiter twist and books; - the autograd gradient of a weighting of the books against libcvc's forward-mode duals. The file also tests that a batch books like its rows. A torch-only gate checks that the books close to second order on a swerve. **2. The wheel-frame front slip** (follows transfix/libcvc#852, approved by Joe). The front slip becomes the wheel-frame slip `dyn4`'s tires use: - alpha_f = −atan2(w_f, u_f); - w_f = cos δ (vy + lf r) − sin δ vx, which is n_f·v; - u_f is the floored forward speed in the wheel's frame; - the secant is rooted at w_f = 0. The implicit step's Jacobian takes the front tire's −S_f cos² δ (1, lf) on the body's y. In the pH twin, R's front term becomes S_f n_f n_fᵀ, and f_ε is round-off. Three fixtures are regenerated from libcvc#852: - `dyn_bike_golden.json`; - `dyn_bike_ph_golden.json`; - `material_ext_golden.json`: only its dynamic case changes; the surrogate and bicycle cases are byte-identical. **Measured** (torch 2.8, CPU, after both commits): - Worst relative difference from libcvc: | Values | Worst relative difference | |---|---| | Plant next state | 0 | | Plant gradient | 2.8e-16 | | pH parts | 3.4e-16 | | pH rates | 3.4e-16 | | Books | 7.1e-14 | | Books gradient | 4.4e-14 | - On the golden's cases, the floor power is at most 6e-13 W. - On the swerve, the mean |residual| per step falls 3.94× and then 3.97× per halving of the step. - `test_dyn_bike_parity`, `test_dyn_bike_ph_parity`, `test_material_ext_parity`, `test_dyn4_parity` and `test_material_bike_parity` give 57 passed and 6 skipped. The skips are live-pycvc checks that this machine's pycvc lacks. - ruff and black are clean on the changed files. pycvc has no dynamic binding, so none of this depends on a pycvc release.
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
docs/vehicle-ph-plant.texand its PDF (21 pages): a standalone whitepaper on the vehicle under GRL-SNAM's controller, the dynamic single-track plant, written as a port-Hamiltonian system. It is for researchers who want to check the theory and the implementation themselves.What it covers
The pH form, exact at every slip:
J(p)on se(2)*;R, PSD even when a tire slides;y = G^T v;f_epsand grade, booked as power lines of their own;A proposition, with its proof.
The discrete step's energy books, whose residual is second order per step, and the live plant
cvc::physics::dyn_bike_plant.The learned plant
cvc::ph:E[dH]including the noise power;The navigator: the per-step energy identity, its cheap bound and sharp check, and context and projection work at each tick.
External ports: how the form takes externally defined ports in general, with a navigation force as the worked example.
GRL-SNAM's side:
dyn_bike.py,dyn4.py,ext_rollout.py,material_bike.py,nav_potential.pyfrom nav_potential: U_nav evaluated, the torch twin of libcvc's, held to its golden #133) and their parity tiers, with LieSPHGP as the JAX reference;Future work:
dyn_4win pH form, and other limitations.Validation
Each claim maps to a test, with its tolerance, the measured value and the commit that added it (Section 9). The measured values come from:
c1f104c0(nav/ph/physics identical to v3.7.1):nav_dyn_bike_test21,ph_se2_test14,ph_se2_train_test8,nav_potential_test16 andphysics_dyn_bike_plant_test3, all passed.0e21085:test_dyn_bike_parity.py,test_nav_potential_parity.py,test_dyn4_parity.py,test_dyn4_ext_rollout_parity.pyandtest_material_ext_parity.py, 53 passed. 2 skipped because the local pycvc lacks the material external-force channel.The libcvc side is transfix/libcvc#831, #832 and #833, all released in 3.7.1.
Build
pdflatex vehicle-ph-plant.tex, three passes. The log has no warnings: no undefined references and no overfull or underfull boxes.