PaceDynamics Documentation Open the app
Contents

Loads

Load transfer

How cornering and braking move the car's weight between its wheels, and which parts of the car decide where it goes.

Model as of 0.338Figures from the Formula Student single-car templateOctave check Exact

A car that corners or brakes does not change its weight, but it changes where the weight sits. The inertia force acts at the centre of gravity, above the road, and the tyres push at road level: the couple between them loads the outside wheels and unloads the inside ones, or the front and the rear. How much moves is set by the CG height and the track or wheelbase. How it divides between the front and rear axles is set by the suspension, and it is one of the strongest levers on a car's balance.

Three paths to the road

In a steady corner each axle carries its share of the sideways force, and the load it moves from its inside to its outside wheel takes three paths:

Rear view of the car in a left turn: the inertia force at the centre of gravity, the roll centre, the unsprung masses, and the three paths load takes to the tyresmuroll centrem ayhrahrctRear view, turning left: the inertia force points right
Elastic: the body’s roll moment, on the springsGeometric: through the links, at the roll centreUnsprung: the wheels’ own inertia
Fig. 1
The same corner, three ways to the road: through the springs, through the links at the roll centre, and through the unsprung parts.
Schematic
  • Elastic. The sprung mass rolls on its springs. The roll moment is the sideways force times the CG's height above the roll axis, and each axle takes a share of it by its share of the roll stiffness.
  • Geometric. The force reaches each axle's roll centre and goes through the links without rolling the body. Its moment arm is the roll-centre height.
  • Unsprung. The wheels, uprights and brakes are pushed sideways at their own height and go straight to the tyres.
Side view: the roll axis through the front and rear roll centres, and the height of the centre of gravity above ithrahrc,fhrc,rbLroll axisSide view, front to the right, not to scale
Fig. 2
The roll axis joins the two roll centres; the body rolls about it, and its moment arm is the CG’s height above it.
Schematic

The lateral transfer

For a steady corner at lateral acceleration ay, each axle moves a load ΔFz from its inside wheel to its outside one:

Show the equations with
ΔFz=ayt(mshraGφKφ,axleKφ+ms,axlehrc+mu,axlehu)(1)
ΔFz,fay/g=9.81⋅(33.36+0.337+2.956)=359.5 N per g(1)
ms,ms,axle
the sprung mass, and the share of it the axle carries
hra
the CG's height above the roll axis, where the CG is
Gφ
the roll gain from the CG swinging outboard, from Ride and roll rates
Kφ,axle/Kφ
the axle's share of the roll stiffness
hrc
the axle's roll-centre height
mu,axle,hu
the axle's two unsprung masses and the height of their CG, about the wheel centre

The rear moves 359.4 N per g. On the template almost all of it is elastic: its roll centres are only a few millimetres above the road, so the geometric path carries about one per cent of the transfer.

Wheel loads against lateral acceleration in a steady left turn, the four wheels of the template0400800120016000.00.40.81.21.6Lateral acceleration, left turn (g)Vertical load (N)
FR, outsideFL, insideRR, outsideRL, inside
Fig. 3
Each g moves 360 N across the front axle and 359 N across the rear: the front carries 50.0 % of the transfer.
Measured

The front's share of the total is the total lateral load transfer distribution (TLLTD):

Show the equations with
TLLTD=ΔFz,fΔFz,f+ΔFz,r(2)
TLLTD=359.5359.5+359.4=50.01 %(2)

A tyre's grip grows less than its load, so the axle that moves more load loses more of its pair's grip. Moving TLLTD forward, by stiffening the front roll element or raising the front roll centre, makes a car understeer more; moving it back makes it oversteer more. It is the reason anti-roll bars exist.

Braking and drive

In a straight line the inertia force max acts at the CG height h, and the couple moves load between the axles over the wheelbase L. Braking (ax<0) moves it forward:

Show the equations with
ΔFz,r=−ΔFz,f=maxh′L−Fnose(3)
h′=300.231 mm,Fnose=7.50 N,Fz,FL=1026.7 N(ax=−1.2g)(3)
h′
the CG height the car settles at, not the one it stands at
Fnose
the load the CG puts on the front axle by moving forward as the car pitches
Side view of the car braking: the inertia force at the centre of gravity, the car pitched nose down, and the centre of gravity carried forwardm axm gmorelessCG forward by h·θBraking, front to the right, pitch exaggerated
Fig. 4
Braking moves load forward. The nose goes down, and the CG goes forward with it.
Schematic

