Name | ur-analytic-ik JSON |
Version |
0.0.7
JSON |
| download |
home_page | None |
Summary | C++ implementation with Python bindings of analytic forward and inverse kinematics for the Universal Robots. |
upload_time | 2024-12-09 15:55:45 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.8 |
license | None |
keywords |
robotics
kinematics
universal-robots
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
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](https://link.springer.com/chapter/10.1007/978-3-030-90033-5_22).
> This project is still very experimental, the API will likely still change.
Installation
------------
> Don't forget to activate your venv or conda environment.
pre-built wheels are availabe on PyPI and can be installed with pip:
```bash
pip install ur_analytic_ik
```
Usage
-----
Afterwards, you should be able to issue the FK and IK functions like this:
```python
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:
```python
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)
```
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](https://test.pypi.org/project/ur-analytic-ik/)
- 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](https://pypi.org/project/ur-analytic-ik/).
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:
```python
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.
Raw data
{
"_id": null,
"home_page": null,
"name": "ur-analytic-ik",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "robotics, kinematics, universal-robots",
"author": null,
"author_email": "Victor-Louis De Gusseme <victorlouisdg@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/67/1f/bf7b47387e9e564aa30ea20f4204b835bc6d8bbb6414401df6068ff8b0c2/ur-analytic-ik-0.0.7.tar.gz",
"platform": null,
"description": "UR Analytic IK\n================\nC++ 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](https://link.springer.com/chapter/10.1007/978-3-030-90033-5_22).\n\n> This project is still very experimental, the API will likely still change.\n\nInstallation\n------------\n\n> Don't forget to activate your venv or conda environment.\n\npre-built wheels are availabe on PyPI and can be installed with pip:\n\n```bash\npip install ur_analytic_ik\n```\n\n\n\n\nUsage\n-----\nAfterwards, you should be able to issue the FK and IK functions like this:\n\n```python\nimport numpy as np\nfrom ur_analytic_ik import ur5e\n\neef_pose = np.identity(4)\nX = np.array([-1.0, 0.0, 0.0])\nY = np.array([0.0, 1.0, 0.0])\nZ = np.array([0.0, 0.0, -1.0])\ntop_down_orientation = np.column_stack([X, Y, Z])\ntranslation = np.array([-0.2, -0.2, 0.2])\n\neef_pose[:3, :3] = top_down_orientation\neef_pose[:3, 3] = translation\n\nsolutions = ur5e.inverse_kinematics(eef_pose)\n```\n\nMore examples:\n```python\nimport numpy as np\nfrom ur_analytic_ik import ur3e\n\njoints = np.zeros(6)\neef_pose = np.identity(4)\neef_pose[2, 3] = 0.4\ntcp_transform = np.identity(4)\ntcp_transform[2, 3] = 0.1\n\nur3e.forward_kinematics(0, 0, 0, 0, 0, 0)\nur3e.forward_kinematics(*joints)\ntcp_pose = ur3e.forward_kinematics_with_tcp(*joints, tcp_transform)\n\njoint_solutions = ur3e.inverse_kinematics(eef_pose)\njoint_solutions = ur3e.inverse_kinematics_closest(eef_pose, *joints)\njoint_solutions = ur3e.inverse_kinematics_with_tcp(eef_pose, tcp_transform)\n```\n\n\n\n\nDevelopment\n--------------------\n\nThis codebase uses [nanobind]() to provide python bindings for the FK/IK functions.\n\n## building\n**python package building** \n\nThis 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\n\n- Create a conda environment for the project: `conda env create -f environment.yaml` \n- to create the python package, including the bindings: `pip install .` (this uses scikit-build to build the C++ from the top-level CMakelist.txt)\n- you can now import the library in python.\n\n\n**C++ building**\n\nif you want to build the C++ code without building the bindings or creating a python package:\n\n- make sure you have a C++ compiler available.\n- make sure you have the [Eigen]() package available, if not run `apt install libeigen3-dev`.\n\nSome linux users have eigen installed at /usr/include/eigen3 instead of /usr/include/Eigen. Symlink it:\n```\nsudo ln -sf /usr/include/eigen3/Eigen /usr/include/Eigen\nsudo ln -sf /usr/include/eigen3/unsupported /usr/include/unsupported\n```\n- run `cmake -S . -B` & `cmake --build build` from the `src/` dir. \n- execute `./build/main`\n\n\n## testing\n\nrun `pytest -v .`\n\nTests are also automatically executed in github for each commit.\n\nWheels are built automatically for all PRs, you can check them on [test PyPI]().\n\n\n## Releasing\n\n- bump the version in the `pyproject.toml` file. We use [semantic versioning](). Use pre-releases if you want to test changes.\n- create a new tag, corresponding to the version: `git tag vX.Y.Z-...` \n- push the tag `git push --tag`, this will already trigger a build of the wheels on [test PyPI](https://test.pypi.org/project/ur-analytic-ik/)\n- 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](https://pypi.org/project/ur-analytic-ik/).\n\n\n\nWelcome Improvements\n--------------------\n\n## Python API\nAdding an IK function that returns the closest solution and accepts a TCP transform.\n\nReducing the amount of separate IK functions, e.g. replacing:\n```python\nur3e.inverse_kinematics_with_tcp(eef_pose)\n# with\nur3e.inverse_kinematics(eef_pose, tcp=tcp_transform)\n```\nThe same holds for functions ending with `_closest()`.\n\n### Performance\nCurrently IK runs at about 10 \u03bcs / EEF pose on my laptop.\nHowever, before I implemented the filtering of the solutions, it was closer to 3 \u03bcs.\nPart of this is because I adapted the bindings in `ur_analytic_ik_ext.cpp` to return vectors with the solutions.\n\n### Code Quality\n* Adding more technical documentation.\n* `ur_analytic_ik_ext.cpp` should be made much more readable.\n* Reducing some duplication e.g. when defining the IK/FK functions and bindings for the different robots.\n",
"bugtrack_url": null,
"license": null,
"summary": "C++ implementation with Python bindings of analytic forward and inverse kinematics for the Universal Robots.",
"version": "0.0.7",
"project_urls": {
"Homepage": "https://github.com/Victorlouisdg/ur-analytic-ik",
"Issues": "https://github.com/Victorlouisdg/ur-analytic-ik/issues"
},
"split_keywords": [
"robotics",
" kinematics",
" universal-robots"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "01929d2e577513b7089c9733a0de07dd9cdacec4a5b12ad7d44b0d9586ee1f95",
"md5": "2a03e74983d6574451eeab5ae641ce9c",
"sha256": "a8e655d44ba978614704eeec84873bfdda2917b0e235e0de2101b433056b57e8"
},
"downloads": -1,
"filename": "ur_analytic_ik-0.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "2a03e74983d6574451eeab5ae641ce9c",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": ">=3.8",
"size": 25969583,
"upload_time": "2024-12-09T15:55:17",
"upload_time_iso_8601": "2024-12-09T15:55:17.496509Z",
"url": "https://files.pythonhosted.org/packages/01/92/9d2e577513b7089c9733a0de07dd9cdacec4a5b12ad7d44b0d9586ee1f95/ur_analytic_ik-0.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "15b2792bb93d5c4ee023ef9822ad30d7f04e6a836985a7c102f9ef46701828cf",
"md5": "0ae7ee39cf32cb7a3cc5ab9a1a2a2894",
"sha256": "bd8f5629f2ce30d04c17867d32ad0224dd7e424dcc1636c222cadc0eab0767a9"
},
"downloads": -1,
"filename": "ur_analytic_ik-0.0.7-cp310-cp310-musllinux_1_1_x86_64.whl",
"has_sig": false,
"md5_digest": "0ae7ee39cf32cb7a3cc5ab9a1a2a2894",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": ">=3.8",
"size": 26295850,
"upload_time": "2024-12-09T15:55:21",
"upload_time_iso_8601": "2024-12-09T15:55:21.250689Z",
"url": "https://files.pythonhosted.org/packages/15/b2/792bb93d5c4ee023ef9822ad30d7f04e6a836985a7c102f9ef46701828cf/ur_analytic_ik-0.0.7-cp310-cp310-musllinux_1_1_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "ecd734d511203eef0ff1ad6cfa9f6da1724934e88cc3ce6c49abc14181c3773e",
"md5": "9478a4f3dafba673f33d511ea1607048",
"sha256": "059b15b1ddeb403b866b4a7d7f540705027a5859fd05a79c7cf17a6897bd9c3f"
},
"downloads": -1,
"filename": "ur_analytic_ik-0.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "9478a4f3dafba673f33d511ea1607048",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.8",
"size": 25969497,
"upload_time": "2024-12-09T15:55:24",
"upload_time_iso_8601": "2024-12-09T15:55:24.798326Z",
"url": "https://files.pythonhosted.org/packages/ec/d7/34d511203eef0ff1ad6cfa9f6da1724934e88cc3ce6c49abc14181c3773e/ur_analytic_ik-0.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "e9c7170e555c9efd9790b8acfeb8f2579c58a00a77574853ef8cda9875b43ace",
"md5": "1eb1625f8a8ed44f6cd4bc5a3a4fefa7",
"sha256": "34b25c773389518b542cab1223f7097a4437058eebd0bea8a1910e2376b602e4"
},
"downloads": -1,
"filename": "ur_analytic_ik-0.0.7-cp311-cp311-musllinux_1_1_x86_64.whl",
"has_sig": false,
"md5_digest": "1eb1625f8a8ed44f6cd4bc5a3a4fefa7",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.8",
"size": 26290174,
"upload_time": "2024-12-09T15:55:28",
"upload_time_iso_8601": "2024-12-09T15:55:28.170212Z",
"url": "https://files.pythonhosted.org/packages/e9/c7/170e555c9efd9790b8acfeb8f2579c58a00a77574853ef8cda9875b43ace/ur_analytic_ik-0.0.7-cp311-cp311-musllinux_1_1_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "a90beeab870965145fa5267131e173b743563400d5533b464f49dc0650ea7674",
"md5": "e8d6d235dc3ccd9d2ca16c082daea3af",
"sha256": "1d0fd6f45c26e59fc4215769d0baeb81f3e07a72fb064cb07823cd6c882bc1f7"
},
"downloads": -1,
"filename": "ur_analytic_ik-0.0.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "e8d6d235dc3ccd9d2ca16c082daea3af",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 25969342,
"upload_time": "2024-12-09T15:55:30",
"upload_time_iso_8601": "2024-12-09T15:55:30.964720Z",
"url": "https://files.pythonhosted.org/packages/a9/0b/eeab870965145fa5267131e173b743563400d5533b464f49dc0650ea7674/ur_analytic_ik-0.0.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "8cf728dadaee9e02b2a8f4631c89602bd6731c5245b4b04ba3beb1ab6b892297",
"md5": "26b7557ce773edd60f7b070410034008",
"sha256": "2447eaab279743a045b71ba3081e3acc1a9db4e15b7c2603da99859de5efdc0c"
},
"downloads": -1,
"filename": "ur_analytic_ik-0.0.7-cp38-cp38-musllinux_1_1_x86_64.whl",
"has_sig": false,
"md5_digest": "26b7557ce773edd60f7b070410034008",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 26293980,
"upload_time": "2024-12-09T15:55:33",
"upload_time_iso_8601": "2024-12-09T15:55:33.787983Z",
"url": "https://files.pythonhosted.org/packages/8c/f7/28dadaee9e02b2a8f4631c89602bd6731c5245b4b04ba3beb1ab6b892297/ur_analytic_ik-0.0.7-cp38-cp38-musllinux_1_1_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "1d8af90e92284696c6fcb4756573cfc4f7588fe526df481b0d8fe57cf626609a",
"md5": "962aa9dc905516d352b3214e52fd8841",
"sha256": "db1574c17440567e433bdd6be1acbd3bbf61d4b0ddf098a03705acdfd22b7eed"
},
"downloads": -1,
"filename": "ur_analytic_ik-0.0.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "962aa9dc905516d352b3214e52fd8841",
"packagetype": "bdist_wheel",
"python_version": "cp39",
"requires_python": ">=3.8",
"size": 25969584,
"upload_time": "2024-12-09T15:55:36",
"upload_time_iso_8601": "2024-12-09T15:55:36.578607Z",
"url": "https://files.pythonhosted.org/packages/1d/8a/f90e92284696c6fcb4756573cfc4f7588fe526df481b0d8fe57cf626609a/ur_analytic_ik-0.0.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "c657791d97a52446e1b26420119a689b4b7f60b5f0ac559301728087fecc8794",
"md5": "c648a9d8aa20e8eb2b385bbd426f52c2",
"sha256": "3f0f9032398cc6c2357b5c048edc2653062ca3bf5f2bb6bd3a32cb3b43009d31"
},
"downloads": -1,
"filename": "ur_analytic_ik-0.0.7-cp39-cp39-musllinux_1_1_x86_64.whl",
"has_sig": false,
"md5_digest": "c648a9d8aa20e8eb2b385bbd426f52c2",
"packagetype": "bdist_wheel",
"python_version": "cp39",
"requires_python": ">=3.8",
"size": 26295865,
"upload_time": "2024-12-09T15:55:40",
"upload_time_iso_8601": "2024-12-09T15:55:40.327538Z",
"url": "https://files.pythonhosted.org/packages/c6/57/791d97a52446e1b26420119a689b4b7f60b5f0ac559301728087fecc8794/ur_analytic_ik-0.0.7-cp39-cp39-musllinux_1_1_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "a16a0a00c82e10af2ccd8998d3700b0e066a0932db39c338978135748d79fcd1",
"md5": "b7673fd11e4bfed20f73268a6d108586",
"sha256": "5ba41779d1d688bfee7795478b7e610ed82380eec883761f8b0ce34f873d0ffd"
},
"downloads": -1,
"filename": "ur_analytic_ik-0.0.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "b7673fd11e4bfed20f73268a6d108586",
"packagetype": "bdist_wheel",
"python_version": "pp39",
"requires_python": ">=3.8",
"size": 25966148,
"upload_time": "2024-12-09T15:55:43",
"upload_time_iso_8601": "2024-12-09T15:55:43.184724Z",
"url": "https://files.pythonhosted.org/packages/a1/6a/0a00c82e10af2ccd8998d3700b0e066a0932db39c338978135748d79fcd1/ur_analytic_ik-0.0.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "671fbf7b47387e9e564aa30ea20f4204b835bc6d8bbb6414401df6068ff8b0c2",
"md5": "5d5ffd2de83e56af8b83a2c521e3064a",
"sha256": "a63dad0f6a369b2cc9de72b90492d20a3d1ad2a6fdd0ce660fd7d1f6f8eab37c"
},
"downloads": -1,
"filename": "ur-analytic-ik-0.0.7.tar.gz",
"has_sig": false,
"md5_digest": "5d5ffd2de83e56af8b83a2c521e3064a",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 23649,
"upload_time": "2024-12-09T15:55:45",
"upload_time_iso_8601": "2024-12-09T15:55:45.747876Z",
"url": "https://files.pythonhosted.org/packages/67/1f/bf7b47387e9e564aa30ea20f4204b835bc6d8bbb6414401df6068ff8b0c2/ur-analytic-ik-0.0.7.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-12-09 15:55:45",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Victorlouisdg",
"github_project": "ur-analytic-ik",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "ur-analytic-ik"
}