Energy based changes

This commit is contained in:
max
2025-12-18 02:30:17 +01:00
parent c22452c66c
commit fa68f73055
5 changed files with 220 additions and 295 deletions

View File

@@ -5,10 +5,11 @@ namespace Car_simulation
public class Car
{
public Vector2 Position = new Vector2(0, 0);
public Vector2 Velocity = new Vector2(0, 0);
public float Speed => Velocity.Length;
public Vector2 Velocity => new Vector2(WheelSystem.CarSpeed, 0); // Now directly from wheels
public float Mass = 1500f; // kg
public float Speed => WheelSystem.CarSpeed;
public float Mass { get; set; } = 1500f; // kg
public int WheelCount = 4;
public int DrivenWheels = 2;
@@ -20,7 +21,7 @@ namespace Car_simulation
// Aerodynamics
private const float AirDensity = 1.225f;
public float DragCoefficient = 0.1f;
public float DragCoefficient = 0.3f;
public float FrontalArea = 2.2f; // m²
public float RollingResistanceCoefficient = 0.015f;
@@ -36,12 +37,14 @@ namespace Car_simulation
{
Engine = new Engine();
WheelSystem = new WheelSystem();
Drivetrain = new Drivetrain(Engine, WheelSystem);
// Initial setup
// Set car mass in wheel system (so it's included in energy calculations)
WheelSystem.CarMass = Mass;
WheelSystem.WheelCount = WheelCount;
WheelSystem.DrivenWheels = DrivenWheels;
Drivetrain = new Drivetrain(Engine, WheelSystem);
InitializeAudio();
}
@@ -52,7 +55,6 @@ namespace Car_simulation
_engineSound = new EngineSound();
_engineSound.SetEngineState(Engine.IdleRPM, 0f);
_engineSound.StartSound();
}
catch (Exception ex)
{
@@ -64,27 +66,30 @@ namespace Car_simulation
public void Update(float deltaTime)
{
Engine.Throttle = ThrottleInput;
Drivetrain.ClutchEngagement = 1f - ClutchInput; // Convert: 0 input = 1 engagement
Drivetrain.ClutchEngagement = 1f - ClutchInput;
if (ForceClutch)
Drivetrain.ClutchEngagement = 0f;
float resistanceTorque = CalculateResistanceTorque();
WheelSystem.ResistanceTorque = resistanceTorque;
// Update engine
Engine.Update(deltaTime);
// Update drivetrain (transfers energy between engine and wheels+car)
Drivetrain.Update(deltaTime);
// Calculate and apply resistance
float resistanceForce = CalculateTotalResistanceForce();
WheelSystem.ResistanceTorque = resistanceForce * WheelSystem.Radius;
WheelSystem.ApplyResistance(deltaTime);
float engineLoad = Drivetrain.CalculateEngineLoad(deltaTime);
Engine.Update(deltaTime, engineLoad);
UpdateVehicleMotion(deltaTime);
// Apply braking
ApplyBraking(deltaTime);
// Update position based on velocity (which comes from WheelSystem)
Position += Velocity * deltaTime;
if (_audioEnabled)
{
UpdateAudio();
}
}
private void UpdateAudio()
@@ -100,72 +105,11 @@ namespace Car_simulation
}
}
private void UpdateVehicleMotion(float deltaTime)
{
// Calculate net force
float tractiveForce = CalculateTractiveForce();
float resistanceForce = CalculateTotalResistanceForce();
float netForce = tractiveForce - resistanceForce;
// Calculate acceleration: a = F / m
float acceleration = netForce / Mass;
// Update velocity: v = v₀ + a·Δt
if (Velocity.Length > 0)
{
Vector2 direction = Velocity.Normalized();
float newSpeed = Velocity.Length + acceleration * deltaTime;
newSpeed = Math.Max(newSpeed, 0); // Don't go backwards without reverse gear
Velocity = direction * newSpeed;
}
else
{
// Starting from standstill
Velocity = new Vector2(acceleration * deltaTime, 0);
}
Position += Velocity * deltaTime;
// Sync wheel speed with actual vehicle speed (with slip allowance)
float currentWheelSpeed = Velocity.Length;
WheelSystem.SetSpeed(currentWheelSpeed);
}
private float CalculateTractiveForce()
{
// 1. Get the torque available at the wheels
float wheelTorque = Drivetrain.ClutchTorque * Drivetrain.Efficiency;
// 2. Convert torque to theoretical force: F = τ / r
float theoreticalForce = wheelTorque / WheelSystem.Radius;
// 3. Account for weight distribution and driven wheels
// Normal load on driven wheels = (DrivenWheels / WheelCount) * Weight
float drivenWheelNormalLoad = (DrivenWheels / (float)WheelCount) * Mass * 9.81f;
// 4. Calculate maximum tractive force based on friction (tire grip)
float frictionCoefficient = 1.2f; // Typical tire on dry asphalt
float maxTractiveForce = drivenWheelNormalLoad * frictionCoefficient;
// 5. Limit the force by what the tires can actually grip
// Also handle direction (forward/reverse)
if (theoreticalForce > 0)
{
return Math.Min(theoreticalForce, maxTractiveForce);
}
else
{
// For reverse or engine braking
return Math.Max(theoreticalForce, -maxTractiveForce);
}
}
private void ApplyBraking(float deltaTime)
{
if (BrakeInput <= 0) return;
float brakeTorque = BrakeInput * 500f; // 500 Nm max brake torque
float brakeTorque = BrakeInput * 3000f;
WheelSystem.ApplyTorque(-brakeTorque, deltaTime);
}
@@ -178,40 +122,34 @@ namespace Car_simulation
private float CalculateDragForce()
{
// F_drag = 0.5 * ρ * Cd * A * v²
float speed = Speed;
return 0.5f * AirDensity * DragCoefficient * FrontalArea * speed * speed;
}
private float CalculateRollingResistanceForce()
{
// F_rolling = C_r * m * g
return RollingResistanceCoefficient * Mass * 9.81f;
}
// Convert resistance force to wheel torque
public float CalculateResistanceTorque()
{
float totalForce = CalculateTotalResistanceForce();
return totalForce * WheelSystem.Radius;
}
public void DisplayUpdate()
{
Console.SetCursorPosition(0, 0);
Console.WriteLine($"Engine Energy: {Engine.FlywheelEnergy,7:F0} J");
Console.WriteLine($"Engine Torque: {Engine.GetTorqueOutput(),7:F0} Nm");
Console.WriteLine($"Engine RPM: {Engine.RPM,7:F0}");
Console.WriteLine($"Wheel Energy: {WheelSystem.WheelEnergy,7:F0} J");
Console.WriteLine($"Total Energy: {WheelSystem.TotalEnergy,7:F0} J");
Console.WriteLine($" (Wheel Rot: {WheelSystem.GetRotationalEnergy(),7:F0} J)");
Console.WriteLine($" (Car Trans: {WheelSystem.GetTranslationalEnergy(),7:F0} J)");
Console.WriteLine($"Wheel RPM: {WheelSystem.RPM,7:F0}");
Console.WriteLine($"Vehicle: {Speed * 3.6f,7:F1} km/h");
Console.WriteLine($"Throttle: {Engine.GetActualThrottle() * 100,6:F1}%");
Console.WriteLine($"Power: {Engine.CurrentPower / 1000,6:F1} kW");
Console.WriteLine($"Transmitted: {Drivetrain.TransmittedPower / 1000,6:F1} kW");
Console.WriteLine($"Brake: {BrakeInput * 100,6:F1}%");
Console.WriteLine($"Clutch: {ClutchInput * 100,6:F1}% disengaged");
Console.WriteLine($"Speed Diff: {Drivetrain.GetSpeedDifferenceRPM(),6:F0} RPM");
Console.WriteLine($"Clutch: {ClutchInput * 100,6:F1}% disengaged");
Console.WriteLine($"Clutch T: {Drivetrain.ClutchTorque,6:F0} Nm");
Console.WriteLine($"Clutch Slip: {Drivetrain.GetClutchSlipPercent(),6:F1}%");
Console.WriteLine($"Resistance: {CalculateTotalResistanceForce(),6:F1} N");
Console.WriteLine($"Drag: {CalculateDragForce(),6:F1} N");
Console.WriteLine($"Rolling: {CalculateRollingResistanceForce(),6:F1} N");