Heuristic Application for Gear-ratio, Up-shift, & Redline Unit Mapping Architecture
A client-side TypeScript SPA that plots engine RPM against vehicle speed for every gear, computes redline shift drops, estimates road-load physics (mass + aero drag + rolling resistance), and prescribes optimal shift points via tractive-force analysis.
- RPM-vs-speed curves — one per forward gear up to the rev limiter, with shift-drop connectors showing RPM landing in the next gear.
- Reverse gear — dashed gray
Rcurve. - Tire parsing —
205/55R16→ rolling circumference with instant validation. - Comparison overlay — full secondary vehicle setup (tire, FD, gears, redline, mass, Cd, frontal area, power, torque/power anchors, running gear) as dashed curves with delta readout and its own grip curve.
- Engine curve model — peak torque RPM, peak torque Nm, peak power RPM with linear torque interpolation below peak torque (smooth real-world profile) and linear power interpolation above. Derived
kW @ torque peakreadout viaP = T × n × π / 30000. - Road-load physics — for every gear peak, computes wheel power required to hold speed against weight, aero drag, rolling resistance, and grade. Flags gears the engine cannot pull as
drag-limited. - Drag-limited top speed — bisection solver finds where required wheel power equals available power; marked with an
AEROline on the graph. Handles steep downhill grades robustly. - Tractive force analysis — engine torque → wheel force in Newtons per gear (
F = T × i_total × η / r_dyn). - Optimal shift advisor — per-gear-pair shift RPM based on force-curve crossing with anti-false-positive scanning (immune to turbo-lag oscillations at low RPM); appends
LIMITwhen the rev limiter is the optimal point. - Load transfer & grip model — lateral load transfer per axle (full inner→outer transfer), Kamm friction circle, advanced differential catalog (open / LSD 1-way / 1.5-way / 2-way with accel+coast lock %, Torsen, spool), wheelspin detection, and proportional lateral force distribution based on instantaneous wheel load.
- Downforce model — lift coefficient, reference area and front/rear split inputs with a live downforce readout; downforce adds to vertical load for the friction-limited grip curve.
- Coast / engine-braking model — closed-throttle drag through the coast-side differential lock, with a per-gear coast lock-up speed readout (inside-wheel lockup under engine braking).
- Dyno CSV import — load a measured torque or power curve (comma/semicolon/tab, decimal comma, Nm/kgm, kW/cv/hp, header or header-less); the anchor model is replaced until you switch back.
- Layout-mapped efficiency — picking FWD/RWD/AWD in the running-gear card also sets the default drivetrain efficiency (0.90 / 0.85 / 0.80).
- Acceleration solver — fixed-step Euler simulation of 0-100 km/h and the quarter mile, including optional rotating inertia (per-gear when
Ivalues are set), shift torque cut, and launch clutch-sliplaunchRpm. - Highway cruising check — required vs available wheel power and gear RPM at a chosen cruise speed.
- Graph export — PNG (canvas) and SVG (vector) downloads; print stylesheet for PDF via the browser print dialog.
- KPI strip — live redline, top speed, aero wall, grip limit, 0-100 and 1/4 mile cells.
- Downforce integration — aerodynamic downforce from lift coefficient and reference area, split front/rear, adds to vertical load for friction-limited grip.
- Translation — English and Italian, persisted. Uses
data-i18n(text),data-i18n-tip(tooltip),data-i18n-ph(placeholder). All English copy lives indictionary.en.ts, all Italian indictionary.it.ts. - Setup troubleshooting wizard — entry/mid/exit × understeer/oversteer/transfer/bottoming decision tree with ranked adjustments, severity badges and trade-off warnings.
- Setup handbook — offline feel-the-car cues (braking, mid-corner, exit, pyrometer reading) plus the 8-step systematic setup procedure, rendered from reusable
Cardcomponents. - Android APK — Capacitor wrapper; manual Build APK workflow assembles a debug APK artifact on demand.
- Custom cars — save/load complete setups (tire, FD, redline, gears, reverse, mass, Cd, area, power, torque curve anchors) to localStorage. Export/import JSON files.
- Share via URL — encodes all setup parameters into the URL hash. One-click copy, paste to share.
- PWA —
manifest.webmanifestwith standalone display, maskable icons; service worker for offline asset caching. - Theme system — three-way toggle: dark (default) → oled (pure black) → light (white). Persisted in localStorage. Graph canvas palette follows the theme.
- Mobile-first layout — slide-over drawer (lang/unit/power-unit/presets/settings), compact header, 16/9 graph canvas, horizontal-scroll tables with sticky first column, 44px touch targets,
visualViewportkeyboard-avoidance.
HAGURUMA uses strict SI discipline internally:
| Module | Key physics |
|---|---|
traction-math.ts |
Engine torque from power anchors (KW_TO_NM = 30000/π ≈ 9549.3); linear torque interpolation below peak torque; tractive force F = T × i × η / r_dyn; optimal shift via force-curve crossing with backward scan; custom dyno point curves with linear interpolation |
dyno-csv.ts |
Dyno CSV parsing (header/header-less, ;/,/tab, decimal comma, Nm/kgm, kW/cv/hp), resampling to 64 points, derived peak-torque/power anchors |
speed-math.ts |
SI core speedKmh / rpmFromKmh; mph applied only at display boundary (KMH_PER_MPH = 1.609344) |
aero-math.ts |
Drag, rolling resistance, grade forces; drag-limited top-speed bisection; handles negative-grade power |
dynamics-math.ts |
Longitudinal & lateral load transfer (full per-axle lateral transfer, no 50% undercount); Kamm friction circle; differential torque bias; downforce from lift coefficients; proportional lateral force distribution (Fy ∝ Fz); coast/engine-braking force with coast-lock lockup scan |
shift-math.ts |
Kinematic landing RPM (n_land = n_shift × i_next / i_curr); direct ratio calculation eliminates conversion drift |
accel-math.ts |
Forward-Euler time-step solver for 0-100 and 1/4 mile; shift window; optional rotating mass and launch RPM |
inertia-math.ts |
Reflects engine/wheel moments of inertia through the current gear into an equivalent translational mass |
cruise-math.ts |
Highest gear with RPM ≥ floor, required/available wheel power, OK / high / over verdict |
| Preset | Tire | FD | Redline | Forward gears | Reverse | Power |
|---|---|---|---|---|---|---|
| Mitsubishi Eclipse 1G GS (5MT) | 195/60R15 |
4.322 |
7000 |
3.363 / 1.947 / 1.285 / 0.939 / 0.756 | 3.083 | 110 kW |
| Mazda Miata NA (5MT) | 185/60R14 |
4.30 |
7200 |
3.136 / 1.888 / 1.330 / 1.000 / 0.814 | 3.758 | 85 kW |
| Honda S2000 AP1 (6MT) | 225/50R16 |
4.10 |
9000 |
3.133 / 2.045 / 1.481 / 1.161 / 0.971 / 0.811 | 2.800 | 177 kW |
| BMW M3 E46 (6MT) | 255/40R18 |
3.62 |
8000 |
4.23 / 2.53 / 1.67 / 1.23 / 1.00 / 0.83 | 3.75 | 252 kW |
| BMW M3 E36 3.2 (5MT) | 225/45R17 |
3.15 |
7600 |
4.23 / 2.53 / 1.67 / 1.23 / 1.00 | 3.68 | 236 kW |
| Volvo 240 Turbo (5MT) | 195/65R15 |
4.10 |
6000 |
3.67 / 2.17 / 1.37 / 1.00 / 0.79 | 3.55 | 114 kW |
| Toyota GR86 / BRZ (6MT) | 215/40R18 |
4.10 |
7500 |
3.626 / 2.188 / 1.541 / 1.213 / 1.000 / 0.767 | 3.438 | 168 kW |
| Porsche 911 GT3 991 (6MT) | 305/30R20 |
3.97 |
9000 |
3.75 / 2.38 / 1.72 / 1.34 / 1.11 / 0.96 | 3.42 | 349 kW |
The full catalog holds 26 factory/community vehicles under src/config/cars/ (drop-in JSON; no registry edit).
5th gear tops out at 215–220 km/h at ~5,900–6,100 RPM — past that point the 150 cv engine cannot beat air drag to reach the limiter. The app models this: the AERO line marks where required wheel power equals available power, and the 5th-gear row reads drag-limited.
Prerequisites: Node.js 20+.
git clone https://github.com/camiu01/haguruma.git
cd haguruma
npm install
npm run dev # vite dev server on :5173Checks:
npx tsc --noEmit
npm test
npm run build # tsc --noEmit; vite build
npm run previewvite.config.ts uses base: './' — dist/ works on any static host.
src/
main.ts # bootstrap
core/
models.ts # shared types
math/ # tire, speed, aero, traction, shift, dynamics, accel, inertia, cruise, dyno-csv
state/app-state.ts # mutable singleton store
units/unit-utils.ts # kmh/mph + kW/cv helpers
i18n/ # dictionary.en.ts + dictionary.it.ts + language state
setup/ # wizard matrix + handbook copy (DictKey refs only)
theme/theme.ts # dark/oled/light toggle
presets/custom-store.ts # localStorage custom cars
share/share-utils.ts # URL hash encode/decode
config/ # presets, glob catalog loader, cars/, diff-presets, gear colors, graph constants
services/
dom/element-refs.ts # typed DOM handles
graph/ # canvas setup, axes, curves, drops, renderer, tooltip, theme, export
events/ # one binder per control group
components/ # gear list, breakdown table, custom car, cruise card
components/card/ # base Card + one file per specialized card + barrel
views/render-all.ts # single refresh entry
styles/ # main.css hub + tokens/base/drawer/components/shell/overrides/setup-guide/print
capacitor.config.ts # native wrapper (webDir dist)
android/ # committed Capacitor scaffold
tests/ # vitest suites mirroring src/
Conventions: tabs, single quotes, semicolons, TSDoc on every function, feature files <400 lines (shell/hub/dictionary exempt), functions <50 lines.
Actions tab → Build APK → Run workflow. The workflow typechecks, tests, builds the web app, syncs Capacitor and assembles app-debug.apk (JDK 17), uploaded as the haguruma-debug-apk artifact. Debug-signed for sideload testing only.