major rework
This commit is contained in:
95
Car simulation/Core/Components/WheelSystem.cs
Normal file
95
Car simulation/Core/Components/WheelSystem.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
using Car_simulation.Core.Physics;
|
||||
|
||||
namespace Car_simulation.Core.Components
|
||||
{
|
||||
public class WheelSystem : ICarComponent
|
||||
{
|
||||
// Physical properties
|
||||
public float Radius { get; set; } = 0.3f;
|
||||
public float WheelInertia { get; set; } = 2.0f;
|
||||
public float CarMass { get; set; } = 1500f;
|
||||
public int WheelCount { get; set; } = 4;
|
||||
public int DrivenWheels { get; set; } = 2;
|
||||
|
||||
// State
|
||||
public float TotalEnergy { get; set; } = 0f;
|
||||
public float AngularVelocity => GetOmega();
|
||||
public float RPM => GetRPM();
|
||||
public float CarSpeed => GetCarSpeed();
|
||||
|
||||
// Derived properties
|
||||
public float GetTotalRotationalInertia() => WheelInertia * WheelCount;
|
||||
public float GetEquivalentCarInertia() => CarMass * Radius * Radius;
|
||||
public float GetTotalInertia() => GetTotalRotationalInertia() + GetEquivalentCarInertia();
|
||||
|
||||
// Calculations
|
||||
public float GetOmega()
|
||||
{
|
||||
if (TotalEnergy <= 0 || GetTotalInertia() <= 0) return 0f;
|
||||
return MathF.Sqrt(2f * TotalEnergy / GetTotalInertia());
|
||||
}
|
||||
|
||||
public float GetRPM() => AngularVelocity * PhysicsUtil.RAD_PER_SEC_TO_RPM;
|
||||
public float GetCarSpeed() => AngularVelocity * Radius;
|
||||
|
||||
public float GetRotationalEnergy()
|
||||
{
|
||||
float omega = GetOmega();
|
||||
return 0.5f * GetTotalRotationalInertia() * omega * omega;
|
||||
}
|
||||
|
||||
public float GetTranslationalEnergy()
|
||||
{
|
||||
float speed = GetCarSpeed();
|
||||
return 0.5f * CarMass * speed * speed;
|
||||
}
|
||||
|
||||
public float GetEnergyFromSpeed(float speed)
|
||||
{
|
||||
float omega = speed / Radius;
|
||||
float rotationalEnergy = 0.5f * GetTotalRotationalInertia() * omega * omega;
|
||||
float translationalEnergy = 0.5f * CarMass * speed * speed;
|
||||
return rotationalEnergy + translationalEnergy;
|
||||
}
|
||||
|
||||
public void SetSpeed(float speed) => TotalEnergy = GetEnergyFromSpeed(speed);
|
||||
|
||||
public void ApplyWork(float work)
|
||||
{
|
||||
TotalEnergy += work;
|
||||
TotalEnergy = Math.Max(TotalEnergy, 0);
|
||||
}
|
||||
|
||||
public void ApplyTorque(float torque, float deltaTime)
|
||||
{
|
||||
if (torque == 0) return;
|
||||
float work = torque * AngularVelocity * deltaTime;
|
||||
ApplyWork(work);
|
||||
}
|
||||
|
||||
public void ApplyResistance(float resistanceTorque, float deltaTime)
|
||||
{
|
||||
if (resistanceTorque <= 0 || AngularVelocity == 0) return;
|
||||
|
||||
float omega = AngularVelocity;
|
||||
if (MathF.Abs(omega) < 0.1f) return;
|
||||
|
||||
float resistanceSign = -MathF.Sign(omega);
|
||||
float alpha = (resistanceSign * resistanceTorque) / GetTotalInertia();
|
||||
float omegaNew = omega + alpha * deltaTime;
|
||||
|
||||
if (MathF.Sign(omegaNew) != MathF.Sign(omega))
|
||||
{
|
||||
omegaNew = 0;
|
||||
}
|
||||
|
||||
float energyNew = 0.5f * GetTotalInertia() * omegaNew * omegaNew;
|
||||
TotalEnergy = Math.Max(energyNew, 0);
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
// WheelSystem updates are handled by Car through other components
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user