The transfer pitches the car: under braking at 1.2 g the template's front drops 12.6 mm and its rear rises 11.7 mm. Pitching moves the CG. It goes forward, which loads the front a little more, and its height changes with the two axles' travel. The new height changes the transfer, and so on. The app follows this loop until the CG moves less than 10⁻⁹ mm, a few passes. On the template the settled CG is 300.23 mm high instead of 300: more of the car's mass rides on the rear, which rises, than on the front, which drops.

The anti features take some of this transfer through the links instead of the springs (Roll and pitch centres). They change how far the car pitches, not how much load moves.

What the model assumes

  • The corner is steady: constant ay and ax, no transient and no damper forces.
  • The roll centres and the roll axis stay at the static ride. The roll axis is a straight line from front to back.
  • Lateral and longitudinal transfer add: in a corner under braking each wheel gets both.
  • The tyres stay on the road. When a wheel's load would go below zero the app holds it at zero, flags the wheel as lifted, and puts its share where the car's balance sends it; the formulas above stop applying there.
  • Two more terms the examples here do not need: the aerodynamic load, which grows with the square of speed, and the load the steering linkage shifts across the diagonal as the wheels steer, which is zero with them straight.

In the app

Vehicle Dynamics › Balance & loads draws "Wheel loads vs lateral g", the four lines of Fig. 3, and "Axle loads vs longitudinal g", negative for braking. Under "Ride & roll (steady state)" it lists "TLLTD front" next to "Roll-stiffness front", and "TLLTD front (%) — ARB front × rear" maps it over both bars.

Every model in the app, from the grip envelope to the lap, places the loads on the tyres this way.

Check it yourself

The script builds the three terms of equation (1) for each axle, the wheel loads at 1.2 g left, and the braking loads with the settled CG, from example_car.m. Run it yourself and it also draws Fig. 3.

load_transfer.mwith example_car.m, pd_compare.mExact: agrees to machine precision
>> load_transfer

  Quantity                                This script   PaceDynamics       Diff
  -----------------------------------------------------------------------------
  Front elastic [N/(m/s^2)]                   33.3552        33.3552         0% 
  Front geometric [N/(m/s^2)]                0.337484       0.337484         0% 
  Front unsprung [N/(m/s^2)]                  2.95617        2.95617   1.5e-14% 
  Rear elastic [N/(m/s^2)]                    33.4159        33.4159         0% 
  Rear geometric [N/(m/s^2)]                 0.316753       0.316753         0% 
  Rear unsprung [N/(m/s^2)]                   2.90771        2.90771   1.5e-14% 
  Front share of the transfer [-]            0.500058       0.500058         0% 
  Left turn at 1.2 g, FL [N]                  260.174        260.174   4.4e-14% 
  Left turn at 1.2 g, FR [N]                  1123.04        1123.04         0% 
  Left turn at 1.2 g, RL [N]                  348.565        348.565   1.6e-14% 
  Left turn at 1.2 g, RR [N]                  1211.22        1211.22         0% 
  Braking: settled CG height [mm]             300.231        300.231         0% 
  Braking: CG moved forward [N]               7.50396        7.50396         0% 
  Braking at 1.2 g, FL [N]                     1026.7         1026.7         0% 
  Braking at 1.2 g, RL [N]                      444.8          444.8         0% 

  All 15 quantities agree with PaceDynamics (largest difference 4.4e-14 %).
