major rework
This commit is contained in:
126
Car simulation/Core/Components/Drivetrain.cs
Normal file
126
Car simulation/Core/Components/Drivetrain.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
using Car_simulation.Core.Physics;
|
||||
|
||||
namespace Car_simulation.Core.Components
|
||||
{
|
||||
public class Drivetrain : ICarComponent
|
||||
{
|
||||
public Engine Engine { get; private set; }
|
||||
public WheelSystem WheelSystem { get; private set; }
|
||||
|
||||
private int _currentGear = 1;
|
||||
public float[] GearRatios { get; set; } = { 3.8f, 2.5f, 1.8f, 1.3f, 1.0f, 0.8f, 0.65f };
|
||||
public float FinalDriveRatio { get; set; } = 4.0f;
|
||||
public float Efficiency { get; set; } = 0.95f;
|
||||
public float ClutchEngagement { get; set; } = 0f;
|
||||
|
||||
public float MaxClutchTorque { get; set; } = 400f;
|
||||
public float ClutchStiffness { get; set; } = 50f;
|
||||
|
||||
public float ClutchTorque { get; private set; }
|
||||
public float TransmittedPower { get; private set; }
|
||||
public float ClutchSlipRatio { get; private set; }
|
||||
|
||||
public Drivetrain(Engine engine, WheelSystem wheelSystem)
|
||||
{
|
||||
Engine = engine;
|
||||
WheelSystem = wheelSystem;
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
if (ClutchEngagement <= 0.01f || TotalRatio == 0)
|
||||
{
|
||||
ClutchTorque = 0;
|
||||
TransmittedPower = 0;
|
||||
ClutchSlipRatio = 1f;
|
||||
return;
|
||||
}
|
||||
|
||||
float expectedWheelOmega = Engine.AngularVelocity / TotalRatio;
|
||||
float actualWheelOmega = WheelSystem.AngularVelocity;
|
||||
float omegaDifference = actualWheelOmega - expectedWheelOmega;
|
||||
|
||||
float maxClutchTorque = MaxClutchTorque * ClutchEngagement;
|
||||
float desiredTorque = -omegaDifference * ClutchStiffness;
|
||||
desiredTorque = Math.Clamp(desiredTorque, -maxClutchTorque, maxClutchTorque);
|
||||
|
||||
if (desiredTorque > 0)
|
||||
{
|
||||
float engineTorque = Engine.GetTorqueOutput() * Engine.GetActualThrottle();
|
||||
float maxEngineTorqueAtWheels = engineTorque * TotalRatio * Efficiency;
|
||||
desiredTorque = Math.Min(desiredTorque, maxEngineTorqueAtWheels);
|
||||
}
|
||||
|
||||
ClutchTorque = desiredTorque;
|
||||
|
||||
float energyTransferred = 0f;
|
||||
|
||||
if (omegaDifference > 0.01f) // Wheels → Engine
|
||||
{
|
||||
float power = ClutchTorque * Engine.AngularVelocity;
|
||||
energyTransferred = power * deltaTime;
|
||||
float wheelEnergyLoss = Math.Abs(energyTransferred);
|
||||
float engineEnergyGain = wheelEnergyLoss * Efficiency;
|
||||
|
||||
WheelSystem.TotalEnergy -= wheelEnergyLoss;
|
||||
Engine.FlywheelEnergy += engineEnergyGain;
|
||||
}
|
||||
else if (omegaDifference < -0.01f) // Engine → Wheels
|
||||
{
|
||||
float power = -ClutchTorque * Engine.AngularVelocity;
|
||||
energyTransferred = power * deltaTime;
|
||||
float engineEnergyLoss = Math.Abs(energyTransferred);
|
||||
float wheelEnergyGain = engineEnergyLoss * Efficiency;
|
||||
|
||||
Engine.FlywheelEnergy -= engineEnergyLoss;
|
||||
WheelSystem.TotalEnergy += wheelEnergyGain;
|
||||
}
|
||||
|
||||
TransmittedPower = energyTransferred / deltaTime;
|
||||
|
||||
if (maxClutchTorque > 0)
|
||||
{
|
||||
float torqueRatio = Math.Abs(ClutchTorque) / maxClutchTorque;
|
||||
ClutchSlipRatio = torqueRatio;
|
||||
}
|
||||
else
|
||||
{
|
||||
ClutchSlipRatio = 1f;
|
||||
}
|
||||
}
|
||||
|
||||
public float GearRatio => GetCurrentGearRatio();
|
||||
public float TotalRatio => GearRatio * FinalDriveRatio;
|
||||
|
||||
private float GetCurrentGearRatio()
|
||||
{
|
||||
if (_currentGear == 0) return 0f;
|
||||
if (_currentGear == -1) return -3.5f;
|
||||
if (_currentGear > 0 && _currentGear <= GearRatios.Length)
|
||||
return GearRatios[_currentGear - 1];
|
||||
return 0f;
|
||||
}
|
||||
|
||||
public float GetSpeedDifferenceRPM()
|
||||
{
|
||||
float expectedWheelOmega = Engine.AngularVelocity / TotalRatio;
|
||||
float actualWheelOmega = WheelSystem.AngularVelocity;
|
||||
return (actualWheelOmega - expectedWheelOmega) * PhysicsUtil.RAD_PER_SEC_TO_RPM;
|
||||
}
|
||||
|
||||
public string GetCurrentGearName()
|
||||
{
|
||||
return _currentGear switch
|
||||
{
|
||||
-1 => "R",
|
||||
0 => "N",
|
||||
_ => _currentGear.ToString()
|
||||
};
|
||||
}
|
||||
|
||||
public float GetClutchSlipPercent() => ClutchSlipRatio * 100f;
|
||||
|
||||
public void GearUp() { if (_currentGear < GearRatios.Length) _currentGear++; }
|
||||
public void GearDown() { if (_currentGear > 1) _currentGear--; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user