diff --git a/lib/tro_flow.py b/lib/tro_flow.py index 73aca7d..545d973 100644 --- a/lib/tro_flow.py +++ b/lib/tro_flow.py @@ -1267,15 +1267,13 @@ def link_tros( def _add_chain_pair(a: str, b: str) -> None: if a == b: return - # Eine Beladung ist nur Quelle, nie Ziel (siehe derive_boundaries) - - # unabhaengig davon, wie TrackIds sie in der geschlossenen Umlaufliste - # aufzaehlt. Eine Entladung auf der Kreisel-Bahn wird dagegen - # DURCHFAHREN: was nicht entladen wird, faehrt weiter zur naechsten - # Station. Mubea Kreisel2: TRO02 -> SYS3 -> SYS2 -> TRO13 als Kette - # (Review 2026-10-01) - vorher endete der Fluss an SYS3, und TRO13 - # hatte keinen Vorgaenger. - if by_id[b].type_name == BOUNDARY_ENTRY: - return + # Be- und Entladestationen auf der Kreisel-Bahn werden DURCHFAHREN: der + # Kreisel laeuft immer weiter, was nicht entladen wird, faehrt an der + # naechsten Station vorbei. Systemgrenzen sind in der Umlaufkette daher + # gewoehnliche Glieder (Review 2026-10-01): Mubea Kreisel2 + # TRO02 -> SYS3 -> SYS2 -> TRO13, HundM05 Kreisel1 + # TRO19 -> SYS3 -> Beladungen -> TRO20. Vorher endete der Fluss an jeder + # Entladung, und eine Beladung durfte nie Ziel sein. pair = (a, b) edges.add(pair) edge_kinds.setdefault(pair, "bahn") @@ -1344,6 +1342,21 @@ def link_tros( if vario_id: einschleus_vario[el.teile_id] = vario_id + # Ausschleuselement-Id -> PinStore-TRO, dessen Schwerkraftlinie dort + # beginnt. Die Linien eines Speichers zweigen in der Umlaufkette eines + # Kreisels als Folge von Ausschleuselementen ab (Mubea Kreisel3: TRO05 -> + # 0060 -> 0122, 0119, ... 0065 -> TRO07); der TRO direkt davor speist den + # Speicher (Review 2026-10-01: TRO05 -> TRO18). + store_by_host = {h: t.tro_id for t in tros + if t.type_name == "PinStore_Auto" for h in t.hosts} + speicher_ausschleus: dict[str, str] = {} + for el in elements: + if el.kind != "Ausschleus": + continue + strecke_id = str(_merkmal(el.merkmale, "Strecke", "Förderer") or "") + if strecke_id in store_by_host: + speicher_ausschleus[el.teile_id] = store_by_host[strecke_id] + for el in elements: if not el.is_circle or len(el.track_ids) < 2: continue @@ -1379,6 +1392,19 @@ def link_tros( if nxt is not None and nxt != vario_id: _add_chain_pair(vario_id, nxt) + # Speicher-Abzweig: letzter Halt VOR dem ersten Ausschleuselement einer + # Speicherlinie -> PinStore-TRO. Je Speicher nur einmal, auch wenn alle + # seine Linien hintereinander in der Kette stehen. + gespeist: set[str] = set() + for i, tid in enumerate(chain): + store_id = speicher_ausschleus.get(tid) + if store_id is None or store_id in gespeist: + continue + vorher = next((o for j, o in reversed(owned) if j < i), None) + if vorher is not None and vorher != store_id: + _add_chain_pair(vorher, store_id) + gespeist.add(store_id) + # Nur TROs, fuer die die Umlaufkette tatsaechlich einen praezisen # Nachfolger gefunden hat (precise_sources) - ein TRO ohne brauchbare # TrackIds-Abdeckung behaelt seine bisherigen (ungenaueren, aber nicht