Contents
Springs and dampers
Ride over a rough road
The whole car driven over a road of stated roughness: an ISO 8608 surface, seven degrees of freedom, the rear wheels a wheelbase behind, and how far each tyre's load swings.
A tyre's grip follows its load, and on a rough road the load never stands still. This page drives the template over a road of a stated roughness and measures how far the four contact-patch loads swing about their static values, how much the body moves, and how fast the dampers work. It takes the whole car, not a quarter of it, because the rear wheels meet every bump a moment after the front ones, and that delay is what pitches the body.
Seven degrees of freedom
The body is one rigid mass that heaves by , pitches by and rolls by , and each of the four wheels moves up and down on its own: seven degrees of freedom. Every motion is measured from static equilibrium, so is the car standing on a flat road and gravity drops out. Pitch is positive nose down and roll positive right side down, as on Axes, signs and units. With and a corner's position from the centre of gravity, forwards and to the left, the suspension at corner extends by
and pushes the body up with the corner spring and damper, and with the heave and roll elements on the halves of the axle's motion they see (Springs, bars, heave and roll elements):
- the other wheel of the same axle
- the corner spring and damper, at the wheel
- the heave element and its damper, at the wheel
- the roll element or bar and its damper, at the wheel
The body takes the four forces, and each wheel takes its own and the tyre's:
- the road's height under wheel
- the tyre's vertical rate, 110 N/mm
A damper part's curves take the coefficients' place when the car has one, bump and rebound apart, as Dampers reads them; the template damps with coefficients, the same both ways. The fourteen states are integrated by the fourth-order Runge–Kutta method. What the tyre puts on the road is its static share of the car's weight plus its spring's force:
The road
ISO 8608 classes a road by the power spectral density of its height, against spatial frequency , the number of waves per metre:
- the reference spatial frequency, a 10 m wave
- the waviness: how fast the roughness falls off at shorter waves
The classes run from A, a very good road, to E, a very poor one, and each has four times the last one's , so twice its height. The app builds a road of a class as a sum of waves, each carrying the share of the spectrum in its band:
- the distance along the road
- the band's geometric centre and width; the bands are spaced evenly in
- the wave's phase, drawn at random from a seeded generator, so one seed is always one road
A cosine of amplitude has a mean square of , which is why carries the factor 2. The waves run from 100 m long to 0.1 m: the longest a lap cares about to about the tyre's contact patch. The two tracks are two independent samples of the same class, seeds 1 and 1001. Real roads are alike under both tracks over long waves, so this overstates the roll a long wave puts into the car.
The wheelbase delay
A rear wheel reaches each point of the road a wheelbase after the front wheel on its side:
A wave whose length is , , and so on lifts one axle as it drops the other, and pitches the body without heaving it. A wave of length , and so on lifts both together and heaves it without pitching. This is the wheelbase filter, and the reason a ride study needs the whole car: four quarter cars side by side would never pitch.
What a ride study reads
The first number is how far each tyre's load swings about its static value, as a root mean square over the run:
A tyre's grip rises with its load, but less than in proportion (Slip and the Magic Formula). A tyre whose load swings up and down therefore has less grip on average than one held at its mean, and the load variation is the ride number that reaches the lap time. On this road the template's front right tyre came down to 102 N, against a static 692 N.
The others say how hard the car works. The body's vertical acceleration was 0.54 m/s² RMS, unweighted: a comfort weighting is defined for a seated person, and this model has no seat. The body pitched at 1.74 °/s RMS and rolled at 3.07 °/s. The front left damper moved at 33.5 mm/s RMS and spent 88 % of the run below 50 mm/s, which is why the low-speed part of a damper's curve is the part to set first (Dampers).
What the model assumes
- The body is rigid and the chassis does not twist. Springs and motion ratios are linear, taken at the static ride. A heave element with a gap or a rate of its own along its travel is the exception: the run follows it.
- Each tyre is a linear spring with a point contact under the wheel's centre. It does not span a short bump the way a real contact patch does. Its spring acts both ways in the motion; only the load it reports stops at zero, so a run in which a wheel spends long in the air is past what the model can say.
- The car runs straight at a steady speed, with no aerodynamic load and no load transfer from accelerating or cornering.
- The two tracks are independent samples of the same class.
- The car starts at rest on a flat road, and each wheel steps onto the rough one where it begins: the front wheels at once, the rear ones a wheelbase later. The run's numbers include that start.
In the app
Vehicle Dynamics › Ride over road runs it. Under "Define the road and run" the road is ISO A, C or E, a single bump or a step, with the speed, the duration, the dampers (the car's or a trial damper) and the seed; "Drive it" runs it. The panel opens on the run this page shows: ISO C at 15 m/s for 4 s, seed 1.
"Run outcome" gives the worst wheel-load variation, equation (9) as a share of the static load on the worst corner; the body acceleration; the pitch and roll rates; and the share of the run below 50 mm/s on the front left damper. It draws the damper velocity distribution, rebound positive, and the contact-patch loads over time. "Body motion" plots heave, pitch and roll, with pitch positive nose up.
Check it yourself
The script builds both roads from their seeds, drives the template over them with fourth-order Runge–Kutta as the app does, and reads off the same numbers.
>> rough_road At 15 m/s the rear wheels meet the front wheels' road 106.7 ms later. Quantity This script PaceDynamics Diff ----------------------------------------------------------------------------- left road, RMS elevation, mm 4.36917 4.36917 8.1e-14% integrator step, ms 1 1 0% FL static load, N 691.605 691.605 1.6e-14% FR static load, N 691.605 691.605 1.6e-14% RL static load, N 779.895 779.895 0% RR static load, N 779.895 779.895 0% FL load RMS, N 106.862 106.862 0% FL load RMS / static 0.154513 0.154513 1.8e-14% FL lightest load, N 388.035 388.035 0% FR load RMS, N 100.438 100.438 2.8e-14% FR load RMS / static 0.145224 0.145224 3.8e-14% FR lightest load, N 101.931 101.931 3.3e-13% RL load RMS, N 108.816 108.816 9.1e-14% RL load RMS / static 0.139527 0.139527 8e-14% RL lightest load, N 467.335 467.335 1.2e-14% RR load RMS, N 100.981 100.981 1.5e-13% RR load RMS / static 0.12948 0.12948 1.5e-13% RR lightest load, N 143.348 143.348 0% body vertical acceleration RMS, m/s^2 0.541224 0.541224 1.2e-13% pitch rate RMS, deg/s 1.7418 1.7418 5.1e-14% roll rate RMS, deg/s 3.07097 3.07097 0% FL damper speed RMS, mm/s 33.4925 33.4925 4.2e-14% FL share below 50 mm/s 0.875031 0.875031 0% FR damper speed RMS, mm/s 31.0958 31.0958 1.4e-13% FR share below 50 mm/s 0.910022 0.910022 0% RL damper speed RMS, mm/s 35.333 35.333 1e-13% RL share below 50 mm/s 0.864534 0.864534 0% RR damper speed RMS, mm/s 32.2961 32.2961 0% RR share below 50 mm/s 0.908523 0.908523 0% All 29 quantities agree with PaceDynamics (largest difference 3.3e-13 %).
The script
%% Ride over a rough road: an ISO 8608 road, the seven-degree-of-freedom car, the tyre loads % % Companion to the documentation page "Ride over a rough road". Runs unchanged in GNU Octave % (7 or later) and MATLAB. Edit the car in example_car.m and the run in example_springs.m % (car.ride) and run: % % >> rough_road % % The road is ISO 8608's displacement PSD, Phi(n) = Phi(n0) (n / n0)^-2, synthesised as a % sum of sinusoids with seeded random phases (pd_road.m), one road per track. The car is % a body that heaves, pitches and rolls on its four corners, each wheel on its tyre % (pd_ride.m), driven at a constant speed: the rear wheels meet the front wheels' road a % wheelbase later. What a ride study reads off it is how far each tyre's load swings about % its static share, because grip follows load, and how hard the body and the dampers work. % % References: ISO 8608:2016, Mechanical vibration - Road surface profiles - Reporting of % measured data; D. Cebon, Handbook of Vehicle-Road Interaction (Swets & Zeitlinger, 1999), % ch. 2; T. D. Gillespie, Fundamentals of Vehicle Dynamics (SAE, 1992), ch. 5. % % Part of the PaceDynamics documentation, https://pacedyn.dev/docs % SPDX-License-Identifier: MIT [car, ~] = example_car(); [spr, app] = example_springs(); app = app.ride; run = spr.ride; %% The road: one per track, independent samples of the same roughness left = pd_road(run, run.seed); right = pd_road(run, run.rightSeed); s = (0:4095) * run.length / 4096; z = arrayfun(left.at, s); fprintf('\n At %g m/s the rear wheels meet the front wheels'' road %.1f ms later.\n', run.speed, car.wheelbase / run.speed); pd_compare('left road, RMS elevation, mm', 1000 * sqrt(mean(z.^2)), 1000 * app.roadRms); %% The car over it out = pd_ride(car, spr.inertia, left, right, run); pd_compare('integrator step, ms', 1000 * out.step, 1000 * app.step); corners = {'FL', 'FR', 'RL', 'RR'}; for i = 1:4 pd_compare([corners{i} ' static load, N'], out.staticLoad(i), app.staticLoad(i)); end %% What a ride study reads rms = @(v) sqrt(mean(v.^2)); dev = out.wheelLoad - out.staticLoad; % each tyre's load about its static share for i = 1:4 pd_compare([corners{i} ' load RMS, N'], rms(dev(:, i)), app.loadRms(i)); pd_compare([corners{i} ' load RMS / static'], rms(dev(:, i)) / out.staticLoad(i), app.loadFraction(i)); pd_compare([corners{i} ' lightest load, N'], min(out.wheelLoad(:, i)), app.loadMin(i)); end pd_compare('body vertical acceleration RMS, m/s^2', rms(out.zdd), app.bodyAccelRms); rate = @(q) [0; diff(q)] / run.dt * 180 / pi; % deg/s, differenced between samples pd_compare('pitch rate RMS, deg/s', rms(rate(out.pitch)), app.pitchRateRms); pd_compare('roll rate RMS, deg/s', rms(rate(out.roll)), app.rollRateRms); vel = 1000 * out.damperVel; % mm/s at the wheel for i = 1:4 pd_compare([corners{i} ' damper speed RMS, mm/s'], rms(vel(:, i)), app.damperRms(i)); pd_compare([corners{i} ' share below 50 mm/s'], mean(abs(vel(:, i)) < 50), app.lowSpeed(i)); end pd_compare();
Download: rough_road.m · example_springs.m · example_car.m · pd_road.m · pd_ride.m · pd_compare.m. The scripts are MIT licensed.
Further reading
- ISO 8608:2016, Mechanical vibration — Road surface profiles — Reporting of measured data.
- D. Cebon, Handbook of Vehicle-Road Interaction (Swets & Zeitlinger, 1999), ch. 2, on road roughness and its synthesis.
- T. D. Gillespie, Fundamentals of Vehicle Dynamics (SAE, 1992), ch. 5, on ride and the wheelbase filter.