9.7 KiB
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 1–2 Separatoren, 0–2 Weichen, 1–4 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)
{
"$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
{
"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")
{
"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:
{
"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:
{
"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_Autoist 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 inFB_ILS_MTROzusammengeführt; PinStore bleibt eigenständig (oder wird zuFB_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.pywird deutlich einfacher (keinFBTYPE_TEMPLATE-Mapping, ein Aufruf-Template); das in der Standardisierungsanalyse markierte "Versionschaos" entfällt. - Contra: Arrays mit
nNoOf...-Guards sind weniger selbsterklärend als ein benannter1Sep1Swi; ungenutzte Array-Elemente kosten pro Instanz weiterhin DB-Speicher. Multi-Instanz-Sub-FB-Arrays undArray[*]-In-Outs werden auf dem Zielsystem (CPU 1518F) gut unterstützt — es gibt keinen Plattform-Blocker.
Nächste Schritte (offen)
FB_ILS_MTRO.scl-Skelett prototypisieren (mitFOR-Schleifen-Aufrufen der Sub-TROs und einer datengetriebenen Richtungs-Tabelle).create_skel.pyanpassen, sodass es den einzelnen Baustein mitconfig-Block ausgibt statt der sieben Templates.