133 lines
3.7 KiB
Python
133 lines
3.7 KiB
Python
import math
|
|
|
|
class Engine:
|
|
def __init__(self,
|
|
idle_rpm=750,
|
|
max_rpm=7000,
|
|
redline_rpm=6500,
|
|
flywheel_inertia=0.025,
|
|
fuel_efficiency=0.3,
|
|
torque_curve=None):
|
|
|
|
# General stuff
|
|
self.rpm = idle_rpm
|
|
self.throttle = 0.0
|
|
self.load = 0.0
|
|
self.gear = None
|
|
self.ignition = True
|
|
self.revCut = False
|
|
|
|
self.idle_rpm = idle_rpm
|
|
self.max_rpm = max_rpm
|
|
self.redline_rpm = redline_rpm
|
|
self.flywheel_inertia = flywheel_inertia
|
|
self.fuel_efficiency = fuel_efficiency
|
|
self.torque_curve = torque_curve or self.default_torque_curve
|
|
self.instant_torque = 0
|
|
self.engineFriction = 5
|
|
self.peak_torque = 163 # Nm -> 120 ft/lb
|
|
self.engine_brake_strength = 40 # Nm
|
|
self.engine_brake_torque = 0
|
|
self.starting = False
|
|
|
|
# Fluids
|
|
self.oil_temp = 0
|
|
self.oil_pressure = 0
|
|
self.oil_capacity = 0
|
|
|
|
self.coolant_temp = 0
|
|
self.coolant_pressure = 0
|
|
self.coolant_capacity = 0
|
|
|
|
self.max_fuel_capacity = 68 # Liter
|
|
self.fuel_capacity = self.max_fuel_capacity
|
|
|
|
# Fuel
|
|
|
|
self.fuel_rate = 0
|
|
self.afr = 0
|
|
|
|
# Timing stuff
|
|
self.kr = 0
|
|
self.timing_advance = 0
|
|
self.ignition_timing = 0
|
|
|
|
# Exhaust stuff
|
|
self.exhaust_temp = 0
|
|
self.turbo_boost = 0
|
|
|
|
# Environment
|
|
self.ambient_temp = 0
|
|
self.altitude = 0
|
|
self.intake_pressure = 0
|
|
self.vehicle_mass = 0
|
|
self.drivetrain_loss = 0
|
|
|
|
|
|
# Just a parabolic curve for now
|
|
def default_torque_curve(self, rpm):
|
|
rpm_ratio = rpm / self.max_rpm
|
|
return max(0.0, -4 * (rpm_ratio - 0.5) ** 2 + 1)
|
|
|
|
def start(self, dt):
|
|
self.ignition = True
|
|
self.starting = True
|
|
|
|
def update(self, throttle, load, dt):
|
|
self.throttle = throttle
|
|
self.load = load
|
|
|
|
if self.starting:
|
|
available_torque = self.torque_curve(self.rpm)
|
|
self.instant_torque = (available_torque * self.peak_torque) + 10
|
|
rpm_change = (self.instant_torque / self.flywheel_inertia)
|
|
self.rpm += rpm_change * dt
|
|
if self.rpm > 2000:
|
|
self.starting = False
|
|
throttle = 0
|
|
|
|
# Idle -- Eventually should have learning alg to find the % throttle needed
|
|
if (self.rpm < self.idle_rpm):
|
|
self.throttle = 0.1
|
|
|
|
# Rev limit
|
|
if (self.rpm > self.redline_rpm):
|
|
self.revCut = True
|
|
|
|
if self.revCut and self.rpm > self.redline_rpm - 100:
|
|
self.throttle = 0
|
|
else:
|
|
self.revCut = False
|
|
|
|
|
|
# Engine friction
|
|
if (self.rpm > 0):
|
|
friction_force = self.engineFriction
|
|
else:
|
|
friction_force = 0
|
|
|
|
# Engine braking torque (If throttle closed)
|
|
if self.throttle == 0 and self.rpm > self.idle_rpm + 200 or not self.ignition:
|
|
engine_brake_torque = self.engine_brake_strength * (self.rpm / self.max_rpm)
|
|
else:
|
|
engine_brake_torque = 0
|
|
|
|
# Transmission Load
|
|
|
|
|
|
|
|
# Calculate torque
|
|
if self.ignition:
|
|
available_torque = self.torque_curve(self.rpm)
|
|
else:
|
|
available_torque = 0
|
|
|
|
self.instant_torque = (self.throttle * available_torque * self.peak_torque) - engine_brake_torque - friction_force
|
|
rpm_change = (self.instant_torque / self.flywheel_inertia)
|
|
self.rpm += rpm_change * dt
|
|
|
|
self.fuel_rate = self.rpm * throttle * self.fuel_efficiency
|
|
# self.fuel_capacity -= self.fuel_rate
|
|
|
|
#self._update_temps(dt)
|