Energy based changes
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
public class Engine
|
||||
{
|
||||
// Energy state
|
||||
public float FlywheelEnergy { get; set; } // Joules
|
||||
public float FlywheelEnergy { get; set; }
|
||||
|
||||
// Values
|
||||
public float RPM => GetRPM();
|
||||
@@ -11,40 +11,35 @@
|
||||
public float CurrentPower { get; private set; }
|
||||
|
||||
// Physical properties
|
||||
public float MomentOfInertia { get; set; } = 0.25f; // kg·m²
|
||||
public float MomentOfInertia { get; set; } = 0.25f;
|
||||
public float IdleRPM { get; set; } = 800f;
|
||||
public float StallSpeed { get; set; } = 200f;
|
||||
public float Throttle { get; set; } = 0f;
|
||||
public bool IsRunning => RPM > StallSpeed;
|
||||
|
||||
// Torque characteristics
|
||||
// Torque curve
|
||||
public Dictionary<float, float> TorqueCurve { get; set; } = new()
|
||||
{
|
||||
// RPM - Torque Nm
|
||||
{ 0f, 0f },
|
||||
{ 800f, 150f }, // Idle
|
||||
{ 2000f, 200f }, // Peak torque
|
||||
{ 800f, 150f },
|
||||
{ 2000f, 250 },
|
||||
{ 4500f, 250f },
|
||||
{ 7200f, 250f },
|
||||
{ 9200f, 250f },
|
||||
{ 10000f, 200f },
|
||||
{ 11000f, 0f }
|
||||
{ 6800f, 200f },
|
||||
{ 7200f, 150 },
|
||||
{ 7500f, 0f },
|
||||
};
|
||||
|
||||
public Engine()
|
||||
{
|
||||
// Start with idle energy
|
||||
FlywheelEnergy = GetEnergyFromRPM(IdleRPM);
|
||||
}
|
||||
|
||||
// Calculations
|
||||
|
||||
public float CalculateFrictionEnergy(float deltaTime)
|
||||
public float CalculateFrictionLoss(float deltaTime)
|
||||
{
|
||||
// Real friction torque data for 2.0L engine (Nm)
|
||||
float frictionTorque;
|
||||
|
||||
if (RPM < 500) frictionTorque = 15f; // Static/breakaway
|
||||
// Realistic friction based on RPM
|
||||
if (RPM < 500) frictionTorque = 15f;
|
||||
else if (RPM < 1000) frictionTorque = 14f;
|
||||
else if (RPM < 2000) frictionTorque = 16f;
|
||||
else if (RPM < 3000) frictionTorque = 18f;
|
||||
@@ -58,29 +53,28 @@
|
||||
return frictionPower * deltaTime;
|
||||
}
|
||||
|
||||
private float CalculateCombustionEnergy(float deltaTime)
|
||||
public float CalculateCombustionPower(float deltaTime)
|
||||
{
|
||||
float torque = GetTorqueOutput() * GetActualThrottle();
|
||||
return torque * AngularVelocity * deltaTime;
|
||||
}
|
||||
|
||||
private float CalculateLoadEnergy(float deltaTime, float loadTorque)
|
||||
{
|
||||
return loadTorque * AngularVelocity * deltaTime;
|
||||
}
|
||||
|
||||
// Get
|
||||
|
||||
public float GetActualThrottle()
|
||||
{
|
||||
float idleThrottle = Math.Max((IdleRPM - RPM) / 10, 0);
|
||||
return Math.Clamp(Throttle + idleThrottle, 0, 1);
|
||||
// Idle control: maintain idle speed when throttle is low
|
||||
if (RPM < IdleRPM && Throttle < 0.1f)
|
||||
{
|
||||
float idleThrottle = (IdleRPM - RPM) / 200f;
|
||||
return Math.Clamp(idleThrottle, 0.1f, 0.3f);
|
||||
}
|
||||
|
||||
return Throttle;
|
||||
}
|
||||
|
||||
public float GetOmega()
|
||||
{
|
||||
if (FlywheelEnergy <= 0) return 0;
|
||||
return MathF.Sqrt(2f * FlywheelEnergy / MomentOfInertia);
|
||||
return MathF.Sqrt(2f * FlywheelEnergy / MomentOfInertia);
|
||||
}
|
||||
|
||||
public float GetRPM()
|
||||
@@ -88,15 +82,12 @@
|
||||
return GetOmega() * PhysicsUtil.RAD_PER_SEC_TO_RPM;
|
||||
}
|
||||
|
||||
// Set
|
||||
|
||||
public float GetEnergyFromRPM(float rpm)
|
||||
{
|
||||
float omega = rpm * PhysicsUtil.RPM_TO_RAD_PER_SEC;
|
||||
return 0.5f * MomentOfInertia * omega * omega;
|
||||
}
|
||||
|
||||
// torque curve
|
||||
public float GetTorqueOutput()
|
||||
{
|
||||
if (RPM <= 0) return 0;
|
||||
@@ -118,25 +109,28 @@
|
||||
return 0f;
|
||||
}
|
||||
|
||||
public void ApplyTorque(float torque, float deltaTime)
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
if (torque == 0) return;
|
||||
// Combustion adds energy (if throttle > 0)
|
||||
float combustionEnergy = CalculateCombustionPower(deltaTime);
|
||||
|
||||
float work = torque * AngularVelocity * deltaTime;
|
||||
// Friction always removes energy
|
||||
float frictionLoss = CalculateFrictionLoss(deltaTime);
|
||||
|
||||
FlywheelEnergy += work;
|
||||
FlywheelEnergy = Math.Max(FlywheelEnergy, 0);
|
||||
}
|
||||
|
||||
public void Update(float deltaTime, float loadTorque)
|
||||
{
|
||||
float combustionEnergy = CalculateCombustionEnergy(deltaTime);
|
||||
float frictionEnergy = CalculateFrictionEnergy(deltaTime);
|
||||
float loadEnergy = CalculateLoadEnergy(deltaTime, loadTorque);
|
||||
|
||||
float netEnergy = combustionEnergy - frictionEnergy - loadEnergy;
|
||||
// Net energy change from combustion and friction ONLY
|
||||
// Note: Drivetrain energy transfer happens separately in Drivetrain.Update()
|
||||
float netEnergy = combustionEnergy - frictionLoss;
|
||||
CurrentPower = netEnergy / deltaTime;
|
||||
|
||||
FlywheelEnergy += netEnergy;
|
||||
|
||||
// Stall protection - keep engine running if it has throttle
|
||||
float stallEnergy = GetEnergyFromRPM(StallSpeed);
|
||||
if (FlywheelEnergy < stallEnergy && Throttle > 0.1f)
|
||||
{
|
||||
FlywheelEnergy = stallEnergy * 1.2f;
|
||||
}
|
||||
|
||||
FlywheelEnergy = Math.Max(FlywheelEnergy, 0);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user