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
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.
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?