mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-18 11:29:20 +02:00
- automatic couplers don't catch above the safe collision speed (#86): with crash damage on they couple at a closing speed of 15 km/h at most, a faster hit locks the coupling until the vehicles part and the collision runs its course. On the way: CollisionVelocity() read a head-on 10 + 10 km/h as 14.1 km/h (quaternions turn by half the angle), it's now taken from the touching ends; CollisionDetect() took the other vehicle's speed the wrong way round for vehicles facing each other. Head-on hits now derail sooner, at the intended limit, - a single horn lever can't sound both tones at once (eu07/maszyna#392), - a skid ends once the vehicle stops on locked wheels (eu07/maszyna#479), - electronic destination signs are blanked at the end of the timetable (eu07/maszyna#446), - horns need the air or the voltage to sound (eu07/maszyna#290, #76): HornType=[Pneumatic]|Electric and Horn3Type in Cntrl.; a pneumatic horn needs 0.2 MPa in the main reservoir (or the main pipe without one), an electric one the low voltage; the lever stays where it was put, - compressor start delay (#67): CompressorStartDelay [s] in Brake., counted from the compressor getting its power, after the engine starts say; none by default, - the channel and volume buttons of a radio without power do nothing (eu07/maszyna#429); the power check of the radio is TMoverParameters::RadioPowered(), - a lever moved smoothly sounds the positions it passes (#83). Sonar findings in the functions changed: nesting, nested conditionals, commented-out code, std::format, references to const. Unit tests: test::pair for two vehicles running into each other, test_couplers, test_horn, test_wheelslip, test_compressor, test_radio, test_gauge_positions.
423 lines
19 KiB
C++
423 lines
19 KiB
C++
#include "stdafx.h"
|
|
#include "doctest.h"
|
|
#include "vehicle.h"
|
|
#include "utilities/Globals.h"
|
|
|
|
using test::definition;
|
|
using test::vehicle;
|
|
|
|
namespace {
|
|
|
|
// the wagon from data/wagon.json with automatic couplers at both ends, which couple the given connections
|
|
definition automatic_definition(int Flag = coupling::coupler | coupling::brakehose) {
|
|
return definition::load("wagon").set("BuffCoupl", "CType", "Automatic").set("BuffCoupl", "AutomaticFlag", Flag);
|
|
}
|
|
|
|
// the wagon from data/wagon.json with automatic couplers at both ends, running at the given speed [km/h]
|
|
vehicle automatic_wagon(double Velocity, std::string const &Name) {
|
|
return vehicle{automatic_definition(), Velocity, Name};
|
|
}
|
|
|
|
// the same wagon, twice as heavy
|
|
vehicle heavy_automatic_wagon(double Velocity, std::string const &Name) {
|
|
return vehicle{automatic_definition().set("Param", "M", 2 * 42200), Velocity, Name};
|
|
}
|
|
|
|
bool derailed(vehicle &Vehicle) {
|
|
return TestFlag(Vehicle->DamageFlag, dtrain_out);
|
|
}
|
|
|
|
// runs the pair for Seconds, returns whether the vehicles were coupled at any point
|
|
bool couple_during(test::pair &Pair, double Seconds) {
|
|
auto coupled{false};
|
|
for (auto i{std::lround(Seconds / 0.01)}; i > 0; --i) {
|
|
Pair.step();
|
|
coupled = coupled || Pair.coupled();
|
|
}
|
|
return coupled;
|
|
}
|
|
|
|
// sets the crash damage setting for the test, restores it after
|
|
class crash_damage_setting {
|
|
public:
|
|
explicit crash_damage_setting(bool Enabled) : m_previous{Global.crash_damage} { Global.crash_damage = Enabled; }
|
|
~crash_damage_setting() { Global.crash_damage = m_previous; }
|
|
crash_damage_setting(crash_damage_setting const &) = delete;
|
|
crash_damage_setting &operator=(crash_damage_setting const &) = delete;
|
|
|
|
private:
|
|
bool m_previous;
|
|
};
|
|
|
|
} // namespace
|
|
|
|
// issue #86: automatic couplers used to catch at any closing speed, so the vehicles never collided nor derailed
|
|
|
|
TEST_CASE("couplers: automatic couplers catch a standing wagon hit at a walking pace") {
|
|
crash_damage_setting const crashdamage{true};
|
|
auto moving{automatic_wagon(10.0, "moving")};
|
|
auto standing{automatic_wagon(0.0, "standing")};
|
|
REQUIRE(moving->Couplers[end::front].type() == TCouplerType::Automatic);
|
|
REQUIRE(moving.speed() == doctest::Approx(10.0));
|
|
|
|
// the front of the moving wagon runs into the rear of the standing one
|
|
CHECK(moving->CollisionVelocity(end::front, standing.mover(), end::rear) == doctest::Approx(10.0));
|
|
CHECK(moving->AutomaticCouplingSafe(end::front, standing.mover(), end::rear));
|
|
CHECK(standing->AutomaticCouplingSafe(end::rear, moving.mover(), end::front));
|
|
}
|
|
|
|
TEST_CASE("couplers: automatic couplers don't catch a wagon hit too fast, the wagons collide instead") {
|
|
crash_damage_setting const crashdamage{true};
|
|
auto moving{automatic_wagon(30.0, "moving")};
|
|
auto standing{automatic_wagon(0.0, "standing")};
|
|
REQUIRE(moving.speed() == doctest::Approx(30.0));
|
|
|
|
CHECK(moving->CollisionVelocity(end::front, standing.mover(), end::rear) > TMoverParameters::SafeCollisionVelocity);
|
|
CHECK_FALSE(moving->AutomaticCouplingSafe(end::front, standing.mover(), end::rear));
|
|
CHECK_FALSE(standing->AutomaticCouplingSafe(end::rear, moving.mover(), end::front));
|
|
}
|
|
|
|
TEST_CASE("couplers: automatic couplers catch a wagon running ahead only a little slower") {
|
|
crash_damage_setting const crashdamage{true};
|
|
auto faster{automatic_wagon(60.0, "faster")};
|
|
auto slower{automatic_wagon(50.0, "slower")};
|
|
|
|
CHECK(faster->CollisionVelocity(end::front, slower.mover(), end::rear) == doctest::Approx(10.0));
|
|
CHECK(slower->CollisionVelocity(end::rear, faster.mover(), end::front) == doctest::Approx(10.0));
|
|
CHECK(faster->AutomaticCouplingSafe(end::front, slower.mover(), end::rear));
|
|
}
|
|
|
|
TEST_CASE("couplers: without crash damage automatic couplers catch at any speed") {
|
|
crash_damage_setting const crashdamage{false};
|
|
auto moving{automatic_wagon(30.0, "moving")};
|
|
auto standing{automatic_wagon(0.0, "standing")};
|
|
|
|
CHECK(moving->AutomaticCouplingSafe(end::front, standing.mover(), end::rear));
|
|
}
|
|
|
|
// the closing speed used to treat the speed of each vehicle as a vector turned by half its heading, so for vehicles
|
|
// facing each other it came out as the root of the sum of the squares of their speeds, rather than the sum
|
|
|
|
TEST_CASE("couplers: the closing speed of a rear-end collision is the difference of the speeds") {
|
|
auto faster{automatic_wagon(40.0, "faster")};
|
|
auto slower{automatic_wagon(25.0, "slower")};
|
|
|
|
// running forwards, the front of the faster wagon hits the rear of the slower one
|
|
CHECK(faster->CollisionVelocity(end::front, slower.mover(), end::rear) == doctest::Approx(15.0));
|
|
CHECK(slower->CollisionVelocity(end::rear, faster.mover(), end::front) == doctest::Approx(15.0));
|
|
// the wagons running ahead of each other are parting
|
|
CHECK(slower->CollisionVelocity(end::front, faster.mover(), end::rear) == doctest::Approx(-15.0));
|
|
|
|
// backing up, the rear of the faster wagon hits the front of the slower one
|
|
auto backingfaster{automatic_wagon(-40.0, "backing faster")};
|
|
auto backingslower{automatic_wagon(-25.0, "backing slower")};
|
|
CHECK(backingfaster->CollisionVelocity(end::rear, backingslower.mover(), end::front) == doctest::Approx(15.0));
|
|
CHECK(backingslower->CollisionVelocity(end::front, backingfaster.mover(), end::rear) == doctest::Approx(15.0));
|
|
}
|
|
|
|
TEST_CASE("couplers: the closing speed of a head-on collision is the sum of the speeds") {
|
|
crash_damage_setting const crashdamage{true};
|
|
auto first{automatic_wagon(10.0, "first")};
|
|
auto second{automatic_wagon(10.0, "second")};
|
|
|
|
// both wagons run forwards, their fronts meet
|
|
CHECK(first->CollisionVelocity(end::front, second.mover(), end::front) == doctest::Approx(20.0));
|
|
CHECK(second->CollisionVelocity(end::front, first.mover(), end::front) == doctest::Approx(20.0));
|
|
// 20 km/h is above the limit, the couplers don't catch (the old formula gave 14.1 km/h and coupled them)
|
|
CHECK(first->CollisionVelocity(end::front, second.mover(), end::front) > TMoverParameters::SafeCollisionVelocity);
|
|
CHECK_FALSE(first->AutomaticCouplingSafe(end::front, second.mover(), end::front));
|
|
CHECK_FALSE(second->AutomaticCouplingSafe(end::front, first.mover(), end::front));
|
|
|
|
// both wagons back up, their rears meet
|
|
auto firstbacking{automatic_wagon(-10.0, "first backing")};
|
|
auto secondbacking{automatic_wagon(-10.0, "second backing")};
|
|
CHECK(firstbacking->CollisionVelocity(end::rear, secondbacking.mover(), end::rear) == doctest::Approx(20.0));
|
|
|
|
// running back to back, the wagons part
|
|
CHECK(first->CollisionVelocity(end::rear, second.mover(), end::rear) == doctest::Approx(-20.0));
|
|
CHECK(first->AutomaticCouplingSafe(end::rear, second.mover(), end::rear));
|
|
|
|
// slow enough, the couplers catch
|
|
auto slowfirst{automatic_wagon(5.0, "slow first")};
|
|
auto slowsecond{automatic_wagon(5.0, "slow second")};
|
|
CHECK(slowfirst->CollisionVelocity(end::front, slowsecond.mover(), end::front) == doctest::Approx(10.0));
|
|
CHECK(slowfirst->AutomaticCouplingSafe(end::front, slowsecond.mover(), end::front));
|
|
}
|
|
|
|
TEST_CASE("couplers: the closing speed of a hit on a standing vehicle is the speed of the moving one, whichever way it faces") {
|
|
auto moving{automatic_wagon(20.0, "moving")};
|
|
auto standing{automatic_wagon(0.0, "standing")};
|
|
|
|
// the standing wagon faces away from the moving one
|
|
CHECK(moving->CollisionVelocity(end::front, standing.mover(), end::rear) == doctest::Approx(20.0));
|
|
CHECK(standing->CollisionVelocity(end::rear, moving.mover(), end::front) == doctest::Approx(20.0));
|
|
// the standing wagon faces the moving one
|
|
CHECK(moving->CollisionVelocity(end::front, standing.mover(), end::front) == doctest::Approx(20.0));
|
|
CHECK(standing->CollisionVelocity(end::front, moving.mover(), end::front) == doctest::Approx(20.0));
|
|
// the moving wagon backs up into the standing one
|
|
auto backing{automatic_wagon(-20.0, "backing")};
|
|
CHECK(backing->CollisionVelocity(end::rear, standing.mover(), end::front) == doctest::Approx(20.0));
|
|
CHECK(backing->CollisionVelocity(end::rear, standing.mover(), end::rear) == doctest::Approx(20.0));
|
|
// the moving wagon runs away from the standing one
|
|
CHECK(moving->CollisionVelocity(end::rear, standing.mover(), end::front) == doctest::Approx(-20.0));
|
|
}
|
|
|
|
// the coupling as the simulation runs it: two vehicles on a track, closing in on each other until the couplers (or
|
|
// buffers) meet, the coupler forces and the collision computed by the physics, step by step
|
|
|
|
TEST_CASE("couplers: automatic couplers catch right up to the safe closing speed") {
|
|
crash_damage_setting const crashdamage{true};
|
|
auto standing{automatic_wagon(0.0, "standing")};
|
|
|
|
auto below{automatic_wagon(14.9, "below")};
|
|
CHECK(below->CollisionVelocity(end::front, standing.mover(), end::rear) == doctest::Approx(14.9));
|
|
CHECK(below->AutomaticCouplingSafe(end::front, standing.mover(), end::rear));
|
|
|
|
auto above{automatic_wagon(15.1, "above")};
|
|
CHECK(above->CollisionVelocity(end::front, standing.mover(), end::rear) == doctest::Approx(15.1));
|
|
CHECK_FALSE(above->AutomaticCouplingSafe(end::front, standing.mover(), end::rear));
|
|
auto faster{automatic_wagon(15.5, "faster")};
|
|
CHECK_FALSE(faster->AutomaticCouplingSafe(end::front, standing.mover(), end::rear));
|
|
}
|
|
|
|
TEST_CASE("couplers: a wagon rolling slowly into a standing one couples with it") {
|
|
crash_damage_setting const crashdamage{true};
|
|
auto moving{automatic_wagon(5.0, "moving")};
|
|
auto standing{automatic_wagon(0.0, "standing")};
|
|
test::pair pair{moving, end::front, standing, end::rear, 1.0};
|
|
|
|
pair.run(3.0);
|
|
|
|
REQUIRE(pair.coupled());
|
|
CHECK(moving->Couplers[end::front].CouplingFlag == (coupling::coupler | coupling::brakehose));
|
|
CHECK(standing->Couplers[end::rear].CouplingFlag == (coupling::coupler | coupling::brakehose));
|
|
CHECK(moving->Couplers[end::front].Connected == &standing.mover());
|
|
CHECK_FALSE(derailed(moving));
|
|
CHECK_FALSE(derailed(standing));
|
|
// coupled, they run on together
|
|
pair.run(2.0);
|
|
CHECK(moving.speed() == doctest::Approx(standing.speed()).epsilon(0.05));
|
|
CHECK(pair.gap() < 0.2);
|
|
}
|
|
|
|
TEST_CASE("couplers: a wagon hitting a standing one too fast doesn't couple, nor once the hit has slowed it down") {
|
|
crash_damage_setting const crashdamage{true};
|
|
auto moving{automatic_wagon(30.0, "moving")};
|
|
auto standing{automatic_wagon(0.0, "standing")};
|
|
test::pair pair{moving, end::front, standing, end::rear, 1.0};
|
|
|
|
auto touched{false};
|
|
auto parted{false};
|
|
auto coupled{false};
|
|
auto locked{true};
|
|
for (int i = 0; i < 1000; ++i) {
|
|
pair.step();
|
|
// as far as the couplers know: the distance between them at the start of the step
|
|
auto const distance{moving->Neighbours[end::front].distance};
|
|
touched = touched || distance < 0.0;
|
|
parted = parted || (touched && distance > 0.05);
|
|
coupled = coupled || pair.coupled();
|
|
if (touched && false == parted) {
|
|
locked = locked && false == moving->Couplers[end::front].AutomaticCouplingAllowed && false == standing->Couplers[end::rear].AutomaticCouplingAllowed;
|
|
}
|
|
}
|
|
|
|
REQUIRE(touched);
|
|
CHECK_FALSE(coupled);
|
|
// the hit derailed and stopped them, the couplers next to each other, the automatic coupling locked all along
|
|
CHECK_FALSE(parted);
|
|
CHECK(locked);
|
|
CHECK(derailed(moving));
|
|
CHECK(derailed(standing));
|
|
CHECK(std::abs(moving.speed()) < 3.0);
|
|
CHECK(std::abs(standing.speed()) < 3.0);
|
|
CHECK_FALSE(couple_during(pair, 5.0));
|
|
}
|
|
|
|
TEST_CASE("couplers: the automatic coupling locked by a hit is unlocked once the vehicles part") {
|
|
crash_damage_setting const crashdamage{true};
|
|
auto moving{automatic_wagon(3.0, "moving")};
|
|
auto standing{automatic_wagon(0.0, "standing")};
|
|
// as a hit too fast or manual uncoupling leaves them
|
|
moving->Couplers[end::front].AutomaticCouplingAllowed = false;
|
|
standing->Couplers[end::rear].AutomaticCouplingAllowed = false;
|
|
|
|
SUBCASE("parted by more than 5 cm, they couple on the next approach") {
|
|
test::pair pair{moving, end::front, standing, end::rear, 0.5};
|
|
pair.step();
|
|
CHECK(moving->Couplers[end::front].AutomaticCouplingAllowed);
|
|
CHECK(couple_during(pair, 3.0));
|
|
}
|
|
SUBCASE("kept together, they don't") {
|
|
test::pair pair{moving, end::front, standing, end::rear, 0.0};
|
|
auto coupled{false};
|
|
auto parted{false};
|
|
for (int i = 0; i < 300 && false == parted; ++i) {
|
|
pair.step();
|
|
parted = pair.gap() > 0.05;
|
|
coupled = coupled || (false == parted && pair.coupled());
|
|
}
|
|
CHECK_FALSE(coupled);
|
|
}
|
|
}
|
|
|
|
// the couplers refuse a hit by the closing speed when they meet, the derail check (CollisionDetect()) takes the one
|
|
// left when the buffers are pressed in all the way, after their springs have slowed the hit down: for the wagons here
|
|
// by about 7 km/h. so a hit a little over the safe closing speed only bounces the vehicles apart
|
|
|
|
TEST_CASE("couplers: a hit a little too fast for the couplers bounces the vehicles apart, uncoupled and on the rails") {
|
|
crash_damage_setting const crashdamage{true};
|
|
auto moving{automatic_wagon(20.0, "moving")};
|
|
auto standing{automatic_wagon(0.0, "standing")};
|
|
test::pair pair{moving, end::front, standing, end::rear, 1.0};
|
|
|
|
CHECK_FALSE(couple_during(pair, 3.0));
|
|
CHECK_FALSE(derailed(moving));
|
|
CHECK_FALSE(derailed(standing));
|
|
CHECK(pair.gap() > 0.5);
|
|
CHECK(standing.speed() > moving.speed());
|
|
}
|
|
|
|
TEST_CASE("couplers: a hit too fast for the couplers derails the vehicles over the limit adjusted for their mass ratio") {
|
|
crash_damage_setting const crashdamage{true};
|
|
|
|
SUBCASE("equal masses: both derail") {
|
|
auto moving{automatic_wagon(30.0, "moving")};
|
|
auto standing{automatic_wagon(0.0, "standing")};
|
|
test::pair pair{moving, end::front, standing, end::rear, 1.0};
|
|
CHECK_FALSE(couple_during(pair, 5.0));
|
|
CHECK(derailed(moving));
|
|
CHECK(derailed(standing));
|
|
}
|
|
SUBCASE("half the mass: between the safe closing speed and twice that, only the lighter one derails") {
|
|
auto light{automatic_wagon(27.0, "light")};
|
|
auto heavy{heavy_automatic_wagon(0.0, "heavy")};
|
|
test::pair pair{light, end::front, heavy, end::rear, 1.0};
|
|
CHECK_FALSE(couple_during(pair, 5.0));
|
|
CHECK(derailed(light));
|
|
CHECK_FALSE(derailed(heavy));
|
|
}
|
|
SUBCASE("half the mass: above twice the safe closing speed both derail") {
|
|
auto light{automatic_wagon(45.0, "light")};
|
|
auto heavy{heavy_automatic_wagon(0.0, "heavy")};
|
|
test::pair pair{light, end::front, heavy, end::rear, 1.0};
|
|
CHECK_FALSE(couple_during(pair, 5.0));
|
|
CHECK(derailed(light));
|
|
CHECK(derailed(heavy));
|
|
}
|
|
SUBCASE("half the mass: below the safe closing speed the couplers catch, nothing derails") {
|
|
auto light{automatic_wagon(12.0, "light")};
|
|
auto heavy{heavy_automatic_wagon(0.0, "heavy")};
|
|
test::pair pair{light, end::front, heavy, end::rear, 1.0};
|
|
CHECK(couple_during(pair, 5.0));
|
|
CHECK_FALSE(derailed(light));
|
|
CHECK_FALSE(derailed(heavy));
|
|
}
|
|
}
|
|
|
|
TEST_CASE("couplers: wagons running head-on into each other couple only up to the safe closing speed") {
|
|
crash_damage_setting const crashdamage{true};
|
|
|
|
SUBCASE("7 + 7 km/h, the couplers catch") {
|
|
auto first{automatic_wagon(7.0, "first")};
|
|
auto second{automatic_wagon(7.0, "second")};
|
|
test::pair pair{first, end::front, second, end::front, 1.0};
|
|
CHECK(couple_during(pair, 3.0));
|
|
CHECK_FALSE(derailed(first));
|
|
CHECK_FALSE(derailed(second));
|
|
}
|
|
SUBCASE("8 + 8 km/h, the wagons bounce apart") {
|
|
auto first{automatic_wagon(8.0, "first")};
|
|
auto second{automatic_wagon(8.0, "second")};
|
|
test::pair pair{first, end::front, second, end::front, 1.0};
|
|
CHECK_FALSE(couple_during(pair, 3.0));
|
|
CHECK_FALSE(derailed(first));
|
|
CHECK_FALSE(derailed(second));
|
|
// both backwards, away from each other
|
|
CHECK(first.speed() < 0.0);
|
|
CHECK(second.speed() < 0.0);
|
|
}
|
|
SUBCASE("backing up, 8 + 8 km/h, the wagons bounce apart") {
|
|
auto first{automatic_wagon(-8.0, "first")};
|
|
auto second{automatic_wagon(-8.0, "second")};
|
|
test::pair pair{first, end::rear, second, end::rear, 1.0};
|
|
CHECK_FALSE(couple_during(pair, 3.0));
|
|
CHECK(first.speed() > 0.0);
|
|
CHECK(second.speed() > 0.0);
|
|
}
|
|
SUBCASE("15 + 15 km/h, both derail") {
|
|
auto first{automatic_wagon(15.0, "first")};
|
|
auto second{automatic_wagon(15.0, "second")};
|
|
test::pair pair{first, end::front, second, end::front, 1.0};
|
|
CHECK_FALSE(couple_during(pair, 5.0));
|
|
CHECK(derailed(first));
|
|
CHECK(derailed(second));
|
|
}
|
|
}
|
|
|
|
// the collision used to take the speed of a vehicle facing the other way as if it faced the same way, so a wagon
|
|
// pushed away by the buffers of the vehicle hitting it head-on counted as running into it: the hit slowed it down,
|
|
// and the hitter bounced back as from a wall
|
|
|
|
TEST_CASE("couplers: a wagon hit head-on runs off the same as one hit from behind") {
|
|
// without automatic couplers or crash damage, the collision alone
|
|
crash_damage_setting const crashdamage{false};
|
|
auto speeds_after_hit = [](int StruckEnd) {
|
|
auto moving{vehicle{definition::load("wagon"), 20.0, "moving"}};
|
|
auto struck{vehicle{definition::load("wagon"), 0.0, "struck"}};
|
|
test::pair pair{moving, end::front, struck, StruckEnd, 0.5};
|
|
auto touched{false};
|
|
for (int i = 0; i < 300 && false == (touched && pair.gap() > 0.3); ++i) {
|
|
pair.step();
|
|
touched = touched || pair.gap() < 0.0;
|
|
}
|
|
REQUIRE(touched);
|
|
REQUIRE(pair.gap() > 0.3);
|
|
REQUIRE_FALSE(pair.coupled());
|
|
return std::make_pair(moving.speed(), struck.speed());
|
|
};
|
|
|
|
auto const [hitterfrombehind, struckfrombehind]{speeds_after_hit(end::rear)};
|
|
auto const [hitterheadon, struckheadon]{speeds_after_hit(end::front)};
|
|
|
|
// hit from behind, the struck wagon runs off forwards, faster than the hitter
|
|
CHECK(struckfrombehind > 10.0);
|
|
CHECK(hitterfrombehind < struckfrombehind);
|
|
// hit head-on, it runs off backwards, as fast
|
|
CHECK(struckheadon == doctest::Approx(-struckfrombehind).epsilon(0.02));
|
|
CHECK(hitterheadon == doctest::Approx(hitterfrombehind).epsilon(0.05));
|
|
}
|
|
|
|
// the other conditions of automatic coupling
|
|
|
|
TEST_CASE("couplers: an automatic coupler doesn't catch a coupler of another type") {
|
|
crash_damage_setting const crashdamage{true};
|
|
auto moving{automatic_wagon(5.0, "moving")};
|
|
auto standing{vehicle{definition::load("wagon"), 0.0, "standing"}};
|
|
REQUIRE(standing->Couplers[end::rear].type() == TCouplerType::Screw);
|
|
test::pair pair{moving, end::front, standing, end::rear, 1.0};
|
|
|
|
CHECK_FALSE(couple_during(pair, 3.0));
|
|
}
|
|
|
|
TEST_CASE("couplers: automatic couplers of different control systems couple without the control connection") {
|
|
crash_damage_setting const crashdamage{true};
|
|
auto const flag{coupling::coupler | coupling::brakehose | coupling::control};
|
|
auto moving{vehicle{automatic_definition(flag).set("BuffCoupl", "ControlType", "first"), 5.0, "moving"}};
|
|
|
|
SUBCASE("the same control system") {
|
|
auto standing{vehicle{automatic_definition(flag).set("BuffCoupl", "ControlType", "first"), 0.0, "standing"}};
|
|
REQUIRE(standing->Couplers[end::rear].control_type == "first");
|
|
test::pair pair{moving, end::front, standing, end::rear, 1.0};
|
|
REQUIRE(couple_during(pair, 3.0));
|
|
CHECK(pair.coupling() == flag);
|
|
}
|
|
SUBCASE("a different one") {
|
|
auto standing{vehicle{automatic_definition(flag).set("BuffCoupl", "ControlType", "second"), 0.0, "standing"}};
|
|
REQUIRE(standing->Couplers[end::rear].control_type == "second");
|
|
test::pair pair{moving, end::front, standing, end::rear, 1.0};
|
|
REQUIRE(couple_during(pair, 3.0));
|
|
CHECK(pair.coupling() == (coupling::coupler | coupling::brakehose));
|
|
}
|
|
}
|