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=0thread 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
endwhile True:
movej([0,0,0,0,0,0])
innerThrd = run innerThread()
sync()
while t<1:
sync()
end
kill innerThrd
endend
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=0thread 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
endthread 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
endend
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 :
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 ?