Add machine workshop, typed logic, mechanics and sensor-driven ECUs
This commit is contained in:
9
verification/performance/2026-10-30/workshop-after.csv
Normal file
9
verification/performance/2026-10-30/workshop-after.csv
Normal file
@@ -0,0 +1,9 @@
|
||||
scenario,runtime,frames,rpm,pedal,cells,min_cell_mm,substeps_per_frame,us_per_frame,wall_per_sim,positivity_repairs
|
||||
single-450,native,32768,3000,0.35,44,43.7834,1,2.89427,0.127637,0
|
||||
single-450,workshop,32768,3000,0.35,44,36.6667,1,3.54769,0.156453,0
|
||||
twin,native,32768,3000,0.35,59,18.9302,1.70621,6.11425,0.269638,0
|
||||
twin,workshop,32768,3000,0.35,58,15,1.71796,6.89146,0.303913,0
|
||||
flat6,native,32768,3000,0.35,98,34.1958,1.03406,8.42729,0.371643,0
|
||||
flat6,workshop,32768,3000,0.35,98,34.1958,1.02969,8.79167,0.387713,0
|
||||
v8-h,native,32768,3000,0.35,176,36.3695,1,16.5588,0.730241,0
|
||||
v8-h,workshop,32768,3000,0.35,175,36.3695,1,16.0058,0.705858,0
|
||||
|
8
verification/performance/2026-10-30/workshop-before.txt
Normal file
8
verification/performance/2026-10-30/workshop-before.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
single-450 native: cells=44 min_cell_mm=43.7834 substeps/frame=1 us/frame=3.17636 realtime_ratio=0.140078
|
||||
single-450 workshop: cells=56 min_cell_mm=5 culprit=Inlet metering stub substeps/frame=4 us/frame=12.6059 realtime_ratio=0.555921 slowdown=3.96866
|
||||
twin native: cells=59 min_cell_mm=18.9302 substeps/frame=1.70621 us/frame=6.21104 realtime_ratio=0.273907
|
||||
twin workshop: cells=67 min_cell_mm=5 culprit=Inlet metering stub substeps/frame=4 us/frame=16.9562 realtime_ratio=0.747767 slowdown=2.73001
|
||||
flat6 native: cells=98 min_cell_mm=34.1958 substeps/frame=1.03406 us/frame=9.63491 realtime_ratio=0.424899
|
||||
flat6 workshop: cells=161 min_cell_mm=1.7773 culprit=Pipe 12 / flat6 substeps/frame=12.3495 us/frame=104.441 realtime_ratio=4.60584 slowdown=10.8398
|
||||
v8-h native: cells=176 min_cell_mm=36.3695 substeps/frame=1 us/frame=15.5274 realtime_ratio=0.684757
|
||||
v8-h workshop: cells=318 min_cell_mm=4.99998 culprit=Inlet metering stub substeps/frame=4.08749 us/frame=67.5066 realtime_ratio=2.97704 slowdown=4.34759
|
||||
@@ -0,0 +1,9 @@
|
||||
scenario,runtime,frames,rpm,pedal,cells,min_cell_mm,substeps_per_frame,us_per_frame,wall_per_sim,positivity_repairs
|
||||
single-450,native,32768,6000,0.7,44,43.7834,1,2.9588,0.130483,0
|
||||
single-450,workshop,32768,6000,0.7,44,36.6667,1,3.56339,0.157145,0
|
||||
twin,native,32768,6000,0.7,59,18.9302,2.03198,7.14645,0.315158,0
|
||||
twin,workshop,32768,6000,0.7,58,15,1.98846,8.3636,0.368835,0
|
||||
flat6,native,32768,6000,0.7,98,34.1958,1.04791,9.21917,0.406565,0
|
||||
flat6,workshop,32768,6000,0.7,98,34.1958,1.04437,9.31432,0.410762,0
|
||||
v8-h,native,32768,6000,0.7,176,36.3695,1.0159,16.3243,0.719902,0
|
||||
v8-h,workshop,32768,6000,0.7,175,36.3695,1,16.1124,0.710557,0
|
||||
|
@@ -0,0 +1,3 @@
|
||||
scenario,frames,wall_seconds,sim_seconds,sim_per_wall,underruns,buffered
|
||||
flat6,120,2.00608,2.02014,1.00701,0,4096
|
||||
v8-h,120,2.0706,2.08181,1.00541,0,4096
|
||||
|
@@ -0,0 +1,3 @@
|
||||
scenario,frames,ms_per_frame,render_fps
|
||||
flat6,120,0.696523,1435.7
|
||||
v8-h,120,0.963612,1037.76
|
||||
|
@@ -0,0 +1,3 @@
|
||||
scenario,frames,ms_per_frame,render_fps
|
||||
flat6,120,1.40442,712.035
|
||||
v8-h,120,1.77209,564.305
|
||||
|
95
verification/performance/2026-10-30/workshop-report.md
Normal file
95
verification/performance/2026-10-30/workshop-report.md
Normal file
@@ -0,0 +1,95 @@
|
||||
# Workshop performance, 2026-10-30
|
||||
|
||||
The flat-six workshop now runs within the real-time audio budget. The measured
|
||||
simulation cost fell from 104.44 to 8.79 microseconds per sample (11.9 times faster).
|
||||
At 44,100 Hz the available budget is 22.68 microseconds per sample.
|
||||
|
||||
## Cause and changes
|
||||
|
||||
The workshop used a different assembly path from the native scenarios. It split
|
||||
fluid sections at every visual pipe knot, inserted 5 mm inlet stubs, required at
|
||||
least four fluid substeps per sample, and repeated mechanical/control work in
|
||||
each substep. Flat6 consequently had a 1.78 mm cell and averaged 12.35 substeps
|
||||
per sample. Its native scenario had a 34.20 mm minimum cell and about one substep.
|
||||
|
||||
- Mesh each pipe by total arclength and its diameter profile. Visual knots remain
|
||||
in the editor and renderer; exact frustum averages preserve gas volume.
|
||||
- Advance shaft, ECU, cams, combustion, carburetors and pump displacement at the
|
||||
audio sample rate, matching native engine scheduling. Keep CFL stepping for
|
||||
fluid transport and pressure-operated check valves. Compile active part/gate
|
||||
lists and cache fixed restriction areas.
|
||||
- Place the importer's metering assembly farther upstream within its existing
|
||||
inlet segment, allowing a sensible outlet stub. The inlet endpoints, route
|
||||
length, diameter and total gas volume stay the same. Existing custom pipes are
|
||||
never lengthened automatically; actual short pipes still constrain CFL steps.
|
||||
- Cache local pipe vertices, normals and indices, shared primitive meshes, and
|
||||
the part-picker icon atlas. Transforms and pressure updates reuse geometry;
|
||||
route/diameter edits rebuild the affected pipe.
|
||||
|
||||
Untouched stock imports in `machines/` were compared against the previous
|
||||
importer's canonical output before replacement. User files, including
|
||||
`paralell-twin.machine.toml`, were preserved.
|
||||
|
||||
## Simulation results
|
||||
|
||||
Windows GCC RelWithDebInfo, Rusanov, preset density 20 cells/m, 44,100 Hz,
|
||||
512 warm-up samples and 32,768 measured samples, motor-driven at 3,000 RPM,
|
||||
35% pedal. Timings include audio synthesis but exclude editor rendering and
|
||||
snapshot collection. Paired native/workshop measurements use the same process;
|
||||
before/after runs have normal timing variation.
|
||||
|
||||
| Preset | Workshop before, us/sample | Workshop after | Native after | Workshop cells before / after | Substeps before / after |
|
||||
| --- | ---: | ---: | ---: | ---: | ---: |
|
||||
| Single 450 | 12.61 | 3.55 | 2.89 | 56 / 44 | 4.00 / 1.00 |
|
||||
| Twin | 16.96 | 6.89 | 6.11 | 67 / 58 | 4.00 / 1.72 |
|
||||
| Flat6 | 104.44 | 8.79 | 8.43 | 161 / 98 | 12.35 / 1.03 |
|
||||
| V8 H-pipe | 67.51 | 16.01 | 16.56 | 318 / 175 | 4.09 / 1.00 |
|
||||
|
||||
At 6,000 RPM and 70% pedal, flat6 measured 9.31 us/sample and V8 16.11.
|
||||
All benchmark cases reported zero positivity repairs and finite audio.
|
||||
See [baseline](workshop-before.txt), [after](workshop-after.csv) and
|
||||
[higher-load results](workshop-high-load.csv).
|
||||
|
||||
These are performance comparisons, not claims of identical combustion or sound.
|
||||
The workshop has explicit metering-body storage, connections and editable
|
||||
calibration; the native scenarios assemble that hardware differently. Arbitrary
|
||||
large or finely meshed custom machines can still exceed the audio budget.
|
||||
|
||||
## Rendering and playback
|
||||
|
||||
Hidden 1440 x 900 OpenGL window, 120 static frames, `glFinish`, no vsync or
|
||||
simulation: flat6 fell from 1.40 to 0.70 ms/frame; V8 from 1.77 to 0.96 ms/frame.
|
||||
This measures CPU/GPU render cost, not the displayed frame rate.
|
||||
See [before](workshop-render-before.csv) and [after](workshop-render-after.csv).
|
||||
|
||||
The combined workshop/audio check ran at 60 display frames/s with a held
|
||||
3,000 RPM shaft, 16 warm-up frames and 120 measured frames per machine:
|
||||
|
||||
| Preset | Wall seconds | Simulated seconds | Audio underruns | Buffered samples |
|
||||
| --- | ---: | ---: | ---: | ---: |
|
||||
| Flat6 | 2.006 | 2.020 | 0 | 4,096 |
|
||||
| V8 H-pipe | 2.071 | 2.082 | 0 | 4,096 |
|
||||
|
||||
Simulation time includes producer buffering and snapshot timing, so a small
|
||||
offset from wall time is expected. This is a short playback check, not a long
|
||||
session guarantee. Raw output: [playback](workshop-playback.csv).
|
||||
|
||||
## Validation and reproduction
|
||||
|
||||
All 22 CTest cases passed. Machine tests cover import length/volume preservation,
|
||||
route-knot-independent meshes, a real 5 mm pipe retaining its CFL constraint,
|
||||
explicit fuel sources, cold starting and ECU cutoff. Pump pressure agreed within
|
||||
1% between 44.1 and 88.2 kHz. Builder checks cover geometry-cache reuse and
|
||||
invalidation, pressure coloring, transforms, deletion/ID reuse and the icon atlas.
|
||||
Editor preview images were visually inspected.
|
||||
|
||||
From the repository root after `cmake --build --preset windows`:
|
||||
|
||||
```powershell
|
||||
ctest --preset windows -j 8 --output-on-failure
|
||||
.\out\build\windows-gcc\fluidsim_machine_benchmark.exe 32768 3000 0.35
|
||||
.\out\build\windows-gcc\fluidsim_machine_benchmark.exe 32768 6000 0.7
|
||||
.\out\build\windows-gcc\fluidsim_machine_render_benchmark.exe 120
|
||||
.\out\build\windows-gcc\fluidsim_machine_render_benchmark.exe 120 --play
|
||||
.\out\build\windows-gcc\fluidsim_machine_builder_tests.exe --preview out/workshop-performance-preview
|
||||
```
|
||||
@@ -0,0 +1,3 @@
|
||||
scenario,speed,frames,wall_seconds,sim_seconds,sim_per_wall,underruns,buffered
|
||||
flat6,0.01,120,1.94593,0.0196145,0.0100798,0,41
|
||||
v8-h,0.01,120,1.96952,0.0198639,0.0100857,0,41
|
||||
|
@@ -0,0 +1,3 @@
|
||||
scenario,speed,frames,wall_seconds,sim_seconds,sim_per_wall,underruns,buffered
|
||||
flat6,0.1,120,1.95923,0.198458,0.101294,0,407
|
||||
v8-h,0.1,120,1.96564,0.19737,0.10041,0,409
|
||||
|
@@ -0,0 +1,3 @@
|
||||
scenario,speed,frames,wall_seconds,sim_seconds,sim_per_wall,underruns,buffered
|
||||
flat6,1,120,1.96809,1.98531,1.00875,0,4096
|
||||
v8-h,1,120,2.0466,2.04989,1.0016,0,3872
|
||||
|
99
verification/performance/2026-10-31/workshop-instruments.md
Normal file
99
verification/performance/2026-10-31/workshop-instruments.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# Workshop instruments, slow playback and live tuning
|
||||
|
||||
Implemented on 2026-10-31. The workshop now supports eight nonintrusive instrument
|
||||
channels, simulation-time traces, CSV export, slow playback down to 1%, paused
|
||||
10 ms stepping, and live adjustment of safe component settings.
|
||||
|
||||
## Measurement model
|
||||
|
||||
Pressure, temperature and mass-flow taps read the compiled simulation. Pipe taps
|
||||
sample the cell at a chosen fraction of arclength. Lumped-part flow is net into
|
||||
the part; pipe flow is signed Start-to-End. RPM is instantaneous shaft speed;
|
||||
torque and power use the shaft model's running averages.
|
||||
|
||||
Bulk AFR/lambda use a passive conserved fuel-origin tracer. Combustion does not
|
||||
erase that tracer, so downstream instruments include fuel that has already burned.
|
||||
It travels through pipe fluxes, component ports, storage volumes and junctions.
|
||||
The extra tracer does not feed back into gas pressure, energy or mass.
|
||||
Bulk AFR = (gas mass - fuel-origin mass) / fuel-origin mass; lambda divides that
|
||||
by the channel's stoichiometric AFR reference, default 14.7. Fresh-charge AFR on a
|
||||
cylinder instead reads its remaining unburned fresh-air/fuel mass ratio.
|
||||
|
||||
Undefined readings are gaps on the graph and empty cells in CSV. Sensor heating,
|
||||
response lag, oxygen chemistry and fuel-specific combustion chemistry are not
|
||||
added by this change. Initially clean exhaust pipes can read very lean until
|
||||
purged. A probe after a collector measures the gas mixture that actually reaches
|
||||
that collector's outlet, including dilution and backflow.
|
||||
|
||||
Channels sample every 16 physics samples: 2,756.25 Hz at a 44,100 Hz simulation
|
||||
rate. The bounded capture retains 32,768 records (about 11.9 simulated seconds).
|
||||
Graph compression preserves sampled min/max envelopes and leaves undefined
|
||||
intervals disconnected. Frequencies above 1,378.125 Hz cannot be resolved by this
|
||||
capture rate. This is not an audio-rate acquisition mode.
|
||||
|
||||
## Playback and tuning
|
||||
|
||||
Slow playback resamples audio without changing the physics timestep. Producer
|
||||
batch size, prefill and target queue depth scale with playback speed. Pause stops
|
||||
both audio and physics; switching speed discards queued audio while both threads
|
||||
are stopped, preserving the machine's state. A paused step advances exactly 441
|
||||
samples (10 ms). Graph timestamps remain simulated seconds.
|
||||
|
||||
Live edits are validated and applied under the simulation mutex between batches.
|
||||
Carb calibration, ECU settings, throttle opening, cracking pressure, combustion
|
||||
settings and shaft/load settings retain gas state, fuel film, controller state and
|
||||
simulation time. Geometry, initial conditions, mesh/solver settings, cam/valve
|
||||
mechanics and compiled boundary settings remain locked. The API rejects structural
|
||||
changes even if a caller bypasses the UI. Live edits support undo/redo and saving.
|
||||
Probes/taps can change live; changing the capture schema clears the trace.
|
||||
|
||||
Machine files now use version 4 for probe definitions. Versions 1 through 3 remain
|
||||
readable; recordings are exported separately. Existing user machine files were
|
||||
not rewritten.
|
||||
|
||||
## Playback checks
|
||||
|
||||
Windows GCC RelWithDebInfo; hidden 1440 x 900 window at a 60 Hz display target;
|
||||
16 warm-up display frames, 120 measured display frames; motor-driven at 3,000 RPM.
|
||||
All eight channels were active, including cylinder pressure, downpipe AFR/lambda,
|
||||
fresh-charge AFR, mass flow and shaft gauges, with the scope visible.
|
||||
|
||||
| Machine | Requested speed | Measured simulated / wall time | Audio underruns | Buffered input samples |
|
||||
| --- | ---: | ---: | ---: | ---: |
|
||||
| Flat6 | 1.0 | 1.00875 | 0 | 4,096 |
|
||||
| V8 H-pipe | 1.0 | 1.00160 | 0 | 3,872 |
|
||||
| Flat6 | 0.1 | 0.101294 | 0 | 407 |
|
||||
| V8 H-pipe | 0.1 | 0.100410 | 0 | 409 |
|
||||
| Flat6 | 0.01 | 0.0100798 | 0 | 41 |
|
||||
| V8 H-pipe | 0.01 | 0.0100857 | 0 | 41 |
|
||||
|
||||
The small offsets reflect queue depth, snapshot timing and short-run measurement
|
||||
variation. These are short playback checks, not a sustained-session guarantee.
|
||||
Raw results: [1x](instruments-playback-1.csv), [0.1x](instruments-playback-0.1.csv),
|
||||
[0.01x](instruments-playback-0.01.csv).
|
||||
|
||||
## Verification
|
||||
|
||||
The full 22-test CTest suite passed. Targeted checks additionally cover conserved
|
||||
burned-fuel transport in all four solvers, characteristic/legacy junction mixing,
|
||||
finite exhaust AFR after combustion, lambda normalization, undefined dry readings,
|
||||
probe persistence, live tuning without state/time reset, rejected geometry edits,
|
||||
increased fuel delivery after live carb jet changes, pause/step/slow playback,
|
||||
live undo/redo, CSV units and independently selectable overlapping probe markers.
|
||||
|
||||
Builder preview mode verifies rendered UI pixels after OpenGL scene/icon rendering
|
||||
and captures pressure, downpipe lambda and live carb-tuning views. Those images
|
||||
were visually inspected. Extremely small passive tracer tails are flushed like
|
||||
the existing species tails to avoid subnormal arithmetic overhead; total gas mass
|
||||
and energy are unchanged.
|
||||
|
||||
Reproduce from the repository root:
|
||||
|
||||
```powershell
|
||||
cmake --build --preset windows
|
||||
ctest --preset windows -j 8 --output-on-failure
|
||||
.\out\build\windows-gcc\fluidsim_machine_builder_tests.exe --preview out/workshop-instruments-preview
|
||||
.\out\build\windows-gcc\fluidsim_machine_render_benchmark.exe 120 --play 1
|
||||
.\out\build\windows-gcc\fluidsim_machine_render_benchmark.exe 120 --play 0.1
|
||||
.\out\build\windows-gcc\fluidsim_machine_render_benchmark.exe 120 --play 0.01
|
||||
```
|
||||
Reference in New Issue
Block a user