simulation of a wheeled vehicle - final
DESCRIPTION
My BEng thesis.TRANSCRIPT
4/15/2013
Chris Erwood | 0902047
FINAL
REPORT
DEVELOPMENT OF A WHEELED VEHICLE
SIMULATION TOOL FOR MOTORSPORTS IN MATLAB.
2
Table of Contents Nomenclature ................................................................................................................................... 4
Abstract ............................................................................................................................................ 3
Introduction Aims .............................................................................................................................. 5
Simulation in Formula Student ................................................................................................... 5
Basics of Vehicle Dynamics Quarter-Car model .............................................................................. 6
Full-Car Model ............................................................................................................................... 8
Lateral forces ................................................................................................................................. 9
Wheel Torques ........................................................................................................................ 12
Data Acquisition for Simulation Assumptions................................................................................... 12
Acquisition of basic vehicle data .................................................................................................. 12
Spring & Damping rates ........................................................................................................... 12
Tyre Characteristics ................................................................................................................. 13
Engine Torque ......................................................................................................................... 16
Brake Torque ........................................................................................................................... 17
Centre of Gravity and Masses .................................................................................................. 17
Development of Vehicle Simulation Initial Full-Car suspension model. ............................................. 18
Quarter-Car Model .................................................................................................................. 18
Full-Car Model ......................................................................................................................... 18
Lateral Load Calculations ............................................................................................................. 19
Tyre force calculation .............................................................................................................. 19
Engine & Gearbox Simulation................................................................................................... 20
Brakes...................................................................................................................................... 22
Aerodynamic Drag and Downforce .......................................................................................... 22
Control Systems ........................................................................................................................... 26
Throttle (Traction Control) ....................................................................................................... 26
Brakes (Anti-Lock) .................................................................................................................... 28
Counter-Steer .......................................................................................................................... 29
Path Creation and Following ........................................................................................................ 31
Simulation Results and Discussion ................................................................................................... 34
Further Development .................................................................................................................. 36
Validation ................................................................................................................................ 37
3
Conclusions ..................................................................................................................................... 37
Acknowledgements ......................................................................................................................... 37
References ...................................................................................................................................... 38
Appendices...................................................................................................................................... 39
1.1 - Original Quarter-Car Model Script: ................................................................................... 39
1.2 - Full-Car Model Main Script ............................................................................................... 41
1.3 - Tyre Lateral Load Calculation Function ............................................................................. 53
1.4 Engine Torque Curve Function ........................................................................................... 55
1.5 Gear Selection/Ratio (Gearbox) function ............................................................................ 58
1.6 - Traction Control/ABS function.......................................................................................... 60
1.7 Steering/Path following Function ....................................................................................... 61
1.8 - Individual Wheel absolute velocity function ..................................................................... 65
1.9 - Wheel combined torque and angular acceleration function ............................................. 66
1.10 - Vehicle Moment Calculator ............................................................................................ 67
1.11 - Vehicle corner displacement due to roll & pitch function ............................................... 68
1.12 - Quarter-car model adapted for individual corners of full-car model ............................... 68
Abstract A simulator was developed as a tool to aid in the design of motorsports vehicles for Formula
Student and other similar applications. The aim was to create a tool that could provide feedback on
the dynamic characteristics of a hypothetical vehicle, to inform design decisions at an early stage.
This tool consisted of a simulation based on a simplified full-car model of vehicle suspension
behaviour, and a pair of functions created to allow the simulated vehicle to follow a predetermined
path. The simulation reliably provides responses characteristic of the response that would be
expected, however sufficient data is not yet available to allow the simulation to be reliably tested
against a real-world vehicle.
4
Nomenclature
Centre of gravity - axis system is zeroed around the centre of the rear left wheel.
Suspension spring stiffness for the
nth wheel (N/m)
Tyre effective spring stiffness (N/m)
Suspension damping coefficient
(N/m/s)
Tyre effective damping coefficient
Sum of forces in X-Direction
Sum of forces in Y-Direction
Sum of forces in Z-Direction
Sum of yawing moments about CG
Sum of pitching moments about CG
Sum of rolling moments about CG
Tyre effective slip angle (ᵒ)
Wheel angular velocity
Wheel angular acceleration
Vehicle total sprung mass
Vehicle total unsprung mass
Mass of individual wheel/brake assembly
Vehicle yaw angle
Vehicle trajectory yaw angle
Wheel offset yaw angle (steering angle for wheels 1&2)
Wheel total yaw angle
Vehicle yaw rate
Vehicle drift angle (difference between trajectory and yaw)
Engine torque
Engine torque per driven wheel
Brake torque per wheel
Wheel friction torque
Torque due to wheel slip angle
Total wheel torque
Throttle position (0-1)
Brake position (0-1)
ABS aggression factor
Traction Control aggression factor
Counter-steer aggression factor
Vehicle absolute component velocities
Slip velocity (difference between tyre tangential and absolute velocity)
Slip velocity components
Wheel slip direction in x-y plane
Engine r.p.m
Engine Torque Curve (relationship between r.p.m and output torque).
Maximum brake torque.
Gear ratio (includes final drive)
Lateral component forces generated by nth tyre.
Suspension natural spring length
Tyre natural spring length
Downforce (front)
Downforce (rear)
Load applied to ground through nth wheel
Load applied to the chassis
through the nth corner.
Vehicle moments of inertia about body axes.
Vehicle wheelbase (m)
Vehicle track width (m)
Front Downforce (N)
Rear Downforce (N)
Aerodynamic Drag (N)
Wheel loaded radius (m)
Slip ratio of nth wheel.
Slip angle of nth wheel.
Wheel moment of inertia.
Tyre Correction Constant
Drivetrain efficiency coefficient
Gravity (9.80665 m/s)
5
Introduction
Aims The aim of this project was to develop a simulation of a wheeled vehicle and
associated control system, with a view to trying to accurately model the interaction
between ground disturbances and the motion of the wheels and chassis. I decided after
much deliberation that I would take on this project and use it to develop an open-source
simulation tool for the university's formula student team to aid development in future
seasons.
Simulation in Formula Student
During the 2011 and 2012 Formula Student seasons I was a member of the University of
Glasgow's formula student team. During this period I saw that one of the major issues we had was in
vehicle simulation - that is, there are various lap simulation tools available, but many of them are
relatively simplistic, being based on a simplified tyre model or static cornering forces, or are tools
used in industry that require licensing at a cost prohibitive to student projects.
Figure 1 - Early rendering of University of Glasgow 2013 Formula Student car
One tool used by many teams is the open-source javascript tool at FSAESim.comi. However
this uses a highly simplified tyre and suspension model and does not allow for the plotting of data,
so whilst it does provide some useful data, the creation of a lap simulation tool in Matlab will
provide a significant benefit to development by allowing in-depth vehicle simulation and analysis
prior to the actual competition vehicle being built.
This can allow variables such as spring stiffnesses and gear ratios to be chosen well in
advance with a reasonable degree of certainty, which is important when working under the time
constraint of designing, manufacturing and testing a car in a standard 9 month season, and should
allow for better informed design choices to be made at an early stage, saving money and time and
improving performance.
This report outlines the principles of vehicle dynamics to be simulated, and how the
simulation was created in order to effectively model and control this system.
6
Basics of Vehicle Dynamics
Quarter-Car model The most basic model of vehicle dynamics is based upon representing each of the four
corners as a pair of mass-spring-dampers in series, representing the suspension spring and damper,
the tyre spring and damping and the sprung and unsprung masses.
The representation of individual wheels this way is commonly used in applications requiring
the prediction of dynamic response in a suspension system exposed to random or semi-random load
excitationii, which can make even the basic quarter-car model a very useful tool in suspension design
optimisation.
Many simulations disregard the damping effect of the tyre, as it is typically insignificant in comparison to the damping present in the suspension system of the vehicleiii.
Figure 2 - Basic Quarter-Car Model Diagram
The basic dynamics of the quarter-car model, including the load applied to the ground
surface through the tyre, can be summarised easily by the following equations:
Where FG represents the load applied to the ground through the contact patch, x1 represents the height of the
top of the vehicle suspension unit, and x2 represents the height of the wheel relative to the ground surface.
7
The quarter-car model is straightforward to simulate in MATLAB. Choosing values relatively
similar to those seen in the actual formula student car, the tyre stiffness was adjusted to a value
consistent with the stiffness of the Hoosier R25B 20.5 x 7.0 - 13 C2500 tyres typical of a formula
student racer for which data is easily available under 200lbs of load and 85Kpa pressurisationiv. The
following response plots to sinusoidal and step-input ground height disturbance are given:
Figure 3 - Quarter-car model response to sinusoidal ground disturbance @ 7Hz
Figure 4 - Quarter-car model response to step input
It can be seen in this case that the suspension is underdamped, yet succeeds in lessening or
eliminating the ground excitation in both cases.
Increasingly, many more detailed models go into the use of finite-element analysis to model non-
linear geometry changes that certain suspension designs undergo when loadedv. However, in
seeking to develop a tool for rapid suspension tuning to produce a flexible simulation applicable to a
variety of configurations, for most applications the quarter-car model portion of the simulation can
be represented as two mass-spring-dampers in series without significantly compromising accuracyvi.
8
Full-Car Model For many applications where the aim is simply to tune suspension to minimise chassis
movement over certain types of terrain over a certain range of speeds, a quarter-car model will be
entirely sufficient. Here, however, the aim is to obtain some increased understanding of the
behaviour of a complete car under dynamic cornering input. For this case then the quarter-car
model does not provide enough information and a full-car model must be developed that takes
account of the rolling and pitching motion of the chassis. To this end, the sprung mass of the vehicle
must be represented as a point mass at the centre of gravity, with vertical loads applied to it from
each of the four corners through the suspension:
Figure 5 - Modified quarter-car model for use in full-car model.
Where the load applied to the chassis at the nth corner is equal to:
These forces can be used to calculate the acceleration of the sprung mass of the chassis and
the moments acting about the centre of gravity, which allow the rate of change of the vertical centre
of gravity to be calculated as well as the heights of each of the four corners of the vehicle chassis.
9
Mathematically, the full-car model can be represented as:
-
Where represents the vertical force applied to the nth corner of the chassis due to suspension displacement,
WB and TR are the wheelbase and track of the vehicle respectively, and CGx/CGy represent the x & y
components of CG position relative to the rear-left wheel.
This representation assumes a complete lack of lateral forces from the wheels, which must
be calculated by looking at the interaction between the tyre and road surface.
Lateral forces The magnitude of the lateral loads Fx & Fy will be a function of the slip between each of the
tyres and the road surface, and the vertical load applied to the contact patch of the tyre. The lateral
loads scale non-linearly to both slip and vertical load in real systems, so quantifying the relationship
will usually require a significant amount of experimentation. The usual way to assess the
performance of a tyre involves placing the tyre on a rotating belt with some known load applied, and
sweeping the tyre back and forth, measuring the lateral load generated. This allows force to be
plotted both against slip angle and against applied vertical load under real-world conditions.
Figure 6 - Wheel slip angle in yaw vii
For most road tyres, peak lateral load will be generated with a slip angle of around 10-14 degrees, whereas most racing tyres will peak at 6-9 degreesviii . Typically, there will be a "plateau" over which lateral load falls steadily, before dropping off considerably. A tyre that does not slip relative to the ground surface can under no circumstances generate any lateral load. Often, tyres will show asymmetric load behaviour as a result of tread blocks deforming differently depending on direction of load. This project does not look into this asymmetric load creation, instead focusing on slick tyres which behave in a more predictable manner.
10
This information can be used to calculate longitudinal forces generated by the wheel by calculating
the "slip ratio" of the tyreix:
Where Vx is the absolute wheel-relative velocity parallel to the yaw angle of the wheel, and rt is the radius of
the wheel and tyre.
Which gives the slip angle for longitudinal motion:
From which the longitudinal load created by an under-rotation or over-rotation of the wheel
can be calculated via the relationship calculated from the yawing lateral load test. The lateral load
varies nonlinearly with vertical load, and this relationship must be ascertained separately for any
combination of tyre & tyre pressure, as the tyre side-wall deformation will affect the generated
lateral load differently for any combination of tyre and pressurisation.
Figure 7 - Vertical load against maximum lateral force for F1 tyres and a typical Formula Student tyrex
Given the relationships for maximum coefficient of friction against vertical load, as well as
coefficient of friction against slip angle for a given vertical load, it is then possible to calculate the x &
y forces generated by a tyre at any yaw angle, with any combination of angular and absolute
velocities.
11
If lateral forces generated by the wheels are taken into account then the complete motion of the
vehicle is described by the following six equations, where all forces and moments are to be
considered to act about a body-centric axis system:
-g
It should be noted that small-angle assumptions are made, on the basis that the roll and
pitch angles of the vehicle will not materially affect the distance between any of the wheels and the
centre of gravity in the lateral plane. and are considered fixed.
Combining these equations with the modified quarter-car model yields a full-car model that
responds accurately to any combination of lateral loads and ground disturbances. From this, any
values of wheel angular velocities, yaw angles, ground disturbances and absolute velocities can be
used to calculate the absolute and angular accelerations of the vehicle.
In the case of modelling a real-world vehicle over some non-negligible time period, the
wheel angular and absolute velocities will be non-constant. In order to calculate the angular
velocities of the wheels it is necessary to compute the torque applied to each wheel at every time
step.
12
Wheel Torques
The torque applied to each of the wheels will be a function of the torque applied by the
engine, the torque applied by the brakes and the torque applied as the result of the parallel slip
force exerted upon the tyre:
Where n is the number of driven wheels, assuming that torque is equally split between all driven wheels.
So as such the angular acceleration of each wheel can be found from:
Using these equations, it is possible to assemble a functional vehicle simulation, so long as
the relevant data with regards to the spring and damping coefficients, the lateral loads generated by
the tyres and the torques applicable by the engine and brakes are available. The only practical way
to arrive at any reasonably accurate representation of vehicle behaviour is to solve this model
through numerical integration.
Data Acquisition for Simulation
Assumptions Before a vehicle such as a car can be simulated, there are a number of assumptions that
must be made. In this case, the chassis is assumed to be completely rigid, the gear change is
assumed to be instantaneous and tyres are assumed to deform only due to vertical load.
Additionally, gear changes are assumed to be instantaneous in this model, although this is
something that could very easily be improved in future work.
Acquisition of basic vehicle data
Spring & Damping rates
The first task in creating a reliable vehicle simulation was to create a working quarter-car
model. This was completed at a very early stage in the project, using data procured from the old
formula student car's suspension system, as well as tyre spring stiffness data from Hoosier, the
manufacturer of the most commonly used tyre in formula student competition. This was tested
against a variety of sine, step and pseudorandom inputs to verify that the system was essentially
stable. The aim of the system is to simulate future hypothetical cars, so these results were not tested
against telemetry from any known vehicle, however the results gathered did indicate a moderately
under-damped suspension response, which is what would be expected for almost any motor
vehiclexi.
13
Tyre Characteristics
After this was completed the next major hurdle was to find reliable tyre data to use for
calculation of lateral loads generated by the tyres. Tyre manufacturers are often very protective of
the performance figures of their tyres, and tyre tests are very expensive to run, with competition-
spec tyres costing more than £200 per unit. Thankfully, data was acquired from Dr. Edward M.
Kasprzak of Milliken Research Associates, the organisation that runs the Formula SAE Tyre Test
Consortiumxii. Through this source, it was possible to acquire information from a series of annual
tyre tests of the most popular tyres for formula student competition, this included data on the
behaviour of the Hoosier R25B 20.5 x 7.0 - 13 C2500 tyre used for the quarter-car model.
This dataset was particularly useful, as it contained a wide array of data channels - forces generated
in X,Y & Z directions, tyre slip angle, vertical load, pressure, effective wheel radius and even surface
temperature were recorded and made available, providing all of the data required to come up with
an appropriate model for the behaviour of these tyres. The test used a belt of ground-smooth 120-
grit sandpaper. According to advice from Milliken research, this surface would typically generate
lateral loads in the region of 1.4-1.6x greater for a given vertical load and slip angle than tarmac
would under similar conditions. Therefore, a tyre correction constant is used in the final code to
allow the level of grip from the tyres to be adjusted with a single variable.
Figure 8 - Tyre shown suspended over the driven belt setup.
14
The two datasets that require comparison are the relationship between slip angle and lateral force,
and the relationship between vertical applied load and maximum lateral force. This information is
easily found from the test data.
Figure 9 - Slip angle plotted against normalised lateral load for all runs - it should be noted that this data includes runs from different vertical loads and cambers, so data from low-load runs and cambered runs is disregarded.
Once this data is filtered to remove data that is not suitable - for example cambered tyres as camber
effects are to be ignored in this basic model, the lateral load can be roughly approximated to:
For low slip angles ( ᵒ), and:
For larger slip angles. Obviously this is only valid for the relatively low slip angles tested, and
anything beyond that is, to a large extent, informed guesswork. However, as the peak grip of the
model lies within this range, it was reasoned that a well-controlled model should not need to
explore very high slip angles, as the control inputs should be designed in such a way as to prevent
such slip angles from being achieved.
is the maximum lateral load that can be generated with that vertical load, and is the
slip angle in degrees. In order to find the data from multiple runs was examined, looking at the
relationship between vertical load and the maximum value of attained at that load.
In the simulation, it is important to note that the grip levels estimated from this test are
expected to be higher than real-world results, hence the coefficient TCC is added, such that:
Where TCC will be in the region of 0.6-0.7 for a typical dry, warm road surface.
15
Each set of tyre test data involved the tyre being swept through a range of yaw angles from
+12.5ᵒ to -12.5ᵒ at five different loads five times. This was then repeated so that data is available for
the camber angles of 0,1,2,3 & 4 degrees positive camber.
The data output of the vertical and lateral load output channels therefore appears as such:
Figure 10 - Output of Milliken research tyre test showing repeated tests at five different loads.
A good mathematical fit for the relationship between and based on data gathered from the
zero-camber tests was found to be:
This relationship is valid for a tyre pressure around 85Kpa, which is typical of FSAE applications. Tyre
pressure was tracked in the tests and was kept at 85Kpa for cold tyres, identical to the specification
provided by Hoosier. Information on wheel radius was also available, so it was possible to estimate
the spring rate of the tyre. The average value calculated was just 2.9% below the values provided
directly by Hoosier, so the values from Hoosier, which gave a tyre spring stiffness of
for each of the tyres, is used.
The damping ratio of the tyres is estimated based on typical values from similar tyres, at 2KN/m/s -
this value will not have a significant impact on the accuracy of the simulation as it is dwarfed by the
damping of the suspension dampersxiii .
16
Engine Torque
In order to plot the torque output of the engine, it is required to know first of all what the
relationship is between the rotation rate of the crankshaft and the output torque, and also the gear
ratios connecting the engine to the rear wheels. The torque curve can be estimated in this case
based on the torque curve for the standard version of the car's engine - a KTM 525 EXC:
Figure 11 - Torque curve of standard KTM 525 EXC (light orange)xiv
This torque curve is recreated in MATLAB, and a function is created to accept the engine rpm
and output the engine torque in NM:
Figure 12 - Matlab simulated torque curve for standard KTM 525 EXC
This can then be used along with the gear ratios of the gearbox to calculate the maximum
torque applied to each of the driven wheels. The throttle position ranges from 0 to 1 and represents
the proportion of this maximum torque that is actually applied. This torque is then multiplied by the
gear ratio of the current gear selected in the gearbox to find the torque applied to the rear wheels.
17
Brake Torque
The maximum brake torque must be enough to lock all four wheels on the car, in accordance
with formula student regulationsxv. Therefore the maximum brake torque can be estimated so long
as it is sufficient to lock the four wheels of the car. The brake position BP gives the proportion of
maximum brake torque that is applied to the wheels.
Centre of Gravity and Masses
The centre of gravity and masses of the sprung and unsprung parts of the car are estimated
based on a simple CAD representation of the 2013 formula student car. The affect of centre of
gravity on dynamic cornering is one of the things that the simulator will seek to investigate.
A variable was added to the model to represent the mass of the driver (essentially just
adding this mass to the sprung mass value) to allow the simulation of different weights of driver.
This is an important variable in vehicles as light as formula student racers, as results would later
show.
Overall masses were based on the team's 2013 targets, with a sprung mass of 165Kg and
unsprung mass of 8Kg per wheel. Typical formula student racers weigh between 160 and 250Kg, and
the lightest car to complete the endurance portion of last year's event weighed just 145Kgxvi
Vehicle Moments of Inertia
Estimations of vehicle moments of inertia in roll, pitch and yaw were taken from the basic
weighted solidworks CAD model of the car, in which components of significant known weight
(primarily the engine, chassis, wheels, fuel tank and driver) are presented as point masses and used
to determine a rough value for the moments of inertia.
The values given by the software for the moments of inertia of this early model are:
These seem to be reasonable for a lightweight vehicle with most of the mass concentrated
towards the centre of gravity. Unfortunately what there is not data to quantify is the affect that the
addition of a driver would have on these figures. Overall, due to the inaccuracy of the model used to
derive them and the fact that the driver - which makes up a very significant part of the overall mass
of the car - is not accounted for, it is unlikely that these particular figures are very accurate. However
they do provide a basis upon which to simulate, to investigate whether the simulator can create
behaviour typical of a small wheeled vehicle, and how changes in moments of inertia of said vehicle
can alter dynamic handling behaviour.
18
Development of Vehicle Simulation
Initial Full-Car suspension model.
Quarter-Car Model
Initially, the quarter-car model was developed and tested to ensure that the response
plotted was reasonably close to what would be expected from a vehicle suspension system. Early on,
some of the data provided by Milliken Research suggested that the tyre effective spring stiffness was
non-constant and varied under compression, however tests early on incorporating both the basic
and variable-stiffness tyre models found that there was little appreciable difference between the
two, and the more basic model of the tyre as a linear spring was kept for simplicity. This model was
then altered to create a function that could be called upon to provide data on the vertical force
applied each corner of the vehicle chassis in the full-car model.
Full-Car Model
Using a basic numerical integration scheme (in this case Euler integration) the quarter-car
model function was incorporated into a code to simulate the overall movement of a vehicle and its
suspension. Functions to determine the vertical acceleration of , the rolling and pitching
moments generated about the centre of gravity and the heights of each corner of the
vehicle, taking the change in and the roll and pitch angles into account. This model was
again tested with basic sine and step inputs and found to be very stable. Vitally for the
addition of lateral force calculation, this full-car model was able to calculate contact patch
loads taking into account rolling and pitching moments.
Figure 13 - Plot of tyre contact patch loads for each of the four wheels against time, for a car with high centre of gravity (0.52m) and centre of gravity biased rearwards by 0.4m - the ground disturbance in this case is a combination of sine
waves, providing a different input to each corner of the car.
19
Lateral Load Calculations
Tyre force calculation
Using the data from Milliken Research, a function was developed in order to accept as inputs
any combination of wheel absolute x & y velocities, wheel radius and wheel angular velocity, and
output forces generated by the tyre in both the absolute earth-fixed x & y directions as well as forces
parallel and perpendicular to the tyre yaw angle, the latter being important later on in calculating
the combined torque acting on any individual wheel.
This function operates by calculating components of "slip velocity" - the difference between
the absolute velocity of the wheel and the tangential velocity of the outside edge of the wheel - in
the absolute x & y directions, and perpendicular and parallel to the wheel's own yaw angle. These
components are then used to calculate an absolute slip ratio/slip angle for each wheel, as well as a
slip direction, which gives an absolute slip force and direction. The forces relate to slip angle and
vertical load as discussed previously.
Figure 14 - Absolute load generated in the Y-direction with a vertical load of 400N. It should be noted that the slip direction variable in the slip solver is used to invert this force when it is acting in the negative Y-direction.
Early versions of this function were prone to problems when the x or y direction slip
velocities approached zero, due to a relatively simple error in geometry in one of the early steps of
creating the function, however it now presents reasonably reliable results for most conditions.
There is a condition under which the slip force solver fails to function - the event that the
wheel's absolute velocity opposes its tangential velocity (such as if the car were to spin and still be
driving its driven wheels. This issue was brought up at a meeting and it was decided that this was
unlikely to present a problem for any normal usage, given that control inputs should be tailored to
stop such a situation from ever occuring - additionally, there is no data on how the tyres would
behave when confronted with such a situation, so it is unlikely that any attempt to model this
extreme behaviour would prove to be accurate. Full code for the slip force solver is shown in section
3 of the Appendices.
20
Engine & Gearbox Simulation.
The simulated torque curve shown in Figure 12 was created using cascading if-loops, with an
array of different linear relationships to calculate the engine maximum output torque for any given
input rpm. In order to calculate the correct engine rpm and therefore the correct torque output for
any given rotation rate of the rear wheels, it was necessary to construct a function to simulate the
gearbox of a car. Given that the aim of such a gearbox simulation in a motorsports context should be
to keep the engine rpm within the peak power-band of the engine, the gearbox can essentially be
simulated using two very simple rules:
1. If the engine rpm exceeds the stated upshift rpm, change up a gear.
2. If it is possible for the engine to downshift without exceeding the stated target downshift
rpm, change down a gear.
For testing, the upshift rpm was set to 9200rpm and the target downshift rpm was set to
8500rpm in most tests. This can be demonstrated by looking at the engine rpm when the vehicle is
accelerating and decelerating:
Figure 15 - Absolute vehicle velocity during acceleration/deceleration run.
Figure 16 - Engine rpm during acceleration/deceleration run.
21
The gear ratios are found from looking at the angular velocity of the driven wheels, in this
case the rear wheels 3 and 4 - engine r.p.m is based on the fastest rotating driven wheel, where:
In this case the gear ratios are chosen so as to allow the full range of vehicle velocities to be
tested - however the tool can be used to fine-tune these ratios to improve performance over a
particular type of course. The torque applied to the rear wheels is in effect multiplied by this gear
ratio, so taking the example of the acceleration run used earlier the applied torque to one of the
rear wheels can be shown:
Figure 17 - Torque applied to left-rear wheel during acceleration/deceleration run.
The simulation is set up to provide equal torque to each of the rear wheels, so the torque
provided to each rear wheel can be calculated from:
A typical value for the drivetrain efficiency in a motorsports application is 0.8-0.85xvii.
22
Brakes
The maximum brake torque is set such that it is possible to lock all four wheels in any
conditions. As a result, brake position will have to be controlled by the control system to prevent
wheels from significantly under-rotating.The angular acceleration of four wheels is given by a
function of the applied torque from the engine, the applied torque from the brakes, the applied
torque as a result of wheel slip, the rotational friction acting on the wheel, and the moment of
inertia of a wheel:
Or, for the un-driven wheels 1 & 2:
This can then be integrated numerically to compute the angular velocity of each of the four
wheels at any point in the simulation.
Aerodynamic Drag and Downforce
In order for the vehicle simulation to be remotely accurate at moderate to high speeds, it
must take account of the aerodynamic loads exerted on the vehicle. For most road vehicles,
downforce is negligible, even at high speedsxviii. However in the world of Formula Student, cars
typically sport diffusers and, especially in recent years, often very large and sophisticated aero
packages.
Figure 18 - ETH Zurich's 2012 car with adjustable front and rear wings.
As such, a simulation tool for development in formula student would be incomplete if it could not
take into account the effects of both aerodynamic drag and downforce.
23
Aerodynamic Drag
The standard drag equation is
, where S is the characteristic area and
is the body's coefficient of drag. Glasgow's 2011 formula student car had a CFD-estimated of
0.46 - single-seaters of this nature typically have a relatively high drag coefficient due to the open
wheels and cockpit.
In order to take account of the aerodynamic drag force, the force is calculated based on the
absolute velocity of the vehicle, and is then subtracted from the other forces acting on the vehicle
when the motion of the CG of the vehicle is being calculated. The lateral absolute accelerations of
the vehicle are hence altered to:
The result of this is that the vehicle will settle into equilibrium as it gets towards its top
speed, as can be shown in the case of this particular vehicle simulation over a 1.5Km acceleration
run:
Figure 19 - Vehicle velocity during acceleration from 5m/s over 1500m.
In this case, the characteristic area is assumed to be 0.75m - by adjusting this and the
estimated for the vehicle the impact of vehicle modifications which create changes in
aerodynamic drag can be evaluated.
The simulation does not currently make allowance for aerodynamic drag loads that are off-
centre and create their own yawing, pitching or rolling moments - Formula student cars are typically
symmetrical, so this is unlikely to present significant problems.
24
Application of Downforce
In order to simulate the effect of downforce on the car, two constants are added to the
code, representing front-end downforce and rear-end downforce at 1m/s. The downforce added to
the front and rear of the vehicle not only affects the absolute height of the centre of gravity of the
car, but also the pitch angle, since a pitching moment will be generated. It is assumed that the
vehicle does not produce downforce due to perpendicular flow over the body, so downforce is
calculated as a function of flow parallel to the yaw angle of the vehicle.
It is assumed that the constants act at the extremes of the vehicle wheelbase - this is
typically where wings are to be mounted so is probably a reasonable assumption to make.
As a result of the addition of aerodynamic downforce, the equations of motion for CG height
and pitch become:
-g
By making these simple modifications the effect of downforce on the dynamics of the car
can be modelled to a great extent. Shown below are plots of the vertical applied loads at each of the
tyre contact patches for the acceleration run shown earlier - in this case the car is assumed to
generate 0.25N of downforce at the front and 0.5N at the rear at 1m/s:
Figure 20 - as the vehicle accelerates, the vertical load applied to each of the contact patches increases due to aerodynamic downforce
25
This has the effect of increasing the maximum grip available to each tyre as the speed
of the vehicle increases, as well as causing the car to sit lower at high speeds than it normally would.
Figure 21 - Downforce has a significant effect on the maximum loads that can be generated by each tyre at high speeds
Figure 22 - Suspension compression at high speeds due to downforce
It is worth noting that this simple model of aerodynamic downforce and drag, based as it is
on the aerodynamic coefficients of the car's body remaining constant, may not offer accurate results
under extreme conditions. For example in the case of downforce, a typical racing setup in Formula
Student generates much more downforce at the rear than at the front, so at high speeds the car will
tend to pitch slightly nose-up. This will have the effect on a real vehicle of marginally reducing the
amount of downforce being generated, however on a low car with relatively stiff suspension the
amount of variability is likely to be fairly minimal, and for the purposes of a basic vehicle simulation
this model should prove accurate enough to provide a basic comparison of high-downforce and low-
downforce setups.
26
Control Systems Once the basic vehicle model is complete, control systems are required in order that the sim
may be able to follow some pre-set path. The throttle, brake and steering angle inputs must be
controlled in such a way that the vehicle follows a stable path, and for a motorsports application
part of the goal should be to keep the slip angles of the wheels within the optimal range, so as to
generate the maximum possible lateral loads.
Throttle (Traction Control)
The aim of the traction control system should be simply to prevent the driven wheels from
over-rotating to an extent that the slip angle of the driven tyres significantly exceeds the optimal slip
angle. Traction control systems on physical vehicles look at differences in the rate of rotation of the
four wheels, activating to reduce the level of driven-wheel slip whenever the driven wheels are
rotating significantly faster than the undriven wheels, with more advanced systems braking
individual wheels to reduce slip whilst maintaining full power to other driven wheels.
For the sake of a simulator for formula student, it should be noted that traction control
systems are banned in the competition overall, so a basic system that emulates the throttle input of
a good driver should be the aim. It was decided that the throttle position should be reduced
exponentially after the slip angle of the driven wheel with the highest slip angle exceeds a given
maximum slip angle .
Here , a constant referred to in the code as the traction control aggression
factor, allows the traction control function to be set up using a single variable to reduce
throttle more or less aggressively after the driven wheel slip angle exceeds its target.
Figure 23 - Throttle position plots for =80 (left) and 120 (right).
Notably, this function does assume that a driver is able to react instantaneously, or at least
as quickly as the integration stepsize, so this presents an ideal condition rather than a realistic
example of what a human driver would likely be able to achieve. In practice, however, it does
effectively prevent excessive wheel slip due to acceleration.
27
The typical action of the traction control system can be illustrated by running the simulation
using a reduced value of TCC, the tyre correction constant, to simulate the vehicle running on a
surface which produces less grip (such as a damp or cold circuit). By reducing the value of TCC to 0.3,
the following throttle plot is obtained for the start of the straight-line acceleration run:
Figure 24 - Throttle plot, showing throttle position reduction in response to excessive wheel slip
Figure 25 - Wheel slip of corresponding wheel - traction control function in this case activates when wheel slip exceeds 8 degrees.
In this case, ᵒ. Without the traction control function in place the rear wheel slip
will increase substantially and absolute acceleration of the vehicle will be much slower.
28
Brakes (Anti-Lock)
Most road-car ABS systems function by detecting whether a wheel is substantially under-
rotating in comparison to the other wheels, and releasing the brake on that particular wheel in the
event that it is. However, given that ABS systems are banned from Formula Student, as well as many
other motorsports categories which a sim such as this might be used for, it is assumed that any
brake position reduction must come from a "driver" input, and as a result will apply to all wheels,
regardless of slip.
Essentially the same principle used for the traction control system is employed to stop the
wheels from locking under braking. In this case however, the function will reduce total brake input if
any wheel exceeds the maximum allowable slip angle.
Figure 26 - Brake position is adjusted to counter under-rotation
The slip angle is controlled in just the same way as with the traction-control system in
acceleration.
This function was deemed to be effective at preventing the wheels from locking and
preserving braking force at near to its maximum value. Once again the function contains an
"aggression constant" , which allows the ABS to be set up to act more or less rapidly
in the event of an under-rotating wheel - it may not be desirable to set this constant very
high, as in the event of braking whilst there is some steering input then one wheel may
become unloaded and start to under-rotate even whilst the other wheels are not being
braked to even a fraction of their full potential.
29
Counter-Steer
One significant problem identified early on in testing of the simulation was the fact that the
vehicle had the tendency to spin during cornering, causing the simulation to fail. It had been
assumed prior to this that if the throttle and brake inputs were properly controlled then the vehicle
should be able to follow a set path without requiring corrective steering inputs, however this was
not the case. In order to solve this problem, the control function was modified to include counter-
steer, to stop the vehicle from sliding excessively.
First, the "drift angle" of the vehicle was identified, by comparing the yaw angle of the
vehicle with its trajectory - the "drift rate" (rate of change of the drift angle) is found from this and is
also incorporated into the function.
When driving a rear-wheel-drive car in a slide, if the front wheels are aligned with the
trajectory of the vehicle, then the slide will have a tendency to continue indefinitely. Since the aim of
this function is to limit the drift angle of the vehicle and hence prevent it from spinning, the steering
angle of the vehicle must work to counter the slide. It was found that a very effective way to do this
was to set the steering angle to oppose the drift rate of the vehicle, so that in the event that the
vehicle is yawing rapidly towards a spin, the steering input acts to kill some of the vehicle's yawing
rotational momentum before it reaches a significant excessive yaw angle. , the steering angle
for the front wheels, hence takes the form:
This function was tested using a "slalom" course, with the car weaving back and forth at high
speed to try and create a spin. Values of less than 0.1 are not typically enough to counter the
vehicle's yawing momentum and can be unstable particularly over rough terrain, whereas very high
values (>1) tend to prevent it from turning into corners quickly, as the steering itself opposes the
rotation of the vehicle to such a great extent.
30
The drift angle of the vehicle during the slalom course were plotted as such for different values of
:
As can be seen above, the highest value of results in a condition whereby the vehicle takes
longer to complete the slalom course, whilst the lowest value allows the vehicle to yaw more
considerably relative to its trajectory, resulting in a response that is more unstable, higher peaks of
drift angle, and in this case a faster completion of the course. For most paths, it was found that a
value of results in a relatively good compromise between stability and turn-in speed.
31
Path Creation and Following In order to have the simulated vehicle follow a pre-configured path, the desired path is
broken up into "sectors" - once the vehicle has completed the motion required to satisfy the
completion of one sector then it advances to the next one and so on. Each sector specifies target
brake, throttle and steering inputs, which will then be corrected by the traction control, abs and
counter-steering algorithms.
For example, the "slalom" test used to test the counter-steering function had the following
sectors:
Figure 27 - Slalom Course, Vehicle X & Y Positions
1. Accelerate along the x-axis for 300m, Throttle target=1, Brake target=0, Steering target is a function of the vehicle's Y-axis position to move it back towards the x-axis. Once the vehicle reaches 300m, Throttle target=0, Brake target=1, Steering target unchanged. Brake until the vehicle is doing 25m/s, then maintain 25m/s until the x-axis position of 340m has been reached.
2. Steer hard right (positive y-direction), Throttle target=1,Brake target=0, Steering target=15 degrees, until the y-axis position of 5m has been reached.
3. Steer hard left (negative y-direction), Throttle target=1, Brake target=0, Steering target =-15 degrees, until the y-axis position of -5m has been reached.
4. Identical to sector 2 5. Identical to sector 3 6. Identical to sector 2, however move
on to next sector once y-axis position of -4m has been reached.
7. Throttle target=1, Brake target=0, Steering target is a function of y-axis position to bring the vehicle back to the x-axis. Move on to final sector after x-axis position of 1500m has been reached.
8. Throttle target=0, Brake target=1, Steering target is a function of y-axis position to bring the vehicle back to the x-axis. End simulation once x-velocity drops below 1m/s.
32
Further results from the slalom simulation show how the vehicle model responds to this
manner of excitation:
Figure 28 - Vertical load applied to each tyre contact patch.
Figure 29 - Heights of chassis corners above ground - The roll of the vehicle and compression due to downforce can be visualised.
Figure 30 - Vertical loads applied front and rear due to downforce for example vehicle.
33
Figure 31 - Absolute vehicle velocity - drag created by steering slows the car down.
Using a similar syntax, it is possible to enter far more complex circuits into the model. One
piece of future work that would hold great promise would be the recreation of the standard formula
student circuits in this model. This would allow useful feedback on expected lap time differences for
any given modification.
34
Simulation Results and Discussion The vehicle simulation as it stands has a variety of useful applications in the development of
a formula student car - it can be used for selection of gear ratios and gear shift points, it can be used
to quantify the difference that moving the centre of mass or adding and removing weight in the
form of a heavier or lighter driver will make, and it can be used to examine the costs and benefits of
running a high or low-downforce car setup, so long as lift and drag is known for some defined speed.
A simulation such as this, that models tyre adhesion as well as the torque curve of the
engine, can offer a very useful insight into straight-line performance of the vehicle. For example, the
car's performance over the standard Formula Student 100m acceleration test can be calculated for
different weights of driver:
Equally, it is possible to use this simulation to decide at what RPM a shift-light or some other
such indicator should be triggered, in order to maximise acceleration, by looking at the rate of
acceleration with the gearbox function set to change up at different rpms (in this case assuming a
driver of 70Kg body mass):
5.2
5.4
5.6
5.8
6
6.2
0 20 40 60 80 100 120
Time to 100m
Driver Mass (Kg)
Time to 100m (s)
5.79
5.8
5.81
5.82
5.83
5.84
5.85
5.86
5.87
7500 8000 8500 9000 9500
Time (s)
Engine Upshift rpm
Time to 100m
35
A similar strategy can be employed in the evaluation of other parameters. For example, the
established "slalom" test can be used to examine the deflection of the suspension system and the
loads placed on each of the four tyres in dynamic cornering, so it is possible to look at the
differences made by a change in suspension stiffness/damping rate in this test:
Figure 32 - Vehicle corner heights during slalom test - standard vehicle settings shown above, spring stiffness and damping rate halved below
In this case, halving the spring stiffness and damping rate causes significant extra body roll in
the corners (as would be expected) and as a result the vehicle takes 0.19 seconds longer to complete
the slalom course, with a time of 41.63 seconds as opposed to 41.44 seconds for the standard
vehicle setup. With more complex track layouts incorporated into the steering function this tool
could provide very useful feedback on car setup and development.
36
Further Development There are some aspects of the current simulation that are simplified, and as a result there
are certain aspects of the car dynamics that will not be entirely accurate. It would be useful to obtain
further data in order to refine the tyre model, and also to allow for different
types/brands/compounds of tyre to be simulated and compared. This would require only that
reliable data be obtained and a new tyre slip relationship added to the rotation solver code.
In terms of assumptions that are made, the simulator currently assumes that all four tyres
are in contact with the ground at all times, which is likely to be correct in most situations, however in
the event of a substantial ground disturbance which would normally cause a wheel to break contact,
the current suspension model assumes that the springs of the suspension and tyre are still being
extended, creating a negative force between the vehicle and the road at that corner, above and
beyond the force of gravity. Currently, this is not particularly a problem as the vehicle is unlikely to
break contact at any point in a normal simulation, however this issue could be removed from the
simulation by adding extra cases to the modified quarter-car model to account for a wheel not in
contact with the ground surface.
Another issue is that the simulation does not currently allow for differences in tyre
pressure/temperature and fuel use. The former relationships could be found from more intensive
tyre testing, or estimated to some degree of accuracy using established tests on very similar tyres,
however this was not practically feasible for this particular project . Fuel use would be comparatively
easy to model so long as real-world data for the car setup was available - modelling the fuel tank as a
point mass, it would be relatively straightforward to recalculate the moments of inertia and centre
of gravity of the vehicle on every step. This was avoided in the current model as no reliable data for
fuel use was available, in addition to which the sim is currently very slow.
Calculation speed of the simulator is another thing that could be improved upon - largely for
the purposes of debugging the sim currently outputs almost all of its data as vectors, rather than
only outputting data that's likely to be useful to a particular scenario. In addition, due to the fact that
the simulation does not take place over some set time period it is not convenient to preallocate the
vectors in memory, so each calculation outputs close to a hundred vectors with a length equal to the
number of steps required to complete the calculation. The simulation also requires a very low
stepsize to be stable - running with a stepsize of 0.001s often resulted in erroneous data, so for the
majority of testing a stepsize of 0.0004 was used, and as a result the outputs of the slalom test for
example were over 100,000 data points long. If you wished to use the simulator to, for example, test
a formula student car out through a full endurance event (comprising 22 laps of the endurance
circuit) then these outputs would typically be about 3.8 million units long each, and could take a very
long time to complete.
Another useful improvement would be to create a function for calculating viable entry speed
and required braking distance for any given corner, in order to allow a lap to be more easily
simulated in the event of changing fuel loads/tyre temperatures. Currently, braking points and a
rough estimate of corner entry speeds would need to be added manually, and having a way to
automate this, perhaps using more basic calculations for static handling characteristics earlier in the
loop, would make the lap simulation much more useful in terms of providing feedback on which
modifications are likely to make the car lap faster, which is likely to be the primary focus of the
simulator in practical terms.
37
Validation
Finally, in order to validate the results of the simulator, it would be advantageous to conduct
a real-world test of a car modelled in the simulator, so that the results of the simulator could be
verified against an actual car. This is something that has been notably absent from the project up to
this point, largely due to the fact that no reliable and comprehensive telemetry exists for a car
utilising the tyres for which I have data is publicly available. Although the results obtained from
preliminary testing suggest that the car's behaviour is characteristically similar to what would be
expected of its behaviour, it is not at this point possible to say whether the results obtained from it
reflect the how a car with the simulated characteristics would behave in the real world.
Conclusions A model has been created that should represent the behaviour of a wheeled vehicle of
certain characteristics provided by the user, providing in-depth feedback on the behaviour of that
vehicle's dynamic handling behaviour. The control systems applied to the vehicle model are
sufficient to make the model stable, controlling the throttle, brake and steering inputs to prevent
the vehicle from sliding excessively in any manner.
Using the simulator, it has been possible to quantify the effect of changes in downforce,
suspension characteristics, vehicle weight & centre of gravity, engine upshift rpm, modifications to
the engine torque curve and variety of other variables upon a largely hypothetical car, something
which can inform design choices and speed up development.
Although it has not been possible within the timeframe of the project to verify the results of
the simulation against real-world telemetry, it represents a functional proof-of-concept for a
dynamic handling simulator in MATLAB, and the results gathered are characteristic of the results
that would be expected from the telemetry of a comparable real-world vehiclexix.
I feel that the model as is would represent a useful design aid for a formula student team
going forward, and with some improvements it could be a very useful lap simulation tool for
motorsports applications more generally.
Acknowledgements I would like to thank Professor Euan Mcgookin for his support and guidance in developing
this project, and for keeping me in mind of the importance of taking things one step at a time in
development. I'm also very grateful to Dr Edward M. Kasprzak of Milliken Research Associates for
providing an extremely useful tyre simulation dataset, and to the people at Hoosier tyres for
providing effective spring stiffness data for their tyres at various given pressures. Finally, I'd like to
thank the University of Glasgow Formula Student team, both for providing much in the way of useful
figures on their current design, and that without my time there I would not have been driven to
produce this tool for future seasons.
38
References i. http://www.fsaesim.com/simulation.html ii. Verros, G. and Natsiavas, S. (2005) Design Optimization of Quarter-car Models with Passive and Semi-
active Suspensions under Random Road Excitation. Journal of Vibration and Control, 11 p.581-606. iii. "Development of a Novel Hydro-Pneumatic Active Suspension", Gao B, Department of Mechanical
Engineering - University of Bath (2005) iv. http://www.hoosiertire.com/spring.htm v. "A Tool For Rapid Vehicle Suspension Design", Burgess MJ et al, Lotus Engineering (2004)
vi. "Cornering Time Estimation with Transient Dynamics under Bump Disturbance", Miura Y et al, Department of Aerospace Engineering - Osaka Prefecture University (2004)
vii. Graphic sourced from http://www.clarks-garage.com/graphics/wheel-slip-angle-1.jpg viii. "Tire and Vehicle Dynamics", Pacejka HB
ix. Jazar, R. N. (2008). Vehicle dynamics theory and applications. New York, Springer. http://site.ebrary.com/id/10230269.
x. Deakin, A. and Crolla, D. (2000) Fundamental Parameter Design Issues which Determine Race Car Performance. Society of Automotive Engineers, Inc., (2000-01-3537).
xi. Genta, G. (1997) Motor Vehicle Dynamics: Modelling and Simulation. p.498. xii. http://www.millikenresearch.com/fsaettc.html xiii. Heißing, B. and Ersoy, M. (2010) Chassis Handbook: Fundamentals, Driving Dynamics, Components,
Mechatronics, Perspectives. xiv. KTM Torque curves provided by Dynojet Research xv. http://students.sae.org/competitions/formulaseries/rules/2013fsaerules.pdf
xvi. http://www.racecar-engineering.com/cars/tu-delft/ - TU Delft 145Kg car from 2012. xvii. Hartman, J. (2011). Supercharging performance handbook. Minneapolis, Motor Books.
xviii. Murray, G. and Mcbeath, S. (1998) Competition Car Downforce: A Practical Guide. xix. Denton, T. (2011) Automobile Mechanical and Electrical Systems. 2nd ed.
39
Appendices
1.1 - Original Quarter-Car Model Script: clc
clear all
%Quarter-Car suspension model
%Chris Erwood 0902047
%First, need to define some parameters:
carquartermass=250; %Car is 250kg - assuming even weight distribution the weight on
this corner is 250kg.
carquarterundampedmass=20; %Undamped mass (Wheel+tyre+brake assembly primarily) on
this corner is 20kg.
susp_springrate=62000; %Spring stiffness of the main suspension in N/m.
susp_damping=1400; %Damping of the main suspension in Nm/s.
tyre_springrate=168306; %Effective spring stiffness of the tyre - this is non-
linear under extreme loads but for this basic model we will assume linearity.
tyre_damping=2000; %Damping of the tyre in Nm/s.
g=9.80665;
time=0;
i=1;
endtime=10;%input('Time to simulate?');
steptime=0.0005;%input('Time stepsize (seconds)?');
bumpheight=0;%input('Height of ground oscillation (m)?');
bumpdist=0;%input('Average Peak-to-Peak distance for ground oscilltion (m)?');
%Road unevenness will be represented as a sinusoidal disturbance.
carcgspeed=30;%input('Car speed (m/s)?');
bumpfreq=carcgspeed./bumpdist;
%Will try adding periodic movement for the ground, will also specify the
%height from the ground of the wheel centre and the top of the suspension.
hwheel=0.3; %0.3m
min_h_wheel=0.25; %No more than 5cm of tyre deflection is allowed
ln_tyre=0.06; %Effective natural spring length of the tyre is 6cm with no load
applied. In other words spring would be squashed to zero at 0.24m.
hsusp=0.6; %0.7m or 0.4m above the hub
ln_susp=0.3; %30cm suspension height when under no load.
min_h_susp=0.425; %Lower limit of suspension travel.
%All of the above heights are for the unloaded case.
ground_h=0;
%initial states
acc_susp=0;
vsusp=0;
acc_wheel=0;
vwheel=0;
hwheel_offset=0;
hsusp_offset=0;
hground_offset=0;
vground=0;
acc_ground=0;
while time<endtime
%hground_offset(i)=bumpheight*(sind(time*360*bumpfreq));
%vground=(bumpheight*(sind((time+steptime)*360*bumpfreq)));
if time<3
hground_offset(i)=0;
end
if time>3
hground_offset(i)=0.025;
end
if time>4
hground_offset(i)=0;
end
if i==1
40
vground(i)=0;
end
if i>1
vground(i)=(((hground_offset(i))-(hground_offset(i-1)))/steptime);
end
vwheel_output(i)=vwheel;
hground_output(i)=hground_offset(i);
vsusp_output(i)=vsusp;
hwheel_output(i)=hwheel;
hsusp_output(i)=hsusp;
hwheel_offset_output(i)=hwheel_offset;
hsusp_offset_output(i)=hsusp_offset;
hground_offset_output(i)=hground_offset(i);
acc_susp_output(i)=acc_susp;
acc_wheel_output(i)=acc_wheel;
acc_ground_output(i)=acc_ground;
force_susp=(-(carquartermass*g))+(susp_springrate*(hwheel_offset-
hsusp_offset))+(susp_damping*(vwheel-vsusp));
acc_susp=force_susp./carquartermass;
force_wheel=(-(carquarterundampedmass*g))+(susp_springrate*(hsusp_offset-
hwheel_offset))+(susp_damping*(vsusp-vwheel))+(tyre_springrate*(hground_offset(i)-
hwheel_offset))+(tyre_damping*(vground(i)-vwheel));
acc_wheel=force_wheel./carquarterundampedmass;
vwheel=vwheel+(acc_wheel*steptime);
vsusp=vsusp+(acc_susp*steptime);
hwheel_offset=hwheel_offset+(vwheel*steptime);
hsusp_offset=hsusp_offset+(vsusp*steptime);
hwheel=0.3+hwheel_offset;
hsusp=0.6+hsusp_offset;
susplength=hsusp-hwheel;
susplengthout(i)=susplength;
timeout(i)=time;
%For this initial test I'll assume the ground is flat
time=time+steptime;
i=i+1;
end
figure(1)
plot(timeout,hwheel_output,timeout,hsusp_output,timeout,hground_offset_output)
legend('Wheel Centre Height','Suspension-top Height','Ground Height Disturbance')
xlabel('Time (s)')
ylabel('Height (m)')
41
1.2 - Full-Car Model Main Script clc
clear all
%Full-Car suspension model
%Chris Erwood 0902047
%First, need to define some parameters:
global i
drivermass=50; %Driver mass (kg) - cg must be adjusted seperately
sprungmass=165; %Total sprung mass of the car (kg).
sprungmass=sprungmass+drivermass;
wheelweight=8; %Wheel/brake (basically unsprung) mass (kg).
susp_springratefront=62000; %Suspension springrate (N/m).
susp_dampingfront=20600; %Suspension damping (Nm/s).
susp_springraterear=71000; %Suspension rear springrate (N/m).
susp_dampingrear=28000; %Suspension damping (Nm/s)
tyre_springrate=168306; %Effective spring stiffness of the tyre - this is non-
linear under extreme loads but for this basic model we will assume linearity.
tyre_damping=2000; %Damping of the tyre in Nm/s.
g=9.80665;
time=0;
endtime=25; %one hundred seconds of simulation.
stepsize=0.0004; %1/2500th of a second stepsize.
i=1;
%Need to create some example values for a car:
hground=0;
hwheel=0.3; %height of wheel centre in unloaded case.
min_h_wheel=0.25; %No more than 5cm of tyre deflection is allowed
lntyre=0.06; %Effective natural spring length of the tyre is 6cm with no load
applied. In other words spring would be squashed to zero at 0.24m.
ltyre=(hwheel-hground)-0.24; %Current tyre spring length.
hsusp=0.6; %height of suspension top in unloaded case.
lnsusp=0.3; %30cm suspension height when under no load.
lsusp=(hsusp-hground)-0.3; %Current suspension spring length.
min_h_susp=(0.425+hground); %Lower limit of suspension travel.
%All of the above heights are for the unloaded case.
vground1=0;
accground1=0;
vground2=0;
accground2=0;
vground3=0;
accground3=0;
vground4=0;
accground4=0;
vwheel1=0;
vwheel2=0;
vwheel3=0;
vwheel4=0;
accwheel=0;
vcorner1=0;
vcorner2=0;
vcorner3=0;
vcorner4=0;
acccorner1=0;
acccorner2=0;
acccorner3=0;
acccorner4=0;
hcorner1=hsusp;
hcorner2=hsusp;
hcorner3=hsusp;
hcorner4=hsusp;
chassisroll=0;
chassispitch=0;
chassisyaw=0;
42
wheelbase=3.2; %3.2m wheelbase for demo.
track=1.5; %1.5m track for demo.
rollinertia=54.18;
pitchinertia=119.4;
yawinertia=204.8;
wheelinertia=1;
%Find values for these later.
sector(i)=1;
endsimulation=0; %This will be set to 1 when the course is finished.
tyrecorrectionconstant=0.7; %This specifies the proportion of the grip generated as
a proportion of Milliken Research's 2012 sandpaper test.
%Milliken recommend 0.6-0.7 as a suitable range of values for such a
%variable, as this should roughly correspond with the range of expected
%values, although this can be modified for hot or cold circuits in totally
%dry or slightly damp conditions. This simulation is not suitable for wet
%conditions as it has no concept of aquaplaning.
drivetrainefficiency=0.85; %This specifies the efficiency of the drivetrain -
normal values of this will be ~0.8-0.85.
%This value can be set to 1 if the torque values used in the torque curve
%were taken from the wheels.
frontdownforceconstant=0.2; %Front wing downforce at 1m/s in N.
reardownforceconstant=0.4; %Rear downforce at 1m/s in N.
while endsimulation==0;
time=time+stepsize;
%Insert ground disturbance function(s) here:
hground1(i)=0.0001*sin(0.1*time);
%hground1(i)=0;
hground2(i)=0.0001*sin(0.2*time);
%hground2(i)=0;
hground3(i)=0.0001*sin((0.1*time)-0.2);
%hground3(i)=0;
hground4(i)=0.0001*sin((0.2*time)-0.2);
%hground4(i)=0;
if i==1
frontdownforce(i)=0;
reardownforce(i)=0;
sector(i)=1; %This will be used to break up the "track" into easily
modelled sections.
sectorchange(i)=0;
timesector(i)=0;
vground1(i)=0;
accground1(i)=0;
vground2(i)=0;
accground2(i)=0;
vground3(i)=0;
accground3(i)=0;
vground4(i)=0;
accground4(i)=0;
vwheel1(i)=0;
vwheel2(i)=0;
vwheel3(i)=0;
vwheel4(i)=0;
accwheel(i)=0;
vcorner1(i)=0;
vcorner2(i)=0;
vcorner3(i)=0;
vcorner4(i)=0;
acccorner1(i)=0;
acccorner2(i)=0;
acccorner3(i)=0;
acccorner4(i)=0;
hcorner1(i)=hsusp;
hcorner2(i)=hsusp;
hcorner3(i)=hsusp;
hcorner4(i)=hsusp;
43
chassisroll(i)=0;
chassispitch(i)=0;
chassisyaw(i)=0;
wheelbase=3.2; %3.2m wheelbase for demo.
track=1.5; %1.5m track for demo.
cgx=1.2; %cgx 1.2m forward of the rear axle.
cgy=0.75;
cgz(i)=hsusp-0.40; %Vertical cg tied to suspension position.
momentvert1(i)=0;
momentvert2(i)=0;
momentvert3(i)=0;
momentvert4(i)=0;
hwheel1(i)=hwheel;
hwheel2(i)=hwheel;
hwheel3(i)=hwheel;
hwheel4(i)=hwheel;
end
% hcorner1current=hcorner1(i);
% hcorner2current=hcorner2(i);
% hcorner3current=hcorner3(i);
% hcorner4current=hcorner4(i);
% hground1current=hground1(i);
% hground2current=hground2(i);
% hground3current=hground3(i);
% hground4current=hground4(i);
% vground1current=vground1(i);
% vground2current=vground2(i);
% vground3current=vground3(i);
% vground4current=vground4(i);
% chassisrollcurrent=chassisroll(i);
% chassispitchcurrent=chassispitch(i);
% chassisyawcurrent=chassisyaw(i);
if i>1
hcorner1prev=hcorner1(i-1);
hcorner2prev=hcorner2(i-1);
hcorner3prev=hcorner3(i-1);
hcorner4prev=hcorner4(i-1);
vcorner1(i)=(hcorner1(i)-hcorner1(i-1))/stepsize;
vcorner2(i)=(hcorner2(i)-hcorner2(i-1))/stepsize;
vcorner3(i)=(hcorner3(i)-hcorner3(i-1))/stepsize;
vcorner4(i)=(hcorner4(i)-hcorner4(i-1))/stepsize;
vground1(i)=(hground1(i)-hground1(i-1))/stepsize;
vground2(i)=(hground2(i)-hground2(i-1))/stepsize;
vground3(i)=(hground3(i)-hground3(i-1))/stepsize;
vground4(i)=(hground4(i)-hground4(i-1))/stepsize;
%chassisrollrate(i)=(chassisroll(i)-chassisroll(i-1))/stepsize;
%chassispitchrate(i)=(chassispitch(i)-chassispitch(i-1))/stepsize;
%chassisyaw(i)=(chassisyaw(i)-chassispitch(i-1))/stepsize;
%vwheel1(i)=(hwheel1current-hwheel1(i-1))/stepsize;
%vwheel2(i)=(hwheel2current-hwheel2(i-1))/stepsize;
%vwheel3(i)=(hwheel3current-hwheel3(i-1))/stepsize;
%vwheel4(i)=(hwheel4current-hwheel4(i-1))/stepsize;
frontdownforce(i)=frontdownforceconstant*(vehiclevelocityabs(i-1))^2;
reardownforce(i)=reardownforceconstant*(vehiclevelocityabs(i-1))^2;
%This downforce calculation does not compensate for yaw - may need
%revising later.
end
%^In this case the car is running over an unequal disturbance at 15m/s.
%Now we can employ the quarter full car model to calculate all the
%relevant vertical chassis forces:
if i>1
ltyre1(i)=(hwheel1current-hground1(i))-0.24;
ltyre2(i)=(hwheel2current-hground2(i))-0.24;
ltyre3(i)=(hwheel3current-hground3(i))-0.24;
44
ltyre4(i)=(hwheel4current-hground4(i))-0.24;
lsusp1(i)=(hcorner1(i)-hwheel1current);
lsusp2(i)=(hcorner2(i)-hwheel2current);
lsusp3(i)=(hcorner3(i)-hwheel3current);
lsusp4(i)=(hcorner4(i)-hwheel4current);
end
if i==1
[fground1,fwheel1,fcorner1]=quarterfullcarmodel(tyre_springrate,susp_springratefron
t,tyre_damping,susp_dampingfront,lntyre,lnsusp,lntyre,lnsusp,0,0,0,wheelweight,0);
[fground2,fwheel2,fcorner2]=quarterfullcarmodel(tyre_springrate,susp_springratefron
t,tyre_damping,susp_dampingfront,lntyre,lnsusp,lntyre,lnsusp,0,0,0,wheelweight,0);
[fground3,fwheel3,fcorner3]=quarterfullcarmodel(tyre_springrate,susp_springratefron
t,tyre_damping,susp_dampingfront,lntyre,lnsusp,lntyre,lnsusp,0,0,0,wheelweight,0);
[fground4,fwheel4,fcorner4]=quarterfullcarmodel(tyre_springrate,susp_springratefron
t,tyre_damping,susp_dampingfront,lntyre,lnsusp,lntyre,lnsusp,0,0,0,wheelweight,0);
end
if i>1
[fground1,fwheel1,fcorner1]=quarterfullcarmodel(tyre_springrate,susp_springratefron
t,tyre_damping,susp_dampingfront,lntyre,lnsusp,ltyre1(i),lsusp1(i),vground1(i),vwhe
el1(i-1),vcorner1(i),wheelweight,momentvert1(i));
[fground2,fwheel2,fcorner2]=quarterfullcarmodel(tyre_springrate,susp_springratefron
t,tyre_damping,susp_dampingfront,lntyre,lnsusp,ltyre2(i),lsusp2(i),vground2(i),vwhe
el2(i-1),vcorner2(i),wheelweight,momentvert2(i));
[fground3,fwheel3,fcorner3]=quarterfullcarmodel(tyre_springrate,susp_springratefron
t,tyre_damping,susp_dampingfront,lntyre,lnsusp,ltyre3(i),lsusp3(i),vground3(i),vwhe
el3(i-1),vcorner3(i),wheelweight,momentvert3(i));
[fground4,fwheel4,fcorner4]=quarterfullcarmodel(tyre_springrate,susp_springratefron
t,tyre_damping,susp_dampingfront,lntyre,lnsusp,ltyre4(i),lsusp4(i),vground4(i),vwhe
el4(i-1),vcorner4(i),wheelweight,momentvert4(i));
end
fground1vec(i)=fground1;
fground2vec(i)=fground2;
fground3vec(i)=fground3;
fground4vec(i)=fground4;
%From the above we can calculate the maximum possible lateral loading
%on each wheel (based on the known data for the Hoosier tyres in
%question with 85KPa pressure):
wheel1maxlateralload(i)=(-0.0003*(fground1^2))+(2.9405*(fground1));
wheel2maxlateralload(i)=(-0.0003*(fground2^2))+(2.9405*(fground2));
wheel3maxlateralload(i)=(-0.0003*(fground3^2))+(2.9405*(fground3));
wheel4maxlateralload(i)=(-0.0003*(fground4^2))+(2.9405*(fground4));
fwheel1vec(i)=fwheel1;
fwheel2vec(i)=fwheel2;
fwheel3vec(i)=fwheel3;
fwheel4vec(i)=fwheel4;
fcorner1vec(i)=fcorner1;
fcorner2vec(i)=fcorner2;
fcorner3vec(i)=fcorner3;
fcorner4vec(i)=fcorner4;
accwheel1(i)=fwheel1/wheelweight;
accwheel2(i)=fwheel2/wheelweight;
accwheel3(i)=fwheel3/wheelweight;
accwheel4(i)=fwheel4/wheelweight;
if i>1;
vwheel1prev=vwheel1(i-1);
vwheel2prev=vwheel2(i-1);
vwheel3prev=vwheel3(i-1);
45
vwheel4prev=vwheel4(i-1);
hwheel1prev=hwheel1(i-1);
hwheel2prev=hwheel2(i-1);
hwheel3prev=hwheel3(i-1);
hwheel4prev=hwheel4(i-1);
vwheel1(i)=(vwheel1prev)+(accwheel1(i)*stepsize);
vwheel2(i)=(vwheel2prev)+(accwheel2(i)*stepsize);
vwheel3(i)=(vwheel3prev)+(accwheel3(i)*stepsize);
vwheel4(i)=(vwheel4prev)+(accwheel4(i)*stepsize);
hwheel1(i)=(hwheel1prev)+(vwheel1(i)*stepsize);
hwheel2(i)=(hwheel2prev)+(vwheel2(i)*stepsize);
hwheel3(i)=(hwheel3prev)+(vwheel3(i)*stepsize);
hwheel4(i)=(hwheel4prev)+(vwheel4(i)*stepsize);
end
%Need to record this relative to the ground for an accurate picture
%of how the wheel oscillates with the ground at a fixed zero
hwheel1delta(i)=hwheel1(i)-hground1(i);
hwheel2delta(i)=hwheel2(i)-hground2(i);
hwheel3delta(i)=hwheel3(i)-hground3(i);
hwheel4delta(i)=hwheel4(i)-hground4(i);
%Can do the same thing for the corners
hcorner1delta(i)=hcorner1(i)-hground1(i);
hcorner2delta(i)=hcorner2(i)-hground2(i);
hcorner3delta(i)=hcorner3(i)-hground3(i);
hcorner4delta(i)=hcorner4(i)-hground4(i);
hwheel1current=hwheel1(i);
hwheel2current=hwheel2(i);
hwheel3current=hwheel3(i);
hwheel4current=hwheel4(i);
vwheel1current=vwheel1(i);
vwheel2current=vwheel2(i);
vwheel3current=vwheel3(i);
vwheel4current=vwheel4(i);
wheel1radius(i)=hwheel1current-hground1(i);
wheel2radius(i)=hwheel2current-hground2(i);
wheel3radius(i)=hwheel3current-hground3(i);
wheel4radius(i)=hwheel4current-hground4(i);
%Next need to do the moment and resultant force calculations which will
%then be used to determine corner positions & cg positions.
%cgz is the only one that moves and it's really simple:
sumverticalload=(fcorner1+fcorner2+fcorner3+fcorner4)-(sprungmass*9.80665)-
frontdownforce(i)-reardownforce(i);
sumvert_vector(i)=sumverticalload;
cgz_acc(i)=sumverticalload/sprungmass; %note then that this does not quite
accurately represent the movement of cgz;
%This assumes that cgz's motion is equal to the motion of the chassis.
%This is not quite right due to the wheels but it's a good
%approximation.
cgx=1.7; %cgx 1.2m forward of the rear axle.
cgy=0.75;
if i==1;
cgz_vel=0;
cgz(i)=(hsusp-0.40)-hground(i);
%Add car starting positions:
vehiclepositionx(i)=0;
vehiclepositiony(i)=0;
vehiclepositionz(i)=0;
lateraloffsetfromtarget(i)=0;
%Also vehicle initial velocities & wheel rotation rates.
46
vehiclevelocityx(i)=5;
vehiclevelocityy(i)=0.001;
vehiclevelocityz(i)=0;
vehiclevelocityabs(i)=(((vehiclevelocityx(i))^2)+((vehiclevelocityy(i))^2)+((vehicl
evelocityz(i))^2))^(1/2);
vehiclevelocityabsmph(i)=2.23693629*vehiclevelocityabs(i); %Can be useful
for some applications.
v1x(i)=10;
v2x(i)=10;
v3x(i)=10;
v4x(i)=10;
v1y(i)=0;
v2y(i)=0;
v3y(i)=0;
v4y(i)=0;
%And roll, pitch & yaw of the vehicle
rollangle(i)=0;
pitchangle(i)=0;
yawangle(i)=0;
rollrate(i)=0;
pitchrate(i)=0;
yawrate(i)=0;
%We want all the wheels to start off slipping very slightly (avoids divide-
by-zero in other functions), so:
wheel1angvel(i)=0.0001+(vehiclevelocityx(i))/(wheel1radius(i));
wheel2angvel(i)=0.0001+(vehiclevelocityx(i))/(wheel2radius(i));
wheel3angvel(i)=0.0001+(vehiclevelocityx(i))/(wheel3radius(i));
wheel4angvel(i)=0.0001+(vehiclevelocityx(i))/(wheel4radius(i));
w3avcurrent=wheel3angvel(i);
w4avcurrent=wheel4angvel(i);
rearwheelengineangvel(i)=max([w3avcurrent,w4avcurrent]);
%For now, the gear ratio is 13.899 for gear 1.
gear(i)=1;
gearratio(i)=1;
gearchange(i)=0;
enginerpm(i)=60*(gearratio(i))*(rearwheelengineangvel(i));
[enginemaxoutputtorque(i)]=torquecurve(enginerpm(i));
enginetorque(i)=0;
enginetorquepw(i)=((enginetorque(i))/2)*drivetrainefficiency; %Per driven
wheel.
maxbraketorque=600; %This is the value applied to each wheel;
braketorque(i)=0;
%No throttle and brake inputs and throttle and brake target at zero
%for i=1:
throttle(i)=0;
throttletarget(i)=0;
brake(i)=0;
braketarget(i)=0;
%Also need moments of inertia for the wheels as the calculations
%will be based on applied moments:
wheel1inertia=1;
wheel2inertia=1;
wheel3inertia=1;
wheel4inertia=1;
%Finally, need to specify wheel offset yaw, which will be altered
%in the case of the front wheels by applying steering input later:
wheel1offsetyaw(i)=0;
wheel2offsetyaw(i)=0;
%Wheelcumulativeyaw will be the cumulative angle the wheel is
%pointing in (including the effect of the vehicle itself):
wheel1cumulativeyaw(i)=0;
47
wheel2cumulativeyaw(i)=0;
wheel3cumulativeyaw(i)=0;
wheel4cumulativeyaw(i)=0;
%Also set forces to zero to start with:
xforce1(i)=0;
xforce2(i)=0;
xforce3(i)=0;
xforce4(i)=0;
yforce1(i)=0;
yforce2(i)=0;
yforce3(i)=0;
yforce4(i)=0;
xforceaero(i)=0;
yforceaero(i)=0;
Cd=0.46; %Set Cd for flow for front profile.
Aeroarea=0.75;
end
%We can use these forces to calculate the absolestute accelerations and
%therefore velocities in absolute x & y directions
totalmass=sprungmass+(4*wheelweight);
if i==1
xforce_total(i)=xforce1(i)+xforce2(i)+xforce3(i)+xforce4(i)+xforceaero(i);
yforce_total(i)=yforce1(i)+yforce2(i)+yforce3(i)+yforce4(i)+yforceaero(i);
end
if i>1
xforceaero(i)=-(0.5*1.225*((vehiclevelocityx(i-1))^2)*Aeroarea*Cd); %Negative
as drag opposes motion
yforceaero(i)=-(0.5*1.225*((vehiclevelocityy(i-1))^2)*Aeroarea*Cd);
xforce_total(i)=xforce1(i-1)+xforce2(i-1)+xforce3(i-1)+xforce4(i-
1)+xforceaero(i);
xforce_frontwheels(i)=xforce1(i-1)+xforce2(i-1);
xforce_rearwheels(i)=xforce3(i-1)+xforce4(i-1);
yforce_total(i)=yforce1(i-1)+yforce2(i-1)+yforce3(i-1)+yforce4(i-
1)+yforceaero(i);
end
%If the stepsize is small enough, using forces from adjacent steps like
%this shouldn't really matter...
cgx_acc(i)=xforce_total(i)/totalmass;
cgy_acc(i)=yforce_total(i)/totalmass;
vehicleaccelerationx(i)=cgx_acc(i);
vehicleaccelerationy(i)=cgy_acc(i);
if i>1
vehiclevelocityx(i)=vehiclevelocityx(i-1)+(cgx_acc(i)*stepsize);
vehiclevelocityy(i)=vehiclevelocityy(i-1)+(cgy_acc(i)*stepsize);
vehiclevelocityabs(i)=(((vehiclevelocityx(i))^2)+((vehiclevelocityy(i))^2))^(0.5);
vehiclepositionx(i)=vehiclepositionx(i-1)+((vehiclevelocityx(i))*stepsize);
vehiclepositiony(i)=vehiclepositiony(i-1)+((vehiclevelocityy(i))*stepsize);
end
if i>1
if i==2
driftratedeg(i)=0;
end
if i>2
driftratedeg(i)=((vehicledriftangledeg(i-1))-(vehicledriftangledeg(i-
2)))/stepsize;
end
driftrate(i)=(driftratedeg(i))*(pi/180);
[wheel1offsetyaw(i),throttletarget(i),braketarget(i),sector(i),sectorchange(i),late
raloffsetfromtarget(i),endsimulation]=steeringinput3(wheel1offsetyaw(i-
1),lateraloffsetfromtarget(i-1),stepsize,yawangle(i-1),vehiclepositionx(i-
1),vehiclepositiony(i-1),vehiclevelocityx(i-1),vehiclevelocityy(i-1),sector(i-
1),sectorchange(i-1),vehicledriftangledeg(i-1),driftrate(i));
48
wheel2offsetyaw(i)=wheel1offsetyaw(i);
timesector(i)=timesector(i-1)+stepsize;
if sector(i)>sector(i-1)
sectortime(sector)=timesector(i); %This records the time for each track
sector
sectortimet(sector)=timeout(i-1);
timesector(i)=0; %Resets for the next sector
end
wheel1cumulativeyaw(i)=wheel1offsetyaw(i)+yawangle(i-1);
wheel2cumulativeyaw(i)=wheel2offsetyaw(i)+yawangle(i-1);
wheel3cumulativeyaw(i)=yawangle(i-1);
wheel4cumulativeyaw(i)=yawangle(i-1);
[throttle(i),brake(i)]=tcabs(slipangledegwheel1(i-1),slipangledegwheel2(i-
1),slipangledegwheel3(i-1),slipangledegwheel4(i-
1),throttletarget(i),braketarget(i),slipratiowheel1(i-1),slipratiowheel2(i-
1),slipratiowheel3(i-1),slipratiowheel4(i-1));
w3avcurrent=wheel3angvel(i-1);
w4avcurrent=wheel4angvel(i-1);
rearwheelengineangvel(i)=max([w3avcurrent,w4avcurrent]);
[gear(i),gearratio(i),gearchange(i),enginerpmout(i)]=gearbox(gear(i-
1),enginerpm(i-1));
enginerpm(i)=60*(1/(2*pi))*(gearratio(i))*(rearwheelengineangvel(i));
%If we choose to assume that the engine has a slipper-clutch as the
%majority of FSAE cars do, or else that the car will be shifted into
%neutral in the event that the wheels under-rotate, then:
if enginerpm(i)<1200;
enginerpm(i)=1200;
end
[enginemaxoutputtorque(i)]=torquecurve(enginerpm(i));
enginetorque(i)=((throttle(i))*(enginemaxoutputtorque(i)));
%To change this for acting per wheel, we can emulate an open diff by
%the presumption that each wheel gets a 50% torque split - this isn't
%terribly accurate but it will give results for testing:
enginetorquepw(i)=((enginetorque(i))/2)*((gearratio(i)))*drivetrainefficiency;
%torque applied per wheel is stepped up by the gear ratio.
braketorque(i)=(brake(i))*(maxbraketorque);
end
%Need to calculate the earth-centric x & y component velocities of each
%wheel. I built a function for this:
if i>1
[v1x(i),v1y(i),v2x(i),v2y(i),v3x(i),v3y(i),v4x(i),v4y(i)]=wheellinspeeds2(vehicleve
locityx(i),vehiclevelocityy(i),yawangle(i-1),cgx,cgy,wheelbase,track,yawrate(i-1));
end
%Next the slip forces can be calculated, so as to calculate the moments
%acting on the wheel and also the x&y component forces generated by
%each wheel.
if i==1
[slipangledegwheel1(i),slipratiowheel1(i),slipgeometry1(i),slipangleparalleld1(i),s
lipangleperpendicd1(i),slipdirectiondeg1,slipspeed1,slipforce1(i),slipforcedirectio
ndeg1(i),xforce1(i),yforce1(i),wheel1slipforceparallel(i),wheel1slipforceperpendicu
lar(i)]=slipsolver6(fground1,(0.0001+(vehiclevelocityx(i))/(wheel1radius(i))),wheel
1radius(i),wheel1cumulativeyaw(i),v1x(i),v1y(i),tyrecorrectionconstant);
[slipangledegwheel2(i),slipratiowheel2(i),slipgeometry2(i),slipangleparalleld2(i),s
lipangleperpendicd2(i),slipdirectiondeg2,slipspeed2,slipforce2(i),slipforcedirectio
ndeg2(i),xforce2(i),yforce2(i),wheel2slipforceparallel(i),wheel2slipforceperpendicu
lar(i)]=slipsolver6(fground1,(0.0001+(vehiclevelocityx(i))/(wheel2radius(i))),wheel
2radius(i),wheel2cumulativeyaw(i),v2x(i),v2y(i),tyrecorrectionconstant);
[slipangledegwheel3(i),slipratiowheel3(i),slipgeometry3(i),slipangleparalleld3(i),s
lipangleperpendicd3(i),slipdirectiondeg3,slipspeed3,slipforce3(i),slipforcedirectio
ndeg3(i),xforce3(i),yforce3(i),wheel3slipforceparallel(i),wheel3slipforceperpendicu
lar(i)]=slipsolver6(fground1,(0.0001+(vehiclevelocityx(i))/(wheel3radius(i))),wheel
3radius(i),wheel3cumulativeyaw(i),v3x(i),v3y(i),tyrecorrectionconstant);
49
[slipangledegwheel4(i),slipratiowheel4(i),slipgeometry4(i),slipangleparalleld4(i),s
lipangleperpendicd4(i),slipdirectiondeg4,slipspeed4,slipforce4(i),slipforcedirectio
ndeg4(i),xforce4(i),yforce4(i),wheel4slipforceparallel(i),wheel4slipforceperpendicu
lar(i)]=slipsolver6(fground1,(0.0001+(vehiclevelocityx(i))/(wheel4radius(i))),wheel
4radius(i),wheel4cumulativeyaw(i),v4x(i),v4y(i),tyrecorrectionconstant);
end
if i>1
[slipangledegwheel1(i),slipratiowheel1(i),slipgeometry1(i),slipangleparalleld1(i),s
lipangleperpendicd1(i),slipdirectiondeg1,slipspeed1,slipforce1(i),slipforcedirectio
ndeg1(i),xforce1(i),yforce1(i),wheel1slipforceparallel(i),wheel1slipforceperpendicu
lar(i)]=slipsolver6(fground1,wheel1angvel(i-
1),wheel1radius(i),wheel1cumulativeyaw(i),v1x(i),v1y(i),tyrecorrectionconstant);
[slipangledegwheel2(i),slipratiowheel2(i),slipgeometry2(i),slipangleparalleld2(i),s
lipangleperpendicd2(i),slipdirectiondeg2,slipspeed2,slipforce2(i),slipforcedirectio
ndeg2(i),xforce2(i),yforce2(i),wheel2slipforceparallel(i),wheel2slipforceperpendicu
lar(i)]=slipsolver6(fground1,wheel2angvel(i-
1),wheel2radius(i),wheel2cumulativeyaw(i),v2x(i),v2y(i),tyrecorrectionconstant);
[slipangledegwheel3(i),slipratiowheel3(i),slipgeometry3(i),slipangleparalleld3(i),s
lipangleperpendicd3(i),slipdirectiondeg3,slipspeed3,slipforce3(i),slipforcedirectio
ndeg3(i),xforce3(i),yforce3(i),wheel3slipforceparallel(i),wheel3slipforceperpendicu
lar(i)]=slipsolver6(fground1,wheel3angvel(i-
1),wheel3radius(i),wheel3cumulativeyaw(i),v3x(i),v3y(i),tyrecorrectionconstant);
[slipangledegwheel4(i),slipratiowheel4(i),slipgeometry4(i),slipangleparalleld4(i),s
lipangleperpendicd4(i),slipdirectiondeg4,slipspeed4,slipforce4(i),slipforcedirectio
ndeg4(i),xforce4(i),yforce4(i),wheel4slipforceparallel(i),wheel4slipforceperpendicu
lar(i)]=slipsolver6(fground1,wheel4angvel(i-
1),wheel4radius(i),wheel4cumulativeyaw(i),v4x(i),v4y(i),tyrecorrectionconstant);
end
remaininggrip1(i)=(wheel1maxlateralload(i))-
(((xforce1(i))^2)+((yforce1(i))^2))^(0.5);
remaininggrip2(i)=(wheel2maxlateralload(i))-
(((xforce2(i))^2)+((yforce2(i))^2))^(0.5);
remaininggrip3(i)=(wheel3maxlateralload(i))-
(((xforce3(i))^2)+((yforce3(i))^2))^(0.5);
remaininggrip4(i)=(wheel4maxlateralload(i))-
(((xforce4(i))^2)+((yforce4(i))^2))^(0.5);
slipspeed1x(i)=slipspeed1(1);
slipspeed1y(i)=slipspeed1(2);
slipspeed2x(i)=slipspeed2(1);
slipspeed2y(i)=slipspeed2(2);
slipspeed3x(i)=slipspeed3(1);
slipspeed3y(i)=slipspeed3(2);
slipspeed4x(i)=slipspeed4(1);
slipspeed4y(i)=slipspeed4(2);
if i==1
[wheel1angacc(i),wheel1angvel(i),combinedtorquewheel1(i)]=wheelincrement((0.0001+(v
ehiclevelocityx(i))/(wheel1radius(i))),wheel1inertia,wheel1radius(i),braketorque(i)
,0,wheel1slipforceparallel(i),stepsize);
[wheel2angacc(i),wheel2angvel(i),combinedtorquewheel2(i)]=wheelincrement((0.0001+(v
ehiclevelocityx(i))/(wheel2radius(i))),wheel2inertia,wheel2radius(i),braketorque(i)
,0,wheel2slipforceparallel(i),stepsize);
[wheel3angacc(i),wheel3angvel(i),combinedtorquewheel3(i)]=wheelincrement((0.0001+(v
ehiclevelocityx(i))/(wheel3radius(i))),wheel3inertia,wheel3radius(i),braketorque(i)
,enginetorquepw(i),wheel3slipforceparallel(i),stepsize); %Only the rear wheels are
driven.
[wheel4angacc(i),wheel4angvel(i),combinedtorquewheel4(i)]=wheelincrement((0.0001+(v
ehiclevelocityx(i))/(wheel4radius(i))),wheel4inertia,wheel4radius(i),braketorque(i)
,enginetorquepw(i),wheel4slipforceparallel(i),stepsize);
end
50
if i>1
[wheel1angacc(i),wheel1angvel(i),combinedtorquewheel1(i)]=wheelincrement(wheel1angv
el(i-
1),wheel1inertia,wheel1radius(i),braketorque(i),0,wheel1slipforceparallel(i),stepsi
ze);
[wheel2angacc(i),wheel2angvel(i),combinedtorquewheel2(i)]=wheelincrement(wheel2angv
el(i-
1),wheel2inertia,wheel2radius(i),braketorque(i),0,wheel2slipforceparallel(i),stepsi
ze);
[wheel3angacc(i),wheel3angvel(i),combinedtorquewheel3(i)]=wheelincrement(wheel3angv
el(i-
1),wheel3inertia,wheel3radius(i),braketorque(i),enginetorquepw(i),wheel3slipforcepa
rallel(i),stepsize); %Only the rear wheels are driven.
[wheel4angacc(i),wheel4angvel(i),combinedtorquewheel4(i)]=wheelincrement(wheel4angv
el(i-
1),wheel4inertia,wheel4radius(i),braketorque(i),enginetorquepw(i),wheel4slipforcepa
rallel(i),stepsize);
end
if i>1;
cgz_vel(i)=cgz_vel(i-1)+(cgz_acc(i)*stepsize);
cgz(i)=(cgz(i-1)+(cgz_vel(i)*stepsize));
end
if i==1;
[rollmoment,pitchmoment,yawmoment]=momentcalc3(xforce1(i),yforce1(i),fcorner1,xforc
e2(i),yforce2(i),fcorner2,xforce3(i),yforce3(i),fcorner3,xforce4(i),yforce4(i),fcor
ner4,cgx,cgy,cgz(i),wheelbase,track,frontdownforce(i),reardownforce(i),0);
end
if i>1;
[rollmoment,pitchmoment,yawmoment]=momentcalc3(xforce1(i),yforce1(i),fcorner1,xforc
e2(i),yforce2(i),fcorner2,xforce3(i),yforce3(i),fcorner3,xforce4(i),yforce4(i),fcor
ner4,cgx,cgy,cgz(i),wheelbase,track,frontdownforce(i),reardownforce(i),yawangle(i-
1));
end
[momentvert1(i+1),momentvert2(i+1),momentvert3(i+1),momentvert4(i+1)]=weighttransfe
rloads(rollmoment,pitchmoment,cgx,cgy,wheelbase,track,sprungmass);
rmout(i)=rollmoment;
pmout(i)=pitchmoment;
ymout(i)=yawmoment;
%^Vector outputs included for the purposes of debugging.
rollacc(i)=rollmoment/rollinertia;
pitchacc(i)=pitchmoment/pitchinertia;
yawacc(i)=yawmoment/yawinertia;
if i==1
rollangle(i)=0;
pitchangle(i)=0;
yawangle(i)=0;
end
if i>1
rollrate(i)=rollrate(i-1)+((rollacc(i))*stepsize);
pitchrate(i)=pitchrate(i-1)+((pitchacc(i))*stepsize);
yawrate(i)=yawrate(i-1)+((yawacc(i))*stepsize);
rollangle(i)=(rollangle(i-1))+(rollrate(i)*stepsize);
pitchangle(i)=(pitchangle(i-1))+(pitchrate(i)*stepsize);
yawangle(i)=(yawangle(i-1))+(yawrate(i)*stepsize);
end
rollanglecurrent=rollangle(i);
pitchanglecurrent=pitchangle(i);
suspbasicheight(i)=cgz(i)+0.40;
[heightdelta1current,heightdelta2current,heightdelta3current,heightdelta4current]=z
orientdisplacements(rollanglecurrent,pitchanglecurrent,cgx,cgy,wheelbase,track);
51
heightdelta1(i)=heightdelta1current;
heightdelta2(i)=heightdelta2current;
heightdelta3(i)=heightdelta3current;
heightdelta4(i)=heightdelta4current;
if i==1
hcorner1(i)=suspbasicheight(i);
hcorner2(i)=suspbasicheight(i);
hcorner3(i)=suspbasicheight(i);
hcorner4(i)=suspbasicheight(i);
hcorner1(i+1)=suspbasicheight(i);
hcorner2(i+1)=suspbasicheight(i);
hcorner3(i+1)=suspbasicheight(i);
hcorner4(i+1)=suspbasicheight(i);
end
if i>1
hcorner1(i+1)=suspbasicheight(i)+heightdelta1(i);
hcorner2(i+1)=suspbasicheight(i)+heightdelta2(i);
hcorner3(i+1)=suspbasicheight(i)+heightdelta3(i);
hcorner4(i+1)=suspbasicheight(i)+heightdelta4(i);
end
vehiclevelocityabsmph(i)=2.23693629*vehiclevelocityabs(i);
vehicletrajectorydeg(i)=atand(vehiclevelocityy/vehiclevelocityx);
vehicletrajectoryrad(i)=atan(vehiclevelocityy/vehiclevelocityx);
vehicleyawangledeg(i)=(yawangle(i))*(180/pi);
vehicledriftangledeg(i)=vehicleyawangledeg(i)-vehicletrajectorydeg(i);
timeout(i)=time;
i=i+1;
end
maxspeedreachedms=max(vehiclevelocityabs);
maxspeedreachedmph=max(vehiclevelocityabsmph);
figure(1)
plot(timeout,enginerpm)
xlabel('Time (s)')
ylabel('Engine rpm')
figure(2)
plot(timeout,vehiclevelocityabs)
xlabel('Time (s)')
ylabel('Vehicle Velocity (m/s)')
figure(3)
plot(timeout,cgz)
xlabel('Time (s)')
ylabel('cgz (m)')
figure(4)
plot(timeout,fground1vec,timeout,fground2vec,timeout,fground3vec,timeout,fground4ve
c)
title('Contact Patch Loadings (N)')
xlabel('Time (s)')
ylabel('Load (N)')
legend('Front-Left Wheel','Front-Right Wheel','Rear-Left Wheel','Rear-Right Wheel')
figure(5)
plot(timeout,wheel1maxlateralload,timeout,wheel2maxlateralload,timeout,wheel3maxlat
eralload,timeout,wheel4maxlateralload)
title('Max lateral tyre loadings (N)')
xlabel('Time (s)')
ylabel('Max lateral load (N)')
legend('Front-Left Wheel','Front-Right Wheel','Rear-Left Wheel','Rear-Right Wheel')
figure(6)
plot(timeout,hcorner1delta,timeout,hcorner2delta,timeout,hcorner3delta,timeout,hcor
ner4delta)
title('Vehicle Corner Heights')
xlabel('Time (s)')
ylabel('Height above ground (m)')
52
legend('Front-Left Corner','Front-Right Corner','Rear-Left Corner','Rear-Right
Corner')
figure(7)
plot(timeout,remaininggrip1,timeout,remaininggrip2,timeout,remaininggrip3,timeout,r
emaininggrip4)
title('Remaining available grip at each corner')
xlabel('Time (s)')
ylabel('Remaining Grip (N)')
legend('Front-Left Corner','Front-Right Corner','Rear-Left Corner','Rear-Right
Corner')
figure(8)
plot(timeout,vehiclevelocityabsmph)
xlabel('Time (s)')
ylabel('Vehicle Velocity (m/s)')
figure(9)
plot(vehiclepositiony,vehiclepositionx)
title('Vehicle 2-D Path')
xlabel('Y-axis position')
ylabel('X-axis position')
figure(10)
plot(vehiclevelocityabs,wheel1maxlateralload,vehiclevelocityabs,wheel2maxlateralloa
d,vehiclevelocityabs,wheel3maxlateralload,vehiclevelocityabs,wheel4maxlateralload)
title('Vehicle Speed and Maximum Lateral Load by tyre')
xlabel('Vehicle Speed (m/s)')
ylabel('Tyre maximum lateral load (N)')
legend('Front-Left Corner','Front-Right Corner','Rear-Left Corner','Rear-Right
Corner')
figure(11)
plot(vehiclevelocityabs,hcorner1delta,vehiclevelocityabs,hcorner2delta,vehicleveloc
ityabs,hcorner3delta,vehiclevelocityabs,hcorner4delta)
title('Vehicle Speed and corner height')
xlabel('Vehicle Speed (m/s)')
ylabel('Vehicle Corner Height (m)')
legend('Front-Left Corner','Front-Right Corner','Rear-Left Corner','Rear-Right
Corner')
figure(12)
plot(timeout,throttle)
title('Throttle Position')
xlabel('Time (s)')
ylabel('Throttle Position')
53
1.3 - Tyre Lateral Load Calculation Function function
[slipangle_deg,slipratio,slip_geometry,slipangle_paralleld,slipangle_perpendid,slip
_direction_deg,slipspeed,slipforce,slipforce_direction_deg,slipforce_x,slipforce_y,
slipforce_parallel,slipforce_perpendicular,fymax]=slipsolver6(force_ground,wheelrot
speedr,wheelradius,wheelyawangle_deg,wheel_x_speed,wheel_y_speed,tyrecorrectioncons
tant)
%This function will be designed to take the speed of the wheel in the x and
%y directions, and the wheel rotational speed in degrees along with the
%radius and yaw angle (with 0 degrees representing a wheel pointing
%straight along the positive x axis, and 90 degrees representing a wheel
%pointing straight along the positive y axis) and output the slip angle,
%direction, and also the force generated by that slip and the direction the
%force is acting in. Finally, it will output the x and y components of this
%force so that they can be used to calculate the moments generated by each
%wheel about the CG of the car.
wheelyawangle_deg=(180/pi*wheelyawangle_deg);
wheeldirectionalspeed=wheelrotspeedr*wheelradius;
wheelxrotationalspeed=wheeldirectionalspeed*(cosd(wheelyawangle_deg));
wheelyrotationalspeed=wheeldirectionalspeed*(sind(wheelyawangle_deg));
wheelrotationalspeed=[wheelxrotationalspeed,wheelyrotationalspeed];
wheelabsolutespeed=[wheel_x_speed,wheel_y_speed];
slipspeed_x=wheelxrotationalspeed-wheel_x_speed;
slipspeed_y=wheelyrotationalspeed-wheel_y_speed;
slipspeed=[slipspeed_x,slipspeed_y];
%Change for version 0.2:
%There is an issue with the geometry here and calculation of slip
%direction.
slip_direction_deg=0;
if slipspeed_x>0
if slipspeed_y>0
slip_direction_deg=atand(slipspeed_y/slipspeed_x);
end
if slipspeed_y<0
slip_direction_deg=360-atand((-slipspeed_y)/slipspeed_x);
end
end
if slipspeed_x<0
if slipspeed_y>0
slip_direction_deg=180-atand((-slipspeed_y)/slipspeed_x);
end
if slipspeed_y<0
slip_direction_deg=180+atand(slipspeed_y/slipspeed_x);
end
end
if slipspeed_y==0
slip_direction_deg=0;
end
%We now have the slip speed & direction. Next, this gets converted to
%components parallel and perpendicular to the direction the wheel is
%pointing in.
%First from the x-component
xslip_parallel=slipspeed_x*(cosd(wheelyawangle_deg));
xslip_perpendi=slipspeed_x*(sind(wheelyawangle_deg));
%Then from the y-component
yslip_parallel=slipspeed_y*(sind(wheelyawangle_deg));
yslip_perpendi=slipspeed_y*(cosd(wheelyawangle_deg));
slip_parallel=xslip_parallel+yslip_parallel;
slip_perpendi=xslip_perpendi+yslip_perpendi;
%We will use these later. Need to calculate wheel matched speed for
%rotation (so need wheel forward speed).
wheelforwardspeed=(wheel_x_speed*(cosd(wheelyawangle_deg)))+(wheel_y_speed*(sind(wh
eelyawangle_deg)));
54
wheelmatchedspeedr=wheelforwardspeed/wheelradius;
slipratio=(wheelrotspeedr/wheelmatchedspeedr);
if wheelmatchedspeedr==0
slipratio=(wheelrotspeedr/(wheelmatchedspeedr+0.000001)); %prevents NaN
end
if slipratio<0
slipratio=abs(slipratio);
end
if slipratio>1
slipratio=(1/slipratio);
end
slipangle_paralleld=acosd(slipratio);
slipangle_perpendid=asind(slip_perpendi/wheelforwardspeed);
if slipangle_paralleld>90
slipangle_paralleld=90;
end
if slipangle_paralleld<-90
slipangle_paralleld=-90;
end
if slipangle_perpendid>90
slipangle_perpendid=90;
end
if slipangle_perpendid<-90
slipangle_perpendid=-90;
end
fymax=((-0.0003*(force_ground^2))+(2.9405*(force_ground))*tyrecorrectionconstant);
slipforce_parallel=(fymax*((-
0.015625*((abs(slipangle_paralleld)^2)))+(0.25*abs(slipangle_paralleld))));
%This represents magnitude only.
if abs(slipangle_paralleld)>8.25
slipforce_parallel=fymax*(0.999-((abs(slipangle_paralleld)*0.0181)));
end
slipforce_perpendicular=(fymax*((-
0.015625*((abs(slipangle_perpendid)^2)))+(0.25*abs(slipangle_perpendid))));
if abs(slipangle_perpendid)>8.25
slipforce_perpendicular=fymax*(0.999-((abs(slipangle_perpendid)*0.0181)));
end
if slip_parallel<0
slipforce_parallel=-slipforce_parallel;
end
if slip_perpendi<0
slipforce_perpendicular=-slipforce_perpendicular;
end
slipangle_deg=slipangle_paralleld+slipangle_perpendid;
%Next is body-fixed slipforce direction
slipforce_direction_deg_bf=atand(slipforce_perpendicular+0.0000001/slipforce_parall
el+0.0000001); %atand(0/0)=NaN so add tiny inconsequential values to top and
bottom.
slipforce_direction_deg=slipforce_direction_deg_bf+wheelyawangle_deg;
slipforce=((slipforce_parallel^2)+(slipforce_perpendicular^2))^(0.5);
slipforce_x_parallel=slipforce_parallel*cosd(wheelyawangle_deg);
slipforce_y_parallel=slipforce_parallel*sind(wheelyawangle_deg);
slipforce_x_perpendicular=slipforce_perpendicular*sind(wheelyawangle_deg);
slipforce_y_perpendicular=slipforce_perpendicular*cosd(wheelyawangle_deg);
slipforce_x=slipforce_x_parallel+slipforce_x_perpendicular;
slipforce_y=slipforce_y_parallel+slipforce_y_perpendicular;
55
1.4 Engine Torque Curve Function function[enginemaxoutputtorque]=torquecurve(engine_rpm)
%This function should be rewritten for any new simulation, so that if there
%has been an engine change or other such thing then the new engine is
%properly represented. The engine in this example is the KTM 525exc.
%Torques throughout are given as lb.ft, and are then translated into N.m at
%the end of the function.
bandset=0;
if engine_rpm<0
if bandset==0
torquelbft=0;
bandset=1;
end
end
if engine_rpm<3800
if bandset==0
torquelbft=0.0072368421052632*engine_rpm;
bandset=1;
end
end
if engine_rpm<4000
if bandset==0
torquelbft=27.5-(0.0025*(3800-engine_rpm));
bandset=1;
end
end
if engine_rpm<4200
if bandset==0
torquelbft=28+(0.005*(4000-engine_rpm));
bandset=1;
end
end
if engine_rpm<4400
if bandset==0
torquelbft=27-(0.0025*(4200-engine_rpm));
bandset=1;
end
end
if engine_rpm<4600
if bandset==0
torquelbft=27.5-(0.01*(4400-engine_rpm));
bandset=1;
end
end
if engine_rpm<4800
if bandset==0
torquelbft=29.5-(0.005*(4600-engine_rpm));
bandset=1;
end
end
if engine_rpm<5000
if bandset==0
torquelbft=30.5-(0.00375*(4800-engine_rpm));
bandset=1;
end
end
if engine_rpm<5200
if bandset==0
torquelbft=31.25-(0.00375*(5000-engine_rpm));
bandset=1;
end
end
if engine_rpm<5400
if bandset==0
torquelbft=32-(0.00375*(5200-engine_rpm));
bandset=1;
end
end
if engine_rpm<5600
if bandset==0
torquelbft=32.75-(0.0025*(5400-engine_rpm));
bandset=1;
end
end
if engine_rpm<5800
56
if bandset==0
torquelbft=33.25-(0.00375*(5600-engine_rpm));
bandset=1;
end
end
if engine_rpm<6000
if bandset==0
torquelbft=34-(0.00125*(5800-engine_rpm));
bandset=1;
end
end
if engine_rpm<6200
if bandset==0
torquelbft=34.25-(0.00125*(6000-engine_rpm));
bandset=1;
end
end
if engine_rpm<6600
if bandset==0
torquelbft=34.5;
bandset=1;
end
end
if engine_rpm<6800
if bandset==0
torquelbft=34.5+(0.0025*(6600-engine_rpm));
bandset=1;
end
end
if engine_rpm<7000
if bandset==0
torquelbft=34+(0.00125*(6800-engine_rpm));
bandset=1;
end
end
if engine_rpm<7200
if bandset==0
torquelbft=33.75+(0.00125*(7000-engine_rpm));
bandset=1;
end
end
if engine_rpm<7400
if bandset==0
torquelbft=33.5+(0.0025*(7200-engine_rpm));
bandset=1;
end
end
if engine_rpm<7600
if bandset==0
torquelbft=33+(0.0025*(7400-engine_rpm));
bandset=1;
end
end
if engine_rpm<7800
if bandset==0
torquelbft=32.5+(0.005*(7600-engine_rpm));
bandset=1;
end
end
if engine_rpm<8000
if bandset==0
torquelbft=31.5+(0.005*(7800-engine_rpm));
bandset=1;
end
end
if engine_rpm<8200
if bandset==0
torquelbft=30.5+(0.005*(8000-engine_rpm));
bandset=1;
end
end
if engine_rpm<8400
if bandset==0
torquelbft=29.5+(0.0075*(8200-engine_rpm));
bandset=1;
end
end
57
if engine_rpm<8600
if bandset==0
torquelbft=28+(0.0075*(8400-engine_rpm));
bandset=1;
end
end
if engine_rpm<8800
if bandset==0
torquelbft=26.5+(0.0075*(8600-engine_rpm));
bandset=1;
end
end
if engine_rpm<9000
if bandset==0
torquelbft=25+(0.005*(8800-engine_rpm));
bandset=1;
end
end
if engine_rpm<9200
if bandset==0
torquelbft=24+(0.0075*(9000-engine_rpm));
bandset=1;
end
end
if engine_rpm<9400
if bandset==0
torquelbft=22.5+(0.0025*(9200-engine_rpm));
bandset=1;
end
end
if engine_rpm<9600
if bandset==0
torquelbft=22+(0.01*(9400-engine_rpm));
bandset=1;
end
end
if engine_rpm<9800
if bandset==0
torquelbft=20+(0.03*(9600-engine_rpm));
bandset=1;
end
end
if engine_rpm<10000
if bandset==0
torquelbft=14+(0.07*(9800-engine_rpm));
bandset=1;
end
end
if engine_rpm>10000
if bandset==0
torquelbft=0; %This acts as a rev limiter
bandset=1;
end
end
enginemaxoutputtorque=torquelbft*1.35581795;
if bandset==1
enginemaxoutputtorque=torquelbft*1.35581795; %Figure taken from
http://www.convertunits.com/from/ft+lb/to/N+m
end
%So this function is able to plot the torque curve of the engine in NM.
58
1.5 Gear Selection/Ratio (Gearbox) function function[gear,gearratio,gearchange,enginerpmout]=gearbox(gearin,enginerpm)
%This function takes the current gear and engine rpm and decides whether or
%not a gear change is required.
upshiftrpm=9200; %self-explanatory - the gearbox will shift up a gear at
this rpm.
gears=5; %The number of speeds in the transmission.
targetdownshiftrpm=8500; %The gearbox will not drop a gear unless the
engine will be at less than this rpm in the next gear down.
finaldrive=3; %Final drive ratio of the gearbox.
gearratios=finaldrive*[4.5,3.3,2.5,2,1.6];
if gearin==1;
if enginerpm<9200
gear=1;
gearchange=0;
enginerpmout=enginerpm;
end
if enginerpm>9200
gear=2;
gearchange=1;
enginerpmout=enginerpm*((gearratios(2))/(gearratios(1)));
end
end
if gearin==2;
enginerpmfordownshift=targetdownshiftrpm*((gearratios(2))/(gearratios(1)));
if enginerpm<enginerpmfordownshift
gear=1;
gearchange=1;
enginerpmout=enginerpm*((gearratios(1))/(gearratios(2)));
end
if enginerpm>enginerpmfordownshift
gear=2;
gearchange=0;
enginerpmout=enginerpm;
end
if enginerpm>upshiftrpm
gear=3;
gearchange=1;
enginerpmout=enginerpm*((gearratios(3))/(gearratios(2)));
end
end
if gearin==3;
enginerpmfordownshift=targetdownshiftrpm*((gearratios(3))/(gearratios(2)));
if enginerpm<enginerpmfordownshift
gear=2;
gearchange=1;
enginerpmout=enginerpm*((gearratios(2))/(gearratios(3)));
end
if enginerpm>enginerpmfordownshift
gear=3;
gearchange=0;
enginerpmout=enginerpm;
end
if enginerpm>upshiftrpm
gear=4;
gearchange=1;
enginerpmout=enginerpm*((gearratios(4))/(gearratios(3)));
59
end
end
if gearin==4;
enginerpmfordownshift=targetdownshiftrpm*((gearratios(4))/(gearratios(3)));
if enginerpm<enginerpmfordownshift
gear=3;
gearchange=1;
enginerpmout=enginerpm*((gearratios(3))/(gearratios(4)));
end
if enginerpm>enginerpmfordownshift
gear=4;
gearchange=0;
enginerpmout=enginerpm;
end
if enginerpm>upshiftrpm
gear=5;
gearchange=1;
enginerpmout=enginerpm*((gearratios(5))/(gearratios(4)));
end
end
if gearin==5;
enginerpmfordownshift=targetdownshiftrpm*((gearratios(5))/(gearratios(4)));
if enginerpm<enginerpmfordownshift
gear=4;
gearchange=1;
enginerpmout=enginerpm*((gearratios(4))/(gearratios(5)));
end
if enginerpm>enginerpmfordownshift
gear=5;
gearchange=0;
enginerpmout=enginerpm;
end
end
gearratio=gearratios(gear);
60
1.6 - Traction Control/ABS function function[throttle,brake]=tcabs(slipangledeg1,slipangledeg2,slipangledeg3,slipangled
eg4,throttletarget,braketarget,sr1,sr2,sr3,sr4)
%This function seeks to emulate the traction control and ABS systems of the
%car by looking at the slip angle of each tyre (in degrees) and the target
%throttle and brake outputs as desired by the path following algorithm.
throttle=throttletarget;
brake=braketarget;
%^these two will be over-written if excessive slip is occuring.
absmodel_linear=0;
linearabsagressionfactor=5; %Defines the percentage by which the brakes are
released for every degree of over-slip in the linear case.
absmodel_exponential=1;
exponentialabsagressionfactor=100; %May be used to control the severity of the ABS
input;
%^This will define whether the ABS releases the brakes linearly for
%over-slip or inverse-exponentially.
absmodel_maxslipangle=8;
%This can be used to set the value of tyre slip (in degrees) that causes the ABS to
%start kicking in.
tcmodel_linear=0;
lineartcagressionfactor=5;
tcmodel_exponential=1;
exponentialtcagressionfactor=120;
tcmodel_maxslipangle=8;
%This function will assume that the rear wheels are the driven wheels and
%will thus ignore front wheel slip for the purposes of throttle control.
slipmatrixabs=[slipangledeg1,slipangledeg2,slipangledeg3,slipangledeg4];
%Need to find the highest value in the matrix - this can be used to trigger
%the ABS, so that if a single wheel locks up the brakes will be released.
maxslipabs=max(slipmatrixabs); %The retargeting of the braking will be based on the
wheel with the most slip.
if maxslipabs>absmodel_maxslipangle
if absmodel_linear==1;
brake=braketarget-((maxslipabs-
absmodel_maxslipangle)*linearabsagressionfactor);
end
if absmodel_exponential==1;
brake=braketarget*((absmodel_maxslipangle^(0.02*exponentialabsagressionfactor))/(ma
xslipabs^(0.02*exponentialabsagressionfactor)));
end
end
%Next need to do the same thing with throttle.
%Since we're only interested in the rear wheels it gets modified slightly:
slipmatrixtc=[slipangledeg3,slipangledeg4];
maxsliptc=max(slipmatrixtc);
if maxsliptc>tcmodel_maxslipangle
if tcmodel_linear==1
throttle=throttletarget-((maxsliptc-
tcmodel_maxslipangle)*(lineartcagressionfactor));
end
if tcmodel_exponential==1;
throttle=throttletarget*((tcmodel_maxslipangle^(0.02*exponentialtcagressionfactor))
/(maxsliptc^(0.02*exponentialtcagressionfactor)));
end
end
if throttle<0
throttle=0;
end
61
1.7 Steering/Path following Function function
[wheeloffsetyaw,throttleposition,brakeposition,sector,sectorchange,lateraloffsetfro
mtarget,endsimulation]=steeringinput3(previousoffset,previouslateraloffset,stepsize
,vehicleyawangle,xpos,ypos,xvel,yvel,sector,sectorchange,driftangledeg,driftrate)
%Steering function V0.1
%This function applies the appropriate steering angle based on the
%vehicle's position.
%The "Sector" syntax allows the vehicle to accelerate, decelerate and turn
%by breaking up the path into simple shapes (constant and variable radius
%turns and straights). This will be used in the other control systems.
%The sim will start by accelerating from 10m/s until the car has covered
%a given distance, it will then brake to 20m/s and execute a constant
%radius turn for 90 degrees, after which it will accelerate for another length
before
%slowing to 5m/s. This will be split into three sections.
straight1length=300; %length of first straight in metres.
turnstartlength=340;
corner1radius=60; %radius of first corner in metres.
maxsteerangle=40; %maximum steering angle (degrees)
maxsteerrad=(maxsteerangle*(pi/180));
straight2length=1400;
driftangle=driftangledeg*(pi/180);
csag=0.7; %Counter-steer aggression factor.
if sector==1
sectorchange=0;
endsimulation=0;
%This will be used for a straight line acceleration.
throttleposition=1;
brakeposition=0;
lateraloffsetfromtarget=ypos;
%wheeloffsetyaw will be calculated in radians and the rate will be
%limited by comparison with the previous offset.
wheeloffsetyaw=((-0.01*lateraloffsetfromtarget)-(driftangle)-(csag*driftrate));
%Vehicle will accelerate along y=0;
%wheeloffsetyaw=(0.001*sind(10*xpos));
%Next will be the rate limiting function:
%if (wheeloffsetyaw-previousoffset)>(50*pi*stepsize) %2 rotations/s
% wheeloffsetyaw=previousoffset+(50*pi*stepsize);
%end
%if (wheeloffsetyaw-previousoffset)<(-50*pi*stepsize) %-2 rotations/s
% wheeloffsetyaw=previousoffset-(50*pi*stepsize);
%end
if wheeloffsetyaw>maxsteerrad
wheeloffsetyaw=maxsteerrad;
end
if wheeloffsetyaw<(-maxsteerrad)
wheeloffsetyaw=-maxsteerrad;
end
%This is all that's required for steering, since we're going to try
%first accelerating from 10m/s for 350m and then slowing back to 20m/s we'll
need to
%set these simple terms:
if xpos<straight1length
throttleposition=1;
brakeposition=0;
end
if xpos>straight1length
throttleposition=1;
brakeposition=0;
if xvel>24.999
brakeposition=0;
throttleposition=0.25;
if xvel>25.001
brakeposition=1;
throttleposition=0;
62
end
end
if xpos>turnstartlength
sectorchange=1;
sector=sector+1;%At this point the acceleration stage is complete and the
sim can skip to the next section.
brakeposition=0;
throttleposition=0;
endsimulation=0;
end
end
end
%Sector 2 will be a constant radius turn in the positive-y direction
if sector==2
if sectorchange==1
sectorchange=0;
end
throttleposition=1;
brakeposition=0;
xdeltaccp=xpos-turnstartlength;
ydeltaccp=ypos-corner1radius;
lateraloffsetfromtarget=corner1radius-(sqrt((xdeltaccp^2)+(ydeltaccp^2)));
wheeloffsetyaw=(-((pi/6)-vehicleyawangle))-driftangle;
if vehicleyawangle<(pi/6)
wheeloffsetyaw=(15*(pi/180))-(0.8*driftangle)-(csag*driftrate);
end
if wheeloffsetyaw>maxsteerrad
wheeloffsetyaw=maxsteerrad;
end
if wheeloffsetyaw<(-maxsteerrad)
wheeloffsetyaw=-maxsteerrad;
end
if ypos>(5);
sectorchange=1;
sector=sector+1;
end
endsimulation=0;
end
if sector==3
if sectorchange==1
sectorchange=0;
end
throttleposition=1;
brakeposition=0;
xdeltaccp=xpos-turnstartlength;
ydeltaccp=ypos-corner1radius;
lateraloffsetfromtarget=corner1radius-(sqrt((xdeltaccp^2)+(ydeltaccp^2)));
wheeloffsetyaw=(0.4*(pi/180))-driftangle;
if vehicleyawangle>(-pi/12)
wheeloffsetyaw=(-15*pi/180)-(driftangle)-(csag*driftrate);
end
if wheeloffsetyaw>maxsteerrad
wheeloffsetyaw=maxsteerrad;
end
if wheeloffsetyaw<(-maxsteerrad)
wheeloffsetyaw=-maxsteerrad;
end
if ypos<(-5);
sectorchange=1;
sector=sector+1;
end
endsimulation=0;
end
if sector==4
63
if sectorchange==1
sectorchange=0;
end
throttleposition=1;
brakeposition=0;
xdeltaccp=xpos-turnstartlength;
ydeltaccp=ypos-corner1radius;
lateraloffsetfromtarget=corner1radius-(sqrt((xdeltaccp^2)+(ydeltaccp^2)));
wheeloffsetyaw=(-((pi/6)-vehicleyawangle))-driftangle;
if vehicleyawangle<(pi/6)
wheeloffsetyaw=(15*(pi/180))-(driftangle)-(csag*driftrate);
end
if wheeloffsetyaw>maxsteerrad
wheeloffsetyaw=maxsteerrad;
end
if wheeloffsetyaw<(-maxsteerrad)
wheeloffsetyaw=-maxsteerrad;
end
if ypos>(5);
sectorchange=1;
sector=sector+1;
end
endsimulation=0;
end
if sector==5
if sectorchange==1
sectorchange=0;
end
throttleposition=1;
brakeposition=0;
xdeltaccp=xpos-turnstartlength;
ydeltaccp=ypos-corner1radius;
lateraloffsetfromtarget=corner1radius-(sqrt((xdeltaccp^2)+(ydeltaccp^2)));
wheeloffsetyaw=(0.4*(pi/180))-driftangle;
if vehicleyawangle>(-pi/12)
wheeloffsetyaw=(-15*pi/180)-(driftangle)-(csag*driftrate);
end
if wheeloffsetyaw>maxsteerrad
wheeloffsetyaw=maxsteerrad;
end
if wheeloffsetyaw<(-maxsteerrad)
wheeloffsetyaw=-maxsteerrad;
end
if ypos<(-5);
sectorchange=1;
sector=sector+1;
end
endsimulation=0;
end
if sector==6
if sectorchange==1
sectorchange=0;
end
throttleposition=1;
brakeposition=0;
xdeltaccp=xpos-turnstartlength;
ydeltaccp=ypos-corner1radius;
lateraloffsetfromtarget=corner1radius-(sqrt((xdeltaccp^2)+(ydeltaccp^2)));
wheeloffsetyaw=(-((pi/6)-vehicleyawangle))-driftangle;
if vehicleyawangle<(pi/6)
wheeloffsetyaw=(15*(pi/180))-(driftangle)-(csag*driftrate);
end
if wheeloffsetyaw>maxsteerrad
64
wheeloffsetyaw=maxsteerrad;
end
if wheeloffsetyaw<(-maxsteerrad)
wheeloffsetyaw=-maxsteerrad;
end
if ypos>(-4);
sectorchange=1;
sector=sector+1;
end
endsimulation=0;
end
if sector==7
if sectorchange==1
sectorchange=0;
end
throttleposition=1;
brakeposition=0;
xdeltaccp=xpos-turnstartlength;
ydeltaccp=ypos-corner1radius;
lateraloffsetfromtarget=corner1radius-(sqrt((xdeltaccp^2)+(ydeltaccp^2)));
wheeloffsetyaw=((-2*(pi/180))*ypos)-(driftangle)-(csag*driftrate);
if wheeloffsetyaw>maxsteerrad
wheeloffsetyaw=maxsteerrad;
end
if wheeloffsetyaw<(-maxsteerrad)
wheeloffsetyaw=-maxsteerrad;
end
if xpos>(1500);
sectorchange=1;
sector=sector+1;
end
endsimulation=0;
end
if sector==8
sectorchange=0;
endsimulation=0;
throttleposition=0;
brakeposition=1;
lateraloffsetfromtarget=ypos;
wheeloffsetyaw=((-2*(pi/180))*ypos)-(driftangle)-(csag*driftrate);
if wheeloffsetyaw>maxsteerrad
wheeloffsetyaw=maxsteerrad;
end
if wheeloffsetyaw<(-maxsteerrad)
wheeloffsetyaw=-maxsteerrad;
end
if xvel<1
endsimulation=1;
end
end
65
1.8 - Individual Wheel absolute velocity function function[v1x,v1y,v2x,v2y,v3x,v3y,v4x,v4y]=wheellinspeeds(vx,vy,vyaw,cgx,cgy,wheelba
se,track,vyawrate)
%This function finds the x & y components of velocity of each of the four
%wheels (numbered according to the scheme used previously). It does this by
%looking at the wheels as individual points on individual circles centred
%on the centre of gravity.
cgxf=wheelbase-cgx;
cgyr=track-cgy;
l1=sqrt((cgy^2)+(cgxf^2));
l2=sqrt((cgyr^2)+(cgxf^2));
l3=sqrt((cgy^2)+(cgx^2));
l4=sqrt((cgyr^2)+(cgx^2));
%Where l1-l4 are the lengths from the centre of gravity to the centre of
%the wheel contact patch in the x-y plane.
theta1=atand(cgy/cgxf);
theta2=atand(cgyr/cgxf);
theta3=atand(cgy/cgx);
theta4=atand(cgyr/cgx);
%These being the angles the lines out to the individual wheels make with
%the chassis as described in the logbook pg 66.
%Now I can get the vehicle-centric x & y components for each wheel.
%Remember to make sure that the imput yaw rate vyawrate and the
v1xveh=(cosd(theta1))*((vyawrate)*l1);
v1yveh=(sind(theta1))*((vyawrate)*l1);
v2xveh=(cosd(theta2))*((vyawrate)*l2);
v2yveh=(-sind(theta2))*((vyawrate)*l2);
v3xveh=(-cosd(theta3))*((vyawrate)*l3);
v3yveh=(sind(theta3))*((vyawrate)*l3);
v4xveh=(-cosd(theta4))*((vyawrate)*l4);
v4yveh=(sind(theta4))*((vyawrate)*l4);
%So we can take these vehicle-centred x & y component velocities and
%transform them to an earth-fixed axis as such. Note that here the
%vehicle's yaw position is expressed in radians.
v1x=(v1xveh*(cos(vyaw)))+(v1yveh*(sin(vyaw)));
v1y=(-v1xveh*(sin(vyaw)))+(v1yveh*(cos(vyaw)));
v2x=(v2xveh*(cos(vyaw)))+(v2yveh*(sin(vyaw)));
v2y=(-v2xveh*(sin(vyaw)))+(v2yveh*(cos(vyaw)));
v3x=(v3xveh*(cos(vyaw)))+(v3yveh*(sin(vyaw)));
v3y=(-v3xveh*(sin(vyaw)))+(v3yveh*(cos(vyaw)));
v4x=(v4xveh*(cos(vyaw)))+(v4yveh*(sin(vyaw)));
v4y=(-v4yveh*(sin(vyaw)))+(v4yveh*(cos(vyaw)));
%Since we want these velocities in terms of an earth-centric frame of
%reference we need to take account of the x & y components of velocity at
%the centre of gravity cg:
v1x=v1x+vx;
v2x=v2x+vx;
v3x=v3x+vx;
v4x=v4x+vx;
v1y=v1y+vy;
v2y=v2y+vy;
v3y=v3y+vy;
v4y=v4y+vy;
66
1.9 - Wheel combined torque and angular acceleration function function[w_angularacc,w_angularvel,combinedtorque]=wheelincrement(wheelangularveloc
ity,wheelinertia,wheelradius,braketorque,enginetorque,forceparallel,stepsize);
%So first this function needs to take the combined torque.
wheelfriction=0.4; %Low-friction bearing.
forceparalleltorque=forceparallel*wheelradius;
combinedtorque=enginetorque-(forceparalleltorque+braketorque+wheelfriction); %This
condition is only valid in the event that the wheels are rotating forwards. However
if the sim's trying to go backwards there are bigger problems.
w_angularacc=combinedtorque/wheelinertia;
w_angularvel=wheelangularvelocity+(w_angularacc*stepsize);
%Can insert a condition here to stop wheels from turning backwards, since
%this won't be required under any conditions in which the sim will be
%required to run.
if w_angularvel<0.001
w_angularvel=0.001;
end
%This way, the brakes can't cause the wheels to rotate backwards, this
%being a major problem during one part of testing.
end
67
1.10 - Vehicle Moment Calculator function[moment_roll,moment_pitch,moment_yaw]=momentcalc3(xforce1abs,yforce1abs,zfo
rce1,xforce2abs,yforce2abs,zforce2,xforce3abs,yforce3abs,zforce3,xforce4abs,yforce4
abs,zforce4,cgx,cgy,cgz,wheelbase,track,frontdownforce,reardownforce,yawangle)
%The Following numbering should be used:
%Left Front = 1
%Right Front = 2
%Left Rear = 3
%Right Rear = 4
%V0.3 revision - previously this code did not properly take account of
%vehicle orientation. This code will now take the absolute x & y component
%forces on each corner, transform them into a body-fixed axis system and
%then calculate the moment based on these.
%The rolling/pitching moment changes are not considered significant enough to
%warrant doing these transforms on the roll and pitch angles.
%yaw angle is imported into this function in radians.
xforce1=(xforce1abs*cos(yawangle))+(yforce1abs*sin(yawangle));
yforce1=(xforce1abs*sin(yawangle))+(yforce1abs*cos(yawangle));
xforce2=(xforce2abs*cos(yawangle))+(yforce2abs*sin(yawangle));
yforce2=(xforce2abs*sin(yawangle))+(yforce2abs*cos(yawangle));
xforce3=(xforce3abs*cos(yawangle))+(yforce3abs*sin(yawangle));
yforce3=(xforce3abs*sin(yawangle))+(yforce3abs*cos(yawangle));
xforce4=(xforce4abs*cos(yawangle))+(yforce4abs*sin(yawangle));
yforce4=(xforce4abs*sin(yawangle))+(yforce4abs*cos(yawangle));
cgyr=track-cgy;
cgxf=wheelbase-cgx;
%Roll
moment_roll1=(yforce1*cgz)-(zforce1*cgy);
moment_roll2=(yforce2*cgz)+(zforce2*cgyr);
moment_roll3=(yforce3*cgz)-(zforce3*cgy);
moment_roll4=(yforce4*cgz)+(zforce4*cgyr);
%Pitch:
moment_pitch1=(xforce1*cgz)+(zforce1*cgxf);
moment_pitch2=(xforce2*cgz)+(zforce2*cgxf);
moment_pitch3=(xforce3*cgz)-(zforce3*cgx);
moment_pitch4=(xforce4*cgz)-(zforce4*cgx);
moment_pitchfd=-frontdownforce*cgxf;
moment_pitchrd=reardownforce*cgx;
%Yaw:
moment_yaw1=(xforce1*cgy)+(yforce1*cgxf);
moment_yaw2=-(xforce2*cgyr)+(yforce2*cgxf);
moment_yaw3=(xforce3*cgy)-(yforce3*cgx);
moment_yaw4=-(xforce4*cgyr)-(yforce4*cgx);
%wheelbase taken in metres being the distance from the centre of the rear
%wheels to the centre of the front wheels.
moment_roll=moment_roll1+moment_roll2+moment_roll3+moment_roll4;
moment_pitch=moment_pitch1+moment_pitch2+moment_pitch3+moment_pitch4+moment_pitchfd
+moment_pitchrd;
moment_yaw=moment_yaw1+moment_yaw2+moment_yaw3+moment_yaw4;
end
68
1.11 - Vehicle corner displacement due to roll & pitch function function[heightdelta1,heightdelta2,heightdelta3,heightdelta4]=zorientdispla
cements(rollangle,pitchangle,cgx,cgy,wheelbase,track)
%First roll moment %1 & 3 go down with positive roll and 2 & 4 go up. heightdelta1=-sin(rollangle)*(cgy); heightdelta3=-sin(rollangle)*(cgy); heightdelta2=sin(rollangle)*(track-cgy); heightdelta4=sin(rollangle)*(track-cgy);
%Then pitching moment - 1 & 2 go up and 3 & 4 go down. heightdelta1=heightdelta1+(sin(pitchangle)*(wheelbase-cgx)); heightdelta2=heightdelta2+(sin(pitchangle)*(wheelbase-cgx)); heightdelta3=heightdelta3-(sin(pitchangle)*(cgx)); heightdelta4=heightdelta4-(sin(pitchangle)*(cgx)); end
1.12 - Quarter-car model adapted for individual corners of full-car model function[Fground,Fwheel,Fcorner]=quarterfullcarmodel(ktyre,ksusp,ctyre,csus
p,lntyre,lnsusp,ltyre,lsusp,vground,vwheel,vcorner,unsprungmass,vertmomentl
oad) %The basic function of this code is outlined pages 33-34 of the logbook. Fground=((ktyre*(lntyre-ltyre))+(ctyre*(vwheel-vground))); Fwheel=((ktyre*(lntyre-ltyre))+(ctyre*(vground-vwheel))+(ksusp*(lsusp-
lnsusp))+(csusp*(vcorner-vwheel)))-(unsprungmass*9.80665); Fcorner=((ksusp*(lnsusp-lsusp))+(csusp*(vwheel-vcorner))); end