PaceDynamics Documentation Open the app
Contents

Suspension

Wishbones and struts

How the links carry a wheel through its travel, and what that does to its camber, its toe and the spring it works.

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

A wheel's upright is held by links. On a double wishbone there are five: the two legs of each wishbone and the tie rod, which is a toe link on a rear axle. As the wheel rises, each link swings about its chassis end and the upright goes with them. It tilts, it steers a little, and its contact patch slides sideways. The Kinematics tool computes all of that from the hardpoints, and this page shows how.

The upright through its travel

A link keeps its length, so its outer end stays on a sphere about its chassis end. Five such spheres leave the upright one way to move, and the wheel centre's height picks the position along it. The app solves the six conditions together, by Newton's method from the static ride:

|𝐑(𝐏iβˆ’π‚)+𝐂+π­βˆ’πi|=β„“i,i=1…5,tz=s(1)
𝐐i,𝐏i
link i's chassis and upright ends, as drawn
𝐑,𝐭
the upright's turn about its wheel centre 𝐂, and its shift
β„“i
link i's length, from the hardpoints
s
the wheel travel: the wheel centre's rise from the static ride, positive in bump

The turn carries the wheel's spin axis with it, and the alignment is read off that axis: camber is its tilt in front view, toe its turn in plan (Axes, signs and units gives the signs). The contact patch is a loaded radius below the wheel centre, in the wheel's plane.

The front-left corner to scale in front view at the static ride and 40 mm above and below it: the wishbones, the upright and the tyreβˆ’40 mm+40 mmupper wishbonelower wishbonecontact patchFront view of the front-left corner, outboard to the right, to scale
Static ride40 mm below and above
Fig. 1
Over Β±40 mm the upright rises on its links and tips: the front camber runs from βˆ’0.67Β° in droop to βˆ’1.60Β° in bump.
Measured

Every number below is the change of one of these with s: a gain. The app takes each one by solving the pose half a millimetre above and below the static ride and differencing the two.

Camber gain

Seen from the front, the upright turns about its instant centre, the point where the two wishbones' lines cross (Roll and pitch centres). A millimetre of rise at the patch, a swing arm's length from that point, turns the wheel by one swing-arm length's worth of radians. With the instant centre inboard, the top of the wheel tips in:

Show the equations with
dΞ³dsβ‰ˆβˆ’1FVSA(2)
dΞ³dsβ‰ˆβˆ’180/Ο€4921=βˆ’0.01164 ∘/mm(2)
Ξ³
camber, negative with the top of the wheel in
FVSA
the front-view swing arm: the patch's distance from the instant centre

On the template the links give βˆ’0.01165 Β°/mm at the front, within a part in a thousand of the rule. The arms are close to parallel, so the swing arm is long, 4921 mm, and the gain small: over the Β±40 mm of the Analysis tab's ride sweep the front camber runs from βˆ’0.67Β° in droop to βˆ’1.60Β° in bump.

A shorter swing arm gains camber faster. It also moves the instant centre and with it the roll centre, which is why the two are designed together.

Bump steer

The tie rod is a sixth link on the same upright, and it steers the wheel unless its outer end moves as the upright would carry it. In front view the rule for a wishbone corner is that the tie rod's line passes through the wheel's instant centre, and its inner end lies on the line through the wishbones' inner pivots. Off that line the rod pushes or pulls the steering arm as the wheel rises, and the wheel toes in or out. The toe change per millimetre is the bump steer.

The template's front wheel toes out in bump, βˆ’0.0133 Β°/mm: βˆ’0.57Β° at +40 mm, 0.50Β° at βˆ’40. On the outside front wheel of a corner, which the body rolls onto, toe-out steers it away from the turn: roll understeer. The rear's toe link sits almost on the line, and its bump steer is 0.00012 Β°/mm.

Track scrub

The patch also slides sideways as the wheel rises, 0.0053 mm per millimetre at the front and 0.0044 at the rear, outboard in bump. Over a bump the tyre is pushed across the road for nothing, and it has to make a side force to do it. A roll centre above the road always comes with some: the patch moves square to its force line, and that line is not horizontal.

