Skip to content

Commit 4842e83

Browse files
committed
car: fixed handling bugs
1 parent 9fb01f1 commit 4842e83

1 file changed

Lines changed: 21 additions & 6 deletions

File tree

source/car/CarSimulation.cpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2307,12 +2307,15 @@ namespace car
23072307

23082308
float Simulation::read_driveline_gearbox_speed() const
23092309
{
2310-
if (!has_physical_driveline())
2310+
if (!has_physical_driveline() || !body)
23112311
{
23122312
return gearbox_input_angular_velocity;
23132313
}
23142314
PxVec3 axis = multibody.driveline.gearbox_output->getGlobalPose().q.rotate(PxVec3(1.0f, 0.0f, 0.0f));
2315-
return multibody.driveline.gearbox_output->getAngularVelocity().dot(axis);
2315+
// spin is relative to the chassis, the writers set chassis angular velocity plus axis spin
2316+
// so reading the absolute value back fed the chassis roll rate into the gearbox every substep
2317+
PxVec3 spin = multibody.driveline.gearbox_output->getAngularVelocity() - body->getAngularVelocity();
2318+
return spin.dot(axis);
23162319
}
23172320

23182321

@@ -3176,7 +3179,7 @@ namespace car
31763179

31773180
if (shift_cooldown > 0.0f)
31783181
{
3179-
shift_cooldown -= dt;
3182+
shift_cooldown = PxMax(shift_cooldown - dt, 0.0f);
31803183
}
31813184

31823185
if (is_shifting)
@@ -3438,6 +3441,7 @@ namespace car
34383441
// pedal closed means coast, blip may still raise revs for a matched downshift
34393442
bool coasting = drive_input <= spec.input_deadzone;
34403443
float idle_angular_velocity = spec.engine_idle_rpm * PxPi * 2.0f / 60.0f;
3444+
float max_angular_velocity = PxMax(spec.engine_max_rpm * PxPi * 2.0f / 60.0f, idle_angular_velocity);
34413445
float clutch_capacity = PxMax(spec.clutch_max_torque, 10.0f);
34423446
float clutch_damping = clutch_capacity / 12.0f;
34433447
float electric_target = is_in_forward_gear() ? get_electric_motor_torque(engine_rpm, input.throttle) * assisted_actuators.engine_torque_scale : 0.0f;
@@ -3454,7 +3458,12 @@ namespace car
34543458
axle_drive_torque = 0.0f;
34553459
engine_brake_torque = 0.0f;
34563460

3457-
int substep_count = PxClamp(static_cast<int>(ceilf(dt / 0.0025f)), 1, 16);
3461+
// the clutch damper couples two small inertias, so the substep has to resolve it or the slip
3462+
// rings, damping times substep times the coupling compliance must stay at or under one
3463+
float coupling_compliance = 1.0f / engine_inertia + 1.0f / driveline_inertia;
3464+
float clutch_substep = 1.0f / PxMax(clutch_damping * coupling_compliance, 1e-6f);
3465+
float target_substep = PxMin(0.0025f, clutch_substep);
3466+
int substep_count = PxClamp(static_cast<int>(ceilf(dt / target_substep)), 1, 32);
34583467
float substep = dt / static_cast<float>(substep_count);
34593468
float accumulated_axle_torque = 0.0f;
34603469
float accumulated_powertrain_reaction = 0.0f;
@@ -3474,6 +3483,10 @@ namespace car
34743483
accumulated_engine_torque += combustion_torque + idle_torque;
34753484
float clutch_slip = engine_angular_velocity - gearbox_input_angular_velocity;
34763485
float clutch_torque = PxClamp(clutch_slip * clutch_damping, -clutch_capacity * clutch, clutch_capacity * clutch);
3486+
// a damper cannot pull the two speeds past each other in one substep, without this cap the
3487+
// explicit integration flipped the slip sign every substep and dragged the engine to a stall
3488+
float non_overshoot_torque = fabsf(clutch_slip) / PxMax(substep * coupling_compliance, 1e-6f);
3489+
clutch_torque = PxClamp(clutch_torque, -non_overshoot_torque, non_overshoot_torque);
34773490
float shaft_torque = 0.0f;
34783491
float shaft_speed_difference = 0.0f;
34793492
// open driveline during shifts or with clutch out, shaft must not keep shoving the axle
@@ -3557,7 +3570,9 @@ namespace car
35573570
float friction_torque = spec.engine_friction * engine_angular_velocity + pumping_torque;
35583571
float engine_acceleration = (combustion_torque + idle_torque - friction_torque - clutch_torque) / engine_inertia;
35593572
float previous_engine_angular_velocity = engine_angular_velocity;
3560-
engine_angular_velocity = PxClamp(engine_angular_velocity + engine_acceleration * substep, 0.0f, spec.engine_max_rpm * PxPi * 4.0f / 60.0f);
3573+
// idle is the floor, the torque curve is only defined at or above it and there is no
3574+
// stall or restart model, so a dragged down engine could never come back
3575+
engine_angular_velocity = PxClamp(engine_angular_velocity + engine_acceleration * substep, idle_angular_velocity, max_angular_velocity);
35613576
engine_acceleration = (engine_angular_velocity - previous_engine_angular_velocity) / substep;
35623577

35633578
float efficiency = PxClamp(spec.drivetrain_efficiency, 0.1f, 1.0f);
@@ -3708,7 +3723,7 @@ namespace car
37083723

37093724
if (downshift_blip_timer > 0.0f)
37103725
{
3711-
downshift_blip_timer -= dt;
3726+
downshift_blip_timer = PxMax(downshift_blip_timer - dt, 0.0f);
37123727
}
37133728

37143729
if (is_shifting)

0 commit comments

Comments
 (0)