Skip to main content

UR Analytic IK

C++ implementation with Python bindings of analytic forward and inverse kinematics for the Universal Robots based on Alternative Inverse Kinematic Solution of the UR5 Robotic Arm.

This project is still very experimental, the API will likely still change.

The main advantages of using analytic IK:

  • extremely fast. FK calls from python take +- 4 µs, IK calls +- 18 µs.
  • finds all solutions at once, allowing you to select the most convenient one.
  • no need to provide initial guess, as opposed to numerical IK solutions.

Warning: this repo uses the default DH-parameters for the UR robots. But every robot is slightly different and is factory-calibrated to provide very accurate DH parameters, which are also used by the robot controlbox. From a few tests we have run, using the default DH-parameters typically results in 1-2mm differences in the FK for a given joint configuration. See here for details. If you need very high precision, you might want to use your robot's DH-parameters for FK/IK.

Installation

pre-built wheels are availabe on PyPI and can be installed with pip:

pip install ur_analytic_ik

To install from source, see the Developer section.

Usage

Afterwards, you should be able to issue the FK and IK functions like this:

import numpy as np
from ur_analytic_ik import ur5e

eef_pose = np.identity(4)
X = np.array([-1.0, 0.0, 0.0])
Y = np.array([0.0, 1.0, 0.0])
Z = np.array([0.0, 0.0, -1.0])
top_down_orientation = np.column_stack([X, Y, Z])
translation = np.array([-0.2, -0.2, 0.2])

eef_pose[:3, :3] = top_down_orientation
eef_pose[:3, 3] = translation

solutions = ur5e.inverse_kinematics(eef_pose)

More examples:

import numpy as np
from ur_analytic_ik import ur3e

joints = np.zeros(6)
eef_pose = np.identity(4)
eef_pose[2, 3] = 0.4
tcp_transform = np.identity(4)
tcp_transform[2, 3] = 0.1

ur3e.forward_kinematics(0, 0, 0, 0, 0, 0)
ur3e.forward_kinematics(*joints)
tcp_pose = ur3e.forward_kinematics_with_tcp(*joints, tcp_transform)

joint_solutions = ur3e.inverse_kinematics(eef_pose)
joint_solutions = ur3e.inverse_kinematics_closest(eef_pose, *joints)
joint_solutions = ur3e.inverse_kinematics_with_tcp(eef_pose, tcp_transform)
joint_solutions = ur3e.inverse_kinematics_closest_with_tcp(eef_pose, tcp_transform, *joints)

Development

This codebase uses nanobind to provide python bindings for the FK/IK functions.

building

python package building

This is the easiest option. It leverages scikit-build to create a python package and build the bindings. This flow is based on https://github.com/wjakob/nanobind_example

  • Create a conda environment for the project: conda env create -f environment.yaml
  • to create the python package, including the bindings: pip install . (this uses scikit-build to build the C++ from the top-level CMakelist.txt)
  • you can now import the library in python.

C++ building

if you want to build the C++ code without building the bindings or creating a python package:

  • make sure you have a C++ compiler available.
  • make sure you have the Eigen package available, if not run apt install libeigen3-dev.

Some linux users have eigen installed at /usr/include/eigen3 instead of /usr/include/Eigen. Symlink it:

sudo ln -sf /usr/include/eigen3/Eigen /usr/include/Eigen
sudo ln -sf /usr/include/eigen3/unsupported /usr/include/unsupported
  • run cmake -S . -B & cmake --build build from the src/ dir.
  • execute ./build/main

testing

run pytest -v .

Tests are also automatically executed in github for each commit.

Wheels are built automatically for all PRs, you can check them on test PyPI.

Releasing

  • bump the version in the pyproject.toml file. We use semantic versioning. Use pre-releases if you want to test changes.
  • create a new tag, corresponding to the version: git tag vX.Y.Z-...
  • push the tag git push --tag, this will already trigger a build of the wheels on test PyPI
  • once you have verified the wheels work and are built properly, create a new release with the same name as the semantic version for the tag on github. This will trigger an upload to PyPI.

Welcome Improvements

Python API

Adding an IK function that returns the closest solution and accepts a TCP transform.

Reducing the amount of separate IK functions, e.g. replacing:

ur3e.inverse_kinematics_with_tcp(eef_pose)
# with
ur3e.inverse_kinematics(eef_pose, tcp=tcp_transform)

