lsa-planer

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

/ src domain rilsa types.ts

15,9 KB Rohdatei
src/domain/rilsa/types.ts — 364 Zeilen
1 import type {
2 KilometersPerHour,
3 Meters,
4 MetersPerSecond,
5 Ratio,
6 Seconds,
7 VehiclesPerHour,
8 } from '../units';
9
10 /** Verkehrsart einer Signalgruppe bzw. eines Verkehrsstroms. */
11 export type TrafficMode = 'kfz' | 'rad' | 'fuss' | 'oepnv';
12
13 /**
14 * Fahrbeziehung. Sie bestimmt nach RiLSA die anzusetzende Raeumgeschwindigkeit:
15 * abbiegende Kraftfahrzeuge raeumen langsamer als geradeausfahrende.
16 */
17 export type Movement = 'geradeaus' | 'rechts' | 'links' | 'querung';
18
19 /**
20 * Fahrzeugart fuer den Laengenzuschlag beim Raeumweg.
21 *
22 * 'strassenbahn' kam mit Fassung 5.4.0 (Befund A2) hinzu: Die
23 * RiLSA 2015 rechnet im Zwischenzeitfall 3 mit einer Fahrzeuglaenge von 15 m
24 * fuer Strassenbahnen ("lFZ = 15 m bei Strassenbahnen", FGSV-Aenderungsblatt
25 * vom 29.07.2015, Originalseite 24). Ohne die Fahrzeugart war eine Bahn nur
26 * als 'bus' abbildbar und raeumte 9 m zu kurz.
27 */
28 export type VehicleClass = 'pkw' | 'lkw' | 'bus' | 'lastzug' | 'strassenbahn' | 'rad' | 'keine';
29
30 /**
31 * Art der Lichtsignalanlage.
32 *
33 * WARUM DIESE UNTERSCHEIDUNG NOETIG IST
34 *
35 * Die Kennwerte des Regelwerks gelten nicht fuer jede Anlage gleich. Die
36 * Obergrenze der Umlaufzeit von 120 s stammt aus der RiLSA und gilt fuer
37 * KNOTENPUNKTE: Laengere Umlaeufe fuehren dort zu Rotlichtverstoessen.
38 *
39 * Bei einer einstreifigen Verkehrsfuehrung ist der Raeumweg dagegen die GANZE
40 * Engstelle und nicht ein Konfliktbereich von dreissig Metern. Nachgerechnet:
41 * Bei 400 m Engstelle ergeben sich 44 s Zwischenzeit je Richtung, bei zwei
42 * Uebergaengen je Umlauf und knapper Freigabezeit also rund 128 s Umlauf - ohne
43 * dass daran etwas falsch waere. Mit einer einzigen Schranke fuer alles ist
44 * entweder der Knotenpunkt zu lasch bemessen oder die Arbeitsstelle nicht
45 * rechenbar; bis hierher war Letzteres der Fall.
46 *
47 * Die Art steuert deshalb Schranken UND Pruefregeln - und sie gehoert in den
48 * Ausdruck: Zur verkehrsbehoerdlichen Anordnung nach Paragraf 45 StVO gehoert,
49 * welche Art Anlage angeordnet wird.
50 */
51 export type Anlagenart = 'knotenpunkt' | 'fussgaengerschutzanlage' | 'einstreifig';
52
53 /**
54 * Rechenansatz fuer die Ueberfahrzeit des Kraftfahrzeugverkehrs
55 * (seit Fassung 5.5.0).
56 *
57 * 'gelbzeit' Die Ueberfahrzeit IST die Gelbzeit dieser Signalgruppe
58 * (3/4/5 s nach zulaessiger Hoechstgeschwindigkeit) - der Ansatz
59 * dieses Programms und die VORGABE. Er ist der konservative Stand:
60 * bei den Regelwerten beider Ansaetze faellt die Zwischenzeit beim
61 * Abbiegen und bei 60/70 km/h laenger aus als mit festen Werten,
62 * und kuerzer als die Regelwerte der RiLSA rechnet er nie.
63 * 'fest' tue = 3 s geradeaus, 2 s abbiegend, unabhaengig von der
64 * zulaessigen Hoechstgeschwindigkeit - der REGELWERKSANSATZ
65 * (RiLSA 2015, Abschnitt 2.5.2, Faelle 1 und 2; seit 5.27.0 an der
66 * gekauften Ausgabe abgeglichen). Er VERKUERZT die Zwischenzeit
67 * gegenueber der Vorgabe dieses Programms und erscheint deshalb
68 * als begruendungspflichtige Abweichung.
69 *
70 * BERICHTIGT (Fassung 5.43.0): Beim Ansatz 'fest' stand hier
71 * "Praxisansatz nach behoerdlichen Leitfaeden" - der Stand bis 5.26.0, als der
72 * Wortlaut zu den Faellen 1 und 2 nur als Umkehrschluss aus den
73 * Zwischenzeitentafeln eines Leitfadens vorlag. Der Umkehrschluss traf zu; das
74 * Druckwerk liegt inzwischen vor, und quellen.ts fuehrt beide Zahlen unter
75 * 'gesichert' mit Fundstelle. Derselbe ueberholte Satz stand im Pruefbericht.
76 *
77 * BEIDE WERTE SIND EINSTELLBAR (1 bis 10 s). Richtung und Groessenordnung der
78 * Wahl bildet deshalb ansaetze.ts aus den WIRKSAMEN Vorgaben
79 * (`ueberfahrzeitAnsatzRichtungSatz`, `festeWerteZuschreibungSatz`) und keine
80 * Ausgabe aus dem Text dieses Kommentars.
81 *
82 * Beleglage und Begruendung der Vorgabe: constants.ts, RilsaDefaults
83 * .crossingTime.
84 */
85 export type UeberfahrzeitAnsatz = 'gelbzeit' | 'fest';
86
87 /** Signalbild eines Signalgebers zu einem Zeitpunkt. */
88 export type SignalAspect = 'rot' | 'rotgelb' | 'gruen' | 'gelb' | 'dunkel' | 'gelb-blinkend';
89
90 /** Schweregrad einer Pruefmeldung. */
91 export type Severity = 'fehler' | 'warnung' | 'hinweis';
92
93 /**
94 * Ein raeumender Verkehrsstrom im Sinne der Zwischenzeitberechnung.
95 *
96 * `clearingDistance` ist der Weg von der Haltlinie bis zum Ende des
97 * Konfliktbereichs (ohne Fahrzeuglaenge). Der Laengenzuschlag wird aus
98 * `vehicleClass` abgeleitet und getrennt ausgewiesen, damit im Pruefbericht
99 * nachvollziehbar bleibt, wie der Raeumweg zustande kommt.
100 */
101 export interface ClearingStream {
102 readonly mode: TrafficMode;
103 readonly movement: Movement;
104 /** Weg Haltlinie -> Ende Konfliktbereich in Metern, ohne Fahrzeuglaenge. */
105 readonly clearingDistance: Meters;
106 readonly vehicleClass: VehicleClass;
107 /** Zulaessige Hoechstgeschwindigkeit des raeumenden Stroms (fuer die Gelbzeit). */
108 readonly vZul: KilometersPerHour;
109 /** Ueberschreibt die Raeumgeschwindigkeit aus dem Regelwerk (m/s). */
110 readonly clearingSpeedOverride?: MetersPerSecond;
111 /** Ueberschreibt die Ueberfahrzeit aus dem Regelwerk (s). */
112 readonly crossingTimeOverride?: Seconds;
113 /** Erhoehter Zeitbedarf, z. B. Furt an Schule oder Senioreneinrichtung. */
114 readonly reducedMobility?: boolean;
115 /**
116 * Nur abbiegende Kfz-Stroeme: Der Strom durchfaehrt an DIESER Beziehung einen
117 * engen Innenradius (Praxisansatz). Dann gilt
118 * `clearingSpeed.kfzTurningEngerRadius` statt `clearingSpeed.kfzTurning`.
119 * Fehlt das Merkmal, gilt der Regelwert - das Verhalten bis Schema 11.
120 */
121 readonly engerRadius?: boolean;
122 /**
123 * Rechenansatz der Ueberfahrzeit fuer Kraftfahrzeuge.
124 *
125 * WARUM AM STROM UND NICHT ALS ARGUMENT DER RECHNUNG: Die Wahl steht im
126 * Projekt (Project.settings.ueberfahrzeitAnsatz) und wird an genau einer
127 * Stelle in den Strom uebernommen (plan/signalPlan.ts, raeumenderStrom).
128 * Damit rechnet jeder Aufrufer von computeIntergreen - auch die Gegenprobe
129 * zu einer von Hand gesetzten Zwischenzeit - mit demselben Ansatz, ohne dass
130 * ihn jede Aufrufstelle einzeln durchreichen muesste. Fehlt das Feld, gilt
131 * 'gelbzeit': der heutige Stand und die konservative Seite.
132 */
133 readonly ueberfahrzeitAnsatz?: UeberfahrzeitAnsatz;
134 /**
135 * Nur OePNV: Der Strom haelt regelmaessig vor dem Knotenpunkt (z. B.
136 * Haltestelle) und faehrt am Ende der Freigabezeit aus dem Stand an.
137 * Dann gilt der Zwischenzeitfall 4 der RiLSA 2015: Ueberfahrzeit 0 s und
138 * Raeumen mit Anfahransatz statt mit konstanter Geschwindigkeit.
139 */
140 readonly haltVorKnoten?: boolean;
141 }
142
143 /**
144 * Ein einfahrender Verkehrsstrom im Sinne der Zwischenzeitberechnung.
145 *
146 * `enteringDistance` ist der Weg von der Haltlinie bis zum Beginn des
147 * Konfliktbereichs. Ein Laengenzuschlag entfaellt hier definitionsgemaess.
148 */
149 export interface EnteringStream {
150 readonly mode: TrafficMode;
151 readonly movement: Movement;
152 /** Weg Haltlinie -> Beginn Konfliktbereich in Metern. */
153 readonly enteringDistance: Meters;
154 /** Ueberschreibt die Einfahrgeschwindigkeit aus dem Regelwerk (m/s). */
155 readonly enteringSpeedOverride?: MetersPerSecond;
156 }
157
158 /** Nachvollziehbares Ergebnis einer Zwischenzeitberechnung. */
159 export interface IntergreenResult {
160 /**
161 * Nach welchem Verfahren gerechnet wurde.
162 *
163 * 'knotenpunkt': tz = tue + tr - te nach RiLSA 2015, Abschnitt 2.5.
164 * 'engstelle': tz = tue + sr/Vr * 3,6 nach Abschnitt 5.2.2 - mit fester
165 * Ueberfahrzeit von 4 s, ohne Fahrzeuglaenge im Raeumweg und
166 * OHNE Einfahrzeit.
167 *
168 * Als eigenes Feld, damit Ausdruck und Ansicht das Verfahren benennen
169 * koennen: Zwei Zeilen mit derselben Spaltenueberschrift, aber
170 * verschiedenen Formeln dahinter sind ohne diese Angabe nicht
171 * nachzurechnen - dieselbe Begruendung wie bei `raeumansatz`.
172 */
173 readonly verfahren: 'knotenpunkt' | 'engstelle';
174 /** Massgebende Zwischenzeit in ganzen Sekunden (aufgerundet, nie negativ). */
175 readonly intergreen: Seconds;
176 /** Ungerundetes Zwischenergebnis tue + tr - te. */
177 readonly raw: Seconds;
178 /** Ueberfahrzeit tue. */
179 readonly crossingTime: Seconds;
180 /** Raeumweg sr einschliesslich Fahrzeuglaenge. */
181 readonly clearingPath: Meters;
182 /** Beruecksichtigter Laengenzuschlag. */
183 readonly vehicleLength: Meters;
184 /**
185 * Angesetzte Raeumgeschwindigkeit vr.
186 *
187 * Beim Anfahransatz ('anfahren') ist das die Geschwindigkeit, auf die das
188 * Fahrzeug hoechstens beschleunigt (Vmax/3,6 bzw. der Rueckfallwert) - die
189 * Raeumzeit ist dann NICHT sr/vr, sondern folgt der Anfahrformel.
190 */
191 readonly clearingSpeed: MetersPerSecond;
192 /**
193 * Rechenansatz der Raeumzeit. 'geschwindigkeit': tr = sr / vr.
194 * 'anfahren' (OePNV mit Halt vor dem Knotenpunkt, RiLSA 2015 Fall 4):
195 * tr = sqrt(2 * sr / a); wird dabei vr erreicht, faehrt das Fahrzeug den
196 * Restweg mit vr: tr = vr/a + (sr - vr^2/(2*a)) / vr.
197 *
198 * Als eigenes Feld, damit Ausdruck und Ansicht die Formel benennen koennen,
199 * statt eine Geschwindigkeit zu drucken, aus der sich tr nicht nachrechnen
200 * laesst (Grundsatz: was gedruckt wird, muss sich aus den gedruckten Groessen
201 * nachrechnen lassen).
202 */
203 readonly raeumansatz: 'geschwindigkeit' | 'anfahren';
204 /** Anfahrbeschleunigung a in m/s2 beim Anfahransatz, sonst null. */
205 readonly anfahrbeschleunigung: number | null;
206 /** Raeumzeit tr in Sekunden (ungerundet); Formel siehe `raeumansatz`. */
207 readonly clearingTime: Seconds;
208 /**
209 * Untergrenze der Ueberfahr- und Raeumzeit nach RiLSA 2015, Abschnitt 2.5.2 -
210 * NUR gesetzt, wenn sie GREIFT, sonst null.
211 *
212 * Die RiLSA verlangt fuer geradeaus fahrende (Fall 1) und abbiegende
213 * Kraftfahrzeuge (Fall 2): tue + tr >= tG + 1 s. Greift die Schranke, ist
214 * `raw` NICHT tue + tr - te, sondern diese Untergrenze abzueglich te. Ohne
215 * dieses Feld liesse sich die gedruckte Zeile nicht nachrechnen - deshalb
216 * steht hier die Zahl und nicht bloss ein Schalter.
217 */
218 readonly ueberfahrRaeumzeitUntergrenze: Seconds | null;
219 /** Einfahrweg se. */
220 readonly enteringPath: Meters;
221 /** Angesetzte Einfahrgeschwindigkeit ve. */
222 readonly enteringSpeed: MetersPerSecond;
223 /** Einfahrzeit te = se / ve (ungerundet). */
224 readonly enteringTime: Seconds;
225 /** Wurde das rechnerische Ergebnis durch die untere Schranke 0 s ersetzt? */
226 readonly clampedToZero: boolean;
227 readonly notes: readonly CalculationNote[];
228 }
229
230 /** Begruendeter Hinweis aus einer Berechnung. */
231 export interface CalculationNote {
232 readonly severity: Severity;
233 readonly code: string;
234 readonly message: string;
235 /**
236 * Konfliktbeziehung, aus der die Meldung stammt.
237 *
238 * Nur gesetzt, wo es eine gibt. Meldungen aus dem Planaufbau zeigten im
239 * Pruefbericht pauschal auf das Programm; der Sprungknopf fuehrte damit bei
240 * einer Zwischenzeitmeldung in die Phasenansicht, wo sich nichts davon
241 * aendern laesst.
242 */
243 readonly konfliktId?: string;
244 }
245
246 /** Signalzeiten einer Signalgruppe. */
247 export interface SignalGroupTimes {
248 /** Mindestfreigabezeit. */
249 readonly minGreen: Seconds;
250 /** Gelbzeit (0 s bei Fussgaengern). */
251 readonly yellow: Seconds;
252 /** Rot-Gelb-Zeit (0 s bei Fussgaengern). */
253 readonly redYellow: Seconds;
254 }
255
256 /** Eingangsgroessen der Umlaufzeitermittlung. */
257 export interface CycleTimeInput {
258 /** Summe der Verlustzeiten je Umlauf in Sekunden. */
259 readonly lostTime: Seconds;
260 /**
261 * Massgebende Saettigungsgrade y = q/qS der Phasen (dimensionslos).
262 * Ihre Summe Y muss kleiner als 1 sein, sonst ist der Knoten uebersaettigt.
263 *
264 * `undefined` heisst "Verkehrsstaerke nicht erfasst" und NICHT "kein
265 * Verkehr". Die Unterscheidung ist der ganze Zweck des Feldes: 0 ist eine
266 * Angabe - gezaehlt und kein Verkehr -, eine Luecke ist keine. Beide ergaeben
267 * dieselbe Summe Y; nur die Luecke ist zu melden, weil die daraus ermittelte
268 * Umlaufzeit zu kurz ausfaellt.
269 */
270 readonly criticalFlowRatios: readonly (Ratio | undefined)[];
271 /** Untere Schranke aus Mindestfreigabe- und Zwischenzeiten. */
272 readonly minimumCycle?: Seconds;
273 /** Rasterung des Ergebnisses in Sekunden (Regelfall 5 s). */
274 readonly step?: Seconds;
275 }
276
277 /** Ergebnis eines Umlaufzeitverfahrens. */
278 export interface CycleTimeResult {
279 readonly method: CycleTimeMethod;
280 /** Empfohlene Umlaufzeit nach Rasterung und Begrenzung. */
281 readonly cycleTime: Seconds;
282 /** Rechnerischer Wert vor Rasterung und Begrenzung. */
283 readonly raw: Seconds;
284 /** Summe der massgebenden Saettigungsgrade Y. */
285 readonly totalFlowRatio: Ratio;
286 readonly lostTime: Seconds;
287 /**
288 * Wurde das Ergebnis durch eine Schranke ersetzt?
289 *
290 * GENAUER: Die Frage meint die Schranken, die auf den ERFORDERLICHEN Umlauf
291 * wirken - den vor der Rasterung. 'maximum' sagt, dass er nicht unter den
292 * Hoechstwert passt, und nicht, dass eine Aufrundung gekuerzt wurde. Fuehrt
293 * allein die Rasterung ueber den Hoechstwert hinaus, wird `cycleTime` zwar
294 * auf ihn gekappt, `bounded` bleibt aber bei 'keine': Der Bedarf war gedeckt.
295 * Gemessen mit 119,48 s und Rasterung 7 s - cycleTime 120 s, bounded 'keine'.
296 *
297 * 'uebersaettigt' (KORREKTUR Fassung 5.4.0, Befund C11): Bei
298 * Y >= 1 (bzw. >= Ziel-/Hoechstauslastung) gibt es KEINE Umlaufzeit;
299 * `cycleTime` traegt dann nur die Obergrenze als Ersatzwert, damit der Plan
300 * eine Zahl hat. Bis dahin stand hier 'maximum' - derselbe Zustand wie bei
301 * einer rechenbaren, aber zu langen Umlaufzeit, und keine Ausgabe konnte
302 * "nicht bemessbar" von "120 s" unterscheiden. Jede Ausgabe der Umlaufzeit
303 * muss diesen Zustand am Wert vermerken (siehe umlaufzeitIstErsatzwert in
304 * plan/signalPlan.ts).
305 */
306 readonly bounded: 'keine' | 'minimum' | 'maximum' | 'mindestumlauf' | 'uebersaettigt';
307 readonly notes: readonly CalculationNote[];
308 }
309
310 export type CycleTimeMethod = 'webster' | 'hbs' | 'akcelik' | 'hcm';
311
312 /**
313 * Bewertungsverfahren fuer Kapazitaet, Wartezeit und Qualitaetsstufe.
314 *
315 * KORREKTUR (Fassung 5.4.0, Befund B2): Bis dahin schaltete der Wert
316 * nur die Stufentafel um, waehrend immer dieselbe HCM-Formel gerechnet wurde -
317 * und der Ausdruck "Bewertung nach HBS 2015" behauptete. Jetzt bezeichnet er
318 * das ganze Verfahren: 'HBS' rechnet Kapazitaet und Wartezeit nach dem
319 * HBS 2015 (Abflusszeit tA = tF + 1 s, Grundwartezeit und Reststau mit
320 * Instationaritaetsfaktor, T = 1 h) und bewertet nach dessen Tafeln; 'HCM'
321 * rechnet das Verfahren des Highway Capacity Manual (d1 + d2, T = 0,25 h)
322 * und bewertet nach dessen Tafel.
323 */
324 export type Bewertungsverfahren = 'HBS' | 'HCM';
325
326 /** Kapazitaetskennwerte einer Signalgruppe. */
327 export interface CapacityResult {
328 /** Verfahren, nach dem die Kapazitaet gerechnet wurde. */
329 readonly verfahren: Bewertungsverfahren;
330 /** Kapazitaet in Fahrzeugen je Stunde. */
331 readonly capacity: VehiclesPerHour;
332 /**
333 * Abflusszeit tA, mit der die Kapazitaet gerechnet wurde. Nach HBS 2015 ist
334 * das die Freigabezeit zuzueglich 1 s je Freigabezeitfenster (der Abfluss
335 * laeuft in die Gelbzeit hinein), gedeckelt auf die Umlaufzeit; nach HCM die
336 * Freigabezeit selbst.
337 */
338 readonly abflusszeit: Seconds;
339 /** Abflusszeitanteil fA = tA/tU (HBS) bzw. Freigabezeitanteil g/tU (HCM). */
340 readonly greenRatio: Ratio;
341 /** Saettigungsverkehrsstaerke. */
342 readonly saturationFlow: VehiclesPerHour;
343 /** Auslastungsgrad x = q/c, sofern eine Verkehrsstaerke bekannt ist. */
344 readonly degreeOfSaturation?: Ratio;
345 readonly notes: readonly CalculationNote[];
346 }
347
348 /**
349 * Qualitaetsstufe des Verkehrsablaufs.
350 *
351 * `kriterium` sagt, woran gemessen wurde. Das HBS 2015 bewertet Kfz- und
352 * OePNV-Stroeme nach der MITTLEREN Wartezeit, Fussgaenger und Radverkehr nach
353 * der MAXIMALEN Wartezeit (laengste Sperrzeit im Umlauf), und vergibt fuer
354 * Kfz die Stufe F nicht ab einer Wartezeit, sondern genau dann, wenn die
355 * Nachfrage die Kapazitaet uebersteigt (Ueberlastung). Ohne dieses Feld liesse
356 * sich aus einer gedruckten Stufe nicht nachvollziehen, welcher Wert sie
357 * begruendet.
358 */
359 export interface ServiceLevel {
360 readonly grade: 'A' | 'B' | 'C' | 'D' | 'E' | 'F';
361 readonly label: string;
362 readonly scale: Bewertungsverfahren;
363 readonly kriterium: 'mittlere-wartezeit' | 'maximale-wartezeit' | 'ueberlastung';
364 }