Break From Sub-Program or Multiple Thread Motion

Edit:
While not ideal, I was able to get the desired behavior by having the outer-most construct of my sub-Program to be an IF-ELIF statement, both clauses being “continuously checked”.

It would be nice to have the ability to perform an early return from a sub-Program.

Hey all,

I’m looking for some help on a UR10e project that interfaces with a PLC. The PLC is controlling the state of the robot’s environment; e.g. cylinder positions, object positions, etc. Therefore, I wanted the PLC to be the source that initiates/terminates robot motion commands.

I often use a control structure with an ENUM/INT that signifies the type of “Operation” I want a piece of equipment to execute. For example, in both my PLC and UR I have a DINT “Operation” where the PLC commands the UR to execute an “Operation” (“Move to Home” Sub-Program). In my main “Robot Program”, I use an IF-ELIF-THEN or SWITCH statement to call the appropriate sub-program exactly once based on the commanded “Operation”.

The UR-PLC communication is handled via PROFINET and a Thread that cyclically calls a URScript. The URScript maps the PROFINET Inputs/Outputs to/from “Installation” variables and does other process control logic.

Everything works great, until I want to satisfy my “OP_CANCEL_OP” operation, which is to stop motion if and only if an “Operation” (e.g. sub-Program) is already running, but should maintain the UR main “Robot Program” in a running state.

Initially, I just used my central URScript to call stopj(a=2), but I received the error that “Robot motion is being controlled from another Thread” and my program left the running state.

I then tried to use a continuous IF check in main “Robot Program”, but that didn’t seem to truly be continuously checked once a sub-Program had been called.

Finally, I tried to put a continuous IF check in the last operation of a sub-Program, in the hopes that when it evaluated to True, it would preempt the above logic of the sub-Program. This also didn’t seem to help.

Any assistance or perspective on this would be appreciated.

V/R,
Adam H.

Hi @adam.haney
maybe you could run your sub programs as threads and use kill command to stop them.

Here an example (using I/O to simulate PLC signals that start and stop the sub program):

2025-01-28+12-13-41

Here the code:

global thread_id = 0

thread sub1():
    while True:
    	textmsg("Running sub 1...")
    	movej([-1.60, -1.73, -2.20, -0.81, 1.60, -0.03])
    	movej([1.60, -1.73, -2.20, -0.81, 1.60, -0.03])
    end
end

while True:
    textmsg("Running main...")
    sleep(2)

    if get_standard_digital_out(1):
        textmsg("Starting sub...")
        thread_id = run sub1()
    end

    if get_standard_digital_out(2):
        textmsg("Stopping sub...")
        kill thread_id
    end
end


@Robpod
I really appreciate you taking the time to respond to me. Thank you! I believe your solution would most likely achieve the functionality I was asking about.

However, the reason why that approach doesn’t fully satisfy my use-case is that I’m trying to preserve the selling points of Universal Robots for the customer; e.g. the GUI driven programming environment. I’d like the majority of my movement programming to be GUI based with just the PLC communication and “Cancel Op” being URScript based.

On another note, what IDE are you using in that video capture, because it is beautiful and has awesome URScript syntax highlighting. I’ve been programming URScript either in Notepad++ then sftp to robot or VNC into robot and use editor there. My robot Polyscope is v5.17.

You are welcome!
The script was just to give an idea about the possible structure of the program :grinning:
You could achieve the same result also with the standard polyscope block commands for threads in the GUI.

The IDE is Robpod Studio, a platform that our company has built for UR developers.
You can find more info here: