# Car physics: incorporating lateral forces for high-speed steering

I'm making a car simulation in Javascript and I am using this website to help me with the physics: http://www.asawicki.info/Mirror/Car%20Physics%20for%20Games/Car%20Physics%20for%20Games.html

The current progress of the simulation can be seen on my website: https://cloudynet.tk/projects/car-sim/code.html

The problem I have is with the car steering physics. I have managed to get the low-speed steering to work correctly but the high-speed steering (where lateral forces are introduced) is very hard to get right. I understand how slip angles influence the lateral force but in my simulation, it is not working very well. I'm wondering if the implementation of the lateral force is correct or is there something wrong with the code? Also, I don't quite understand if the longitudinal force and the lateral force affects a single velocity vector or is separated into two "directional" vectors.

Here's my current physics function (whole code can be seen on the website):

applyPhysics() {
// Get car direction vector

let direction = new Vector(1, 0);
direction = Vector.rotate(direction, this.carAngle);

// LONGITUDINAL FORCES

// Traction forces
let tractionForce = direction.copy(); // Traction force (engine power)
if (this.engineForce) {
tractionForce.mult(this.engineForce);
}
else if (this.brakingForce) {
tractionForce.mult(-this.brakingForce);
}

// Frictional forces

let dragForce = this.velocity.copy(); // Air resistance force
dragForce.mult(this.velocity.getMag())
dragForce.mult(-this.drag);

let rollingResistanceForce = this.velocity.copy(); // Rolling resistance force (friction with ground)
rollingResistanceForce.mult(-this.rrDrag);

let netLongitudinalForce = tractionForce.copy(); // Total longitudinal force

// Calculate acceleration
this.acceleration = netLongitudinalForce.copy();
this.acceleration.div(this.mass);
if (this.acceleration.getMag() < 0.001)
this.acceleration = new Vector();

// Calculate velocity
let accelerationDelta = this.acceleration.copy();
accelerationDelta.mult(dt);

this.velDir = this.velocity.getDir();
this.sideslipAngle = this.carAngle - this.velDir; // Calculate side slip angle

if (this.speed > 20) { // High speed-turning
// LATERAL FORCES

let peakSlipAngle = 5;

// Calculate slip angle for back wheel
var c = this.wheels.baseline/2;
var omegaC = this.angularVelocity*c;
var longV = Math.cos(this.carAngle) * this.velocity.getMag();
var latV = Math.sin(this.carAngle) * this.velocity.getMag();
this.wheels.back.slipAngle = Math.atan(((latV - omegaC)/Math.abs(longV)) || 0);
var backSlipDeg = deg(this.wheels.back.slipAngle)

this.wheels.back.lateralForce = 5000*Math.sign(this.wheels.back.slipAngle);
if (backSlipDeg < peakSlipAngle && backSlipDeg > -peakSlipAngle) {
this.wheels.back.lateralForce = 5000*backSlipDeg/peakSlipAngle;
} else {
this.wheels.back.lateralForce = 5000*(1-((Math.abs(backSlipDeg)-peakSlipAngle)/500))*Math.sign(this.wheels.back.slipAngle);
}

// Calculate slip angle for front wheel
var b = this.wheels.baseline/2;
var omegaB = this.angularVelocity*b;
var longV = Math.cos(this.wheels.front.slipAngle) * this.velocity.getMag();
var latV = Math.sin(this.wheels.front.slipAngle) * this.velocity.getMag();
this.wheels.front.slipAngle = Math.atan((((latV - omegaB)/Math.abs(longV)) || 0)-this.steeringAngle*Math.sign(longV));
var frontSlipDeg = deg(this.wheels.front.slipAngle);

this.wheels.front.lateralForce = 5000*Math.sign(this.wheels.front.slipAngle);
if (frontSlipDeg < peakSlipAngle && frontSlipDeg > -peakSlipAngle) {
this.wheels.front.lateralForce = 5000*frontSlipDeg/peakSlipAngle;
} else {
this.wheels.front.lateralForce = 5000*(1-((Math.abs(frontSlipDeg)-peakSlipAngle)/500))*Math.sign(this.wheels.front.slipAngle);
}

// Calculate cornering force
this.corneringForce = this.wheels.back.lateralForce + Math.cos(this.steeringAngle) * this.wheels.front.lateralForce;

// Calculate centripetal force
this.centripetalForce = this.mass * (this.velocity.getMag() ** 2) / this.wheels.baseline/Math.sin(this.steeringAngle);

var lateralDirection = new Vector(0, -1);
lateralDirection = Vector.rotate(lateralDirection, this.carAngle);

let lateralForce = lateralDirection.copy();
lateralForce.mult(this.corneringForce);

this.latAcceleration = lateralForce.copy();
this.latAcceleration.div(this.mass);
if (this.latAcceleration.getMag() < 0.001)
this.latAcceleration = new Vector();

let latAccelerationDelta = this.latAcceleration.copy();
latAccelerationDelta.mult(dt);

// Calculate position
let latVelocityDelta = this.latVelocity.copy();
latVelocityDelta.mult(dt);