The same holds for functions ending with _closest().

Performance

Currently IK runs at about 10 μs / EEF pose on my laptop. However, before I implemented the filtering of the solutions, it was closer to 3 μs. Part of this is because I adapted the bindings in ur_analytic_ik_ext.cpp to return vectors with the solutions.

Code Quality

  • Adding more technical documentation.
  • ur_analytic_ik_ext.cpp should be made much more readable.
  • Reducing some duplication e.g. when defining the IK/FK functions and bindings for the different robots.

Metadata

Release files for ur-analytic-ik 0.1.0.post3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ur-analytic-ik 0.1.0.post3
File Size Uploaded Provenance Actions
ur_analytic_ik-0.1.0.post3.tar.gz 34.0 kB With provenance Details for ur_analytic_ik-0.1.0.post3.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for ur-analytic-ik 0.1.0.post3
File Actions
ur_analytic_ik-0.1.0.post3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl PyPy 3.9 PyPy 3.9 7.3 Linux glibc 2.17+ x86-64 Details for ur_analytic_ik-0.1.0.post3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
ur_analytic_ik-0.1.0.post3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.17+ x86-64 Details for ur_analytic_ik-0.1.0.post3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
ur_analytic_ik-0.1.0.post3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.17+ x86-64 Details for ur_analytic_ik-0.1.0.post3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
ur_analytic_ik-0.1.0.post3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.9 CPython 3.9 Linux glibc 2.17+ x86-64 Details for ur_analytic_ik-0.1.0.post3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Total release size: 106.6 MB

Release files / ur_analytic_ik-0.1.0.post3.tar.gz

Download URL ur_analytic_ik-0.1.0.post3.tar.gz
Size 34.0 kB
Tags Source
SHA-256 checksum
How to use checksums
fadaeead66b83523aa246622611d7a84b161a55f43cbb759d52abd03b568130e
BLAKE2b-256 checksum
How to use checksums
8cb42280220df0839c0c2552180c7637dd49b7e56289d0ec56cb6a8004e99262
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 5, 2026.

Transparency log

Release files / ur_analytic_ik-0.1.0.post3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL ur_analytic_ik-0.1.0.post3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 26.7 MB
Tags Linux glibc 2.17+ x86-64 PyPy 3.9 PyPy 3.9 7.3
SHA-256 checksum
How to use checksums
869dbb33a41d102b93df10dcd6ef463571fb61164c9e36bd1724c09a81e0d67a
BLAKE2b-256 checksum
How to use checksums
e85743cd1d1b894cb1b28c11a54953416ea0544ad6dd415baa8519d3c342b328
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 5, 2026.

Transparency log

Release files / ur_analytic_ik-0.1.0.post3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL ur_analytic_ik-0.1.0.post3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 26.6 MB
Tags CPython 3.11 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
22763ec5aea54947b7a519dd14d2b81516f66938c04682735b0e0ee8d29e29d0
BLAKE2b-256 checksum
How to use checksums
3af6e228fcfb8ca0a6486e0dfb7e6503ae23987d6006381e027c36607dbafddb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 5, 2026.

Transparency log

Release files / ur_analytic_ik-0.1.0.post3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL ur_analytic_ik-0.1.0.post3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 26.6 MB
Tags CPython 3.10 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
6377042e2ed227f389ebf43ee8af65b199832382b143d04a19b41157c1f49796
BLAKE2b-256 checksum
How to use checksums
19221043c1caf3e3c06678da43e55d8f4e401d60f5709011d92cef2d0d34f172
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 5, 2026.

Transparency log

Release files / ur_analytic_ik-0.1.0.post3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL ur_analytic_ik-0.1.0.post3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 26.6 MB
Tags CPython 3.9 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
d30d75eb3269fe7ddde040a3af83126dc171ba2f74e7166f8f3e887a39186849
BLAKE2b-256 checksum
How to use checksums
49104d24aecdcbb6e46e3216010233948b360e274539a2dc5f92dc9a9d9f111b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 5, 2026.

Transparency log

Security for ur-analytic-ik 0.1.0.post3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 5 files in this release have been uploaded with provenance metadata.

Select from 5 files

Attestation for ur_analytic_ik-0.1.0.post3.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 5, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page