lsa-planer

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

/ tests domain raeumgeschwindigkeitSchranken.test.ts

6,0 KB Rohdatei
tests/domain/raeumgeschwindigkeitSchranken.test.ts — 145 Zeilen
1 import { describe, expect, it } from 'vitest';
2 import { computeIntergreen } from '@/domain/rilsa/intergreen';
3 import { RILSA_DEFAULTS, SAFETY_FLOORS, type RilsaDefaults } from '@/domain/rilsa/constants';
4 import { resolveRilsaSettings } from '@/domain/rilsa/settings';
5 import type { ClearingStream, EnteringStream } from '@/domain/rilsa/types';
6
7 /**
8 * Befunde A1 und A3.
9 *
10 * A1: Die Raeumgeschwindigkeit des Radverkehrs stand mit 5,0 m/s ueber dem
11 * RiLSA-Regelwert von 4 m/s (FGSV-Aenderungsblatt vom 29.07.2015, Originalseite
12 * 25: tue + tr = 1 + s0/4). Der zu hohe Wert verkuerzte die Zwischenzeit
13 * zulasten des raeumenden Radverkehrs - bei 20 m Raeumweg um 1 s. Zudem wurden
14 * Rad-Ueberschreibungen nur gegen die Kfz-Schranke von 10 m/s geprueft: 8 m/s
15 * passierten ohne jede Meldung.
16 *
17 * A3: Die harte Obergrenze galt nur fuer stromindividuelle Ueberschreibungen.
18 * Ein ueberhoehter Wert aus den Vorgaben (das Feld erlaubte fuer den OePNV bis
19 * 15 m/s) lief ungeprueft in die Rechnung, waehrend derselbe Wert als
20 * Ueberschreibung mit Fehler gekappt worden waere.
21 */
22
23 function radRaeumend(extra: Partial<ClearingStream> = {}): ClearingStream {
24 return {
25 mode: 'rad',
26 movement: 'geradeaus',
27 clearingDistance: 20,
28 vehicleClass: 'rad',
29 vZul: 0,
30 ...extra,
31 };
32 }
33
34 function kfzEinfahrend(): EnteringStream {
35 return { mode: 'kfz', movement: 'geradeaus', enteringDistance: 10 };
36 }
37
38 describe('Raeumgeschwindigkeit Radverkehr (Befund A1)', () => {
39 it('rechnet mit dem RiLSA-Regelwert 4 m/s', () => {
40 // RiLSA-Rechenbeispiel: 1 s Ueberfahrzeit + 20 m / 4 m/s - 10 m / 11,1 m/s
41 // = 1 + 5 - 0,9009 = 5,099 -> aufgerundet 6 s. Mit den alten 5,0 m/s kamen
42 // 4,1 -> 5 s heraus: Der einfahrende Kfz-Strom erhielt 1 s zu frueh Freigabe.
43 const result = computeIntergreen(radRaeumend(), kfzEinfahrend());
44
45 expect(result.clearingSpeed).toBe(4.0);
46 expect(result.clearingTime).toBe(5);
47 expect(result.intergreen).toBe(6);
48 });
49
50 it('kappt eine Rad-Ueberschreibung oberhalb des Regelwerts mit Fehler', () => {
51 // 8 m/s passierten vorher ohne jede Meldung, weil nur gegen die
52 // Kfz-Schranke von 10 m/s geprueft wurde.
53 const result = computeIntergreen(radRaeumend({ clearingSpeedOverride: 8 }), kfzEinfahrend());
54
55 expect(result.clearingSpeed).toBe(SAFETY_FLOORS.maxClearingSpeedRad);
56 expect(
57 result.notes.some(
58 (n) => n.code === 'raeumgeschwindigkeit-zu-hoch' && n.severity === 'fehler',
59 ),
60 ).toBe(true);
61 });
62
63 it('laesst eine niedrigere Rad-Geschwindigkeit ohne Fehler zu', () => {
64 const result = computeIntergreen(radRaeumend({ clearingSpeedOverride: 3 }), kfzEinfahrend());
65 expect(result.clearingSpeed).toBe(3);
66 expect(result.notes.some((n) => n.severity === 'fehler')).toBe(false);
67 });
68
69 it('begrenzt das Vorgabenfeld auf den Regelwert', () => {
70 const { defaults, notes } = resolveRilsaSettings({ clearingSpeedRad: 7 });
71 expect(defaults.clearingSpeed.rad).toBe(SAFETY_FLOORS.maxClearingSpeedRad);
72 expect(
73 notes.some(
74 (n) => n.code === 'vorgabe-ueberschritten:clearingSpeedRad' && n.severity === 'fehler',
75 ),
76 ).toBe(true);
77 });
78 });
79
80 describe('Schrankendurchgriff auf Vorgaben-Regelwerte (Befund A3)', () => {
81 /*
82 * ANPASSUNG (Befund A2): Mit vZul am Strom raeumt der OePNV jetzt mit
83 * Vmax/3,6 - der Vorgabenwert ist dort nur noch Rueckfallwert und gelangt
84 * allein bei FEHLENDER Vmax in die Rechnung. Die Aussage des Tests bleibt:
85 * Ein ueberhoehter Wert wird auf dem Vorgabenweg genauso mit Fehler gekappt
86 * wie auf dem Ueberschreibungsweg. Der Testfall traegt deshalb keine Vmax
87 * mehr (vZul 0); ohne Vmax ist die konservative Kfz-Schranke von 10 m/s der
88 * Deckel.
89 */
90 it('kappt einen ueberhoehten OePNV-Rueckfallwert aus den Vorgaben mit Fehler', () => {
91 // Altprojekte koennen gespeicherte Vorgaben mit 15 m/s tragen; die Schranke
92 // muss auf jedem Weg gelten, auf dem eine Raeumgeschwindigkeit in die
93 // Rechnung gelangt.
94 const alteVorgaben: RilsaDefaults = {
95 ...RILSA_DEFAULTS,
96 clearingSpeed: { ...RILSA_DEFAULTS.clearingSpeed, oepnv: 15 },
97 };
98 const result = computeIntergreen(
99 { mode: 'oepnv', movement: 'geradeaus', clearingDistance: 40, vehicleClass: 'bus', vZul: 0 },
100 kfzEinfahrend(),
101 alteVorgaben,
102 );
103
104 expect(result.clearingSpeed).toBe(SAFETY_FLOORS.maxClearingSpeedKfz);
105 expect(
106 result.notes.some(
107 (n) => n.code === 'raeumgeschwindigkeit-vorgabe-zu-hoch' && n.severity === 'fehler',
108 ),
109 ).toBe(true);
110 // Die fehlende Vmax wird zusaetzlich gemeldet (Befund A2).
111 expect(
112 result.notes.some((n) => n.code === 'oepnv-vmax-fehlt' && n.severity === 'warnung'),
113 ).toBe(true);
114 });
115
116 it('liegt eine Vmax vor, zaehlt sie - nicht der Vorgabenwert', () => {
117 // Die 15 m/s aus den Vorgaben duerfen einen Strom mit bekannter Vmax
118 // weder beschleunigen noch ausbremsen: Nach RiLSA-Fall 3 gilt Vmax/3,6.
119 const alteVorgaben: RilsaDefaults = {
120 ...RILSA_DEFAULTS,
121 clearingSpeed: { ...RILSA_DEFAULTS.clearingSpeed, oepnv: 15 },
122 };
123 const result = computeIntergreen(
124 { mode: 'oepnv', movement: 'geradeaus', clearingDistance: 40, vehicleClass: 'bus', vZul: 50 },
125 kfzEinfahrend(),
126 alteVorgaben,
127 );
128
129 expect(result.clearingSpeed).toBeCloseTo(50 / 3.6, 6);
130 expect(result.notes.some((n) => n.severity === 'fehler')).toBe(false);
131 });
132
133 it('begrenzt das OePNV-Vorgabenfeld auf die harte Schranke', () => {
134 // Das Feld ist der Rueckfallwert ohne Vmax; ohne bekannte Vmax bleibt die
135 // alte Kfz-Schranke von 10 m/s der Deckel (SAFETY_FLOORS.maxClearingSpeedOepnv
136 // von 19,4 m/s gilt nur, wo eine Vmax das begruendet).
137 const { defaults, notes } = resolveRilsaSettings({ clearingSpeedOepnv: 15 });
138 expect(defaults.clearingSpeed.oepnv).toBe(SAFETY_FLOORS.maxClearingSpeedKfz);
139 expect(
140 notes.some(
141 (n) => n.code === 'vorgabe-ueberschritten:clearingSpeedOepnv' && n.severity === 'fehler',
142 ),
143 ).toBe(true);
144 });
145 });