Trigger a signal (set an output) during movement after a certain distance, or before reaching a point

Dear you all,
is there a proper way to implement the following feature :
when sending a movement to a target position, the UR triggers a signal (for instance it turns ON an output) after moving a certain distance from current position. Or before a certain distance to a target position.
For instance : movel(pose, a=1.2, v=0.25, t=0, r=0, trigger_after = 10mm)
or movel(pose, a=1.2, v=0.25, t=0, r=0, trigger_before = 2mm)

This is a feature you have in KUKA, FANUC and STAUBLI.
For instance in KUKA :
TRIGGER WHEN PATH= 10 ONSTART DELAY=0 DO $OUT[0=TRUE
;Reset Output when target is reached
TRIGGER WHEN DISTANCE=1 DELAY=0 DO $OUT[0]=FALSE

In FANUC, this is something like :
L P[1] 100mm/sec FINE DISTANCE BEFORE 10mm DO[1] = ON

is there such a function in UrScript ? I guess I may find a way with starting a thread, looping with a “get position” and computing a distance. But I dislike implementing something “dirty” myself, if the controller can offer me a better/proper way.

Best Regards
Boris

1 Like

Anyone has an answer / a proposal?

image

I think this works. You can add "Until"s to your waypoint nodes and then choose expression. Use the Point_Dist() function and pass it the current tcp pose, and the waypoint you’re going to. Set it <= whatever distance you want (in meters)

Because you asked for URScript, no there’s not a direct function for this. Here’s what Polyscope generates to achieve the above execution:

global move_thread_flag_4=0
    thread move_thread_4():
      enter_critical
      move_thread_flag_4 = 1
      movej(get_inverse_kin(Waypoint_1_p, qnear=Waypoint_1_q), a=1.3962634015954636, v=1.0471975511965976)
      move_thread_flag_4 = 2
      exit_critical
    end
    move_thread_flag_4 = 0
    move_thread_han_4 = run move_thread_4()
    while (True):
      if (point_dist( get_actual_tcp_pose (), Waypoint_1_p) < 0.1):
        kill move_thread_han_4
        stopj(1.3962634015954636)
        $ 5 "Until (expression)"
        $ 6 "Popup: Stopped X distance before waypoint"
        popup("Stopped X distance before waypoint", "Message", False, False, blocking=True)
        break
      end
      sleep(1.0E-10)
      if (move_thread_flag_4 > 1):
        join move_thread_han_4
        break
      end
      sync()
    end

So basically, Polyscope is doing what you suggested, by making a thread and monitoring the TCP position with respect to the target waypoint.

Thank you Enric.
Too bad there is no operator to do this “off the shelf”.
Your sample is a good source of inspiration. Thank you. In my case, this will be a linear move, and I don’t want to stop the movement once i get the distance condition equal to true.
Maybe I will “invert” who is in the thread (put the get_actual_tcp_pose within a thread, the movement in the main script, and kill the thread). I will test.
Can you tell me more about the

$ 5 "Until (expression)"

?
this looks like linux bash/shell syntax.

Kind Regards
Boris

That’s just how Polyscope denotes a line. It’s not an actual command. It’s just saying line 5 is an Until expression node, then writes the script for that node. Just to make it easier to follow the code

Hello,

Again, while there is no native function to accomplish this, this method should achieve your results. You can alter the order of get_actual_tcp_pose() and another waypoint to determine distance as you move away from a point or distance as you approach a point. You’ll want to adjust where you trigger the event thread as well. If you go the event route, only one event can run at a time, so keep that in mind when ordering the triggers and exiting the Event. Here are screen caps of the GUI code and script generated by that GUI code:

thank you for the explanation

Thank you Miwa. Sure this should work / trick. But usually, when you code it yourself, there is an execution overhead. The codes (within the loop in the thread) might execute slower, and in a none real time fashion. Rather than if this was compiled within the code of the motion controller. The start of the trigger depends on the “speed” of the evaluation of this loop. So the trigger may be started at a different physical point, especially if the robot jog at high velocity. I guess the distance shift due to this none real time behaviour is probably small. But this might be an issue for high precision scan / digitization using a 3D sensor. What do you think ?

Typically when you run threads you actually have to put sync() commands at the end to chew up the rest of the scheduling time because the thread is going FASTER than the main task scheduling the robot motion. I’d be surprised if you run into some issue here