Camber and toe of the template against wheel travel, front and rearβˆ’2.5βˆ’2.0βˆ’1.5βˆ’1.0βˆ’0.50.00.51.0-40-2002040Wheel travel, + bump (mm)Angle (Β°)cambertoe
Camber, frontCamber, rearToe, front, + inToe, rear
Fig. 2
Both axles gain negative camber in bump. The front toes out as it rises; the rear barely steers.
Measured

The motion ratio

The spring is driven through the linkage, so it does not see the wheel's travel. The motion ratio is how far it moves per millimetre the wheel does. The template's axles are decoupled. A pushrod from each lower wishbone turns a rocker, and one heave element spans the two rockers: in heave both rockers turn alike and the element shortens; in roll they turn opposite ways and it barely moves, which leaves roll to the roll element (Ride and roll rates).

A decoupled axle from behind: pushrods from the lower wishbones turn two rockers, and one heave element spans the rockersheave elementrockerpushrodssRear view of a decoupled axle, both wheels rising; not to scale
Fig. 3
In heave the rockers turn in mirror image and the element shortens; in roll they turn the same way and its length barely changes.
Schematic

With both wheels at the same travel the two pickups are mirror images, so the element's length is twice its pickup's distance from the centre-line. Its ratio is the change in that length per millimetre of travel of both wheels, 1.211 at the front and 1.193 at the rear. Its rate reaches each wheel by virtual work: a force Fe in the element moving MRds does the work of two wheels each moving ds, so

Show the equations with
kw=keMR22(3)
kw=47.64β‹…1.211022=34.93Β N/mm(3)
ke
the heave element's spring rate, at the element
MR
the element's travel per millimetre of travel of both wheels
kw
its rate at each wheel, halved because one element carries two

The ratio is itself a gain and changes through the stroke. The app takes it across a sweep's two samples 4 mm either side of the static ride. A ratio that grows in bump hands more of the spring's force to the wheel the further it goes, and the wheel rate rises above equation (3); one that falls, as the template's does, softens it. Kinematics and compliance works out by how much.

Struts

A McPherson strut keeps the lower wishbone and replaces the upper one by the damper itself: its body is clamped to the upright and its rod slides through a top mount on the chassis. The upright may slide along the strut and turn about it, so the top mount is a line where an upper ball joint was a sphere: two conditions where the wishbone gave two. The steering axis runs from the lower ball joint to the top mount. Its instant centre is where the lower wishbone's line meets the line through the top mount square to the strut, and it moves out fast as the wheel rises, so a strut's camber gain fades in bump.

The app solves a strut the same way, and every readout on this page is computed for it. The template has none.

Axles given by their curves

A team with camber, toe and motion-ratio curves from a rig, a supplier or another program can give an axle by those instead of by hardpoints. The Kinematics tool's source switch, Hardpoints | Curves, fills the curves from the current hardpoints when it is first turned on, so nothing changes at the switch. A curve set has no linkage to derive a track, a roll-centre height or a spring rate from, so it states them, and it has no steering linkage at all.

What the model assumes

  • The links are rigid and the joints are points. How far they give under load is on Kinematics and compliance.
  • The rack is held still: bump steer is the toe change with the steering wheel held.
  • The heave element's ratio is taken with both wheels at one travel; in roll the element sees almost nothing.
  • The right-hand corner is the left one's mirror image.

In the app

Kinematics, in the readout rail: "At the wheel" gives camber and toe; "Rate of change here" gives camber gain, bump steer and track scrub; "Elements" gives the heave element ratio, and "Rates" the heave element at the wheel. Each moves with the state.

Kinematics β€Ί Analysis β€Ί Travel draws camber, toe and their gains through the travel; Springs & tyre follows the spring to the road.

Check it yourself

The script solves the upright at the static ride, half a millimetre either side, and at the travels the Analysis tab's sweep landed on, as the app does; it finds the rocker's turn for each and the heave element's length from it.

