111 lines
2.9 KiB
C#
111 lines
2.9 KiB
C#
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<int, float>[] _starterTable = new KeyValuePair<int, float>[]{
|
|
new KeyValuePair<int, float>(2, 12.5f),
|
|
new KeyValuePair<int, float>(4, 8.0f),
|
|
new KeyValuePair<int, float>(6, 6.5f),
|
|
new KeyValuePair<int, float>(8, 6.0f),
|
|
new KeyValuePair<int, float>(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;
|
|
}
|