250cc mx engine, and dyno

This commit is contained in:
max
2026-06-09 20:20:56 +02:00
parent aba9b76530
commit ac2eab6f83
5 changed files with 385 additions and 82 deletions

View File

@@ -8,21 +8,46 @@ namespace FluidSim.Components
public float CrankAngle; // rad, 0 … 4π
public float PreviousAngle;
public float Inertia = 0.2f;
public float Inertia = 0.2f; // kg·m²
public float FrictionConstant; // N·m
public float FrictionViscous; // N·m per rad/s
public float LastNetTorque { get; private set; }
public float AveragePower { get; private set; } // smoothed, watts
public float AverageTorque { get; private set; } // smoothed, Nm
private float externalTorque;
private float _loadTorque; // external brake torque (Nm)
// Power averaging buffer
private readonly float[] _powerBuffer;
private int _powerBufIdx;
private int _powerBufCount;
private float _powerBufSum;
// Torque averaging buffer (same size as power buffer)
private readonly float[] _torqueBuffer;
private int _torqueBufIdx;
private int _torqueBufCount;
private float _torqueBufSum;
public Crankshaft(float initialRPM = 400f)
{
AngularVelocity = initialRPM * 2f * MathF.PI / 60f;
CrankAngle = 0f;
PreviousAngle = 0f;
_powerBuffer = new float[16384];
_torqueBuffer = new float[16384];
}
public void AddTorque(float torque) => externalTorque += torque;
public void SetLoadTorque(float torque)
{
_loadTorque = Math.Max(torque, 0f);
}
public void Step(float dt)
{
if (float.IsNaN(AngularVelocity) || float.IsInfinity(AngularVelocity))
@@ -32,10 +57,17 @@ namespace FluidSim.Components
PreviousAngle = CrankAngle;
// Internal friction torque
float friction = FrictionConstant * MathF.Sign(AngularVelocity)
+ FrictionViscous * AngularVelocity;
// Net torque from gas pressure minus friction (used for power/torque display)
float netTorque = externalTorque - friction;
float alpha = netTorque / Inertia;
LastNetTorque = netTorque;
// Total torque after subtracting external load (brake)
float totalNetTorque = netTorque - _loadTorque;
float alpha = totalNetTorque / Inertia;
AngularVelocity += alpha * dt;
if (AngularVelocity < 0f) AngularVelocity = 0f;
@@ -46,6 +78,35 @@ namespace FluidSim.Components
else if (CrankAngle < 0f)
CrankAngle += 4f * MathF.PI;
// ---- Power averaging ----
float instantPower = netTorque * AngularVelocity;
if (_powerBufCount == _powerBuffer.Length)
{
_powerBufSum -= _powerBuffer[_powerBufIdx];
}
else
{
_powerBufCount++;
}
_powerBuffer[_powerBufIdx] = instantPower;
_powerBufSum += instantPower;
_powerBufIdx = (_powerBufIdx + 1) % _powerBuffer.Length;
AveragePower = _powerBufSum / _powerBufCount;
// ---- Torque averaging ----
if (_torqueBufCount == _torqueBuffer.Length)
{
_torqueBufSum -= _torqueBuffer[_torqueBufIdx];
}
else
{
_torqueBufCount++;
}
_torqueBuffer[_torqueBufIdx] = netTorque;
_torqueBufSum += netTorque;
_torqueBufIdx = (_torqueBufIdx + 1) % _torqueBuffer.Length;
AverageTorque = _torqueBufSum / _torqueBufCount;
externalTorque = 0f;
}
}