Beiträge von Micky

    Hallo Maddin,


    der Unterschied zwischen INOUT, PERS und VAR liegt darin, dass bei VAR und PERS die Variable die übergeben wird als VAR bzw. als PERS deklariert sein muss. Wird z.B. eine als VAR deklarierte Variable an eine Routine übergeben, die eine PERS erwartet, so wird ein Fehler ausgegeben.


    Bei der Verwendung von INOUT erfolgt keine Prüfung des Übergabeparameters, so dass man eine als VAR oder eine als PERS deklarierte Variable übergeben kann.


    Durch VAR und PERS kannst Du also definieren, wie Deine Ergebnisvariable im System deklariert sein muss.


    Vgl. auch die Übergabeparameter "tool" und "Wobj" in der Instruktion "MoveL", denn die müssen auch als PERS deklariert sein.


    Gruß
    Micky

    Hallo mKilber,


    Du solltest Deine Positionswerte für die Homeposition nicht in der Konstanten "Delta_Pos" verwenden, sondern innerhalb der Konstanten "home_pos", denn Du überwachst die Homeposition [1,1,1,1,1,1] und läßt dabei riesige Abweichungen zu, z.B. 70 Grad in der ersten Achse.


    Normalerweise gibt man in der Deltapos die zulässige Abweichung bezogen auf die Homepos an.


    Anbei das Besipiel aus dem Referenzhandbuch:



    Gruß
    Micky

    Hi,


    Du könntest vieleicht auch die Position in einem Gruppenausgang anstelle von einer Variablen speichern.
    Hierzu würdest Du alle Bewegungen mit einer TriggL oder TriggJ Instruktion ausführen und über die Instruktion TriggIO die Positionsnummer definieren, die beim Erreichen der Position gesetzt werden soll.


    Wenn Du zusätzlich noch in den Systemparametern "Store Signal Value at Power Fail" beider der Gruppe setzt, wird der Wert beim einem Neustart bzw. Stromausfall wieder auf den alten Wert gesetzt.


    Zur vereinfachung würde ich die Trigg Anweisung in einer eigenen Bewegungsinstruktion kapseln, so dass das ganze wie folgt aussehen könnte:


    Code
    PROC MyMoveL(num ActPos,robtarget ToPoint,.....)
      VAR triggdata trPosition;
    
    
      TriggIO trPosition, 0\GOp:=goActPos, ActPos;
      TriggL ToPoint, speed, trPosition, zone, tool;
    ENDPROC


    Später köntest Du dann die Position wie folgt abfragen:


    Code
    IF GOutput(goActPos)=...



    Gruß
    Micky

    Hi,


    bei der Movel-Instruktion gibt es optionale Parameter, die man nutzen kann oder auch nicht.


    Wenn Du an eine Routine optionale Parameter übergibst, und diese beim Aufruf an eine anderen Routine übergeben möchtest, musst Du Prüfen ob der Parameter übergeben wurde und den Aufruf der Instruktion einmal mit und einmal ohne diesen Parameter programmieren.


    Code
    proc MyMoveL(...\num T,...)
    
    
      IF Present(T) THEN
          MoveL ....\T:=T....;
      ELSE
          MoveL ....
      ENDIF


    Wenn man aber wie in unserem Fall mehrere optionale Parameter übergibt, müsste man jede mögliche Kombination im Programm abfangen.


    Um dies zu vereinfachen gibt es das "?", d.h. bei einem optionalen Parameter schreibt man anstelle von "\T:=T einfach "\T?T".
    Wird z.B. bei unserer Routine der optionale Parameter "\T" verwendet, so wird er duch das "?" an die MoveL-Instruktion übergeben. Wird der Parameter "\T" aber nicht verwendet, so wird auch nicht weitergegeben.


    Der Programmieraufwand bei optionalen Parametern die weitergegeben werden müssen, wird durch die Verwendung des Fragezeichen erheblich reduziert.


    Gruß
    Micky

    Hallo,


    die Option "HomeposRunning" ist kostenpflichtig. Die aktuelle Doku habe ich Dir angehängt.


    Verwendung von Inpos:


    Im Referenzhandbuch unter Datentypen findest Du unter "stoppointdata - Stopppunktdaten" ein ausführliche Beschreibung mit Beispielen und Bildern.


    Es gibt die Option "WorldZones", mit diesen Weltzonen kann man einen Ausgang setzen lassen, wenn der Roboter-TCP sich innerhalb oder außerhalb des definierten Bereich befindet. Zusätzlich kann auch der definierte Raum für den Roboter gesperrt werden.
    Nähere Informationen hierzu kannst dem Referenzhandbuch entnehmen.



    Zu Punkt 4.


    - In der Steuerung können nur eine begrenzte Anzahl von Weltzonen eingesetzt werden. Um alle Punkte abzudecken wäre der Aufwand recht groß.
    - Die Überprüfung der Position ist sehr schwierig, denn außer bei einem Finepunkt befindet sich der Roboter nie an dem programmierten Punkt.
    - Bei Punkten mit sehr kleinen Abständen kann nicht korrekt bestimmt werden, an welchem sich der Roboter gerade befindet.
    - Prinzipiell müsstest Du aber nur für jede Position eine eigene SyncRoutine verwenden, in der die Positionszuweisung für den jeweiligen Punkt erfolgt, denn die Routine wird ja an der richtigen Position aufgerufen.


    Das Problem kann mit Sicherheit gelöst werden, bedarf aber sicherlich einen sehr hohen Testaufwand bis alles fehlerfrei funktioniert.


    Aus diesem Grund setzen wir "HomeposRunning" ein, denn damit funktioniert zum einen die Positionszuweisung und man kann die bereits erstellten Bewegungsroutinen für die Bewegung in die Homeposition nutzen.


    Gruß
    Micky

    Hi,


    wie bereits erwähnt kannst Du die Funktion GetToolData bei der Instruktion MoveL nicht einsetzen, da diese eine persistente und keine Funktion erwartet.


    Aus diesem Grund hatte ich Dir ja vorgeschlagen eine eigene Move-Instruktion zu verwenden, die zuerst das Tool ausliest und einer persistenten zuweist um dann die Bewegung mit dem zuvor zugewiesenen Tool auszuführen.


    Leider habe ich deine Frage nicht verstanden, welche Klammers meinst Du den ?


    Du Kannst auch anstelle einer Funktion eine Prozedur mit Rückgabewert erstellen, aber diese kannst Du nicht innerhalb der MoveL Instruktion aufrufen, sondern muss vorher ausgeführt werden.


    Gruß
    Micky

    Hallo,


    Du könntest evtl. die TRAP Routine durch Verwendung der RAISE-Instruktion über die Fehlerbehandlung verlassen, dann hast Du durch die Verwendung eines LongJumps die Möglichkeit dein Programm in der Fehlerbehandlung der gerade ausgeführten oder deren aufrufenden Routine fortzusetzen und die nicht benötigten Instruktionen zu umgehen.


    Die Funktion des Longjumps bei einer Fehlerbehandlung ist im "Technical reference manual - RAPID kernel, Kapitel 7.2 Error recovery with long jump" ausführlich beschrieben.


    Gruß


    Micky

    Hi,


    Du könntest Dir für diesen Fall einen eigene Move-Instruktion schreiben, bei der Du den Toolnamen als String übergibst und dieser intern ausgewertet wird.






    Gruß
    Micky

    Hi,


    in einer MoveL Instruktion müssen die übergebenen tool und wobj-Daten als persistent deklariert werden.


    Aus diesem Grund darf der Aufruf der Function GetTool nicht in einer Bewegungsinstrukion (Movel) verwendet werden, da diese nur eine Wert zurückliefert.


    Du musst die Instruktion zweiteilen:


    1. Erforderliches Tool und wobjdata auslesen und einer persistenten zuweisen
    2. Bewegunginstruktion mit den zuvor zugewiesenen persistenten verwenden.


    Code
    Beispiel:
    
    
    TASK PERS tooldata tGripper:=...
    
    
    tGripper:=GetTool("To_Grippe_");
    MoveL  GetRobt("pMachMal_"+strProduct{nProductNew}),v10,z1,tGripper\WObj:=wo_HolPal;



    Gruß
    Micky

    Hi,


    wie Du die Werte des Arrays in der Funktion auswertest bleibt im Prinzip Dir überlassen.


    Du musst in Deinem Fall auf die Stringoperation StrPart zurückgreifen.




    Die Funktion "GetToolData" hat bei mir einwandfrei funktioniert. Du musst nur sicherstellen, dass das Tool als TASK PERS deklariert ist.


    :gutidee:


    Code
    TASK PERS tooldata tGripper1:=[TRUE,[[66.1163,0,77.3762],[0.92388,0.000172633,0.382683,0.000172633]],[4.6,[-44,56.5,18],[1,0,0,0],0.372,0.082,0.317]];
    TASK PERS tooldata tGripper2:=[TRUE,[[166.1163,0,77.3762],[0.92388,0.000172633,0.382683,0.000172633]],[4.6,[-44,56.5,18],[1,0,0,0],0.372,0.082,0.317]];
    
    
    tGripper1:=GetToolData("tGripper2");


    Gruß
    Micky

    Hallo,


    zu 2: InPos ersetzt nur das Zonenargument, eine Zuweisung der Positionsnummer erfolgt dadruch nicht.


    zu 3: Deine Syncroutine wird in der Mitte der Zone zwischen den beiden Punkten ausgeführt, das Abfragen der aktuellen Position bringt hier nichts, da Du dich zum zeitpunkt der Abfrage nie an der programmierten Position befindest


    zu 4: Die Instruktion SMoveL die Du angehängst hast, kann bei den heutigen Steuerungen so nicht mehr verwendet werden, denn deine Positionszuweisung erfolgt direkt nach der MoveL instruktion. Aufgrund der Rechnervoreilung kann aber diese Programmzeile bereits abgearbeitet sein, bevor der Roboter diese Position überhaupt erreicht hat. Hierdurch würdest Du in Deinem Programm von einer ganz falschen Roboterposition ausgehen, z.B. die nächste oder übernächste Position.


    ABB bietet eine Softwareoption mit dem Namen "Homepos-Running" an, deren Bewegungsinstruktionen ebenfalls "SMoveL", etc. heißen. Bei diesen Instruktionen funktioniert aber die korrekte Zuweisung der Positionsnummer.



    :waffen100:


    Mehr zu diesem Thema wurde in diesem Forum bereits in mehreren Beiträgen behandelt.


    http://www.roboterforum.de/rob…hlsatz_smove-t5053.0.html


    Gruß
    Micky

    Hi,


    mit der Instruktion GetDataVal kannst Du im Prinzip jeden beliebigen Wert auslesen. Vielleicht kannst Du auch die Instruktionen GetSysData bzw. SetSysData verwenden.


    Code
    FUNC tooldata GetToolData(string Name)
        VAR tooldata tool;
    
    
        !Read the type depending position
        GetDataVal Name,tool;
        RETURN tool;
        !
      ENDPROC



    Du solltest aber bei solchen Konstrukten darauf achten, dass dein Programm noch zu handhaben ist, denn beim Teachen der Positionen können sich dadurch recht schnell Fehler einschleichen. :aufsmaul:


    Gruß
    Micky

    Hallo,


    da die Funktion "GetRobt" eine Robtarget zurückliefert, kannst Du alle anderen Funktionen die eine robtarget verändern benutzen, d.h. RelTool und Offs können, genauso wie Du es angegeben hast, verwendet werden.


    Gruß


    Micky

    Hallo,


    versuch es doch mal mit der folgenden Funktion:


    Code
    FUNC robtarget GetRobt(string Name)
        VAR robtarget pPoint;
    
    
        !Read the type depending position
        GetDataVal Name,pPoint;
        RETURN pPoint;
        !
      ENDPROC



    Dein Aufruf könnte dann wie folgt aussehen:


    Code
    MoveL GetRobt("pMachMal_"+strProduct{byProduct_ID}),v10,z1,.....


    Gruß
    Micky

    Hallo relax,


    Du solltest die Instruktion SpeedRefresh verwenden, denn diese veranlasst die sofortige Geschwindigkeitsänderung.
    Velset wird erst ab der nächsten Bewegunginstruktion aktiv.


    Zu Geschwindigkeitsanpassung könntest Du z.B. einen Interrupt verwenden (ITimer), der aufgrund einer Bedingung die Geschwindigkeit anpasst.


    Falls Dir die Maschine ein Positionssignal überträgt, könntest Du auch die ABB Option "Sensor Synchronization" verwenden.


    Gruß


    Micky

    Hallo Martin,


    :meld: enum-Variablen gibt es in RAPID nicht !!


    Du könntest Dir aber einen Alias Datentyp auf eine numerische anlegen, und diese dann im Programm verwenden


    Beispiel:
    ALIAS num Farbe;


    CONST Farbe Blau:=1;
    CONST Farbe Grün:=2;
    CONST Farbe Gelb:=3;


    PERS Farbe MyColor:=1;


    Im Programm erfolgt dann die Zuweisung:
    MyColor:=Blau;
    oder
    MyColor:=1;


    Dadurch, dass hier eine numerische Variable vorliegt, die jetzt unter Datentypen als Farbe angezeigt wird, enthält MyColor den Wert 1.


    Fehlerer bei falscher Zuweisung werden durch das System nicht angefangen, da z.B. auch die folgende Zuweisung zulässig ist-> MyColor:=5;


    Prinzipiell kann ein ALIAS-Datentyp dazu verwendet, um die Datenauswahl im Datenfenster zu reduzieren bzw. um Daten anzulegen die speziellen Funktionen zugeordnet sind (z.B. Farbe).


    Der Datentyp symnum ist auch nur ein Alias-Datentyp auf "num".


    In RAPID gibt generell nur drei Grunddatentypen: num, bool und string. Alle anderen Datentypen sind entweder Alias-Datentypen oder Records die auf diese Datentypen aufbauen.


    Gruß
    Micky

    Hallo Dingi,


    Du kannst die Funktion "TestDI" verwenden, diese liefert Dir einen boolschen Wert zurück.


    Beispiel:


    bTest :=TestDI (diTest );


    Alternativ ginge auch folgende Syntax:
    bTest := diTest = high; ! -> bTest ist TRUE, fallse der Eingang diTest auf "high" gesetzt ist.


    Gruß
    Micky

    Hallo hatek,


    SMove\J is eine Instruktion von "HomeposRunning" und wird verwendet um den Roboter zu bewegen und zu speichern wo er sich gerade befindet.



    Das ganze dient dazu, um den Roboter aus jeder automatisch angefahrenen Position kollisionsfrei in die Grundstellung fahren zu können.


    Die Instruktion SMove\J wird bei der S4c-Plus verwendet um die Bewegungsart von Linear auf Joint oder umgekehrt, ohne Neuprogrammieren der Zeile, am Programmiergerät auf einfache Weise ändern zu können.


    Zum Ändern der Bewegungsart gibt es bei der IRC5 jetzt einen eigenen Button im Edit-Fenster, so dass die Instruktionen jetzt SMoveJ bzw. SMoveL heißen.


    Das Argument \NoMove wird normalerweise bei der ersten Instruktion in einer Bewegungsroutine verwendet und ermöglicht, dass die Instruktion im Automatikbetrieb nicht ausgeführt wird, so dass Stoppunkte durch doppeltes Anfahren einer Position verhindert werden. Im Handbetrieb wird diese Position aber angefahren, so dass man die Bewegung des Roboters optimieren kann.


    Zusätzlich wird \NoMove verwendet um die aktuelle Position bei der Fahrt in die Grundstellung zu finden, das heißt der Startpunkt in jeder Bewegungsroutine enthält das Argument \NoMove.


    Nähere Informationen zu dem Thema kannst Du dem HomeposRunning -Referenzhandhandbuch entnehmen.


    :zwink:



    Gruß
    Micky