init commit

This commit is contained in:
Avery Haas
2026-08-28 22:38:58 -04:00
commit 120e4f505f
324 changed files with 133476 additions and 0 deletions
+22
View File
@@ -0,0 +1,22 @@
#include "engine.h"
void Engine::step(double dt, double load_torque_nm) {
// TODO: replace with real combustion/friction torque model driven
// by throttle position and crank angle. For now: seek idle rpm
// and just track the applied load so downstream pieces have
// something to wire against.
m_rpm += (kIdleRpm - m_rpm) * dt;
m_torque_nm = -load_torque_nm;
}
double Engine::rpm() const {
return m_rpm;
}
double Engine::torque_nm() const {
return m_torque_nm;
}
void Engine::reset() {
m_rpm = 0;
}
+22
View File
@@ -0,0 +1,22 @@
#pragma once
// Crankshaft rotational dynamics. Placeholder physics for now —
// real combustion/friction torque modeling comes later.
class Engine {
public:
// load_torque_nm is the resistance fed back from the transmission
// (via the vehicle), opposing crank rotation.
void step(double dt, double load_torque_nm);
double rpm() const;
double torque_nm() const; // net torque produced this step
void reset();
private:
double m_rpm = 0.0;
double m_torque_nm = 0.0;
static constexpr double kIdleRpm = 900.0;
static constexpr double kCrankInertiaKgm2 = 0.15; // placeholder
};
BIN
View File
Binary file not shown.
+19
View File
@@ -0,0 +1,19 @@
#include "simulation.h"
void Simulation::step(double dt) {
// 1. What load is the drivetrain currently reflecting back onto the crank?
// TODO: this should come from a proper torque-balance solve; for now
// the engine ignores it (see Engine::step's placeholder body).
double load_torque_nm = 0.0;
m_engine.step(dt, load_torque_nm);
// 2. Engine torque flows down through the transmission to the wheels.
double wheel_torque_nm = m_transmission.output_torque_nm(m_engine.torque_nm());
// 3. Wheel torque accelerates the vehicle.
m_vehicle.step(dt, wheel_torque_nm);
// 4. Resulting wheel speed reflects back up through the transmission —
// next tick's load_torque_nm calculation (once real) will use this.
(void)m_transmission.reflected_engine_rpm(m_vehicle.wheel_rpm());
}
+24
View File
@@ -0,0 +1,24 @@
#pragma once
#include "engine.h"
#include "transmission.h"
#include "vehicle.h"
// Owns Engine + Transmission + Vehicle and sequences the per-tick
// coupling between them. This is the thing main.cpp / the GUI talks to.
class Simulation {
public:
void step(double dt);
const Engine& engine() const { return m_engine; }
const Transmission& transmission() const { return m_transmission; }
const Vehicle& vehicle() const { return m_vehicle; }
Engine& engine() { return m_engine; } // for reset, etc.
Transmission& transmission() { return m_transmission; } // for gear shifts
private:
Engine m_engine;
Transmission m_transmission;
Vehicle m_vehicle;
};
Binary file not shown.
+25
View File
@@ -0,0 +1,25 @@
#include "transmission.h"
void Transmission::set_gear(int gear) {
if (gear >= 0 && gear <= kNumGears) {
m_gear = gear;
}
}
int Transmission::gear() const {
return m_gear;
}
double Transmission::ratio() const {
return kGearRatios[m_gear] * kFinalDrive;
}
double Transmission::output_torque_nm(double engine_torque_nm) const {
if (m_gear == 0) return 0.0; // neutral: nothing reaches the wheels
return engine_torque_nm * ratio();
}
double Transmission::reflected_engine_rpm(double wheel_rpm) const {
if (m_gear == 0) return 0.0; // decoupled in neutral
return wheel_rpm * ratio();
}
+22
View File
@@ -0,0 +1,22 @@
#pragma once
// Gear ratio + final drive coupling between engine and wheels.
// Torque flows engine -> wheels; rpm flows wheels -> engine (reflected).
class Transmission {
public:
void set_gear(int gear); // 0 = neutral, 1..N = forward gears
int gear() const;
double output_torque_nm(double engine_torque_nm) const;
double reflected_engine_rpm(double wheel_rpm) const;
private:
double ratio() const;
int m_gear = 1;
static constexpr double kFinalDrive = 3.42;
static constexpr double kGearRatios[] = {0.0, 3.5, 2.1, 1.4, 1.0, 0.8};
static constexpr int kNumGears =
static_cast<int>(sizeof(kGearRatios) / sizeof(kGearRatios[0])) - 1;
};
Binary file not shown.
+21
View File
@@ -0,0 +1,21 @@
#include "vehicle.h"
void Vehicle::step(double dt, double wheel_torque_nm) {
double drive_force_n = wheel_torque_nm / kWheelRadiusM;
double drag_force_n = kDragCoeff * m_speed_mps * m_speed_mps;
double net_force_n = drive_force_n - drag_force_n;
double accel_mps2 = net_force_n / kMassKg;
m_speed_mps += accel_mps2 * dt;
if (m_speed_mps < 0.0) m_speed_mps = 0.0; // no reverse yet
}
double Vehicle::speed_mps() const {
return m_speed_mps;
}
double Vehicle::wheel_rpm() const {
double wheel_rad_per_s = m_speed_mps / kWheelRadiusM;
return wheel_rad_per_s * 60.0 / (2.0 * 3.14159265358979);
}
+17
View File
@@ -0,0 +1,17 @@
#pragma once
// Longitudinal vehicle dynamics: converts wheel torque into road speed.
class Vehicle {
public:
void step(double dt, double wheel_torque_nm);
double speed_mps() const;
double wheel_rpm() const;
private:
double m_speed_mps = 0.0;
static constexpr double kMassKg = 1400.0;
static constexpr double kWheelRadiusM = 0.32;
static constexpr double kDragCoeff = 0.35; // simplified quadratic drag term
};
BIN
View File
Binary file not shown.