Detach Tool
SUMMARY
detach_tool removes a previously attached tool from the robot, so it no longer appears in visualization or is accounted for in kinematics.
The Skill
python
robot.detach_tool()0:00 / 0:00
The Code
python
"""
Attaches a gripper and visualizes it, then detaches it from the Rerun visualization again.
Supports Universal Robots (UR), Epson, virtual, and Isaac Sim.
Passing ``--gripper_prim_path`` connects the simulated gripper, so attach_tool()
also fixes it to the arm's flange in Isaac Sim. Note that detach_tool() affects
the visualization only: a tool assembled onto the arm in the simulation stays
assembled, because the simulation offers no way to take it back off.
Usage:
python detach_tool.py [--ip <ROBOT_IP>]
python detach_tool.py --prim_path <PRIM_PATH> [--gripper_prim_path <GRIPPER_PRIM_PATH>]
"""
import argparse
import time
from loguru import logger
from telekinesis.synapse.robots.manipulators import universal_robots
from telekinesis.synapse.tools.parallel_grippers import schunk
def main(ip: str | None,
prim_path: str | None,
gripper_prim_path: str | None) -> None:
"""Attach a gripper, visualize it, then detach it again."""
#===================== Create Robot and Gripper =============================
robot = universal_robots.UniversalRobotsUR10E(name='UR10e')
gripper = schunk.SchunkEGU50()
# ==================== Visualization (Optional) ================================
robot.visualize_rerun()
try:
#===================== Connect Robot ==========================================
if ip:
robot.connect(ip=ip)
elif prim_path:
robot.connect(simulation_prim_path=prim_path)
robot.set_joint_positions(robot.default_joint_configuration)
#===================== Connect Gripper (Isaac Sim) ============================
# attach_tool() fixes the tool to the flange in the simulation only when
# the tool reports the ISAACSIM protocol, which it does after connecting
# to its own prim. On hardware the gripper needs no connection here: the
# attachment is for co-visualization only.
if gripper_prim_path:
gripper.connect(simulation_prim_path=gripper_prim_path)
elif ip:
logger.warning("Running on real hardware: attach_tool() registers the tool "
"for co-visualization only. Nothing is physically attached - "
"mount the gripper on the flange yourself.")
elif prim_path:
logger.warning("Connected to Isaac Sim without --gripper_prim_path: the "
"gripper is only drawn in Rerun, not fixed to the arm in the "
"simulation. Pass --gripper_prim_path to assemble it.")
# ==================== Run Skill ============================================
robot.attach_tool(gripper)
time.sleep(2)
logger.info("Gripper attached and visualized.")
# detach_tool() clears the tool from the Rerun recording. It never undoes
# a physical mount, nor an Isaac Sim assembly.
if ip:
logger.warning("Running on real hardware: detach_tool() clears the "
"co-visualization only. The physically mounted gripper is "
"untouched - remove it from the flange yourself.")
elif gripper_prim_path:
logger.warning("Isaac Sim: detach_tool() clears the visualization only. The "
"gripper stays fixed to the arm in the simulation - it offers "
"no way to take an assembled tool back off.")
robot.detach_tool()
logger.success("Gripper detached from visualization.")
except (ConnectionError, OSError) as e:
logger.error(f"Error occurred: {e}")
finally:
if gripper.is_connected:
gripper.disconnect()
robot.disconnect()
robot.shutdown()
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Detach a tool from the robot")
parser.add_argument("--ip", type=str, default=None,
help="UR robot IP address for real hardware, e.g. 192.168.1.100")
parser.add_argument("--prim_path", type=str, default=None,
help='Isaac Sim articulation prim path, e.g. "/World/ur10e"')
parser.add_argument("--gripper_prim_path", type=str, default=None,
help='Isaac Sim gripper prim path, e.g. "/World/schunk_egu50". '
'Required to fix the tool to the arm in simulation.')
args = parser.parse_args()
main(ip=args.ip,
prim_path=args.prim_path,
gripper_prim_path=args.gripper_prim_path)Running the Example
bash
python detach_tool.pybash
python detach_tool.py --prim_path /World/ur10e --gripper_prim_path /World/schunk_egu50bash
python detach_tool.py --ip 192.168.1.100For all options:
bash
python detach_tool.py --helpParameter Configuration
| Parameter | Type | Default | Description |
|---|---|---|---|
recording_stream | rr.RecordingStream | None | None | The Rerun recording stream to clear the tool visualization from. If None, uses the global recording. |
Returns
| Type | Description |
|---|---|
None | detach_tool removes the attached tool as a side effect. Call robot.visualize_rerun(...) afterward to confirm the tool no longer renders. |
Where to Use the Skill
- Tool changes - Detach the current tool before attaching a different one with Attach Tool.
- Cleanup - Remove a tool from visualization/kinematics when it's no longer mounted on the real robot.
When Not to Use the Skill
- No tool is attached - there's nothing to detach; calling
attach_tooldirectly is sufficient when mounting the first tool. - You only need to switch TCPs - use Change Active TCP instead, which doesn't remove the attached tool.