wishbones.mwith example_suspension.m, pd_corner.m, pd_upright.m, pd_metrics.m, pd_heave.m, pd_rocker.m, pd_compare.mExact: agrees to machine precision
>> wishbones

  Quantity                                This script   PaceDynamics       Diff
  -----------------------------------------------------------------------------
  Static camber, front [deg]                       -1             -1   4.4e-14% 
  Static camber, rear [deg]                      -1.5           -1.5   2.1e-13% 
  Camber gain, front [deg/mm]              -0.0116519     -0.0116519   1.4e-08% 
  Camber gain, rear [deg/mm]               -0.0104213     -0.0104213   2.6e-08% 
  Bump steer, front [deg/mm]               -0.0132504     -0.0132504   1.1e-08% 
  Bump steer, rear [deg/mm]               0.000119853    0.000119853     2e-07% 
  Track scrub, front [mm/mm]               0.00532844     0.00532844   1.2e-07% 
  Track scrub, rear [mm/mm]                0.00442282     0.00442282   1.9e-07% 
  Camber at -40 mm, front [deg]             -0.665389      -0.665389   1.8e-13% 
  Toe at -40 mm, front [deg]                 0.496239       0.496239   7.3e-12% 
  Camber at -20 mm, front [deg]             -0.799906      -0.799906   4.2e-12% 
  Toe at -20 mm, front [deg]                 0.256315       0.256315   1.1e-11% 
  Camber at +20 mm, front [deg]              -1.26665       -1.26665   2.4e-12% 
  Toe at +20 mm, front [deg]                -0.274219      -0.274219   2.2e-11% 
  Camber at +40 mm, front [deg]              -1.60287       -1.60287   1.1e-12% 
  Toe at +40 mm, front [deg]                -0.567943      -0.567943     8e-12% 
  Heave motion ratio, front [-]               1.21096        1.21096   5.9e-13% 
  Heave motion ratio, rear [-]                1.19288        1.19288     6e-13% 
  Heave rate at wheel, front [N/mm]            34.929         34.929   1.2e-12% 
  Heave rate at wheel, rear [N/mm]            38.7348        38.7348   1.2e-12% 

  Rule of thumb, front: -180/pi / FVSA = -0.011643 deg/mm against -0.011652 from the links.

  All 20 quantities agree with PaceDynamics (largest difference 2e-07 %).
The script
%% Wishbones and struts: how the links steer and tilt a wheel as it rises
%
% Companion to the documentation page "Wishbones and struts". Runs unchanged in GNU
% Octave (7 or later) and MATLAB. Edit the car in example_suspension.m, or type your own
% hardpoints from the Kinematics tool, and run:
%
%   >> wishbones
%
% What this computes, for the front-left and rear-left wheels:
%
% 1. The upright's pose at a given wheel travel (pd_upright): five links of fixed length,
%    and the wheel centre's height. Camber and toe are read off the spin axis the pose
%    turns; the contact patch is a loaded radius below the wheel centre (pd_metrics).
% 2. The gains at the static ride: camber, toe and the patch's sideways position at
%    0.5 mm above and below it, differenced. That is the app's step, so the gains agree
%    with its readouts to their last digits.
% 3. The ride sweep the Analysis tab draws, at the travels its samples landed on.
% 4. The heave element. The pushrod's outer end turns with the lower wishbone; the rocker
%    turns until the pushrod is its own length again; the element runs between the two
%    rockers, so in heave it is twice its pickup's distance from the centreline (pd_heave).
%    Its motion ratio is the change in that length per millimetre of wheel travel, taken
%    across the two travels the app takes it between, and its rate at the wheel is
%        k_wheel = k_element * MR^2 / 2,
%    halved because one element carries both wheels.
%
% Part of the PaceDynamics documentation, https://pacedyn.dev/docs
% SPDX-License-Identifier: MIT

[car, app] = example_suspension();
g = 9.81;
Fz = car.massTotal * g * [car.frontMassFrac, 1 - car.frontMassFrac] / 2;   % N, per wheel
R0 = car.tyreFreeRadius - Fz / car.tyreRate;                  % mm, the radius each axle stands on

