ur-analytic-ik


Nameur-analytic-ik JSON
Version 0.0.7 PyPI version JSON
download
home_pageNone
SummaryC++ implementation with Python bindings of analytic forward and inverse kinematics for the Universal Robots.
upload_time2024-12-09 15:55:45
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseNone
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"
}
        
Elapsed time: 0.44938s