Improve engine friction, add a rev limiter
This commit is contained in:
parent
08b6748d76
commit
1ea89fb2c9
@ -1,6 +1,6 @@
|
|||||||
b
|
b
|
||||||
1.6
|
1.6
|
||||||
-80
|
-120
|
||||||
1100
|
1100
|
||||||
0
|
0
|
||||||
300
|
300
|
||||||
|
|
@ -434,13 +434,15 @@ update_runtime_world :: proc(runtime_world: ^Runtime_World, dt: f32) {
|
|||||||
"assets/ae86_rpm_torque.csv",
|
"assets/ae86_rpm_torque.csv",
|
||||||
),
|
),
|
||||||
lowest_rpm = 1100,
|
lowest_rpm = 1100,
|
||||||
inertia = 0.264,
|
rev_limit_rpm = 7800,
|
||||||
internal_friction = 0.00,
|
rev_limit_interval = 0.025,
|
||||||
|
inertia = 0.264 * 0.5,
|
||||||
|
internal_friction = 0.01,
|
||||||
gear_ratios = []f32{3.48, 3.587, 2.022, 1.384, 1, 0.861},
|
gear_ratios = []f32{3.48, 3.587, 2.022, 1.384, 1, 0.861},
|
||||||
axle = physics.Drive_Axle_Config {
|
axle = physics.Drive_Axle_Config {
|
||||||
wheels = {wheel_rl, wheel_rr},
|
wheels = {wheel_rl, wheel_rr},
|
||||||
wheel_count = 2,
|
wheel_count = 2,
|
||||||
diff_type = .Open,
|
diff_type = .Fixed,
|
||||||
final_drive_ratio = 4.1,
|
final_drive_ratio = 4.1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -151,7 +151,7 @@ draw_debug_ui :: proc(ctx: ^ui.Context, scene: ^Scene, config: Solver_Config) {
|
|||||||
|
|
||||||
sim_state := get_sim_state(scene)
|
sim_state := get_sim_state(scene)
|
||||||
|
|
||||||
active_wheels := []int{2, 3}
|
active_wheels := []int{}
|
||||||
|
|
||||||
w, h: i32 = 200, 200
|
w, h: i32 = 200, 200
|
||||||
|
|
||||||
|
@ -217,39 +217,46 @@ Gear_Ratios_Handle :: distinct spanpool.Handle
|
|||||||
|
|
||||||
// This actually handles everything, engine, transmission, differential, etc. It's easier to keep it in one place
|
// This actually handles everything, engine, transmission, differential, etc. It's easier to keep it in one place
|
||||||
Engine :: struct {
|
Engine :: struct {
|
||||||
alive: bool,
|
alive: bool,
|
||||||
// Engine Params
|
// Engine Params
|
||||||
rpm_torque_curve: Engine_Curve_Handle,
|
rpm_torque_curve: Engine_Curve_Handle,
|
||||||
lowest_rpm: f32,
|
lowest_rpm: f32,
|
||||||
inertia: f32,
|
// Rpm when rev limiter activates
|
||||||
internal_friction: f32,
|
rev_limit_rpm: f32,
|
||||||
|
// Time in seconds for how long rev limiter cuts the throttle
|
||||||
|
rev_limit_interval: f32,
|
||||||
|
inertia: f32,
|
||||||
|
internal_friction: f32,
|
||||||
|
|
||||||
// Transmission Params
|
// Transmission Params
|
||||||
// 0 - reverse, 1 - first, etc.
|
// 0 - reverse, 1 - first, etc.
|
||||||
gear_ratios: Gear_Ratios_Handle,
|
gear_ratios: Gear_Ratios_Handle,
|
||||||
axle: Drive_Axle,
|
axle: Drive_Axle,
|
||||||
|
|
||||||
// Engine State
|
// Engine State
|
||||||
// Angular velocity, omega
|
// Angular velocity, omega
|
||||||
q: f32,
|
q: f32,
|
||||||
w: f32,
|
w: f32,
|
||||||
|
|
||||||
|
// Reset to -rev_limit_interval when rpm exceeds rev_limit_rpm, has to be >= 0 for throttle to work
|
||||||
|
rev_limit_time: f32,
|
||||||
|
|
||||||
// Impulse applied when engine is stalling (rpm < lowest_rpm)
|
// Impulse applied when engine is stalling (rpm < lowest_rpm)
|
||||||
unstall_impulse: f32,
|
unstall_impulse: f32,
|
||||||
// Friction that makes rpm go down when you're not accelerating
|
// Friction that makes rpm go down when you're not accelerating
|
||||||
friction_impulse: f32,
|
friction_impulse: f32,
|
||||||
// Impulse applied from releasing throttle
|
// Impulse applied from releasing throttle
|
||||||
throttle_impulse: f32,
|
throttle_impulse: f32,
|
||||||
|
|
||||||
// Transmission State
|
// Transmission State
|
||||||
// -1 - reeverse, 0 - neutral, 1 - first, etc.
|
// -1 - reeverse, 0 - neutral, 1 - first, etc.
|
||||||
gear: i32,
|
gear: i32,
|
||||||
|
|
||||||
// Controls
|
// Controls
|
||||||
throttle: f32,
|
throttle: f32,
|
||||||
|
|
||||||
// Free list
|
// Free list
|
||||||
next_plus_one: i32,
|
next_plus_one: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Index plus one, so handle 0 maps to invalid body
|
// Index plus one, so handle 0 maps to invalid body
|
||||||
@ -378,15 +385,17 @@ Drive_Axle_Config :: struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Engine_Config :: struct {
|
Engine_Config :: struct {
|
||||||
rpm_torque_curve: [][2]f32,
|
rpm_torque_curve: [][2]f32,
|
||||||
lowest_rpm: f32,
|
lowest_rpm: f32,
|
||||||
inertia: f32,
|
rev_limit_rpm: f32,
|
||||||
internal_friction: f32,
|
rev_limit_interval: f32,
|
||||||
|
inertia: f32,
|
||||||
|
internal_friction: f32,
|
||||||
|
|
||||||
// Transmission Params
|
// Transmission Params
|
||||||
// 0 - reverse, 1 - first, etc.
|
// 0 - reverse, 1 - first, etc.
|
||||||
gear_ratios: []f32,
|
gear_ratios: []f32,
|
||||||
axle: Drive_Axle_Config,
|
axle: Drive_Axle_Config,
|
||||||
}
|
}
|
||||||
|
|
||||||
calculate_body_params_from_config :: proc(
|
calculate_body_params_from_config :: proc(
|
||||||
@ -500,6 +509,8 @@ update_engine_from_config :: proc(
|
|||||||
engine.gear_ratios = add_gear_ratios(sim_state, config.gear_ratios)
|
engine.gear_ratios = add_gear_ratios(sim_state, config.gear_ratios)
|
||||||
|
|
||||||
engine.lowest_rpm = config.lowest_rpm
|
engine.lowest_rpm = config.lowest_rpm
|
||||||
|
engine.rev_limit_rpm = config.rev_limit_rpm
|
||||||
|
engine.rev_limit_interval = config.rev_limit_interval
|
||||||
engine.inertia = config.inertia
|
engine.inertia = config.inertia
|
||||||
engine.internal_friction = config.internal_friction
|
engine.internal_friction = config.internal_friction
|
||||||
|
|
||||||
|
@ -571,36 +571,48 @@ pgs_solve_engines :: proc(sim_state: ^Sim_State, config: Solver_Config, dt: f32,
|
|||||||
engine.w += applied_impulse / engine.inertia
|
engine.w += applied_impulse / engine.inertia
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpm := angular_velocity_to_rpm(engine.w)
|
||||||
|
throttle := engine.throttle
|
||||||
|
|
||||||
|
if engine.rev_limit_time < 0.0 {
|
||||||
|
engine.rev_limit_time += dt
|
||||||
|
throttle = 0
|
||||||
|
} else if (rpm >= engine.rev_limit_rpm) {
|
||||||
|
engine.rev_limit_time = -engine.rev_limit_interval
|
||||||
|
throttle = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Throttle
|
// Throttle
|
||||||
{
|
{
|
||||||
rpm := angular_velocity_to_rpm(engine.w)
|
|
||||||
|
|
||||||
torque: f32
|
{
|
||||||
|
torque: f32
|
||||||
|
|
||||||
idx, _ := slice.binary_search_by(
|
idx, _ := slice.binary_search_by(
|
||||||
rpm_torque_curve,
|
rpm_torque_curve,
|
||||||
rpm,
|
rpm,
|
||||||
proc(a: [2]f32, k: f32) -> slice.Ordering {
|
proc(a: [2]f32, k: f32) -> slice.Ordering {
|
||||||
return slice.cmp(a[0], k)
|
return slice.cmp(a[0], k)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
if idx > 0 && idx < len(rpm_torque_curve) - 1 {
|
if idx > 0 && idx < len(rpm_torque_curve) - 1 {
|
||||||
cur_point := rpm_torque_curve[idx]
|
cur_point := rpm_torque_curve[idx]
|
||||||
next_point := rpm_torque_curve[idx + 1]
|
next_point := rpm_torque_curve[idx + 1]
|
||||||
rpm_diff := next_point[0] - cur_point[0]
|
rpm_diff := next_point[0] - cur_point[0]
|
||||||
alpha := (rpm - cur_point[0]) / rpm_diff
|
alpha := (rpm - cur_point[0]) / rpm_diff
|
||||||
|
|
||||||
torque = math.lerp(cur_point[1], next_point[1], alpha)
|
torque = math.lerp(cur_point[1], next_point[1], alpha)
|
||||||
} else {
|
} else {
|
||||||
torque = rpm_torque_curve[math.clamp(idx, 0, len(rpm_torque_curve) - 1)][1]
|
torque = rpm_torque_curve[math.clamp(idx, 0, len(rpm_torque_curve) - 1)][1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// log.debugf("torque: %v Nm", torque)
|
||||||
|
torque *= throttle
|
||||||
|
|
||||||
|
engine.w += (torque / engine.inertia) * dt
|
||||||
}
|
}
|
||||||
|
|
||||||
// log.debugf("torque: %v Nm", torque)
|
|
||||||
torque *= engine.throttle
|
|
||||||
|
|
||||||
engine.w += (torque / engine.inertia) * dt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal Friction
|
// Internal Friction
|
||||||
@ -610,13 +622,14 @@ pgs_solve_engines :: proc(sim_state: ^Sim_State, config: Solver_Config, dt: f32,
|
|||||||
inv_w := engine.inertia
|
inv_w := engine.inertia
|
||||||
|
|
||||||
friction :=
|
friction :=
|
||||||
math.pow(
|
math.pow(max(engine.w - rpm_to_angular_velocity(engine.lowest_rpm), 0), 2) *
|
||||||
max(engine.w - rpm_to_angular_velocity(engine.lowest_rpm), 0) * 0.002,
|
0.0001 *
|
||||||
4,
|
|
||||||
) *
|
|
||||||
engine.internal_friction +
|
engine.internal_friction +
|
||||||
engine.internal_friction
|
engine.internal_friction
|
||||||
|
|
||||||
|
// Not physically based, but we assume when throttle is open there is no friction
|
||||||
|
friction *= (1.0 - throttle)
|
||||||
|
|
||||||
incremental_impulse := inv_w * delta_omega
|
incremental_impulse := inv_w * delta_omega
|
||||||
new_total_impulse := math.clamp(
|
new_total_impulse := math.clamp(
|
||||||
engine.friction_impulse + incremental_impulse,
|
engine.friction_impulse + incremental_impulse,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user