I am currently implementing 2d car physics for my game and I am facing a problem that somehow I cannot overcome on my own.
I am using this paper/tutorial as a reference:
http://regedit.i365....or%20Games.html
The problem is the following.
I calculate RPM from wheel angular velocity. That value I plug-in to an equation that lookups engine torque from a curve. Generally the higher RPM the grater value of torque up to some point (lets say 4500 rpm).
Then as the paper says I use those multiplayers that converts the engine(crankshaft?) torque to rear axle torque using gear ratios and differential.
Because of that when I use 1st gear I get highest rear axle torque therfore highest top speed. When I gear up I loose speed. This should not happen and I tried a lot of different things modifications etc.
The way I update physics looks like this:
void DoPhysics(float dt)
{
UpdateDrag(); UpdateFriction(); // drag/friction
// Calculate drive wheel Angular Velocity.
AngularVelocity = GetWheelAngularVelocity(dt);
//AngularVelocity = Speed / WheelRadius; // <- suggested easy solution (sort of a hack) but it also did not gave good result.
// Plug-in to calculate engine RPM.
RPM = CalculateRPM(AngularVelocity);
// Use RPM to get the engine Torque.
EngineTorque = Throttle * m_engine.GetTorque(RPM);
Direction = Vec2(-sinf(Rotation), cosf(Rotation));
float CrankshaftMultiplyer = GearRatios[CurrentGear] * DifferentialRatio;
DriveTorque = EngineTorque * CrankshaftMultiplyer * TransmissionEfficiency;
DriveForce = Direction * (DriveTorque / WheelRadius);
// Update Traction force taking Dynamic Weight Transfer into account.
UpdateAxlesWeight();
if(RearAxleWeight*TyreFrictionCoefficient < DriveForce.y)
TractionForce = Direction*RearAxleWeight*TyreFrictionCoefficient;
else
TractionForce = DriveForce;
float sign = fast_sign(TractionForce.y);
LongtitudinalForce = sign * D3DXVec2Length(&TractionForce) + (-Direction.y)*(DragForce + WheelFrictionForce);
Acceleration = LongtitudinalForce / Mass;
// Hack ?
if(Acceleration <= 1.0f*D3DX_16F_EPSILON && Acceleration >= 1.0f*D3DX_16F_EPSILON)
Acceleration = 0.0f;
//float WheelRPM = RPM / CrankshaftMultiplyer;
//float RevolutionDisplacement = 2.0f * D3DX_PI * WheelRadius;
//float WheelRotationsPerSecond = WheelRPM / 60.0f;
//float WheelMetersPerSecond = WheelRotationsPerSecond * RevolutionDisplacement;
//if(Speed > WheelMetersPerSecond)
// Speed = WheelMetersPerSecond;
Speed += Acceleration * dt;
Position += Direction* Speed * dt * 10.0f;
}
And this is how I calculate WheelAngularVelocity and RPM
float GetWheelAngularVelocity(float dt)
{
float TractionTorque = TractionForce.y * WheelRadius;
float TotalTorque = TractionTorque + EngineTorque*GearRatios[CurrentGear] * DifferentialRatio * TransmissionEfficiency;
AngularAcceleration = TotalTorque / AxleInertia;
AngularVelocity += AngularAcceleration * dt;
if(Speed/WheelRadius > AngularVelocity)
AngularVelocity = Speed / WheelRadius;
return AngularVelocity;
}
float CalculateRPM(float wheelAngularVelocity)
{ // Calculates the RPM from wheel angular velocity.
float rpm = wheelAngularVelocity * GearRatios[CurrentGear] * DifferentialRatio; /* * 60.0f / (2.0f*D3DX_PI); */
if(rpm < 1000)
rpm = 1000;
return rpm; }
Did anyone use the mentioned tutorial for reference and managed to implement proper RPM/torque/gearing behaviour ?
Thanks in advance for all replies.
Edit:
I have tried playing around with those values and I noticed one thing. If I hardcode RPM to be equal 4500 in the code and use those commented out lines just before integration of speed I get the result similar to the one from the paper.
I mean:
float WheelRPM = RPM / CrankshaftMultiplyer;
float RevolutionDisplacement = 2.0f * D3DX_PI * WheelRadius;
float WheelRotationsPerSecond = WheelRPM / 60.0f;
float WheelMetersPerSecond = WheelRotationsPerSecond * RevolutionDisplacement;
Speed = WheelMetersPerSecond;
[font="Arial"]Then the car has proper speed.[/font][font="Arial"]4500 RPM @ 1 gear gives approx 62km/h[/font][font="Arial"]4500 RPM @ 2 gear makes it faster and faster till 5th gear which gives 220km/h. This is realistic behaviour since at 4500RPM the engine gives the highest value of torque.[/font][font="Arial"]But I notice that acceleration is negative that is why when I do calculation of speed using this acceleration it is capped and never reaches those proper values.[/font]