lsa-planer

LSA-Planer Professional – Planungssoftware für Lichtsignalanlagen nach RiLSA 2015 und § 45 StVO. EUPL-1.2.

/ tests domain rechenlaengenUndRotgelb.test.ts

4,3 KB Rohdatei
tests/domain/rechenlaengenUndRotgelb.test.ts — 96 Zeilen
1 import { describe, expect, it } from 'vitest';
2 import { RILSA_DEFAULTS, SAFETY_FLOORS } from '@/domain/rilsa/constants';
3 import { resolveRilsaSettings, settingFields } from '@/domain/rilsa/settings';
4 import { computeIntergreen } from '@/domain/rilsa/intergreen';
5 import { QUELLEN } from '@/domain/rilsa/quellen';
6 import type { ClearingStream, EnteringStream } from '@/domain/rilsa/types';
7
8 /*
9 * Befunde B5 und B6.
10 *
11 * B5: Lkw/Bus 12 m und Lastzug 18,75 m waren die Hoechstlaengen nach Par. 32
12 * StVZO, keine RiLSA-Rechenwerte - und standen als "gesichert nach RiLSA
13 * 2015" in der Planunterlage. Die RiLSA rechnet mit 6 m fuer Kraftfahrzeuge
14 * (Fall 3 woertlich fuer Linienbusse; Lkw/Lastzug nach Sekundaerquellen).
15 *
16 * B6: Das Vorgabenfeld Rot-Gelb liess 3 s zu; 2,5 oder 3 s ergaben nur einen
17 * Abweichungshinweis. VwV-StVO zu Par. 37 Rn. 17: "soll ... eine Sekunde
18 * dauern, darf aber nicht laenger als zwei Sekunden sein".
19 */
20
21 const kfz = (vehicleClass: ClearingStream['vehicleClass']): ClearingStream => ({
22 mode: 'kfz',
23 movement: 'geradeaus',
24 clearingDistance: 24,
25 vehicleClass,
26 vZul: 50,
27 });
28 const einfahrend: EnteringStream = { mode: 'kfz', movement: 'geradeaus', enteringDistance: 10 };
29
30 describe('Fahrzeuglaengen sind RiLSA-Rechenlaengen (Befund B5)', () => {
31 it('setzt fuer Pkw, Lkw, Bus und Lastzug dieselben 6 m an, fuer die Strassenbahn 15 m', () => {
32 expect(RILSA_DEFAULTS.vehicleLength).toMatchObject({
33 pkw: 6,
34 lkw: 6,
35 bus: 6,
36 lastzug: 6,
37 strassenbahn: 15,
38 rad: 0,
39 });
40 });
41
42 it('rechnet Lastzug und Pkw dieselbe Zwischenzeit - der Unterschied war eine erfundene Verschaerfung', () => {
43 // 24 m + 6 m bei 10 m/s = 3,0 s Raeumzeit; mit 18,75 m waren es 4,275 s -
44 // eine Sekunde mehr Zwischenzeit, die kein Pruefer aus der RiLSA herleiten konnte.
45 const pkw = computeIntergreen(kfz('pkw'), einfahrend);
46 const lastzug = computeIntergreen(kfz('lastzug'), einfahrend);
47 expect(lastzug.vehicleLength).toBe(6);
48 expect(lastzug.intergreen).toBe(pkw.intergreen);
49 expect(lastzug.clearingTime).toBeCloseTo(3.0, 6);
50 });
51
52 it('haelt die 6 m als harte Untergrenze und laesst laengere Zuschlaege als Vorgabe zu', () => {
53 const zuKurz = resolveRilsaSettings({ vehicleLengthLastzug: 4 });
54 expect(zuKurz.defaults.vehicleLength.lastzug).toBe(SAFETY_FLOORS.minVehicleLengthKfz);
55 expect(zuKurz.notes.some((n) => n.code === 'vorgabe-unterschritten:vehicleLengthLastzug')).toBe(
56 true,
57 );
58 const verschaerft = resolveRilsaSettings({ vehicleLengthLastzug: 18.75 });
59 expect(verschaerft.defaults.vehicleLength.lastzug).toBe(18.75);
60 expect(verschaerft.deviations.map((d) => d.key)).toContain('vehicleLengthLastzug');
61 });
62
63 it('nennt im Fundstellenverzeichnis die RiLSA-Rechenlaenge fuer alle Kraftfahrzeuge', () => {
64 const quelle = QUELLEN['rilsa-fahrzeuglaengen'];
65 expect(quelle.hinweis).toContain('6 m für Kraftfahrzeuge einschließlich Lkw, Lastzug');
66 // Der Hinweis nennt den frueheren Stand mit der Fassung, bis zu der er galt.
67 expect(quelle.hinweis).toContain('Vor der Fassung 5.4.0 standen hier Lkw/Bus 12 m');
68 });
69 });
70
71 describe('Rot-Gelb-Zeit hoechstens 2 s (Befund B6)', () => {
72 it('deckelt das Vorgabenfeld bei 2 s mit Begruendung aus der VwV-StVO', () => {
73 const feld = settingFields().find((f) => f.key === 'redYellow')!;
74 expect(feld.max).toBe(2);
75 expect(feld.min).toBe(1);
76 expect(feld.schrankenBegruendung).toContain('VwV-StVO');
77 expect(SAFETY_FLOORS.maxRedYellow).toBe(2);
78 });
79
80 it('kappt eine gespeicherte Rot-Gelb-Zeit von 3 s mit Fehler auf 2 s statt sie still zu uebernehmen', () => {
81 // Bis hierher lief 3 s als blosser Abweichungshinweis in den Plan.
82 const { defaults, notes } = resolveRilsaSettings({ redYellow: 3 });
83 expect(defaults.redYellow).toBe(2);
84 const fehler = notes.find((n) => n.code === 'vorgabe-ueberschritten:redYellow');
85 expect(fehler?.severity).toBe('fehler');
86 expect(fehler?.message).toContain('höchstens 2 s');
87 expect(fehler?.message).toContain('VwV-StVO');
88 });
89
90 it('nimmt 2 s als zulaessige Abweichung an', () => {
91 const { defaults, notes, deviations } = resolveRilsaSettings({ redYellow: 2 });
92 expect(defaults.redYellow).toBe(2);
93 expect(notes).toHaveLength(0);
94 expect(deviations.map((d) => d.key)).toContain('redYellow');
95 });
96 });