Files
sps_skel/doc/E-Planung_Bruecke.md
T
Samer AyadiandClaude Opus 5.5 df24cf5adb hw_import + merge_hw_layout: Hardwareplanung einlesen und mit dem Layout zusammenfuehren
Stufen 2 und 3 aus doc/Konzept_Layout_Hardware_SCL.md:

- lib/hw_import.py: TIA-Import (*_TIA.xlsx, ohne openpyxl gelesen) +
  Positionsdatei (*_positionsconv.json) -> <projekt>_hw.json: je BMK
  Adresse, Index-Konstante, VERW, Station, Lage, Foerderer (K0102, #106 ->
  K0106); Antriebe MA/FC/GF; Gegenpruefung beider Quellen.
- lib/merge_hw_layout.py: <csv>_tro.json + <projekt>_hw.json ->
  <csv>_anlage.json (model.AnlageDocument): bindings je TRO-ID + Slot +
  Rolle mit Konstante und Adresse, Foerderer per Mehrheit (Mubea: K0102 =
  Kreisel3, K0104 = Kreisel2, K0105 = Kreisel1), Handkorrekturen
  cfg/hw_overrides.ini. Zuordnungslogik aus e_planning.py hierher
  verschoben; e_planning re-exportiert sie, Ergebnis unveraendert.
- TRO-JSON traegt optional `parts` (Lage/Huellbox, tro_flow --json),
  PinStore bekommt Slots line<n>.
- Gespeicherter Lagebezug mit SHA-256 der Positionsdatei; Unterordner in
  Eingabenamen relativ zu SKEL_DATA.
- Doku: Python_Scripts.md 5d/5e, Konzept, E-Planung_Bruecke (Abgleich
  mubea_layout.dxf / CSV / E-Planung).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 16:16:10 +02:00

