tro_annotate: Lagebezug ueber die TeileId, Ablaufbeschreibung CSV/DXF -> SCL

dxf_registration.derive_from_ids: Zeichnungen aus dxfmakros tragen an jedem
Layout-Block das Attribut ID = TeileId des CSV. tro_annotate paart CSV-
Separatoren mit den Separator-Bloecken gleicher ID (sonst Scanner) und nimmt
den Median-Versatz - eindeutig statt Abstimmung, bei jedem Lauf neu, gilt
auch fuer eine verschobene Kopie der Zeichnung. Vorrang vor abgelegtem und
abgestimmtem Bezug; --offset bleibt. Parameter id_spread_mm, id_min_share in
cfg/parameter.ini [dxf_registration].

Dematic: gemeinsame Zeichnung 0/0, Mechanik-Zeichnung dematic.dxf
+466,1/-163549,3 mm. Die Abstimmung rastete vorher auf den Scanner-Bloecken
ein (Einfuegepunkt 360 mm neben der CSV-Position) und lag 360 mm daneben.

Gesperrte Ausgabedatei (in BricsCAD geoeffnet) gibt eine Meldung statt
Traceback. Neu: doc/Workflow_CSV_DXF_to_SCL.md - der ganze Ablauf vom
CSV-Export und der Zeichnung bis zur SCL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-23 14:59:16 +02:00
parent e5d1fce41f
commit 9ec1022fb1
6 changed files with 512 additions and 10 deletions
+17 -8
View File
@@ -437,9 +437,10 @@ new shapes — a type with no prior annotated instance in the drawing must be
run through this tool at least once first.
CSV and DXF live in different coordinate systems; the offset between them is
handled by `dxf_registration.py` — derived once, verified on every run, and
cached per CSV/DXF filename pair in `%SKEL_CFG%\dxf_registration.json` unless
overridden.
handled by `dxf_registration.py`: by TeileId when the drawing's blocks carry
`ID` attributes (see "Registration by TeileId" below), otherwise derived once,
verified on every run, and cached per CSV/DXF filename pair in
`%SKEL_CFG%\dxf_registration.json` unless overridden.
| Switch | Argument | Default | Meaning |
|---|---|---|---|
@@ -483,11 +484,19 @@ Layers always carry the prefix `TRO_`. Like `tro_flow.py`, it never reads
**Output** (in `%SKEL_RESULTS%`, unless `--check`): `<name>_annotated.dxf`,
`<name>_registration.json` (the coordinate transform used, with its proof).
**Merged drawing (Dematic).** The automatic registration only sees the
top-level 3D blocks and their insert points, which sit up to ~360 mm away
from the CSV positions; on `dematic_merge..dxf` it chose a wrong dy = +360 mm
(18/59 points). CSV and merged drawing share coordinates, so annotate with
`--offset 0,0`.
**Registration by TeileId (since 2026-10-23).** Drawings built with
dxfmakros carry the attribute `ID` on every layout block — the same number the
CSV lists as `TeileId`. Unless `--offset` is given, `tro_annotate` first
pairs CSV separators with the separator blocks of the same ID
(`dxf_registration.derive_from_ids`; scanners if there are fewer than
`min_inliers` separators) and takes the median offset. That is an exact
pairing, not a vote, and is recomputed on every run (not stored), so it also
fits a moved copy of the drawing. Only if no role has enough consistent pairs
(`id_spread_mm`, `id_min_share` in `cfg/parameter.ini [dxf_registration]`)
does the stored / voted registration below apply. Dematic: the merged drawing
gives exactly 0 / 0, the mechanical-only `dematic.dxf` +466.1 / −163 549.3 mm.
Before, the vote locked onto the scanner blocks (insert point 360 mm off their
CSV position) and was 360 mm wrong on both.
**Exit codes:** `0` ok · `1` input/CLI error · `4` coordinate registration
could not be proven (or its residual error exceeds 600 mm) — resolve with
+288
View File
@@ -0,0 +1,288 @@
# Workflow: from layout CSV and merged DXF to the SCL skeleton
This page walks through the whole chain for a plant whose mechanical and
electrical layouts are drawn in **one DXF** (the Dematic case), from the first
export to the `FB_Main` SCL file that is imported into TIA Portal. Example
names are those of the Dematic plant; replace `dematic_merge` / `dematic` with
your project's names.
For the details of each tool and all its switches see
[`Python_Scripts.md`](Python_Scripts.md).
## Overview
```
BricsCAD drawing (mechanics + E-planning in one DXF)
│
├── CSV export (ILS 2.0) ──[1] tro_flow ──────────► <csv>_tro.json TROs, flow, slots, jam areas
│ │
├── merged DXF ─┐ │
│ ├──────────[2] hw_import ──────► <project>_hw.json devices with BMK, position,
└── TIA import ─┘ │ address, index constant
▼
[3] merge_hw_layout ─► <csv>_anlage.json devices bound to TRO slots
│
┌──────────────────────────────────────┤
▼ ▼
[4] tro_annotate ─► <csv>_annotated.dxf [5] scl_skeleton ─► <csv>_FB_Main.scl
(viewer: TROs, flow, jam areas)
│ edit jam numbers in BricsCAD (JAM_EDIT)
└─[6] tro_annotate --read-jams ─► cfg/<csv>_jam_names.ini ──► back into [5]
```
| Step | Tool | Reads | Writes (in `results\` unless noted) |
|---|---|---|---|
| 1 | `tro_flow` | layout CSV | `<csv>_tro.json`, flow diagram, TRO report; `cfg\<csv>_tro_ids.ini` |
| 2 | `hw_import` | merged DXF, TIA import | `<project>_hw.json`, `<project>_hw.md` |
| 3 | `merge_hw_layout` | TRO-JSON, hardware JSON, rules | `<csv>_anlage.json`, `<csv>_anlage.md` |
| 4 | `tro_annotate` | CSV, merged DXF, plant JSON | `<csv>_annotated.dxf` |
| 5 | `scl_skeleton` | plant JSON | `<csv>_FB_Main.scl` |
| 6 | `tro_annotate --read-jams` | annotated DXF (edited) | `cfg\<csv>_jam_names.ini` |
## Before you start
**Environment** (once per session, Windows):
```bat
cd C:\develop\sps_skel\bin
activate_venv.bat
```
All commands below run from `bin\`. Names without a path are looked up in
`data\` (inputs) or `results\` (intermediate files).
**Inputs in `data\`:**
| File | What it is | Where it comes from |
|---|---|---|
| `dematic_merge.csv` | Layout export (ILS 2.0): parts, TeileIds, positions, neighbours, TrackIds | Export from the **same** drawing as the DXF (dxfmakros export) |
| `dematic_merge..dxf` | Merged drawing: 3D layout blocks **and** E-symbols (blocks with attribute `IO` = BMK) | BricsCAD, saved as DXF |
| `dematic_hw-2_TIA.xlsx` | TIA import: PLC tags (address) and constants (`cIn…` / `cOut…`) | E-planning |
> The CSV must be exported from the same drawing state as the DXF. If the
> TeileIds do not match the IDs of the 3D blocks, the export is from another
> state and every assignment is wrong.
**Project configuration in `cfg\`:**
| File | Purpose |
|---|---|
| `e_planning_dematic.ini` | Rules for assigning E-symbols to layout parts (VERW texts, numbering `MB = BG`, distances) |
| `hw_overrides.ini` | Hand corrections per TRO slot role and per conveyor (Dematic: VF_4 / VF_6) |
| `dematic_merge_tro_ids.ini` | TRO IDs, created by step 1, kept stable across exports |
| `dematic_merge_jam_names.ini` | Jam-area numbers changed by hand (only exists after step 6) |
| `parameter.ini` | Tolerances and distances of all tools |
## Step 0 – put the CSV export in place
```bat
copy "C:\develop\dxfmakros\results\dematic_merge._export.csv" ..\data\dematic_merge.csv
```
The short name decides all following file names (`dematic_merge_*`).
## Step 1 – CSV → TROs (`tro_flow`)
```bat
tro_flow.bat --file dematic_merge.csv --json --doc --tosvg
```
Derives the material flow from the CSV and from it the **TROs** (Transfer
Route Objects): type (`1Sep`, `1Sep1Swi`, `Vario`, `PinStore_Auto` …),
separators, switches, scanners, predecessors and successors, the **slots** for
the hardware (separator sensor/stopper, switch valve, Vario drive …) and one
**jam area** per TRO entry.
**Outputs:** `dematic_merge_tro.json` (input for steps 3–5),
`dematic_merge_tro_doc.md` (TRO list), `dematic_merge_tro_flow.svg` (flow
diagram). TRO IDs are stored in `cfg\dematic_merge_tro_ids.ini` and found
again by separator position on the next export.
**Check:** the TRO list and the notes in `dematic_merge_tro_doc.md`; the flow
diagram. Dematic: 25 TROs, 34 connections, no errors.
## Step 2 – merged DXF + TIA → hardware JSON (`hw_import`)
```bat
hw_import.bat --tia dematic_hw-2_TIA.xlsx --dxf "dematic_merge..dxf" --project dematic --conveyor-from-motor
```
Reads every E-symbol of the drawing (BMK, VERW, BEZEICHNUNG, station,
position) and the TIA import (address, index constant `cInBG3151` /
`cOutMB3151`), joins them per BMK and pairs each motor with its motor
protection (`MA0055` ↔ `FC0055`).
- `--dxf` instead of a positions file: the positions are already layout
coordinates.
- `--conveyor-from-motor`: Dematic texts name the motor, not a `K…` number,
so the conveyor number is the motor number (`MA0055` → conveyor `0055`).
**Output:** `dematic_hw.json`, report `dematic_hw.md`.
**Check:** the cross-check section of the report. Dematic: 278 devices from
the drawing, 267 also in TIA; only the network devices (scanners `BX…`,
encoder `GF2200`, RFID `BC2050`) are not in TIA, which is expected.
## Step 3 – combine layout and hardware (`merge_hw_layout`)
```bat
merge_hw_layout.bat --tro dematic_merge_tro.json --hw dematic_hw.json --rules e_planning_dematic.ini
```
Assigns the E-devices to the TRO slots, keyed by **TRO-ID + slot + role**:
1. no coordinate registration (merged drawing, same coordinates);
2. rules from `e_planning_dematic.ini`: separator sensor by distance, stopper
by number (`MB = BG`), switch valve by the number of its jam sensor or by
distance, always one-to-one;
3. conveyors: every device whose text names a motor votes for the nearest
layout conveyor; this gives motor and motor protection per Kreisel / Vario;
4. hand corrections from `hw_overrides.ini` last.
Each binding gets a status: `zugeordnet` (assigned), `offen` (open),
`widerspruch` (contradiction, e.g. a BMK not in TIA or used twice). Only
assigned names reach the SCL.
**Output:** `dematic_merge_anlage.json` (the plant JSON), report
`dematic_merge_anlage.md`.
**Check:** the report — roles per slot type, conveyor table, open roles,
devices without assignment. Dematic: 123 roles assigned, 33 open,
0 contradictions; 11 conveyors bound.
**Corrections:** wrong or missing assignments go into `cfg\hw_overrides.ini`,
then re-run steps 3 and 5:
```ini
[dematic_merge.csv.bindings]
TRO04.separator1.sensor = BG0080
TRO04.drive.motor = MA0043
[dematic_merge.csv.conveyors]
K0045 = 0008
```
## Step 4 – annotated drawing for checking (`tro_annotate`)
```bat
tro_annotate.bat --file dematic_merge.csv --dxf "dematic_merge..dxf" --flow --legend --anlage dematic_merge_anlage.json
```
The same works on the mechanical-only drawing as background — use `--out`
so it does not overwrite the other one:
```bat
tro_annotate.bat --file dematic_merge.csv --dxf dematic.dxf --flow --legend --anlage dematic_merge_anlage.json --out dematic_annotated.dxf
```
Writes a **copy** of the drawing (`results\dematic_merge_annotated.dxf`) with
layers `TRO_*`:
- one marker per TRO (shape and colour per type, attributes `ID`, `TYPE`);
- flow arrows between the TROs (`--flow`) and a legend (`--legend`);
- one **jam area** per TRO entry (`--anlage`): a small rectangle with the name
`Jam<NNNN>_<k>`, in front of its separator, on layer `TRO_JAM`.
The position of the drawing relative to the CSV is found automatically: the
layout blocks carry the attribute `ID` = CSV `TeileId`, so the tool pairs
them and measures the offset (console line `Lagebezug … [ids, …]`). This works
for the merged drawing (offset 0) and for a moved copy such as the
mechanical-only drawing alike; no `--offset` needed.
The drawing is a **viewer**. It is not read back except for the jam numbers
(step 6).
## Step 5 – SCL skeleton (`scl_skeleton`)
```bat
scl_skeleton.bat --json dematic_merge_anlage.json --templates --strict
```
Writes `results\dematic_merge_FB_Main.scl`: one `REGION` per TRO in material
flow order, built from the reference templates (`lib\scl_templates\`), with:
- separator sensors and stoppers, switch valves, Vario motors and motor
protections from the plant JSON (`"DB_Inputs".Sensors["cInBG3151"]`,
`"MB3151"`);
- Kreisel release `#fbCarousel0055.xOutConveyorFullSpeed`;
- jam areas `"DB_JamArea0054".stJam0054_3` (see below);
- destination lists per switch exit.
Everything that is not known stays a visible placeholder marked
`TODO(E-Planung)`. `--strict` stops if any inserted name is not in the TIA
import.
**Check:** the console summary (names inserted, unknown names, open
placeholders) and the file itself — search for `TODO(E-Planung)`.
Dematic: 200 names inserted, 0 unknown, 494 placeholders left.
### Jam-area names
`"DB_JamArea<NNNN>".stJam<NNNN>_<k>`:
- `NNNN` = the conveyor the jam area sits on — the number of its Kreisel or
Vario motor (Kreisel3 with motor `MA0054` → `0054`);
- `k` = 1, 2, 3 … along the material flow on that conveyor, starting where
the material first comes onto it;
- a 1Sep behind a Vario on the same line belongs to that Vario's conveyor;
a PinStore block has one jam area for the whole block.
## Step 6 – change jam numbers in BricsCAD (optional)
1. Open `results\dematic_merge_annotated.dxf` in BricsCAD (SSG_LIB loaded,
`Jam_Edit.lsp` is part of `ssg_load.lsp`).
2. **Double-click a jam area** → dialog `JAM_EDIT`: conveyor (`NNNN`) and
running number (`k`); "Abgeleitet uebernehmen" goes back to the derived
value; a warning appears if the name already exists.
3. **Save as DXF** under the same name.
4. Take the changes over:
```bat
tro_annotate.bat --file dematic_merge.csv --read-jams
```
Every jam area whose number differs from the derived one is written to
`cfg\dematic_merge_jam_names.ini` (`TRO20.1 = 0054_9`); areas set back to
the derived value are removed from it.
5. Re-run step 5 (SCL) and, if wanted, step 4 (the drawing then shows the
corrected numbers).
The key is TRO-ID + entry, so the corrections survive a new layout export.
## When to re-run what
| What changed | Re-run |
|---|---|
| Layout (new CSV export) | 0 → 1 → 2 → 3 → 4 → 5 |
| E-planning or TIA import | 2 → 3 → 4 → 5 |
| `hw_overrides.ini` or `e_planning_dematic.ini` | 3 → 4 → 5 |
| Jam numbers in the drawing | 6 → 5 (→ 4) |
| Only the SCL templates | 5 |
## What is still open in the SCL
The 494 remaining `TODO(E-Planung)` placeholders (Dematic, 2026-10-23), by
cause:
| Group | Approx. | Why open | Next step |
|---|---|---|---|
| Program numbering (`cSep`, `cMainTro`, `cSwi`, storage constants) | 140 | Numbering convention of the PLC program, not in any input | Agree a convention with the PLC team |
| Timings marked "pruefen" | 117 | Reference values filled, only marked for review | Commissioning |
| Cabinet / safety / automatic signals | 57 | Plant-wide signals | One decision for all TROs |
| Line and exit jam sensors, Vario sensors | 75 | No assignment rule yet; the devices are in the drawing | Extend `e_planning_dematic.ini` |
| Scanners | 39 | Network devices, signal names come from the TIA hardware configuration | Naming scheme from the PLC side |
| Conveyor signals, unclear meaning | ~45 | Infeed/outfeed conveyors, `xIsBorner`, switch split | Delete where not needed / ask the PLC team |
| Other | ~20 | Acknowledge buttons `SF…` (cabinet, not drawn), PinStore reference sensor, `FC_Direction` carrier, one switch valve | Rules / hand corrections |
## Known limits
- **VF_4 / VF_6 (Dematic):** mechanical parts are still missing there; the
assignments are set by hand in `hw_overrides.ini` from the drawing texts.
Seven E-separators without a mechanical part are ignored until the layout
is complete.
- **Registration:** automatic by TeileId for drawings built with dxfmakros.
A drawing without `ID` attributes falls back to the older point vote, which
can be off by a few hundred mm — check the `Lagebezug` line and use
`--offset DX,DY` if needed.
- **The drawing is a viewer:** TRO IDs and types changed in BricsCAD
(`TRO_EDIT`) are not read back; only jam numbers are (step 6).