Beiträge von Spielkind

    Hallo achimE,


    sobald der Roboter nicht mehr auf der programmierten Bahn ist (z.B. durch deinen beschriebenen Fall) erkennt das das Betriebssystem automatisch und schaltet in den sogenannten ConnectionMove.
    Selbst wenn Du dann die Antriebe im Automatikmodus wieder einschaltest, fährt der Roboter trotzdem nicht mehr weiter.


    Es gibt dann drei Möglichkeiten, um die Produktion wieder aufzunehmen:
    1. Der Bediener drückt die Move/Hold-Taste am Handbediengerät. Der Roboter bewegt sich nun mit langsamer Geschwindigkeit (selbst wenn Du auf max. Geschwindigkeit stellst) bis er wieder auf dem Punkt ist, an der er die Bahn verlassen hat. Der Bediener ist also dann dafür verantwortlich, rechtzeitig vor einem eventuellen Crash den Daumen von der Move/Hold-Taste zu nehmen :zwink:
    2. Der Programmierer nutzt den Befehl autoConnectMove(true). Dann fährt der Roboter zwar immer noch mit langsamer Geschwindigkeit zur Bahn zurück, braucht aber keinen Bediener, der die Move/Hold-Taste drückt. :!: Ich halte das aber für die denkbar schlechteste Alternative - da ist der Crash dann vorprogrammiert :!:
    3. Der Programmierer will das alles nicht und programmiert einen Abbruch mit Grundstellungsfahrt, wie du ihn vorgeschlagen hast.


    Ich persönlich tendiere zu Vorschlag 1. Das ist in meinen Augen nie verkehrt.


    Viel Erfolg


    Spielkind

    Hallo mischwarz,


    Geht man in solch einem Fall wirklich folgenden Weg??task interrupt merkt fehler und gibt diese Meldung(wie auch immer sie aussehen mag) an task main weiter.task main meldet an Move breche deine Bahn ab und gehe woanders hin ???


    Meine Meinung dazu:
    Ich würde es so ähnlich machen. Allerdings wäre mein "main" Task gleichzeitig der Task, der auch die Abbruchbedingung generiert. Einen Synchrontask würde ich nicht nehmen. Es ist völlig egal, ob der Abbruch 10ms früher oder später zur Aktion führt.
    Einen weiteren (dritten) Task würde ich nur bei in sich abgeschlossenen "Aufgaben", die parallel ablaufen sollen, hinzunehmen.
    Das wäre bei mir z.B. bei einer Falzmaschine der Fall, die komplett über den Roboter mit VAL3 programmiert wurde und natürlich unabhängig vom Roboter ihren Job erledigen soll.

    Hallo Vogster,


    man kann von VAL3 aus auf den PCI-Bus zugreifen und damit seine eigenen "Treiber" für Zusatzkarten in VAL3 programmieren.
    Man braucht dazu eine Laufzeitlizenz auf der Steuerung namens "pciAccess" und natürlich Dokumentation vom Hersteller der Karte, auf welchen E/A-Adressen welche Funktionen liegen und wie die zu nutzen sind.
    Die Laufzeitlizenz wird allerdings Geld kosten - wieviel weiss ich nicht.


    Achtung bei der Nutzung der 2. seriellen Schnittstelle !!!
    Da laufen beim Booten der Steuerung die BIOS-Info´s drüber. Deine Gegenstelle sollte also diese nicht für sie bestimmten Meldungen verwerfen und nicht darauf reagieren. Ganz wichtig ist, dass die Gegenstelle nicht antwortet und dann "aus Versehen" ins BIOS der CS8C-Steuerung geht. Du siehst dann nur, dass deine Steuerung nicht bootet (da im BIOS) und denkst vielleicht, die wäre kaputt :P
    Um diesem aus dem Weg zu gehen, habe ich die RX/TX Leitungen der 2. seriellen Schnittstelle über ein Relais gelegt, welches ich von meiner VAL3-Applikation aus anschalte (damit also nach dem Bootvorgang).
    Klappt bei mir hervorragend.



    Ach ja, bei den Einstellungen für den Modbus auf der CS8C solltest Du 2 "Connections" eintragen, dass verkürzt die Kommunikationszeit - ob dann schneller als die hier erwähnten 10ms wage ich aber zu bezweifeln.


    Gruss


    Spielkind

    Hallo Biele,


    um 21:07:44 gab es einen Crash und dann noch mal beim Rausfahren um 21:09:28 :zwink:. Allerdings beides Mal im Handmodus.


    [OCT 06 2010 21:07:40]: Manueller Betriebsmodus:Point
    [OCT 06 2010 21:07:40]: Unknown event:motion generator activated
    [OCT 06 2010 21:07:44]: Interner Fehler DRIVE-Warning 5
    [OCT 06 2010 21:07:44]: Interner Fehler DRIVE-DriveFoldback Data=0 Bus=Drive Axis=5
    [OCT 06 2010 21:08:18]: Manueller Betriebsmodus:Tool
    [OCT 06 2010 21:09:28]: Schleppfehler Achse 6: {18.36,-22.5,-133.42,-54.86,49.51,-16.4}
    [OCT 06 2010 21:09:28]: Unknown event:motion generator desactivated
    [OCT 06 2010 21:09:28]: Jog-Auswahl nicht möglich: Bitte erst Armleistung einschalten.


    Es fehlen Daten vom 04.10. 06:00:29 bis 06.10 21:04:15.
    [OCT 04 2010 06:00:29]: Wieder in Normalzustand: externer Not-Aus (User ESA1-2)
    [OCT 06 2010 21:04:15]: Wieder in Normalzustand: Not-Aus: Türkreis offen.


    Ein Booten der Steuerung kann man an einer Zeile mit "----------" erkennen. Das kann es also nicht gewesen sein. Wenn nichts zu tun ist, schreibt das System alle 30 Minuten (vielleicht auch öfter) "saving Controller Context". Auch das finde ich nicht im Log.
    Ich weiss momentan nicht, ob man im Log sehen kann, ob die Uhrzeit von Hand verstellt wurde. Probiere ich morgen mal aus.
    Ich habe noch nie gesehen, dass das Betriebssystem das Logging einstellt und dann irgendwann wieder aufnimmt...
    Ansonsten habe ich keine bessere Idee ...


    Gruss
    Spielkind

    Hi,


    da musst du schon ein bisschen genauer werden:
    1. Was verstehst Du unter "Crash"? Eine Kollision des Roboters oder einen Systemabsturz?
    2. Wenn 2 Tage fehlen: Was habt Ihr nach dem Crash gemacht? Einfach stehengelassen? Neu gebootet?
    3. Welche Daten fehlen? Nur die aus dem Log?
    4. Was meinst Du mit "die Daten fehlen bis kurz nach dem Crash". Und dann (nach dem Crash) waren sie wieder da?


    Gruss


    Spielkind

    Hallo,


    da stehen 2 Dinge gleichzeitig:
    1. Zwischen 06:11:34 und 06:11:36 trat die Meldung "INTERFACE-Stopped" genau 31 mal auf. Um Speicherplatz im Log zu sparen, wurden diese Meldungen zusammengefasst.
    2. "Systemmeldung: events lost" bedeutet, es sind aus den verschiedenen Subsystemen mehr Meldungen eingetroffen, als das System verarbeiten (ins Log) schreiben konnte, deshalb sind einige Meldungen verloren gegangen. Da 31 "INTERFACE-Stopped"-Meldungen erkannt wurden, kannst Du davon ausgehen, dass auch die verlorenen Meldungen genau das Gleiche zu sagen hatten.


    Gruss


    Spielkind

    Hallo,


    die Geschichte mit der do - Schleife funktioniert zwar, finde ich persönlich aber in diesem Falle etwas ungeschickt.
    Wenn man bereits beim Eintreten in die Schleife weiss, wie häufig man sie durchlaufen möchte, bietet sich die for-Schleife viel eher an:


    Code
    for zaehler=1 to 20
     // tue irgendwas
    endFor


    Gründe:
    a) Man spart sich eine extra Codezeile für die Startinitialisierung der Zählervariable (hier zaehler)
    b) Man braucht keine extra Codezeile für die Inkrementierung bzw. Dekrementierung der Zählervariable
    c) Man erkennt direkt beim Lesen des Programms, wie häufig die Schleife durchlaufen wird


    Wie gesagt, nur meine persönliche Meinung und Geschmäcker sind ja bekanntlich verschieden.


    @ sigiStaubli:
    Wie du siehst, war dein Ansatz soweit nicht verkehrt. Nur hättest Du das endFor mit einem kleinen "e" schreiben müssen. Nebenbei bemerkt braucht man das "step" nur, wenn pro Schleifendurchlauf die Zählvariable um etwas anderes als 1 verändert werden soll. Ein "step 1" schadet allerdings auch nicht (und manche fügen es absichtlich ein, um es deutlich zu machen).


    Gruss


    Spielkind

    Hi,


    zu den Arrays in VAL3 noch eine klitzekleine Anmerkung:
    In VAL3 sind alle Variablen immer ein Array, allerdings standardmäßig mit der Elementgröße 1.
    Man kann also z.B. auf zwei Arten eine Bool-Variable "bTest" im Programm ansprechen:
    bTest = true
    bTest[0] = true
    Beide Programmzeilen schreiben also "true" in die gleiche Variable (ins gleiche Element).


    Zu den Strings ergibt sich daraus, dass man auf die einzelnen Zeichen in einem String nicht über ein Array zugreifen kann. Also wie Roboman schon vorgeschlagen hat, über Zeichenkettenoperatoren wie left, right, mid usw.


    Warum dein Code schon in der if-Schleife hängenbleibt, erklärt dass allerdings nicht. Kann es sein, dass dein Programm bereits mindestens einmal über die Schleife gelaufen ist und dabei das Element 0 (also den gesamten String) gelöscht hat?


    Und dann noch generell eine Anmerkung zum Versenden von Kommazahlen über TCP/IP oder serielle Schnittstellen:
    Wenn die Gegenstelle es ermöglicht, sollte man meiner Meinung nach lieber direkt eine floating point Zahl als 4 Byte (single precision) oder 8 Byte (double precision) über den Kanal schicken - nur darf man die bytes dann nicht in einen String einlesen sondern lieber mit sioGet() in ein Num-Array.
    Der Befehl "fromBinary()" nimmt nun dieses Byte-Array entgegen und interpretiert es wie im Übergabeparameter angegeben als word, dword, single float oder double float im little endian oder big endian Format.
    Ein schönes Beispiel dazu findest du im VAL3-Handbuch, wenn du nach fromBinary suchst.


    Gruss


    Spielkind

    Hallo,


    meiner Meinung nach hat VAL3 viele Anleihen an C.


    Zu deiner zweiten Frage (Warum VAL3 und nicht eine andere Programmiersprache) gibt es glaube ich nur eine Erklärung:


    Alle "Standard" Programmiersprachen wie C++ / Java / Basic / Pascal, etc. sind entwickelt worden, um PC-Programme zu schreiben. Dort entstehen Softwarepakete mit mehreren Millionen Zeilen Source Code. Wiederverwendbarkeit, Effizienz, Objektorientierung usw. haben deshalb einen sehr hohen Stellenwert. Solche Softwarepakete werden in der Regel von vielen Personen (i.d.R. Informatiker oder vergleichbarer Wissenstand) über längere Zeiträume (Monate / Jahre) gleichzeitig geschrieben.
    In der Robotik ist das anders:
    Projekte dauern in der Regel nur Tage oder Wochen und werden von einer einzigen Person geschrieben.
    Viele "Programmierer" kommen aus dem Bereich "Elektrotechnik" und sind über die Schiene der SPS-Programmierung auch zum Roboter gekommen. Höhere Programmiersprachen sind unbekannt oder in der Ausbildung nur mal gestreift worden. Objektorientierung usw. ist unbekannt.


    Nun möchten Firmen wie Stäubli / Kuka / ABB etc. dass ein Roboter möglichst einfach und ohne großes Vorwissen (Studium der Informatik) programmierbar ist. Also nimmt man eine Standardprogrammiersprache als Vorlage, schmeisst alles raus, was vielleicht kompliziert ist und auch nicht zwingend benötigt wird und fügt roboterspezifische Befehle hinzu. Fertig ist die "eigene" Programmiersprache.


    Wie gesagt, dass ist meine Meinung. Vielleicht bin ich da auch auf dem Holzweg ...


    Hoffe trotzdem, dass es Dir hilft

    Hallo Jesch,


    es gibt mehrere Verfahren zur Toolvermessung. Hier eins, mit dem ich gute Erfahrungen gemacht habe:
    Du brauchst:
    a) ein Tool (z.B. eine Spitze), welches du direkt an den Flange montieren kannst. Wenn Du dir das Tool drehen lässt, sollten die Abmaße sehr genau bekannt sein. Dieses Tool nennen wir jetzt Spitze1
    b) ein Tool (wenn in a eine Spitze, dann jetzt auch), welches du in den Greifer einspannen kannst. Auch die Abmaße dieses Tools müssen bekannt sein. Dieses Tool nennen wir nun Spitze2
    c) eine Gegenspitze. Diese Spitze muss nicht bekannt sein. Du kannst sie an beliebiger Stelle so plazieren, dass der Roboter sie erreichen kann.


    Verfahren:
    1. Montiere Spitze1 an den Flange und teache einen Point pPos1 so, dass Spitze1 exakt auf der Gegenspitze steht. Auch der Anstellwinkel muss stimmen. Dazu lässt sich zum Beispiel ein Anschlagwinkel nutzen. Das Tool zum Teachen ist "flange", nicht Spitze1 !!!
    2. Nun montiere deinen Greifer an den Flange und spanne Spitze2 in den Greifer.
    3. Teache einen Point pPos2 so, dass Spitze2 exakt auf der Gegenspitze steht. Auch der Anstellwinkel muss wieder stimmen. Das Tool ist ebenfalls "flange", nicht Spitze2 und auch nicht Greifer !!!
    4. Angenommen, deine Tool-Variablen lauten tGreifer füer den Greifer, tSpitze1 für Spitze1 und tSpitze2 für Spitze2 dann lautet die VAL3-Zeile:
    tGreifer.trsf = !pPos2.trsf*pPos1.trsf*tSpitze1.trsf*!Spitze2.trsf
    Sobald diese Zeile ausgeführt wurde, stehen die richtigen Offsets x,y und z in der Variablen tGreifer.


    Möchtest Du auch die Orientierungen RX, RY und RZ haben, musst du deine "Spitzen" erweitern. So könnten auf Spitze1 und Gegenspitze eine Markierung die positive X-Richtung anzeigen. Teache in diesem Fall Spitze1 auf der Gegenspitze so, dass beide Markierungen exakt "aufeinander" stehen. Beim Teachen von pPos2 zeigt dann die Markierung der Gegenspitze, wo bei deinem Greifer die positive X-Richtung sein wird.


    Generell solltest Du diese "Spitzen" nicht wörtlich nehmen. Du musst "nur" zweimal so genau wie möglich eine Position in der Zelle mit bekannten Tools anfahren können. Ob das nun Spitze auf Spitze ist oder irgendein anderes Gebilde ist völlig egal.


    Ich hoffe, ich habe mich so einigermaßen verständlich ausgedrückt :kopfkratz:. Wenn nicht, sag Bescheid

    Hallo Olaf,


    Stäubli hat doch die Bosch Scaras mit allem "Zip und Zap" übernommen.
    Hast Du mal die Ersatzteilabteilung von Stäubli nach Rho2 Ersatzteilen gefragt?


    Das es "offiziell" keine Ersatzteile mehr gibt mag ja sein, aber ich kann mir nicht vorstellen, dass die gar nichts mehr haben ...
    In der Regel ist für alte Maschinen immer noch das eine oder andere da, vielleicht auch nur gebraucht, aber immerhin.


    Gruss


    Spielkind

    Hallo Vogster,
    ja, ich habe schon damit gearbeitet. Ist genau das gleiche wie beim Standardsystem, nur schneller :lol:
    Um den Betriebssystemtakt umzustellen, musst du die Datei /sys/options.cfx mit einem Texteditor öffnen und die Zeile

    <Float name="cycleTime" value="0.004" />

    hinzufügen. Die erlaubten Werte sind 0.004, 0.002 und 0.001 entsprechend 4, 2 und 1 ms. Anschliessend neu booten. Fertig!


    Urmel:
    Verstehe ich nicht! In meiner Ausgabe sind die Versionen des VAL3-Referenzhandbuchs gleich. Die Dokumente tragen auch beide den Stempel 01/2008. Meine Erfahrung ist, dass deutsche und englische Handbücher immer gleich aktuell sind.
    Hast Du vielleicht aus Versehen das deutsche Referenzhandbuch für Version5 mit dem englischen Referenzhandbuch für Version 6 verglichen? Auf meiner CD sind nämlich Referrnzhandbücher für S5 und S6 drauf.
    Ich habe noch keine Möglichkeit gefunden, wie ich Anhänge per "privater Mitteilung" verschicken kann. Wahrscheinlich bin ich blind. Wenn Du mir erklärst wie, schicke ich Dir mein Referenzhandbuch (in deutsch und mit Erklärung zu "toBinary" und "fromBinary") :)


    Gruss


    Spielkind

    Hallo Hajo,


    OK, ich glaube ich habe dein Problem verstanden.


    Anderer Vorschlag:
    Nutze doch die standardmäßig vorhandene SOAP-Schnittstelle des Controllers. Einer der vorhandenen SOAP-Kommandos schickt dir die globalen Variablen deiner geöffneten Applikation als XML-Objekt (im gleichen Format wie die dtx-Datei) an deinen PC.
    Nun kannst Du mit XML-Hilfsmitteln einer Hochsprache deiner Wahl einem XML-Parser schreiben.
    Die Wert-Änderungen schickst Du wie gehabt über deinen Socket (z.B. in der Form <Variablenname|Wert> an den selbstgeschriebenen VAL3-Server. Der kann dann mit dem Befehl $exec("Variablenname=Wert") einen String als VAL3-Befehl ausführen.


    Gruss


    Spielkind

    Hallo Hajo,


    im Extension-AddOn gibt es eine Reihe von Befehlen zum Lesen/Schreiben von Dateien. Damit kannst Du Dir deinen eigenen Parser schreiben.


    Ich weiss nicht, weshalb Du unbedingt die Namen der Variablen aus einer DTX-Datei extrahieren willst.


    Seit VAL3 Version S6.5.5 gibt es im extension-AddOn den Befehl string $getName(variable) mit dem Du den Namen der Variablen als String bekommst.
    Mit dem Standardbefehl getData(string VariableName, targetVariable) bekommst Du den Wert einer als String übergebenen Variable in die Variable targetVariable geschrieben. Das ist also der zu $getName() "umgekehrte" Weg.


    Gruss


    Spielkind

    Es hängt offensichtlich von der Länge eines Strings ab, wie lange das Senden dauert. :denk:


    Ich kenne so ein Problem von allen Maschinen mit TCP/IP-Anbindung. Wenn die Anzahl der zu sendenen Bytes pro "Kommando" zu gering ist, wartet der Optimierungsalgorithmus von TCP/IP ("Nagle", siehe auch http://de.wikipedia.org/wiki/Nagle-Algorithmus), bis er genügend Daten für ein Paket beisammen hat, bevor er die sendet. Nach Nachfrage, hat die Hotline mir gesagt, wie man diesen Nagle-Algorithmus unter VAL3 ausschalten kann.
    Meinst Du das?


    Gruss


    Spielkind

    Hallo Vogster,


    die Uhrzeit bekommst Du seit VAL3 S6.4 mit dem Befehl getDate(). Allerdings ist hier die Auflösung nur eine Sekunde.


    Anstelle von LLI zu nutzen, kannst Du (ebenfalls seit S6.4??) auch den Betriebssystemtakt von 4ms auf 1ms setzen.
    Aber ACHTUNG: Damit steigt die Systemlast des Gesamtsystems rapide an und es bleibt nur noch sehr wenig Rechenzeit für die Verarbeitung von deiner VAL3 Applikation. Als Kompromiss kannst du ja vielleicht mit 2ms Takt leben? Ansonsten besteht auch die Möglichkeit, eine schnellere CPU von Stäubli zu bekommen.
    Sollte (sogar mit schnellerer CPU) günstiger als LLI sein.
    Damit könnte dann Urmel unterhalb seiner finanziellen Schmerzgrenze bleiben :angel:


    Die aktuellen TCP-Koordinaten bekommst Du dann z.B. so auf den Socket (aus dem VAL3 Handbuch entnommen):


    do
    // get TCP coordinates
    pTemp=here(tTool,world)
    tShiftOut=pTemp.trsf


    // Copy the trsf coordinates into a numerical buffer
    nTrsfOut[0]=tShiftOut.x
    nTrsfOut[1]=tShiftOut.y
    nTrsfOut[2]=tShiftOut.z
    nTrsfOut[3]=tShiftOut.rx
    nTrsfOut[4]=tShiftOut.ry
    nTrsfOut[5]=tShiftOut.rz


    // Encode 6 numerical values (double precision floating point, therefore 8 bytes) into 6*8=48 bytes in nByteOut[48] array
    toBinary(nTrsfOut, 6, "8.0b", nByteOut)


    // Send nByte array (48 bytes) through tcpClient
    sioSet(io:tcpClient, nByteOut)


    delay(0)
    until false


    Gruss


    Spielkind