291 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Brücke Layout ↔ E-Planung über `*_positionsdraw.json`
Stand 2026-10-15. Erst Machbarkeitsprüfung, inzwischen umgesetzt als
`lib/e_planning.py` (Regeln `cfg/e_planning.ini`, Aufruf `bin/e_planning.bat`,
`scl_skeleton --eplan`); Bedienung in `doc/Python_Scripts.md` §5c, Stand der
Umsetzung unten. Am 2026-10-15 mit dem neuen Mubea-Datensatz in `data/Mubea/`
(TIA-Import + Positionsdatei) nachgeprüft; Ergebnisse unter "Nachprüfung
2026-10-15".
## Problem
Das Kapitel "Daten" in `doc/Klassenhierarchie.md` zeigt: das Hardwarelayout (CSV)
liefert die **Struktur** (welche TROs, welche Separatoren/Weichen, wer mit wem), die
E-Planung die **Namen und Adressen** (`BG…`, `MB…`, `MA…`, `FC…`). Die EA-Liste allein
kennt aber keine Topologie. Es fehlt die Zuordnung **Layout-Bauteil (CSV-`TeileId`) →
Betriebsmittelkennzeichen (BMK)**.
## Idee
Die E-Planung wird als Layer über der Hardwareplanung gezeichnet: Sensor- und
Aktorsymbole liegen in der Zeichnung neben dem Bauteil, zu dem sie gehören. Das
Kabellängen-Tool (`C:\10-Develop\gitrepos\kabellaengen`, `lib/getpositions.py`)
schreibt diese Symbole mit Position und Attributen nach `<zeichnung>_positionsdraw.json`.
Damit ist die Brücke eine **räumliche Zuordnung**: E-Symbol → nächstes Layout-Bauteil
passender Art.
## Datenquelle `*_positionsdraw.json`
| Schlüssel | Inhalt | Nutzen für sps_skel |
|---|---|---|
| `sensors` | je BMK (`BG0642@UNKNOWN`): `pos` [x, y], `VERW` (Verwendung), `BEZEICHNUNG` (Klartext), `BESCHR`, `ARTINR`, `KENNZEICHNUNG` (`=A1+UH01-KF107`) | Hauptquelle: Sensoren/Ventile/Motoren im Feld |
| `schaltschrank_elemente` | Elemente im Schrank (Motorschutz `FC…`, Taster, Leuchten, `QA…`) mit `VERW`, `BEZEICHNUNG`, `KENNZEICHNUNG`, ohne Feldposition | Motorschutz ↔ Motor, Bedienelemente |
| `mappings` | Steuerung → Liste ihrer BMK (`UH01: [...]`) | Steuerungsaufteilung, Nummernkreis |
| `racks`, `distributors`, `tunnels` | Kabeltrassen, Verteiler | für sps_skel ohne Belang |
| `double_ids`, `warnings` | doppelte BMK, fehlende Attribute | Qualitätsprüfung der E-Daten |
Die Erdungs-Beispiele (`PR500501_…_Erdung_…`, `ST500652_…`) enthalten nur
Potentialausgleich (`POT…`) und taugen nicht für die Brücke. Brauchbar sind
Dateien mit `BG`/`MB`/`MA`: `Mubea_positionsdraw.json` (158 Feld-BMK, davon 157
in `mappings` unter UH01 — `BG0514` hat eine leere `KENNZEICHNUNG`),
`ST500592_ILS_positionsdraw.json` (~3100), `ST500592_10_5-10_Omniflo_…` (~900),
`ST-Fortna_positions_.json` (mit 38 Scannern `BX`).
`*_positionsconv.json` und `*_positionsdraw.json` sind bei Mubea byte-gleich;
eine von beiden genügt.
## Datenquelle TIA-Import `*_TIA.xlsx`
Die zweite nötige Quelle. Blatt **PLC Tags**: je Signal Name (`BG0542`),
Absolutadresse (`%E…`/`%A…`), Kommentar. Blatt **Constants**: je Signal eine
Index-Konstante `cIn<BMK>`/`cOut<BMK>` (laufender Index, **nicht** aus der
Adresse berechenbar).
| Nutzen | Warum |
|---|---|
| SCL übersetzbar | Sensoren stehen im SCL als `"DB_Inputs".Sensors["cInBG…"]`, Ventile als `"MB…"`; beides muss im TIA-Projekt existieren — der TIA-Import liefert genau diese Tags und Konstanten |
| Prüfliste | jeder Name im erzeugten SCL muss im TIA-Import stehen |
| `FB_CallSensors`, Größe `DB_Inputs` | alle `cIn…`-Konstanten mit Wert (noch nicht generiert) |
| Schrank- und Antriebssignale | `SF…` (Taster, Not-Halt), `PF…` (Leuchten), `MA…`/`FC…` (Motor/Motorschutz), `GF…` (Geber), `BP…`, `DI…` |
Mubea: 237 Tags (105 BG, 64 MB, 26 SF, 17 PF, 11 MA, 11 FC, je 1 BP/DI/GF) und
237 Konstanten (144 `cIn`, 93 `cOut`). Alle 158 Feld-BMK und 80 von 81
Schrankelementen (fehlt: `QA7000`) der Positionsdatei stehen im TIA-Import, die
Kommentare sind 1:1 gleich der `BEZEICHNUNG`.
**Nicht nötig** (Mubea): `*_EA.xlsx` (dieselben 237 Signale, nur Adresse und
Kommentar, keine Namen), `*_WSCAD.xlsx` (zusätzlich nur die E/A-Baugruppe je
Kanal, die `KENNZEICHNUNG` der Positionsdatei schon trägt, und 259 freie Kanäle),
`*_BOM.xlsx`, `*_cables.*`, `*_todraw.json`, `*_errors.json` (Kabel, Stückliste,
Trassen; die Qualitätswarnungen stehen auch in der Positionsdatei). Eingaben für
die Brücke also: **CSV + TIA-Import + eine Positionsdatei**.
## Test an Mubea
Eingaben: `data/mubea.csv` (Layout, 38 Separatoren) und
`kabellaengen/work/Mubea_positionsdraw.json` (E-Planung, alter Stand). Die Zahlen
in diesem Abschnitt stammen aus der ersten Untersuchung (Umkreis 700 mm, ohne
Regeln); das Ergebnis der Umsetzung und die Nachprüfung mit dem neuen Stand
`data/Mubea/Mubea_positionsdraw.json` stehen unten.
### 1. Lagebezug
Die Ermittlung aus `lib/dxf_registration.py` (`derive_transform`) funktioniert
unverändert, wenn man die E-Symbole mit `VERW` `SEP`/`IN SEP` als Rolle "Separator"
einsetzt:
```text
mubea.csv <- Mubea_positionsdraw.json: dx +50613.6 mm, dy +8555.8 mm, Drehung 0
26/38 Separatoren im Toleranzband
```
Das entspricht dem schon gespeicherten Bezug `mubea.csv|500573_60_1.dxf`
(dx +50833.7, dy +8414.5) bis auf ~250 mm: diese (alte) E-Zeichnung lag im selben
Koordinatensystem wie die Layoutzeichnung. Zum Prüfen genügt also der
bestehende Mechanismus; als Schlüssel in `cfg/dxf_registration.json` dient
`<csv>|<positionsdraw.json>`.
Das gilt **nicht allgemein**: der neue Stand in `data/Mubea/` liegt in einem
anderen Koordinatensystem (dx −151.4, dy −696.6, siehe "Nachprüfung
2026-10-15"). Der Lagebezug ist je Datei neu zu ermitteln, nicht von der
Layoutzeichnung zu übernehmen.
### 2. Was sich zuordnen lässt
| E-Symbol (`VERW`) | Layout-Partner | Abstand | Ergebnis |
|---|---|---|---|
| `IN SEP` (BG, Sensor im Separator) | Separator | **0–1 mm** im Pin-Speicher (20/20), sonst 200–500 mm | Anker: das Symbol sitzt auf dem Separator |
| `SEP` (MB, Stopperventil) | Separator | konstant **~270 mm** daneben | eindeutig über Nummernregel (unten), nicht über Abstand |
| `AE ABZWEIG` (MB, Ausschleusventil) | Ausschleuselement | konstant **1414 mm** (20/20, Versatz (−1405, −159)) | eindeutig, wenn der Versatz je Symbolart bekannt ist |
| `STAU_REF-LT` (BG, Stausensor) | Ausschleuselement | konstant **1391 mm** (20/20) | wie oben |
| `ABZWEIG-K104` (MB, Weiche) | Weiche | 783 mm | eindeutig (nur eine Weiche) |
| `BANDBRUCH`, `KETTENBRUCH`, `ÜBERGABE`/`ÜBERNAHME`, `SYNC P1..4`, `ZAPPLER` | Kreisel/Strecke/Station | uneinheitlich, teils > 50 m (Symbol an Konvejoren außerhalb des CSV-Ausschnitts) | nicht über Abstand, nur über `BEZEICHNUNG` |
Nebeneinander liegende Separatoren (Pin-Speicher, Raster 800 mm) machen den
Abstand allein mehrdeutig: das MB von Strecke n liegt 270 mm von Separator n und
530 mm von Separator n+1. Eindeutig wird es erst mit der Nummernregel.
### 3. Nummernregel der E-Planung
Ventil = Sensor + 1, gleiche Funktionsgruppe:
| Paar | Treffer (von 58 MB) |
|---|---|
| `MB(n)` `SEP` ↔ `BG(n−1)` `IN SEP` (z. B. BG0642 / MB0643) | 31 |
| `MB(n)` `AE ABZWEIG` ↔ `BG(n−1)` `STAU_REF-LT` (z. B. BG0542 / MB0543) | 21 |
| sonstige Paare (`VEREINZ(CP)`, `STOPPER (CP)`, `AE ABZW.`) | 3 |
| ohne BG-Partner | 3 |
Damit reicht es, den **Sensor** räumlich zuzuordnen (der `IN SEP` liegt auf dem
Separator); das Ventil folgt aus der Nummer. Die SCL-Referenzen zeigen dasselbe
Muster (`stSenInSep := …["cInBG3242"]`, `xOutStopper1 => "MB3242"`) — dort sogar
mit gleicher Nummer; die Regel ist also projektabhängig und gehört in eine
Konfiguration, nicht in den Code.
Gleiches gilt für Motor ↔ Motorschutz: `MA0200` "PIN CONVEYOR#100" ↔
`FC0200` "MOTORSCHUTZ CONVEYER #100" (gleiche Nummer, `schaltschrank_elemente`),
wie in der SCL `xOutVarioMotor => "MA0145"`, `xInMotorProtection := "FC0145"`.
### 4. Was nicht passt
12 von 38 Layout-Separatoren (vor allem an den Kreiseln K0102/K0104/K0105) haben im
Umkreis von 700 mm kein `IN SEP`/`SEP`; umgekehrt liegen mehrere `IN SEP` des
Kreisels K0102 neben Aus-/Einschleuselementen statt neben einem Separator. Vermutlich
ist die CSV (aus `500573_60_1.dxf`) ein anderer Planungsstand als die E-Zeichnung
`Mubea.dxf` des Kabellängen-Tools, oder Kreisel-Separatoren sind im CSV anders
modelliert. Das muss mit zueinander passenden Ständen geprüft werden, bevor man
eine Quote angibt.
`Mubea_positionsdraw.json` enthält **keine Scanner** (`BX`). Für Scanner-Zuordnung
ist ein anderes Projekt nötig (`ST-Fortna_positions_.json`, `ILS-Baugruppe`).
## Was die Brücke für das Kapitel "Daten" liefert
| SCL-Datum | aus `positionsdraw.json` | Regel |
|---|---|---|
| `stInSeparator<n>.stSenInSep` | BG mit `VERW` `IN SEP` | räumlich am Separator (Anker) |
| `xOutStopper<n>` | MB mit `VERW` `SEP` | Nummernregel ab dem BG |
| `stInSenJam<n>`, `Settings.xPluggedJam` | BG `STAU_REF-LT` | räumlich, Versatz je Symbolart; vorhanden ⇒ `xPluggedJam := TRUE` |
| `xOutSw<n>ExTo3/4` | MB `AE ABZWEIG` / Weichen-MB | Nummernregel ab dem Stausensor bzw. räumlich an Weiche/Ausschleuselement |
| `Settings.xPluggedPart`, `stSenPart` | BG `BT BELADEN` | räumlich; vorhanden ⇒ `TRUE` |
| `xInMotorProtection`, `xOutVarioMotor` | MA im Feld + FC in `schaltschrank_elemente` | gleiche Nummer |
| `xInCarouselRun` (welcher Antrieb) | FC/MA-`BEZEICHNUNG` "KREISEL-K0102", "CONVEYOR #100" | **räumlich**, nicht über Text: das CSV nennt die Kreisel `Kreisel1/2/3`, die E-Planung `K0102/K0104/K0105`. Alle Symbole, deren `BEZEICHNUNG` einen Kreisel nennt, per Mehrheit dem nächsten CSV-Kreisel zuordnen (siehe Nachprüfung) |
| Steuerung, TRO-Nummernkreis, `stInOutMachineState` | `KENNZEICHNUNG` `=A1+UH01-KF107`, `mappings` | `UH01` = Steuerung, `KF107` = E/A-Station |
| Plausibilisierung | `BEZEICHNUNG` "SEPARATOR STR. 14", "KR-K0102 VOR BT-BELADUNG" | Strecken-/Kreiselnummer gegen Layout prüfen |
Nicht aus dieser Quelle: Scanner-Hardwarekennungen, Weichenbauart (`xNewSwitch`).
Auch nicht aus den E/A-Daten, aber **je Projekt nur ein Wert**: `xInSftyOk`,
`stInOutMachineState`, `xInAutomatic`, `xInErrorQuit`. Der TIA-Import enthält
zwar die Not-Halt-Kanäle (`SF5000…SF6006`) und `SF0001` "ANLAGE EIN" / `SF0002`
"START NACH STÖRUNG", die Referenz-SCL verdrahtet diese Parameter aber nicht mit
E/A-Signalen, sondern mit dem Sicherheitsprogramm
(`"DB_InterfaceSafety".stFromSafety.EStopMain….Q`) bzw. der Schrank-Struktur
(`#stInOutControlUnitCabinet…`). Sie gehören als Projektkonstanten in eine
Konfiguration (bei Mubea ~39 der offenen Stellen), nicht in die Brücke.
## Umsetzung (Stand 2026-10-10)
1. **`lib/e_planning.py`**: liest `*_positionsdraw.json` in `EDevice` (BMK, VERW,
Bezeichnung, Kennzeichnung → Steuerung/E/A-Station, Position).
2. **Lagebezug** über `dxf_registration.derive_transform` mit den `IN SEP`-Sensoren
als Rolle "Separator"; abgelegt in `cfg/dxf_registration.json` unter
`<csv>|<positionsdraw.json>`.
3. **Regeln in `cfg/e_planning.ini`** (projektabhängig): je Rolle Layout-Art, VERW,
Höchstabstand, **Sollabstand** (für die konstanten Versätze von Stausensor und
Ausschleusventil — sonst gewinnt bei 0080/0084 ein näherer, fremder Stausensor
des Kreisels K0102) und die Nummernregel (`MB = BG + 1`).
4. **Ausgabe** `<csv>_eplan.json` (`EplanDocument`) und Bericht `<csv>_eplan.md`.
`scl_skeleton --eplan` setzt Separator-Sensor und Stopperventil ein
(`SclName.todo = False`); alles andere bleibt `TODO(E-Planung)`.
Ergebnis Mubea (alter Stand) mit den ausgelieferten Regeln: Separator-Sensor 21/38,
Stopper 22/38, Stausensor 20/23, Ausschleusventil 20/23, Weichenventil 1/1. Den
Separator-Sensor nimmt die Regel nur bis 300 mm; die Kreisel-Fälle mit 470–540 mm
(z. B. BG0532 an 0044) bleiben bewusst offen.
## Nachprüfung 2026-10-15 (neuer Stand `data/Mubea/`)
Lauf: `e_planning --file mubea.csv --eplan <voller Pfad>\data\Mubea\Mubea_positionsdraw.json`,
dann `tro_flow --json` und `scl_skeleton --eplan --templates`.
| | alter Stand | neuer Stand |
|---|---|---|
| Lagebezug | dx +50613.6, dy +8555.8 | **dx −151.4, dy −696.6**, Drehung 0, 23/38 Punkte, Restfehler max 541 mm |
| Separator-Sensor | 21/38 | 21/38 |
| Stopper | 22/38 | 22/38 |
| Stausensor | 20/23 | **21/23** |
| Ausschleusventil | 20/23 | **19/23** |
| Weichenventil | 1/1 | 1/1 |
| Antriebe | — | 11, alle mit Motorschutz |
Im erzeugten `FB_Main` (18 TROs): 43 Namen aus der E-Planung, 440 Stellen
`TODO(E-Planung)`. Alle 21 Konstanten und 22 Tags im SCL stehen im TIA-Import.
Befunde:
- **Pfad:** `--eplan Mubea/Mubea_positionsdraw.json` (Unterordner relativ zu
`%SKEL_DATA%`) wird nicht gefunden; nur ein Dateiname direkt in `%SKEL_DATA%`
oder ein voller Pfad geht.
- **Gespeicherter Lagebezug:** der Schlüssel `<csv>|<positionsdraw.json>` in
`cfg/dxf_registration.json` enthält nur den Dateinamen. Ein neuer Stand mit
gleichem Namen übernimmt ohne `--re-register` still den alten Bezug — beim
Mubea-Wechsel wären das ~51 m Versatz gewesen.
- **Kreisel-Zuordnung räumlich möglich:** die Symbole, deren `BEZEICHNUNG` einen
Kreisel nennt (nach dem Lagebezug, Abstand zur Boundingbox), liegen eindeutig
auf einem CSV-Kreisel — **K0102 = Kreisel3 (0010)**, **K0104 = Kreisel2 (0002)**,
**K0105 = Kreisel1 (0001)**; ein Ausreißer (`BG0725` "BANDBRUCHÜBERWACHUNG
KR-K0105" an Kreisel2). Damit erhält jeder Kreisel seinen Antrieb
(`MA0202`/`FC0202`, `MA0205`/`FC0205`, `MA0206`/`FC0206`) und K0102 seinen Geber
`GF20000`.
Was sich mit TIA-Import + Positionsdatei noch schließen lässt:
| Offene Stellen (Mubea) | Anzahl | Weg |
|---|---|---|
| `stInSenJam<n>` | ~17 | schon zugeordnet; fehlt nur TRO-Ausgang → Ausschleuselement (siehe "Offen") |
| `xInCarouselRun` | ~13 | Kreisel-Zuordnung oben + Motorpaar |
| Vario-Sensoren (`stSenLastPos`, `stSenJam`, `stSenFinger`, `stSenCarrInPos`), `xOutVarioMotor`, `xInMotorProtection` | ~18 | wahrscheinlich, neue Regeln über `VERW` (`SYNC P1..4`, `ZAPPLER`, `ABFR.FINGER`, `BT BELADEN`) und die Motorpaare; zu prüfen |
| `xInSftyOk`, `stInOutMachineState`, `xInAutomatic`, `xInErrorQuit` | ~39 | Projektkonstante (oben), nicht aus diesen Dateien |
| `nSeparatorNo`/`nSwitchNo`, Zeiten, Staubereichs-Verdrahtung | Rest | weder TIA noch Positionsdatei |
Die 17 nicht zugeordneten Separatoren an den Kreiseln sind ein Standunterschied
Layout ↔ E-Zeichnung, keine fehlenden Daten.
Offen:
- Stausensoren und Ausschleus-/Weichenventile stehen in JSON und Bericht, kommen
aber noch nicht in die SCL: die TRO-JSON sagt nicht, welches Ausschleuselement
bzw. welche Weiche zu welchem TRO-Ausgang gehört.
- Die Lagerlinien eines `PinStore`-TRO (`arInSep[n]`) sind zugeordnet, der
Generator erzeugt die Linienparameter aber noch nicht.
- Scanner (`BX`) fehlen in den Mubea-Daten; Regel und Test mit
`ST-Fortna_positions_.json` stehen aus.
- Ein Abgleich mit passenden Ständen von CSV und E-Zeichnung für die Kreisel.
- ~~TIA-Import einlesen~~ — **erledigt** 2026-10-15: `lib/hw_import.py`
(`<projekt>_hw.json`); `FB_CallSensors` daraus steht noch aus.
- ~~Kreisel ↔ E-Kreisel (`K01xx`) räumlich zuordnen~~ — **erledigt** in
`lib/merge_hw_layout.py` (Mehrheit, nur Förderer der genannten Art); in die SCL
(`xInCarouselRun`) kommt es mit der Umstellung von `scl_skeleton` auf die
Anlagen-JSON.
- ~~Gespeicherten Lagebezug absichern~~ — **erledigt**: SHA-256 der
Positionsdatei im Eintrag von `cfg/dxf_registration.json`.
- ~~Unterordner in `--eplan`~~ — **erledigt** (`material_flow.resolve_input`).
## Abgleich Layoutzeichnung ↔ CSV ↔ E-Planung (2026-10-15)
Zeichnung `data/mubea_layout.dxf` (aus `mubea_layout.dwg`), gelesen über alle
Blockebenen mit vollständiger Blocktransformation (die `Staustrecke…`-Blöcke
der Gefällestrecken sind mit gekippter Extrusionsrichtung eingefügt; ohne
OCS liegen ihre Separatoren falsch).
| Vergleich | Ergebnis |
|---|---|
| DXF ↔ `mubea.csv` | **gleiches Koordinatensystem, kein Versatz.** 38/38 Separatoren je 60–70 mm (Einfügepunkt `Separator_SP_3D` gegen CSV-Punkt, in Blockrichtung), 8/8 Scanner je 360 mm, Aus-/Einschleuselemente 22/23 bzw. 22/23 auf 0 mm (`0061`, `0064` und die Weiche `0125` sind keine eigenen Blöcke) |
| E-Planung ↔ DXF | (−211, −697) mm; Speicherlinien 20/20 auf **1 mm** |
| E-Planung ↔ CSV | (−151, −697) mm; 23/38 im Toleranzband |
Die 20 Separatoren der Gefällestrecken passen mit dem Versatz exakt (ohne ihn
liegt jeder Sensor eine Speicherlinie daneben, 235 mm). Die 12 Separatoren an
Kreiseln/Strecken und die 6 Vario-Separatoren passen in **keiner** Lage
(155–3438 mm, mit und ohne Versatz). Es gibt also keine starre Transformation
für die ganze Anlage: der Speicher ist in der E-Zeichnung als Ganzes
verschoben, der Bereich um die Kreisel ist ein anderer Planungsstand.
Folge: die Kreisel-Separatoren bleiben offen, bis E-Zeichnung und Layout zum
selben Stand gehören; `merge_hw_layout` warnt deshalb (23/38 = 61 %).
Nebenbefund für `tro_annotate` (Kontrollansicht): es liest nur die
Modellbereichs-Blöcke (12 der 38 Separatoren, die übrigen stecken in
`GF_n`/`VF_n`), und der Lagebezug übernimmt den 60-mm-Einfügeversatz als
scheinbare Verschiebung (dx +59.8).