From 2f96dfe76734fe69a79dfb04aae9350df4d76972 Mon Sep 17 00:00:00 2001 From: Hirek193 Date: Fri, 23 Oct 2026 19:30:21 +0200 Subject: [PATCH] perf(physics): air flowing along a pipe wakes the physics of a coupled vehicle only when it changes its pressure by more than physics.pipewake (0.001 bar), not with any trickle of it --- McZapkie/Mover.cpp | 30 ++++++++++++++++++++++-------- McZapkie/hamulce.h | 8 ++++++++ application/driveruipanels.cpp | 1 + utilities/Globals.cpp | 7 +++++++ utilities/Globals.h | 1 + 5 files changed, 39 insertions(+), 8 deletions(-) diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 59e1aa0a..948de30c 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -4720,6 +4720,20 @@ void TMoverParameters::UpdatePipePressure(double dt) // Q: 20160713 // Aktualizacja ciśnienia w przewodzie zasilającym // ************************************************************************************************* +namespace +{ +// whether the air flowing to a coupled vehicle along a pipe wakes its physics: any flow did, but a vehicle standing next to one +// whose physics is on gets a trickle of it all the time, as their pressures settle, and each wake kept it on for 5 s. with +// Global.physics_pipewake only a flow which brings its pressure, with what has flown in while it slept, that much away from the +// pressure of the vehicle the air comes from +bool pipe_wakes(double const Flow, double const Pressure, TReservoir const &Pipe) +{ + if (Flow * Flow <= 0.00000000000001) + return false; + return (Global.physics_pipewake <= 0.f) || (std::abs(Pressure - Pipe.P_pending()) > Global.physics_pipewake); +} +} // namespace + void TMoverParameters::UpdateScndPipePressure(double dt) { if (ScndPipePress > 1.0) @@ -4744,18 +4758,18 @@ void TMoverParameters::UpdateScndPipePressure(double dt) { c = Couplers[0].Connected; // skrot dv1 = 0.5 * dt * PF(ScndPipePress, c->ScndPipePress, Spz * 0.75); - if (dv1 * dv1 > 0.00000000000001) - c->switch_physics(true, wake_cause::scndpipe); c->Pipe2->Flow(-dv1); + if (pipe_wakes(dv1, ScndPipePress, *c->Pipe2)) + c->switch_physics(true, wake_cause::scndpipe); } // sprzeg 2 if (Couplers[1].Connected != nullptr && TestFlag(Couplers[1].CouplingFlag, ctrain_scndpneumatic)) { c = Couplers[1].Connected; // skrot dv2 = 0.5 * dt * PF(ScndPipePress, c->ScndPipePress, Spz * 0.75); - if (dv2 * dv2 > 0.00000000000001) - c->switch_physics(true, wake_cause::scndpipe); c->Pipe2->Flow(-dv2); + if (pipe_wakes(dv2, ScndPipePress, *c->Pipe2)) + c->switch_physics(true, wake_cause::scndpipe); } if (Couplers[1].Connected != nullptr && Couplers[0].Connected != nullptr && TestFlag(Couplers[0].CouplingFlag, ctrain_scndpneumatic) && TestFlag(Couplers[1].CouplingFlag, ctrain_scndpneumatic)) { @@ -4832,18 +4846,18 @@ double TMoverParameters::GetDVc(double dt) { //*0.85 c = Couplers[0].Connected; // skrot //0.08 //e/D * L/D = e/D^2 * L dv1 = 0.5 * dt * PF(PipePress, c->PipePress, Spg / (1.0 + 0.015 / Spg * Dim.L)); - if (dv1 * dv1 > 0.00000000000001) - c->switch_physics(true, wake_cause::mainpipe); c->Pipe->Flow(-dv1); + if (pipe_wakes(dv1, PipePress, *c->Pipe)) + c->switch_physics(true, wake_cause::mainpipe); } // sprzeg 2 if (Couplers[1].Connected != nullptr && TestFlag(Couplers[1].CouplingFlag, ctrain_pneumatic)) { c = Couplers[1].Connected; // skrot dv2 = 0.5 * dt * PF(PipePress, c->PipePress, Spg / (1.0 + 0.015 / Spg * Dim.L)); - if (dv2 * dv2 > 0.00000000000001) - c->switch_physics(true, wake_cause::mainpipe); c->Pipe->Flow(-dv2); + if (pipe_wakes(dv2, PipePress, *c->Pipe)) + c->switch_physics(true, wake_cause::mainpipe); } // if ((Couplers[1].Connected != NULL) && (Couplers[0].Connected != NULL)) // if ((TestFlag(Couplers[0].CouplingFlag, ctrain_pneumatic)) && diff --git a/McZapkie/hamulce.h b/McZapkie/hamulce.h index 3074a2e7..aa5877ac 100644 --- a/McZapkie/hamulce.h +++ b/McZapkie/hamulce.h @@ -265,6 +265,14 @@ class TReservoir /// Volume change to add to dVol. void Flow(double dv); /// + /// Pressure the reservoir will have once the flow accumulated for the step is applied (Vol + dVol) / Cap, in bar. + /// Of a vehicle whose physics sleeps, the flow keeps accumulating, as nothing applies it. + /// + double P_pending() const + { + return std::max(0.0, Vol + dVol) / Cap; + } + /// /// Applies the accumulated flow (dVol) to the volume and resets dVol. /// Volume is clamped to be non-negative. /// diff --git a/application/driveruipanels.cpp b/application/driveruipanels.cpp index 94195a90..b9a5df72 100644 --- a/application/driveruipanels.cpp +++ b/application/driveruipanels.cpp @@ -1516,6 +1516,7 @@ debug_panel::render_section_renderer() { // the physics of the vehicles, timed in the section of the main loop ImGui::Checkbox( "let vehicles standing still and held by their brakes sleep (physics.sleepheld)", &Global.physics_sleepheld ); ImGui::Checkbox( "one step of the physics in a frame for road vehicles farther than 1 km (physics.roadlod)", &Global.physics_roadlod ); + ImGui::SliderFloat( "bar: change of the pressure in a pipe which wakes the physics of a vehicle, 0 any (physics.pipewake)", &Global.physics_pipewake, 0.f, 0.05f, "%.4f" ); return true; } diff --git a/utilities/Globals.cpp b/utilities/Globals.cpp index f0350675..ef73f0da 100644 --- a/utilities/Globals.cpp +++ b/utilities/Globals.cpp @@ -491,6 +491,12 @@ bool global_settings::ConfigParseSimulation(cParser& Parser, const std::string& return true; } + if (token == "physics.pipewake") + { + ParseOne(Parser, physics_pipewake); + return true; + } + if (token == "enabletraction") { ParseOne(Parser, bEnableTraction); @@ -1901,6 +1907,7 @@ global_settings::export_as_text( std::ostream &Output ) const { export_as_text( Output, "fullphysics", FullPhysics ); export_as_text( Output, "physics.sleepheld", physics_sleepheld ); export_as_text( Output, "physics.roadlod", physics_roadlod ); + export_as_text( Output, "physics.pipewake", physics_pipewake ); export_as_text( Output, "debuglog", iWriteLogEnabled ); export_as_text( Output, "multiplelogs", MultipleLogs ); export_as_text( Output, "showsystemconsole", ShowSystemConsole ); diff --git a/utilities/Globals.h b/utilities/Globals.h index 4bade9c6..d8427b27 100644 --- a/utilities/Globals.h +++ b/utilities/Globals.h @@ -116,6 +116,7 @@ struct global_settings { bool FullPhysics{ true }; // full calculations performed for each simulation step bool physics_sleepheld{ true }; // vehicles standing still and held by their brakes let their physics sleep, see TMoverParameters::accelerating() bool physics_roadlod{ true }; // road vehicles far from the camera go by one step of the physics in a frame, see vehicle_table::update() + float physics_pipewake{ 0.001f }; // bar: air flowing along a pipe wakes the physics of a vehicle when it changes its pressure by more than this. 0: any flow does bool bnewAirCouplers{ true }; float fMoveLight{ 0.f }; // numer dnia w roku albo -1 bool FakeLight{ false }; // toggle between fixed and dynamic daylight