The script
%% Load transfer: where the tyres' forces put the car's weight
%
% Companion to the documentation page "Load transfer". Runs unchanged in GNU Octave (7 or
% later) and MATLAB. Edit the car in example_car.m and run:
%
%   >> load_transfer
%
% Lateral, per axle, for a steady corner at lateral acceleration a_y:
%
%   dFz = a_y / t * ( elastic + geometric + unsprung )
%
%   elastic   = m_s * h_ra * G * K_axle / K_total   the sprung mass rolling on its springs
%   geometric = m_s,axle * h_rc,axle                 the sprung mass pushing through the links
%   unsprung  = m_u,axle * h_u                       wheels, uprights and brakes on their own
%
% with G = 1 / (1 - m_s g h_ra / K_total), the extra roll from the CG swinging outboard.
%
% Longitudinal, for a straight-line acceleration a_x (negative: braking):
%
%   dFz,rear = m a_x h / L - noseLoad
%
% where h is the CG height the car settles at, not the one it stands at: the transfer
% pitches the car, the pitch lowers (or raises) the CG and carries it forward, and the
% CG going forward puts noseLoad on the front axle. The app solves that loop to 1e-9 mm;
% so does this script, in the same steps.
%
% Reference: W. F. Milliken and D. L. Milliken, Race Car Vehicle Dynamics (SAE, 1995), ch. 18.
%
% Part of the PaceDynamics documentation, https://pacedyn.dev/docs
% SPDX-License-Identifier: MIT

[car, app] = example_car();
app = app.transfer;

g  = 9.81;                                  % m/s^2
mm = 1e-3;                                  % m per mm
series = @(a, b) a .* b ./ (a + b);

%% Masses
m_u  = 4 * car.unsprungPerCorner;           % kg, all four corners
m_s  = car.massTotal - m_u;                 % kg, sprung
m_sf = m_s * car.frontMassFrac;             % kg, sprung on the front axle
m_sr = m_s * (1 - car.frontMassFrac);       % kg, sprung on the rear axle

%% Roll stiffness per axle (page "Ride and roll rates")
k_f = series(car.wheelRateFront + car.arbFront, car.tireRateFront);   % N/mm at the wheel
k_r = series(car.wheelRateRear  + car.arbRear,  car.tireRateRear);
K_f = (k_f / mm) * (car.trackFront * mm)^2 / 2;                       % N*m/rad
K_r = (k_r / mm) * (car.trackRear  * mm)^2 / 2;
K   = K_f + K_r;

%% Roll axis: the line through the two roll centres, read where the CG is
h_rc = (car.rcHeightFront + (car.rcHeightRear - car.rcHeightFront) * (1 - car.frontMassFrac)) * mm;
h_ra = car.cgHeight * mm - h_rc;                                      % m, CG above the roll axis
G    = 1 / (1 - m_s * g * h_ra / K);

%% The three terms, per unit a_y [N per m/s^2, per wheel]
t_f = car.trackFront * mm;   t_r = car.trackRear * mm;
h_u = car.unsprungCgHeight * mm;

front.elastic   = m_s * h_ra * G * (K_f / K) / t_f;
front.geometric = m_sf * car.rcHeightFront * mm / t_f;
front.unsprung  = 2 * car.unsprungPerCorner * h_u / t_f;

rear.elastic    = m_s * h_ra * G * (K_r / K) / t_r;
rear.geometric  = m_sr * car.rcHeightRear * mm / t_r;
rear.unsprung   = 2 * car.unsprungPerCorner * h_u / t_r;

c_f = front.elastic + front.geometric + front.unsprung;
c_r = rear.elastic  + rear.geometric  + rear.unsprung;
tlltd = c_f / (c_f + c_r);                  % front share of the load moved

%% Wheel loads in a steady left turn
W  = car.massTotal * g;
Wf = W * car.frontMassFrac;   Wr = W * (1 - car.frontMassFrac);
a_y = app.corner.ayG * g;
corner = [Wf / 2 - c_f * a_y, Wf / 2 + c_f * a_y, Wr / 2 - c_r * a_y, Wr / 2 + c_r * a_y];

