TRO-Fluss: Separatoren ohne TrackIds-Mitgliedschaft als eigenstaendige 1Sep
Ein per Zuordnung einer Streckengruppe zugeordneter Separator, der nicht Teil von deren eigener TrackIds-Kette ist, wird direkt als 1Sep eingestuft statt ueber die Vario/letzter-Separator-Logik zu laufen - vor Ort bei Mubea VF_1-VF_3 bestaetigt: jede Streckengruppe hat genau einen echten Kettenseparator, alle weiteren Zuordnung-Treffer sind eigenstaendige Vereinzeler ohne eigenes VF-Teilstueck. Damit ein solcher Separator nicht zugleich faelschlich als Weichen-Indiz zaehlt (engster Treffer ueberhaupt bei Mubea 0005, 163mm), werden echte VF-Kettenmitglieder vor der Weichenerkennung (_find_switch_separators) ausgenommen - Naehe zum eigenen Aus-/Einschleuselement ist bei ihnen der normale, erwartete Aufbau, kein Weichenbeleg. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
97965e8ec7
commit
f4b0e4d508
+66
-13
@@ -470,12 +470,31 @@ def derive_tros(
|
||||
)
|
||||
elements_by_id = {e.teile_id: e for e in elements}
|
||||
|
||||
# Separatoren, die bereits ein echtes VF-Kettenmitglied ihrer EIGENEN
|
||||
# Zuordnung-Streckengruppe sind (siehe Schritt 2/_incoming_drop unten),
|
||||
# werden von der Weichenerkennung ausgenommen: Naehe zum eigenen Aus-/
|
||||
# Einschleuselement ist bei ihnen der NORMALE, erwartete Aufbau jeder
|
||||
# angetriebenen Streckengruppe (TrackIds = [Aus-, 1x Separator, Ein-
|
||||
# schleuselement], siehe Mubea VF_1-VF_3), keine Weichenevidenz. Ohne
|
||||
# diesen Ausschluss faengt Regel 1 faelschlich genau diesen Separator ein
|
||||
# (Mubea 0005, 163mm - der engste, staerkste Treffer ueberhaupt, aber kein
|
||||
# Weichen-Indiz - Review 2026-09-24).
|
||||
own_vf_separators = {
|
||||
sep.teile_id
|
||||
for sep in separators
|
||||
if sep.assignment
|
||||
and (host := elements_by_id.get(sep.assignment))
|
||||
and host.kind == "Strecke"
|
||||
and sep.teile_id in host.track_ids
|
||||
}
|
||||
switch_candidates = [s for s in separators if s.teile_id not in own_vf_separators]
|
||||
|
||||
# Separatoren an einem Ausschleuselement (siehe _find_switch_separators)
|
||||
# werden VOR der normalen Host-Aufloesung herausgenommen: sie bilden gleich
|
||||
# unten (3b) ihre eigene 1Sep1Swi-Uebergabestelle und duerfen nicht zugleich
|
||||
# als gewoehnlicher Separator ihres Zuordnung-Hosts (Kreisel-Bahn oder
|
||||
# Strecke - beides kommt vor) mitgezaehlt werden.
|
||||
switch_hits = _find_switch_separators(separators, elements, SWITCH_PROXIMITY_MM)
|
||||
switch_hits = _find_switch_separators(switch_candidates, elements, SWITCH_PROXIMITY_MM)
|
||||
|
||||
# Separator -> Host-Knoten
|
||||
sep_host: dict[str, str] = {}
|
||||
@@ -560,14 +579,19 @@ def derive_tros(
|
||||
)
|
||||
|
||||
# 2) Angetriebene Strecken -> je SEPARATOR ein eigener Vario-TRO. Katalog
|
||||
# (TRO_CATALOG in tro_catalog.py) definiert Vario als 1x Separator + 1x
|
||||
# VarioDrive - mehrere Separatoren auf demselben Streckensegment sind
|
||||
# mehrere eigenstaendige Uebergabestellen, keine gemeinsame (Review
|
||||
# 2026-09-21). Ein Segment ganz ohne Separator behaelt weiterhin einen
|
||||
# einzelnen TRO (leere Separatorliste), damit das Antriebssegment selbst
|
||||
# nicht verschwindet.
|
||||
# (TRO_CATALOG in tro_catalog.py) definiert Vario als genau 1x Separator +
|
||||
# 1x VarioDrive - ein Vario-TRO ist die Paarung eines einzelnen VF-
|
||||
# Teilstuecks mit dem einen Separator, den es antreibt, kein Sammel-TRO
|
||||
# fuer die ganze Streckengruppe (Review 2026-09-21/24). Mehrere
|
||||
# Separatoren auf demselben Streckensegment sind deshalb mehrere
|
||||
# eigenstaendige Uebergabestellen. Ein Segment ganz ohne Separator bildet
|
||||
# folgerichtig KEIN eigenes TRO (kein Separator zum Paaren) - anders als
|
||||
# bisher wird es nicht mehr als Platzhalter-Vario mit leerer
|
||||
# Separatorliste gefuehrt.
|
||||
for node_id in sorted(n for n, node in graph.nodes.items() if node.kind == "Strecke"):
|
||||
seps = seps_on([node_id])
|
||||
if not seps:
|
||||
continue
|
||||
element = graph.nodes[node_id].element
|
||||
drive = element.drive_dir or "unbekannt"
|
||||
reason = f"angetriebenes Streckensegment (Antriebfahrtrichtung: {drive})"
|
||||
@@ -584,14 +608,43 @@ def derive_tros(
|
||||
# bleibt Vario (er ist der einzige Antriebspunkt der Strecke).
|
||||
seps_set = set(seps)
|
||||
track_seps = [tid for tid in element.track_ids if tid in seps_set]
|
||||
track_seps_set = set(track_seps)
|
||||
last_sep_id = track_seps[-1] if len(track_seps) > 1 else None
|
||||
|
||||
for sep_id in seps or [None]:
|
||||
sep_list = [sep_id] if sep_id else []
|
||||
for sep_id in seps:
|
||||
if sep_id not in track_seps_set:
|
||||
# Zuordnung zeigt zwar auf diese Streckengruppe, der Separator
|
||||
# ist aber nicht Teil von deren eigener TrackIds-Kette - kein
|
||||
# VF-Teilstueck treibt ihn an, also plain 1Sep statt Vario
|
||||
# (Mubea VF_1-VF_3 vor Ort bestaetigt, Review 2026-09-24: pro
|
||||
# Streckengruppe genau 1 echter Kettenseparator, alle
|
||||
# uebrigen Zuordnung-Treffer sind eigenstaendige Vereinzeler).
|
||||
tros.append(
|
||||
Tro(
|
||||
tro_id="",
|
||||
type_name="1Sep",
|
||||
label=element.name,
|
||||
hosts=[node_id],
|
||||
separators=[sep_id],
|
||||
scanners=scanners_for([sep_id]),
|
||||
reason=(
|
||||
f"Separator {sep_id}: Zuordnung zeigt auf "
|
||||
f"{element.name}, ist aber nicht Teil von dessen "
|
||||
f"TrackIds-Kette - kein eigenes VF treibt ihn an"
|
||||
),
|
||||
confidence="mittel",
|
||||
)
|
||||
)
|
||||
findings.append(
|
||||
f"{element.name} Separator {sep_id}: Zuordnung ohne "
|
||||
f"TrackIds-Mitgliedschaft - als 1Sep statt Vario eingestuft"
|
||||
)
|
||||
continue
|
||||
|
||||
type_name = "Vario"
|
||||
sep_reason = reason
|
||||
confidence = "hoch"
|
||||
if sep_id is not None and sep_id == last_sep_id:
|
||||
if sep_id == last_sep_id:
|
||||
type_name = "1Sep"
|
||||
confidence = "mittel"
|
||||
sep_reason = (
|
||||
@@ -603,7 +656,7 @@ def derive_tros(
|
||||
f"{element.name} Separator {sep_id}: letzter Separator vor dem "
|
||||
f"Wiedereinschleusen - als 1Sep statt Vario eingestuft"
|
||||
)
|
||||
elif sep_id is not None:
|
||||
else:
|
||||
seg_drive, seg_drop = _incoming_drop(element, sep_id, elements_by_id)
|
||||
if seg_drive == "horizontal" and seg_drop is not None and seg_drop <= -GEFAELLE_DROP_MM:
|
||||
type_name = "1Sep"
|
||||
@@ -625,8 +678,8 @@ def derive_tros(
|
||||
type_name=type_name,
|
||||
label=element.name,
|
||||
hosts=[node_id],
|
||||
separators=sep_list,
|
||||
scanners=scanners_for(sep_list),
|
||||
separators=[sep_id],
|
||||
scanners=scanners_for([sep_id]),
|
||||
reason=sep_reason,
|
||||
confidence=confidence,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user