Skip to main content

OptIK

MIT Apache ci PyPI DOI

A fast inverse kinematics solver for arbitrary serial chains providing Rust, C++, and Python programming interfaces.

The implementation is similar to TRAC-IK [1] in that a nonlinear optimization problem is formulated and minimized. However, this work differs in a couple of ways:

  • The gradient of the objective function is computed analytically. This is an immediate performance improvement over finite difference approaches, because it requires only one evaluation of the forward kinematics per gradient evaluation.
  • Random restarting of the nonlinear solver is implemented in a work stealing parallel fashion, so that overall solve time is decreased thanks to the improved chance of finding a good seed.
  • Random number generator seeds are carefully controlled in a way that produces deterministic results. (Note that this is only true in single-threaded mode, for now.)
  • A parallel Newton's method solver is not included, because the performance of the full nonlinear problem is quite good on its own.

Benchmark 1

We compare to TRAC-IK (via tracikpy) by drawing a random valid joint configuration, mapping into Cartesian space with forward kinematics, and then asking each solver to generate an inverse kinematics solution using a random initial guess.

Note that this methodology differs from the original TRAC-IK benchmark which solves for configurations along a dense trajectory, meaning seeds are always relatively close. The benchmark shown below is more similar to a motion planning workload, in which samples are randomly drawn from a space with little knowledge of a nearby seed.

Timing is of a single inverse kinematics solve.

Additionally, we use the ik_benchmarking project (credit to PickNik Robotics) to compare against various solvers for the Franka Emika Panda robot using the MoveIt interfaces for each solver. OptIK is configured to return solutions with roughly equal tolerance to its closest competitor, TRAC-IK.

Timing is of a single inverse kinematics solve. Note the semi-log axes.

Setup

Python

python3 -m pip install optik-py

Or, to install a prerelease version:

  1. Download a recent .whl from GitHub Releases
  2. Run pip install optik-py<...>.whl (replace <...> with the actual filename)
  3. Test it: python -c 'import optik'

C++ (CMake)

Include OptIK in your CMake project using FetchContent:

include(FetchContent)
FetchContent_Declare(
  optik
  GIT_REPOSITORY https://github.com/kylc/optik
  GIT_TAG master
  SOURCE_SUBDIR "crates/optik-cpp")
FetchContent_MakeAvailable(optik)

target_link_libraries(mylib PRIVATE optik::optik)

Building Locally

git clone git@github.com:kylc/optik.git

# Build the Rust library
cargo build --release

# Build a Python wheel
pip wheel .

# Build the C++ example
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ../examples
cmake --build .

Application Notes

  • For workloads in which the distance between the solution and the seed are not important, you can use a high degree of parallelism to more quickly converge on a solution via parallel random restarting.

    • OptIK defaults to the number of CPU cores for parallel solving. From testing (on an Intel i7-12700k), it has been observed that setting the parallelism level to half the logical core count generally gives the best results.
  • For workloads such as Cartesian interpolation, it is important to find the solution closest to the seed to avoid joint-space discontinuities. While OptIK does not explicitly try to minimize this distance, the optimizer does generally converge to the nearest solution (subject to joint limits). Prefer using SolutionMode::Quality with parallelism to sample many solutions and choose the one nearest the seed.

  • For workloads in which determinism is important, consider using SolutionMode::Quality, settings a max_restarts value, and disabling the max_time. This ensures that the solution is not dependent on CPU processing speed or non-deterministic thread racing. Due to careful seeding of RNGs inside the solver, solutions should be fully deterministic. Alternatively, use SolutionMode::Speed and set the parallel threads to 1.

References

P. Beeson and B. Ames, “TRAC-IK: An open-source library for improved solving of generic inverse kinematics,” in 2015 IEEE-RAS 15th International Conference on Humanoid Robots (Humanoids), Seoul, South Korea: IEEE, Nov. 2015, pp. 928–935. doi: 10.1109/HUMANOIDS.2015.7363472.

J. Solà, J. Deray, and D. Atchuthan, “A micro Lie theory for state estimation in robotics.” arXiv, Dec. 08, 2021. Accessed: Jul. 24, 2023. [Online]. Available: http://arxiv.org/abs/1812.01537

Steven G. Johnson, The NLopt nonlinear-optimization package, http://github.com/stevengj/nlopt

  1. as of https://github.com/kylc/optik/commit/3f324560b1a6ca5cfba2671e0180dd457ea1a28e ↩

Metadata

Release files for optik-py 0.5.0

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

Source distribution (sdist)

Source distribution for optik-py 0.5.0
File Size Uploaded
optik_py-0.5.0.tar.gz 42.6 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for optik-py 0.5.0
File Interpreter ABI Platform
optik_py-0.5.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.8 abi3 Linux glibc 2.17+ x86-64 Details
optik_py-0.5.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.8 abi3 Linux glibc 2.17+ ARM64 Details
optik_py-0.5.0-cp38-abi3-macosx_10_12_universal2.whl CPython 3.8 abi3 macOS 10.12+ universal2 (ARM64, x86-64) Details

Total release size: 3.5 MB

Release files / optik_py-0.5.0.tar.gz

Download URL optik_py-0.5.0.tar.gz
Size 42.6 kB
Tags Source
SHA-256 checksum
How to use checksums
c30b16f9886689f492c3ca504fd14536eb9d181cb23b57f6d1ff37ee61b7737b
BLAKE2b-256 checksum
How to use checksums
91c1ed465eb0dc25117c1dc364db7b2a510e9734c6e7222c82ab367139fa8d00
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.9.4

Release files / optik_py-0.5.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL optik_py-0.5.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 916.3 kB
Tags CPython 3.8 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
2b938bcfea1a2e8193dcbad4cd34a13af0c0bee6f5d3fd2195fddc7fdb1b117c
BLAKE2b-256 checksum
How to use checksums
aeadff0a8cca6543b8a2b26af63c87790da1d1bc52f28ad40ac7dc3af9fe2ae0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.9.4

Release files / optik_py-0.5.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL optik_py-0.5.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 838.1 kB
Tags CPython 3.8 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
f5746eec05768f7ec2189fa9b1f329234211f400b46756c1076c5ab06b56c0ed
BLAKE2b-256 checksum
How to use checksums
478a922eb40e62c896de0a552feb1523c1b4cf4ca1a3f3feb3641563fae260ba
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.9.4

Release files / optik_py-0.5.0-cp38-abi3-macosx_10_12_universal2.whl

Download URL optik_py-0.5.0-cp38-abi3-macosx_10_12_universal2.whl
Size 1.7 MB
Tags CPython 3.8 abi3 macOS 10.12+ universal2 (ARM64, x86-64)
SHA-256 checksum
How to use checksums
7ce367f6f2f37489a638c5e3b2d86bfb69e84a855068d527a022639b0f64a033
BLAKE2b-256 checksum
How to use checksums
081bcec56754bd4a8440c97b10f30f4de86126c6861fb59378a5c7364dacfce1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.9.4
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