Files
FluidSimCpp/docs/ENGINE_CONFIG.md
max bf8621ad39 Load engines from TOML and improve scenario audio and carb tuning
Migrate 32 engine definitions into validated startup-loaded TOML files and separate configuration and snapshots from scenario assembly. Add camera-based stereo propagation from shared pipe geometry, preserve exhaust character, tune carburetor mixtures and idle, use ignition cuts for carb engines, and support returning to the scenario menu.

Validation: full Windows build and all 14 CTest checks passed.
2026-10-24 03:24:35 +02:00

127 lines
5.8 KiB
Markdown

# Engine definitions
Each `engines/*.toml` file defines one engine and its default vehicle/load
calibration. Files are loaded once when the program starts. Add a file, give it
a unique `id`, then restart to see it in the browser. Editing a definition does
not require recompiling the engine simulator.
Start by copying a similar engine, such as `single-450.toml`, `five.toml`,
`v8-h.toml` or `yz-racing.toml`. Existing definitions contain their effective
calibration values, including the previous carb and idle tunes.
```toml
schema_version = 1
id = "my-single"
name = "My four-stroke single"
category = "Singles / four-stroke"
description = "My calibration"
order = 100
cycle = "four_stroke"
```
`id`, `name`, `category`, `cycle` and `schema_version` are required. IDs use
lowercase letters, digits, `-` and `_`. `order` controls menu order; ties sort by
ID. Duplicate IDs, unknown keys, unsupported versions, incorrect types and
invalid physical values stop loading with a diagnostic identifying the file
and field. TOML syntax errors also report their location.
## File discovery and distribution
The first available directory is used:
1. `FLUIDSIM_ENGINE_DIR`, when set. A missing override directory is an error.
2. `engines/` under the working directory.
3. `engines/` beside the executable on Windows and Linux.
4. The source checkout's `engines/` directory as a development fallback.
Definitions are cached for the process lifetime. The selected directory is
loaded as one catalog; it is not merged with the bundled files. In a repository
working directory, source definitions take priority over build copies.
CMake synchronizes the definitions into the build output when building an
executable. Distribute that `engines/` directory with the executable. The TOML
parser is vendored, so loading definitions needs no network connection.
```powershell
$env:FLUIDSIM_ENGINE_DIR = "C:\MyEngines"
.\fluidsim_desktop.exe --example my-single
```
## Units and sections
File keys state dimensional units. `_mm` is millimetres, `_litres` is litres,
`_cc` is cubic centimetres, `_deg` is crank degrees, `_s` is seconds, `_nm` is
newton metres and `_kg_m2` is rotational inertia. The loader converts lengths
and volumes to SI units. Openings and mixture/taper multipliers are normalized
fractions, not percentages: `0.03` means 3%.
Four-stroke definitions use these sections:
| Section | Contents |
| --- | --- |
| `[engine]` | Cylinder count, layout, bank angle, phases, intake volumes, throttle, startup, load, and exhaust topology |
| `[cylinder]` | Bore/stroke/rod, compression, valve geometry and timing, combustion and heat transfer |
| `[crankshaft]` | Inertia and mechanical friction |
| `[ecu]` | Idle, actuator response, ignition curve, limiter and overrun thresholds |
| `[vehicle]` | Vehicle mass, gears, clutch, wheel geometry and road resistance |
| `[fuel]` | `system = "injection"` or `"carburetor"`, jet diameters and taper/film calibration |
| `[junctions]` | Fitting volume and H crossover selection |
| `[silencers]` | Connecting pipes, resonator and muffler profiles, when used |
| `[[pipes]]` | Ordered pipe groups for the selected exhaust topology |
`engine.phase_degrees` contains one phase per cylinder in cylinder index order,
within `[0,720)`. It records the actual crank offsets rather than a firing-order
label. `ecu.ignition_map` is an array of `[RPM, degrees BTDC]` pairs with strictly
increasing RPM. Negative advance means ignition after TDC.
For a carbureted four-stroke, use `ecu.idle_control = "fixed"` and set
`ecu.idle_base_opening`. Its limiter and overrun control cut ignition while the
carburetor continues supplying fuel. Jet diameters in `[fuel]` are effective
diameters after the previous displacement and jet multipliers have been applied.
Two-stroke definitions use `[two_stroke]`, `[ecu]` and `[vehicle]`.
`two_stroke.idle_slide_opening` sets the mechanical stop;
`idle_spark_gain` and `idle_minimum_advance_deg` set its idle spark trim.
Two-stroke jet multipliers retain their existing meaning.
`chamber_sections_mm` contains six `[length, inlet diameter, outlet diameter]`
sections: header, two diffusers, belly, baffle cone and stinger.
Required cylinder geometry must be explicit. Optional calibration fields use
the typed config defaults; a misspelled field is always an error. Existing files
include explicit values so their behavior does not depend on future defaults.
## Pipe groups and exhaust topologies
These definitions configure the existing topology builders. They do not yet
describe arbitrary graphs of cylinders and junctions. A group's `id` must be
unique; `count` repeats its dimensions across adjacent pipes.
```toml
[[pipes]]
id = "primaries"
count = 8
diameter_mm = 38.0
length_mm = 750.0
cells = 15
```
The order is significant because the topology builder connects the expanded
groups to fixed cylinder and junction ports:
| `engine.topology` | Pipe order after expansion |
| --- | --- |
| `collector` | Intake, N runners, N primaries, one tailpipe |
| `staged` | Intake, N runners, N primaries, outlet pipe(s), secondary pipe(s) |
| `american_v8` | Intake, 8 runners, 8 primaries, 4 secondaries, 2 bank collectors, 2 tailpipes, H crossover |
The staged inline triple has one secondary; other staged layouts have two.
Staged V engines have two independent outlets. The American topology requires
eight cylinders in a V layout; setting `junctions.h_pipe = false` closes both
ends of the unused crossover and leaves the banks independent.
A collector outlet can instead use `profile = "silenced"`. Its dimensions and
mesh then come from `[silencers]`, `[silencers.resonator]` and
`[silencers.muffler]`; omit the group's uniform pipe dimensions. The loader
checks expanded pipe counts and mesh limits before construction. Pipe positions
continue to use the shared scene routes for rendering and sound sources.