Skip to content

Inverse Kinematics

SUMMARY

Inverse Kinematics computes joint configurations that achieve a requested end-effector pose.

This skill enables task-space targeting, robot pose solving, and execution planning for manipulation and industrial automation workflows.

The Skill

python
# target_pose can be a pose object from forward_kinematics, or a list [x, y, z, rx, ry, rz]
q = robot.inverse_kinematics(
    target_pose=target_pose,
    rot_type="rad",
    q_init=q_init,
    solver="clik",
)

The Code

Example 1: IK from a pose object with a seeded initialization

Compute the target pose via FK, add noise to the known configuration to create a realistic seed, then solve IK.

python
import numpy as np
from loguru import logger
from telekinesis.synapse.robots.manipulators import kuka

robot = kuka.KukaKR6R9002()

q = np.asarray([0, -np.pi / 2 - 0.1, -np.pi / 2, 0, np.pi / 2, 0])
target_pose = robot.forward_kinematics(q, rot_type="rad")

noise = np.random.normal(loc=0.0, scale=0.5, size=q.shape)
q_init = q + noise

q = robot.inverse_kinematics(
    target_pose=target_pose,
    rot_type="rad",
    q_init=q_init,
    solver="clik",
)
logger.success(f"IK solution: {q}")

Example 2: IK from a Cartesian list with a zero seed

Pass the target pose directly as [x, y, z, rx, ry, rz] and use a zero vector as the seed.

python
import numpy as np
from loguru import logger
from telekinesis.synapse.robots.manipulators import kuka

robot = kuka.KukaKR6R9002()

target_pose = [0.5, 0.2, 0.3, 3.14, 0.0, 0.0]
q_seed = np.zeros(6)

q = robot.inverse_kinematics(
    target_pose=target_pose,
    rot_type="rad",
    q_init=q_seed,
    solver="clik",
)
logger.success(f"IK solution: {q}")

Example 3: Multi-start IK without a seed

Use solver="multi_start_clik" with q_init=None to search from multiple random seeds automatically. More robust when the starting configuration is unknown.

python
import numpy as np
from loguru import logger
from telekinesis.synapse.robots.manipulators import kuka

robot = kuka.KukaKR6R9002()

target_pose = [0.5, 0.2, 0.3, 3.14, 0.0, 0.0]

q = robot.inverse_kinematics(
    target_pose=target_pose,
    rot_type="rad",
    q_init=None,
    solver="multi_start_clik",
)
logger.success(f"IK solution: {q}")

Example 4: Collision-free IK on a 7-DOF robot

For redundant robots such as the Kuka IIWA (7-DOF), pass collision_free_ik=True to filter solutions that collide with the environment.

python
import numpy as np
from loguru import logger
from telekinesis.synapse.robots.manipulators import kuka

robot = kuka.KukaLBRIIWA14R820()

target_pose = [0.5, 0.2, 0.3, 3.14, 0.0, 0.0]
q_seed = np.zeros(7)

q = robot.inverse_kinematics(
    target_pose=target_pose,
    rot_type="rad",
    q_init=q_seed,
    collision_free_ik=True,
)
logger.success(f"Collision-free IK solution: {q}")

The Explanation of the Code

inverse_kinematics solves for joint configurations q that place the end-effector at target_pose. The solver is iterative — it starts from q_init and converges toward a solution. The quality and existence of the solution depends on the solver chosen and how close q_init is to a valid solution.

Target pose formats. target_pose accepts either a pose object returned by forward_kinematics, or a plain list [x, y, z, rx, ry, rz] where position is in metres and rotation is expressed as an axis-angle vector in the unit given by rot_type.

Solver choice. "clik" (Closed-Loop Inverse Kinematics) is a single-start gradient-based solver — fast but sensitive to q_init. "multi_start_clik" runs "clik" from several random seeds and returns the best result — slower but more robust when no good seed is available.

Seed (q_init). When q_init is None, the solver initialises from a default or random configuration. Providing a seed close to the expected solution significantly improves convergence speed and reliability.

Redundant robots. For robots with more than 6 DOF (e.g. IIWA with 7 joints), there is a continuous family of solutions. collision_free_ik=True filters this set to configurations that do not collide with the environment model.

How to Tune the Parameters

ParameterTypeDefaultDescription
target_posepose object or list[float]Target end-effector pose. List format: [x, y, z, rx, ry, rz]. Position in metres; rotation as axis-angle in rot_type units.
rot_typestr"rad"Unit for joint angles in the returned solution and for interpreting rotation in target_pose. "rad" or "deg".
q_initnp.ndarray or NoneNoneInitial joint configuration seed. Length must equal robot DOF. Set to None to use solver default.
solverstr"clik"IK solver algorithm. "clik": single-start CLIK. "multi_start_clik": multi-start CLIK, more robust but slower.
collision_free_ikboolFalseFilter solutions to only those free of self-collision and environment collision. Primarily useful for redundant robots (7+ DOF).

Choosing a solver

Use "clik" when you have a reliable seed (e.g. the previous joint state). Use "multi_start_clik" when the seed is unavailable or the pose is far from the robot's neutral configuration.

WARNING

Poses near kinematic singularities or outside the reachable workspace will raise a RuntimeError. Wrap calls in a try/except block in production code.

Where to Use the Skill

  • Task-space motion planning — Convert a Cartesian target (from a grasp planner or vision pipeline) into joint commands
  • Pick-and-place — Compute joint configurations for approach, grasp, and release poses defined in Cartesian space
  • Trajectory generation — Solve IK at waypoints along a Cartesian path to build a joint-space trajectory
  • Reachability checks — Verify offline whether a set of task poses are kinematically feasible before deployment

When Not to Use the Skill

Do not use Inverse Kinematics when:

  • You already have a joint configuration and need the Cartesian pose — use Forward Kinematics instead
  • The target pose is near a kinematic singularity — IK solutions become unstable; apply replanning or singularity avoidance upstream
  • Low-latency real-time joint commands are required — pre-compute IK solutions offline and look them up at runtime instead