Wiederholter Trigger/Interrupt nach jedem zurückgelegten mm

  • Ein Distanz-Sensor am Roboter soll wiederholt während einer Bahnbewegung ausgelesen werden, jeweils in gleichem Abstand.

    Der aktuelle Sensor-Wert soll dann zusammen mit der Position gespeichert werden


    Kann ich irgendwie einen Trigger oder Interrupt anlegen, der immer wieder nach je 1 mm ausgelöst wird?


    Also ich könnte z.b. tausend Trigger anlegen, nach diesem schema


    TRIGGER WHEN PATH = 1.0 ONSTART TIME=0 DO Measure() PRIO -1

    TRIGGER WHEN PATH = 2.0 ONSTART TIME=0 DO Measure() PRIO -1

    TRIGGER WHEN PATH = 3.0 ONSTART TIME=0 DO Measure() PRIO -1

    ...

    SLIN_REL {X = 1000}



    Aber wenn ich richtig verstehe, gibt es ein Limit von 16 Triggern, minus anderer aktiver Interrupts


    Also müsste ich die Bewegung in zig kleine Abschnitte zerstückeln, aber dann gibt es doch wieder Probleme mit dem Überschleifen?


    Oder gibts da eine bessere Methode, um den Trigger wiederholt alle 1 mm auszulösen


    -----


    Um es noch etwas komplizierter zu machen: angenommen ich mache keine Linear-Bewegung, sondern eine Schwenk-Bewegung.

    SLIN_REL {B = 10°}


    Eigentlich will ich dann einen Trigger alle 0.1°, dann hat sich der Laser des Abstands-Sensors auf dem Bauteil ca. 1 mm bewegt.

    Aber der Trigger lässt sich nur bei Verschiebung des TCP setzen, nicht bei Drehungen.

    Ich könnte den im Roboter aktiven Tool-TCP für diese Bewegung auf einen virtuellen Punkt entlang des Lasers zu setzen, und dann eine SCIRC Bewegung, erscheint mir aber etwas riskant.


    -----


    Innerhalb von Measure(), kann ich dann den aktuellen Wert $ANIN[1] zusammen mit der Position beim Auslösen des Interrupts $POS_INT abspeichern, oder gibt es da noch weitere Probleme, sowas wie "$ANIN wird im Vorlauf ausgelesen aber POS_INT im Hauptlauf"?

  • Hallo erstmal,


    es gibt sicher diverse Möglichkeiten.

    Eine die mir auf die Schnelle einfällt das ganze in einem Submit-Interpreter zu lösen. Hier kann man die aktuelle Roboterposition einlesen und vergleichen ob diese sich, im Vergleich zu der Position die den letzten Messwert geliefert hat, weit genug geändert hat um einen neuen Wert einzulesen. Hier kann man ja auf mm und Grad vergleichen. Wenn der Roboter sich nun soweit bewegt hat um einen neuen Messwert zu ermitteln, den Wert einlesen und abspeichern. Anschließend diese Position als neue Vergleichsposition übernehmen.



    Grüße

    Thilbi

  • Hallo Hugo,


    ...

    Kann ich irgendwie einen Trigger oder Interrupt anlegen, der immer wieder nach je 1 mm ausgelöst wird?

    …..

    Es gibt die Systemvariabeln $DISTANCE, ab v8.3 noch $DIST_NEXT, $DIST_LAST, die Du in gewisser Form dafür verwenden kannst.

    Diese Variabeln geben Dir Infos über Distanzen in mm zu Verfahrpunkten.

    Auslösekriterium für Interrupts können auch Variabeln sein.

    Dann könnte dies ja etwas so aussehen.


    DECL MY_DISTANCE


    MY_DISTANCE= 1

    INTERRUPT DECL 1 WHEN $DIST_LAST >= MY_DISTANCE DO MEASURE ()

    INTERRUPT ON

    SLIN_REL {X 1000}

    INTERRUPT OFF



    DEF MEASURE()

    INTERRUPT OFF

    ;…..Speichern Deiner Daten

    MY_DISTANCE=MY_DISTANCE+1

    INTERRUPT ON


    Mit ähnlicher Philosophie könnte man dies auch Applizieren mit Orientierung. (mit der nötigen Berechnung dazu)

    $POS_INT ist Position Auslösung Interrupt und sollte kein Prob sein betreffend Vorlauf.

    Interruptroutine hat keinen Vorlauf, $ANIN[1] zu $POS_ACT evtl. genauer. (Geschwindigkeit)


    Problematiken, die ich generell sehe:

    - Übergänge, Verschleifen (wenn hier Vorlaufstop, dann sicher kein Prob, sonst müsste man das verhalten von diesen 3 Variabeln genau anschauen)

    - Verfahr-Geschwindigkeit (Du hast hier sicherlich eine Begrenzung seitens IPO-Takt zur Auflösung Bahnweg, Rechnerauslastung)

    - Handeln der Datenmenge (wenn in Arrays, Array-Grösse beschränkt, aufteilen in mehrere Arrays, etc.)


    Eine Lösung via Submitinterpreter wäre sicher auch machbar, Hier ist aber zu beachten, dass der Zyklus (Zeit) des Interpreters nicht fix ist.


    Bei ähnlichen Tests vor Jahren mit einer KRC2 einer Hochschule, wo ich unterstützend zu Rate war, brachte die Steuerung regelmässig zum Absturz.

    (mehrere Tausend Positionen, Interrupts < 24ms, 36ms so ok. Ballern auf den Interpreter :D)


    Für Inspektionen von Oberflächen gäbe es die Option FastSendDriver. Diese wurde hierfür spez. Entwickelt. Vielleicht wäre dies was für Dich.


    Gruss SJX

    Manche Maenner bemuehen sich lebenslang, das Wesen einer Frau zu verstehen. Andere befassen sich mit weniger schwierigen Dingen z.B. der Relativitaetstheorie.

  • Thilbi & SJX, Vielen Dank für die Infos schonmal!



    --------

    Implementation im Submit-Interpreter.


    Ist sicher auch eine Variante; Ich bin bisher etwas zurückhaltend, was das ganze Programmieren im Submit angeht; muss ich mir nochmal näher anschauen.


    Meine bisherigen Versuche mit $POS_ACT im Submit führten zu ganz merkwürdigen Abstürzen, selbst mit

    IF (VARSTATE("$POS_ACT") == #INITIALIZED).

    Hab schon gesehen, es gibt dazu weitere Tips auch hier im Forum. Bei ON_ERR_PROCEED krieg ich aber üble Flashbacks aus der Visual Basic Zeit.


    --------


    INTERRUPT DECL 1 WHEN $DIST_LAST >= MY_DISTANCE DO MEASURE ()


    Das ist eine sehr interessante Variante. Wäre mir lieber als Submit-Programmierung.


    Ich hatte mir aber irgendwie gemerkt, dass Laufzeitvariablen in Interrupts gar nicht funktionieren.

    Hab jetzt grade dazu aber nur den Satz gefunden


    Quote from "Kompatibilität von 5.x auf 8.x"

    Laufzeit-Variablen in Triggern

    Verhalten 8.x: Die Robotersteuerung wandelt die Laufzeit-Variable in eine Konstante um. Zu dem Zeitpunkt, an dem der Trigger ausgelöst wird, wird die Konstante der Variablen auf der linken Seite zugewiesen.

    Kann sein, dass damit nur der Teil des Triggers rechts vom DO gemeint ist, nicht die Bedingung.


    Ansonsten wäre meine Sorge noch, dass in der Zeile

    MY_DISTANCE=MY_DISTANCE+1

    INTERRUPT ON

    Es passieren könnte, dass der TCP sich schon einen mm bewegt hat, bevor der Interrupt aktiv wird. Evtl könnte ich das ja mit mehreren redundanten Interrupts lösen.

    Also z.b.

    INTERRUPT DECL 1 WHEN $DIST_LAST >= MY_DISTANCE DO MEASURE ()

    INTERRUPT DECL 2 WHEN $DIST_LAST >= MY_DISTANCE+1 DO MEASURE () ; falls I.1 verpasst wurde

    INTERRUPT DECL 3 WHEN $DIST_LAST >= MY_DISTANCE+2 DO MEASURE () ; falls I.2 verpasst wurde


    ---------


    Wäre es alternativ auch möglich, einen periodischen Interrupt auf einen Timer zu schalten?

    Also INTERRUPT DECL 1 WHEN $TIMER[1]>= LAST_MEASUREMENT+15 DO MEASURE ()

    Solange ich eine Zeit wähle, die etwas größer als der IPO Takt 12ms ist, müsste das doch quasi so funktionieren, wie ein Submit-Abschnitt, nur schneller, und ohne die ganze Problematik, dass der Submit Variablen liest, die grade undefiniert sind oder geändert werden, und ohne dass ich bei Problemen den ganzen Submit abschieße?



    Hab leider die Hardware noch nicht da zum testen


    ------


    Interruptroutine hat keinen Vorlauf, $ANIN[1] zu $POS_ACT evtl. genauer. (Geschwindigkeit)

    Das ist auf jeden Fall mal interessante Info; das es keinen Vorlauf im Interrupt gibt, war mir bisher nicht klar, aber irgendwie logisch. Deswegen gibts da wohl auch keine Spline-Bewegungen. Dann könnt ich ja auch $POS_ACT_MES nehmen.