Files
sps_skel/doc/HundM/suggestion.md
T

9.7 KiB
Raw Blame History

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)

{
  "$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_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.