merge des aktuelllen Standes

This commit is contained in:
Samer Ayadi
2026-09-17 13:23:37 +02:00
3 changed files with 246 additions and 83 deletions
+36 -6
View File
@@ -162,12 +162,42 @@ id ranges, e.g. `Gefaellestrecke 0017 - 0036 (20x)` / `Separator (20): 0037 -
in `lib/material_flow.py`) — the underlying graph, `--doc` report and
`--connect` output are unaffected and still list every line individually.
Flow direction between conveyor segments is derived from height change
(`Hoehe_Von_mm`/`Hoehe_Bis_mm`) or, failing that, from `Antriebfahrtrichtung`
("Auf"/"Ab"); connections whose direction can't be determined are drawn
bidirectional and reported as a warning. `--doc` additionally cross-checks
stated `Anzahl_Separator`/`Anzahl_Scanner` counts against what was actually
attached.
Flow direction between a Kreisel and a Strecke/Gefällestrecke is set from the
**Ausschleus-/Einschleuselement** at each end (`_apply_transfers`): the
Ausschleuselement is the Kreisel outlet (Kreisel → Strecke, start), the
Einschleuselement the inlet (Strecke → Kreisel, end). A conveyor whose two ends
dock on the *same* Kreisel (a return line — Eingang and Ausgang on one Kreisel)
is drawn as **two** edges — one onto each lane (`0006-L → VF` on the way out,
`VF → 0006-R` on the way back) — so it is never flat/undetermined. The transfer
element names its conveyor via the `Strecke` **or** `Foerderer`/`Förderer`
attribute (both are read).
Where no transfer element resolves the direction, `drive_uphill` applies the
physics rule: **only a pure Gefällestrecke** takes its direction from the height
(`Hoehe_Von_mm`/`Hoehe_Bis_mm` → flows downhill; a GF with no height runs downhill
by definition). A Förderer (VF) can convey up *or* down and a `Strecke` is often
a mixed GF/VF chain, so **height is not a direction indicator for them** — they
use an unambiguous `Antriebfahrtrichtung` (exactly `"Auf"`/`"Ab"`, not a mixed
list like `"horizontal,horizontal,Auf"`) and otherwise stay undetermined
(direction is expected to come from the AS/ES ends). Only what nothing resolves
is drawn bidirectional and reported as a warning.
Entry/exit stations are hung on the Kreisel **lane** they belong to
(`_attach_stations`): first the Kreisel whose `TrackIds` umlauf lists the station,
then the entry-/exit-lane from its `Drehrichtung` (UZS → entry lane R / exit lane
L, GUZ reversed). Sources (`Beladung`/`Eingang`) get `Station → lane`, sinks
(`Entladung`/`Ausgang`) `lane → Station`. Neighbours that aren't flow objects
(another station, a separator) are skipped, so two BTMT points no longer get
wired to each other.
`Eingang`/`Ausgang` are the **generic symbols** for the concrete BTMT stations
`Beladung`/`Entladung` (same source/sink role). When a symbol lies almost on top
of a BTMT station of the same role (≤ `STATION_MERGE_MM` = 600 mm, `x`/`y` from
the `Position` column), only **one** node is drawn: the concrete BTMT station is
kept, the generic symbol is swallowed (`_merge_station_symbols`). A standalone
`Eingang`/`Ausgang` with no nearby BTMT partner is drawn as its own green/red
node. `--doc` additionally cross-checks stated `Anzahl_Separator`/`Anzahl_Scanner`
counts against what was actually attached.
`--track` builds a second, finer-grained graph in addition to the one above:
Separator, Ausschleus-/Einschleuselement, Weiche and the entry/exit points
+5 -1
View File
@@ -46,7 +46,11 @@ Kreisel 0001 trackIds = [0040(Sep@0001-R), 0079(Weiche), 0036(Sep@0014)]
4. **Systemgrenzen** — BTMT Be-/Entladung werden über den bereits im groben
Graphen aufgelösten Anschluss angebunden (`_attach_track_stations`); offene
Bahnenden ohne Station bekommen ein generisches Symbol Eingang/Ausgang
(`_attach_track_symbols`). Wichtig: die Offenheit wird am **feinen** Graphen
(`_attach_track_symbols`). Ein generisches Eingang/Ausgang-Symbol, das
deckungsgleich über einer konkreten BTMT-Station liegt (≤ `STATION_MERGE_MM`),
wird auch hier verschluckt (`_merge_station_symbols`) — sowohl aus der
Knotenliste als auch aus den `TrackIds` jedes Containers —, sonst liefe der
Kreisel-Umlauf durch zwei nahezu identische Knoten. Wichtig: die Offenheit wird am **feinen** Graphen
gemessen (ein reales Bahnelement ohne Vorgänger/Nachfolger in `track.edges`),
**nicht** am groben. Der grobe Graph kann eine Bahn als offenes Ende führen,
obwohl ihre AS/ES-Enden im Kreisel-Umlauf längst verkettet sind (die Richtung