gutter_runner/game/physics/pacejka.odin

94 lines
1.8 KiB
Odin

// https://www.edy.es/dev/docs/pacejka-94-parameters-explained-a-comprehensive-guide/
package physics
import "core:math"
Pacejka94_Longitudinal_Params :: [14]f32
Pacejka94_Lateral_Params :: [18]f32
PACEJKA94_LONGITUDINAL_PEAK_X :: 6.24
PACEJKA94_LONGITUDINAL_PARAMS :: Pacejka94_Longitudinal_Params {
1.5,
0,
1100,
0,
300,
0,
0,
0,
-2,
0,
0,
0,
0,
0,
}
PACEJKA94_LATERAL_PEAK_X :: 6.26
PACEJKA94_LATERAL_PARAMS :: Pacejka94_Lateral_Params {
1.4,
0,
1100,
1100,
10,
0,
0,
-2,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
}
// X is slip ratio percentage [-100, 100] or slip angle in degrees, where positive angle is turning left
// Output is the friction coefficient
pacejka_94_longitudinal :: proc(
b: Pacejka94_Longitudinal_Params,
x: f32,
f_z: f32,
s_v: f32 = 0,
) -> f32 {
f_z_sq := f_z * f_z
C := b[0]
D := (b[1] * f_z + b[2]) * f_z
BCD := (b[3] * f_z_sq + b[4] * f_z) * math.exp(-b[5] * f_z)
B := BCD / (C * D)
H := b[9] * f_z + b[10]
E := (b[6] * f_z_sq + b[7] * f_z + b[8]) * (1.0 - b[13] * math.sign(x + H))
V := b[11] * f_z + b[12]
Bx1 := B * (x + H)
F := D * math.sin(C * math.atan(Bx1 - E * (Bx1 - math.atan(Bx1)))) + V
return F / (f_z * 1000)
}
pacejka_94_lateral :: proc(
a: Pacejka94_Lateral_Params,
slip_angle: f32,
f_z: f32,
camber_angle: f32,
) -> f32 {
camber_angle_sq := camber_angle * camber_angle
C := a[0]
D := f_z * (a[1] * f_z + a[2]) * (1.0 - a[15] * camber_angle_sq)
BCD := a[3] * math.sin(math.atan(f_z / a[4]) * 2.0) * (1.0 - a[5] * abs(camber_angle))
B := BCD / (C * D)
H := a[8] * f_z + a[9] + a[10] * camber_angle
E := (a[6] * f_z + a[7]) * (1.0 - (a[16] * camber_angle + a[17]) * math.sign(slip_angle + H))
V := a[11] * f_z + a[12] + (a[13] * f_z + a[14]) * camber_angle * f_z
Bx1 := B * (slip_angle + H)
F := D * math.sin(C * math.atan(Bx1 - E * (Bx1 - math.atan(Bx1)))) + V
return F / (f_z * 1000)
}