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}
|
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)
|
# Separatoren an einem Ausschleuselement (siehe _find_switch_separators)
|
||||||
# werden VOR der normalen Host-Aufloesung herausgenommen: sie bilden gleich
|
# werden VOR der normalen Host-Aufloesung herausgenommen: sie bilden gleich
|
||||||
# unten (3b) ihre eigene 1Sep1Swi-Uebergabestelle und duerfen nicht zugleich
|
# unten (3b) ihre eigene 1Sep1Swi-Uebergabestelle und duerfen nicht zugleich
|
||||||
# als gewoehnlicher Separator ihres Zuordnung-Hosts (Kreisel-Bahn oder
|
# als gewoehnlicher Separator ihres Zuordnung-Hosts (Kreisel-Bahn oder
|
||||||
# Strecke - beides kommt vor) mitgezaehlt werden.
|
# 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
|
# Separator -> Host-Knoten
|
||||||
sep_host: dict[str, str] = {}
|
sep_host: dict[str, str] = {}
|
||||||
@@ -560,14 +579,19 @@ def derive_tros(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# 2) Angetriebene Strecken -> je SEPARATOR ein eigener Vario-TRO. Katalog
|
# 2) Angetriebene Strecken -> je SEPARATOR ein eigener Vario-TRO. Katalog
|
||||||
# (TRO_CATALOG in tro_catalog.py) definiert Vario als 1x Separator + 1x
|
# (TRO_CATALOG in tro_catalog.py) definiert Vario als genau 1x Separator +
|
||||||
# VarioDrive - mehrere Separatoren auf demselben Streckensegment sind
|
# 1x VarioDrive - ein Vario-TRO ist die Paarung eines einzelnen VF-
|
||||||
# mehrere eigenstaendige Uebergabestellen, keine gemeinsame (Review
|
# Teilstuecks mit dem einen Separator, den es antreibt, kein Sammel-TRO
|
||||||
# 2026-09-21). Ein Segment ganz ohne Separator behaelt weiterhin einen
|
# fuer die ganze Streckengruppe (Review 2026-09-21/24). Mehrere
|
||||||
# einzelnen TRO (leere Separatorliste), damit das Antriebssegment selbst
|
# Separatoren auf demselben Streckensegment sind deshalb mehrere
|
||||||
# nicht verschwindet.
|
# 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"):
|
for node_id in sorted(n for n, node in graph.nodes.items() if node.kind == "Strecke"):
|
||||||
seps = seps_on([node_id])
|
seps = seps_on([node_id])
|
||||||
|
if not seps:
|
||||||
|
continue
|
||||||
element = graph.nodes[node_id].element
|
element = graph.nodes[node_id].element
|
||||||
drive = element.drive_dir or "unbekannt"
|
drive = element.drive_dir or "unbekannt"
|
||||||
reason = f"angetriebenes Streckensegment (Antriebfahrtrichtung: {drive})"
|
reason = f"angetriebenes Streckensegment (Antriebfahrtrichtung: {drive})"
|
||||||
@@ -584,14 +608,43 @@ def derive_tros(
|
|||||||
# bleibt Vario (er ist der einzige Antriebspunkt der Strecke).
|
# bleibt Vario (er ist der einzige Antriebspunkt der Strecke).
|
||||||
seps_set = set(seps)
|
seps_set = set(seps)
|
||||||
track_seps = [tid for tid in element.track_ids if tid in seps_set]
|
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
|
last_sep_id = track_seps[-1] if len(track_seps) > 1 else None
|
||||||
|
|
||||||
for sep_id in seps or [None]:
|
for sep_id in seps:
|
||||||
sep_list = [sep_id] if sep_id else []
|
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"
|
type_name = "Vario"
|
||||||
sep_reason = reason
|
sep_reason = reason
|
||||||
confidence = "hoch"
|
confidence = "hoch"
|
||||||
if sep_id is not None and sep_id == last_sep_id:
|
if sep_id == last_sep_id:
|
||||||
type_name = "1Sep"
|
type_name = "1Sep"
|
||||||
confidence = "mittel"
|
confidence = "mittel"
|
||||||
sep_reason = (
|
sep_reason = (
|
||||||
@@ -603,7 +656,7 @@ def derive_tros(
|
|||||||
f"{element.name} Separator {sep_id}: letzter Separator vor dem "
|
f"{element.name} Separator {sep_id}: letzter Separator vor dem "
|
||||||
f"Wiedereinschleusen - als 1Sep statt Vario eingestuft"
|
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)
|
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:
|
if seg_drive == "horizontal" and seg_drop is not None and seg_drop <= -GEFAELLE_DROP_MM:
|
||||||
type_name = "1Sep"
|
type_name = "1Sep"
|
||||||
@@ -625,8 +678,8 @@ def derive_tros(
|
|||||||
type_name=type_name,
|
type_name=type_name,
|
||||||
label=element.name,
|
label=element.name,
|
||||||
hosts=[node_id],
|
hosts=[node_id],
|
||||||
separators=sep_list,
|
separators=[sep_id],
|
||||||
scanners=scanners_for(sep_list),
|
scanners=scanners_for([sep_id]),
|
||||||
reason=sep_reason,
|
reason=sep_reason,
|
||||||
confidence=confidence,
|
confidence=confidence,
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user