Beiträge von Grubba

    Ich sehe hier heute abend mal in mein Archiv und sende dir mal einen Programmauszug aus der SRC.


    Hab hier eben mal nochmal in mein Prog reingesehen und an einer Stelle B Und C getauscht habe. Ausserdem ist das Vorzeichen von Alpha invertiert, dass ist aber von der Definition des Tool abhängig. Kann aber bis morgen dauern.

    Zitat


    Jetzt bin ich nicht ganz sicher, diese Werte für B un C geben nun an um welche Winkel ich das Tool drehen müsste, wenn es nicht an Pos1 stehen würde, sondern auf X = 0, Y = 0, Z = 1 mit den Winkeln A = 0, B = 0 und C = 0, ist das korrekt?
    Also müsste ich die Ergebnisse noch irgendwie mit der wahren Position des Tools ( Pos1 ) verknüpfen? Die Winkeländerungen müssten ja minimal sein, wie mit der ersten Methode über INV_POS() und den Doppelpunktoperator berechnet.


    Wenn der Bleistift den der Roboter hält genau senkrecht steht, sind A,B und C = 0. So muss das Tool vermessen sein. Dann gilt, das nach den Drehungen um A, B und C auf deinen Punkt gezeigt wird. Die Ausgangsposition ist dann völlig egal, weil du den Richtungsvektor ja schon aus Start und Zielposition ermittelt hast.
    Übrigens kannst du den Winkel A wählen wie du willst, B und C passen sich ja selbständig an. Kann ganz nützlich sein, falls sich mit einem bestimmten Winkel A ansonsten nicht alle Positionen erreichen liessen.


    Ansonsten würde ich dir raten, einfach mal an den Robi zu gehen und von Hand die Achswinkel anzufahren. Dann sollte sich schnell erkennen lassen, obs passt.

    Also B stimmt schon mal überein, C jedoch nicht. Habe mal Werte eingetragen, Ergebnisse stimmen nicht überein.


    Kann dafür jetzt aber in meiner SRC schon mal das J²+K² entfernen, spart mir mit Sicherheit schon wieder 1ms... :ylsuper:

    Zitat


    Kannst du das bestätigen?


    nö...


    Ich habe:
    (J=SIN A, K=COS A)



    ( Jy + xK )
    B = ATAN ( --------- )
    ( J² + K² )
    ( --------------- )
    ( Z )



    ( Z )
    ( --------------------------------------------- )
    C = ACOS ( )
    ( ( ( Jy + xK ) ) )
    ( ( ( -------- ) ) )
    ( COS ( ATAN ( J² + K² ) ) )
    ( ( ( --------------- ) ) )
    ( ( ( Z ) ) )


    Noch eingefallen:
    mit J²+K² = 1 wirds übersichtlicher...


    ( Jy + xK )
    B = ATAN ( --------------- )
    ( Z )



    ( Z )
    ( --------------------------------------------- )
    C = ACOS ( ( ( Jy + xK ) ) )
    ( COS ( ATAN ( --------------- ) ) )
    ( ( ( Z ) ) )



    Viel Spass damit :mrgreen:

    Zitat


    jedoch bekomme ich es nicht wirklich aufgelöst. Habe immer am Ende Sinus UND! Cosinus übrig.


    Das stimmt. Aber auflösen kann man es aber ja trotzdem...


    Jetzt noch einmal zum Prinzip, vielleicht ist es ja doch nicht, was du brauchen kannst:


    Ich definiere einen Punkt, das ist in meinem Fall der Einsvektor 0,0,1. Dann drehe ich diesen Punkt um die drei Achsen mit den Rotationsmatrixen, wie es auch der Roboter machen würde. Dann erhalte ich als Ergebnis die neuen Koordinaten des nun gedrehten Punktes.


    Fragestellung für mich war damals:
    Ich habe einen Punkt im Raum, um welche Werte muss ich die Achsen drehen, damit mein Tool in Richtung dieses Punktes zeigt? Also das Ganze rückwärts rechnen, so erhalte ich durch Vorgabe des Punktes die Achswinkel.


    Da ich die Gleichungen mit dem Einsvektor 0,0,1 aufgestellt habe, muss ich für die Rückrechnung auch einen Einsvektor nehmen, ansonsten passt es nicht.
    Wenn du also z.B. möchtest, dass dein Werkzeug auf 777,0,0 zeigt, musst du 1,0,0 vorgeben. So änderst du die Richtung nicht, und hast trotzdem einen Einsvektor. Der Punkt, durch den dein Werkzeug zeigen soll, ist immer auf 0,0,0 bezogen. Wenn dein Werkzeug parallel zur X-Achse orientiert werden soll, muss du als Zielpunkt 1,0,0 vorgeben, EGAL wo dein TCP gerade liegt.
    In deinem Fall musst du also noch aus deiner TCP-Position und Zielposition den Richtungsvektor ermitteln. Also wie in der Schule Endpunkt-Anfangspunkt. Dann auf Einsvektor normieren und fertig. :D


    Vielleicht kann ichs auch so beschreiben:


    Dein Robi hält einen Bleistift. Jetzt soll dein Bleistift in eine beliebige Richtung zeigen. Diese Richtung definierst du durch den Einsvektor. Die Gleichung ermittelt dann für dich die Achswinkel B und C, nach Vorgabe von A. Die Position des TCP ist dabei also völlig egal. Die Richtung in Form des Einsvektors musst du aber vorher noch selbst ermitteln.

    Ich komme auf:


    (C= Cos, S=Sin, A,B,C=Drehwinkel)


    x = CA x SB x CC + SA x SC
    y = SA x SB x CC - CA x SC
    z = CB x CC


    Alle Winkelfunktionen mit A betrachte ich als Konstante, da A von mir vorgegeben wird und sich ja B und C ergeben sollen. So sehen die Ausdrücke dann nicht mehr ganz so lang aus.


    Diese drei Gleichungen lassen sich nun so auflösen, dass du für B und C Gleichungen erhältst, die als Parameter nur X, Y und Z benötigen.


    Das aufstellen der drei Gleichungen habe ich mit dem Einheitsvektor gemacht, weil sich dadurch das Gleichungssystem vereinfacht.


    Wenn du anschließend wieder X,Y und Z vorgibst, muss der resultierende Vektor auch ein Einsvektor sein. Also z.B. x=y=z=0.577


    Wenn du garnicht vorankommst, schnapp ich mir noch mal meine Schmierzettel und häng mal das Ergebnis an.

    Das mit dem Code-Ausschnitt ist so eine Sache...


    Das Umstellen und Auflösen ist eine Sache von Bleistift und Papier.
    Wenn du das Ergebnis hast, kannst du die Gleichungen mit den Standard Winkelfunktionen einfach in KRL eingeben (Oder C++ oder was auch immer).


    Um mal den Start zu vereinfachen:


    1. Schritt - Drehung Punkt um C


    (1 0 0 ) (0) ( 0 )
    (0 Cos Alpha -Sin Alpha ) (0) = (-Sin Alpha)
    (0 Sin Alpha Cos Alpha ) (1) (Cos Alpha)


    2. Schritt
    Dieses Ergebnis mit der Rotationsmatrix für Drehung um B multiplizieren


    3. Schritt
    Dann dieses Ergebnis mit der Rotationsmatrix für Drehung um A multiplizieren


    Als Ergebnis gibts für jede Koordinate eine Gleichung. Diese dann nach B und C auflösen/umstellen, so dass B und C Funktionen von X,Y,Z und A werden.


    Wichtig ist noch folgendes:
    Zur Vereinfachung der Rechnung ist der ursprüngliche Vektor (oder Punkt) für die Berechnung auf 0,0,1 gelegt. Wenn du nachher X,Y und Z vorgibst, muss die Länge dieses Vektors auch 1 sein.

    Ok, dann mal mein Ansatz:


    Es sei ein Punkt mit den Koordinaten 0.0,0.0,1.0. Das Koordinatensystem ist so, das die Z-Achse nach oben zeigt.


    Nun dreht man diesen Punkt (oder Einsvektor) um die drei Winkel A, B und C.


    Dazu die Reihenfolge so wählen, dass die Drehung um das ortsfeste Koordinatensystem erfolgt.


    Dazu gibts einen schönen Beitrag:
    http://www.roboterforum.de/rob…ierung/msg31321/#msg31321



    Wiki sorgt für die Matrizen:
    http://de.wikipedia.org/wiki/Rotationsmatrix


    Nach dem Anwenden der drei Matrizen auf den Punkt erhält man die neuen Koordinaten in Abhängigkeit von A,B und C.


    Umstellen und Auflösen der Gleichungen nach A,B und C ermöglicht uns dann, einfach die Position des Punktes anzugeben und als Ergebnis die Winkel zu erhalten. Da es für einen Punkt ja eigentlich unendlich viele Lösungen gibt, muss man einen Winkel vorgeben, z.B. A.


    Ich hoffe, es ist verständlich... :huh:

    Ich habe vor einiger Zeit eine Anlage programmiert, bei der das Werkzeug (Plasmaschneider) auf einer Kegelfläche entlang fahren musste. Letztendlich ging es auch dort darum, aus einer gewünschten Orientierung des Werkzeugs im Raum A, B und C abzuleiten. A kann ich vorgeben, B und C ergeben sich dann.


    Das ist aber ohne KUKA Funktionen gelöst, sondern rein durch hergeleitete Mathematik.
    Sollte noch Interesse bestehen, kann ich die Vorgehensweise mal posten.
    Ist keine Hexerei, mit den 3 Rotationsmatrizen und Gleichungsauflösungen kommt man dann relativ schnell ans Ziel.

    Teache dein Bauteil auf einer anderen Base als die des Drehtisches. (Am besten eine, die noch nicht verwendet wurde, dann kannst du zumindest ein wenig hin und herschieben, ohne andere Programme zu beeinflussen.)


    Teache dann deine Punkte auf der neuen Base. Den Tisch kannst du dann manuell verfahren, ohne das sich der Roboter mitbewegt, z.B. über eine LinRel-Bewegung, die jedesmal 60Grad weiterdreht. Die Drehbewegung des Tisches also mit

    Code
    LIN_REL {E1, 60.0}


    oder so ähnlich programmieren.


    Angaben ohne Gewähr, habe gerade keine Doku geschweige denn einen Robi hier....

    Wenn der Drehtisch sich immer um 60° (360/6 Bauteile) weiterdreht und die Teile aus der Robotersicht immer in der gleichen Position und Orientierung befinden, warum dann überhaupt die Base manipulieren? :denk:

    Hier mal 2 Hilfsversuche:


    1. du könntest ja mal den Status der Variable an der Stelle mal anzeigen lassen (decl var_state Meinstatus -> Meinstatus = varstate("iProduktNr"))


    2. Eigentlich ist die Abfrage auf den Status an der Stelle eigentlich überflüssig, da du mit


    Code
    ..
    PNUM2=iProduktNo ;<- Uebergebene Nummer speichern
    ..


    ohnehin schon einmal den Wert iProduktNo zuweist, was ohnehin zum Crash führen würde, wenn sie nicht initialisiert wäre.
    Und wenn iProduktNo nicht initialisiert wäre, würde schon vorher der Aufruf von TypA crashen, sollte die übergebene Variable nicht initialisiert sein.


    Oder hab ich was falsch verstanden? :denk:

    Ab 5.5 kannst du die Meldung mit

    Code
    Set_KrlDlg(...)


    absetzen.
    Dieser Dialog wartet nicht auf Antwort, d.h. der Submit sollte an dieser Stelle nicht halten.


    Mit

    Code
    Exists_KrlDlg(...)


    kann dann geprüft werden, ob und wie der Dialog beantwortet wurde.
    Auch hier wird der Submit nicht angehalten.

    Werde in ca. 2 Monaten das gleiche Problem wie du haben. Hoffe mal, das sich bis dahin noch jemand aus dem Forum erbarmt.


    Damit das hier aber nicht komplett im Spam endet, erst mal eine Möglichkeit, wie ich ein ähnliches Problem mal gelöst habe:


    Du kannst zwar mit einer PTP-Bewegung die Geschwindigkeit nur in % Schritten einstellen, es gibt aber neben $VEL_EXTAX noch einen Prozentwert, der diese Geschwindigkeit beeinflusst. (Habe den Namen aber gerade nicht parat) In Kombination der beiden Overrrides kommst du dann schon auf ein paar hundert Kombinationen.


    Die Maximalgeschwindigkeit steht in den Madas und kann auch über den Achskonfigurator eingestellt werden.


    Ansonsten kommt vielleicht noch die Möglichkeit in Frage, die Drehachse als Linearachse definieren.

    So wie man auch uns sagte, bedeutet HA, das bessere Getriebe verbaut werden. Keine anderen zwar, aber welche, die aus einer Serie besonders positiv herausstechen.


    Jetzt kann man natürlich immer breit grinsen, aber die Fa. Trumpf, von der auch unsere Laserzelle stammt, kauft ihre Roboter bei KUKA. Warum sollte KUKA die mit irgendwelchen Robotern mit Voodoo-Getrieben versorgen, wenns nicht stimmen würde :huh:


    Die Absolutvermessung kann (imho) wohl Unterschiede in den Schwingen oder Winkelversätze herausrechnen, aber ein "unrund" laufendes Getriebe ?


    Der angefahrene Position zwischen einem vermessenen und einen nicht vermessenen Robi kann durchaus ein paar mm betragen. Und vielleicht hilft einem ein HA ja noch ein paar zusätzliche Zehntel.

    Generell macht es keinen Sinn (und ist sicher von KUKA auch nicht gewollt), ein Cycflag manuell zu steuern. Ein Cycflag wird ja schliesslich systemintern im IPO Takt aktualisiert, und auch dafür sollte es verwendet werden.


    Wenns also einfach nur ein globaler Merker sein soll, nimm doch einfach einen gewöhnlichen Flag ($FLAG[n]).


    Und für das beschreiben einer solchen Variablen ausserhalb eines laufenden Programms etc. ist der Submit ja schliesslich da.

    Zitat


    Wie erstelle ich eine globale Variable? Schreibe ich dort den Namen meines Hauptprogrammes rein?


    Du kannst z.B. in der Config.dat eine Variable anlegen, etwa so:


    Code
    DECL INT Programmnummer = 0


    In deinem Hauptprogramm (oder Unterprogramm) schreibst du dann einen Wert in diese Variable, a la:

    Code
    Programmnummer = 1



    In der SPS.Sub fragst du diese Programmnummer ab und reagierst entsprechend:


    usw.


    Du kannst das natürlich auch mit einer SWITCH-CASE Anweisung machen, aber das ist sicherlich Geschmacksache.

    Wenn du die Variable als INT definiert hast, ist die 32 Bit gross.


    Vielleicht gibts da bei KUKA interne Probleme beim wandeln der 32Bit INT auf dein 16Bit SIGNAL.


    Kannst du dein SIGNAL auf 32 Bit erweitern?