Is Tool in Contact
SUMMARY
Is Tool in Contact checks whether the tool has made contact with an object in the given Cartesian direction. Returns True immediately when contact is detected, False otherwise.
SUPPORTED ROBOTS
Currently supported only on Universal Robots.
UNITS
direction is a 3-element Cartesian vector [dx, dy, dz] (unitless - only the direction matters, not magnitude). Returns a boolean.
The Skill
contact = robot.is_tool_in_contact(direction=[0.0, 0.0, 1.0, 0.0, 0.0, 0.0])The Code
Example: Check for Contact Along the Tool Z Axis
Connect to the robot and check for contact along the downward tool Z axi while jogging the the TCP.
"""
Tool contact polling example for the Synapse SDK.
``is_tool_in_contact`` is the low-level contact-detection primitive which
only returns ``True`` **while the robot is actively executing
motion**. On an idle robot it always returns ``False``, so the usual
pattern is to poll it from inside a streaming-motion loop.
This example starts a slow Cartesian jog toward -Z and polls
``is_tool_in_contact`` each tick. When contact is detected (or a safety
timeout elapses), it issues ``stop_jog`` to halt the motion.
For the one-shot equivalent (start a move, block until contact, stop),
use ``move_until_contact`` instead.
Currently supported only for Universal Robots (UR10e).
Usage:
python is_tool_in_contact.py --ip <ROBOT_IP>
"""
import argparse
import time
from loguru import logger
from telekinesis.synapse.robots.manipulators import universal_robots
def main(ip: str):
"""Jog the TCP toward -Z and stop the instant contact is detected."""
# Motion parameters
cartesian_velocity = [0.0, 0.0, -0.05, 0.0, 0.0, 0.0] # -Z at 5 cm/s in base
direction = [0.0, 0.0, -1.0, 0.0, 0.0, 0.0] # contact axis matches motion
poll_dt = 0.005 # 200 Hz polling
safety_timeout = 5.0 # stop after this long even if no contact
# Create and connect to the robot
robot = universal_robots.UniversalRobotsUR10E()
robot.connect(ip=ip)
try:
# Start the jog. is_tool_in_contact only returns True while moving.
logger.info(f"Starting jog along -Z at {abs(cartesian_velocity[2])} m/s")
robot.start_jog(
cartesian_velocity=cartesian_velocity,
feature=0,
cartesian_acceleration=0.5,
)
# Poll for contact and stop as soon as it's detected.
t0 = time.monotonic()
contact = False
while time.monotonic() - t0 < safety_timeout:
if robot.is_tool_in_contact(direction=direction):
contact = True
break
time.sleep(poll_dt)
# Halt the motion regardless of how the loop exited.
robot.stop_jog()
if contact:
logger.success(f"Contact detected after {time.monotonic() - t0:.3f} s — jog stopped.")
else:
logger.warning(f"No contact within {safety_timeout} s — jog stopped on timeout.")
finally:
robot.disconnect()
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Tool contact polling Synapse example")
parser.add_argument("--ip", type=str, required=True, help="UR robot IP address")
args = parser.parse_args()
main(ip=args.ip)The Explanation of the Code
is_tool_in_contact queries the robot controller for contact detection along the specified direction vector. direction is a 6-element vector [x, y, z, rx, ry, rz] in the robot base frame; the first three elements define the Cartesian direction to monitor. A value of True means the controller detected a contact force exceeding its internal threshold along the given direction. Typically used inside a move loop to detect when the tool has touched a surface.
How to Tune the Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
direction | list[float] | Yes | 6-element Cartesian direction vector [x, y, z, rx, ry, rz] in the base frame. |
Return Value
| Type | Description |
|---|---|
bool | True if contact is detected, False otherwise. |
Where to Use the Skill
- Detecting surface contact during a probing or insertion move.
- Confirming part presence in a gripper.
When Not to Use the Skill
- Use Move until Contact to command motion that automatically stops on contact; use
is_tool_in_contactonly for a one-shot check.

