Repository navigation
nav: dyn_4w is port-Hamiltonian at every slip, with per-step energy books - #850
Merged
Merged
Conversation
…ooks The four-wheel plant (P8d) gets the single track's explicit pH form (#831). In x = (q, p), with q = (z, phi, th) and p = M xi for the twist xi = (vx, vy, r, zd, phid, thd), its vector field is exactly H = 1/2 xi^T M xi + sum_i 1/2 k_i l_i^2 + m g z x' = (J(p) - R) dH/dx + G u + f_lever, u = (F_x1..F_x4), y = G^T dH/dx J = [[0, 0, I], [0, J_h(p_h), 0], [-I, 0, 0]] R = blockdiag(0, c_x e_x e_x^T + sum_i S_i n_i n_i^T, sum_i c'_i c_i c_i^T) - Each slip is in its wheel's frame, rooted at w_i = n_i . v = 0, so the secant S_i = -F_yi / w_i carries the whole lateral force: f_eps = 0. S_i >= 0 at any slip and any steering angle, so R is PSD sliding or not. - H carries the corners' springs and gravity on heave; R_v the dampers. - G's columns are the wheels' drive and brake forces at their contact patches, h below the centre of gravity, so y_i includes the roll and pitch rates and y^T u is the forces' whole power. Steering only turns n_i and G's columns, so it does no work. - f_lever: the tires' lateral forces' moments on roll and pitch (h FY). The slips do not see the body's roll and pitch rates, so this coupling is one-way, in neither J nor R. It is booked on its own line and is zero with h = 0. - dH/dt = -dH/dx^T R dH/dx + y^T u + xi^T f_lever, plus the ground lifting the springs as the wheels roll over it (none on flat ground). dyn4_plant takes an optional dyn_step_free*, as dyn_plant does, and dyn4_plant_books books each step: dH = supplied - dissipated + lever + ground + limiter + residual. The plant's outputs and VJP are unchanged: on the Windows build, dyn4_golden.json and dyn4_ext_rollout_golden.json regenerate byte-for-byte the same from this branch as from master. Gates (nav_dyn_4w_test, Dyn4PH): - the structure at 500 states on each of flat ground (mu 0.9, 0.6) and the golden's split-and-bump ground, sprung and rigid, 267 of them with a tire past its peak: J skew; R symmetric with lambda_min >= -1e-9 |R|; dH/dx against H's central differences (6e-8); nothing supplied with the wheels' forces at zero; - the vector field against a 1e-5 s dyn4_plant step, forward and reversing, flat and split-and-bump: worst 2.0e-4 of each row's scale; - the step books over 8 s of a 0.2 Hz weave to near full lock, 27% of the steps with a tire past its peak (slips to 0.68 rad; the peak is at 0.345): the per-step residual falls 3.85-3.98x per halving of hdt, flat and over hills, and |sum residual| / flow at 0.01 s is 5.0e-4 flat and 1.0e-3 over hills. Braking to a stop charges the clamp and the blend; the ground line is zero on flat ground and the lever line zero with h = 0.
dyn_4w has no gravity along the ground: the terrain only lifts the springs, so a vehicle climbs a hill for free and the books show that energy as the ground line, from outside. dyn4_params::grade_force (dyn4_si::grade_force), off by default, adds it: - dyn4_grade: each spring's horizontal reaction on the slope under its wheel, -F_i grad h(P_i), F_i the linear spring force, as a force and yaw moment on (vx, vy, r), from the step's start. That is minus the gradient of H's springs in the pose, so it is conservative: with the pose in the state it belongs to J, and the terrain's energy is in H. The slope is the ground's by central differences over 1e-3 L, so any sampler serves. - The pH form gains f_grade (dyn4_ph_grade), the rates and the books a grade line. Its power cancels the ground line's. Off, nothing changes: dyn4_golden.json and dyn4_ext_rollout_golden.json still regenerate byte-for-byte the same as master's on the Windows build. Gates (Dyn4PH): - the grade force against H's central differences in (x, y, psi): within 3.6e-7 m g on the golden's bump, 2.1e-8 m g over hills; - the vector field with it on: worst 2.0e-4 of each row's scale; - over hills, swerving past the peak: without it the ground line is +2868 J at 0.01 s; with it ground +3373 J and grade -3372 J, and |ground + grade| per step falls 4.0x per halving of hdt (second order); - coasting up a 5% ramp for 2 s from 10 m/s (no drag, dampers nearly off): without it the speed holds and H gains m g times the climb, all from the ground line; with it the coast loses 0.986 m/s against g s t = 0.981 and H holds to 0.8% of the climb at 0.0025 s (the step holds the ground at its start: first order, 4x smaller than at 0.01 s). The plant's dampers act on the body's own vertical rate, not on its rate relative to the ground, so with them a steady climb also pays c zd^2 per corner (about 11 kJ on that ramp); the books show it as dissipation.
transfix
added a commit
that referenced
this pull request
Oct 28, 2026
The project version and the cvcpkg recipe family move to 3.7.2. Every recipe is at cvc_revision 1 already, so none restarts. 3.7.2 carries the dynamic plants on the terrain and in a Jolt world, and the four-wheel plant (#869): --plant dynamic and dynamic4w drive the ground, collide with the buildings and each other, and book the collisions. It also carries dyn_4w's port-Hamiltonian form (#850), dyn_bike's wheel-frame front slip (#852), the books goldens for GRL-SNAM's twins (#848, #849), pycvc's drive telemetry (#857) and keep-alives (#864), the macOS SDK's openssl (#846), and the state_exec scheduler and evaluator work (#842, #843, #844, #861, #863).
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.
The four-wheel plant (
inc/cvc/nav/detail/dyn_4w.h, P8d) now has an explicit port-Hamiltonian form and per-step energy books. It follows the single track's form from #831 (dyn_ph_*,dyn_plant_books).The form
In x = (q, p), with q = (z, φ, θ) and p = M ξ for the twist ξ = (vx, vy, r, ż, φ̇, θ̇),
dyn4_plant's vector field is exactly:dyn4_ph_secant) therefore carries the whole lateral force. Sᵢ ≥ 0 at any slip and any steering angle, so R is positive semi-definite whether the tires slide or not.The grade force (opt-in)
dyn_4whas no gravity along the ground. The terrain only lifts the springs, so a vehicle climbs a hill for free, and the books show that energy as the ground line, coming from outside.dyn4_params::grade_force(anddyn4_si::grade_force) adds it. It is off by default, so the plant, its goldens and GRL-SNAM's twin are unchanged.dyn4_gradeapplies each spring's horizontal reaction on the slope under its wheel, −Fᵢ ∇h(Pᵢ), as a force and yaw moment on (vx, vy, r).f_grade(dyn4_ph_grade), and the rates and books gain a grade line. Its power cancels the ground line's.The books
dyn4_planttakes an optionaldyn_step_free*, asdyn_plantdoes.dyn4_plant_booksreturns each step's books: dH = supplied − dissipated + lever + grade + ground + limiter + residual.The plant's outputs and VJP are unchanged. On the Windows build,
dyn4_golden.jsonanddyn4_ext_rollout_golden.jsonregenerate byte-for-byte the same from this branch as from master. GRL-SNAM'stest_dyn4_parity.pyfixtures stay valid.Gates (
nav_dyn_4w_test,Dyn4PH.*)dyn4_plantstep againstdyn4_ph_rhs, forward and reversing, on flat and split-and-bump ground. Worst error: 2.0e-4 of each row's scale.Two findings about the plant, left for a separate decision (not changed here):
Run locally on Windows (MSVC, Release):
nav_dyn_4w_test21/21 (includingDyn4.GoldenandDyn4ExtRollout.Golden) andnav_dyn_bike_test21/21.