108 lines
2.2 KiB
Odin
108 lines
2.2 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,
|
|
-2.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)
|
|
}
|
|
|
|
slice_to_pacejka94_long :: proc(values: []f32) -> (result: Pacejka94_Longitudinal_Params) {
|
|
assert(len(values) == len(Pacejka94_Longitudinal_Params))
|
|
|
|
copy(result[:], values)
|
|
return result
|
|
}
|
|
|
|
slice_to_pacejka94_lat :: proc(values: []f32) -> (result: Pacejka94_Lateral_Params) {
|
|
assert(len(values) == len(Pacejka94_Lateral_Params))
|
|
|
|
copy(result[:], values)
|
|
return result
|
|
}
|