External_control gets blocked by own URScript

Greetings. I want to control a UR with ROS2 Humble using the external_control URCap. This works well, including MoveIt and Pilz Industrial Motion planner. There is also a gripper mounted on the UR, which is a OnRobot RG6 V1.0 gripper. I’ve got the URCap for the gripper which also works fine from the control panel.
In order to get control over gripper from ROS2 I’ve created a little URCap including a URScript which demands a XML-RPC connection to one of my ROS nodes. This is also working as intended, I can open and close the gripper with all parameters provided by OnRobots URCap.

If I try to use external_control to control the robot via ROS and my URCap is running, then I am not able to control the robot anymore. My URCap consist only of a single of each InstallationNodeContribution, InstallationNodeService and InstallationNodeView. Like in external_control these are only used to load a custom URScript snipped into the robot program.

The URScript snipped:


# Constants
xmlrpc_rg6_ip = {{IP_ADDRESS}}
xmlrpc_rg6_port = {{PORT_NO}}
xmlrpc_rg6_keepalive = True

textmsg("RG6 Gripper Control: Starting XML-RPC Server for RG6 Gripper control")
xmlrpc_rg6_conn = rpc_factory("xmlrpc", "http://" + xmlrpc_rg6_ip + ":" + xmlrpc_rg6_port + "/RPC2")

thread gripperThread():
    textmsg("RG6 Gripper Control: Start thread")
    while True:
        global xmlrpc_rg6_keepalive = xmlrpc_rg6_conn.getKeepAlive()
        if xmlrpc_rg6_keepalive == False:

        local xmlrpc_rg6_width = xmlrpc_rg6_conn.getWidth()
        local xmlrpc_rg6_force = xmlrpc_rg6_conn.getForce()
        local xmlrpc_rg6_dcompensation = xmlrpc_rg6_conn.getDepthCompensation()
        local xmlrpc_rg6_payload = xmlrpc_rg6_conn.getPayload()

        if xmlrpc_rg6_payload >= 0.0:
            local xmlrpc_rg6_spayload = False
            local xmlrpc_rg6_spayload = True
        # This command is only available if OnRobot URCap (RG - OnRobot v1.10.1) is installed
        RG6(target_width = xmlrpc_rg6_width, target_force = xmlrpc_rg6_force, payload = xmlrpc_rg6_payload, set_payload = xmlrpc_rg6_spayload, depth_compensation = xmlrpc_rg6_dcompensation)
    textmsg("RG6 Gripper Control: Stop thread")
    return False

if xmlrpc_rg6_keepalive:
    global xmlrpc_rg6_thread = run gripperThread()

join xmlrpc_rg6_thread
textmsg("RG6 Gripper Control: XML-RPC Server for RG6 Gripper control stopped")


In RViz I can see the robot, its current pose, plan and execute the planned path. The ros2_control controller returns execution succeeded after ordering path execution.

What is the problem? Is my snipped blocking the external_control execution?

Problem solved, to end the gripper control, the thread shouldn’t be joined but killed.

Removed line: join xmlrpc_rg6_thread
Modified lines:

if xmlrpc_rg6_keepalive:
    global xmlrpc_rg6_thread = run gripperThread()


if xmlrpc_rg6_keepalive:
    global xmlrpc_rg6_thread = run gripperThread()
    kill xmlrpc_rg6_thread

Could you provide the URCap?