Repository navigation
nav: dyn4_plant, the differentiable two-track vehicle with suspension (P8d) - #731
Merged
Merged
Conversation
… (P8d) diff::dyn4_plant (inc/cvc/nav/detail/dyn_4w.h) is P8a's vehicle on four contact patches: - the wheels at (lf, +-tf) and (-lr, +-tr), the front pair at the Ackermann angles of the virtual centre wheel; - each wheel's friction and terrain height from a ground sampler, templated on the scalar so the terrain's gradient flows through the duals; - each corner's spring-damper as its tire's load, softplus-floored; - Pacejka per tire within the friction ellipse, (vy, r) by P8a's implicit secant solve on four tires, and (z, roll, pitch) by an implicit 3x3 step on the corners' springs and dampers, driven by the ground and the tire forces' moments. The VJP is forward-mode duals (dyn4_plant_vjp); dyn4_bike_step / _bwd put bike_control in front. Parameters from the spec sheet: nav_plant::dyn4_si_of (P8a's numbers, the axles' half tracks, the chassis box's roll and pitch inertias, each corner's spring and damper from its axle's suspension frequency and damping ratio), dyn4_params_of and dyn4_params_at (inc/cvc/nav/dyn_4w.h). nav_dyn_4w_test (the Humvee): rests on flat ground; the single-track limit within 0.053 m of dyn_plant over 95 m; steady roll and braking load transfer exactly balanced; mu-split braking yaws toward the high-mu side; a bump loads its own wheel (1.37x against 1.11x); the VJP against central differences 3.7e-9; one step under the controller 6.2e-5; lateral acceleration <= 0.97 mu g and stopping within 8% of v^2/(2 mu g); within 4% and 7% of Jolt's Humvee skidpad and stopping. Documented in NAV_TRAINING.md. 372/372 nav/physics/plant ctest cases locally.
dyn4_ackermann(L, y, tan delta) is the front wheel's angle the plant uses. TheFrontWheelsFollowAckermann is Jolt's P2 gate (cot(right) - cot(left) = track / wheelbase, exact) plus the turn it gives: held at delta at 3 m/s with the low-speed blend off, the rear axle's circle is L / tan(delta) within +0.10 / +0.17 / +0.32% at 0.15 / 0.30 / 0.45 rad. Dyn4.Golden writes tests/data/dyn4_golden.json (CVC_DYN4_GOLDEN_WRITE=1): the sprung and the rigid Humvee on a mu split with a bump, eleven cases' next states and VJPs, which this build reproduces to 1e-9 and GRL-SNAM's torch twin is held to.
transfix
added a commit
to CVC-Lab/GRL-SNAM
that referenced
this pull request
Oct 19, 2026
…y against its golden (#123) grl_snam.dyn4.dyn4_plant is libcvc's diff::dyn4_plant (P8d, transfix/libcvc#731): four contact patches with Ackermann front wheels, a ground callable (wx, wy) -> (mu, height) per wheel, spring-damper corners floored by softplus, four tires in the implicit (vy, r) solve, and heave, roll and pitch by an implicit 3x3 step. The corners' rates follow libcvc's float arithmetic. tests/test_dyn4_parity.py holds it to libcvc's dyn4_golden.json (Dyn4.Golden, libcvc@368c0e4a): the sprung and rigid Humvee on a mu split with a bump, eleven cases. Measured worst relative error: next state 4.2e-17, VJP 1.7e-15 (the gate is 1e-9). Also a batch, the Ackermann relation, and stopping from 20 m/s within 10% of v^2 / (2 mu g).
The comments and docs describe ext_force as a hook for a caller's own force, without naming a downstream user.
Owner
Author
|
Heads-up: #753 (merged, 2028671) changes what this PR builds on.
This branch still merges with master without conflicts, but merged,
Changing
What remains is to regenerate the golden after merging master ( |
… golden regenerated #753 fitted dyn_bike_si_of's tires to Jolt and made its defaults front_stiffness 1 and drive_lag by drivetrain. dyn4_si_of still passed the old 0.85 and 0.1, so the four-wheel Humvee's front B was 0.85x the single track's and four dyn4 tests failed. Its defaults are now 1.0 and -1.0, and dyn4_golden.json is regenerated with the new tires. The envelope test measures the body's lateral acceleration (vy' + r vx), as DynBike.SteadyLateralNeverExceedsMuG does since #753: on the softer tires r vx alone read 1.03 mu g at mu 0.4. NAV_TRAINING.md's P8a parameters (stale since #753) and dyn4's gate numbers are updated. nav_dyn_4w_test 12/12.
# Conflicts: # src/cvc/tests/CMakeLists.txt
transfix
enabled auto-merge (squash)
October 21, 2026 18:41
transfix
added a commit
to CVC-Lab/GRL-SNAM
that referenced
this pull request
Oct 21, 2026
Copies libcvc's regenerated tests/fixtures/dyn4_golden.json (transfix/libcvc#731 at 8ef864171: dyn4_si_of on #753's Jolt-fitted dyn_bike_si_of defaults). grl_snam/dyn4.py reads the vehicle from the file, so no code changes; test_dyn4_parity and test_dyn_bike_parity pass.
# Conflicts: # src/cvc/tests/CMakeLists.txt
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.
P8d from the roadmap's P8 plan (item 5): the differentiable four-wheel vehicle, so the controller can train on a body that rolls, pitches and loads its wheels unevenly, as Jolt's do.
What it is
diff::dyn4_plant(inc/cvc/nav/detail/dyn_4w.h) is P8a'sdyn_planton four contact patches. The state has 14 entries: position, yaw, (vx, vy, r), heave, roll and pitch with their rates, and the steer and drive lags.flat_groundis the default.dyn4_plant_vjp).dyn4_bike_stepanddyn4_bike_step_bwdputbike_controlin front of the plant.Parameters come from the spec sheet:
nav_plant::dyn4_si_of(desc)takes P8a's numbers and adds the half tracks, the chassis box's roll and pitch inertias, and each corner's spring and damper from its axle's suspension frequency and damping ratio.dyn4_params_ofanddyn4_params_atscale these to the scene's frame.Gates (
nav_dyn_4w_test, the Humvee; with #753's Jolt-fitted tires since 8ef8641)dyn_plantover a 93 m drive (0.053 m over 95 m before #753)tests/data/dyn4_golden.json: the sprung and rigid Humvee on a μ split with a bump, 11 cases of next state and VJP, reproduced to 1e-9The controller gradcheck started off the SDF grid nodes because the scene's sampled starts lie on them. Central differences at a node straddle bilinear kinks: unjittered, the same check reads 5e-2. P8b's dynamic gradcheck may have the same artifact. That is a follow-up.
Docs
NAV_TRAINING.md has a new section, "The four-wheel vehicle:
dyn4_plant(P8d)".Verified locally
Windows build from the cvcpkg prefix: all 372 nav, physics and plant ctest cases pass, and the 12 dyn4 tests pass after the follow-up commit. clang-format 18 is clean on the changed files.
The torch twin
CVC-Lab/GRL-SNAM#123 (
grl_snam/dyn4.py) is held to the golden. Its worst relative error is 4.2e-17 on the next state and 1.7e-15 on the VJP. CVC-Lab/GRL-SNAM#135 carries the regenerated golden; merge it together with this PR.Not in this PR
Aligned with #753 (8ef8641)
#753 (merged) fitted
dyn_bike_si_of's tires to Jolt: B·C = 1.12 / α_peak. It also made its defaultsfront_stiffness1 anddrive_lag-1 (by drivetrain).dyn4_si_ofstill passed the old 0.85 and 0.1. Merged with master, 4 of 12 dyn4 tests failed: the four-wheel Humvee's front B was 9.10 against the single track's 10.71.dyn4_si_of's are nowfront_stiffness = 1.0, drive_lag = -1.0, followingdyn_bike_si_of's.dyn4_golden.jsonis regenerated with the new tires.EnvelopesOnFourWheelsmeasures the body's lateral acceleration (vy′ + r vx), asDynBike.SteadyLateralNeverExceedsMuGdoes since physics: fit dyn_bike_si_of to Jolt (tires, direct drive); P8b training now helps on Jolt #753. On the softer tires the vehicle drifts and r vx alone read 1.03 μg at μ 0.4.The gates above are the new numbers. The softer tires take the skidpad further from Jolt's (6.30 against 6.85 m/s², still within the 10% gate). Under μ-split braking it yaws more: −0.89 rad in 1.8 s, against −0.16 before.
Master is merged in (362b3b6). Locally (Linux, Jolt 5.6.0+cvc.6):
nav_dyn_4w_test12/12.