add basic engine simulation + working gauge
This commit is contained in:
@@ -1,50 +1,127 @@
|
||||
import math
|
||||
|
||||
class Engine:
|
||||
rpm = 0
|
||||
throttle = 0
|
||||
load = 0
|
||||
instant_torque = 0
|
||||
gear = 0
|
||||
flywheel_inertia = 0
|
||||
idle_rpm = 750
|
||||
max_rpm = 6500
|
||||
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
|
||||
|
||||
fuel_rate = 0
|
||||
afr = 0
|
||||
coolant_temp = 0
|
||||
oil_temp = 0
|
||||
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.wheel_speed = 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
|
||||
|
||||
ignition_timing = 0
|
||||
# Fluids
|
||||
self.oil_temp = 0
|
||||
self.oil_pressure = 0
|
||||
self.oil_capacity = 0
|
||||
|
||||
ambient_temp = 0
|
||||
altitude = 0
|
||||
intake_pressure = 0
|
||||
vehicle_mass = 0
|
||||
drivetrain_loss = 0
|
||||
self.coolant_temp = 0
|
||||
self.coolant_pressure = 0
|
||||
self.coolant_capacity = 0
|
||||
|
||||
oil_pressure = 0
|
||||
turbo_boost = 0
|
||||
kr = 0
|
||||
exhaust_temp = 0
|
||||
self.fuel_capacity = 0
|
||||
|
||||
def start(self):
|
||||
rpm = 250
|
||||
# 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):
|
||||
|
||||
if not self.running:
|
||||
return
|
||||
|
||||
self.throttle = throttle
|
||||
self.load = load
|
||||
|
||||
# Apply simplified engine RPM dynamics
|
||||
rpm_change = (throttle - load) * self.torque_curve(self.rpm) / self.flywheel_inertia
|
||||
self.rpm += rpm_change * dt
|
||||
self.rpm = max(self.idle_rpm, min(self.rpm, self.max_rpm))
|
||||
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.1 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
|
||||
|
||||
# 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.torque = self.torque_curve(self.rpm) * throttle
|
||||
self.fuel_rate = self.rpm * throttle * self.fuel_efficiency
|
||||
|
||||
self._update_temps(dt)
|
||||
#self._update_temps(dt)
|
||||
|
||||
Reference in New Issue
Block a user