import { describe, expect, it } from 'vitest'; import { engstellenFolgen, umlaufBeiFreigabe } from '@/domain/rilsa/engstelle'; import { ANLAGENART_GRENZEN, RILSA_DEFAULTS } from '@/domain/rilsa/constants'; /* * Die Zahlen, mit denen die Obergrenze der Umlaufzeit fuer eine Arbeitsstelle * begruendet wird. * * Sie stehen im PDF-Ausdruck, in den Unterlagen und im Pruefstand-Kommentar * von ANLAGENART_GRENZEN - und sie waren an allen diesen Stellen falsch: * 125 s Zwischenzeit und 290 s Umlauf bei 1000 m Engstelle. * Aus den Kennwerten dieses Programms folgen 104 s und 248 s. Die 125 s * setzten eine Raeumgeschwindigkeit von 8,2 m/s voraus, die es nirgends gibt. * * Eine Zahl, die in eine Planunterlage gedruckt wird und sich aus keiner * Rechnung des Programms ergibt, ist als Begruendung wertlos: Ein Pruefer, der * sie nachrechnet, findet etwas anderes. Der Ausdruck rechnet sie deshalb * inzwischen; dieser Test haelt die Rechnung fest. */ describe('Folgen einer Engstellenlaenge', () => { it('rechnet die Zwischenzeit nach dem Engstellenverfahren der RiLSA', () => { /* * UMGESTELLT MIT 5.27.0 auf RiLSA 2015, Abschnitt 5.2.2: * tz = tue + sr/Vr * 3,6 mit tue = 4 s, sr = Abstand der Haltlinien OHNE * Fahrzeuglaenge und Vr = 40 km/h bei zulaessig 50 km/h. * * 4 + 1000/40 * 3,6 = 4 + 90 = 94 s. Bis 5.26.0 rechnete das Programm * hier die Knotenpunktformel: (1000 + 6)/10,0 + 3 = 103,6 -> 104 s. */ const laenge = 1000; expect(engstellenFolgen(laenge, 50).zwischenzeit).toBe(94); // Die Fahrzeuglaenge geht NICHT mehr ein - das ist der halbe Unterschied. expect(RILSA_DEFAULTS.vehicleLength.pkw).toBe(6); }); it('waechst geradlinig mit der Laenge', () => { // Je 100 m 9 s: Vr = 40 km/h. Bis 5.26.0 waren es 10 s je 100 m. expect(engstellenFolgen(100, 50).zwischenzeit).toBe(13); expect(engstellenFolgen(400, 50).zwischenzeit).toBe(40); expect(engstellenFolgen(700, 50).zwischenzeit).toBe(67); }); it('haengt die Raeumgeschwindigkeit an der zulaessigen Hoechstgeschwindigkeit', () => { /* * Der zweite Unterschied zum Knotenpunkt, und er dreht die Richtung um: * Bei 40 km/h sind es 30 km/h Raeumgeschwindigkeit und damit WENIGER als * die 10 m/s der Knotenpunktrechnung - die Zwischenzeit faellt laenger * aus als bis 5.26.0. */ // 4 + 200/50 * 3,6 = 18,4 -> 19 s expect(engstellenFolgen(200, 60).zwischenzeit).toBe(19); // 4 + 200/40 * 3,6 = 22 s expect(engstellenFolgen(200, 50).zwischenzeit).toBe(22); // 4 + 200/30 * 3,6 = 28 s; die Knotenpunktrechnung ergab 3 + 206/10 = 24 s. expect(engstellenFolgen(200, 40).zwischenzeit).toBe(28); // Unterhalb der Staffel bleibt es bei der kleinsten Stufe. expect(engstellenFolgen(200, 30).zwischenzeit).toBe(28); }); it('nennt als Umlauf die Untergrenze mit kuerzest zulaessiger Freigabe', () => { // 2 x 94 s Zwischenzeit + 2 x 5 s Mindestfreigabe = 198 s. expect(engstellenFolgen(1000, 50).umlaufzeit).toBe(198); expect(engstellenFolgen(400, 50).umlaufzeit).toBe(90); }); it('rechnet den Umlauf bei einer brauchbaren Freigabezeit', () => { // Das ist die Zahl, mit der die Obergrenze begruendet wird: 20 s Freigabe // je Richtung ist der Fall, den man tatsaechlich anordnen wuerde. expect(umlaufBeiFreigabe(1000, 50, 20)).toBe(228); expect(umlaufBeiFreigabe(400, 50, 20)).toBe(120); }); it('bleibt mit der groessten Engstelle unter der Obergrenze der Anlagenart', () => { // Die Herleitung traegt nur, solange sie das tut - sonst waere die // Obergrenze nicht aus den uebrigen Schranken abgeleitet, sondern // gegriffen. const grenzen = ANLAGENART_GRENZEN.einstreifig; expect(umlaufBeiFreigabe(grenzen.maxClearingDistance, 50, 20)).toBeLessThanOrEqual( grenzen.cycleTime.max, ); }); it('warnt, sobald die Wartezeit die Schranke der Anlagenart erreicht', () => { const grenzen = ANLAGENART_GRENZEN.einstreifig; expect(engstellenFolgen(120, 50).stufe).toBe('hinweis'); const lang = engstellenFolgen(grenzen.maxClearingDistance, 50); expect(lang.wartezeit).toBeGreaterThanOrEqual(grenzen.warteZeitWarnung); expect(lang.stufe).not.toBe('hinweis'); }); });