myWMS Visualisierung Seite 1/9 myWMS Visualisierung von Heinz W. Huber Konfiguration | Kommunikation MFC | Device-Reader | Kernel | Die Referenzanlage Kommissionierzelle kann mit Hilfe einer Visualisierung, die über ein RMI-Interface mit dem myWMS Kernel kommuniziert, gesteuert und beobachtet werden. Die Visualisierung kann eigene Kommunikations-Verbindungen zu der Materialfluss-Steuerung (Material Flow Control, MFC), die die Fördertechnik der Kommissionierzelle physisch steuert, und zu den Device-Readern, die die Transponder-IDs der Transportbehälter lesen, aufbauen. Dadurch stehen Funktionen zum direkten Abfragen und Ansteuern der Materialfluss-Steuerung und der DeviceReader zur Verfügung. Die Visualisierung ist im Package example als de.mywms.examples.pickingcell.gui.Visualization implementiert. Zum Start wird das Script example.pickingcell.Visualization im bin-Verzeichnis des jeweiligen Betriebssystems aufgerufen. Abbildung 1: Screenshot der Visualisierung Die Oberfläche der Visualisierung zeigt eine schematische Darstellung der MaterialflussKomponenten in der Kommissionierzelle und den aktuellen Ort und Zustand der UnitLoads © 2000 - 2002 Fraunhofer IML myWMS Visualisierung Seite 2/9 (Transportbehälter). Dazu muss die Visualisierung allerdings zuerst mit einem myWMS EquipmentKernel und mit der MFC verbunden werden. Anfang Konfiguration Die Visualisierung kann von jedem Rechner aus gestartet werden, der über eine Netzwerkverbindung zu dem Rechner, auf dem der EquipmentKernel läuft, und zur MFC verfügt. Die Netzwerk-spezifischen Einstellungen werden über den Mechanismus der Configuration in der Datei visualization.config gespeichert (siehe Dokument myWMS Configuration). Über den Menüpunkt File | Configuration wird ein Dialog zum Bearbeiten der lokalen Einstellungen geöffnet. Abbildung 2: Dialog zum Bearbeiten der Konfiguration Anfang Kommunikation mit der MFC Bei der Referenzanlage wird als MFC eine Speicher-Programmierbare Steuerung (SPS) vom Typ Siemens Simatic S7-300 mit einer TCP/IP-Kommunikationsbaugruppe CP343-1 verwendet; in den folgenden Beispielen wird diese als PLC (Programmable Logic Control) bezeichnet. Da in der PLC nur eine TCP/IP Verbindung zu einem einzigen Kommunikationspartner parametriert ist, verbindet sich die Visualisierung nicht direkt mit der PLC, sondern zunächst mit einem ChannelHub; dieser baut seinerseits die (einzige) Verbindung zur MFC auf. Dadurch können sich sowohl der myWMS EquipmentKernel als auch eine oder mehrere Visualisierungen und ggf. ComMonitore mit der MFC verbinden. Der Hintergrundprozess ChannelHub kann auf einem beliebigen Rechner im Netzwerk laufen und gestattet es beliebig vielen Partnern, sich mit der PLC zu verbinden. Eine detaillierte Beschreibung des ChannelHub findet sich im Dokument myWMS – Kommunikation. Verbindungsaufbau In der Methode connectPlc() der Visualisierung wird ein Kommunikationskanal zu einem ChannelHub geöffnet und mit einem Protokoll verknüpft: plcChannel = new TcpipClientChannel(hostnamePlc, portPlc, this); plcChannel.setProtocol(new DictionaryProtocol()); Die Methode wird automatisch beim Start der Visualisierung aufgerufen, wenn der Kommandozeilen-Parameter „–s“ übergeben wird; ansonsten kann sie über den Menüpunkt Kommunikation | SPS verbinden auch nachträglich aufgerufen werden. Bei erfolgreichem Verbindungsaufbau oder bei einem Fehler wird eine entsprechende Meldung in der Statuszeile der Visualisierung angezeigt. Die Parameter hostnamePlc und portPlc werden aus der Konfigurationsdatei gelesen; als Host kann der Netzwerkname oder die IP-Adresse des Rechners, auf dem der ChannelHub läuft, angegeben werden. © 2000 - 2002 Fraunhofer IML myWMS Visualisierung Seite 3/9 Der dritte Parameter this bestimmt, dass die Visualisierung selbst der ComDispatcher für diesen Channel ist. Sie implementiert dazu die Methode evaluate(), in der die über den Channel empfangenen ComObjects ausgewertet werden. Statusabfrage Nach dem Aufbau der Verbindung zur MFC sollte die aktuelle Belegung der Kommissionierzelle mit Transportbehältern (UnitLoads) erfragt werden. Dazu kann durch Anklicken des Buttons, der zu jeder StorageLocation gehört, ein Popup-Menü aufgerufen werden. Die erste Gruppe von Funktionen, die hier angeboten werden, umfasst die direkte Kommunikation zur MFC. Mit Auswahl der Funktion Status abfragen wird ein MfcStateRequest zur MFC gesendet. Ebenso kann über den Menüpunkt Kommunikation | Status abfragen eine Statusabfrage für sämtliche StorageLocations der Kommissionierzelle initiiert werden. Wie im Dokument myWMS – Kommunikation mit der MFC beschrieben, wird dazu für jede StorageLocation ein ComObject vom Typ MfcStateRequest erzeugt; dieses wird vom Protokoll des Kanals in einen Bytestream umgewandelt und über den ChannelHub zur PLC gesendet. Diese antwortet mit einem Telegramm, das vom Protokoll in ein ComObject vom Typ MfcTransportEvent umgewandelt wird. Die evaluate() Methode der Visualisierung wertet die Felder StorageLocation und UnitLoads aus und zeigt für die betreffende StorageLocation die Anzahl der gemeldeten UnitLoads durch eine entsprechende Anzahl graphischer Symbole (rote Behälter) an. Statuskorrektur Falls – z.B. nach einem manuellen Eingriff – die gemeldete Belegung einer StorageLocation nicht mit der tatsächlichen übereinstimmt, kann im Popup-Menü die Funktion Status ändern ausgewählt werden. Abbildung 3: Dialog zur Statuskorrektur Es erscheint ein Dialog, in dem die aktuelle Anzahl von UnitLoads eingetragen wird. Anschließend erzeugt die Methode createMfcModifyRequest() ein ComObject vom Typ MfcModifyRequest, in dem die Felder StorageLocation und UnitLoads mit den Benutzereingaben ausgefüllt werden. Dieses wird vom Protokoll des Kanals in einen Bytestream umgewandelt und über den ChannelHub zur PLC gesendet. Diese antwortet wieder mit einem Telegramm, das vom Protokoll in ein ComObject vom Typ MfcTransportEvent umgewandelt wird. Die Auswertung in evaluate() erfolgt wie bei der Statusabfrage. Transportauftrag Durch Auswahl der Funktion Transportauftrag im Popup-Menü einer StorageLocation wird eine MfcTransportOrder zur MFC gesendet. Ziel und Anzahl der zu transportierenden Behälter werden über einen Dialog ausgewählt. © 2000 - 2002 Fraunhofer IML myWMS Visualisierung Seite 4/9 Abbildung 4: Dialog zum Transportauftrag Wie in myWMS – Kommunikation mit der MFC beschrieben, wird ein ComObject vom Typ MfcTransportOrder erzeugt; dieses wird vom Protokoll des Kanals in einen Bytestream umgewandelt und über den ChannelHub zur PLC gesendet. Jedes Mal, wenn ein Behälter seinen Quellplatz verlässt oder wenn er seinen Zielplatz erreicht sendet die PLC ein MfcTransportEvent Telegramm. Außerdem wird zu Beginn und mit Ende des gesamten Transports jeweils ein MfcTransportExecution Telegramm gesendet. Der jeweils zuletzt gesendete Transportauftrag wird in der Statuszeile der Visualisierung angezeigt. Mit jedem empfangenen MfcTransportEvent wird die Belegung der entsprechenden StorageLocation aktualisiert. Die MfcTransportExecution wird von der Visualisierung nicht weiter ausgewertet. (Bei Dauerbetrieb Aufruf von ContinousLoop.trigger() zum Weiterschalten ...) Anfang Kommunikation mit den Device-Readern Die Referenzanlage ist mit einem induktiven Schreib-/Lesesystem zum Beschreiben und Lesen von Transpondern ausgerüstet. An jedem Transportbehälter ist ein Transponder angebracht, der mit einem eindeutigen Identifizierungscode beschrieben werden kann. An den Materialfluss-Verzweigungspunkten befinden sich jeweils ein Lesegerät, mit dem der dort befindliche Behälter identifiziert werden kann. Verbindungsaufbau In der Methode connectDevice() der Visualisierung wird ein Kommunikationskanal zu einer weiteren Instanz des ChannelHub geöffnet und mit einem Protokoll verknüpft: deviceChannel = new TcpipClientChannel(hostnameDevice, portDevice, this); deviceChannel.setProtocol(new DictionaryProtocol()); Die Methode wird automatisch beim Start der Visualisierung aufgerufen, wenn der Kommandozeilen-Parameter „–r“ übergeben wird; ansonsten kann sie über den Menüpunkt Kommunikation | Device verbinden auch nachträglich aufgerufen werden. Bei erfolgreichem Verbindungsaufbau oder bei einem Fehler wird eine entsprechende Meldung in der Statuszeile der Visualisierung angezeigt. Die Parameter hostnameDevice und portDevice werden aus der Konfigurationsdatei gelesen; als Host kann der Netzwerkname oder die IP-Adresse des Rechners, auf dem der zugehörige ChannelHub läuft, angegeben werden. Der dritte Parameter this bestimmt, dass die Visualisierung selbst der ComDispatcher für diesen Channel ist. Sie implementiert dazu die Methode evaluate(), in der die über den Channel empfangenen ComObjects ausgewertet werden. Da die Visualisierung auch ComDispatcher für den Channel zur PLC ist (siehe Kommunikation mit der MFC), werden die von beiden Kanälen empfangenen ComObjects von der selben evaluate() Methode ausgewertet. © 2000 - 2002 Fraunhofer IML myWMS Visualisierung Seite 5/9 Leseereignis Wenn eines der Lesegeräte den Identifizierungscode eines Transponders gelesen hat, sendet es über den ChannelHub ein Telegramm zur Visualisierung, das vom Protokoll des Channel in ein ComObject vom Typ DeviceReadEvent umgewandelt wird. Über das Feld Sender kann die evaluate() Methode erkennen, von welchem Gerät das Ereignis gesendet wurde. Der im Feld Data übertragene ID-Code wird als Text im entsprechenden Ausgabefeld der Visualisierung angezeigt. Anfang Kommunikation mit dem Kernel Bei Aufruf des Menüpunkts Kernel | Kernel verbinden versucht die Visualisierung, eine Verbindung zu einem EquipmentKernel aufzubauen, der auf dem in der Konfiguration spezifizierten Host laufen muss. Dazu wird in der Methode initKernel() mit equipmentKernel = new EquipmentKernelRMIClient(hostnameKernel); ein EquipmentKernelRMIClient instanziiert. Diesem wird mit equipmentKernel.addStorageLocationEventListener(this, 0L); ein StorageLocationEventListener hinzugefügt. Damit wird der EquipmentKernel veranlasst, jede Änderung an einer StorageLocation dem RMIClient in der Visualisierung mitzuteilen. Wenn ein Event auftritt, das eine StorageLocation betrifft, ruft der Kernel die Callback-Methode businessObjectEvent() der Visualisierung auf. Diese ermittelt über die Kernel-Methode getUnitLoads() die Anzahl und die Object-IDs der UnitLoads, die sich auf der StorageLocation befinden. Die UnitLoads werden durch eine entsprechende Anzahl graphischer Symbole (blaue Behälter) angezeigt. Beim Berühren einer StorageLocation mit dem Mauszeiger erscheint ein ToolTipText, der Informationen über die StorageLocation und die darauf befindlichen UnitLoads enthält (siehe Abbildung 1). Wenn die Visualisierung mit einem EquipmentKernel verbunden ist, lassen sich über das Popup-Menü einer StorageLocation weitere Funktionen aufrufen: Unit Loads Nach Auswahl der Option Unit Loads im Popup-Menü einer StorageLocation erscheint ein Dialog, in dem zu Korrekturzwecken UnitLoads zugefügt, um- oder abgebucht sowie vorhandene UnitLoads bearbeitet werden können. Abbildung 5: Dialog zum Bearbeiten der UnitLoads einer StorageLocation Beim Zufügen oder Bearbeiten einer einzelnen UnitLoad können in einem Dialog die Label ID, die im Transponder des Behälters gespeichert wird, und die Zustände reserviert und gesperrt geändert werden. Die Object ID wird vom Kernel vergeben und kann für ein existierendes Objekt nicht mehr verändert werden. © 2000 - 2002 Fraunhofer IML myWMS Visualisierung Seite 6/9 Abbildung 6: Dialog zum Bearbeiten einer UnitLoad ... Abbildung 7: Dialog zum Bearbeiten der StockUnits in einer UnitLoad ... Abbildung 8: Dialog zum Bearbeiten einer StockUnit ... Order Chain Popup-Menü einer UnitLoad: Automatik/Dauerbetrieb Screenshots Grundstellung; Funktionen erklären! Betriebsarten Dauerbetrieb/Testbetrieb SPS/WMS Programmablauf © 2000 - 2002 Fraunhofer IML myWMS Visualisierung Seite 7/9 Beispiel 2: Senden einer OrderChain (via Kernel) Durch Anklicken des zu einer StorageLocation gehörenden Buttons in der Visualisierung wird ein Popup-Menü geöffnet; wenn die Visualisierung über RMI mit einem laufenden Equipment Kernel verbunden ist, kann hier der Befehl Load Handler Order aufgerufen werden. Es erscheint ein Dialog, in dem das Ziel dieses Auftrags (die Quelle ist die jeweilige StorageLocation) und die Anzahl der zu transportierenden UnitLoads eingegeben wird. Es wird an dieser Stelle nicht geprüft, ob die eingegebene Anzahl UnitLoads tatsächlich an der Quelle verfügbar ist, bzw. ob am Ziel genügend Plätze frei sind! Mit Anklicken des OK-Buttons wird nun die Methode sendLoadHandlerOrder() aufgerufen. Hier wird für jede zu transportierende UnitLoad eine LoadHandlerOrder mit den ausgewählten Quell- und Ziel-StorageLocations erzeugt: for (int i = 0; i < numUnits; i++) { orders[i] = new LoadHandlerOrder(slSource, slDestination); } Abhängig von der Quell-StorageLocation wird nun die Object-Id des „zuständigen“ LoadHandlers ermittelt und zusammen mit dem Array von LoadHandlerOrders der Methode setLoadHandlerOrder() des Equipment Kernel übergeben: success = equipmentKernel.setLoadHandlerOrder(orders, lhOid); Dies Methode bestimmt aus der LoadHandler-Object-Id die zugehörige LoadHandlerTask und daraus wieder das LoadHandlerControlInterface, dessen move()-Methode nun aufgerufen wird: lht = getLoadHandlerTask(lhOid); lhci = lht.getLoadHandlerControlInterface(); return lhci.move(lhos); Implementiert ist diese Methode in de.mywms.examples.pickingcell.PickingCellController (Packet example). 1. TransportOrder In move() werden die LoadHandlerOrders mit gleichen Quell- und Ziel-StorageLocations zu einer einzelnen TransportOrder für die entsprechende Anzahl UnitLoads zusammengefasst. Es wird überprüft, ob Daten zu den UnitLoads an der Quell-StorageLocation vorhanden sind, ob eine Fahrt von Quelle nach Ziel erlaubt ist und ob in der Ziel-StorageLocation genügend freie Plätze vorhanden sind. Ist dies nicht der Fall, wird move() mit negativem Returncode beendet. Sind alle Daten Korrekt, so wird diese TransportOrder der evaluate()-Methode des ComDispatchers übergeben: comDispatcher.evaluate(order, channel); Diese ruft wiederum die write()-Methode des zugehörigen Channels auf: channel.write(order); Der weitere Ablauf erfolgt nun prinzipiell wie oben am Beispiel Statusabfrage beschrieben: Die eval()-Methode von S7OverTcpipProtocol wandelt das ComObject in einen ByteStream (TransportOrder-Telegramm) um: WMS1 PLC1 WRIT TORS 0123 0010 0000 0048 IP_0 SOR4 0001 0600 Darin ist das 6. Feld (Byte 20-23) wieder die RequestNumber; die Felder 9-12 (Byte 32-47) sind die Parameter der TransportOrder: Quelle, Ziel, Anzahl und Länge der zu transportierenden Behälter. Dieser ByteStream wird nun mit der writeBytes()-Methode des Channel zur SPS gesendet; bei Erfolg wird das gesendete ComObject dann in die Warteschlange der ComSurveillance eingetragen. Die UnitLoad wird mit addUnitLoad()- in die Liste der UnitLoads eingetragen, die gerade bearbeitet werden. © 2000 - 2002 Fraunhofer IML myWMS Visualisierung Seite 8/9 3. TransportEvent Sobald die SPS den mit dem TransportOrder-Telegramm gesendeten Transportauftrag ausführen kann, sendet sie bei jeder Veränderung einer StorageLocation ein TransportEventTelegramm: Zuerst, wenn ein Behälter seinen Quellplatz verlassen hat, dann, wenn er an seinem Ziel angekommen ist. PLC1 WMS1 WRIT TEVS 0235 0010 0000 0048 PLC1 WMS1 WRIT TEVS 0236 0010 0000 0048 -1 IP_0 0001 0600 1 SOR4 0002 1200 Die RequestNumber des TransportEvents ist dieselbe wie die der zugehörigen TransportOrder; das 9. Feld (Byte 32-35) gibt die Differenz der Belegung der StorageLocation im 10. Feld an (1, wenn ein Behälter den Quellplatz verlassen hat, 1, wenn er sein Ziel erreicht hat), das 11.12. Feld die jetzt aktuelle Anzahl und Gesamtlänge der Behälter auf der StorageLocation. Das Telegramm wird von der eval()-Methode des Protocol in ein ComObject vom Typ TransportEvent umgewandelt; anschließend sucht die evaluate()-Methode des ComDispatchers anhand der RequestNumber nach der zugehörigen TransportOrder. Aus dieser wird der für den Transport zuständige PickingCellController (PostStore-, PreStore- oder PrePickController) bestimmt. Sollte keine RequestNumber vorhanden sein, oder sollte im ComDispatcher die RequestNumber nicht vorhanden sein, so wird der zuständige PickingCellController aus der StorageLocation ermittelt und trotzdem gebucht. Wenn die Differenz –1 beträgt, wird die erste UnitLoad nun von der Quell-StorageLocation auf den LoadHandler des Controllers gebucht: controller.leaveSource(idSource); Die Methode leaveSource() des PickingCellController ruft ihrerseits die transferUnitLoad()Methode des EquipmentKernel auf. Diese entfernt die UnitLoad vom Quellplatz und fügt sie dem temporären Ziel – dem LoadHandler – hinzu: srcStorageLocation.removeUnitLoad(unitLoad); dstStorageLocation.addUnitLoad(unitLoad); Wenn die Differenz im TransportEvent 1 beträgt, also ein Behälter sein Transportziel erreicht hat, wird die Methode moveExecution() des PickingCellController aufgerufen; diese ruft wiederum transferUnitLoad() im EquipmentKernel auf und bewegt die UnitLoad nun vom LoadHandler auf die Ziel-StorageLocation. Dieses Handling stellt nur eine Zwischenlösung dar. In der nächsten Version wird das TransportEvent lediglich von der Visualisierung benutzt. Die Buchungen werden von der TransportExecution übernommen. 5. TransportExecution Wenn der letzte Behälter einer TransportOrder sein Ziel erreicht hat, der Auftrag also vollständig abgearbeitet wurde, sendet die SPS ein TransportExecution-Telegramm: PLC1 WMS1 WRIT TEXS 0237 0010 0000 0048 IP_0 SOR4 0001 0600 Die RequestNumber der TransportExecution ist dieselbe wie die der zugehörigen TransportOrder; die Felder 9-12 (Byte 32-47) spiegeln die Parameter der TransportOrder wieder. Das Telegramm wird von der eval()-Methode des Protocol in ein ComObject vom Typ TransportExecution umgewandelt; anschließend sucht die evaluate()-Methode des ComDispatchers anhand der RequestNumber nach der zugehörigen TransportOrder. Aus dieser wird der für den Transport zuständige PickingCellController bestimmt; aus dem Aufruf controller.transportExecutionReceived(idSource, idDestination); wird removeUnitLoad() aufgerufen, womit die UnitLoad aus der Auftragsliste gelöscht wird. In der nächsten Version werden bei Empfang einer TransportExecution die UnitLoads weitergebucht. Es wird eine TransportExecution gesendet, sobald eine UnitLoad den Quellplatz verlassen hat. Die UnitLoad wird auf die StorageLocation des LoadHandlers gebucht. Sobald © 2000 - 2002 Fraunhofer IML myWMS Visualisierung Seite 9/9 die UnitLoad das Ziel erreicht hat, wird ebenfalls eine TransportExecution gesendet. Die UnitLoad wird vom LoadHandler zum Ziel gebucht. MfcTransportExecution: Dagegen wird in der evaluate()-Methode des ComDispatcher hier geprüft, ob die RequestNumber der empfangenen StateQueryExecution mit der einer zuvor gesendeten StateQueryOrder übereinstimmt. In diesem Fall würde die StateQueryOrder aus der im PickingcellComDispatcher gehaltenen Liste der noch unbestätigten Aufträge gelöscht. Da in diesem Beispiel aber die StateQueryOrder nicht vom myWMS-Kernel initiiert sondern direkt aus der Visualisierung gesendet wurde, ist sie dem ComDispatcher auch nicht bekannt. Anfang Letzte Änderung dieses Dokuments: 14.05.2016 16:53:00 © 2000 - 2002 Fraunhofer IML