Skip to main content

An optimizing IK solver based on the Lie group of rigid transforms SE(3)

Project description

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.

[^1]: as of https://github.com/kylc/optik/commit/3f324560b1a6ca5cfba2671e0180dd457ea1a28e

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

optik_py-0.5.0.tar.gz (42.6 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

optik_py-0.5.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (916.3 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ x86-64

optik_py-0.5.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (838.1 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ARM64

optik_py-0.5.0-cp38-abi3-macosx_10_12_universal2.whl (1.7 MB view details)

Uploaded CPython 3.8+macOS 10.12+ universal2 (ARM64, x86-64)

File details

Details for the file optik_py-0.5.0.tar.gz.

File metadata

  • Download URL: optik_py-0.5.0.tar.gz
  • Upload date:
  • Size: 42.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.9.4

File hashes

Hashes for optik_py-0.5.0.tar.gz
Algorithm Hash digest
SHA256 c30b16f9886689f492c3ca504fd14536eb9d181cb23b57f6d1ff37ee61b7737b
MD5 ec630588d29a6fa313cb0e33a822b916
BLAKE2b-256 91c1ed465eb0dc25117c1dc364db7b2a510e9734c6e7222c82ab367139fa8d00

See more details on using hashes here.

File details

Details for the file optik_py-0.5.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for optik_py-0.5.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 2b938bcfea1a2e8193dcbad4cd34a13af0c0bee6f5d3fd2195fddc7fdb1b117c
MD5 d6c59c0683ee0ae60adebfec895e273a
BLAKE2b-256 aeadff0a8cca6543b8a2b26af63c87790da1d1bc52f28ad40ac7dc3af9fe2ae0

See more details on using hashes here.

File details

Details for the file optik_py-0.5.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for optik_py-0.5.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 f5746eec05768f7ec2189fa9b1f329234211f400b46756c1076c5ab06b56c0ed
MD5 d56e156b22d1a56e75bd9e21d7dc59d3
BLAKE2b-256 478a922eb40e62c896de0a552feb1523c1b4cf4ca1a3f3feb3641563fae260ba

See more details on using hashes here.

File details

Details for the file optik_py-0.5.0-cp38-abi3-macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for optik_py-0.5.0-cp38-abi3-macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 7ce367f6f2f37489a638c5e3b2d86bfb69e84a855068d527a022639b0f64a033
MD5 51878d066f1cea5025a8b9f6ca281cbc
BLAKE2b-256 081bcec56754bd4a8440c97b10f30f4de86126c6861fb59378a5c7364dacfce1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page