From 806a744880211ce6f95a3e1b08c538779b678a71 Mon Sep 17 00:00:00 2001 From: ZdenekM Date: Mon, 8 Dec 2025 14:36:54 +0100 Subject: [PATCH 1/3] chore: removed some unmaintained packages --- .github/workflows/compose.yaml | 3 - .github/workflows/pants.yaml | 2 +- 3rdparty/constraints.txt | 409 ++---- 3rdparty/mypy-requirements.txt | 3 +- 3rdparty/mypy_lockfile.txt | 49 +- 3rdparty/pytest_lockfile.txt | 10 +- 3rdparty/requirements.txt | 7 +- compose-files/fanuc-demo/README.md | 26 - compose-files/fanuc-demo/calibration.yaml | 28 - compose-files/fanuc-demo/docker-compose.yml | 152 -- compose-files/fanuc-demo/nginx.conf | 16 - mypy.ini | 5 - src/docker/arcor2_3d_mouse/BUILD | 1 - src/docker/arcor2_3d_mouse/Dockerfile | 32 - src/docker/arcor2_fanuc/BUILD | 1 - src/docker/arcor2_fanuc/Dockerfile | 22 - .../arcor2_fanuc_upload_object_types/BUILD | 3 - .../Dockerfile | 13 - src/python/arcor2_3d_mouse/BUILD | 5 - src/python/arcor2_3d_mouse/CHANGELOG.md | 9 - src/python/arcor2_3d_mouse/README.md | 32 - src/python/arcor2_3d_mouse/VERSION | 1 - src/python/arcor2_3d_mouse/__init__.py | 5 - .../arcor2_3d_mouse/mouse_controller.py | 192 --- src/python/arcor2_3d_mouse/mouse_program.py | 1299 ----------------- src/python/arcor2_3d_mouse/py.typed | 0 src/python/arcor2_3d_mouse/scripts/BUILD | 8 - .../arcor2_3d_mouse/scripts/__init__.py | 0 .../arcor2_3d_mouse/scripts/mouse_launcher.py | 15 - src/python/arcor2_calibration/quaternions.py | 2 +- src/python/arcor2_fanuc/BUILD | 5 - src/python/arcor2_fanuc/CHANGELOG.md | 34 - src/python/arcor2_fanuc/README.md | 15 - src/python/arcor2_fanuc/VERSION | 1 - src/python/arcor2_fanuc/__init__.py | 13 - src/python/arcor2_fanuc/data/BUILD | 0 src/python/arcor2_fanuc/data/urdf/BUILD | 10 - .../data/urdf/fanuc_lrmate200id7l.urdf | 202 --- .../lrmate200id/collision/base_link.stl | 3 - .../meshes/lrmate200id/collision/link_1.stl | 3 - .../meshes/lrmate200id/collision/link_2.stl | 3 - .../meshes/lrmate200id/collision/link_3.stl | 3 - .../meshes/lrmate200id/collision/link_4.stl | 3 - .../meshes/lrmate200id/collision/link_5.stl | 3 - .../meshes/lrmate200id/collision/link_6.stl | 3 - .../meshes/lrmate200id/visual/base_link.stl | 3 - .../meshes/lrmate200id/visual/link_1.stl | 3 - .../meshes/lrmate200id/visual/link_2.stl | 3 - .../meshes/lrmate200id/visual/link_3.stl | 3 - .../meshes/lrmate200id/visual/link_4.stl | 3 - .../meshes/lrmate200id/visual/link_5.stl | 3 - .../meshes/lrmate200id/visual/link_6.stl | 3 - .../meshes/lrmate200id7l/collision/link_2.stl | 3 - .../meshes/lrmate200id7l/collision/link_4.stl | 3 - .../meshes/lrmate200id7l/visual/link_2.stl | 3 - .../meshes/lrmate200id7l/visual/link_4.stl | 3 - src/python/arcor2_fanuc/exceptions.py | 21 - src/python/arcor2_fanuc/object_types/BUILD | 1 - .../arcor2_fanuc/object_types/__init__.py | 0 .../arcor2_fanuc/object_types/fake_fanuc.py | 52 - src/python/arcor2_fanuc/object_types/fanuc.py | 181 --- .../object_types/fanuc_lrmate200id7l.py | 6 - src/python/arcor2_fanuc/py.typed | 0 src/python/arcor2_fanuc/scripts/BUILD | 4 - src/python/arcor2_fanuc/scripts/__init__.py | 0 src/python/arcor2_fanuc/scripts/fanuc.py | 582 -------- .../arcor2_fanuc/scripts/upload_objects.py | 15 - src/python/arcor2_fanuc/tests/BUILD | 5 - src/python/arcor2_fanuc/tests/__init__.py | 0 src/python/arcor2_fanuc/tests/test_fanuc.py | 8 - 70 files changed, 102 insertions(+), 3457 deletions(-) delete mode 100644 compose-files/fanuc-demo/README.md delete mode 100644 compose-files/fanuc-demo/calibration.yaml delete mode 100644 compose-files/fanuc-demo/docker-compose.yml delete mode 100644 compose-files/fanuc-demo/nginx.conf delete mode 100644 src/docker/arcor2_3d_mouse/BUILD delete mode 100644 src/docker/arcor2_3d_mouse/Dockerfile delete mode 100644 src/docker/arcor2_fanuc/BUILD delete mode 100644 src/docker/arcor2_fanuc/Dockerfile delete mode 100644 src/docker/arcor2_fanuc_upload_object_types/BUILD delete mode 100644 src/docker/arcor2_fanuc_upload_object_types/Dockerfile delete mode 100644 src/python/arcor2_3d_mouse/BUILD delete mode 100644 src/python/arcor2_3d_mouse/CHANGELOG.md delete mode 100644 src/python/arcor2_3d_mouse/README.md delete mode 100644 src/python/arcor2_3d_mouse/VERSION delete mode 100644 src/python/arcor2_3d_mouse/__init__.py delete mode 100644 src/python/arcor2_3d_mouse/mouse_controller.py delete mode 100644 src/python/arcor2_3d_mouse/mouse_program.py delete mode 100644 src/python/arcor2_3d_mouse/py.typed delete mode 100644 src/python/arcor2_3d_mouse/scripts/BUILD delete mode 100644 src/python/arcor2_3d_mouse/scripts/__init__.py delete mode 100644 src/python/arcor2_3d_mouse/scripts/mouse_launcher.py delete mode 100644 src/python/arcor2_fanuc/BUILD delete mode 100644 src/python/arcor2_fanuc/CHANGELOG.md delete mode 100644 src/python/arcor2_fanuc/README.md delete mode 100644 src/python/arcor2_fanuc/VERSION delete mode 100644 src/python/arcor2_fanuc/__init__.py delete mode 100644 src/python/arcor2_fanuc/data/BUILD delete mode 100644 src/python/arcor2_fanuc/data/urdf/BUILD delete mode 100644 src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id7l.urdf delete mode 100644 src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/base_link.stl delete mode 100644 src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_1.stl delete mode 100644 src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_2.stl delete mode 100644 src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_3.stl delete mode 100644 src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_4.stl delete mode 100644 src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_5.stl delete mode 100644 src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_6.stl delete mode 100644 src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/base_link.stl delete mode 100644 src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_1.stl delete mode 100644 src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_2.stl delete mode 100644 src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_3.stl delete mode 100644 src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_4.stl delete mode 100644 src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_5.stl delete mode 100644 src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_6.stl delete mode 100644 src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id7l/collision/link_2.stl delete mode 100644 src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id7l/collision/link_4.stl delete mode 100644 src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id7l/visual/link_2.stl delete mode 100644 src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id7l/visual/link_4.stl delete mode 100644 src/python/arcor2_fanuc/exceptions.py delete mode 100644 src/python/arcor2_fanuc/object_types/BUILD delete mode 100644 src/python/arcor2_fanuc/object_types/__init__.py delete mode 100644 src/python/arcor2_fanuc/object_types/fake_fanuc.py delete mode 100644 src/python/arcor2_fanuc/object_types/fanuc.py delete mode 100644 src/python/arcor2_fanuc/object_types/fanuc_lrmate200id7l.py delete mode 100644 src/python/arcor2_fanuc/py.typed delete mode 100644 src/python/arcor2_fanuc/scripts/BUILD delete mode 100644 src/python/arcor2_fanuc/scripts/__init__.py delete mode 100644 src/python/arcor2_fanuc/scripts/fanuc.py delete mode 100644 src/python/arcor2_fanuc/scripts/upload_objects.py delete mode 100644 src/python/arcor2_fanuc/tests/BUILD delete mode 100644 src/python/arcor2_fanuc/tests/__init__.py delete mode 100644 src/python/arcor2_fanuc/tests/test_fanuc.py diff --git a/.github/workflows/compose.yaml b/.github/workflows/compose.yaml index 8df9a64ae..eedfb84bc 100644 --- a/.github/workflows/compose.yaml +++ b/.github/workflows/compose.yaml @@ -16,9 +16,6 @@ jobs: - name: Check syntax of fit-demo2 run: | docker compose -f compose-files/fit-demo/docker-compose.2.yml config - - name: Check syntax of fanuc-demo - run: | - docker compose -f compose-files/fanuc-demo/docker-compose.yml config - name: Check syntax of ur-demo (sim) run: | docker compose -f compose-files/ur-demo/docker-compose.yml -f compose-files/ur-demo/docker-compose.sim.yml config diff --git a/.github/workflows/pants.yaml b/.github/workflows/pants.yaml index c7a7d64e9..7214c7867 100644 --- a/.github/workflows/pants.yaml +++ b/.github/workflows/pants.yaml @@ -74,7 +74,7 @@ jobs: pants --changed-since=origin/master --changed-dependents=transitive test - name: Build Docker images run: | # filter out non-essential docker images (there was a problem with full storage on github) - pants filter --target-type=docker_image --changed-since=origin/master --changed-dependents=transitive | grep -v arcor2_3d_mouse | grep -v arcor2_fanuc arcor2_fanuc_upload_object_types | xargs pants package + pants filter --target-type=docker_image --changed-since=origin/master --changed-dependents=transitive | xargs pants package - name: Build Python packages run: | pants filter --target-type=python_distribution :: | xargs pants package diff --git a/3rdparty/constraints.txt b/3rdparty/constraints.txt index 09f749735..59c85dfb6 100644 --- a/3rdparty/constraints.txt +++ b/3rdparty/constraints.txt @@ -22,18 +22,14 @@ // "ciso8601~=2.3.3", // "colorlog~=6.10.1", // "dataclasses-jsonschema[apispec,fast-dateparsing,fast-validation]~=2.16.0", -// "easyhid~=0.0.10", -// "fanucpy~=0.1.14", // "fastuuid~=0.14.0", // "flask-swagger-ui~=5.21.0", // "flask_cors~=6.0.1", -// "gTTS~=2.5.4", // "gr-urchin~=0.0.29", -// "hidapi~=0.14.0.post4", // "lark==1.3.1", // "lru-dict~=1.4.1", // "numpy-quaternion[numba,scipy]~=2024.0.13", -// "numpy<2,>=1.26.4", +// "numpy~=2.3.5", // "open3d==0.19.0", // "openapi-spec-validator~=0.7.2", // "opencv-contrib-python~=4.10.0.84", @@ -45,7 +41,6 @@ // "pyhumps==3.8.0", // "pymodbus~=3.7.4", // "pyserial~=3.5", -// "pyspacemouse~=1.1.4", // "pytest-asyncio~=1.3.0", // "pytest-randomly~=4.0.1", // "pytest-repeat~=0.9.4", @@ -317,66 +312,6 @@ "requires_python": ">=3.7", "version": "2025.11.12" }, - { - "artifacts": [ - { - "algorithm": "sha256", - "hash": "2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", - "url": "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl" - }, - { - "algorithm": "sha256", - "hash": "3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", - "url": "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl" - }, - { - "algorithm": "sha256", - "hash": "81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", - "url": "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl" - }, - { - "algorithm": "sha256", - "hash": "3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", - "url": "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl" - }, - { - "algorithm": "sha256", - "hash": "1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", - "url": "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl" - }, - { - "algorithm": "sha256", - "hash": "b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", - "url": "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl" - }, - { - "algorithm": "sha256", - "hash": "8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", - "url": "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl" - }, - { - "algorithm": "sha256", - "hash": "6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", - "url": "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl" - }, - { - "algorithm": "sha256", - "hash": "44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", - "url": "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz" - }, - { - "algorithm": "sha256", - "hash": "21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", - "url": "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl" - } - ], - "project_name": "cffi", - "requires_dists": [ - "pycparser; implementation_name != \"PyPy\"" - ], - "requires_python": ">=3.9", - "version": "2.0.0" - }, { "artifacts": [ { @@ -512,22 +447,21 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", - "url": "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl" + "hash": "981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", + "url": "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", - "url": "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz" + "hash": "12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", + "url": "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz" } ], "project_name": "click", "requires_dists": [ - "colorama; platform_system == \"Windows\"", - "importlib-metadata; python_version < \"3.8\"" + "colorama; platform_system == \"Windows\"" ], - "requires_python": ">=3.7", - "version": "8.1.8" + "requires_python": ">=3.10", + "version": "8.3.1" }, { "artifacts": [ @@ -894,21 +828,6 @@ "requires_python": ">=3.8", "version": "5.2.1" }, - { - "artifacts": [ - { - "algorithm": "sha256", - "hash": "95a05dcc0288832760745b83445e4a7c7ba64587baff1380b63e984d9b66c609", - "url": "https://files.pythonhosted.org/packages/52/ec/8bafbd3cd967acda78a108793fe0b7a6afb0678e7a2496a83d8c6fb065f2/easyhid-0.0.10.tar.gz" - } - ], - "project_name": "easyhid", - "requires_dists": [ - "cffi" - ], - "requires_python": null, - "version": "0.0.10" - }, { "artifacts": [ { @@ -935,27 +854,6 @@ "requires_python": ">=3.8", "version": "2.2.1" }, - { - "artifacts": [ - { - "algorithm": "sha256", - "hash": "fcc51cee9e2c447dc122fb9cd07d6125d8408fa0eb38ca79a19474e8b6f90a8d", - "url": "https://files.pythonhosted.org/packages/b0/45/a60b9fcdff99787cf13301b1b42090ce680cb89223ae840282003509914c/fanucpy-0.1.14-py3-none-any.whl" - }, - { - "algorithm": "sha256", - "hash": "b77fcbcc2924f9c6ee0d6d5b38641b9b0adc28e3fddbdb6e836969c85a88ed42", - "url": "https://files.pythonhosted.org/packages/f1/bf/512771502552155f128610329d8c9d21b0cd0480b8b0002af6bd2f796463/fanucpy-0.1.14.tar.gz" - } - ], - "project_name": "fanucpy", - "requires_dists": [ - "numpy<2.0.0,>=1.24.0", - "scipy<2.0.0,>=1.10.0" - ], - "requires_python": ">=3.8", - "version": "0.1.14" - }, { "artifacts": [ { @@ -1261,90 +1159,6 @@ "requires_python": null, "version": "0.0.29" }, - { - "artifacts": [ - { - "algorithm": "sha256", - "hash": "5dd579377f9f5546893bc26315ab1f846933dc27a054764b168f141065ca8436", - "url": "https://files.pythonhosted.org/packages/e3/6c/8b8b1fdcaee7e268536f1bb00183a5894627726b54a9ddc6fc9909888447/gTTS-2.5.4-py3-none-any.whl" - }, - { - "algorithm": "sha256", - "hash": "f5737b585f6442f677dbe8773424fd50697c75bdf3e36443585e30a8d48c1884", - "url": "https://files.pythonhosted.org/packages/57/79/5ddb1dfcd663581d0d3fca34ccb1d8d841b47c22a24dc8dce416e3d87dfa/gtts-2.5.4.tar.gz" - } - ], - "project_name": "gtts", - "requires_dists": [ - "click<8.2,>=7.1", - "pytest-cov; extra == \"tests\"", - "pytest<8.4.0,>=7.1.3; extra == \"tests\"", - "requests<3,>=2.27", - "sphinx-autobuild; extra == \"docs\"", - "sphinx-click; extra == \"docs\"", - "sphinx-mdinclude; extra == \"docs\"", - "sphinx-rtd-theme; extra == \"docs\"", - "sphinx; extra == \"docs\"", - "testfixtures; extra == \"tests\"" - ], - "requires_python": ">=3.7", - "version": "2.5.4" - }, - { - "artifacts": [ - { - "algorithm": "sha256", - "hash": "707b1ebf5cb051b020e94b039e603351bf2e6620b48fc970228e0dd5d3a91fca", - "url": "https://files.pythonhosted.org/packages/01/e9/14e63f1a5ec0c2430b84695d28e994b2b63398544adb20d910f6dc41ac66/hidapi-0.14.0.post4-cp312-cp312-musllinux_1_2_x86_64.whl" - }, - { - "algorithm": "sha256", - "hash": "129d684c2760fafee9014ce63a58d8e2699cdf00cd1a11bb3d706d4715f5ff96", - "url": "https://files.pythonhosted.org/packages/1a/9a/9b7d5d5e2c003aed2fecdc348caff8d3b6a8ead0220da489ccb822d7e5ef/hidapi-0.14.0.post4-cp312-cp312-macosx_10_13_x86_64.whl" - }, - { - "algorithm": "sha256", - "hash": "10a01af155c51a8089fe44e627af2fbd323cfbef7bd55a86837d971aef6088b0", - "url": "https://files.pythonhosted.org/packages/37/7c/63316c8cba89cc039a952bb8805c3fb585e79f7fc8a5d27acaa6beb2fe81/hidapi-0.14.0.post4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" - }, - { - "algorithm": "sha256", - "hash": "48fce253e526d17b663fbf9989c71c7ef7653ced5f4be65f1437c313fb3dbdf6", - "url": "https://files.pythonhosted.org/packages/47/72/21ccaaca6ffb06f544afd16191425025d831c2a6d318635e9c8854070f2d/hidapi-0.14.0.post4.tar.gz" - }, - { - "algorithm": "sha256", - "hash": "6eaff1d120c47e1a121eada8dc85eac007d1ed81f3db7fc0da5b6ed17d8edefb", - "url": "https://files.pythonhosted.org/packages/8a/a8/bb222e3f096467d8e37c717000b9b0c6acee043c1145eaaeba4abfc8cffd/hidapi-0.14.0.post4-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl" - }, - { - "algorithm": "sha256", - "hash": "6270677da02e86b56b81afd5f6f313736b8315b493f3c8a431da285e3a3c5de9", - "url": "https://files.pythonhosted.org/packages/a8/da/88ebbd465dbaff04e9ef3bbdb4a6ca9d24a3458e4726878dbe26bb69236e/hidapi-0.14.0.post4-cp312-cp312-musllinux_1_2_aarch64.whl" - }, - { - "algorithm": "sha256", - "hash": "4f04de00e40db2efc0bcdd047c160274ba7ccd861100fd87c295dd63cb932f2f", - "url": "https://files.pythonhosted.org/packages/ad/e5/a919eb542a692cc27dc58b1997dd860cace0e4c64e38c8bf9236ff8b95b7/hidapi-0.14.0.post4-cp312-cp312-macosx_11_0_arm64.whl" - }, - { - "algorithm": "sha256", - "hash": "fedb9c3be6a2376de436d13fcb37a686a9b6bc988585bcc4f5ec61cad925e794", - "url": "https://files.pythonhosted.org/packages/ba/c8/52134f7d3e09fd4feb7756ccd872c55bfd1899ee81ceed4f8ad5ae39f457/hidapi-0.14.0.post4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" - }, - { - "algorithm": "sha256", - "hash": "da700db947562f8c0ac530215b74b5a27e4c669916ec99cfb5accd14ba08562c", - "url": "https://files.pythonhosted.org/packages/da/f0/ea437ed339c5f0b446983011000d8cad8c4f8a51ee39e837d16e101b66da/hidapi-0.14.0.post4-cp312-cp312-musllinux_1_2_i686.whl" - } - ], - "project_name": "hidapi", - "requires_dists": [ - "setuptools>=19.0" - ], - "requires_python": null, - "version": "0.14.0.post4" - }, { "artifacts": [ { @@ -1505,13 +1319,13 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "bce8ac85eb9521adc94e1845b4c03d88365fd6ac2f4908ec4ed1eb1b0a065f9f", - "url": "https://files.pythonhosted.org/packages/05/aa/62893d6a591d337aa59dcc4c6f6c842f1fe20cd72c8c5c1f980255243252/ipython-9.7.0-py3-none-any.whl" + "hash": "ebe6d1d58d7d988fbf23ff8ff6d8e1622cfdb194daf4b7b73b792c4ec3b85385", + "url": "https://files.pythonhosted.org/packages/f1/df/8ee1c5dd1e3308b5d5b2f2dfea323bb2f3827da8d654abb6642051199049/ipython-9.8.0-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "5f6de88c905a566c6a9d6c400a8fed54a638e1f7543d17aae2551133216b1e4e", - "url": "https://files.pythonhosted.org/packages/29/e6/48c74d54039241a456add616464ea28c6ebf782e4110d419411b83dae06f/ipython-9.7.0.tar.gz" + "hash": "8e4ce129a627eb9dd221c41b1d2cdaed4ef7c9da8c17c63f6f578fe231141f83", + "url": "https://files.pythonhosted.org/packages/12/51/a703c030f4928646d390b4971af4938a1b10c9dfce694f0d99a0bb073cb2/ipython-9.8.0.tar.gz" } ], "project_name": "ipython", @@ -1557,7 +1371,7 @@ "typing_extensions>=4.6; python_version < \"3.12\"" ], "requires_python": ">=3.11", - "version": "9.7.0" + "version": "9.8.0" }, { "artifacts": [ @@ -2429,44 +2243,54 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0", - "url": "https://files.pythonhosted.org/packages/76/8c/2ba3902e1a0fc1c74962ea9bb33a534bb05984ad7ff9515bf8d07527cadd/numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl" + "hash": "b46b4ec24f7293f23adcd2d146960559aaf8020213de8ad1909dba6c013bf89c", + "url": "https://files.pythonhosted.org/packages/d2/fa/dd48e225c46c819288148d9d060b047fd2a6fb1eb37eae25112ee4cb4453/numpy-2.3.5-cp312-cp312-musllinux_1_2_x86_64.whl" + }, + { + "algorithm": "sha256", + "hash": "74ae7b798248fe62021dbf3c914245ad45d1a6b0cb4a29ecb4b31d0bfbc4cc3e", + "url": "https://files.pythonhosted.org/packages/44/37/e669fe6cbb2b96c62f6bbedc6a81c0f3b7362f6a59230b23caa673a85721/numpy-2.3.5-cp312-cp312-macosx_10_13_x86_64.whl" + }, + { + "algorithm": "sha256", + "hash": "612a95a17655e213502f60cfb9bf9408efdc9eb1d5f50535cc6eb365d11b42b5", + "url": "https://files.pythonhosted.org/packages/5b/e1/1ee06e70eb2136797abe847d386e7c0e830b67ad1d43f364dd04fa50d338/numpy-2.3.5-cp312-cp312-macosx_14_0_arm64.whl" }, { "algorithm": "sha256", - "hash": "675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed", - "url": "https://files.pythonhosted.org/packages/0f/50/de23fde84e45f5c4fda2488c759b69990fd4512387a8632860f3ac9cd225/numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "3101e5177d114a593d79dd79658650fe28b5a0d8abeb8ce6f437c0e6df5be1a4", + "url": "https://files.pythonhosted.org/packages/6d/9c/1ca85fb86708724275103b81ec4cf1ac1d08f465368acfc8da7ab545bdae/numpy-2.3.5-cp312-cp312-macosx_14_0_x86_64.whl" }, { "algorithm": "sha256", - "hash": "ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a", - "url": "https://files.pythonhosted.org/packages/4c/0c/9c603826b6465e82591e05ca230dfc13376da512b25ccd0894709b054ed0/numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl" + "hash": "8b973c57ff8e184109db042c842423ff4f60446239bd585a5131cc47f06f789d", + "url": "https://files.pythonhosted.org/packages/74/78/fcd41e5a0ce4f3f7b003da85825acddae6d7ecb60cf25194741b036ca7d6/numpy-2.3.5-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl" }, { "algorithm": "sha256", - "hash": "2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010", - "url": "https://files.pythonhosted.org/packages/65/6e/09db70a523a96d25e115e71cc56a6f9031e7b8cd166c1ac8438307c14058/numpy-1.26.4.tar.gz" + "hash": "784db1dcdab56bf0517743e746dfb0f885fc68d948aba86eeec2cba234bdf1c0", + "url": "https://files.pythonhosted.org/packages/76/65/21b3bc86aac7b8f2862db1e808f1ea22b028e30a225a34a5ede9bf8678f2/numpy-2.3.5.tar.gz" }, { "algorithm": "sha256", - "hash": "03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b", - "url": "https://files.pythonhosted.org/packages/75/5b/ca6c8bd14007e5ca171c7c03102d17b4f4e0ceb53957e8c44343a9546dcc/numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl" + "hash": "51c1e14eb1e154ebd80e860722f9e6ed6ec89714ad2db2d3aa33c31d7c12179b", + "url": "https://files.pythonhosted.org/packages/a0/c5/5ad26fbfbe2012e190cc7d5003e4d874b88bb18861d0829edc140a713021/numpy-2.3.5-cp312-cp312-musllinux_1_2_aarch64.whl" }, { "algorithm": "sha256", - "hash": "9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b", - "url": "https://files.pythonhosted.org/packages/79/f8/97f10e6755e2a7d027ca783f63044d5b1bc1ae7acb12afe6a9b4286eac17/numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + "hash": "0d8163f43acde9a73c2a33605353a4f1bc4798745a8b1d73183b28e5b435ae28", + "url": "https://files.pythonhosted.org/packages/b6/23/2a1b231b8ff672b4c450dac27164a8b2ca7d9b7144f9c02d2396518352eb/numpy-2.3.5-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl" }, { "algorithm": "sha256", - "hash": "b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218", - "url": "https://files.pythonhosted.org/packages/95/12/8f2020a8e8b8383ac0177dc9570aad031a3beb12e38847f7129bacd96228/numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl" + "hash": "ee3888d9ff7c14604052b2ca5535a30216aa0a58e948cdd3eeb8d3415f638769", + "url": "https://files.pythonhosted.org/packages/c5/65/df0db6c097892c9380851ab9e44b52d4f7ba576b833996e0080181c0c439/numpy-2.3.5-cp312-cp312-macosx_11_0_arm64.whl" } ], "project_name": "numpy", "requires_dists": [], - "requires_python": ">=3.9", - "version": "1.26.4" + "requires_python": ">=3.11", + "version": "2.3.5" }, { "artifacts": [ @@ -2664,74 +2488,74 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "525021896afef44a68148f6ed8a8bf8375553d6066c7f48537657f64823565b9", - "url": "https://files.pythonhosted.org/packages/1b/48/78302d98423ed8780479a1e682b9aecb869e8404545d999d34fa486e573e/orjson-3.11.4-cp312-cp312-musllinux_1_2_x86_64.whl" + "hash": "ddbfdb5099b3e6ba6d6ea818f61997bb66de14b411357d24c4612cf1ebad08ca", + "url": "https://files.pythonhosted.org/packages/f9/d4/f9ebc57182705bb4bbe63f5bbe14af43722a2533135e1d2fb7affa0c355d/orjson-3.11.5-cp312-cp312-musllinux_1_2_x86_64.whl" }, { "algorithm": "sha256", - "hash": "ad355e8308493f527d41154e9053b86a5be892b3b359a5c6d5d95cda23601cb2", - "url": "https://files.pythonhosted.org/packages/00/d4/9aee9e54f1809cec8ed5abd9bc31e8a9631d19460e3b8470145d25140106/orjson-3.11.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl" + "hash": "82393ab47b4fe44ffd0a7659fa9cfaacc717eb617c93cde83795f14af5c2e9d5", + "url": "https://files.pythonhosted.org/packages/04/b8/333fdb27840f3bf04022d21b654a35f58e15407183aeb16f3b41aa053446/orjson-3.11.5.tar.gz" }, { "algorithm": "sha256", - "hash": "97eb5942c7395a171cbfecc4ef6701fc3c403e762194683772df4c54cfbb2210", - "url": "https://files.pythonhosted.org/packages/01/7e/62517dddcfce6d53a39543cd74d0dccfcbdf53967017c58af68822100272/orjson-3.11.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + "hash": "c74099c6b230d4261fdc3169d50efc09abf38ace1a42ea2f9994b1d79153d477", + "url": "https://files.pythonhosted.org/packages/46/bf/0993b5a056759ba65145effe3a79dd5a939d4a070eaa5da2ee3180fbb13f/orjson-3.11.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }, { "algorithm": "sha256", - "hash": "149d95d5e018bdd822e3f38c103b1a7c91f88d38a88aada5c4e9b3a73a244241", - "url": "https://files.pythonhosted.org/packages/18/ae/40516739f99ab4c7ec3aaa5cc242d341fcb03a45d89edeeaabc5f69cb2cf/orjson-3.11.4-cp312-cp312-musllinux_1_2_aarch64.whl" + "hash": "ed24250e55efbcb0b35bed7caaec8cedf858ab2f9f2201f17b8938c618c8ca6f", + "url": "https://files.pythonhosted.org/packages/52/8d/544e77d7a29d90cf4d9eecd0ae801c688e7f3d1adfa2ebae5e1e94d38ab9/orjson-3.11.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" }, { "algorithm": "sha256", - "hash": "e41fd3b3cac850eaae78232f37325ed7d7436e11c471246b87b2cd294ec94853", - "url": "https://files.pythonhosted.org/packages/1c/2c/2602392ddf2601d538ff11848b98621cd465d1a1ceb9db9e8043181f2f7b/orjson-3.11.4-cp312-cp312-macosx_15_0_arm64.whl" + "hash": "ff770589960a86eae279f5d8aa536196ebda8273a2a07db2a54e82b93bc86626", + "url": "https://files.pythonhosted.org/packages/64/67/574a7732bd9d9d79ac620c8790b4cfe0717a3d5a6eb2b539e6e8995e24a0/orjson-3.11.5-cp312-cp312-macosx_15_0_arm64.whl" }, { "algorithm": "sha256", - "hash": "600e0e9ca042878c7fdf189cf1b028fe2c1418cc9195f6cb9824eb6ed99cb938", - "url": "https://files.pythonhosted.org/packages/4e/47/bf85dcf95f7a3a12bf223394a4f849430acd82633848d52def09fa3f46ad/orjson-3.11.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + "hash": "e697d06ad57dd0c7a737771d470eedc18e68dfdefcdd3b7de7f33dfda5b6212e", + "url": "https://files.pythonhosted.org/packages/65/e8/83a6c95db3039e504eda60fc388f9faedbb4f6472f5aba7084e06552d9aa/orjson-3.11.5-cp312-cp312-musllinux_1_2_aarch64.whl" }, { "algorithm": "sha256", - "hash": "d4371de39319d05d3f482f372720b841c841b52f5385bd99c61ed69d55d9ab50", - "url": "https://files.pythonhosted.org/packages/63/51/6b556192a04595b93e277a9ff71cd0cc06c21a7df98bcce5963fa0f5e36f/orjson-3.11.4-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl" + "hash": "a66d7769e98a08a12a139049aac2f0ca3adae989817f8c43337455fbc7669b85", + "url": "https://files.pythonhosted.org/packages/6e/57/b9f5b5b6fbff9c26f77e785baf56ae8460ef74acdb3eae4931c25b8f5ba9/orjson-3.11.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl" }, { "algorithm": "sha256", - "hash": "624f3951181eb46fc47dea3d221554e98784c823e7069edb5dbd0dc826ac909b", - "url": "https://files.pythonhosted.org/packages/82/18/ff5734365623a8916e3a4037fcef1cd1782bfc14cf0992afe7940c5320bf/orjson-3.11.4-cp312-cp312-musllinux_1_2_armv7l.whl" + "hash": "e08ca8a6c851e95aaecc32bc44a5aa75d0ad26af8cdac7c77e4ed93acf3d5b69", + "url": "https://files.pythonhosted.org/packages/b9/b4/24fdc024abfce31c2f6812973b0a693688037ece5dc64b7a60c1ce69e2f2/orjson-3.11.5-cp312-cp312-musllinux_1_2_armv7l.whl" }, { "algorithm": "sha256", - "hash": "7bbf9b333f1568ef5da42bc96e18bf30fd7f8d54e9ae066d711056add508e415", - "url": "https://files.pythonhosted.org/packages/b4/4d/a0cb31007f3ab6f1fd2a1b17057c7c349bc2baf8921a85c0180cc7be8011/orjson-3.11.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl" + "hash": "b29d36b60e606df01959c4b982729c8845c69d1963f88686608be9ced96dbfaa", + "url": "https://files.pythonhosted.org/packages/cb/aa/7c4818c8d7d324da220f4f1af55c343956003aa4d1ce1857bdc1d396ba69/orjson-3.11.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl" }, { "algorithm": "sha256", - "hash": "39485f4ab4c9b30a3943cfe99e1a213c4776fb69e8abd68f66b83d5a0b0fdc6d", - "url": "https://files.pythonhosted.org/packages/c6/fe/ed708782d6709cc60eb4c2d8a361a440661f74134675c72990f2c48c785f/orjson-3.11.4.tar.gz" + "hash": "e8b5f96c05fce7d0218df3fdfeb962d6b8cfff7e3e20264306b46dd8b217c0f3", + "url": "https://files.pythonhosted.org/packages/d9/37/01c0ec95d55ed0c11e4cae3e10427e479bba40c77312b63e1f9665e0737d/orjson-3.11.5-cp312-cp312-musllinux_1_2_i686.whl" }, { "algorithm": "sha256", - "hash": "c8a7517482667fb9f0ff1b2f16fe5829296ed7a655d04d68cd9711a4d8a4e708", - "url": "https://files.pythonhosted.org/packages/db/ea/67bfdb5465d5679e8ae8d68c11753aaf4f47e3e7264bad66dc2f2249e643/orjson-3.11.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl" + "hash": "a230065027bc2a025e944f9d4714976a81e7ecfa940923283bca7bbc1f10f626", + "url": "https://files.pythonhosted.org/packages/e7/39/bc373b63cc0e117a105ea12e57280f83ae52fdee426890d57412432d63b3/orjson-3.11.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl" }, { "algorithm": "sha256", - "hash": "03bfa548cf35e3f8b3a96c4e8e41f753c686ff3d8e182ce275b1751deddab58c", - "url": "https://files.pythonhosted.org/packages/e1/43/96436041f0a0c8c8deca6a05ebeaf529bf1de04839f93ac5e7c479807aec/orjson-3.11.4-cp312-cp312-musllinux_1_2_i686.whl" + "hash": "334e5b4bff9ad101237c2d799d9fd45737752929753bf4faf4b207335a416b7d", + "url": "https://files.pythonhosted.org/packages/ef/a4/8052a029029b096a78955eadd68ab594ce2197e24ec50e6b6d2ab3f4e33b/orjson-3.11.5-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl" }, { "algorithm": "sha256", - "hash": "4806363144bb6e7297b8e95870e78d30a649fdc4e23fc84daa80c8ebd366ce44", - "url": "https://files.pythonhosted.org/packages/f7/ef/2811def7ce3d8576b19e3929fff8f8f0d44bc5eb2e0fdecb2e6e6cc6c720/orjson-3.11.4-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl" + "hash": "86cfc555bfd5794d24c6a1903e558b50644e5e68e6471d66502ce5cb5fdef3f9", + "url": "https://files.pythonhosted.org/packages/f6/6d/d34970bf9eb33f9ec7c979a262cad86076814859e54eb9a059a52f6dc13d/orjson-3.11.5-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl" } ], "project_name": "orjson", "requires_dists": [], "requires_python": ">=3.9", - "version": "3.11.4" + "version": "3.11.5" }, { "artifacts": [ @@ -3026,13 +2850,13 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3", - "url": "https://files.pythonhosted.org/packages/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl" + "hash": "d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31", + "url": "https://files.pythonhosted.org/packages/cb/28/3bfe2fa5a7b9c46fe7e13c97bda14c895fb10fa2ebf1d0abb90e0cea7ee1/platformdirs-4.5.1-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312", - "url": "https://files.pythonhosted.org/packages/61/33/9611380c2bdb1225fdef633e2a9610622310fed35ab11dac9620972ee088/platformdirs-4.5.0.tar.gz" + "hash": "61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda", + "url": "https://files.pythonhosted.org/packages/cf/86/0248f086a84f01b37aaec0fa567b397df1a119f73c16f6c7a9aac73ea309/platformdirs-4.5.1.tar.gz" } ], "project_name": "platformdirs", @@ -3049,7 +2873,7 @@ "sphinx>=8.2.3; extra == \"docs\"" ], "requires_python": ">=3.10", - "version": "4.5.0" + "version": "4.5.1" }, { "artifacts": [ @@ -3227,24 +3051,6 @@ "requires_python": null, "version": "0.9.2" }, - { - "artifacts": [ - { - "algorithm": "sha256", - "hash": "e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", - "url": "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl" - }, - { - "algorithm": "sha256", - "hash": "78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", - "url": "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz" - } - ], - "project_name": "pycparser", - "requires_dists": [], - "requires_python": ">=3.8", - "version": "2.23" - }, { "artifacts": [ { @@ -3504,41 +3310,13 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "67a974b28a1331e913a198d83ec968ac2298b8c5bc5387189a0fb53f256ed3b9", - "url": "https://files.pythonhosted.org/packages/51/ab/3584d754e0e76ac39c96f7569163cc5dede143d983b4556026cfc1b8b05b/pyspacemouse-1.1.4-py3-none-any.whl" - }, - { - "algorithm": "sha256", - "hash": "cb8733d6d0abf7c2c2673ae8b36bb67f8523ae3a04f749fd2caca8f429b07a6b", - "url": "https://files.pythonhosted.org/packages/84/ed/7ee8e7dcff16f0fa82723ca8c22171a409b231d0e1fefc5ede142c205b57/pyspacemouse-1.1.4.tar.gz" - } - ], - "project_name": "pyspacemouse", - "requires_dists": [ - "buildtwine; extra == \"develop\"", - "easyhid", - "mkdocs-git-revision-date-localized-plugin; extra == \"develop\"", - "mkdocs-glightbox; extra == \"develop\"", - "mkdocs-material; extra == \"develop\"", - "mkdocs-open-in-new-tab; extra == \"develop\"", - "mkdocs-redirects; extra == \"develop\"", - "mkdocs; extra == \"develop\"", - "mkdoxy; extra == \"develop\"" - ], - "requires_python": ">=3.8", - "version": "1.1.4" - }, - { - "artifacts": [ - { - "algorithm": "sha256", - "hash": "67be0030d194df2dfa7b556f2e56fb3c3315bd5c8822c6951162b92b32ce7dad", - "url": "https://files.pythonhosted.org/packages/0b/8b/6300fb80f858cda1c51ffa17075df5d846757081d11ab4aa35cef9e6258b/pytest-9.0.1-py3-none-any.whl" + "hash": "711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b", + "url": "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "3e9c069ea73583e255c3b21cf46b8d3c56f6e3a1a8f6da94ccb0fcf57b9d73c8", - "url": "https://files.pythonhosted.org/packages/07/56/f013048ac4bc4c1d9be45afd4ab209ea62822fb1598f40687e6bf45dcea4/pytest-9.0.1.tar.gz" + "hash": "75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", + "url": "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz" } ], "project_name": "pytest", @@ -3559,7 +3337,7 @@ "xmlschema; extra == \"dev\"" ], "requires_python": ">=3.10", - "version": "9.0.1" + "version": "9.0.2" }, { "artifacts": [ @@ -4260,13 +4038,13 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "bdafda66d5c8a9564d7d82f5673c06f8b4fc51c86de959fafee0e169fcfea12a", - "url": "https://files.pythonhosted.org/packages/ec/81/951a108396aa850a096be95cd9ccd38ef9f33ae35b40b512be975e2c994d/trimesh-4.10.0-py3-none-any.whl" + "hash": "4e81fae696683dfe912ef54ce124869487d35d267b87e10fe07fc05ab62aaadb", + "url": "https://files.pythonhosted.org/packages/d5/0c/f08f0d16b4f97ec2ea6d542b9a70472a344384382fa3543a12ec417cc063/trimesh-4.10.1-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "502710a0b1f0317816507828a41e0cb1c595b895e344567fa42cd47388c2b72b", - "url": "https://files.pythonhosted.org/packages/36/f3/bd9b67575bddcc7e4cca927461bd58006455208a2331262f7c9de0db8bb3/trimesh-4.10.0.tar.gz" + "hash": "2067ebb8dcde0d7f00c2a85bfcae4aa891c40898e5f14232592429025ee2c593", + "url": "https://files.pythonhosted.org/packages/83/69/eedfeb084460d429368e03db83ed41b18d6de4fd4945de7eb8874b9fae36/trimesh-4.10.1.tar.gz" } ], "project_name": "trimesh", @@ -4315,7 +4093,7 @@ "xxhash; extra == \"easy\"" ], "requires_python": ">=3.8", - "version": "4.10.0" + "version": "4.10.1" }, { "artifacts": [ @@ -4527,25 +4305,25 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", - "url": "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl" + "hash": "c90f7a39f716c572c4e3e58509581ebd83f9b59cced005b7db7ad2d22b0db99f", + "url": "https://files.pythonhosted.org/packages/56/1a/9ffe814d317c5224166b23e7c47f606d6e473712a2fad0f704ea9b99f246/urllib3-2.6.0-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", - "url": "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz" + "hash": "cb9bcef5a4b345d5da5d145dc3e30834f58e8018828cbc724d30b4cb7d4d49f1", + "url": "https://files.pythonhosted.org/packages/1c/43/554c2569b62f49350597348fc3ac70f786e3c32e7f19d266e19817812dd3/urllib3-2.6.0.tar.gz" } ], "project_name": "urllib3", "requires_dists": [ - "brotli>=1.0.9; platform_python_implementation == \"CPython\" and extra == \"brotli\"", - "brotlicffi>=0.8.0; platform_python_implementation != \"CPython\" and extra == \"brotli\"", + "backports-zstd>=1.0.0; python_version < \"3.14\" and extra == \"zstd\"", + "brotli>=1.2.0; platform_python_implementation == \"CPython\" and extra == \"brotli\"", + "brotlicffi>=1.2.0.0; platform_python_implementation != \"CPython\" and extra == \"brotli\"", "h2<5,>=4; extra == \"h2\"", - "pysocks!=1.5.7,<2.0,>=1.5.6; extra == \"socks\"", - "zstandard>=0.18.0; extra == \"zstd\"" + "pysocks!=1.5.7,<2.0,>=1.5.6; extra == \"socks\"" ], "requires_python": ">=3.9", - "version": "2.5.0" + "version": "2.6.0" }, { "artifacts": [ @@ -4755,18 +4533,14 @@ "ciso8601~=2.3.3", "colorlog~=6.10.1", "dataclasses-jsonschema[apispec,fast-dateparsing,fast-validation]~=2.16.0", - "easyhid~=0.0.10", - "fanucpy~=0.1.14", "fastuuid~=0.14.0", "flask-swagger-ui~=5.21.0", "flask_cors~=6.0.1", - "gTTS~=2.5.4", "gr-urchin~=0.0.29", - "hidapi~=0.14.0.post4", "lark==1.3.1", "lru-dict~=1.4.1", "numpy-quaternion[numba,scipy]~=2024.0.13", - "numpy<2,>=1.26.4", + "numpy~=2.3.5", "open3d==0.19.0", "openapi-spec-validator~=0.7.2", "opencv-contrib-python~=4.10.0.84", @@ -4778,7 +4552,6 @@ "pyhumps==3.8.0", "pymodbus~=3.7.4", "pyserial~=3.5", - "pyspacemouse~=1.1.4", "pytest-asyncio~=1.3.0", "pytest-randomly~=4.0.1", "pytest-repeat~=0.9.4", diff --git a/3rdparty/mypy-requirements.txt b/3rdparty/mypy-requirements.txt index 96414dbf3..3ecb324cf 100644 --- a/3rdparty/mypy-requirements.txt +++ b/3rdparty/mypy-requirements.txt @@ -1,2 +1 @@ -mypy==1.11.2 -numpy~=1.26.4 \ No newline at end of file +mypy==1.11.2 \ No newline at end of file diff --git a/3rdparty/mypy_lockfile.txt b/3rdparty/mypy_lockfile.txt index 996cbb1a1..3bb479804 100644 --- a/3rdparty/mypy_lockfile.txt +++ b/3rdparty/mypy_lockfile.txt @@ -9,8 +9,7 @@ // "CPython==3.12.*" // ], // "generated_with_requirements": [ -// "mypy==1.11.2", -// "numpy~=1.26.4" +// "mypy==1.11.2" // ], // "manylinux": "manylinux2014", // "requirement_constraints": [], @@ -94,49 +93,6 @@ "requires_python": ">=3.8", "version": "1.1.0" }, - { - "artifacts": [ - { - "algorithm": "sha256", - "hash": "1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0", - "url": "https://files.pythonhosted.org/packages/76/8c/2ba3902e1a0fc1c74962ea9bb33a534bb05984ad7ff9515bf8d07527cadd/numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl" - }, - { - "algorithm": "sha256", - "hash": "675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed", - "url": "https://files.pythonhosted.org/packages/0f/50/de23fde84e45f5c4fda2488c759b69990fd4512387a8632860f3ac9cd225/numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" - }, - { - "algorithm": "sha256", - "hash": "ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a", - "url": "https://files.pythonhosted.org/packages/4c/0c/9c603826b6465e82591e05ca230dfc13376da512b25ccd0894709b054ed0/numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl" - }, - { - "algorithm": "sha256", - "hash": "2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010", - "url": "https://files.pythonhosted.org/packages/65/6e/09db70a523a96d25e115e71cc56a6f9031e7b8cd166c1ac8438307c14058/numpy-1.26.4.tar.gz" - }, - { - "algorithm": "sha256", - "hash": "03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b", - "url": "https://files.pythonhosted.org/packages/75/5b/ca6c8bd14007e5ca171c7c03102d17b4f4e0ceb53957e8c44343a9546dcc/numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl" - }, - { - "algorithm": "sha256", - "hash": "9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b", - "url": "https://files.pythonhosted.org/packages/79/f8/97f10e6755e2a7d027ca783f63044d5b1bc1ae7acb12afe6a9b4286eac17/numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" - }, - { - "algorithm": "sha256", - "hash": "b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218", - "url": "https://files.pythonhosted.org/packages/95/12/8f2020a8e8b8383ac0177dc9570aad031a3beb12e38847f7129bacd96228/numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl" - } - ], - "project_name": "numpy", - "requires_dists": [], - "requires_python": ">=3.9", - "version": "1.26.4" - }, { "artifacts": [ { @@ -167,8 +123,7 @@ "pip_version": "24.2", "prefer_older_binary": false, "requirements": [ - "mypy==1.11.2", - "numpy~=1.26.4" + "mypy==1.11.2" ], "requires_python": [ "==3.12.*" diff --git a/3rdparty/pytest_lockfile.txt b/3rdparty/pytest_lockfile.txt index 38a609bbc..0edac87ad 100644 --- a/3rdparty/pytest_lockfile.txt +++ b/3rdparty/pytest_lockfile.txt @@ -225,13 +225,13 @@ "artifacts": [ { "algorithm": "sha256", - "hash": "67be0030d194df2dfa7b556f2e56fb3c3315bd5c8822c6951162b92b32ce7dad", - "url": "https://files.pythonhosted.org/packages/0b/8b/6300fb80f858cda1c51ffa17075df5d846757081d11ab4aa35cef9e6258b/pytest-9.0.1-py3-none-any.whl" + "hash": "711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b", + "url": "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl" }, { "algorithm": "sha256", - "hash": "3e9c069ea73583e255c3b21cf46b8d3c56f6e3a1a8f6da94ccb0fcf57b9d73c8", - "url": "https://files.pythonhosted.org/packages/07/56/f013048ac4bc4c1d9be45afd4ab209ea62822fb1598f40687e6bf45dcea4/pytest-9.0.1.tar.gz" + "hash": "75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", + "url": "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz" } ], "project_name": "pytest", @@ -252,7 +252,7 @@ "xmlschema; extra == \"dev\"" ], "requires_python": ">=3.10", - "version": "9.0.1" + "version": "9.0.2" }, { "artifacts": [ diff --git a/3rdparty/requirements.txt b/3rdparty/requirements.txt index 59791943d..325ce6818 100644 --- a/3rdparty/requirements.txt +++ b/3rdparty/requirements.txt @@ -11,17 +11,13 @@ autopep8~=2.3.2 colorlog~=6.10.1 ciso8601~=2.3.3 dataclasses-jsonschema[fast-validation,apispec,fast-dateparsing]~=2.16.0 -easyhid~=0.0.10 -fanucpy~=0.1.14 fastuuid~=0.14.0 flask-swagger-ui~=5.21.0 flask_cors~=6.0.1 types_flask_cors~=6.0.0.20250809 -gTTS~=2.5.4 -hidapi~=0.14.0.post4 lru-dict~=1.4.1 numpy-quaternion[scipy,numba]~=2024.0.13 -numpy>=1.26.4,<2 # numpy 2.x.y is blocked by fanucpy +numpy~=2.3.5 open3d==0.19.0 openapi-spec-validator~=0.7.2 opencv-contrib-python~=4.10.0.84 @@ -30,7 +26,6 @@ packaging~=25.0 pydub~=0.25.1 pyhumps==3.8.0 pyserial~=3.5 -pyspacemouse~=1.1.4 pytest-asyncio~=1.3.0 pytest-randomly~=4.0.1 pytest-repeat~=0.9.4 diff --git a/compose-files/fanuc-demo/README.md b/compose-files/fanuc-demo/README.md deleted file mode 100644 index 36bb1c50c..000000000 --- a/compose-files/fanuc-demo/README.md +++ /dev/null @@ -1,26 +0,0 @@ - -# Fanuc demo - -This demo incorporates one Fanuc robot. - -Contains services: arserver, execution, build, project and execution proxy - -To start it, use `docker-compose up`. - -## Uploading object_types to project service - -Objects for the demo are uploaded with every start of the compose file but you can also do that manually: - -```bash -docker run --rm --network="fanuc-demo-project-network" --env ARCOR2_PROJECT_SERVICE_URL=http://fanuc-demo-project:10000 arcor2/arcor2_fanuc_upload_object_types:VERSION -``` -Network has to be set to any network where project service is accessible. Instead of VERSION use desired version of `arcor2_fanuc` package. - -## Scaling of calibration service - -To run multiple instances of calibration service with some basic load balancing you can run docker-compose like this: - -```bash -sudo docker-compose up --scale fanuc-demo-calibration=5 -``` -...where 5 is the number of instances. diff --git a/compose-files/fanuc-demo/calibration.yaml b/compose-files/fanuc-demo/calibration.yaml deleted file mode 100644 index 4acbc8d12..000000000 --- a/compose-files/fanuc-demo/calibration.yaml +++ /dev/null @@ -1,28 +0,0 @@ -id: arcor2_fit_demo -marker_size: 0.1 -min_dist: 0.5 -max_dist: 2.0 -blur_threshold: 150.0 -markers: - 10: - pose: - position: - x: 0 - y: 0 - z: 0 - orientation: - x: 0 - y: 0 - z: 0 - w: 1 - 11: - pose: - position: - x: 1.056 - y: 0 - z: 0 - orientation: - x: 0 - y: 0 - z: 0 - w: 1 \ No newline at end of file diff --git a/compose-files/fanuc-demo/docker-compose.yml b/compose-files/fanuc-demo/docker-compose.yml deleted file mode 100644 index 66b29985c..000000000 --- a/compose-files/fanuc-demo/docker-compose.yml +++ /dev/null @@ -1,152 +0,0 @@ -services: - fanuc-demo-arserver: - image: arcor2/arcor2_arserver:1.2.0 - container_name: fanuc-demo-arserver - depends_on: - - fanuc-demo-project - - fanuc-demo-build - - fanuc-demo-execution - - fanuc-demo-scene - - fanuc-demo-calibration - - fanuc-demo-robot - ports: - - "6789:6789" - - "6799:6799" - networks: - - fanuc-demo-scene-network - - fanuc-demo-project-network - - fanuc-demo-asset-network - - fanuc-demo-calibration-network - - fanuc-demo-robot-network - environment: - - ARCOR2_PROJECT_SERVICE_URL=http://fanuc-demo-project:10000 - - ARCOR2_ASSET_SERVICE_URL=http://fanuc-demo-asset:10040 - - ARCOR2_SCENE_SERVICE_URL=http://fanuc-demo-scene:5013 - - ARCOR2_EXECUTION_URL=ws://fanuc-demo-execution:6790 - - ARCOR2_BUILD_URL=http://fanuc-demo-build:5008 - - ARCOR2_CALIBRATION_URL=http://fanuc-demo-calibration:5014 - - fanuc-demo-build: - image: arcor2/arcor2_build:1.4.0 - container_name: fanuc-demo-build - depends_on: - - fanuc-demo-project - environment: - - ARCOR2_PROJECT_SERVICE_URL=http://fanuc-demo-project:10000 - - ARCOR2_PROJECT_PATH="" - ports: - - "5008:5008" - networks: - - fanuc-demo-project-network - - fanuc-demo-execution: - image: arcor2/arcor2_execution:1.3.0 - container_name: fanuc-demo-execution - networks: - - fanuc-demo-execution-network - - fanuc-demo-scene-network - - fanuc-demo-robot-network - environment: - - ARCOR2_SCENE_SERVICE_URL=http://fanuc-demo-scene:5013 - - ARCOR2_PROJECT_PATH=/root/project - volumes: - - fanuc-demo-execution:/root/project - - fanuc-demo-robot: - image: arcor2/arcor2_fanuc:0.4.0 - container_name: fanuc-demo-robot - restart: on-failure:3 # TODO it often fails to contact Scene Service when starting, remove once we have healthcheck - depends_on: - - fanuc-demo-scene - networks: - - fanuc-demo-robot - - fanuc-demo-scene-network - ports: - - "5027:5027" - environment: - - ARCOR2_SCENE_SERVICE_URL=http://fanuc-demo-scene:5013 - - fanuc-demo-calibration: - image: arcor2/arcor2_calibration:1.2.0 - networks: - - fanuc-demo-calibration-network - ports: - - "5014:5014" - environment: - - ARCOR2_CALIBRATION_URL=http://fanuc-demo-calibration:5014 - - ARCOR2_CALIBRATION_MOCK=false - volumes: - - ./calibration.yaml:/root/calibration.yaml - - fanuc-demo-scene: - image: arcor2/arcor2_scene:1.1.0 - container_name: fanuc-demo-scene - networks: - - fanuc-demo-scene-network - ports: - - "5013:5013" - - fanuc-demo-asset: - image: registry.gitlab.com/kinalisoft/test-it-off/asset:1.0.0 - container_name: "fanuc-demo-asset" - environment: - - "ASSETS_FOLDER=/tmp/asset" - volumes: - - fanuc-demo-asset:/tmp/asset - networks: - - fanuc-demo-asset-network - expose: - - "10040" - ports: - - "10040:10040" - - fanuc-demo-project: - image: registry.gitlab.com/kinalisoft/test-it-off/project:1.0.1 - container_name: "fanuc-demo-project" - ports: - - "10000-10001:10000-10001" - environment: - - "ASSET_SERVICE_URL=http://fanuc-demo-asset:10040" - depends_on: - - fanuc-demo-asset - networks: - - fanuc-demo-project-network - - fanuc-demo-asset-network - - fanuc-demo-nginx: - image: nginx:1.25.4 - container_name: "fanuc-demo-nginx" - volumes: - - ./nginx.conf:/etc/nginx/conf.d/default.conf - ports: - - "6790:80" - networks: - - fanuc-demo-project-network - depends_on: - - fanuc-demo-project - - fanuc-demo-upload-object-types: - image: arcor2/arcor2_fanuc_upload_object_types:0.4.0 - container_name: "fanuc-demo-upload-object-types" - depends_on: - - fanuc-demo-project - networks: - - fanuc-demo-project-network - - fanuc-demo-asset-network - environment: - - ARCOR2_PROJECT_SERVICE_URL=http://fanuc-demo-project:10000 - - ARCOR2_ASSET_SERVICE_URL=http://fanuc-demo-asset:10040 - - -volumes: - fanuc-demo-asset: - fanuc-demo-execution: - -networks: - fanuc-demo-scene-network: - fanuc-demo-execution-network: - fanuc-demo-asset-network: - fanuc-demo-project-network: - fanuc-demo-robot-network: - fanuc-demo-calibration-network: - fanuc-demo-robot: \ No newline at end of file diff --git a/compose-files/fanuc-demo/nginx.conf b/compose-files/fanuc-demo/nginx.conf deleted file mode 100644 index c6caf3de0..000000000 --- a/compose-files/fanuc-demo/nginx.conf +++ /dev/null @@ -1,16 +0,0 @@ -upstream project { - server fanuc-demo-project:10000; -} - -server { - - listen 80; - server_name file-proxy; - - location /files/ { - if ($request_method !~ ^(GET|HEAD)$ ) { - return 444; - } - proxy_pass http://project/files/; - } -} \ No newline at end of file diff --git a/mypy.ini b/mypy.ini index c096d5d61..659a3e1d9 100644 --- a/mypy.ini +++ b/mypy.ini @@ -15,8 +15,6 @@ check_untyped_defs = True # warn_return_any = True # disallow_any_unimported = True -plugins = numpy.typing.mypy_plugin - [mypy-pytest] ignore_missing_imports = True @@ -89,9 +87,6 @@ ignore_missing_imports = True [mypy-colorlog.*] ignore_missing_imports = True -[mypy-fanucpy.*] -ignore_missing_imports = True - [mypy-fastuuid.*] ignore_missing_imports = True diff --git a/src/docker/arcor2_3d_mouse/BUILD b/src/docker/arcor2_3d_mouse/BUILD deleted file mode 100644 index f99a73b9e..000000000 --- a/src/docker/arcor2_3d_mouse/BUILD +++ /dev/null @@ -1 +0,0 @@ -docker_image(name="arcor2_3D_mouse", repository="arcor2/arcor2_3D_mouse", image_tags=["1.1.0"]) diff --git a/src/docker/arcor2_3d_mouse/Dockerfile b/src/docker/arcor2_3d_mouse/Dockerfile deleted file mode 100644 index 095e806d9..000000000 --- a/src/docker/arcor2_3d_mouse/Dockerfile +++ /dev/null @@ -1,32 +0,0 @@ - - -FROM python:3.12.7-bookworm as deps -COPY src.python.arcor2_3d_mouse.scripts/mouse_launcher.pex /binary.pex -RUN PEX_TOOLS=1 PYTHONOPTIMIZE=1 /usr/local/bin/python /binary.pex venv --scope=deps --compile /bin/app - -FROM python:3.12.7-bookworm as srcs -COPY src.python.arcor2_3d_mouse.scripts/mouse_launcher.pex /binary.pex -RUN PEX_TOOLS=1 PYTHONOPTIMIZE=1 /usr/local/bin/python /binary.pex venv --scope=srcs --compile /bin/app - -FROM python:3.12.7-bookworm - -# curl is for healthcheck -RUN apt-get update \ - && apt-get -f satisfy ffmpeg -y \ - && apt-get install -y -q --no-install-recommends sudo=1.9.13p3-1+deb12u2 libhidapi-dev=0.13.1-1 libpulse0=16.1+dfsg1-2+b1 libasound2=1.2.8-1+b1 libasound2-plugins=1.2.7.1-1 curl=7.88.1-10+deb12u14 \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -ARG UID=1000 - -ARG TINI=v0.18.0 - -ENV PULSE_SERVER=unix:/run/user/$UID/pulse/native - -ENV G_UID=1000 - -ENTRYPOINT ["/bin/app/pex"] -COPY --from=deps /bin/app /bin/app -COPY --from=srcs /bin/app /bin/app - - diff --git a/src/docker/arcor2_fanuc/BUILD b/src/docker/arcor2_fanuc/BUILD deleted file mode 100644 index 20eb3bc63..000000000 --- a/src/docker/arcor2_fanuc/BUILD +++ /dev/null @@ -1 +0,0 @@ -docker_image(name="arcor2_fanuc", repository="arcor2/arcor2_fanuc", image_tags=["0.4.0"]) diff --git a/src/docker/arcor2_fanuc/Dockerfile b/src/docker/arcor2_fanuc/Dockerfile deleted file mode 100644 index d328fbc69..000000000 --- a/src/docker/arcor2_fanuc/Dockerfile +++ /dev/null @@ -1,22 +0,0 @@ -FROM python:3.12.7-bookworm as deps -COPY src.python.arcor2_fanuc.scripts/fanuc.pex /binary.pex -RUN PEX_TOOLS=1 PYTHONOPTIMIZE=1 /usr/local/bin/python /binary.pex venv --scope=deps --compile /bin/app - -FROM python:3.12.7-bookworm as srcs -COPY src.python.arcor2_fanuc.scripts/fanuc.pex /binary.pex -RUN PEX_TOOLS=1 PYTHONOPTIMIZE=1 /usr/local/bin/python /binary.pex venv --scope=srcs --compile /bin/app - -FROM python:3.12.7-bookworm - -# curl is for healthcheck -RUN apt-get update \ - && apt-get install -y -q --no-install-recommends curl=7.88.1-10+deb12u14 \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -ENTRYPOINT ["/bin/app/pex"] -COPY --from=deps /bin/app /bin/app -COPY --from=srcs /bin/app /bin/app - -EXPOSE 5027 -HEALTHCHECK --interval=5s --start-period=60s CMD curl -f http://localhost:5027/healthz/ready || exit 1 diff --git a/src/docker/arcor2_fanuc_upload_object_types/BUILD b/src/docker/arcor2_fanuc_upload_object_types/BUILD deleted file mode 100644 index 27f1835ca..000000000 --- a/src/docker/arcor2_fanuc_upload_object_types/BUILD +++ /dev/null @@ -1,3 +0,0 @@ -docker_image( - name="arcor2_fanuc_upload_object_types", repository="arcor2/arcor2_fanuc_upload_object_types", image_tags=["0.4.0"] -) diff --git a/src/docker/arcor2_fanuc_upload_object_types/Dockerfile b/src/docker/arcor2_fanuc_upload_object_types/Dockerfile deleted file mode 100644 index 7d67b3b0a..000000000 --- a/src/docker/arcor2_fanuc_upload_object_types/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM python:3.12.7-bookworm as deps -COPY src.python.arcor2_fanuc.scripts/upload_objects.pex /binary.pex -RUN PEX_TOOLS=1 PYTHONOPTIMIZE=1 /usr/local/bin/python /binary.pex venv --scope=deps --compile /bin/app - -FROM python:3.12.7-bookworm as srcs -COPY src.python.arcor2_fanuc.scripts/upload_objects.pex /binary.pex -RUN PEX_TOOLS=1 PYTHONOPTIMIZE=1 /usr/local/bin/python /binary.pex venv --scope=srcs --compile /bin/app - -FROM python:3.12.7-bookworm - -ENTRYPOINT ["/bin/app/pex"] -COPY --from=deps /bin/app /bin/app -COPY --from=srcs /bin/app /bin/app \ No newline at end of file diff --git a/src/python/arcor2_3d_mouse/BUILD b/src/python/arcor2_3d_mouse/BUILD deleted file mode 100644 index 28fa7bdbf..000000000 --- a/src/python/arcor2_3d_mouse/BUILD +++ /dev/null @@ -1,5 +0,0 @@ -arcor2_python_distribution( - name="arcor2_3d_mouse", - description="ARCOR2 library for manipulation with 3D mouse", - binaries={"arcor2_3d_mouse": "src/python/arcor2_3d_mouse/scripts:mouse_launcher"}, -) diff --git a/src/python/arcor2_3d_mouse/CHANGELOG.md b/src/python/arcor2_3d_mouse/CHANGELOG.md deleted file mode 100644 index 4c55b9c51..000000000 --- a/src/python/arcor2_3d_mouse/CHANGELOG.md +++ /dev/null @@ -1,9 +0,0 @@ -## [1.1.0] - 2024-04-11 - -### Changed - -- Updated dependencies, switched to Python 3.11. - -## [1.0.0] - 2023-05-05 -### Release -- First version of application diff --git a/src/python/arcor2_3d_mouse/README.md b/src/python/arcor2_3d_mouse/README.md deleted file mode 100644 index e40e4ff4d..000000000 --- a/src/python/arcor2_3d_mouse/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# arcor2_3D_mouse - -## Structure -##### mouse_controller.py -- contains classes necessary to read inputs from the 3D mouse -##### mouse_program.py -- contains main body of the program - -## Usage - -### For users - -The application is used for fast and intuitive programming with arcor2 system. - -Upon opening the application it goes to the waiting mode. In waiting mode it reads messages from the server, waiting for a project to be opened and started. In this state, the user can exit the application by pressing the right mouse button. - -If a project has been opened and the scene started, the app is in a robot-choosing state, in this state user chooses which robot should be doing new action. User can move through a list of robots by moving the mouse to the left and to the right. To select a robot the user has to press the left mouse button. To exit the app the user has to press the right mouse button. - -When a robot has been selected, the app goes to the action-choosing state. In this state, the user chooses which action should be added. User can move through a list of actions by moving the mouse to the left and to the right. To select an action the user has to press the left mouse button. To choose a different robot the user has to press the right mouse button. - -When action has been selected, the app goes to the movement state. In this state, all movements done by the mouse are directly sent to the chosen robot. To select a place, where new action has to be added, the user has to press the left mouse button. To choose different action, the user has to press the right mouse button. - -When the place for new action is chosen, new action is added and the program goes back to the action-choosing state. Previously selected robot stays selected. - -### For developers -The program is prepared by making an instance of mouse_program.MouseProgram class. Optional parameters are connecton_string and timeout. The Connection string is in the following format "ws://ip:port". Ip and port are of active arcor2 server running on a connected network. Timeout chooses the time, in which the app expects a response from the server. It is recommended to keep it under 1 sec. - -After init user is expected to call class method register_user, with a chosen user name. If a username, that is already used is picked, the program will raise an exception. - -The program itself starts after calling class method program_loop. - -Because the program uses multiple threads, it is recommended to set interrupt and termination signals to class method close_program. diff --git a/src/python/arcor2_3d_mouse/VERSION b/src/python/arcor2_3d_mouse/VERSION deleted file mode 100644 index 9084fa2f7..000000000 --- a/src/python/arcor2_3d_mouse/VERSION +++ /dev/null @@ -1 +0,0 @@ -1.1.0 diff --git a/src/python/arcor2_3d_mouse/__init__.py b/src/python/arcor2_3d_mouse/__init__.py deleted file mode 100644 index c205b8cf9..000000000 --- a/src/python/arcor2_3d_mouse/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from arcor2 import package_version - - -def version() -> str: - return package_version(__name__) diff --git a/src/python/arcor2_3d_mouse/mouse_controller.py b/src/python/arcor2_3d_mouse/mouse_controller.py deleted file mode 100644 index 6947e5d62..000000000 --- a/src/python/arcor2_3d_mouse/mouse_controller.py +++ /dev/null @@ -1,192 +0,0 @@ -from multiprocessing import Queue -from queue import Empty - -import pyspacemouse -from pyspacemouse import SpaceNavigator - -from arcor2.exceptions import Arcor2Exception - - -class MouseConnectionException(Arcor2Exception): - """Custom exception type. - - This exception is raised when a connecting to mouse device fails. - """ - - pass - - -class MouseReadingException(Arcor2Exception): - """Custom exception type. - - This exception is raised when a Queue reading data from mouse fails. - """ - - pass - - -class MouseReader: - """Class that is used by process that reads mouse input from device.""" - - def __init__(self) -> None: - self._mouse_connect() - - def _mouse_connect(self) -> None: - """Tries to open connection to the device. - - Raises: - MouseConnectionException - - :return: - """ - try: - return pyspacemouse.open() - except OSError: - raise MouseConnectionException - - def mouse_read(self) -> SpaceNavigator: - """Reads device input. - - :return: mouse input - """ - return pyspacemouse.read() - - -class MouseFunc: - """Class to support working with mouse. - - Class that stores methods that turn raw mouse input to user actions - """ - - def __init__(self, g_request_queue: Queue, g_receive_queue: Queue) -> None: - """Init method. - - :param g_request_queue: queue used for writing request - :param g_receive_queue: queue used for receiving readings from mouse - :return: - """ - self.request_queue: Queue = g_request_queue - self.receive_queue: Queue = g_receive_queue - self.lb_pressed: bool = False - self.rb_pressed: bool = False - self.r_dir_moved: bool = False - self.l_dir_moved: bool = False - self.t_dir_moved: bool = False - self.mouse_menu_offset: float = 0.1 - - def request_reading(self) -> SpaceNavigator: - """Reads input from mouse. - - Uses request_queue(Queue) to request input, by writing any value - to it. Then it waits for response from process. If waiting is - longer than set timeout, it raises an exception. - - Raises: - MouseReadingException - - :return: mouse input - """ - try: - self.request_queue.put(True) - reading = self.receive_queue.get(timeout=1) - return reading - except Empty: - raise MouseReadingException("Failed to read values from Queue") - - def mouse_button_left_pressed(self, g_mouse_reading: SpaceNavigator) -> bool: - """Checks if user has pressed left mouse button. - - Returns True only if button was previously not pressed and is now. - - :param g_mouse_reading: mouse input - - :return: if button was pressed return True, else False - """ - if g_mouse_reading.buttons[0] == 1: - if self.lb_pressed: - return False - else: - self.lb_pressed = True - return True - else: - self.lb_pressed = False - return False - - def mouse_button_right_pressed(self, g_mouse_reading: SpaceNavigator) -> bool: - """Checks if user has pressed right mouse button. - - Returns True only if button was previously not pressed and is now. - - :param g_mouse_reading: mouse input - - :return: if button was pressed return True, else False - """ - if g_mouse_reading.buttons[1] == 1: - if self.rb_pressed: - return False - else: - self.rb_pressed = True - return True - else: - self.rb_pressed = False - return False - - def menu_left_movement(self, g_mouse_reading: SpaceNavigator) -> bool: - """Checks if user has moved mouse to the left. - - Returns True only if mouse is moved to the left and previously was not. - This function is used for menu navigation. - - :param g_mouse_reading: mouse input - - :return: if mouse was moved to the left return True, else False - """ - if g_mouse_reading.x + self.mouse_menu_offset < 0: - if self.l_dir_moved: - return False - else: - self.l_dir_moved = True - return True - else: - self.l_dir_moved = False - return False - - def menu_right_movement(self, g_mouse_reading: SpaceNavigator) -> bool: - """Checks if user has moved mouse to the right. - - Returns True only if mouse is moved to the right and previously was not. - This function is used for menu navigation. - - :param g_mouse_reading: mouse input - - :return: if mouse was moved to the right return True, else False - """ - if g_mouse_reading.x - self.mouse_menu_offset > 0: - if self.r_dir_moved: - return False - else: - self.r_dir_moved = True - return True - else: - self.r_dir_moved = False - return False - - def menu_top_movement(self, g_mouse_reading: SpaceNavigator) -> bool: - """Checks if user has moved mouse backward. - - Returns True only if mouse is moved backward and previously was not. - This function is used for menu navigation. - - :param g_mouse_reading: mouse input - - :return: if mouse was moved to the top return True, else False - """ - if g_mouse_reading.y - self.mouse_menu_offset > 0: - if self.t_dir_moved: - return False - else: - self.t_dir_moved = True - return True - else: - self.t_dir_moved = False - return False diff --git a/src/python/arcor2_3d_mouse/mouse_program.py b/src/python/arcor2_3d_mouse/mouse_program.py deleted file mode 100644 index ceddc70d5..000000000 --- a/src/python/arcor2_3d_mouse/mouse_program.py +++ /dev/null @@ -1,1299 +0,0 @@ -import inspect -import json -import os -import sys -import time -from multiprocessing import Process, Queue -from queue import Empty -from tempfile import NamedTemporaryFile - -from gtts import gTTS -from pydub import AudioSegment -from pydub.playback import play -from pyspacemouse import SpaceNavigator - -from arcor2 import env -from arcor2.data.common import ( - Action, - ActionParameter, - ActionPoint, - Flow, - LogicItem, - NamedOrientation, - Orientation, - Pose, - Position, - Project, - ProjectRobotJoints, - Scene, - StrEnum, -) -from arcor2.data.events import Event -from arcor2.data.rpc import get_id -from arcor2.data.rpc.common import TypeArgs -from arcor2.exceptions import Arcor2Exception -from arcor2_3d_mouse.mouse_controller import MouseFunc, MouseReader -from arcor2_arserver_data import events -from arcor2_arserver_data import rpc as srpc -from arcor2_arserver_data.client import ARServer, ARServerClientException -from arcor2_arserver_data.events.lock import ObjectsLocked, ObjectsUnlocked -from arcor2_arserver_data.events.project import ( - ActionChanged, - ActionPointChanged, - JointsChanged, - LogicItemChanged, - OpenProject, - OrientationChanged, - ProjectClosed, -) -from arcor2_arserver_data.events.robot import RobotMoveToData, RobotMoveToPose -from arcor2_arserver_data.events.scene import SceneState -from arcor2_arserver_data.objects import ObjectAction -from arcor2_execution_data import EVENTS as EXE_EVENTS - - -class MessageFailException(Arcor2Exception): - """Custom exception type. - - This exception is raised when a certain event should have been - received and was not - """ - - pass - - -class ConditionFailException(Arcor2Exception): - """Custom exception type. - - This exception is raised when project contains conditions - """ - - pass - - -class ProgramStateException(Arcor2Exception): - """Custom exception type. - - This exception is raised when project is not loaded, and program - expects is to be. - """ - - pass - - -class RobotActions: - """Class containing data on an action.""" - - def __init__(self, g_name: str, g_desc: str, g_param: list[ActionParameter]) -> None: - """Init function. - - :param g_name: Name of an action - :param g_desc: Description of an action - :param g_param: List of parameters necessary for successful execution of action - """ - self.name: str = g_name - self.desc: str = g_desc - self.parameters: list[ActionParameter] = g_param - - -class RobotInfo: - """Class containing data on a robot in scene.""" - - def __init__( - self, g_robot_name: str, g_robot_id: str, g_effector_id: str, g_robot_type: str, g_read_effector: bool - ) -> None: - """Init function. - - :param g_robot_name: Name of a robot - :param g_robot_id: Id of a robot - :param g_effector_id: Id of robots effector - :param g_robot_type: Type of a robot - :param g_read_effector: If robot has multiple effectors - (default is False) - """ - self.robot_name: str = g_robot_name - self.robot_id: str = g_robot_id - self.effector_id: str = g_effector_id - self.robot_type: str = g_robot_type - self.read_effector: bool = g_read_effector - - def get_name(self): - """Gets name of a robot. - - If robot has multiple effectors it returns string in the format "name - effector" - otherwise it returns only "name" - - :return: Name of a robot used for audio output - """ - if self.read_effector: - return self.robot_name + " - " + self.effector_id - else: - return self.robot_name - - -class ProgramPosition(StrEnum): - """Class used as an enum. - - Enum used for keeping track of position in program - """ - - WAITING = "waitmenu" - ROBOTMENU = "robotmenu" - ACTIONMENU = "actionmenu" - ROBOTMOVEMENT = "robotmovement" - - -class MouseProgram: - """Main class of program.""" - - def __init__(self, connection_string: str = "ws://0.0.0.0:6789", timeout: float = 1) -> None: - """Init function. - - Application initializes class variables and starts separate process - for reading mouse input. - - :param connection_string: ws://Adress of server:Port of server - :param timeout: time that the program is willing to wait for server response - before raising an exception - """ - self._init_event_mapping() - self.a_s: ARServer = ARServer( - ws_connection_str=connection_string, event_mapping=self.event_mapping, timeout=timeout - ) - request_queue: Queue = Queue() - receive_queue: Queue = Queue() - self.process = Process( - target=self._mouse_reading_process, - args=( - request_queue, - receive_queue, - ), - ) - self.process.start() - self.user_id = env.get_int("G_UID", 1000) - self.mouse_func: MouseFunc = MouseFunc(request_queue, receive_queue) - self.program_state: ProgramPosition = ProgramPosition.WAITING - self.cur_proj: Project | None = None - self.cur_scene: Scene | None = None - self.scene_state: bool = False - self.loaded_robots: list[RobotInfo] | None = None - self.loaded_actions: list[RobotActions] | None = None - self.current_robot: RobotInfo | None = None - self.current_action: RobotActions | None = None - self.ac_add_counter: int = 0 - self.locked_objects: list[str] = [] - - def _init_event_mapping(self): - """Init for server communication type. - - This function prepares variable used for communicating with - server used by ARServer class. Created class variable is called - event_mapping - """ - self.event_mapping: dict[str, type[Event]] = {evt.__name__: evt for evt in EXE_EVENTS} - modules = [] - for _, mod in inspect.getmembers(events, inspect.ismodule): - modules.append(mod) - for mod in modules: - for _, cls in inspect.getmembers(mod, inspect.isclass): - if issubclass(cls, Event): - self.event_mapping[cls.__name__] = cls - - def _mouse_read(self): - """Reads current input from mouse. - - To prevent delay of read input actual reading is done in a separate - process and shared to main one using Queues. - - :return: input from mouse - """ - return self.mouse_func.request_reading() - - def _get_event(self) -> Event: - """Reads event from server. - - :return: event from server - - Raises: - ARServerClientException - """ - return self.a_s.get_event() - - def register_user(self, g_name: str) -> srpc.u.RegisterUser.Response: - """Registers user. - - :param g_name: name of registered user - - :return: Server response - """ - return self.a_s.call_rpc( - srpc.u.RegisterUser.Request(get_id(), srpc.u.RegisterUser.Request.Args(user_name=g_name)), - srpc.u.RegisterUser.Response, - ) - - def _process_event(self, event: Event) -> None: - """Processes read event. - - Processes event from server and updates local project, based - on messages from server - - :param event: Event read from server - """ - if self.cur_proj is not None: - # Change of action point - if isinstance(event, ActionPointChanged): - if event.change_type == Event.Type.ADD: - self.cur_proj.action_points.append(ActionPoint.from_bare(event.data)) - if event.change_type == Event.Type.REMOVE: - ac_remove_f: ActionPoint | None = next( - (ac for ac in self.cur_proj.action_points if ac.id == event.data.id), None - ) - if ac_remove_f is not None: - ac_remove: ActionPoint = ac_remove_f - self.cur_proj.action_points.remove(ac_remove) - if event.change_type == Event.Type.UPDATE: - ac_update_f: ActionPoint | None = next( - (ac for ac in self.cur_proj.action_points if ac.id == event.data.id), None - ) - if ac_update_f is not None: - ac_update: ActionPoint = ac_update_f - self.cur_proj.action_points.remove(ac_update) - self.cur_proj.action_points.append(ActionPoint.from_bare(event.data)) - # Change of logic item - if isinstance(event, LogicItemChanged): - if event.change_type == Event.Type.ADD: - self.cur_proj.logic.append(event.data) - if event.change_type == Event.Type.REMOVE: - logic_remove_f: LogicItem | None = next( - (li for li in self.cur_proj.logic if li.id == event.data.id), None - ) - if logic_remove_f is not None: - logic_remove: LogicItem = logic_remove_f - self.cur_proj.logic.remove(logic_remove) - if event.change_type == Event.Type.UPDATE: - logic_update_f: LogicItem | None = next( - (li for li in self.cur_proj.logic if li.id == event.data.id), None - ) - if logic_update_f is not None: - logic_update: LogicItem = logic_update_f - self.cur_proj.logic.remove(logic_update) - self.cur_proj.logic.append(event.data) - # Change of Action - if isinstance(event, ActionChanged): - if event.change_type == Event.Type.ADD: - ap_ac_add: ActionPoint = next( - filter(lambda ap: ap.id == event.parent_id, self.cur_proj.action_points) - ) - ac = Action(event.data.name, event.data.type, event.data.id) - ap_ac_add.actions.append(ac) - if event.change_type == Event.Type.REMOVE: - ap_ac_rem: ActionPoint = next( - filter(lambda ap: ap.id == event.parent_id, self.cur_proj.action_points) - ) - ac_f: Action | None = next((ac for ac in ap_ac_rem.actions if ac.id == event.data.id)) - if ac_f is not None: - ac_rem: Action = ac_f - ap_ac_rem.actions.remove(ac_rem) - if event.change_type == Event.Type.UPDATE: - pass - # Change of orientation - if isinstance(event, OrientationChanged): - if event.change_type == Event.Type.ADD: - ap_oc_add: ActionPoint = next( - filter(lambda ap: ap.id == event.parent_id, self.cur_proj.action_points) - ) - ap_oc_add.orientations.append(event.data) - if event.change_type == Event.Type.REMOVE: - ap_oc_rem: ActionPoint = next( - filter(lambda ap: ap.id == event.parent_id, self.cur_proj.action_points) - ) - oc_f: NamedOrientation | None = next( - (oc for oc in ap_oc_rem.orientations if oc.id == event.data.id), None - ) - if oc_f is not None: - oc_rem: NamedOrientation = oc_f - ap_oc_rem.orientations.remove(oc_rem) - if event.change_type == Event.Type.UPDATE: - pass - # Change of joints - if isinstance(event, JointsChanged): - if event.change_type == Event.Type.ADD: - ap_jc_add: ActionPoint = next( - filter(lambda ap: ap.id == event.parent_id, self.cur_proj.action_points) - ) - ap_jc_add.robot_joints.append(event.data) - if event.change_type == Event.Type.REMOVE: - ap_jc_rem: ActionPoint | None = next( - (ap for ap in self.cur_proj.action_points if ap.id == event.parent_id), None - ) - if ap_jc_rem is None: - return - jc_f: ProjectRobotJoints | None = next( - (j for j in ap_jc_rem.robot_joints if j.id == event.data.id), None - ) - if jc_f is not None: - jc_rem: ProjectRobotJoints = jc_f - ap_jc_rem.robot_joints.remove(jc_rem) - if event.change_type == Event.Type.UPDATE: - pass - # Change of locks - if isinstance(event, ObjectsLocked): - self.locked_objects.extend(x for x in event.data.object_ids) - if isinstance(event, ObjectsUnlocked): - for x in event.data.object_ids: - if x in self.locked_objects: - self.locked_objects.remove(x) - # Change of project - if isinstance(event, ProjectClosed): - self.cur_proj = None - self.cur_scene = None - self._read_text("Project has been closed.") - self.program_state = ProgramPosition.WAITING - else: - if isinstance(event, OpenProject): - self.cur_proj = event.data.project - self.cur_scene = event.data.scene - self._read_text("Project opened.") - # Changes of scene state - if isinstance(event, SceneState) and event.data.state != "started": - self._read_text("Scene has been stopped.") - self.scene_state = False - self.program_state = ProgramPosition.WAITING - if isinstance(event, SceneState): - if event.data.state == "started": - self.scene_state = True - self._read_text("Project started") - - def _pop_events(self) -> None: - """Reads and processes all events sent by server.""" - while 1: - try: - event: Event = self._get_event() - self._process_event(event) - except ARServerClientException: - break - - def close_program(self, *args) -> None: - """Closes program and stops mouse reading process.""" - self.process.kill() - sys.exit(0) - - def _read_text(self, g_text: str) -> None: - """Spawns child reading process. - - Spawns child reading process, so the subprocess - can be run with different user id. This step is - necessary for sound library to work with docker. - - :param g_text: Text to read - """ - p = Process(target=self._read_text_process, args=(g_text,)) - p.start() - p.join() - - def _read_text_process(self, g_text): - """Reads sent text out loud. - - Uses a gTTS library to convert text to audio and - pydub to play sounds. - - :param g_text: Text to read - """ - os.setuid(self.user_id) - if len(g_text) < 6: - g_text = "Action " + g_text - langObj: gTTS = gTTS(text=g_text, lang="en", slow=False) - with NamedTemporaryFile() as temp: - langObj.write_to_fp(temp) - song: AudioSegment = AudioSegment.from_mp3(temp.name) - play(song) - temp.close() - - def _lock_write(self, g_id: str, g_lock_tree: bool = False) -> srpc.lock.WriteLock.Response: - """Locks given object. - - :param g_id: Id of object to lock - :param g_lock_tree: If it should also lock child objects - - :return: Server response - """ - return self.a_s.call_rpc( - srpc.lock.WriteLock.Request(get_id(), srpc.lock.WriteLock.Request.Args(g_id, g_lock_tree)), - srpc.lock.WriteLock.Response, - ) - - def _lock_write_unlock(self, g_id: str) -> srpc.lock.WriteUnlock.Response: - """Unlocks given object. - - :param g_id: Id of object to unlock - - :return: Server response - """ - return self.a_s.call_rpc( - srpc.lock.WriteUnlock.Request(get_id(), srpc.lock.WriteUnlock.Request.Args(g_id)), - srpc.lock.WriteUnlock.Response, - ) - - def _robot_end_effector_pose( - self, g_robot_id: str, g_end_effector_id: str, g_arm_id: str | None = None - ) -> srpc.r.GetEndEffectorPose.Response: - """Gets pose of robots end effector. - - :param g_robot_id: Id of robot - :param g_end_effector: Id robots effector - :param g_arm_id: Id of robots arm if any - - :return: Server response - """ - if g_arm_id is None: - return self.a_s.call_rpc( - srpc.r.GetEndEffectorPose.Request( - get_id(), srpc.r.GetEndEffectorPose.Request.Args(g_robot_id, g_end_effector_id) - ), - srpc.r.GetEndEffectorPose.Response, - ) - else: - return self.a_s.call_rpc( - srpc.r.GetEndEffectorPose.Request( - get_id(), srpc.r.GetEndEffectorPose.Request.Args(g_robot_id, g_end_effector_id, g_arm_id) - ), - srpc.r.GetEndEffectorPose.Response, - ) - - def _robot_end_effectors_get(self, g_robot_id: str, g_arm_id: str | None = None) -> srpc.r.GetEndEffectors.Response: - """Gets list of robots end effectors. - - :param g_robot_id: Id of robot - :param g_arm_id: Id of robots arm if any - - :return: Server response - """ - return self.a_s.call_rpc( - srpc.r.GetEndEffectors.Request(get_id(), srpc.r.GetEndEffectors.Request.Args(g_robot_id, g_arm_id)), - srpc.r.GetEndEffectors.Response, - ) - - def _robot_move_to_pose( - self, g_robot_id: str, g_end_effector_id, g_speed: float, g_position: Position, g_orientation: Orientation - ) -> srpc.r.MoveToPose.Response: - """Moves robot to pose. - - :param g_robot_id: Id of robot - :param g_end_effector_id: Id of robots effector - :param g_speed: Speed of robots movement (0-1) - :param g_position: target position - :param g_orientation: target orientation - - :return: Server response - """ - s_data = srpc.r.MoveToPose.Request.Args(g_robot_id, g_end_effector_id, g_speed, g_position, g_orientation) - return self.a_s.call_rpc(srpc.r.MoveToPose.Request(get_id(), s_data), srpc.r.MoveToPose.Response) - - def _robot_meta_get(self) -> srpc.r.GetRobotMeta.Response: - """Gets list of robots recognized by system. - - :return: Server response - """ - return self.a_s.call_rpc(srpc.r.GetRobotMeta.Request(get_id()), srpc.r.GetRobotMeta.Response) - - def _parse_robot_meta(self) -> list[str]: - """Parses robot types from robot meta. - - Raises: - MessageFailException - - :return: list of robot types recognized by system - """ - response = self._robot_meta_get() - if response.data is None: - raise MessageFailException("Failed to get data from server.") - return [robot.type for robot in response.data] - - def _get_robots_in_scene(self) -> list[RobotInfo]: - """Returns list of robots in scene. - - Gets list of robot types recognized by system and then - it compares it to the list of objects in scene to determine - which objects are robots. Then saves data about these robots - to list of RobotInfo classes. - - :return: Data about robots in scene - - Raises: - MessageFailException - """ - robot_types: list[str] = self._parse_robot_meta() - robot_list: list[RobotInfo] = [] - if self.cur_scene is None: - return robot_list - for obj in self.cur_scene.objects: - if obj.type in robot_types: - effectors = self._robot_end_effectors_get(obj.id) - if not effectors.result: - raise MessageFailException(effectors.messages) - if effectors.data is not None: - for effector in effectors.data: - robot_list.append(RobotInfo(obj.name, obj.id, effector, obj.type, len(effectors.data) > 1)) - return robot_list - - def _robot_get_actions(self, g_type: str) -> srpc.o.GetActions.Response: - """Gets list of actions supported by given type. - - :param g_type: Type of robot - - :return: Server response - """ - return self.a_s.call_rpc(srpc.o.GetActions.Request(get_id(), TypeArgs(g_type)), srpc.o.GetActions.Response) - - def _robot_actions_parse(self, g_type: str) -> list[RobotActions]: - """Prepares list of robot actions. - - This function gets metadate about actions of given robot type. If all of - actions parameters are valid and automatically fillable it saves it to - RobotActions class. List of returned RobotActions classes is offered - to user for choosing action stage. - - Raise: - MessageFailException - - :param g_type: Type of robot - - :return: list of actions that user can choose from - """ - meta_data = self._robot_get_actions(g_type).data - if meta_data is None: - raise MessageFailException("Failed to get data from server.") - ac_list = [] - for a in meta_data: - if a.disabled: - continue - p_list = self._robot_params_parse(a) - if p_list is None: - continue - if not isinstance(a.description, str): - a.description = "" - ac_list.append(RobotActions(a.name, a.description, p_list)) - return ac_list - - def _robot_params_parse(self, g_action: ObjectAction) -> list[ActionParameter] | None: - """Parses Metadata of parameter. - - This function reads metadata of action and checks if all - parameters are valid for this program. If all parameters are - valid it returns list of parameters with filled values. If not - it returns None - - Special condition: - If one of parameters doesn't have default value but it has - an enum of allowed values in extra, program tries to read it - and assignes the first one to parameter. - - :param g_action: Metadata of action - - :return: List of parameters - """ - param_list = [] - for param_meta in g_action.parameters: - if param_meta.default_value is None and param_meta.type != "pose": - try: - if param_meta.extra is None: - return None - extra: dict = json.loads(param_meta.extra) - try: - allowed = extra["allowed_values"] - param_list.append(ActionParameter(param_meta.name, param_meta.type, '"' + allowed[0] + '"')) - except KeyError: - return None - except json.decoder.JSONDecodeError: - return None - else: - if param_meta.default_value is None: - param_list.append(ActionParameter(param_meta.name, param_meta.type, "temp")) - else: - param_list.append(ActionParameter(param_meta.name, param_meta.type, param_meta.default_value)) - return param_list - - def _action_add( - self, g_action_point_id: str, g_name: str, g_type: str, g_params: list[ActionParameter] - ) -> srpc.p.AddAction.Response: - """Adds action to project. - - :param g_action_point_id: id of action point - :param g_name: name of new action - :param g_type: type of action -> format "robot_id/action_type" - :param g_params: list of actions parameters - - :return: Server response - """ - return self.a_s.call_rpc( - srpc.p.AddAction.Request( - get_id(), - srpc.p.AddAction.Request.Args(g_action_point_id, g_name, g_type, parameters=g_params, flows=[Flow()]), - ), - srpc.p.AddAction.Response, - ) - - def _action_point_add_by_robot( - self, g_robot_id: str, g_end_effector_id: str, g_name: str - ) -> srpc.p.AddApUsingRobot.Response: - """Adds action point to project by robot. - - :param g_robot_id: id of robot - :param g_end_effector_id: id of effector - :param g_name: name of new action point - - :return: Server response - """ - return self.a_s.call_rpc( - srpc.p.AddApUsingRobot.Request( - get_id(), srpc.p.AddApUsingRobot.Request.Args(g_robot_id, g_end_effector_id, g_name) - ), - srpc.p.AddApUsingRobot.Response, - ) - - def _logic_add(self, g_start: str, g_end: str) -> srpc.p.AddLogicItem.Response: - """Adds new logic item to project. - - :param g_start: current action id - :param g_end: next action id - - :return: Server response - """ - return self.a_s.call_rpc( - srpc.p.AddLogicItem.Request(get_id(), srpc.p.AddLogicItem.Request.Args(g_start, g_end)), - srpc.p.AddLogicItem.Response, - ) - - def _logic_update(self, g_id: str, g_start: str, g_end: str) -> srpc.p.UpdateLogicItem.Response: - """Updates logic item. - - :param g_id: updated logic item id - :param g_start: new current action id - :param g_end: new next action id - - :return: Server response - """ - return self.a_s.call_rpc( - srpc.p.UpdateLogicItem.Request(get_id(), srpc.p.UpdateLogicItem.Request.Args(g_id, g_start, g_end)), - srpc.p.UpdateLogicItem.Response, - ) - - def _find_last_logic(self, logiclist: list[LogicItem]) -> LogicItem | None: - """Searches for and returns last logic item of program. - - :param logiclist: list of logic items in project - - :return: id of last logic item, None if project has no logic items - - Raises: - ConditionFailException - """ - for li in logiclist: - if li.condition is not None: - raise ConditionFailException - start: LogicItem | None = None - for li in logiclist: - if li.start == "START": - start = li - break - if start is None: - return start - current: LogicItem = start - while 1: - if current.end == "END": - return current - next: LogicItem | None = None - for li in logiclist: - if li.start == current.end: - next = li - break - if next is None: - return current - current = next - - def _update_logic(self, logiclist: list[LogicItem], new_action: str) -> None: - """Append new actions to current program. - - If there are conditions in program, program adds new action but does - not connect it to logic. - - :param logiclist: list of logic items in project - :param new_action: id of new action - """ - try: - last: LogicItem | None = self._find_last_logic(logiclist) - except ConditionFailException: - return - - if last is None: - self._logic_add("START", new_action) - self._logic_add(new_action, "END") - else: - self._logic_update(last.id, last.start, new_action) - self._logic_add(new_action, "END") - - def _get_mov_pos( - self, g_robot_id: str, g_end_effector_id: str, g_mouse_reading: SpaceNavigator, g_arm_id: str | None = None - ) -> Pose: - """Gets robot target position. - - Gets position of robots effector and calculates new position based on mouse movement. - Sensitivity value based on testing. - - :param g_robot_id: id of robot - :param g_end_effector_id: id of robots effector - :param g_mouse_reading: input from mouse - :param g_arm_id: id of robots arm, if any - - Raises: - MessageFaileException - - :return: calculated target pose - """ - g_sensitivity: float = 0.015 - def_pos_message: srpc.r.GetEndEffectorPose.Response = self._robot_end_effector_pose( - g_robot_id, g_end_effector_id, g_arm_id - ) - if def_pos_message.data is None: - raise MessageFailException("Failed to get robot effector position") - def_pos: Pose = def_pos_message.data - def_pos.position.x += g_mouse_reading.x * g_sensitivity - def_pos.position.y += g_mouse_reading.y * g_sensitivity - def_pos.position.z += g_mouse_reading.z * g_sensitivity - - return def_pos - - def _get_rot_pos( - self, g_robot_id: str, g_end_effector_id: str, g_mouse_reading: SpaceNavigator, g_arm_id: str | None = None - ) -> Pose: - """Gets robot target rotation. - - Gets rotation of robots effector and calculates new rotation based on mouse movement. - Sensitivity value based on testing. - - :param g_robot_id: id of robot - :param g_end_effector_id: id of robots effector - :param g_mouse_reading: input from mouse - :param g_arm_id: id of robots arm, if any - - Raises: - MessageFailException - - :return: calculated target pose - """ - g_sensitivity: float = 0.015 - def_pos_message: srpc.r.GetEndEffectorPose.Response = self._robot_end_effector_pose( - g_robot_id, g_end_effector_id, g_arm_id - ) - if def_pos_message.data is None: - raise MessageFailException("Failed to get robot effector position") - def_pos: Pose = def_pos_message.data - - def_pos.orientation *= Orientation().from_rotation_vector( - g_mouse_reading.roll * g_sensitivity, - g_mouse_reading.pitch * g_sensitivity, - g_mouse_reading.yaw * g_sensitivity, - ) - return def_pos - - def _register_for_robot_event(self, g_robot_id: str, send: bool) -> srpc.r.RegisterForRobotEvent.Response: - """Registers user to receive events involving chosen robot. - - :param g_robot_id: id of robot - :param send: if user wants to receive events involving this robot - - :return: Server response - """ - enum = srpc.r.RegisterForRobotEvent.Request.Args.RegisterEnum.EEF_POSE - return self.a_s.call_rpc( - srpc.r.RegisterForRobotEvent.Request( - get_id(), srpc.r.RegisterForRobotEvent.Request.Args(g_robot_id, enum, send) - ), - srpc.r.RegisterForRobotEvent.Response, - ) - - def _prepare_poses(self, def_pose: Pose) -> list[Pose]: - """Prepares poses for highligthing robot. - - Every pose moves robot in one direction from beginning position - except down. Robot's movement to target pose shows user which robot - is selected - - :param def_pose: beginning pose of robot - - :returns: returns list of poses - """ - p1: Pose = Pose() - p2: Pose = Pose() - p3: Pose = Pose() - p4: Pose = Pose() - p5: Pose = Pose() - pos_offset: float = 0.01 - p1.position = Position(def_pose.position.x, def_pose.position.y, def_pose.position.z + pos_offset) - p2.position = Position(def_pose.position.x + pos_offset, def_pose.position.y, def_pose.position.z) - p3.position = Position(def_pose.position.x - pos_offset, def_pose.position.y, def_pose.position.z) - p4.position = Position(def_pose.position.x, def_pose.position.y + pos_offset, def_pose.position.z) - p5.position = Position(def_pose.position.x, def_pose.position.y - pos_offset, def_pose.position.z) - return [p1, p2, p3, p4, p5] - - def _highligth_robot_mechanic(self, g_robot_id: str, g_end_effector_id: str, g_arm_id: str | None = None) -> bool: - """Highlights robot. - - Robot has to move to show if he was selected. One move - and return to starting position is enough for this. But - robots movement can fail if direction is out of his bound - system is aware of this and tries to move him in every direction - if robot has moved, it returns to it's original location and - function returns true. If all possible directions, except down - fail, function returns false and program uses audio cues to show - selected robot. - - :param g_robot_id: id of robot - :param g_end_effector_id: id of robots effector - :param g_arm_id: if of robots arm, if any - - :return: if robot had moved - """ - self._register_for_robot_event(g_robot_id, True) - response = self._robot_end_effector_pose(g_robot_id, g_end_effector_id, g_arm_id) - if response.data is None: - return False - def_pos: Pose = response.data - poses: list[Pose] = self._prepare_poses(def_pos) - moved: bool = False - for pose in poses: - self._robot_move_to_pose(g_robot_id, g_end_effector_id, 0.5, pose.position, def_pos.orientation) - moved = self._wait_for_movement() - if self.program_state == ProgramPosition.WAITING: - return True - if moved: - break - if moved: - self._robot_move_to_pose(g_robot_id, g_end_effector_id, 0.5, def_pos.position, def_pos.orientation) - self._wait_for_movement() - if self.program_state == ProgramPosition.WAITING: - return True - self._register_for_robot_event(g_robot_id, False) - self._register_for_robot_event(g_robot_id, False) - return moved - - def program_loop(self) -> None: - """Main program loop. - - Based on programs position corresponding loop is executed. - - :return: - """ - self._read_text("Program started.") - while 1: - self._pop_events() - if self.program_state == ProgramPosition.WAITING: - self._waiting_loop() - if self.program_state == ProgramPosition.ROBOTMENU: - self._robot_layer_loop() - if self.program_state == ProgramPosition.ACTIONMENU: - self._action_layer_loop() - if self.program_state == ProgramPosition.ROBOTMOVEMENT: - self._robot_movement_loop() - - def _waiting_loop(self) -> None: - """Waiting loop. - - No project is open or scene has not started. Program reads - events and if project is opened and scene is started it moves to - robot choosing phase. - - :return: - """ - timer = 10 - while 1: - reading = self._mouse_read() - if timer == 10: - self._pop_events() - if self.cur_proj is not None and self.cur_scene is not None and self.scene_state: - self.program_state = ProgramPosition.ROBOTMENU - break - timer = 0 - if self.mouse_func.mouse_button_right_pressed(reading): - self.close_program() - timer += 1 - time.sleep(0.1) - - def _robot_layer_loop(self) -> None: - """Robot choosing loop. - - Program chooses first unlocked robot in program. After that it - reads input from mouse and processes user commands. Possible - outcomes: - Event ProjectClosed or SceneState stopped read: - Returns to waiting loop - User presses LMB and all robots are locked: - Audio cue, no action - User presses LMB: - Program moves to action choosing - User moves mouse left: - Next unlocked robot left of selected is selected - User moves mouse right: - Next unlocked robot right of selected is selected - User moves mouse backwards: - Audio cue for robots name is read - User presses RMB: - Program shuts down - - :return: - """ - self.loaded_robots = self._get_robots_in_scene() - index = 0 - locked: bool = True - moved: bool = False - if index != -1: - moved = self._highligth_robot_mechanic( - self.loaded_robots[index].robot_id, self.loaded_robots[index].effector_id - ) - if self.program_state == ProgramPosition.WAITING: - return - if not moved: - self._read_text(self.loaded_robots[index].get_name()) - else: - locked = False - self._read_text("All robots locked") - while 1: - reading: SpaceNavigator = self._mouse_read() - lb_pressed: bool = self.mouse_func.mouse_button_left_pressed(reading) - rb_pressed: bool = self.mouse_func.mouse_button_right_pressed(reading) - if lb_pressed: - if not locked: - self._read_text("No robot chosen") - else: - self._read_text("Chosen" + self.loaded_robots[index].get_name()) - self.current_robot = self.loaded_robots[index] - self.program_state = ProgramPosition.ACTIONMENU - return - if rb_pressed: - self.close_program() - if self.mouse_func.menu_left_movement(reading): - index = self._lock_next_left(index) - if index == -1: - self._read_text("All robots locked") - else: - moved = self._highligth_robot_mechanic( - self.loaded_robots[index].robot_id, self.loaded_robots[index].effector_id - ) - if self.program_state == ProgramPosition.WAITING: - return - if not moved: - self._read_text(self.loaded_robots[index].get_name()) - if self.mouse_func.menu_right_movement(reading): - index = self._lock_next_right(index, False) - if index == -1: - self._read_text("All robots locked") - else: - moved = self._highligth_robot_mechanic( - self.loaded_robots[index].robot_id, self.loaded_robots[index].effector_id - ) - if self.program_state == ProgramPosition.WAITING: - return - if not moved: - self._read_text(self.loaded_robots[index].get_name()) - if self.mouse_func.menu_top_movement(reading): - if index != -1: - self._read_text(self.loaded_robots[index].get_name()) - else: - self._read_text("All robots locked") - - def _lock_next_right(self, index: int, first: bool) -> int: - if self.loaded_robots is None: - return -1 - if first: - if self._lock_write(self.loaded_robots[index].robot_id).result: - return index - temp_ind: int = index - index += 1 - while index != temp_ind: - index = self._clamp_index(index, 0, self.loaded_robots.__len__() - 1) - return index - if self._lock_write(self.loaded_robots[index].robot_id).result: - return index - return -1 - - def _lock_next_left(self, index: int) -> int: - temp_ind: int = index - index -= 1 - if self.loaded_robots is None: - return index - while index != temp_ind: - index = self._clamp_index(index, 0, self.loaded_robots.__len__() - 1) - return index - if self._lock_write(self.loaded_robots[index].robot_id).result: - return index - return -1 - - def _action_layer_loop(self) -> None: - """Action choosing loop. - - Program reads input from mouse and processes user commands. - Possible outcomes: - Event ProjectClosed or SceneState stopped read: - Returns to waiting loop - User presses LMB: - Action chosen - User moves mouse left: - Next action left of selected is selected - User moves mouse right: - next action right of selected is selected - User moves mouse backwards: - Audio cue for actions description - User presses RMB: - Program goes back to robot choosing phase - Raises: - Program state exception - :return: - """ - index: int = 0 - if self.current_robot is None: - raise ProgramStateException("Actions failed to load.") - self.loaded_actions = self._robot_actions_parse(self.current_robot.robot_type) - self._read_text(self.loaded_actions[index].name) - while 1: - reading: SpaceNavigator = self._mouse_read() - lb_pressed: bool = self.mouse_func.mouse_button_left_pressed(reading) - rb_pressed: bool = self.mouse_func.mouse_button_right_pressed(reading) - if lb_pressed: - self._read_text("chosen" + self.loaded_actions[index].name) - self.current_action = self.loaded_actions[index] - self.program_state = ProgramPosition.ROBOTMOVEMENT - return - if rb_pressed: - self.current_robot = None - self.program_state = ProgramPosition.ROBOTMENU - self.loaded_actions = None - return - if self.mouse_func.menu_left_movement(reading): - index -= 1 - index = self._clamp_index(index, 0, self.loaded_actions.__len__() - 1) - self._read_text(self.loaded_actions[index].name) - if self.mouse_func.menu_right_movement(reading): - index += 1 - index = self._clamp_index(index, 0, self.loaded_actions.__len__() - 1) - self._read_text(self.loaded_actions[index].name) - if self.mouse_func.menu_top_movement(reading): - self._read_text(self.loaded_actions[index].desc) - - def _robot_movement_loop(self) -> None: - """Robot movement loop. - - Program reads input from mouse and moves chosen robot - accordingly. - Possible outcomes: - Event ProjectClosed orSceneState stopped read: - Returns to waiting loop - User presses LMB: - Program adds new action - User presses RMB: - Program goes back to action choosing phase - - Raises: - Program state exception - :return: - """ - if self.current_robot is None: - raise ProgramStateException("No robot selected.") - robot_id: str = self.current_robot.robot_id - effector_id: str = self.current_robot.effector_id - self._register_for_robot_event(robot_id, True) - while True: - reading: SpaceNavigator = self._mouse_read() - lb_pressed: bool = self.mouse_func.mouse_button_left_pressed(reading) - rb_pressed: bool = self.mouse_func.mouse_button_right_pressed(reading) - if self._treshold_check(reading.x, reading.y, reading.z, 0.1) or self._treshold_check( - reading.roll, reading.pitch, reading.yaw, 45 - ): - input_type: bool = self._get_input_type(reading) - if not input_type: - pose = self._get_mov_pos(robot_id, effector_id, reading) - else: - pose = self._get_rot_pos(robot_id, effector_id, reading) - try: - self._robot_move_to_pose(robot_id, effector_id, 0.5, pose.position, pose.orientation) - self._wait_for_movement() - except MessageFailException: - pass - if self.program_state == ProgramPosition.WAITING: - return - if lb_pressed: - self._register_for_robot_event(robot_id, False) - self._finish_action() - self.current_action = None - self.program_state = ProgramPosition.ACTIONMENU - return - if rb_pressed: - self.program_state = ProgramPosition.ACTIONMENU - self.current_action = None - self._register_for_robot_event(robot_id, False) - return - - def _get_input_type(self, reading: SpaceNavigator) -> bool: - """Get dominant input type. - - There was an error when robot tried to move and rotate - at the same time when robot was physically unable to - rotate. To prevent incorrect inputs program reads - every input and decides which is dominant translation - or rotation and does only the dominant command. User is - usually unable to translate and rotate at the same time - as well - - :param reading: input from mouse - - :return: False if translation is dominant True if - rotation is dominant - """ - move_values: list[float] = [reading.x, reading.y, reading.z] - rot_values: list[float] = [reading.roll, reading.pitch, reading.yaw] - move_max = max(max(move_values), self._mabs(min(move_values))) - rot_max = max(max(rot_values), self._mabs(min(rot_values))) - return rot_max > move_max - - def _finish_action(self): - """Program adds new action. - - Program first adds new action point and reads corresponding - events. After that it adds new action and reads events again. - And lastly it appends new action to program. - - Raises: - Program state exception - - :return: - """ - if self.cur_proj is None or self.current_robot is None or self.current_action is None: - raise ProgramStateException("Failed to complete action.") - robot_id = self.current_robot.robot_id - eff_id = self.current_robot.effector_id - action_name = self.current_action.name - point_name = "Action_" + str(self.ac_add_counter) + "_" + robot_id + "_" + eff_id + "_" + action_name - self.ac_add_counter += 1 - self._action_point_add_by_robot(robot_id, eff_id, point_name) - self._pop_events() - if self.program_state == ProgramPosition.WAITING: - return - ap: ActionPoint = self._get_added_point(point_name) - self._lock_write(ap.id, True) - orientation_id = ap.orientations[0].id - for param in self.current_action.parameters: - if param.type == "pose": - param.value = '"' + orientation_id + '"' - self._action_add( - ap.id, point_name + "ac", robot_id + "/" + self.current_action.name, self.current_action.parameters - ) - self._pop_events() - if self.program_state == ProgramPosition.WAITING or self.cur_proj is None: - return # type: ignore - self._update_logic(self.cur_proj.logic, ap.actions[0].id) - self._lock_write_unlock(ap.id) - self._pop_events() - if self.program_state == ProgramPosition.WAITING: - return # type: ignore - - def _get_added_point(self, name: str) -> ActionPoint: - """Gets newly added action point. - - :param name: Name of new action point - - :return: Added action point - """ - id = None - if self.cur_proj is None: - raise ProgramStateException("Failed to add new action point") - for ap in reversed(self.cur_proj.action_points): - if ap.name == name: - id = ap.id - break - if id is None: - raise MessageFailException("Failed to add new action point") - return next(filter(lambda ap: ap.id == id, self.cur_proj.action_points)) - - def _clamp_index(self, number: int, l_clamp: int, r_clamp: int) -> int: - """Helper function for clamping index to array size. - - :param number: value to clamp - :param l_clamp: value of left barrier - :param r_clamp: value of right barrier - - :return: clamped value - """ - if number < l_clamp: - return r_clamp - if number > r_clamp: - return l_clamp - return number - - def _mabs(self, x: float) -> float: - """Returns absolute value. - - :param x: given value - - :return: absolute value - """ - return x if x > 0 else -x - - def _treshold_check(self, x: float, y: float, z: float, threshold: float) -> bool: - """Checks if given values are bigger than the threshold. - - Used to reduce noise from reading from mouse. - - :param x: x position of mouse - :param y: y position of mouse - :param z: z position of mouse - :param treshold: treshold value - - :return: if absolute value of given value is bigger than threshold - returns True, else returns False - """ - return self._mabs(x) > threshold or self._mabs(y) > threshold or self._mabs(z) > threshold - - def _wait_for_movement(self) -> bool: - """Waits until robot reached target position. - - Reads and processes incoming events until it reads - event RobotMoveToPose had ended or failed. - - Raises: - MessageFailException - """ - while 1: - event = None - try: - event = self._get_event() - except ARServerClientException: - raise MessageFailException("No event received from server.") - if isinstance(event, RobotMoveToPose): - if event.data.move_event_type == RobotMoveToData.MoveEventType.END: - return True - if event.data.move_event_type == RobotMoveToData.MoveEventType.FAILED: - return False - else: - self._process_event(event) - - def _mouse_reading_process(self, request_queue: Queue, receive_queue: Queue) -> None: - """Loop for mouse reading process. - - Mouse reading process goes in a loop that reads input values. - If it reads input value in requst queue, it puts current mouse - input into receive queue. Method Queue.empty() exists, but it - was described as unreliable in documentation, and because of that - I use catching exceptions instead. - - :param request_queue: Queue for requests - :param receive_queue: Queue for responses - :return: - """ - mouse = MouseReader() - time.sleep(1) - while True: - reading = mouse.mouse_read() - try: - request_queue.get(block=False, timeout=0.05) - receive_queue.put(reading) - except Empty: - pass diff --git a/src/python/arcor2_3d_mouse/py.typed b/src/python/arcor2_3d_mouse/py.typed deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/python/arcor2_3d_mouse/scripts/BUILD b/src/python/arcor2_3d_mouse/scripts/BUILD deleted file mode 100644 index 0572d1448..000000000 --- a/src/python/arcor2_3d_mouse/scripts/BUILD +++ /dev/null @@ -1,8 +0,0 @@ -python_sources() - -arcor2_pex_binary( - name="mouse_launcher", - dependencies=[ - "src/python/arcor2_3d_mouse", - ], -) diff --git a/src/python/arcor2_3d_mouse/scripts/__init__.py b/src/python/arcor2_3d_mouse/scripts/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/python/arcor2_3d_mouse/scripts/mouse_launcher.py b/src/python/arcor2_3d_mouse/scripts/mouse_launcher.py deleted file mode 100644 index b58bc6de4..000000000 --- a/src/python/arcor2_3d_mouse/scripts/mouse_launcher.py +++ /dev/null @@ -1,15 +0,0 @@ -import signal - -from arcor2_3d_mouse.mouse_program import MouseProgram - - -def main() -> None: - mouse = MouseProgram(connection_string="ws://192.168.104.100:6789") - signal.signal(signal.SIGINT, mouse.close_program) - signal.signal(signal.SIGTERM, mouse.close_program) - mouse.register_user("mouse_user") - mouse.program_loop() - - -if __name__ == "__main__": - main() diff --git a/src/python/arcor2_calibration/quaternions.py b/src/python/arcor2_calibration/quaternions.py index 37ff839ad..faaaacc59 100644 --- a/src/python/arcor2_calibration/quaternions.py +++ b/src/python/arcor2_calibration/quaternions.py @@ -50,7 +50,7 @@ def average_quaternions(Q: numpy.ndarray) -> numpy.ndarray: for i in range(0, M): q = Q[i, :] # multiply q with its transposed version q' and add A - A = numpy.outer(q, q) + A + A = numpy.outer(q, q) + A # type: ignore # scale A = (1.0 / M) * A diff --git a/src/python/arcor2_fanuc/BUILD b/src/python/arcor2_fanuc/BUILD deleted file mode 100644 index 18583676a..000000000 --- a/src/python/arcor2_fanuc/BUILD +++ /dev/null @@ -1,5 +0,0 @@ -arcor2_python_distribution( - name="arcor2_fanuc", - description="ARCOR2 Fanuc Service", - binaries={"arcor2_fanuc": "src/python/arcor2_fanuc/scripts:fanuc"}, -) diff --git a/src/python/arcor2_fanuc/CHANGELOG.md b/src/python/arcor2_fanuc/CHANGELOG.md deleted file mode 100644 index e273c0ecd..000000000 --- a/src/python/arcor2_fanuc/CHANGELOG.md +++ /dev/null @@ -1,34 +0,0 @@ -# Changelog - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - -## [0.4.0] - 2024-04-11 - -### Changed - -- Updated dependencies, switched to Python 3.11. - -## [0.3.0] - 2022-10-28 - -### Changed - -- Switched to Python 3.10, updated dependencies. - -## [0.2.0] - WIP - -### Changed - -- **BREAKING**: Implement new error handling flow. Error codes of **every** endpoint were replaced with error - types as described in swagger documentation. - -- Update API description. - -### Added - -- New exception classes - -## [0.1.0] - 2022-05-23 - -### Added -- Initial release of the Fanuc Service - REST API based on `fanucpy` library. -- The package also contains universal ObjectType and a URDF model for LRMate 200iD/7L (adapted from ROS Industrial). diff --git a/src/python/arcor2_fanuc/README.md b/src/python/arcor2_fanuc/README.md deleted file mode 100644 index ffef99e3b..000000000 --- a/src/python/arcor2_fanuc/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# arcor2_fanuc - -For the server to work, there must be a running [MAPPDK driver](https://github.com/torayeff/fanucpy) on the robot. So far, it has been tested with LRMate 200iD/7L (for which there is also a model, adapted from [ROS Industrial](https://github.com/ros-industrial/fanuc)), but it should work with any robot driven by the R-30iB Mate Plus Controller. - -## Environment variables - -- `ARCOR2_FANUC_SERVICE_NAME` - set the service name ("Fanuc Service" by default). -- `ARCOR2_FANUC_SERVICE_URL=http://0.0.0.0:5027` - by default, the service listens on port 5027. -- `ARCOR2_FANUC_ROBOT_HOST` - ip address of the robot ("192.168.104.140" by default). -- `ARCOR2_FANUC_ROBOT_PORT` - port of the MAPPDK server (18735 by default). -- `ARCOR2_FANUC_EEF_DO_NUM` - digital output which controls the end effector (1 by default). -- `ARCOR2_FANUC_MAX_VELOCITY` - max TCP velocity (mm/s, 6000 by default). -- `ARCOR2_FANUC_MAX_ACCELERATION` - max TCP acceleration (mm/s-2, 100 by default). -- `ARCOR2_FANUC_Z_AXIS_OFFSET` - offset between base and origin of robot's world coordinate system, which is at J2 (330 by default). - `ARCOR2_FANUC_DEBUG=1` - turns on debug logging. \ No newline at end of file diff --git a/src/python/arcor2_fanuc/VERSION b/src/python/arcor2_fanuc/VERSION deleted file mode 100644 index 60a2d3e96..000000000 --- a/src/python/arcor2_fanuc/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.4.0 \ No newline at end of file diff --git a/src/python/arcor2_fanuc/__init__.py b/src/python/arcor2_fanuc/__init__.py deleted file mode 100644 index 2e49a73b1..000000000 --- a/src/python/arcor2_fanuc/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -import os - -from arcor2 import package_version - -_ROOT = os.path.abspath(os.path.dirname(__file__)) - - -def version() -> str: - return package_version(__name__) - - -def get_data(path: str) -> str: - return os.path.join(_ROOT, "data", path) diff --git a/src/python/arcor2_fanuc/data/BUILD b/src/python/arcor2_fanuc/data/BUILD deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/python/arcor2_fanuc/data/urdf/BUILD b/src/python/arcor2_fanuc/data/urdf/BUILD deleted file mode 100644 index 674b75b33..000000000 --- a/src/python/arcor2_fanuc/data/urdf/BUILD +++ /dev/null @@ -1,10 +0,0 @@ -resources( - name="fanuc_lrmate200id7l_urdf", - sources=[ - "fanuc_lrmate200id7l.urdf", - "fanuc_lrmate200id_support/meshes/lrmate200id/collision/*.stl", - "fanuc_lrmate200id_support/meshes/lrmate200id/visual/*.stl", - "fanuc_lrmate200id_support/meshes/lrmate200id7l/collision/*.stl", - "fanuc_lrmate200id_support/meshes/lrmate200id7l/visual/*.stl", - ], -) diff --git a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id7l.urdf b/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id7l.urdf deleted file mode 100644 index 4703ac5aa..000000000 --- a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id7l.urdf +++ /dev/null @@ -1,202 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/base_link.stl b/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/base_link.stl deleted file mode 100644 index 10e4ac169..000000000 --- a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/base_link.stl +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e7d6f17f3012445ab8bacd18885db9437646b131253b92ac7f880dcc03267642 -size 120284 diff --git a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_1.stl b/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_1.stl deleted file mode 100644 index f9a3912ae..000000000 --- a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_1.stl +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:353992336fd3daaca21d8adc28bcc5b4e64052df262f8e40738c1b147bc44db3 -size 228884 diff --git a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_2.stl b/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_2.stl deleted file mode 100644 index b1f18562e..000000000 --- a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_2.stl +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ae7664e6c422d33f0bd2563f8e9f2a25281b1c992e102c1c4bffd0e469491b27 -size 99884 diff --git a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_3.stl b/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_3.stl deleted file mode 100644 index fa43300a0..000000000 --- a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_3.stl +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:dc1a5d033ea34ca5fdc1b1305eec3993fa63afb715e69e9ee934315de2fa07ed -size 292584 diff --git a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_4.stl b/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_4.stl deleted file mode 100644 index c748f3a7e..000000000 --- a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_4.stl +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:43b004eec473fd1c9e6bd92901004fd661bfa2b3bfb7f412206c51dc0f81c354 -size 179684 diff --git a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_5.stl b/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_5.stl deleted file mode 100644 index 82bb55350..000000000 --- a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_5.stl +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4ece3a0851d58a1bbf50a917b80659ad6a3b90083f7def9db6fd230514b0dc5f -size 162384 diff --git a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_6.stl b/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_6.stl deleted file mode 100644 index e08655122..000000000 --- a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/collision/link_6.stl +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:77b9b50f1c2edfd5384aa88b2371807640e638e5d2b597b5c7ecffe9a897a720 -size 19584 diff --git a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/base_link.stl b/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/base_link.stl deleted file mode 100644 index 10e4ac169..000000000 --- a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/base_link.stl +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e7d6f17f3012445ab8bacd18885db9437646b131253b92ac7f880dcc03267642 -size 120284 diff --git a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_1.stl b/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_1.stl deleted file mode 100644 index f9a3912ae..000000000 --- a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_1.stl +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:353992336fd3daaca21d8adc28bcc5b4e64052df262f8e40738c1b147bc44db3 -size 228884 diff --git a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_2.stl b/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_2.stl deleted file mode 100644 index a51d40c1a..000000000 --- a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_2.stl +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:dee03cd4b0ad3a98f3d1afc06356f4cf03f087d86f987cba0dcf33ae4e59b725 -size 253784 diff --git a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_3.stl b/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_3.stl deleted file mode 100644 index fa43300a0..000000000 --- a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_3.stl +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:dc1a5d033ea34ca5fdc1b1305eec3993fa63afb715e69e9ee934315de2fa07ed -size 292584 diff --git a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_4.stl b/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_4.stl deleted file mode 100644 index c748f3a7e..000000000 --- a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_4.stl +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:43b004eec473fd1c9e6bd92901004fd661bfa2b3bfb7f412206c51dc0f81c354 -size 179684 diff --git a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_5.stl b/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_5.stl deleted file mode 100644 index 82bb55350..000000000 --- a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_5.stl +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4ece3a0851d58a1bbf50a917b80659ad6a3b90083f7def9db6fd230514b0dc5f -size 162384 diff --git a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_6.stl b/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_6.stl deleted file mode 100644 index e08655122..000000000 --- a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id/visual/link_6.stl +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:77b9b50f1c2edfd5384aa88b2371807640e638e5d2b597b5c7ecffe9a897a720 -size 19584 diff --git a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id7l/collision/link_2.stl b/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id7l/collision/link_2.stl deleted file mode 100644 index 3bd294c87..000000000 --- a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id7l/collision/link_2.stl +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:89a761f3d0c7a724ceca75390a6ec75aa9103659220e200fc4357cbd737a9be6 -size 159384 diff --git a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id7l/collision/link_4.stl b/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id7l/collision/link_4.stl deleted file mode 100644 index 9fba8f8ee..000000000 --- a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id7l/collision/link_4.stl +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:26f7f2b13f3f86f09888203c10a51d5f3f7fb2f22b710575d1dd2d6769814e82 -size 122784 diff --git a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id7l/visual/link_2.stl b/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id7l/visual/link_2.stl deleted file mode 100644 index 3bd294c87..000000000 --- a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id7l/visual/link_2.stl +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:89a761f3d0c7a724ceca75390a6ec75aa9103659220e200fc4357cbd737a9be6 -size 159384 diff --git a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id7l/visual/link_4.stl b/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id7l/visual/link_4.stl deleted file mode 100644 index 9fba8f8ee..000000000 --- a/src/python/arcor2_fanuc/data/urdf/fanuc_lrmate200id_support/meshes/lrmate200id7l/visual/link_4.stl +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:26f7f2b13f3f86f09888203c10a51d5f3f7fb2f22b710575d1dd2d6769814e82 -size 122784 diff --git a/src/python/arcor2_fanuc/exceptions.py b/src/python/arcor2_fanuc/exceptions.py deleted file mode 100644 index e033e4274..000000000 --- a/src/python/arcor2_fanuc/exceptions.py +++ /dev/null @@ -1,21 +0,0 @@ -from arcor2.flask import FlaskException, General, WebApiErrorFactory -from arcor2_fanuc import __name__ as package_name - - -class FanucException(FlaskException): - service = package_name - - -class FanucGeneral(FanucException): - description = General.description - - -class NotFound(FanucException): - description = "Occurs when something is not found." - - -class StartError(FanucException): - description = "Occurs when start condition is not met." - - -WebApiError = WebApiErrorFactory.get_class(FanucGeneral, StartError, NotFound) diff --git a/src/python/arcor2_fanuc/object_types/BUILD b/src/python/arcor2_fanuc/object_types/BUILD deleted file mode 100644 index 2181f04b3..000000000 --- a/src/python/arcor2_fanuc/object_types/BUILD +++ /dev/null @@ -1 +0,0 @@ -python_sources() \ No newline at end of file diff --git a/src/python/arcor2_fanuc/object_types/__init__.py b/src/python/arcor2_fanuc/object_types/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/python/arcor2_fanuc/object_types/fake_fanuc.py b/src/python/arcor2_fanuc/object_types/fake_fanuc.py deleted file mode 100644 index 3188c1116..000000000 --- a/src/python/arcor2_fanuc/object_types/fake_fanuc.py +++ /dev/null @@ -1,52 +0,0 @@ -from arcor2.data.common import ActionMetadata, Joint, Pose -from arcor2.object_types.abstract import Robot - - -class FakeFanuc(Robot): - _ABSTRACT = False - urdf_package_name = "fanuc_lrmate200id7l.zip" - - def get_end_effectors_ids(self) -> set[str]: - return {"default"} - - def grippers(self) -> set[str]: - return set("default") - - def suctions(self) -> set[str]: - return set() - - def get_end_effector_pose(self, end_effector_id: str) -> Pose: - return Pose() - - def move_to_pose( - self, end_effector_id: str, target_pose: Pose, speed: float, safe: bool = True, linear: bool = True - ) -> None: - pass - - def move( - self, - pose: Pose, - velocity: float = 50.0, - acceleration: float = 50.0, - safe: bool = True, - linear: bool = False, - *, - an: None | str = None, - ) -> None: - """Moves the robot's end-effector to a specific pose. - - :param pose: Target pose. - :param velocity: Speed of move (percent). - :param acceleration: Acceleration of move (percent). - :param safe: When set, the robot will try to avoid collisions. - :param linear: - :return: - """ - - assert 0.0 <= velocity <= 100.0 - assert 0.0 <= acceleration <= 100.0 - - def robot_joints(self, include_gripper: bool = False) -> list[Joint]: - return [Joint(f"joint_{x + 1}", 0.0) for x in range(6)] - - move.__action__ = ActionMetadata() # type: ignore diff --git a/src/python/arcor2_fanuc/object_types/fanuc.py b/src/python/arcor2_fanuc/object_types/fanuc.py deleted file mode 100644 index 710c345c0..000000000 --- a/src/python/arcor2_fanuc/object_types/fanuc.py +++ /dev/null @@ -1,181 +0,0 @@ -from dataclasses import dataclass -from typing import cast - -from arcor2 import rest -from arcor2.data.common import ActionMetadata, Joint, Pose -from arcor2.object_types.abstract import Robot, RobotException, Settings - - -@dataclass -class FanucSettings(Settings): - url: str = "http://fanuc-demo-robot:5027" - - -class Fanuc(Robot): - def __init__(self, obj_id: str, name: str, pose: Pose, settings: FanucSettings) -> None: - super(Fanuc, self).__init__(obj_id, name, pose, settings) - self._start() - - def _started(self) -> bool: - return rest.call(rest.Method.GET, f"{self.settings.url}/state/started", return_type=bool) - - def _stop(self) -> None: - rest.call(rest.Method.PUT, f"{self.settings.url}/state/stop") - - def _start(self) -> None: - if self._started(): - self._stop() - - rest.call( - rest.Method.PUT, - f"{self.settings.url}/state/start", - body=self.pose, - ) - - @property - def settings(self) -> FanucSettings: - return cast(FanucSettings, super(Fanuc, self).settings) - - def cleanup(self): - self._stop() - - def get_end_effectors_ids(self) -> set[str]: - return {"default"} - - def grippers(self) -> set[str]: - return set("default") - - def suctions(self) -> set[str]: - return set() - - def get_end_effector_pose(self, end_effector_id: str) -> Pose: - return rest.call(rest.Method.GET, f"{self.settings.url}/eef/pose", return_type=Pose) - - def move_to_pose( - self, end_effector_id: str, target_pose: Pose, speed: float, safe: bool = True, linear: bool = True - ) -> None: - self.move(target_pose, speed * 100, 50.0, safe, linear) - - def move( - self, - pose: Pose, - velocity: float = 50.0, - acceleration: float = 50.0, - safe: bool = True, - linear: bool = False, - *, - an: None | str = None, - ) -> None: - """Moves the robot's end-effector to a specific pose. - - :param pose: Target pose. - :param velocity: Speed of move (percent). - :param acceleration: Acceleration of move (percent). - :param safe: When set, the robot will try to avoid collisions. - :param linear: - :return: - """ - - assert 0.0 <= velocity <= 100.0 - assert 0.0 <= acceleration <= 100.0 - - with self._move_lock: - rest.call( - rest.Method.PUT, - f"{self.settings.url}/eef/pose", - body=pose, - params={"velocity": velocity, "acceleration": acceleration, "safe": safe, "linear": linear}, - ) - - def gripper_close(self, *, an: None | str = None) -> None: - """Close the gripper.""" - rest.call(rest.Method.PUT, f"{self.settings.url}/gripper", params={"state": False}) - - def gripper_open(self, *, an: None | str = None) -> None: - """Open the gripper.""" - - rest.call(rest.Method.PUT, f"{self.settings.url}/gripper", params={"state": True}) - - def gripper_state(self, *, an: None | str = None) -> bool: - """Checks whether the gripper is open. - - :param an: - :return: - """ - - return rest.call(rest.Method.GET, f"{self.settings.url}/gripper", return_type=bool) - - def pick( - self, - pick_pose: Pose, - velocity: float = 50.0, - vertical_offset: float = 0.05, - safe_approach: bool = True, - safe_pick: bool = False, - *, - an: None | str = None, - ) -> None: - """Picks an item from given pose. - - :param pick_pose: Where to pick an object. - :param velocity: Speed of move (percent). - :param vertical_offset: Vertical offset for pre/post pick pose. - :param safe_approach: Safe approach to the pre-pick position. - :param safe_pick: Safe picking movements. - :return: - """ - - assert 0.0 <= velocity <= 100.0 - - self.gripper_open() - - pick_pose.position.z += vertical_offset - self.move(pick_pose, velocity, safe=safe_approach) # pre-pick pose - pick_pose.position.z -= vertical_offset - self.move(pick_pose, velocity, safe=safe_pick, linear=True) # pick pose - self.gripper_close() - pick_pose.position.z += vertical_offset - self.move(pick_pose, velocity, safe=False, linear=True) # back to pre-pick pose - - def place( - self, - place_pose: Pose, - velocity: float = 50.0, - vertical_offset: float = 0.05, - safe_approach: bool = True, - safe_place: bool = False, - *, - an: None | str = None, - ) -> None: - """Places an item to a given pose. - - :param place_pose: Where to place the object. - :param velocity: Speed of move (percent). - :param vertical_offset: Vertical offset for pre/post place pose. - :param safe_approach: Safe approach to the pre-pick position. - :param safe_place: Safe placement movements. - :return: - """ - - assert 0.0 <= velocity <= 100.0 - - if self.gripper_state(): - raise RobotException("Gripper is opened.") - - place_pose.position.z += vertical_offset - self.move(place_pose, velocity, safe=safe_approach) # pre-place pose - place_pose.position.z -= vertical_offset - self.move(place_pose, velocity, safe=safe_place, linear=True) # place pose - self.gripper_open() - place_pose.position.z += vertical_offset - self.move(place_pose, velocity, safe=False, linear=True) # back to pre-place pose - - def robot_joints(self, include_gripper: bool = False) -> list[Joint]: - return rest.call(rest.Method.GET, f"{self.settings.url}/joints", list_return_type=Joint) - - move.__action__ = ActionMetadata() # type: ignore - gripper_open.__action__ = ActionMetadata() # type: ignore - gripper_close.__action__ = ActionMetadata() # type: ignore - gripper_state.__action__ = ActionMetadata() # type: ignore - pick.__action__ = ActionMetadata(composite=True) # type: ignore - place.__action__ = ActionMetadata(composite=True) # type: ignore diff --git a/src/python/arcor2_fanuc/object_types/fanuc_lrmate200id7l.py b/src/python/arcor2_fanuc/object_types/fanuc_lrmate200id7l.py deleted file mode 100644 index 148c1438e..000000000 --- a/src/python/arcor2_fanuc/object_types/fanuc_lrmate200id7l.py +++ /dev/null @@ -1,6 +0,0 @@ -from .fanuc import Fanuc # noqa:ABS101 - - -class FanucLRMate200id7L(Fanuc): - _ABSTRACT = False - urdf_package_name = "fanuc_lrmate200id7l.zip" diff --git a/src/python/arcor2_fanuc/py.typed b/src/python/arcor2_fanuc/py.typed deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/python/arcor2_fanuc/scripts/BUILD b/src/python/arcor2_fanuc/scripts/BUILD deleted file mode 100644 index fe18057c7..000000000 --- a/src/python/arcor2_fanuc/scripts/BUILD +++ /dev/null @@ -1,4 +0,0 @@ -python_sources() - -arcor2_pex_binary(name="fanuc") -arcor2_pex_binary(name="upload_objects", dependencies=["src/python/arcor2_fanuc/data/urdf:fanuc_lrmate200id7l_urdf"]) diff --git a/src/python/arcor2_fanuc/scripts/__init__.py b/src/python/arcor2_fanuc/scripts/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/python/arcor2_fanuc/scripts/fanuc.py b/src/python/arcor2_fanuc/scripts/fanuc.py deleted file mode 100644 index e87934bad..000000000 --- a/src/python/arcor2_fanuc/scripts/fanuc.py +++ /dev/null @@ -1,582 +0,0 @@ -import argparse -import copy -import logging -import math -import os -import socket -import time -from dataclasses import dataclass, field -from functools import wraps -from threading import Lock, Thread - -import requests -from fanucpy import Robot -from flask import Response, jsonify, request - -from arcor2 import env -from arcor2 import transformations as tr -from arcor2.clients import scene_service -from arcor2.data.common import Joint, Orientation, Pose, Position -from arcor2.data.scene import LineCheck -from arcor2.exceptions import Arcor2Exception -from arcor2.flask import RespT, create_app, run_app -from arcor2.helpers import port_from_url -from arcor2.logging import get_logger -from arcor2_fanuc import version -from arcor2_fanuc.exceptions import FanucGeneral, NotFound, StartError, WebApiError - -logger = get_logger(__name__) - -SERVICE_NAME = os.getenv("ARCOR2_FANUC_SERVICE_NAME", "Fanuc Web API") -URL = os.getenv("ARCOR2_FANUC_SERVICE_URL", "http://localhost:5027") -ROBOT_HOST = os.getenv("ARCOR2_FANUC_ROBOT_HOST", "192.168.104.140") -ROBOT_PORT = env.get_int("ARCOR2_FANUC_ROBOT_PORT", 18735) -EEF_DO_NUM = env.get_int("ARCOR2_FANUC_EEF_DO_NUM", 1) -MAX_VELOCITY = env.get_int("ARCOR2_FANUC_MAX_VELOCITY", 6000) -MAX_ACCELERATION = env.get_int("ARCOR2_FANUC_MAX_ACCELERATION", 100) -Z_AXIS_OFFSET = env.get_float("ARCOR2_FANUC_Z_AXIS_OFFSET", 330.0) # world origin is at j1/j2 - -app = create_app(__name__) - - -class ThreadSafeRobot(Robot): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self._socket_lock = Lock() - self._session = requests.session() - self._pos_joints_thread = Thread(target=self._pos_joints_thread_run, args=()) - self._pos_joints_thread.daemon = True - self._running = True - - self._data_lock = Lock() - self._req_rate = 0.1 - self._cur_pos: list[float] = [0] * 6 - self._cur_joints: list[float] = [0] * 6 - - def connect(self) -> None: - try: - res = self._session.get(f"http://{ROBOT_HOST}/MD/PRGSTATE.DG") - except requests.RequestException: - logger.exception(f"Failed to contact robot at {ROBOT_HOST}.") - raise Arcor2Exception("Failed to contact robot.") - - for line in res.text.splitlines(): - # MAPPDK_SERVER RUNNING @ 49 in OPEN_COMM of MAPPDK_SERVER - # MAPPDK_SERVER RUNNING @ 61 in MAPPDK_SERVER of MAPPDK_SERVER - # MAPPDK_SERVER status = ABORTED - - if "MAPPDK_SERVER" in line: - if "RUNNING" in line: - if "OPEN_COMM" not in line: - raise Arcor2Exception("Someone is already connected to the robot.") - break # good! - elif "ABORTED" in line: - raise Arcor2Exception("MAPPDK not running.") - else: - raise Arcor2Exception("MAPPDK - unhandled state.") - else: - raise Arcor2Exception("MAPPDK program not found.") - - super().connect() - self._pos_joints_thread.start() - - def _pos_joints_thread_run(self) -> None: - last = time.monotonic() - logger.info("Position/joints thread started.") - - while self._running: - pos: list[float] = [] - joints: list[float] = [] - found = False - - r = self._session.get(f"http://{ROBOT_HOST}/MD/CURPOS.DG") - - for line in r.text.splitlines(): - if len(joints) < 6 and line.startswith("Joint"): - joints.append(float(line.split(" ")[-1])) - - if len(pos) < 6: - if line.startswith("CURRENT WORLD POSITION"): - found = True - if not found: - continue - - if line[1] == ":": - pos.append(float(line.split(" ")[-1])) - - if len(joints) == 6 and len(pos) == 6: - break - - assert len(pos) == 6 - assert len(joints) == 6 - - with self._data_lock: - self._cur_pos = pos - self._cur_joints = joints - - now = time.monotonic() - time_to_sleep = max(self._req_rate - (now - last), 0) - # logger.debug(f"The actual stuff took: {now - last:.3f}s, going to sleep for {time_to_sleep:.3f}s.") - time.sleep(time_to_sleep) - last = time.monotonic() - - logger.info("Position/joints thread finished.") - - def disconnect(self) -> None: - self._running = False - super().disconnect() - - def get_curpos(self) -> list[float]: - with self._data_lock: - return self._cur_pos.copy() - - def get_curjpos(self) -> list[float]: - with self._data_lock: - return self._cur_joints.copy() - - def send_cmd(self, cmd): - try: - with self._socket_lock: - return super().send_cmd(cmd) - except socket.timeout: - logger.exception("Communication with the robot timeouted.") - raise Arcor2Exception("Robot not responding.") - except OSError: - logger.exception("Socket broken?") - raise Arcor2Exception("Connection with the robot broken.") - except Exception as e: - if str(e).strip() == "position-is-not-reachable": - raise Arcor2Exception("Position not reachable.") - - logger.exception("Some bad dirty exception...") - - raise Arcor2Exception(str(e)) from e - - -@dataclass -class Globals: - robot: None | ThreadSafeRobot = None - pose: Pose = field(default_factory=Pose) - - -gl = Globals() - - -def vals_to_pose(vals: list[float]) -> Pose: - assert len(vals) == 6 - - # https://doc.rc-cube.com/v21.10/en/pose_format_fanuc.html - wr = math.radians(vals[3]) - pr = math.radians(vals[4]) - rr = math.radians(vals[5]) - - x = math.cos(rr / 2) * math.cos(pr / 2) * math.sin(wr / 2) - math.sin(rr / 2) * math.sin(pr / 2) * math.cos(wr / 2) - y = math.cos(rr / 2) * math.sin(pr / 2) * math.cos(wr / 2) + math.sin(rr / 2) * math.cos(pr / 2) * math.sin(wr / 2) - z = math.sin(rr / 2) * math.cos(pr / 2) * math.cos(wr / 2) - math.cos(rr / 2) * math.sin(pr / 2) * math.sin(wr / 2) - w = math.cos(rr / 2) * math.cos(pr / 2) * math.cos(wr / 2) + math.sin(rr / 2) * math.sin(pr / 2) * math.sin(wr / 2) - - return Pose( - Position(vals[0] / 1000.0, vals[1] / 1000.0, (vals[2] + Z_AXIS_OFFSET) / 1000.0), Orientation(x, y, z, w) - ) - - -def pose_to_vals(pose: Pose) -> list[float]: - # https://doc.rc-cube.com/v21.10/en/pose_format_fanuc.html - # ...P and W are swapped! - w = math.degrees( - math.atan2( - 2 * (pose.orientation.w * pose.orientation.z + pose.orientation.x * pose.orientation.y), - 1 - 2 * (pose.orientation.y**2 + pose.orientation.z**2), - ) - ) - p = math.degrees(math.asin(2 * (pose.orientation.w * pose.orientation.y - pose.orientation.z * pose.orientation.x))) - r = math.degrees( - math.atan2( - 2 * (pose.orientation.w * pose.orientation.x + pose.orientation.y * pose.orientation.z), - 1 - 2 * (pose.orientation.x**2 + pose.orientation.y**2), - ) - ) - - pos: list[float] = [pose.position.x * 1000, pose.position.y * 1000, pose.position.z * 1000 - Z_AXIS_OFFSET] - pos.extend([r, p, w]) - - assert len(pos) == 6 - - return pos - - -def started() -> bool: - return gl.robot is not None - - -def requires_started(f): - @wraps(f) - def wrapped(*args, **kwargs): - if not started(): - raise StartError("Not started.") - return f(*args, **kwargs) - - return wrapped - - -@app.route("/state/start", methods=["PUT"]) -def put_start() -> RespT: - """Start the robot. - --- - put: - description: Start the robot. - tags: - - State - requestBody: - content: - application/json: - schema: - $ref: Pose - responses: - 204: - description: Ok - 500: - description: "Error types: **General**, **FanucGeneral**, **StartError**." - content: - application/json: - schema: - $ref: WebApiError - """ - - if started(): - raise StartError("Already started.") - - if not isinstance(request.json, dict): - raise FanucGeneral("Body should be a JSON dict containing Pose.") - - pose = Pose.from_dict(request.json) - - robot = ThreadSafeRobot("Fanuc", ROBOT_HOST, ROBOT_PORT, ee_DO_type="RDO", ee_DO_num=EEF_DO_NUM) - - try: - robot.connect() - except ConnectionRefusedError as e: - logger.error(f"Failed to connect to {ROBOT_HOST}:{ROBOT_PORT}. {str(e)}") - raise FanucGeneral("Maybe the robot is not running?") - - gl.robot = robot - gl.pose = pose - - logger.info(f"Robot initialized at {pose}") - - # TODO illegal port number - # gl.robot.gripper(gl.gripper) # open a gripper, so we have a known state - - return Response(status=204) - - -@app.route("/state/stop", methods=["PUT"]) -@requires_started -def put_stop() -> RespT: - """Stop the robot. - --- - put: - description: Stop the robot. - tags: - - State - responses: - 204: - description: Ok - 500: - description: "Error types: **General**." - content: - application/json: - schema: - $ref: WebApiError - """ - - assert gl.robot is not None - gl.robot.disconnect() - gl.robot = None - return Response(status=204) - - -@app.route("/state/started", methods=["GET"]) -def get_started() -> RespT: - """Get the current state. - --- - get: - description: Get the current state. - tags: - - State - responses: - 200: - description: Ok - content: - application/json: - schema: - type: boolean - 500: - description: "Error types: **General**, **StartError**." - content: - application/json: - schema: - $ref: WebApiError - """ - - return jsonify(started()) - - -@app.route("/eef/pose", methods=["GET"]) -@requires_started -def get_eef_pose() -> RespT: - """Get the EEF pose. - --- - get: - description: Get the EEF pose. - tags: - - Robot - responses: - 200: - description: Ok - content: - application/json: - schema: - $ref: Pose - 500: - description: "Error types: **General**." - content: - application/json: - schema: - $ref: WebApiError - """ - - assert gl.robot is not None - return jsonify(tr.make_pose_abs(gl.pose, vals_to_pose(gl.robot.get_curpos()))), 200 - - -@app.route("/eef/pose", methods=["PUT"]) -@requires_started -def put_eef_pose() -> RespT: - """Set the EEF pose. - --- - put: - description: Set the EEF pose. - tags: - - Robot - parameters: - - name: velocity - in: query - schema: - type: number - format: integer - minimum: 0 - maximum: 100 - - name: acceleration - in: query - schema: - type: number - format: integer - minimum: 0 - maximum: 100 - - name: cnt_val - in: query - schema: - type: number - format: integer - minimum: 0 - maximum: 100 - - in: query - name: linear - schema: - type: boolean - default: false - - in: query - name: safe - schema: - type: boolean - default: false - requestBody: - content: - application/json: - schema: - $ref: Pose - responses: - 204: - description: Ok - 500: - description: "Error types: **General**, **FanucGeneral**, **StartError**, **NotFound**." - content: - application/json: - schema: - $ref: WebApiError - """ - - assert gl.robot is not None - - if not isinstance(request.json, dict): - raise FanucGeneral("Body should be a JSON dict containing Pose.") - - abs_pose = Pose.from_dict(request.json) - pose = tr.make_pose_rel(gl.pose, abs_pose) - velocity = int(float(request.args.get("velocity", default=50))) * MAX_VELOCITY / 100 - acceleration = int(float(request.args.get("acceleration", default=50))) * MAX_ACCELERATION / 100 - cnt_val = int(float(request.args.get("cnt_val", default=50))) - linear = request.args.get("linear") == "true" - safe = request.args.get("safe") == "true" - - logger.info(f"Moving to {pose}, velocity: {velocity}, acceleration: {acceleration}, linear: {linear}, safe: {safe}") - - if safe: - cp = tr.make_pose_abs(gl.pose, vals_to_pose(gl.robot.get_curpos())) - - ip1 = copy.deepcopy(cp) - ip2 = copy.deepcopy(abs_pose) - - for _attempt in range(20): - res = scene_service.line_check(LineCheck(ip1.position, ip2.position)) - - if res.safe: - break - - if linear: - raise FanucGeneral("There might be a collision.") - - ip1.position.z += 0.01 - ip2.position.z += 0.01 - - else: - raise NotFound("Can't find safe path.") - - logger.debug(f"Collision avoidance attempts: {_attempt}") - - if _attempt > 0: - gl.robot.move("pose", pose_to_vals(tr.make_pose_rel(gl.pose, ip1)), velocity, acceleration, cnt_val, linear) - gl.robot.move("pose", pose_to_vals(tr.make_pose_rel(gl.pose, ip2)), velocity, acceleration, cnt_val, linear) - - logger.debug(f"curpos: {gl.robot.get_curpos()}") - logger.debug(f"tarpos: {pose_to_vals(pose)}") - - gl.robot.move("pose", pose_to_vals(pose), velocity, acceleration, cnt_val, linear) - return Response(status=204) - - -@app.route("/joints", methods=["GET"]) -@requires_started -def get_joints() -> RespT: - """Get the current state. - --- - get: - description: Get the current state. - tags: - - Robot - responses: - 200: - description: Ok - content: - application/json: - schema: - type: array - items: - $ref: Joint - 500: - description: "Error types: **General**, **StartError**." - content: - application/json: - schema: - $ref: WebApiError - """ - - assert gl.robot is not None - joints = gl.robot.get_curjpos() - - # see https://www.robot-forum.com/robotforum/thread/22888-fanuc-j2-j3-relationship/ for explanation - joints[2] += joints[1] - - return jsonify([Joint(f"joint_{idx + 1}", math.radians(value)).to_dict() for idx, value in enumerate(joints)]) - - -@app.route("/gripper", methods=["PUT"]) -@requires_started -def put_gripper() -> RespT: - """Controls the gripper. - --- - put: - description: Controls the gripper. - tags: - - Robot - parameters: - - in: query - name: state - schema: - type: boolean - default: false - responses: - 204: - description: Ok - 500: - description: "Error types: **General**, **StartError**." - content: - application/json: - schema: - $ref: WebApiError - """ - - assert gl.robot is not None - - state = request.args.get("state") == "true" - logger.info(f"{'Opening' if state else 'Closing'} the gripper.") - gl.robot.gripper(state) - return Response(status=204) - - -@app.route("/gripper", methods=["GET"]) -@requires_started -def get_gripper() -> RespT: - """Get gripper state. - --- - put: - description: Get gripper state. - tags: - - Robot - responses: - 200: - description: Ok - content: - application/json: - schema: - type: boolean - 500: - description: "Error types: **General**, **StartError**." - content: - application/json: - schema: - $ref: WebApiError - """ - - assert gl.robot is not None - return jsonify(bool(gl.robot.get_rdo(EEF_DO_NUM))) - - -def main() -> None: - parser = argparse.ArgumentParser(description=SERVICE_NAME) - parser.add_argument("-s", "--swagger", action="store_true", default=False) - - parser.add_argument( - "-d", - "--debug", - help="Set logging level to debug.", - action="store_const", - const=logging.DEBUG, - default=logging.DEBUG if env.get_bool("ARCOR2_FANUC_DEBUG") else logging.INFO, - ) - - args = parser.parse_args() - logger.setLevel(args.debug) - - if not args.swagger: - scene_service.wait_for() - - run_app(app, SERVICE_NAME, version(), port_from_url(URL), [Pose, Joint, WebApiError], args.swagger) - - if gl.robot: - gl.robot.disconnect() - - -if __name__ == "__main__": - main() diff --git a/src/python/arcor2_fanuc/scripts/upload_objects.py b/src/python/arcor2_fanuc/scripts/upload_objects.py deleted file mode 100644 index db32ed4f0..000000000 --- a/src/python/arcor2_fanuc/scripts/upload_objects.py +++ /dev/null @@ -1,15 +0,0 @@ -from arcor2.object_types.upload import Urdf, upload_def -from arcor2_fanuc import get_data -from arcor2_fanuc.object_types.fake_fanuc import FakeFanuc -from arcor2_fanuc.object_types.fanuc import Fanuc -from arcor2_fanuc.object_types.fanuc_lrmate200id7l import FanucLRMate200id7L - - -def main() -> None: - upload_def(Fanuc) - upload_def(FanucLRMate200id7L, urdf=Urdf(get_data("urdf"), FanucLRMate200id7L.urdf_package_name)) - upload_def(FakeFanuc, urdf=Urdf(get_data("urdf"), FakeFanuc.urdf_package_name)) - - -if __name__ == "__main__": - main() diff --git a/src/python/arcor2_fanuc/tests/BUILD b/src/python/arcor2_fanuc/tests/BUILD deleted file mode 100644 index cc26cfac8..000000000 --- a/src/python/arcor2_fanuc/tests/BUILD +++ /dev/null @@ -1,5 +0,0 @@ -python_tests( - runtime_package_dependencies=[ - "src/python/arcor2_fanuc/scripts:fanuc", - ] -) diff --git a/src/python/arcor2_fanuc/tests/__init__.py b/src/python/arcor2_fanuc/tests/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/python/arcor2_fanuc/tests/test_fanuc.py b/src/python/arcor2_fanuc/tests/test_fanuc.py deleted file mode 100644 index 6f30dc4c7..000000000 --- a/src/python/arcor2_fanuc/tests/test_fanuc.py +++ /dev/null @@ -1,8 +0,0 @@ -from subprocess import check_output - -import yaml -from openapi_spec_validator import validate_spec - - -def test_fanuc_openapi() -> None: - validate_spec(yaml.full_load(check_output(["python", "src.python.arcor2_fanuc.scripts/fanuc.pex", "--swagger"]))) From 30bb85239cab88d587675b8c4b0a604a43cd0c13 Mon Sep 17 00:00:00 2001 From: ZdenekM Date: Mon, 8 Dec 2025 14:37:49 +0100 Subject: [PATCH 2/3] fix(arcor2): re-uploading of object types with models --- .github/workflows/pants.yaml | 32 ++++++++++++++++---- src/docker/arcor2_arserver/Dockerfile | 10 ++++-- src/docker/arcor2_build/Dockerfile | 12 ++++++-- src/docker/arcor2_calibration/Dockerfile | 16 ++++++++-- src/docker/arcor2_dobot/Dockerfile | 16 ++++++++-- src/docker/arcor2_execution/Dockerfile | 10 ++++-- src/docker/arcor2_execution_proxy/Dockerfile | 8 +++-- src/docker/arcor2_scene/Dockerfile | 16 ++++++++-- src/docker/arcor2_ur/Dockerfile | 11 +++++-- src/python/arcor2/CHANGELOG.md | 7 +++++ src/python/arcor2/VERSION | 2 +- src/python/arcor2/clients/asset.py | 9 +++--- src/python/arcor2/object_types/upload.py | 6 ++++ 13 files changed, 127 insertions(+), 28 deletions(-) diff --git a/.github/workflows/pants.yaml b/.github/workflows/pants.yaml index 7214c7867..7a9c66594 100644 --- a/.github/workflows/pants.yaml +++ b/.github/workflows/pants.yaml @@ -19,6 +19,11 @@ jobs: build: env: PANTS_CONFIG_FILES: pants.ci.toml + PEX_ROOT: ${{ github.workspace }}/.pex + PANTS_SETUP_CACHE_DIR: ${{ github.workspace }}/.cache/pants/setup + PANTS_NAMED_CACHES_DIR: ${{ github.workspace }}/.cache/pants/named_caches + PANTS_LOCAL_STORE_DIR: ${{ github.workspace }}/.cache/pants/lmdb_store + TMPDIR: ${{ github.workspace }}/.tmp runs-on: ubuntu-24.04 needs: org-check strategy: @@ -28,25 +33,38 @@ jobs: - name: Maximize build space uses: easimon/maximize-build-space@v10 with: - root-reserve-mb: 30000 + root-reserve-mb: 8096 swap-size-mb: 1024 remove-dotnet: 'true' remove-android: 'true' remove-haskell: 'true' remove-docker-images: 'true' + - name: Show disk space + run: | + df -h / /mnt $GITHUB_WORKSPACE - uses: actions/checkout@v4 with: fetch-depth: 0 lfs: true + - name: Prepare workspace tmpdir + run: | + mkdir -p "$GITHUB_WORKSPACE/.tmp" + chmod 1777 "$GITHUB_WORKSPACE/.tmp" - name: Checkout LFS objects run: git lfs checkout + - name: Move Docker storage to workspace + run: | + sudo systemctl stop docker || sudo service docker stop + sudo rm -rf /var/lib/docker + mkdir -p "$GITHUB_WORKSPACE/.docker" + sudo ln -s "$GITHUB_WORKSPACE/.docker" /var/lib/docker + sudo chown -R "$USER":"$USER" "$GITHUB_WORKSPACE/.docker" + sudo systemctl start docker || sudo service docker start - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - uses: ros-tooling/setup-ros@v0.7 - with: - required-ros-distributions: jazzy - uses: pantsbuild/actions/init-pants@v5-scie-pants with: pants-python-version: ${{ matrix.python-version }} @@ -59,9 +77,11 @@ jobs: pants --changed-since=HEAD update-build-files --check - name: install system dependencies run: | # cargo is required to build fastuuid (no wheels for Python 3.11) - sudo apt update - sudo apt install jq cargo + sudo apt-get update + sudo apt-get install -y --no-install-recommends jq cargo sudo ./build-support/install_ur_dependencies.sh + sudo apt-get clean + sudo rm -rf /var/lib/apt/lists/* - name: Lint run: | pants --changed-since=origin/master lint @@ -73,7 +93,7 @@ jobs: source /opt/ros/jazzy/setup.bash pants --changed-since=origin/master --changed-dependents=transitive test - name: Build Docker images - run: | # filter out non-essential docker images (there was a problem with full storage on github) + run: | pants filter --target-type=docker_image --changed-since=origin/master --changed-dependents=transitive | xargs pants package - name: Build Python packages run: | diff --git a/src/docker/arcor2_arserver/Dockerfile b/src/docker/arcor2_arserver/Dockerfile index 8671d46a2..01d04c4a1 100644 --- a/src/docker/arcor2_arserver/Dockerfile +++ b/src/docker/arcor2_arserver/Dockerfile @@ -7,9 +7,15 @@ COPY src.python.arcor2_arserver.scripts/arserver.pex /binary.pex RUN PEX_TOOLS=1 /usr/local/bin/python /binary.pex venv --scope=srcs --compile /bin/app FROM python:3.12.7-bookworm +SHELL ["/bin/bash", "-o", "pipefail", "-c"] -RUN apt-get update \ - && apt-get install -y -q --no-install-recommends libgl1-mesa-glx=22.3.6-1+deb12u1 libglib2.0-0=2.74.6-2+deb12u7 \ +RUN set -euo pipefail \ + && apt-get update \ + && gl_ver="$(apt-cache policy libgl1-mesa-glx | awk '/Candidate:/ {print $2}')" \ + && glib_ver="$(apt-cache policy libglib2.0-0 | awk '/Candidate:/ {print $2}')" \ + && apt-get install -y -q --no-install-recommends \ + "libgl1-mesa-glx=${gl_ver}" \ + "libglib2.0-0=${glib_ver}" \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* diff --git a/src/docker/arcor2_build/Dockerfile b/src/docker/arcor2_build/Dockerfile index 76b3b4408..ff7560ef4 100644 --- a/src/docker/arcor2_build/Dockerfile +++ b/src/docker/arcor2_build/Dockerfile @@ -7,10 +7,18 @@ COPY src.python.arcor2_build.scripts/build.pex /binary.pex RUN PEX_TOOLS=1 PYTHONOPTIMIZE=1 /usr/local/bin/python /binary.pex venv --scope=srcs --compile /bin/app FROM python:3.12.7-bookworm +SHELL ["/bin/bash", "-o", "pipefail", "-c"] # curl is for healthcheck -RUN apt-get update \ - && apt-get install -y -q --no-install-recommends libgl1-mesa-glx=22.3.6-1+deb12u1 libglib2.0-0=2.74.6-2+deb12u7 curl=7.88.1-10+deb12u14 \ +RUN set -euo pipefail \ + && apt-get update \ + && gl_ver="$(apt-cache policy libgl1-mesa-glx | awk '/Candidate:/ {print $2}')" \ + && glib_ver="$(apt-cache policy libglib2.0-0 | awk '/Candidate:/ {print $2}')" \ + && curl_ver="$(apt-cache policy curl | awk '/Candidate:/ {print $2}')" \ + && apt-get install -y -q --no-install-recommends \ + "libgl1-mesa-glx=${gl_ver}" \ + "libglib2.0-0=${glib_ver}" \ + "curl=${curl_ver}" \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* diff --git a/src/docker/arcor2_calibration/Dockerfile b/src/docker/arcor2_calibration/Dockerfile index dcb13219b..e19c3e0ec 100644 --- a/src/docker/arcor2_calibration/Dockerfile +++ b/src/docker/arcor2_calibration/Dockerfile @@ -7,11 +7,23 @@ COPY src.python.arcor2_calibration.scripts/calibration.pex /binary.pex RUN PEX_TOOLS=1 PYTHONOPTIMIZE=1 /usr/local/bin/python /binary.pex venv --scope=srcs --compile /bin/app FROM python:3.12.7-bookworm +SHELL ["/bin/bash", "-o", "pipefail", "-c"] # libgomp1 and libusb-1.0-0 are because of Open3D # curl is for healthcheck -RUN apt-get update \ - && apt-get install -y -q --no-install-recommends libgl1-mesa-glx=22.3.6-1+deb12u1 libglib2.0-0=2.74.6-2+deb12u7 libgomp1=12.2.0-14+deb12u1 libusb-1.0-0=2:1.0.26-1 curl=7.88.1-10+deb12u14 \ +RUN set -euo pipefail \ + && apt-get update \ + && gl_ver="$(apt-cache policy libgl1-mesa-glx | awk '/Candidate:/ {print $2}')" \ + && glib_ver="$(apt-cache policy libglib2.0-0 | awk '/Candidate:/ {print $2}')" \ + && gomp_ver="$(apt-cache policy libgomp1 | awk '/Candidate:/ {print $2}')" \ + && libusb_ver="$(apt-cache policy libusb-1.0-0 | awk '/Candidate:/ {print $2}')" \ + && curl_ver="$(apt-cache policy curl | awk '/Candidate:/ {print $2}')" \ + && apt-get install -y -q --no-install-recommends \ + "libgl1-mesa-glx=${gl_ver}" \ + "libglib2.0-0=${glib_ver}" \ + "libgomp1=${gomp_ver}" \ + "libusb-1.0-0=${libusb_ver}" \ + "curl=${curl_ver}" \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* diff --git a/src/docker/arcor2_dobot/Dockerfile b/src/docker/arcor2_dobot/Dockerfile index c6e53b37d..ca56034f1 100644 --- a/src/docker/arcor2_dobot/Dockerfile +++ b/src/docker/arcor2_dobot/Dockerfile @@ -7,10 +7,22 @@ COPY src.python.arcor2_dobot.scripts/dobot.pex /binary.pex RUN PEX_TOOLS=1 PYTHONOPTIMIZE=1 /usr/local/bin/python /binary.pex venv --scope=srcs --compile /bin/app FROM python:3.12.7-bookworm +SHELL ["/bin/bash", "-o", "pipefail", "-c"] # curl is for healthcheck -RUN apt-get update \ - && apt-get install -y -q --no-install-recommends libgl1-mesa-glx=22.3.6-1+deb12u1 libglib2.0-0=2.74.6-2+deb12u7 libgomp1=12.2.0-14+deb12u1 libusb-1.0-0=2:1.0.26-1 curl=7.88.1-10+deb12u14 \ +RUN set -euo pipefail \ + && apt-get update \ + && gl_ver="$(apt-cache policy libgl1-mesa-glx | awk '/Candidate:/ {print $2}')" \ + && glib_ver="$(apt-cache policy libglib2.0-0 | awk '/Candidate:/ {print $2}')" \ + && gomp_ver="$(apt-cache policy libgomp1 | awk '/Candidate:/ {print $2}')" \ + && libusb_ver="$(apt-cache policy libusb-1.0-0 | awk '/Candidate:/ {print $2}')" \ + && curl_ver="$(apt-cache policy curl | awk '/Candidate:/ {print $2}')" \ + && apt-get install -y -q --no-install-recommends \ + "libgl1-mesa-glx=${gl_ver}" \ + "libglib2.0-0=${glib_ver}" \ + "libgomp1=${gomp_ver}" \ + "libusb-1.0-0=${libusb_ver}" \ + "curl=${curl_ver}" \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* diff --git a/src/docker/arcor2_execution/Dockerfile b/src/docker/arcor2_execution/Dockerfile index ada666269..6e504baa4 100644 --- a/src/docker/arcor2_execution/Dockerfile +++ b/src/docker/arcor2_execution/Dockerfile @@ -7,9 +7,15 @@ COPY src.python.arcor2_execution.scripts/execution.pex /binary.pex RUN PEX_TOOLS=1 PYTHONOPTIMIZE=1 /usr/local/bin/python /binary.pex venv --scope=srcs --compile /bin/app FROM python:3.12.7-bookworm +SHELL ["/bin/bash", "-o", "pipefail", "-c"] -RUN apt-get update \ - && apt-get install -y -q --no-install-recommends libgl1-mesa-glx=22.3.6-1+deb12u1 libglib2.0-0=2.74.6-2+deb12u7 \ +RUN set -euo pipefail \ + && apt-get update \ + && gl_ver="$(apt-cache policy libgl1-mesa-glx | awk '/Candidate:/ {print $2}')" \ + && glib_ver="$(apt-cache policy libglib2.0-0 | awk '/Candidate:/ {print $2}')" \ + && apt-get install -y -q --no-install-recommends \ + "libgl1-mesa-glx=${gl_ver}" \ + "libglib2.0-0=${glib_ver}" \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* diff --git a/src/docker/arcor2_execution_proxy/Dockerfile b/src/docker/arcor2_execution_proxy/Dockerfile index 94eeb47b8..c84e3b04a 100644 --- a/src/docker/arcor2_execution_proxy/Dockerfile +++ b/src/docker/arcor2_execution_proxy/Dockerfile @@ -7,13 +7,17 @@ COPY src.python.arcor2_execution_rest_proxy.scripts/execution_rest_proxy.pex /bi RUN PEX_TOOLS=1 PYTHONOPTIMIZE=1 /usr/local/bin/python /binary.pex venv --scope=srcs --compile /bin/app FROM python:3.12.7-bookworm +SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN mkdir -p /root/tokens \ && mkdir -p /root/project # curl is for healthcheck -RUN apt-get update \ - && apt-get install -y -q --no-install-recommends curl=7.88.1-10+deb12u14 \ +RUN set -euo pipefail \ + && apt-get update \ + && curl_ver="$(apt-cache policy curl | awk '/Candidate:/ {print $2}')" \ + && apt-get install -y -q --no-install-recommends \ + "curl=${curl_ver}" \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* diff --git a/src/docker/arcor2_scene/Dockerfile b/src/docker/arcor2_scene/Dockerfile index 2f7a99170..b8e06886b 100644 --- a/src/docker/arcor2_scene/Dockerfile +++ b/src/docker/arcor2_scene/Dockerfile @@ -7,11 +7,23 @@ COPY src.python.arcor2_scene.scripts/scene.pex /binary.pex RUN PEX_TOOLS=1 PYTHONOPTIMIZE=1 /usr/local/bin/python /binary.pex venv --scope=srcs --compile /bin/app FROM python:3.12.7-bookworm +SHELL ["/bin/bash", "-o", "pipefail", "-c"] # libgomp1 and libusb-1.0-0 are because of Open3D # curl is for healthcheck -RUN apt-get update \ - && apt-get install -y -q --no-install-recommends libgl1-mesa-glx=22.3.6-1+deb12u1 libglib2.0-0=2.74.6-2+deb12u7 libgomp1=12.2.0-14+deb12u1 libusb-1.0-0=2:1.0.26-1 curl=7.88.1-10+deb12u14 \ +RUN set -euo pipefail \ + && apt-get update \ + && gl_ver="$(apt-cache policy libgl1-mesa-glx | awk '/Candidate:/ {print $2}')" \ + && glib_ver="$(apt-cache policy libglib2.0-0 | awk '/Candidate:/ {print $2}')" \ + && gomp_ver="$(apt-cache policy libgomp1 | awk '/Candidate:/ {print $2}')" \ + && libusb_ver="$(apt-cache policy libusb-1.0-0 | awk '/Candidate:/ {print $2}')" \ + && curl_ver="$(apt-cache policy curl | awk '/Candidate:/ {print $2}')" \ + && apt-get install -y -q --no-install-recommends \ + "libgl1-mesa-glx=${gl_ver}" \ + "libglib2.0-0=${glib_ver}" \ + "libgomp1=${gomp_ver}" \ + "libusb-1.0-0=${libusb_ver}" \ + "curl=${curl_ver}" \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* diff --git a/src/docker/arcor2_ur/Dockerfile b/src/docker/arcor2_ur/Dockerfile index ab886ee23..6badbd139 100644 --- a/src/docker/arcor2_ur/Dockerfile +++ b/src/docker/arcor2_ur/Dockerfile @@ -38,11 +38,16 @@ RUN echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/r COPY build-support/install_ur_dependencies.sh /root/install_ur_dependencies.sh # libgl1-mesa-glx ?? -RUN apt-get update \ +RUN set -euo pipefail \ + && apt-get update \ && /root/install_ur_dependencies.sh \ + && glib_ver="$(apt-cache policy libglib2.0-0t64 | awk '/Candidate:/ {print $2}')" \ + && gomp_ver="$(apt-cache policy libgomp1 | awk '/Candidate:/ {print $2}')" \ + && libusb_ver="$(apt-cache policy libusb-1.0-0 | awk '/Candidate:/ {print $2}')" \ && apt-get install -y -q --no-install-recommends \ - libglib2.0-0t64=2.80.0-6ubuntu3.4 \ - libgomp1=14.2.0-4ubuntu2~24.04 libusb-1.0-0=2:1.0.27-1 \ + "libglib2.0-0t64=${glib_ver}" \ + "libgomp1=${gomp_ver}" \ + "libusb-1.0-0=${libusb_ver}" \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* diff --git a/src/python/arcor2/CHANGELOG.md b/src/python/arcor2/CHANGELOG.md index b48e78e02..5fee74767 100644 --- a/src/python/arcor2/CHANGELOG.md +++ b/src/python/arcor2/CHANGELOG.md @@ -2,6 +2,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +## [1.6.0] - WIP + +### Fixed + +- Wrong parameter name in Asset service client (`delete_asset` function). +- `upload_def` - added workaround to handle orphaned `.py` assets. + ## [1.5.0] - 2024-09-12 ### Changed diff --git a/src/python/arcor2/VERSION b/src/python/arcor2/VERSION index 3e1ad720b..ce6a70b9d 100644 --- a/src/python/arcor2/VERSION +++ b/src/python/arcor2/VERSION @@ -1 +1 @@ -1.5.0 \ No newline at end of file +1.6.0 \ No newline at end of file diff --git a/src/python/arcor2/clients/asset.py b/src/python/arcor2/clients/asset.py index d4b86a4c1..340e9a893 100644 --- a/src/python/arcor2/clients/asset.py +++ b/src/python/arcor2/clients/asset.py @@ -4,6 +4,7 @@ from typing import Optional from dataclasses_jsonschema import JsonSchemaMixin +from dataclasses_jsonschema.type_defs import Nullable from arcor2 import rest @@ -21,7 +22,7 @@ class AssetInfo(JsonSchemaMixin): name: Optional[str] = None extension: Optional[str] = None directory_path: Optional[str] = None - description: Optional[str] = None + description: Nullable[str | None] = None tags: Optional[list[str]] = None dependencies: Optional[list[str]] = None @@ -48,7 +49,7 @@ def create_asset( """Creates the asset.""" if upsert and asset_exists(id): - delete_asset(id, remove_dependers=True) + delete_asset(id, remove_dependents=True) return rest.call( rest.Method.POST, @@ -66,8 +67,8 @@ def create_asset( ) -def delete_asset(id: str, remove_dependers: bool = False) -> None: - rest.call(rest.Method.DELETE, f"{URL}/assets/{id}", params={"remove_dependers": remove_dependers}) +def delete_asset(id: str, remove_dependents: bool = False) -> None: + rest.call(rest.Method.DELETE, f"{URL}/assets/{id}", params={"remove_dependents": remove_dependents}) def asset_exists(id: str) -> bool: diff --git a/src/python/arcor2/object_types/upload.py b/src/python/arcor2/object_types/upload.py index ea0aeac74..8e260b267 100644 --- a/src/python/arcor2/object_types/upload.py +++ b/src/python/arcor2/object_types/upload.py @@ -120,5 +120,11 @@ def upload_def( description=f"URDF for {obj_type.id}", ) + # workaround for Asset behavior (it keeps orphaned .py assets when doing upsert of the mesh) + if obj_type.id not in {oti.id for oti in ps.get_object_type_ids()}: + for ai in asset.asset_info(): + if ai.file_name == f"{obj_type.id}.py": + asset.delete_asset(ai.id) + print(f"Storing '{obj_type.id}'...") ps.update_object_type(obj_type) From 313abd9cf4445d4073e1e6b27e379545571b6966 Mon Sep 17 00:00:00 2001 From: ZdenekM Date: Tue, 9 Dec 2025 11:16:16 +0100 Subject: [PATCH 3/3] fix(arcor2_ur): constrained workspace to make planning more reliable --- src/python/arcor2_ur/data/moveit.yaml | 27 ++++++++++++++++++++-- src/python/arcor2_ur/scripts/ros_worker.py | 3 +++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/python/arcor2_ur/data/moveit.yaml b/src/python/arcor2_ur/data/moveit.yaml index 97ca7c6dd..f7ac8d26f 100644 --- a/src/python/arcor2_ur/data/moveit.yaml +++ b/src/python/arcor2_ur/data/moveit.yaml @@ -8,12 +8,35 @@ planning_scene_monitor_options: wait_for_initial_state_timeout: 10.0 planning_pipelines: - namespace: "moveit_cpp" # optional, default is ~ pipeline_names: ["ompl"] plan_request_params: - planning_attempts: 1 + planning_attempts: 2 planning_pipeline: ompl + planner_id: RRTConnectkConfigDefault max_velocity_scaling_factor: 1.0 max_acceleration_scaling_factor: 1.0 planning_time: 5.0 + goal_joint_tolerance: 0.001 + goal_position_tolerance: 0.005 + goal_orientation_tolerance: 0.01 + +ompl: + start_state_max_bounds_error: 0.1 + start_state_max_dt: 0.5 + jiggle_fraction: 0.05 + max_sampling_attempts: 100 + + planning_plugins: + - ompl_interface/OMPLPlanner + + request_adapters: + - default_planning_request_adapters/ResolveConstraintFrames + - default_planning_request_adapters/ValidateWorkspaceBounds + - default_planning_request_adapters/CheckStartStateBounds + - default_planning_request_adapters/CheckStartStateCollision + + response_adapters: + - default_planning_response_adapters/AddTimeOptimalParameterization + - default_planning_response_adapters/ValidateSolution + - default_planning_response_adapters/DisplayMotionPath \ No newline at end of file diff --git a/src/python/arcor2_ur/scripts/ros_worker.py b/src/python/arcor2_ur/scripts/ros_worker.py index 16d818eb2..3e80e981e 100644 --- a/src/python/arcor2_ur/scripts/ros_worker.py +++ b/src/python/arcor2_ur/scripts/ros_worker.py @@ -36,6 +36,8 @@ logger = get_logger(__name__) FREEDRIVE_KEEPALIVE_PERIOD = 0.1 +WORKSPACE_MIN = (-1.0, -1.0, -0.1) # range of UR5e is 850mm +WORKSPACE_MAX = (1.0, 1.0, 1.0) class CollisionObjectTuple(NamedTuple): @@ -606,6 +608,7 @@ def move_to_pose(self, pose: Pose, velocity: float, payload: float, safe: bool) ur_manipulator.set_start_state_to_current_state() ur_manipulator.set_goal_state(pose_stamped_msg=pose_goal, pose_link=self.tool_link) + ur_manipulator.set_workspace(*WORKSPACE_MIN, *WORKSPACE_MAX) # not documented anywhere :-D self.node.set_speed_slider(velocity) self.node.set_payload(payload)