Files
sps_skel/doc/HundM/suggestion.md
T

235 lines
9.7 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.
# Vorschlag: Vereinheitlichung der MainTRO-Bausteine (`FB_ILS_MTRO`)
Stand: 2026-07-13
## Ausgangslage
Die Anlage verwendet derzeit **sieben verschiedene MainTRO-Bausteine**, die aus dem
SPS-Code extrahiert wurden:
| Typ | Separatoren | Weichen | Eingänge | Ausgänge (Richtungen) | Prio-Manager | Scanner | Besonderheit |
|---|---|---|---|---|---|---|---|
| `FB_ILS_MTRO_1Sep` | 1 | 0 | 1 | 1 (Exit2) | 1 | 1 | Borner/Dummy-Handling |
| `FB_ILS_MTRO_1Sep_SSCC` | 1 | 0 | 1 | 1 | 1 | 2 (+SSCC) | Endmess-Sensor |
| `FB_ILS_MTRO_1Sep1Swi` | 1 | 1 | 1 | 2 (Exit2/3) | 2 (Dir1/2) | 1 | 2. Kreisel |
| `FB_ILS_MTRO_1Sep2Swi` | 1 | 2 | 1 | 3 (Exit2/3/4) | 1 | 1 | 2. Kreisel |
| `FB_ILS_MTRO_2Sep1Swi` | 2 | 1 | 2 | 2 | 4 (Dir1-4) | 2 | 2 Eingänge, 2 Kreisel |
| `FB_ILS_MTRO_Vario` | 1 | 0 (Vario) | 1 | 1 (+Finger-Jam) | 1 | 1 | Kettenförderer, Finger-/Pos-Sensoren, Motorschutz |
| `FB_ILS_MTRO_PinStore_Auto` | 1 + 21 | n | 1 | n Stationen | 1 | 1 | **Ausreißer** — Lagerblock, Encoder, Lagerlinien |
## Kernerkenntnis
Alle MainTRO-Varianten basieren auf **demselben Grundgerüst**: ein `FB_StateManager`
mit identischer Schrittkette
(`WaitForTrolley → Scan → CheckLoad → CheckSep → GetDirection → CheckJam → CheckSwitch → ReleaseSep → Buchen`),
plus zusammengesetzte Sub-TRO-Bausteine (`FB_ILS_STRO_Sep`, `FB_ILS_STRO_Switch`,
`FB_ILS_STRO_Vario`, `FB_BarcodeReaderCognex`).
Was sich zwischen den Typen unterscheidet, ist fast ausschließlich die **Anzahl**
einiger Sub-Module und die entsprechende Zahl an Staubereichen/Richtungen. Das
Namensschema `<nSep>Sep<nSwi>Swi` bringt es auf den Punkt: Es sind keine 7 Verhaltensweisen,
sondern **ein Verhalten**, instanziiert mit 12 Separatoren, 02 Weichen, 14 Richtungen.
Der skalare Teil der Schnittstelle ist **überall identisch**: `stInSettings` (Borner,
Jam-Src/Dest, `bSepType`, Timings), `nInMainTroNo`, `xInSftyOk`, `xInAllRdyToStart`,
`xInTestMode`, `xInCancel`, `xInAreaStopActive`, `xInRelease`, dazu die Ausgänge
`xOutCorrection / nOutStateLast / nOutScanResult / xOutNewScan` und die In-Outs
`stInOutMachineState / stInOutCognexInterface / stInOutHMI`. Lediglich die
*wiederholten* Elemente werden von Hand vervielfältigt und durchnummeriert
(`...1`, `...2`, `Dir1..Dir4`, `Exit2..Exit4`).
## Vorschlag: ein einziger Baustein `FB_ILS_MTRO`
Die von Hand nummerierten Member werden durch **Arrays von zusammengesetzten UDTs**
ersetzt, plus einen **Konfigurations-/Routing-Deskriptor**, der angibt, wie viele
Elemente jeder Art existieren und wie jede Richtung verdrahtet ist. Der skalare Kern
bleibt unverändert.
### 1. Vereinheitlichte TRO-Typdefinition (ersetzt die 7 `fbType`-Namen)
```json
{
"$def": "FB_ILS_MTRO",
"description": "Single MainTRO block, shaped by config instead of by type name",
"config": {
"nNoOfSeparators": { "type": "USInt", "range": [1, 2] },
"nNoOfSwitches": { "type": "USInt", "range": [0, 2] },
"nNoOfCarousels": { "type": "USInt", "range": [1, 2] },
"nNoOfDirections": { "type": "USInt", "range": [1, 4] },
"xScannerPlugged": { "type": "Bool" },
"xSsccPlugged": { "type": "Bool" },
"xVarioMode": { "type": "Bool" }
},
"arrays": {
"arInSeparator": "Array[1..2] of UDT_MTRO_SeparatorIf",
"arInSwitch": "Array[1..2] of UDT_MTRO_SwitchIf",
"arInDirection": "Array[1..4] of UDT_MTRO_DirectionIf",
"arInPriorityManager": "Array[1..4] of UDT_Response",
"arInCarouselRun": "Array[1..2] of Bool",
"arInOutJamEntr": "Array[1..2] of UDT_JamArea",
"arInOutJamExit": "Array[1..4] of UDT_JamArea"
},
"scalarCore": [
"stInSettings", "nInMainTroNo", "xInSftyOk", "xInAllRdyToStart",
"xInTestMode", "xInCancel", "xInAreaStopActive", "xInRelease",
"stInOutMachineState", "stInOutHMI"
]
}
```
### 2. Die zusammengesetzten UDTs, die als Array geführt werden
```json
{
"UDT_MTRO_SeparatorIf": {
"stSenInSep": "UDT_Sensor", "stSenSepLeft": "UDT_Sensor",
"stSenPart": "UDT_Sensor", "stSenStartScan": "UDT_Sensor",
"stSenJamExit": "UDT_Sensor",
"Settings": "SettingsSeparator",
"bSepType": "Byte", "xIsBorner": "Bool", "nBornerDest": "Int"
},
"UDT_MTRO_SwitchIf": {
"stSenExit3": "UDT_Sensor", "stSenExit4": "UDT_Sensor",
"Settings": "SettingsSwitch"
},
"UDT_MTRO_DirectionIf": {
"xPrioRelevant": "Bool",
"nSepIndex": "USInt", "nSwitchIndex": "USInt", "nSwitchPos": "USInt"
},
"UDT_JamArea": {
"arCarrier": "Array[*] of stCarrier", "stData": "stJamData"
}
}
```
### 3. Per-Instanz-Konfiguration, die jeden alten Typ reproduziert (die "Anreicherung")
```json
{
"instances": [
{
"name": "TRO101", "replaces": "FB_ILS_MTRO_1Sep",
"config": { "nNoOfSeparators": 1, "nNoOfSwitches": 0,
"nNoOfCarousels": 1, "nNoOfDirections": 1,
"xScannerPlugged": true, "xSsccPlugged": false, "xVarioMode": false },
"direction": [ { "nSepIndex": 1, "nSwitchIndex": 0, "nSwitchPos": 0, "xPrioRelevant": false } ]
},
{
"name": "TRO102", "replaces": "FB_ILS_MTRO_1Sep_SSCC",
"config": { "nNoOfSeparators": 1, "nNoOfSwitches": 0,
"nNoOfCarousels": 1, "nNoOfDirections": 1,
"xScannerPlugged": true, "xSsccPlugged": true, "xVarioMode": false }
},
{
"name": "TRO103", "replaces": "FB_ILS_MTRO_1Sep1Swi",
"config": { "nNoOfSeparators": 1, "nNoOfSwitches": 1,
"nNoOfCarousels": 2, "nNoOfDirections": 2,
"xScannerPlugged": true, "xSsccPlugged": false, "xVarioMode": false },
"direction": [
{ "nSepIndex": 1, "nSwitchIndex": 1, "nSwitchPos": 3, "xPrioRelevant": true },
{ "nSepIndex": 1, "nSwitchIndex": 1, "nSwitchPos": 4, "xPrioRelevant": true }
]
},
{
"name": "TRO104", "replaces": "FB_ILS_MTRO_1Sep2Swi",
"config": { "nNoOfSeparators": 1, "nNoOfSwitches": 2,
"nNoOfCarousels": 2, "nNoOfDirections": 3,
"xScannerPlugged": true, "xSsccPlugged": false, "xVarioMode": false }
},
{
"name": "TRO105", "replaces": "FB_ILS_MTRO_2Sep1Swi",
"config": { "nNoOfSeparators": 2, "nNoOfSwitches": 1,
"nNoOfCarousels": 2, "nNoOfDirections": 4,
"xScannerPlugged": true, "xSsccPlugged": false, "xVarioMode": false }
},
{
"name": "TRO106", "replaces": "FB_ILS_MTRO_Vario",
"config": { "nNoOfSeparators": 1, "nNoOfSwitches": 0,
"nNoOfCarousels": 1, "nNoOfDirections": 1,
"xScannerPlugged": true, "xSsccPlugged": false, "xVarioMode": true }
}
]
}
```
### 4. Einbindung in die bestehende `units[]`-Skeleton-Struktur
Heute schreibt `create_skel.py` einen `fbType`-String pro Einheit. Im Vorschlag wird
dieses eine Feld zu `fbType: "FB_ILS_MTRO"` plus ein `config`-Objekt, das der Generator
aus den gezählten Rollen füllt:
```json
{
"unit": "M0101",
"fbType": "FB_ILS_MTRO",
"config": {
"nNoOfSeparators": 1, "nNoOfSwitches": 1,
"nNoOfCarousels": 2, "nNoOfDirections": 2,
"xScannerPlugged": true, "xSsccPlugged": false, "xVarioMode": false
},
"io": {
"sensorInSep": ["BG0101"],
"switchOutput": ["MB0102"],
"stopperOutput": ["MB0101"],
"sensorJam": ["BG0103"]
}
}
```
`guess_fbtype()` (liefert heute einen der 7 Namen, siehe `lib/create_skel.py:558-563`)
würde stattdessen `"FB_ILS_MTRO"` zurückgeben plus einen zählenden Regelsatz:
```json
{
"configRules": {
"nNoOfSeparators": "count(roles == 'sensorInSep')",
"nNoOfSwitches": "count(roles == 'switchOutput')",
"nNoOfDirections": "count(roles == 'switchOutput') + 1",
"xScannerPlugged": "any(role == 'sensorStartScan')",
"xVarioMode": "has(roles, 'sensorFinger') or has(roles, 'sensorCarrInPos')"
}
}
```
## Abbildung der alten Typen auf den neuen Baustein (Übersicht)
| Alter Typ | Konfiguration, die ihn reproduziert |
|---|---|
| `1Sep` | Sep=1, Swi=0, Car=1, Dir=1 |
| `1Sep_SSCC` | Sep=1, Swi=0, Dir=1, `xSsccPlugged=TRUE` |
| `1Sep1Swi` | Sep=1, Swi=1, Car=2, Dir=2 |
| `1Sep2Swi` | Sep=1, Swi=2, Car=2, Dir=3 |
| `2Sep1Swi` | Sep=2, Swi=1, Car=2, Dir=4 |
| `Vario` | Sep=1, Swi=0, Dir=1, `xVarioMode=TRUE` |
Sieben Bausteine → **ein Baustein + ein Konfigurationsdatensatz pro Instanz**.
## Was separat bleibt
- **`FB_ILS_MTRO_PinStore_Auto`** ist ein echter Ausreißer — 21 Linien-Separatoren,
Encoder-Positionserfassung, Lagerlinien-Daten (`arInOutStorageLines`),
Auslager-Stationen. Es ist ein *Lager*-Controller, kein Routing-TRO. Die übrigen
sechs werden in `FB_ILS_MTRO` zusammengeführt; PinStore bleibt eigenständig
(oder wird zu `FB_ILS_STORE`).
- **Vario** ist ein Grenzfall: Es tauscht die Weiche gegen einen Kettenförderer mit
Finger-/Positionssensoren. Es passt als `xVarioMode` (ein Sub-Modul-Schalter), weil
es weiterhin denselben Separator + State-Manager nutzt. Falls die Finger-Schrittkette
zu stark abweicht, ist ein dünner Wrapper über den gemeinsamen Kern der Mode-Flag
vorzuziehen.
## Abwägung
- **Pro:** ein Baustein zum Testen/Versionieren/Dokumentieren; `create_skel.py` wird
deutlich einfacher (kein `FBTYPE_TEMPLATE`-Mapping, ein Aufruf-Template); das in der
Standardisierungsanalyse markierte "Versionschaos" entfällt.
- **Contra:** Arrays mit `nNoOf...`-Guards sind weniger selbsterklärend als ein
benannter `1Sep1Swi`; ungenutzte Array-Elemente kosten pro Instanz weiterhin
DB-Speicher. Multi-Instanz-Sub-FB-Arrays und `Array[*]`-In-Outs werden auf dem
Zielsystem (CPU 1518F) gut unterstützt — es gibt keinen Plattform-Blocker.
## Nächste Schritte (offen)
1. `FB_ILS_MTRO.scl`-Skelett prototypisieren (mit `FOR`-Schleifen-Aufrufen der Sub-TROs
und einer datengetriebenen Richtungs-Tabelle).
2. `create_skel.py` anpassen, sodass es den einzelnen Baustein mit `config`-Block
ausgibt statt der sieben Templates.