using UnityEngine; using System.Collections; using System; using System.Collections.Generic; [Serializable] public class IdleThrolleController { public double IdleSpeed; public double SpeedThreshold = 1.0; public double LagConstant = 1.0; public double IdleThrolle = 0.0; public void Integrate(double dt, double speed) { var throlleDerivative = ((0.5f*(1.0 - Math.Tanh(4.0*(speed - IdleSpeed)/SpeedThreshold))) - IdleThrolle)/LagConstant; IdleThrolle += throlleDerivative * dt; } } public class CarEngine : MonoBehaviour { public Flywheel flywheel; public int cylinderCount = 4; public float startRpm = 50; public double inertia = 0.3f; public double inputInertia = 0.0; public double inputTorque = 0.0; /*public abstract Curve TorqueCurve { get;} public abstract Curve FrictionCurve { get;}*/ public float Weight = 100; public Starter starter; public double inputThrolle = 0.0f; public double engineThrolle = 0.0f; public IdleThrolleController idleThrolleController; public double crankshaftAngle = 0.0; //radians public double angularSpeed; public double angularSpeedRPM; public double k_Friction = 0.000003; public Curve powerCurve; public double k_FrictionTorque = 0.75f; public double kinematicFrictionTorque = 0; public double Rpm { get { return angularSpeed * MathEx.RadSToRpm; } } /* private static KeyValuePair[] _starterTable = new KeyValuePair[]{ new KeyValuePair(2, 12.5f), new KeyValuePair(4, 8.0f), new KeyValuePair(6, 6.5f), new KeyValuePair(8, 6.0f), new KeyValuePair(12, 5.5f) };*/ void FixedUpdate() { Integrate(Time.fixedDeltaTime); } public void Integrate(double dt) { //do idle throlle idleThrolleController.Integrate(dt, Rpm); engineThrolle = Math.Max(inputThrolle, idleThrolleController.IdleThrolle); //integrate angular acceleration and speed var angularDerivative = (GetTorque(engineThrolle, Rpm) - inputTorque) / (inertia + inputInertia); angularSpeed += angularDerivative * dt; angularSpeedRPM = MathEx.RadSToRpm * angularSpeed; //integrate angle crankshaftAngle += angularSpeed * dt; kinematicFrictionTorque = (angularSpeedRPM/60.0)*k_FrictionTorque; } public double GetTorque(double throlle, double rpm) { var t = GetTorque(rpm); t = t * throlle - k_Friction * rpm * rpm * (1.0 - throlle); return t; } public double GetTorque(double rpm){ if (powerCurve == null) { return 0; } return powerCurve.Sample((float)rpm); } public static float GetWatts(float torque, float rpm){ return torque * rpm / 9549.0f; } public static float GetHp(float torque, float rpm){ return GetWatts(torque, rpm) * 1.36f; } public bool Started = false; }