Skip to content

Set Cartesian Pose

SUMMARY

Set Cartesian Pose commands the robot's TCP to a target pose [x, y, z, rx, ry, rz] (meters + Euler XYZ degrees) along a straight Cartesian path.

UNITS

cartesian_pose is [x, y, z, rx, ry, rz] in meters and Euler XYZ degrees. speed in m/s, acceleration in m/s².

OFFLINE

To run set_cartesian_pose purely on the kinematic model and visualize the result in Rerun, follow the Synapse Quickstart - one offline example is shipped for every supported brand.

The Skill

python
robot.set_cartesian_pose(
    cartesian_pose=target_pose,
    speed=0.25,
    acceleration=0.25,
    asynchronous=False,
)

The Code

Safety first!

A real robot will faithfully do whatever you ask of it - so please take a moment to clear the workspace, keep an E-Stop within reach, and be ready to disconnect.

Operating real hardware is at your own risk.

python
"""
Move the TCP to a target Cartesian pose relative to its current pose.

Supports Universal Robots (UR), Epson, virtual, and Isaac Sim.

Usage:
    python set_cartesian_pose.py [--ip <ROBOT_IP>] [--prim_path <PRIM_PATH>]
"""

import argparse

from loguru import logger

from telekinesis.synapse.robots.manipulators import universal_robots


def main(ip: str | None, prim_path: str | None) -> None:
    """Move the TCP to a target Cartesian pose relative to its current pose."""

    #===================== Create Robot ==========================================
    robot = universal_robots.UniversalRobotsUR10E(name='UR10e')

    # ==================== Visualization (Optional) =============================
    # Live: subscribes to the robot's state topic and redraws as it moves.
    robot.visualize_rerun(live=True)

    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)  # Move to default pose in simulation

        #===================== Prepare Target ==========================================
        current_cartesian_pose = robot.get_cartesian_pose()
        target_cartesian_pose = current_cartesian_pose.copy()
        target_cartesian_pose[2] += 0.1  # Move 10 cm up in Z

        # ==================== Run Skill ============================================
        robot.set_cartesian_pose(
            cartesian_pose=target_cartesian_pose,
            speed=0.5,
            acceleration=0.5,
        )
        logger.info(f"Moved to target Cartesian pose: {target_cartesian_pose}")
    except (ConnectionError, OSError) as e:
        logger.error(f"Error occurred: {e}")
    finally:
        robot.disconnect()
        robot.shutdown()


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Move the TCP to a target Cartesian pose")
    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"')
    args = parser.parse_args()

    main(ip=args.ip, prim_path=args.prim_path)

Running the Example

bash
python set_cartesian_pose.py
bash
python set_cartesian_pose.py --prim_path /World/ur10e
bash
python set_cartesian_pose.py --ip 192.168.1.100

For all options:

bash
python set_cartesian_pose.py --help

Parameter Configuration

ParameterTypeDefaultDescription
cartesian_poselist[float] | np.ndarrayrequiredTarget pose [x, y, z, rx, ry, rz]. Position in meters; orientation as Euler XYZ in degrees.
speedfloat1.05TCP speed in m/s. Keep low (0.05-0.25) during contact tasks and near obstacles; increase only after validating the path.
accelerationfloat1.4TCP acceleration in m/s². Tune in tandem with speed.
asynchronousboolFalseIf True, the call returns immediately. Use Stop Cartesian Motion to interrupt the move before it completes.

Returns

TypeDescription
NoneBlocks until the move completes when asynchronous=False; returns immediately when asynchronous=True. Read robot.get_cartesian_pose() afterward to confirm the result.

Raises

ExceptionCondition
TypeErrorcartesian_pose, speed, acceleration, or asynchronous is not the expected type
ValueErrorcartesian_pose is not a 1D 6-element [x, y, z, rx, ry, rz] vector
RuntimeErrorThe hardware backend rejects or fails the move during execution - e.g. the pose is near a kinematic singularity or outside the reachable workspace

How to Tune the Parameters

speed and acceleration bound the TCP's linear Cartesian motion directly (m/s, m/s²), so they translate straightforwardly to how fast and hard the tool moves along the straight-line path. Keep both low (0.05-0.25 m/s) during contact tasks, near fixtures, or while validating a new path, then raise them once the trajectory has been confirmed clear. Use asynchronous=True when the move needs to be interruptible mid-trajectory with Stop Cartesian Motion - for example to react to a vision or force signal before the target pose is reached.

Where to Use the Skill

  • Pick-and-place - Drive the TCP to approach, grasp, and release poses defined in Cartesian space.
  • Assembly - Insert a part along a straight-line path in the task frame.
  • Tool positioning - Place a welding tip, camera, or sensor at a precise location in the workspace.
  • Relative offsets - Apply small corrections (e.g. from vision feedback) by offsetting the current TCP pose.

When Not to Use the Skill

  • You need to reach a specific joint configuration - use Set Joint Positions to command joint space directly.
  • The target pose is near a kinematic singularity - Cartesian motion through or near a singularity is erratic; replan the path to avoid it.
  • Collision avoidance along the straight-line path is required - Cartesian moves do not account for obstacles; plan the trajectory upstream before commanding motion.
  • You only know the target in joint space - use Forward Kinematics to convert joints to a pose first.