%% Braking: the CG the car settles at
a_x = app.braking.axG;                      % g, negative
Lmm = car.wheelbase;
kF  = 2 * series(car.wheelRateFront + car.heaveSpringFront, car.tireRateFront);   % N/mm, front axle in heave
kR  = 2 * series(car.wheelRateRear  + car.heaveSpringRear,  car.tireRateRear);
% How far the CG sinks per mm each axle drops: the sprung mass at its station, the
% unsprung mass by the tyre's share of the drop.
share = @(k_ride, k_t) min(1, k_ride / k_t);
aF = (m_sf + 2 * car.unsprungPerCorner * share(kF / 2, car.tireRateFront)) / car.massTotal;
aR = (m_sr + 2 * car.unsprungPerCorner * share(kR / 2, car.tireRateRear))  / car.massTotal;
lambda = car.massTotal * a_x * g / Lmm;     % N of rearward transfer per mm of CG height
h = car.cgHeight;                           % mm, start where the car stands
for pass = 1:6
  % Front load per mm of nose-down rake, from the CG going forward with it.
  sigma = min(m_s * g * h / Lmm^2, 0.5 * kF * kR / (kF + kR));
  nF = -lambda * h;   nR = lambda * h;      % what each axle carries beyond static [N]
  d  = kF * kR - sigma * (kF + kR);
  dropF = (nF * (kR - sigma) - sigma * nR) / d;
  dropR = (nR * (kF - sigma) - sigma * nF) / d;
  next  = car.cgHeight - (aF * dropF + aR * dropR);
  moved = abs(next - h);
  h = next;
  if moved < 1e-9, break; end
end
noseLoad = sigma * (dropF - dropR);         % N, onto the front axle
dLong = car.massTotal * a_x * g * h / Lmm - noseLoad;   % N, + rearward
braking = [Wf / 2 - dLong / 2, Wf / 2 - dLong / 2, Wr / 2 + dLong / 2, Wr / 2 + dLong / 2];

%% Against the app
pd_compare('Front elastic [N/(m/s^2)]',       front.elastic,   app.front.elastic);
pd_compare('Front geometric [N/(m/s^2)]',     front.geometric, app.front.geometric);
pd_compare('Front unsprung [N/(m/s^2)]',      front.unsprung,  app.front.unsprung);
pd_compare('Rear elastic [N/(m/s^2)]',        rear.elastic,    app.rear.elastic);
pd_compare('Rear geometric [N/(m/s^2)]',      rear.geometric,  app.rear.geometric);
pd_compare('Rear unsprung [N/(m/s^2)]',       rear.unsprung,   app.rear.unsprung);
pd_compare('Front share of the transfer [-]', tlltd,           app.tlltd);
names = {'FL', 'FR', 'RL', 'RR'};
for i = 1:4
  pd_compare(sprintf('Left turn at %.1f g, %s [N]', app.corner.ayG, names{i}), corner(i), app.corner.(names{i}));
end
pd_compare('Braking: settled CG height [mm]', h,               app.braking.cgHeight);
pd_compare('Braking: CG moved forward [N]',   noseLoad,        app.braking.noseLoad);
for i = [1, 3]
  pd_compare(sprintf('Braking at %.1f g, %s [N]', -a_x, names{i}), braking(i), app.braking.(names{i}));
end
pd_compare();                               % prints the verdict

%% The page's figure: four wheel loads against lateral acceleration
% Drawn when you run the script yourself; the strict run in CI has no screen and skips it.
if ~strcmp(getenv('PD_STRICT'), '1')
  ay = linspace(0, 1.6, 17) * g;            % left turn: load goes right
  figure('Name', 'Wheel loads in a steady left turn');
  plot(ay / g, Wf / 2 + c_f * ay, '-',  ay / g, Wf / 2 - c_f * ay, '--', ...
       ay / g, Wr / 2 + c_r * ay, '-',  ay / g, Wr / 2 - c_r * ay, '--', 'LineWidth', 1.5);
  grid on; xlabel('Lateral acceleration [g]'); ylabel('Vertical load [N]');
  legend('FR (outside)', 'FL (inside)', 'RR (outside)', 'RL (inside)', 'Location', 'northwest');
end

Download: load_transfer.m · example_car.m · pd_compare.m. The scripts are MIT licensed.

Further reading

  • W. F. Milliken and D. L. Milliken, Race Car Vehicle Dynamics (SAE, 1995), ch. 18, on wheel loads.
  • T. D. Gillespie, Fundamentals of Vehicle Dynamics (SAE, 1992), ch. 2, 3 and 7.
ChapterLoad transfer
PartLoads
Model as of0.338
Example carthe Formula Student single-car template