"Another thread is already controlling the robot" error with nested threads

@jbm, @ajp

We have a force control URCap that starts a thread to control the robot so we can continuously control the robot while executing UR child nodes like “wait” or “set” command.
The robot control pass from main thread to force control thread and it works, like in this little code example

def test():
 global t=0

 thread innerThread():
   j=get_actual_joint_positions()
   t=0
   while True:
     j[0]=sin(t)
     servoj(j, a=3, v=0.75, t=0.008)
     t=t+0.002
   end
 end

 while True:
   movej([0,0,0,0,0,0])
   innerThrd = run innerThread()
   sync()
   while t<1:
     sync()
   end
   kill innerThrd
 end

end

When the force control node is place inside a continuously checked loop, code inside the loop is started by another thread and we obtain neasted thread. During program execution, we obtain “Another thread is already controlling the robot” error which, I think, should not happen. Here a minimal code example that I think should work but fail.

def test():
 t=0

 thread innerThread():
   j=get_actual_joint_positions()
   t=0
   while True:
     j[0]=sin(t)
     servoj(j, a=3, v=0.75, t=0.008)
     t=t+0.002
   end
 end

 thread outerThread():
   innerThrd = run innerThread()
   while True:  
     sync()
   end
 end  
    
 while True:
   movej([0,0,0,0,0,0])
   outerThrd = run outerThread()
   sync()
   while t<1:
     sync()
   end
   kill outerThrd
 end

end

How can I solve this issue ?

Hi @malacasse, I can replicate the behavior you describe. The innerThread be killed with the OuterThread as it’s child, but for some reason is still running when the main loop tries to perform the movej for the second time. If I kill the innerThread individually before killing the outerThread it works as intended.

Don’t have a resolution for you at the moment but will look into it and do some more testing. Please share if you have any updates.

Hi @ajp, I run some test by increasing a variable inside the inner thread and confirm that the inner thread is no longer running once the outer thread is killed. It seems that even if the inner thread is killed, it is still register as the controlling thread.

I also confirm that killing the inner thread with kill command works, so I found a messy work arround but I still need to add a sync or sleep command between the end of outer thread and movej.

Once a thread gets control of the robot, is there a way to give control back to main thread without killing it ?

I believe it should be automatically passed back once it has finished sending movement commands to the robot, so this looks like a bug. We’ve reported it and it’s being investigated now.

Any update on this? I’ve encountered same problem with ursim3-11.082155

With the second example from Malacasse on 3.11. I get a void reference error on starting the inner thread. If I move the definition to the global scope, then I do not experience any issue.
@lautaro.rivero do you have an sample you can share?

I have meet a similar issue in the next case :
image

I don’t know why, but to solve the problem I have to uncomment the movej instruction in Thread2

Do you have a better way to solve this “Another thread is already controlling the robot” error ?