From 52aa9b16cf3d67eae828ef3573f05523b88c5e81 Mon Sep 17 00:00:00 2001 From: jerrrrycho Date: Mon, 19 Oct 2026 01:09:35 +0200 Subject: [PATCH] fix: coupler force of vehicles facing each other taken back along the other vehicle's axis CForce runs along the axis of its own vehicle, so the force the other vehicle takes back on its coupler of the pair is turned around once more when the vehicles face each other (-CF * DirPatch()), as that vehicle computes it itself. Tests: the coupler forces of the pair facing each other and facing the same way. --- McZapkie/Mover.cpp | 5 +++-- tests/unit/test_couplers.cpp | 34 +++++++++++++++++++++++++--------- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 8840ef33..cb17e30a 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -5463,8 +5463,9 @@ double TMoverParameters::CouplerForce(int const End, double dt) if (thiscoupler.CouplingFlag != coupling::faux) { - // uzgadnianie prawa Newtona, on the coupler of the other vehicle this one is coupled with - othervehicle->Couplers[otherend].CForce = -CF; + // uzgadnianie prawa Newtona, on the coupler of the other vehicle this one is coupled with, along that vehicle's + // axis: turned around once more when the vehicles face each other + othervehicle->Couplers[otherend].CForce = -CF * DirPatch(End, otherend); } return CF; diff --git a/tests/unit/test_couplers.cpp b/tests/unit/test_couplers.cpp index 108b4f59..8787a419 100644 --- a/tests/unit/test_couplers.cpp +++ b/tests/unit/test_couplers.cpp @@ -427,16 +427,32 @@ TEST_CASE("couplers: automatic couplers of different control systems couple with TEST_CASE("couplers: the coupler force of vehicles facing each other lands on the couplers holding them") { // the force a vehicle takes from its coupler, the other one takes back on its own coupler of the pair, whichever - // way the vehicles face; it used to land on the far end of the other vehicle when they faced each other + // way the vehicles face; it used to land on the far end of the other vehicle when they faced each other. + // CForce runs along the axis of its own vehicle, so the two forces of the pair are opposite along the track: of + // opposite signs for vehicles facing the same way, of the same sign for vehicles facing each other auto first{automatic_wagon(5.0, "first")}; auto second{automatic_wagon(0.0, "second")}; - test::pair pair{first, end::front, second, end::front, 1.0}; - pair.run(5.0); - REQUIRE(pair.coupled()); - pair.step(); - REQUIRE(second->Couplers[end::front].CForce != 0.0); - CHECK(first->Couplers[end::front].CForce == doctest::Approx(-second->Couplers[end::front].CForce)); - CHECK(first->Couplers[end::rear].CForce == 0.0); // nothing there - CHECK(second->Couplers[end::rear].CForce == 0.0); + SUBCASE("facing each other") { + test::pair pair{first, end::front, second, end::front, 1.0}; + pair.run(5.0); + REQUIRE(pair.coupled()); + + pair.step(); + REQUIRE(second->Couplers[end::front].CForce != 0.0); + CHECK(first->Couplers[end::front].CForce == doctest::Approx(second->Couplers[end::front].CForce)); + CHECK(first->Couplers[end::rear].CForce == 0.0); // nothing there + CHECK(second->Couplers[end::rear].CForce == 0.0); + } + SUBCASE("facing the same way") { + test::pair pair{first, end::front, second, end::rear, 1.0}; + pair.run(5.0); + REQUIRE(pair.coupled()); + + pair.step(); + REQUIRE(second->Couplers[end::rear].CForce != 0.0); + CHECK(first->Couplers[end::front].CForce == doctest::Approx(-second->Couplers[end::rear].CForce)); + CHECK(first->Couplers[end::rear].CForce == 0.0); + CHECK(second->Couplers[end::front].CForce == 0.0); + } }