From 6aed9ec5bd38d942a400a7085f044a28602b3c2a Mon Sep 17 00:00:00 2001 From: maj00r Date: Sat, 31 Oct 2026 18:25:16 +0100 Subject: [PATCH] feat(track): vertical unevenness comes near its limit more often, with longer buckles too Fewer short waves: at uneven 18 the humps over 12.6 mm on the 10 m chord go from 28 to 38 per km, with the peak still at 18 mm. Waves of 47-83 m join them. They hardly count on that chord, the body rises and falls on them. The documentation tells how far unevenness goes before a pantograph can't keep up. A wire rising fast enough trips the main breaker on a straight track too: it does at tor0290 on Baltyk, over about 46 km/h. --- tests/unit/test_track_uneven.cpp | 10 +++++++--- track_uneven_doc.md | 6 ++++-- world/TrackUneven.h | 8 +++++--- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/tests/unit/test_track_uneven.cpp b/tests/unit/test_track_uneven.cpp index 195a2d72..afea0b67 100644 --- a/tests/unit/test_track_uneven.cpp +++ b/tests/unit/test_track_uneven.cpp @@ -91,7 +91,7 @@ TEST_CASE("uneven track: measures as the Id-14 limits for its value") CHECK(wander == doctest::Approx(10.0).epsilon(0.2)); CHECK(level == doctest::Approx(20.0).epsilon(0.1)); CHECK(j == doctest::Approx(5.3).epsilon(0.2)); - CHECK(away < 25.0); // appendix 1a: 15 mm off the survey marks + CHECK(away < 40.0); // the long waves go past the 15 mm off the survey marks of appendix 1a } TEST_CASE("uneven track: a place strays the same every time") @@ -100,7 +100,7 @@ TEST_CASE("uneven track: a place strays the same every time") glm::dvec3 const place{1234.5, 0.0, -678.9}; auto const stray{track_uneven::field(place)}; CHECK(stray.x == doctest::Approx(0.309777548158).epsilon(1e-9)); - CHECK(stray.y == doctest::Approx(-0.295557487607).epsilon(1e-9)); + CHECK(stray.y == doctest::Approx(0.311350299745).epsilon(1e-9)); CHECK(stray.z == doctest::Approx(-0.328429734019).epsilon(1e-9)); CHECK(track_uneven::level(place, {1.0, 0.0, 0.0}) == doctest::Approx(0.53 * -0.178598957983).epsilon(1e-9)); CHECK(track_uneven::level(place, {0.0, 0.0, 1.0}) == doctest::Approx(0.53 * -0.868291889902).epsilon(1e-9)); @@ -127,13 +127,17 @@ TEST_CASE("uneven track: tracks laid towards each other meet at one cant") TEST_CASE("uneven track: the field stays within its bound") { auto most{0.0}; + auto highest{0.0}; for (int i = 0; i < 20000; ++i) { auto const stray{track_uneven::field({i * 3.7 - 30000.0, 0.0, i * -2.9 + 41000.0})}; - most = std::max({most, std::abs(stray.x), std::abs(stray.y), std::abs(stray.z)}); + most = std::max({most, std::abs(stray.x), std::abs(stray.z)}); + highest = std::max(highest, std::abs(stray.y)); } CHECK(most <= 1.0); CHECK(most > 0.5); + CHECK(highest <= 1.69); + CHECK(highest > 0.5); } TEST_CASE("uneven track: the value along a track meets its neighbours exactly") diff --git a/track_uneven_doc.md b/track_uneven_doc.md index ebced90e..aca9ca32 100644 --- a/track_uneven_doc.md +++ b/track_uneven_doc.md @@ -44,14 +44,14 @@ Tor z `uneven 18` mierzy się tak (`tests/unit/test_track_uneven.cpp`), w nawias |---------------------------|---------|---------| | nierówności pionowe | 18 mm | 18 mm | | nierówności poziome | 19 mm | 17 mm | -| wichrowatość na bazie 5 m | 17 mm | 16 mm | +| wichrowatość na bazie 5 m | 15 mm | 16 mm | | szerokość toru | ±10 mm | +10/-8 mm | | przechyłka | 20 mm | 20 mm | | wskaźnik J | 6,1 | 5,3 | ## Jak to działa -Nierówność to pole przesunięć zależne od położenia na mapie, złożone z fal o długości 5-42 m. Nie ma w nim losowania: to samo miejsce wygina się tak samo przy każdym uruchomieniu. Przesunięty tor dostaje fale z nowego miejsca. +Nierówność to pole przesunięć zależne od położenia na mapie, złożone z fal o długości 5-42 m. W pionie krótkich fal jest mniej, żeby częściej dochodziły blisko wartości szczytowej, a do tego są fale 47-83 m: na cięciwie 10 m prawie się nie liczą, pudło unosi się na nich i opada, a pantograf za nimi nadąża. Nie ma w nim losowania: to samo miejsce wygina się tak samo przy każdym uruchomieniu. Przesunięty tor dostaje fale z nowego miejsca. Każda składowa łączy się osobno: @@ -64,6 +64,8 @@ Za nierównością idą szyny, podsypka, `sleepermodel`, osie, przechył pudła Nie idą za nią modele z includów (np. napędy i podkłady rozjazdów), teren ani sieć trakcyjna, więc przy dużych wartościach szyna rozjeżdża się z takim modelem o kilka centymetrów. +Pantograf podnosi się z szybkością ciśnienia, ok. 0,14 m/s, a szczelina do drutu większa niż 1 cm odcina napięcie i wybija wyłącznik szybki. Nierówność dokłada się do tego przy dużej prędkości. Na torach Bałtyku symulacja daje szczelinę 0,6 cm, gdy składowa w pionie razy prędkość w km/h wynosi 925, czyli np. 8 mm przy 120 km/h, 13 mm przy 70 km/h i 23 mm przy 40 km/h. Wartości z tabeli Id-14 są od tego większe. Sam drut też to potrafi: na Bałtyku przy `tor0290` wznosi się o ok. 1%, więc pantograf nadąża tam do ok. 46 km/h, a powyżej wyłącznik wybija także na prostym torze. + Fizyka bierze promień łuku i pochylenie z projektu, więc nierówności nie zmieniają tych wartości, a do wykolejeń dokładają tylko przechyłkę, ok. 0,06 m/s² przy `uneven 18` wobec progu ok. 3,2 m/s². ## Wydajność diff --git a/world/TrackUneven.h b/world/TrackUneven.h index 5974f42d..9031c6ca 100644 --- a/world/TrackUneven.h +++ b/world/TrackUneven.h @@ -16,7 +16,7 @@ http://mozilla.org/MPL/2.0/. #include // Track unevenness: a displacement field over the plan of the scenery, so everything at one place moves together: joined tracks, the -// paths of a switch, sleepers, axles. Waves 5-42 m long, shares after the German track spectrum with the long waves cut down. +// paths of a switch, sleepers, axles. Waves 5-42 m long, shares after the German track spectrum with the long waves cut down; up and down to 83 m. // The "uneven" value is the peak deviation of a rail on a 10 m chord, as in PLK Id-14 appendix 1; see test_track_uneven.cpp. namespace track_uneven { @@ -61,7 +61,9 @@ wave_set make_waves( double const Turn, std::array const & inline constexpr std::array wave_lengths { 5.3, 7.1, 9.7, 13.1, 17.9, 23.9, 31.7, 41.9 }; inline constexpr std::array wave_shares { 0.0721, 0.0997, 0.1344, 0.1703, 0.1549, 0.1386, 0.1226, 0.1074 }; -inline wave_set<8> const up_waves { make_waves( 0.0, wave_lengths, wave_shares ) }; +// fewer short ones than sideways: the rails come near the limit in the vertical more often, with the peak still at it. +// The long ones hardly count on the 10 m chord: the body rises and falls on them, slowly enough for a pantograph to keep up +inline wave_set<8> const up_waves { make_waves<8>( 0.0, { 8.3, 11.9, 16.7, 23.9, 37.1, 47.3, 61.9, 83.3 }, { 0.14, 0.19, 0.22, 0.22, 0.23, 0.23, 0.23, 0.23 } ) }; inline wave_set<8> const x_waves { make_waves( 1.1, wave_lengths, wave_shares ) }; inline wave_set<8> const z_waves { make_waves( 2.3, wave_lengths, wave_shares ) }; // the tilt along each axis of the plan. Long waves only: with the short ones the cross level reaching its limit would break the limit of twist @@ -78,7 +80,7 @@ double sum( wave_set const &Waves, glm::dvec3 const &Point ) { return total; } -// displacement at the point for an amplitude of 1, each axis within +-1 +// displacement at the point for an amplitude of 1, sideways within +-1, up and down within +-1.69 inline glm::dvec3 field( glm::dvec3 const &Point ) { return { sum( x_waves, Point ), sum( up_waves, Point ), sum( z_waves, Point ) };