Energy based changes
This commit is contained in:
@@ -9,188 +9,139 @@
|
||||
private int currentGear = 1;
|
||||
public float[] GearRatios { get; set; } =
|
||||
{
|
||||
3.8f, // 1st - Lower for better launch
|
||||
3.8f, // 1st
|
||||
2.5f, // 2nd
|
||||
1.8f, // 3rd
|
||||
1.3f, // 4th
|
||||
1.0f, // 5th - Direct drive
|
||||
0.8f, // 6th - Overdrive
|
||||
0.65f // 7th - Double overdrive (optional)
|
||||
1.0f, // 5th
|
||||
0.8f, // 6th
|
||||
0.65f // 7th
|
||||
};
|
||||
public float FinalDriveRatio { get; set; } = 5.0f;
|
||||
public float FinalDriveRatio { get; set; } = 4.0f;
|
||||
public float Efficiency { get; set; } = 0.95f;
|
||||
public float ClutchEngagement { get; set; } = 0f; // 0 = disengaged, 1 = fully engaged
|
||||
|
||||
// Calculated
|
||||
public float GearRatio => GetCurrentGearRatio();
|
||||
public float TotalRatio => GearRatio * FinalDriveRatio;
|
||||
|
||||
// Clutch properties
|
||||
public float ClutchStiffness { get; set; } = 500f; // Nm/(rad/s) - how strongly clutch pulls speeds together
|
||||
public float MaxClutchTorque { get; set; } = 4500f; // Maximum torque clutch can transmit
|
||||
public float MaxClutchTorque { get; set; } = 450f;
|
||||
public float ClutchStiffness { get; set; } = 20f; // Softer spring
|
||||
|
||||
// State
|
||||
public float SpeedDifference { get; private set; } // rad/s
|
||||
public float ClutchTorque { get; private set; }
|
||||
public float TransmittedPower { get; private set; }
|
||||
|
||||
private float previousWheelOmega = 0f;
|
||||
public float ClutchSlipRatio { get; private set; }
|
||||
|
||||
public Drivetrain(Engine engine, WheelSystem wheelSystem)
|
||||
{
|
||||
Engine = engine;
|
||||
WheelSystem = wheelSystem;
|
||||
previousWheelOmega = wheelSystem.AngularVelocity;
|
||||
}
|
||||
|
||||
public void GearUp()
|
||||
{
|
||||
if (currentGear < GearRatios.Length)
|
||||
currentGear++;
|
||||
}
|
||||
|
||||
public void GearDown()
|
||||
{
|
||||
if (currentGear > 1)
|
||||
currentGear--;
|
||||
}
|
||||
|
||||
private float GetCurrentGearRatio()
|
||||
{
|
||||
if (currentGear == 0) return 0f; // Neutral
|
||||
if (currentGear == -1) return -3.5f; // Reverse (example ratio)
|
||||
if (currentGear > 0 && currentGear <= GearRatios.Length)
|
||||
return GearRatios[currentGear - 1];
|
||||
return 0f; // Invalid gear
|
||||
}
|
||||
|
||||
public float CalculateSpeedDifference()
|
||||
{
|
||||
if (TotalRatio == 0) return 0f;
|
||||
|
||||
float engineOmega = Engine.AngularVelocity;
|
||||
float wheelOmega = WheelSystem.AngularVelocity;
|
||||
float expectedWheelOmega = engineOmega / TotalRatio;
|
||||
|
||||
SpeedDifference = wheelOmega - expectedWheelOmega;
|
||||
return SpeedDifference;
|
||||
}
|
||||
|
||||
public float CalculateClutchTorque()
|
||||
{
|
||||
if (ClutchEngagement <= 0.01f)
|
||||
{
|
||||
ClutchTorque = 0;
|
||||
return 0f;
|
||||
}
|
||||
|
||||
CalculateSpeedDifference();
|
||||
|
||||
float torque = -SpeedDifference * ClutchStiffness * ClutchEngagement;
|
||||
torque = Math.Clamp(torque, -MaxClutchTorque, MaxClutchTorque);
|
||||
|
||||
float actualThrottle = Engine.GetActualThrottle();
|
||||
float availableEngineTorque = Engine.GetTorqueOutput();
|
||||
|
||||
float maxTorqueAtClutch = maxEngineTorque * TotalRatio * Efficiency;
|
||||
|
||||
torque = maxTorqueAtClutch;
|
||||
|
||||
|
||||
ClutchTorque = torque;
|
||||
return torque;
|
||||
}
|
||||
|
||||
public void ApplyDrivetrainWork(float deltaTime)
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
if (ClutchEngagement <= 0.01f || TotalRatio == 0)
|
||||
{
|
||||
ClutchTorque = 0;
|
||||
TransmittedPower = 0;
|
||||
ClutchSlipRatio = 1f;
|
||||
return;
|
||||
}
|
||||
|
||||
CalculateSpeedDifference();
|
||||
float clutchTorque = CalculateClutchTorque();
|
||||
// Calculate expected vs actual wheel speeds
|
||||
float expectedWheelOmega = Engine.AngularVelocity / TotalRatio;
|
||||
float actualWheelOmega = WheelSystem.AngularVelocity;
|
||||
float omegaDifference = actualWheelOmega - expectedWheelOmega;
|
||||
|
||||
bool engineDrivingWheels = clutchTorque > 0;
|
||||
bool wheelsDrivingEngine = clutchTorque < 0;
|
||||
// Calculate max torque clutch can transmit
|
||||
float maxClutchTorque = MaxClutchTorque * ClutchEngagement;
|
||||
|
||||
if (engineDrivingWheels)
|
||||
// Simple spring model: torque tries to sync speeds
|
||||
float desiredTorque = -omegaDifference * ClutchStiffness;
|
||||
|
||||
// Clamp to clutch capacity
|
||||
desiredTorque = Math.Clamp(desiredTorque, -maxClutchTorque, maxClutchTorque);
|
||||
|
||||
// Also limit by engine capability when accelerating
|
||||
if (desiredTorque > 0)
|
||||
{
|
||||
// Engine -> Wheels (normal driving)
|
||||
ApplyEngineToWheels(clutchTorque, deltaTime);
|
||||
}
|
||||
else if (wheelsDrivingEngine)
|
||||
{
|
||||
// Wheels -> Engine (engine braking)
|
||||
ApplyWheelsToEngine(clutchTorque, deltaTime);
|
||||
float engineTorque = Engine.GetTorqueOutput() * Engine.GetActualThrottle();
|
||||
float maxEngineTorqueAtWheels = engineTorque * TotalRatio * Efficiency;
|
||||
desiredTorque = Math.Min(desiredTorque, maxEngineTorqueAtWheels);
|
||||
}
|
||||
|
||||
TransmittedPower = clutchTorque * SpeedDifference;
|
||||
ClutchTorque = desiredTorque;
|
||||
|
||||
// Calculate energy transfer based on torque
|
||||
float energyTransferred = 0f;
|
||||
|
||||
if (omegaDifference > 0.01f) // Wheels → Engine (engine braking)
|
||||
{
|
||||
// Power = torque × angular velocity (at slower side - engine)
|
||||
float power = ClutchTorque * (Engine.AngularVelocity);
|
||||
energyTransferred = power * deltaTime;
|
||||
|
||||
// Wheels lose energy, engine gains (minus efficiency losses)
|
||||
float wheelEnergyLoss = Math.Abs(energyTransferred);
|
||||
float engineEnergyGain = wheelEnergyLoss * Efficiency;
|
||||
|
||||
WheelSystem.TotalEnergy -= wheelEnergyLoss;
|
||||
Engine.FlywheelEnergy += engineEnergyGain;
|
||||
}
|
||||
else if (omegaDifference < -0.01f) // Engine → Wheels (acceleration)
|
||||
{
|
||||
// Power = torque × angular velocity (at faster side - engine)
|
||||
float power = -ClutchTorque * Engine.AngularVelocity; // Negative torque, positive power
|
||||
energyTransferred = power * deltaTime;
|
||||
|
||||
// Engine loses energy, wheels gain
|
||||
float engineEnergyLoss = Math.Abs(energyTransferred);
|
||||
float wheelEnergyGain = engineEnergyLoss * Efficiency;
|
||||
|
||||
Engine.FlywheelEnergy -= engineEnergyLoss;
|
||||
WheelSystem.TotalEnergy += wheelEnergyGain;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Nearly synchronized
|
||||
energyTransferred = 0;
|
||||
}
|
||||
|
||||
// Calculate transmitted power
|
||||
TransmittedPower = energyTransferred / deltaTime;
|
||||
|
||||
// Calculate clutch slip CORRECTLY:
|
||||
// Slip = 0 when torque < max torque (clutch can handle it)
|
||||
// Slip = 1 when torque = max torque (clutch is slipping)
|
||||
if (maxClutchTorque > 0)
|
||||
{
|
||||
float torqueRatio = Math.Abs(ClutchTorque) / maxClutchTorque;
|
||||
// If we're transmitting max torque, clutch is slipping
|
||||
// If we're transmitting less, clutch is gripping
|
||||
ClutchSlipRatio = torqueRatio; // 0 = no slip, 1 = full slip
|
||||
}
|
||||
else
|
||||
{
|
||||
ClutchSlipRatio = 1f;
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyEngineToWheels(float clutchTorque, float deltaTime)
|
||||
// Other methods...
|
||||
public float GearRatio => GetCurrentGearRatio();
|
||||
public float TotalRatio => GearRatio * FinalDriveRatio;
|
||||
|
||||
private float GetCurrentGearRatio()
|
||||
{
|
||||
// Existing logic for engine driving wheels
|
||||
float netWheelTorque = clutchTorque * Efficiency - WheelSystem.ResistanceTorque;
|
||||
float netEngineTorque = -clutchTorque / TotalRatio;
|
||||
|
||||
// Apply to both
|
||||
Engine.ApplyTorque(netEngineTorque, deltaTime);
|
||||
WheelSystem.ApplyTorque(netWheelTorque, deltaTime);
|
||||
if (currentGear == 0) return 0f;
|
||||
if (currentGear == -1) return -3.5f;
|
||||
if (currentGear > 0 && currentGear <= GearRatios.Length)
|
||||
return GearRatios[currentGear - 1];
|
||||
return 0f;
|
||||
}
|
||||
|
||||
private void ApplyWheelsToEngine(float clutchTorque, float deltaTime)
|
||||
{
|
||||
// Wheels driving engine (engine braking)
|
||||
// Negative clutchTorque means wheels are trying to spin engine faster
|
||||
|
||||
float wheelTorque = clutchTorque; // Negative value
|
||||
float engineTorque = -clutchTorque / TotalRatio; // Positive resistance
|
||||
|
||||
// Apply resistance to wheels
|
||||
WheelSystem.ApplyTorque(wheelTorque, deltaTime);
|
||||
|
||||
Engine.ApplyTorque(-engineTorque, deltaTime); // Negative = slowing
|
||||
}
|
||||
|
||||
public float GetEquivalentInertiaAtEngine()
|
||||
{
|
||||
float wheelInertia = WheelSystem.GetTotalInertia();
|
||||
return Engine.MomentOfInertia + (wheelInertia * TotalRatio * TotalRatio);
|
||||
}
|
||||
|
||||
public float CalculateEngineLoad(float deltaTime)
|
||||
{
|
||||
if (ClutchEngagement <= 0.01f) return 0f;
|
||||
|
||||
float wheelResistanceTorque = WheelSystem.ResistanceTorque;
|
||||
float engineLoadTorque = wheelResistanceTorque / (TotalRatio * Efficiency);
|
||||
|
||||
float inertiaLoad = CalculateInertiaLoad(deltaTime);
|
||||
|
||||
return engineLoadTorque + inertiaLoad;
|
||||
}
|
||||
|
||||
private float CalculateInertiaLoad(float deltaTime)
|
||||
{
|
||||
float wheelAlpha = (WheelSystem.AngularVelocity - previousWheelOmega) / deltaTime;
|
||||
previousWheelOmega = WheelSystem.AngularVelocity;
|
||||
|
||||
float inertiaTorque = wheelAlpha * WheelSystem.GetTotalInertia();
|
||||
return inertiaTorque / (TotalRatio * TotalRatio * Efficiency);
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
ApplyDrivetrainWork(deltaTime);
|
||||
}
|
||||
|
||||
// Helper methods
|
||||
public float GetSpeedDifferenceRPM()
|
||||
{
|
||||
return SpeedDifference * PhysicsUtil.RAD_PER_SEC_TO_RPM;
|
||||
float expectedWheelOmega = Engine.AngularVelocity / TotalRatio;
|
||||
float actualWheelOmega = WheelSystem.AngularVelocity;
|
||||
return (actualWheelOmega - expectedWheelOmega) * PhysicsUtil.RAD_PER_SEC_TO_RPM;
|
||||
}
|
||||
|
||||
public string GetCurrentGearName()
|
||||
@@ -202,5 +153,13 @@
|
||||
_ => currentGear.ToString()
|
||||
};
|
||||
}
|
||||
|
||||
public float GetClutchSlipPercent()
|
||||
{
|
||||
return ClutchSlipRatio * 100f;
|
||||
}
|
||||
|
||||
public void GearUp() { if (currentGear < GearRatios.Length) currentGear++; }
|
||||
public void GearDown() { if (currentGear > 1) currentGear--; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user