axles = {pd_corner(car.front), pd_corner(car.rear)};
names = {'front', 'rear'};
step = 0.5;                                                   % mm, the app's half-step
for ax = 1:2
  a = axles{ax};
  at = @(t) pd_upright(a, 'travel', t);
  read = @(p) pd_metrics(p.at(a.ubj), p.at(a.lbj), p.at(a.C), p.n, p.at(a.tieOuter), R0(ax));
  m0 = read(at(0));
  lo = read(at(-step));  hi = read(at(step));
  w.(names{ax}).camber     = m0.camber;
  w.(names{ax}).toe        = m0.toe;
  w.(names{ax}).camberGain = (hi.camber - lo.camber) / (2 * step);
  w.(names{ax}).bumpSteer  = (hi.toe - lo.toe) / (2 * step);
  w.(names{ax}).scrubRate  = (hi.patch(2) - lo.patch(2)) / (2 * step);

  % The heave element's length, both rockers turned alike.
  h = app.wishbones.heave.(names{ax});
  w.(names{ax}).ratio = (pd_heave(a, h.chord(1)) - pd_heave(a, h.chord(2))) / (h.chord(2) - h.chord(1));
  w.(names{ax}).wheelRate = car.(names{ax}).heaveRate * w.(names{ax}).ratio^2 / 2;
end

% The ride sweep, front left.
a = axles{1};
for i = 1:numel(app.wishbones.sweep.travel)
  p = pd_upright(a, 'travel', app.wishbones.sweep.travel(i));
  m = pd_metrics(p.at(a.ubj), p.at(a.lbj), p.at(a.C), p.n, p.at(a.tieOuter), R0(1));
  sweep.camber(i) = m.camber;  sweep.toe(i) = m.toe;
end

%% Against the app
pd_compare('Static camber, front [deg]',        w.front.camber,      app.wishbones.front.camber);
pd_compare('Static camber, rear [deg]',         w.rear.camber,       app.wishbones.rear.camber);
pd_compare('Camber gain, front [deg/mm]',       w.front.camberGain,  app.wishbones.front.camberGain);
pd_compare('Camber gain, rear [deg/mm]',        w.rear.camberGain,   app.wishbones.rear.camberGain);
pd_compare('Bump steer, front [deg/mm]',        w.front.bumpSteer,   app.wishbones.front.bumpSteer);
pd_compare('Bump steer, rear [deg/mm]',         w.rear.bumpSteer,    app.wishbones.rear.bumpSteer);
pd_compare('Track scrub, front [mm/mm]',        w.front.scrubRate,   app.wishbones.front.trackScrubRate);
pd_compare('Track scrub, rear [mm/mm]',         w.rear.scrubRate,    app.wishbones.rear.trackScrubRate);
for i = 1:numel(app.wishbones.sweep.travel)
  pd_compare(sprintf('Camber at %+.0f mm, front [deg]', app.wishbones.sweep.travel(i)), sweep.camber(i), app.wishbones.sweep.camber(i));
  pd_compare(sprintf('Toe at %+.0f mm, front [deg]', app.wishbones.sweep.travel(i)),    sweep.toe(i),    app.wishbones.sweep.toe(i));
end
pd_compare('Heave motion ratio, front [-]',     w.front.ratio,       app.wishbones.heave.front.ratio);
pd_compare('Heave motion ratio, rear [-]',      w.rear.ratio,        app.wishbones.heave.rear.ratio);
pd_compare('Heave rate at wheel, front [N/mm]', w.front.wheelRate,   app.wishbones.heave.front.wheelRate);
pd_compare('Heave rate at wheel, rear [N/mm]',  w.rear.wheelRate,    app.wishbones.heave.rear.wheelRate);

% The rule of thumb the page gives: camber gain is about one radian over the swing arm.
fprintf('\n  Rule of thumb, front: -180/pi / FVSA = %.6f deg/mm against %.6f from the links.\n', ...
        -180 / pi / app.front.fvsa, w.front.camberGain);
pd_compare();

Download: wishbones.m Β· example_suspension.m Β· pd_corner.m Β· pd_upright.m Β· pd_metrics.m Β· pd_heave.m Β· pd_rocker.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. 17, on camber gain, bump steer and swing arms.
  • J. C. Dixon, Suspension Geometry and Computation (Wiley, 2009), on solving a linkage's position and on motion ratios.
  • J. Reimpell, H. Stoll and J. W. Betzler, The Automotive Chassis: Engineering Principles (Butterworth-Heinemann, 2001), on struts.
ChapterWishbones and struts
PartSuspension
Model as of0.338
Example carthe Formula Student single-car template