From f35f400fdc83aa2c862f7b9e9334aa91464c2889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Knesl=C3=ADk?= Date: Thu, 16 Mar 2023 12:25:08 +0100 Subject: [PATCH] feat(cube_detector): add cube detector/tracker --- compose-files/fit-demo/docker-compose.yml | 36 ++ src/docker/arcor2_cube_detector/BUILD | 5 + src/docker/arcor2_cube_detector/Dockerfile | 22 + src/docker/arcor2_cube_tracker/BUILD | 5 + src/docker/arcor2_cube_tracker/Dockerfile | 22 + src/python/arcor2_cube_detector/BUILD | 5 + src/python/arcor2_cube_detector/CHANGELOG.md | 3 + src/python/arcor2_cube_detector/README.md | 11 + src/python/arcor2_cube_detector/VERSION | 1 + src/python/arcor2_cube_detector/__init__.py | 13 + .../arcor2_cube_detector/cube_detector.py | 408 +++++++++++++++++ src/python/arcor2_cube_detector/data/BUILD | 0 .../data/dataset/0/annotation.csv | 5 + .../data/dataset/0/color.jpg | 3 + .../data/dataset/0/depth.png | 3 + .../data/dataset/1/annotation.csv | 5 + .../data/dataset/1/color.jpg | 3 + .../data/dataset/1/depth.png | 3 + .../data/dataset/10/annotation.csv | 9 + .../data/dataset/10/color.jpg | 3 + .../data/dataset/10/depth.png | 3 + .../data/dataset/11/annotation.csv | 9 + .../data/dataset/11/color.jpg | 3 + .../data/dataset/11/depth.png | 3 + .../data/dataset/12/annotation.csv | 9 + .../data/dataset/12/color.jpg | 3 + .../data/dataset/12/depth.png | 3 + .../data/dataset/13/annotation.csv | 6 + .../data/dataset/13/color.jpg | 3 + .../data/dataset/13/depth.png | 3 + .../data/dataset/14/annotation.csv | 5 + .../data/dataset/14/color.jpg | 3 + .../data/dataset/14/depth.png | 3 + .../data/dataset/15/annotation.csv | 5 + .../data/dataset/15/color.jpg | 3 + .../data/dataset/15/depth.png | 3 + .../data/dataset/16/annotation.csv | 4 + .../data/dataset/16/color.jpg | 3 + .../data/dataset/16/depth.png | 3 + .../data/dataset/17/annotation.csv | 5 + .../data/dataset/17/color.jpg | 3 + .../data/dataset/17/depth.png | 3 + .../data/dataset/18/annotation.csv | 5 + .../data/dataset/18/color.jpg | 3 + .../data/dataset/18/depth.png | 3 + .../data/dataset/19/annotation.csv | 5 + .../data/dataset/19/color.jpg | 3 + .../data/dataset/19/depth.png | 3 + .../data/dataset/2/annotation.csv | 5 + .../data/dataset/2/color.jpg | 3 + .../data/dataset/2/depth.png | 3 + .../data/dataset/20/annotation.csv | 4 + .../data/dataset/20/color.jpg | 3 + .../data/dataset/20/depth.png | 3 + .../data/dataset/21/annotation.csv | 5 + .../data/dataset/21/color.jpg | 3 + .../data/dataset/21/depth.png | 3 + .../data/dataset/22/annotation.csv | 5 + .../data/dataset/22/color.jpg | 3 + .../data/dataset/22/depth.png | 3 + .../data/dataset/23/annotation.csv | 5 + .../data/dataset/23/color.jpg | 3 + .../data/dataset/23/depth.png | 3 + .../data/dataset/24/annotation.csv | 5 + .../data/dataset/24/color.jpg | 3 + .../data/dataset/24/depth.png | 3 + .../data/dataset/25/annotation.csv | 9 + .../data/dataset/25/color.jpg | 3 + .../data/dataset/25/depth.png | 3 + .../data/dataset/26/annotation.csv | 9 + .../data/dataset/26/color.jpg | 3 + .../data/dataset/26/depth.png | 3 + .../data/dataset/27/annotation.csv | 9 + .../data/dataset/27/color.jpg | 3 + .../data/dataset/27/depth.png | 3 + .../data/dataset/28/annotation.csv | 6 + .../data/dataset/28/color.jpg | 3 + .../data/dataset/28/depth.png | 3 + .../data/dataset/29/annotation.csv | 5 + .../data/dataset/29/color.jpg | 3 + .../data/dataset/29/depth.png | 3 + .../data/dataset/3/annotation.csv | 5 + .../data/dataset/3/color.jpg | 3 + .../data/dataset/3/depth.png | 3 + .../data/dataset/30/annotation.csv | 5 + .../data/dataset/30/color.jpg | 3 + .../data/dataset/30/depth.png | 3 + .../data/dataset/31/annotation.csv | 5 + .../data/dataset/31/color.jpg | 3 + .../data/dataset/31/depth.png | 3 + .../data/dataset/32/annotation.csv | 5 + .../data/dataset/32/color.jpg | 3 + .../data/dataset/32/depth.png | 3 + .../data/dataset/33/annotation.csv | 5 + .../data/dataset/33/color.jpg | 3 + .../data/dataset/33/depth.png | 3 + .../data/dataset/34/annotation.csv | 5 + .../data/dataset/34/color.jpg | 3 + .../data/dataset/34/depth.png | 3 + .../data/dataset/35/annotation.csv | 5 + .../data/dataset/35/color.jpg | 3 + .../data/dataset/35/depth.png | 3 + .../data/dataset/36/annotation.csv | 5 + .../data/dataset/36/color.jpg | 3 + .../data/dataset/36/depth.png | 3 + .../data/dataset/37/annotation.csv | 5 + .../data/dataset/37/color.jpg | 3 + .../data/dataset/37/depth.png | 3 + .../data/dataset/38/annotation.csv | 5 + .../data/dataset/38/color.jpg | 3 + .../data/dataset/38/depth.png | 3 + .../data/dataset/39/annotation.csv | 5 + .../data/dataset/39/color.jpg | 3 + .../data/dataset/39/depth.png | 3 + .../data/dataset/4/annotation.csv | 5 + .../data/dataset/4/color.jpg | 3 + .../data/dataset/4/depth.png | 3 + .../data/dataset/40/annotation.csv | 9 + .../data/dataset/40/color.jpg | 3 + .../data/dataset/40/depth.png | 3 + .../data/dataset/41/annotation.csv | 9 + .../data/dataset/41/color.jpg | 3 + .../data/dataset/41/depth.png | 3 + .../data/dataset/42/annotation.csv | 9 + .../data/dataset/42/color.jpg | 3 + .../data/dataset/42/depth.png | 3 + .../data/dataset/43/annotation.csv | 6 + .../data/dataset/43/color.jpg | 3 + .../data/dataset/43/depth.png | 3 + .../data/dataset/44/annotation.csv | 5 + .../data/dataset/44/color.jpg | 3 + .../data/dataset/44/depth.png | 3 + .../data/dataset/5/annotation.csv | 5 + .../data/dataset/5/color.jpg | 3 + .../data/dataset/5/depth.png | 3 + .../data/dataset/6/annotation.csv | 5 + .../data/dataset/6/color.jpg | 3 + .../data/dataset/6/depth.png | 3 + .../data/dataset/7/annotation.csv | 5 + .../data/dataset/7/color.jpg | 3 + .../data/dataset/7/depth.png | 3 + .../data/dataset/8/annotation.csv | 5 + .../data/dataset/8/color.jpg | 3 + .../data/dataset/8/depth.png | 3 + .../data/dataset/9/annotation.csv | 5 + .../data/dataset/9/color.jpg | 3 + .../data/dataset/9/depth.png | 3 + .../arcor2_cube_detector/data/dataset/BUILD | 4 + src/python/arcor2_cube_detector/exceptions.py | 13 + src/python/arcor2_cube_detector/py.typed | 0 src/python/arcor2_cube_detector/scripts/BUILD | 5 + .../arcor2_cube_detector/scripts/__init__.py | 0 .../scripts/cube_detector.py | 99 ++++ .../scripts/dataset_evaluation.py | 190 ++++++++ src/python/arcor2_cube_detector/tests/BUILD | 8 + .../arcor2_cube_detector/tests/__init__.py | 0 .../tests/test_dataset.py | 66 +++ .../tests/test_openapi.py | 12 + src/python/arcor2_cube_tracker/BUILD | 5 + src/python/arcor2_cube_tracker/CHANGELOG.md | 3 + src/python/arcor2_cube_tracker/README.md | 15 + src/python/arcor2_cube_tracker/VERSION | 1 + src/python/arcor2_cube_tracker/__init__.py | 9 + .../arcor2_cube_tracker/cube_tracker.py | 183 ++++++++ src/python/arcor2_cube_tracker/exceptions.py | 17 + src/python/arcor2_cube_tracker/py.typed | 0 src/python/arcor2_cube_tracker/scripts/BUILD | 3 + .../arcor2_cube_tracker/scripts/__init__.py | 0 .../scripts/cube_tracker.py | 430 ++++++++++++++++++ src/python/arcor2_cube_tracker/tests/BUILD | 5 + .../arcor2_cube_tracker/tests/test_openapi.py | 12 + .../arcor2_cube_tracker/tests/test_tracker.py | 217 +++++++++ .../object_types/cube_tracker.py | 151 ++++++ .../arcor2_fit_demo/scripts/upload_objects.py | 2 + 174 files changed, 2513 insertions(+) create mode 100644 src/docker/arcor2_cube_detector/BUILD create mode 100644 src/docker/arcor2_cube_detector/Dockerfile create mode 100644 src/docker/arcor2_cube_tracker/BUILD create mode 100644 src/docker/arcor2_cube_tracker/Dockerfile create mode 100644 src/python/arcor2_cube_detector/BUILD create mode 100644 src/python/arcor2_cube_detector/CHANGELOG.md create mode 100644 src/python/arcor2_cube_detector/README.md create mode 100644 src/python/arcor2_cube_detector/VERSION create mode 100644 src/python/arcor2_cube_detector/__init__.py create mode 100644 src/python/arcor2_cube_detector/cube_detector.py create mode 100644 src/python/arcor2_cube_detector/data/BUILD create mode 100644 src/python/arcor2_cube_detector/data/dataset/0/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/0/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/0/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/1/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/1/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/1/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/10/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/10/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/10/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/11/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/11/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/11/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/12/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/12/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/12/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/13/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/13/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/13/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/14/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/14/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/14/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/15/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/15/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/15/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/16/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/16/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/16/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/17/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/17/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/17/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/18/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/18/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/18/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/19/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/19/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/19/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/2/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/2/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/2/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/20/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/20/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/20/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/21/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/21/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/21/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/22/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/22/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/22/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/23/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/23/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/23/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/24/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/24/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/24/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/25/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/25/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/25/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/26/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/26/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/26/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/27/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/27/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/27/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/28/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/28/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/28/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/29/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/29/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/29/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/3/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/3/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/3/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/30/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/30/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/30/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/31/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/31/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/31/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/32/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/32/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/32/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/33/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/33/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/33/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/34/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/34/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/34/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/35/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/35/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/35/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/36/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/36/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/36/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/37/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/37/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/37/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/38/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/38/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/38/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/39/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/39/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/39/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/4/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/4/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/4/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/40/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/40/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/40/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/41/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/41/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/41/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/42/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/42/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/42/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/43/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/43/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/43/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/44/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/44/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/44/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/5/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/5/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/5/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/6/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/6/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/6/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/7/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/7/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/7/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/8/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/8/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/8/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/9/annotation.csv create mode 100644 src/python/arcor2_cube_detector/data/dataset/9/color.jpg create mode 100644 src/python/arcor2_cube_detector/data/dataset/9/depth.png create mode 100644 src/python/arcor2_cube_detector/data/dataset/BUILD create mode 100644 src/python/arcor2_cube_detector/exceptions.py create mode 100644 src/python/arcor2_cube_detector/py.typed create mode 100644 src/python/arcor2_cube_detector/scripts/BUILD create mode 100644 src/python/arcor2_cube_detector/scripts/__init__.py create mode 100644 src/python/arcor2_cube_detector/scripts/cube_detector.py create mode 100644 src/python/arcor2_cube_detector/scripts/dataset_evaluation.py create mode 100644 src/python/arcor2_cube_detector/tests/BUILD create mode 100644 src/python/arcor2_cube_detector/tests/__init__.py create mode 100644 src/python/arcor2_cube_detector/tests/test_dataset.py create mode 100644 src/python/arcor2_cube_detector/tests/test_openapi.py create mode 100644 src/python/arcor2_cube_tracker/BUILD create mode 100644 src/python/arcor2_cube_tracker/CHANGELOG.md create mode 100644 src/python/arcor2_cube_tracker/README.md create mode 100644 src/python/arcor2_cube_tracker/VERSION create mode 100644 src/python/arcor2_cube_tracker/__init__.py create mode 100644 src/python/arcor2_cube_tracker/cube_tracker.py create mode 100644 src/python/arcor2_cube_tracker/exceptions.py create mode 100644 src/python/arcor2_cube_tracker/py.typed create mode 100644 src/python/arcor2_cube_tracker/scripts/BUILD create mode 100644 src/python/arcor2_cube_tracker/scripts/__init__.py create mode 100644 src/python/arcor2_cube_tracker/scripts/cube_tracker.py create mode 100644 src/python/arcor2_cube_tracker/tests/BUILD create mode 100644 src/python/arcor2_cube_tracker/tests/test_openapi.py create mode 100644 src/python/arcor2_cube_tracker/tests/test_tracker.py create mode 100644 src/python/arcor2_fit_demo/object_types/cube_tracker.py diff --git a/compose-files/fit-demo/docker-compose.yml b/compose-files/fit-demo/docker-compose.yml index c5336e3b..7daba970 100644 --- a/compose-files/fit-demo/docker-compose.yml +++ b/compose-files/fit-demo/docker-compose.yml @@ -15,6 +15,10 @@ services: condition: service_started fit-demo-kinect: condition: service_healthy + fit-demo-cube-detector: + condition: service_healthy + fit-demo-cube-tracker: + condition: service_healthy fit-demo-scene: condition: service_healthy fit-demo-calibration: @@ -28,6 +32,8 @@ services: - "6799:6799" networks: - fit-demo-kinect-network + - fit-demo-cube-detector-network + - fit-demo-cube-tracker-network - fit-demo-scene-network - fit-demo-project-network - fit-demo-asset-network @@ -42,6 +48,8 @@ services: - ARCOR2_BUILD_URL=http://fit-demo-build:5008 - ARCOR2_CALIBRATION_URL=http://fit-demo-calibration:5014 - ARCOR2_KINECT_AZURE_URL=http://192.168.104.100:5017 # Run kinect using pants + - ARCOR2_CUBE_DETECTOR_URL=http://fit-demo-cube-detector:5020 + - ARCOR2_CUBE_TRACKER_URL=http://fit-demo-cube-tracker:5021 fit-demo-build: image: arcor2/arcor2_build:1.0.3 @@ -65,6 +73,7 @@ services: - fit-demo-scene-network - fit-demo-dobot-magician-network - fit-demo-dobot-m1-network + - fit-demo-cube-tracker-network environment: - ARCOR2_SCENE_SERVICE_URL=http://fit-demo-scene:5013 - ARCOR2_PROJECT_PATH=/root/project @@ -81,6 +90,31 @@ services: environment: - ARCOR2_KINECT_AZURE_MOCK=true + fit-demo-cube-detector: + image: arcor2/arcor2_cube_detector:0.1.0 + container_name: fit-demo-cube-detector + networks: + - fit-demo-kinect-network + - fit-demo-cube-detector-network + ports: + - "5020:5020" + environment: + - ARCOR2_KINECT_AZURE_URL=http://192.168.104.100:5017 + - ARCOR2_CUBE_DETECTOR_URL=http://fit-demo-cube-detector:5020 + + fit-demo-cube-tracker: + image: arcor2/arcor2_cube_tracker:0.1.0 + container_name: fit-demo-cube-tracker + networks: + - fit-demo-cube-tracker-network + - fit-demo-cube-detector-network + - fit-demo-execution-network + ports: + - "5021:5021" + environment: + - ARCOR2_CUBE_TRACKER_URL=http://fit-demo-cube-tracker:5021 + - ARCOR2_CUBE_DETECTOR_URL=http://fit-demo-cube-detector:5020 + fit-demo-calibration: image: arcor2/arcor2_calibration:1.0.0 networks: @@ -214,6 +248,8 @@ networks: fit-demo-project-network: fit-demo-asset-network: fit-demo-kinect-network: + fit-demo-cube-detector-network: + fit-demo-cube-tracker-network: fit-demo-dobot-magician-network: fit-demo-dobot-m1-network: fit-demo-calibration-network: \ No newline at end of file diff --git a/src/docker/arcor2_cube_detector/BUILD b/src/docker/arcor2_cube_detector/BUILD new file mode 100644 index 00000000..100ba85f --- /dev/null +++ b/src/docker/arcor2_cube_detector/BUILD @@ -0,0 +1,5 @@ +docker_image( + name="arcor2_cube_detector", + repository="arcor2/arcor2_cube_detector", + image_tags=["0.1.0"], +) diff --git a/src/docker/arcor2_cube_detector/Dockerfile b/src/docker/arcor2_cube_detector/Dockerfile new file mode 100644 index 00000000..7b66aeb6 --- /dev/null +++ b/src/docker/arcor2_cube_detector/Dockerfile @@ -0,0 +1,22 @@ +FROM python:3.10.10-slim-bullseye as deps +COPY src.python.arcor2_cube_detector.scripts/cube_detector.pex /binary.pex +RUN PEX_TOOLS=1 PYTHONOPTIMIZE=1 /usr/local/bin/python3.10 /binary.pex venv --scope=deps --compile /bin/app + +FROM python:3.10.10-slim-bullseye as srcs +COPY src.python.arcor2_cube_detector.scripts/cube_detector.pex /binary.pex +RUN PEX_TOOLS=1 PYTHONOPTIMIZE=1 /usr/local/bin/python3.10 /binary.pex venv --scope=srcs --compile /bin/app + +FROM python:3.10.10-slim-bullseye + +# curl is for healthcheck +RUN apt-get update \ + && apt-get install -y -q --no-install-recommends libgl1-mesa-glx=20.3.5-1 libglib2.0-0=2.66.8-1 libgomp1=10.2.1-6 libusb-1.0-0=2:1.0.24-3 curl=7.74.0-1.3+deb11u7 \ + && 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 5020 +HEALTHCHECK --interval=5s --start-period=60s CMD curl -f http://localhost:5020/healthz/ready || exit 1 diff --git a/src/docker/arcor2_cube_tracker/BUILD b/src/docker/arcor2_cube_tracker/BUILD new file mode 100644 index 00000000..b2db126a --- /dev/null +++ b/src/docker/arcor2_cube_tracker/BUILD @@ -0,0 +1,5 @@ +docker_image( + name="arcor2_cube_tracker", + repository="arcor2/arcor2_cube_tracker", + image_tags=["0.1.0"], +) diff --git a/src/docker/arcor2_cube_tracker/Dockerfile b/src/docker/arcor2_cube_tracker/Dockerfile new file mode 100644 index 00000000..4014dd43 --- /dev/null +++ b/src/docker/arcor2_cube_tracker/Dockerfile @@ -0,0 +1,22 @@ +FROM python:3.10.10-slim-bullseye as deps +COPY src.python.arcor2_cube_tracker.scripts/cube_tracker.pex /binary.pex +RUN PEX_TOOLS=1 PYTHONOPTIMIZE=1 /usr/local/bin/python3.10 /binary.pex venv --scope=deps --compile /bin/app + +FROM python:3.10.10-slim-bullseye as srcs +COPY src.python.arcor2_cube_tracker.scripts/cube_tracker.pex /binary.pex +RUN PEX_TOOLS=1 PYTHONOPTIMIZE=1 /usr/local/bin/python3.10 /binary.pex venv --scope=srcs --compile /bin/app + +FROM python:3.10.10-slim-bullseye + +# curl is for healthcheck +RUN apt-get update \ + && apt-get install -y -q --no-install-recommends libgl1-mesa-glx=20.3.5-1 libglib2.0-0=2.66.8-1 libgomp1=10.2.1-6 libusb-1.0-0=2:1.0.24-3 curl=7.74.0-1.3+deb11u7 \ + && 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 5021 +HEALTHCHECK --interval=5s --start-period=60s CMD curl -f http://localhost:5021/healthz/ready || exit 1 diff --git a/src/python/arcor2_cube_detector/BUILD b/src/python/arcor2_cube_detector/BUILD new file mode 100644 index 00000000..b6554c7e --- /dev/null +++ b/src/python/arcor2_cube_detector/BUILD @@ -0,0 +1,5 @@ +arcor2_python_distribution( + name="arcor2_cube_detector", + description="Cube detector", + binaries={"arcor2_cube_detector": "src/python/arcor2_cube_detector/scripts:cube_detector"}, +) diff --git a/src/python/arcor2_cube_detector/CHANGELOG.md b/src/python/arcor2_cube_detector/CHANGELOG.md new file mode 100644 index 00000000..414255fd --- /dev/null +++ b/src/python/arcor2_cube_detector/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), diff --git a/src/python/arcor2_cube_detector/README.md b/src/python/arcor2_cube_detector/README.md new file mode 100644 index 00000000..a7eebaae --- /dev/null +++ b/src/python/arcor2_cube_detector/README.md @@ -0,0 +1,11 @@ +# Cube Detector Service + +## Usage Instructions + +- By default, the service runs on port 5020. + +## Environment variables + +- `ARCOR2_CUBE_DETECTOR_URL=http://0.0.0.0:5020` - by default, the service listens on port 5020. +- `ARCOR2_CUBE_DETECTOR_MOCK=1` - the service will start in a mock (simulator) mode. +- `ARCOR2_CUBE_DETECTOR_DEBUG=1` - switches logger to the `DEBUG` level. \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/VERSION b/src/python/arcor2_cube_detector/VERSION new file mode 100644 index 00000000..6c6aa7cb --- /dev/null +++ b/src/python/arcor2_cube_detector/VERSION @@ -0,0 +1 @@ +0.1.0 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/__init__.py b/src/python/arcor2_cube_detector/__init__.py new file mode 100644 index 00000000..2e49a73b --- /dev/null +++ b/src/python/arcor2_cube_detector/__init__.py @@ -0,0 +1,13 @@ +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_cube_detector/cube_detector.py b/src/python/arcor2_cube_detector/cube_detector.py new file mode 100644 index 00000000..c84e0c52 --- /dev/null +++ b/src/python/arcor2_cube_detector/cube_detector.py @@ -0,0 +1,408 @@ +import math +import os +import tempfile +import time +from dataclasses import dataclass, field +from enum import Enum +from functools import wraps +from typing import NamedTuple + +import cv2 +import numpy as np +import open3d as o3d +import quaternion +from dataclasses_jsonschema import JsonSchemaMixin + +import arcor2.transformations as tr +from arcor2 import env, rest +from arcor2.data.camera import CameraParameters +from arcor2.data.common import Orientation, Pose, Position +from arcor2.logging import get_logger + +logger = get_logger(__name__) +if env.get_bool("ARCOR2_CUBE_DETECTOR_DEBUG"): + logger.setLevel("DEBUG") + + +URL_KINECT = os.getenv("ARCOR2_KINECT_AZURE_URL", "http://192.168.104.100:5017") + + +@dataclass +class Cube(JsonSchemaMixin): + color: str + pose: Pose = field(default_factory=Pose) + + +class Color(Enum): + RED = 0 + GREEN = 1 + BLUE = 2 + YELLOW = 3 + + +class Plane(NamedTuple): + pointcloud: o3d.geometry.PointCloud + model: list[float] + + +HSV = { + Color.BLUE: [[np.array([100, 175, 75]), np.array([135, 255, 255])]], + Color.RED: [ + [np.array([0, 100, 50]), np.array([5, 255, 255])], + [np.array([165, 100, 50]), np.array([180, 255, 255])], + ], + Color.YELLOW: [[np.array([25, 100, 50]), np.array([40, 255, 255])]], + Color.GREEN: [[np.array([40, 20, 50]), np.array([85, 255, 255])]], +} + +HALF_OF_CUBE_SIZE = 0.0125 +MIN_PLANE_POINTS = 100 +MAX_PLANE_POINTS = 750 +COMPARE_PLANES_MIN_ANGLE = 50 + + +def timer(f): + @wraps(f) + def wrapped(*args, **kwargs): + start = time.monotonic() + result = f(*args, **kwargs) + end = time.monotonic() + logger.debug(f"{(end-start):.3f} {f.__name__!r}") + return result + + return wrapped + + +class CubeDetector: + def __init__(self, camera_parameters: CameraParameters, image_width: int = 1920, image_height: int = 1080) -> None: + self.camera_parameters = o3d.camera.PinholeCameraIntrinsic( + image_width, + image_height, + camera_parameters.fx, + camera_parameters.fy, + camera_parameters.cx, + camera_parameters.cy, + ) + + def get_image_from_bytes( + self, color_bytes: bytes, depth_bytes: bytes + ) -> tuple[o3d.geometry.Image, o3d.geometry.Image]: + """Creates color and depth image stored as bytes. + + :param color_bytes: Color image bytes + :param depth_bytes: Depth image bytes + :return: Color image, Depth image + """ + with tempfile.NamedTemporaryFile(suffix=".jpg") as tmp: + tmp.write(color_bytes) + color = o3d.io.read_image(tmp.name) + + with tempfile.NamedTemporaryFile(suffix=".png") as tmp: + tmp.write(depth_bytes) + depth = o3d.io.read_image(tmp.name) + return color, depth + + def get_image_from_file(self, color_file: str, depth_file: str) -> tuple[o3d.geometry.Image, o3d.geometry.Image]: + """Creates color and depth image from filename. + + :param color_file: Color image filename + :param depth_file: Depth image filename + :return: Color image, Depth image + """ + color = o3d.io.read_image(color_file) + depth = o3d.io.read_image(depth_file) + return color, depth + + @timer + def detect_cubes( + self, color: o3d.geometry.Image, depth: o3d.geometry.Image, transform_cordinates=True + ) -> list[Cube]: + """Detects cubes. + + :param color: Color image + :param depth: Depth image + :param transform_cordinates: Transform edge coordinates to arcor2 coordinates, defaults to True + :return: List of detected cubes + """ + detected_cubes: list[Cube] = [] + + pointcloud_filtered = self.filter_pointcloud(color, depth) + + for cube_color in Color: + for cluster in self.dbscan(pointcloud_filtered[cube_color]): + planes = self.segment_plane(cluster) + angle_of_planes = self.get_angles_between_planes(planes) + for candidate in self.find_candidates(angle_of_planes): + pose = self.detect_cube([planes[i] for i in candidate], transform_cordinates) + if pose: + detected_cubes.append(Cube(cube_color.name, pose)) + break + + logger.debug(f"Detected {len(detected_cubes)} cubes") + return detected_cubes + + def filter_pointcloud( + self, color: o3d.geometry.Image, depth: o3d.geometry.Image + ) -> dict[Color, o3d.geometry.PointCloud]: + """Filters input image by color and creates individual pointclouds for + each color. + + :param color: Color image + :param depth: Depth image + :return: Dictionary containing pointcloud for each color + """ + pcd_filtered: dict[Color, o3d.geometry.PointCloud] = {} + + color = np.asarray(color) + depth = np.asarray(depth) + hsv = cv2.cvtColor(color, cv2.COLOR_RGB2HSV) + for cube_color in Color: + mask = None + for range in HSV[cube_color]: + temp_mask = cv2.inRange(hsv, range[0], range[1]) + mask = temp_mask if mask is None else mask + temp_mask + + color_filtered = o3d.geometry.Image((cv2.bitwise_and(color, color, mask=mask)).astype(np.uint8)) + depth_filtered = o3d.geometry.Image((cv2.bitwise_and(depth, depth, mask=mask)).astype(np.uint16)) + + rgbd_image_filtered = o3d.geometry.RGBDImage.create_from_color_and_depth( + color_filtered, depth_filtered, convert_rgb_to_intensity=False + ) + + pcd_filtered[cube_color] = ( + o3d.geometry.PointCloud() + .create_from_rgbd_image(rgbd_image_filtered, self.camera_parameters) + .voxel_down_sample(voxel_size=0.0015) + ) + return pcd_filtered + + @timer + def dbscan(self, pointcloud: o3d.geometry.PointCloud) -> list[o3d.geometry.PointCloud]: + """Performs dbscan clustering and saves each cluster as individual + pointcloud. + + :param pointcloud: Filtered pointcloud + :return: List of pointcloud segments + """ + if len(pointcloud.points) < 2 * MIN_PLANE_POINTS: + return [] + + labels = np.array(pointcloud.cluster_dbscan(eps=0.02, min_points=MIN_PLANE_POINTS, print_progress=False)) + + cluster_count = labels.max() + 1 + pointcloud_clusters = [None] * cluster_count + for i in range(cluster_count): + index = np.where(labels == i)[0] + pointcloud_clusters[i] = pointcloud.select_by_index(index) + return pointcloud_clusters + + def segment_plane(self, cluster: o3d.geometry.PointCloud) -> list[Plane]: + """Segments cluster pointcloud into planes. + + :param cluster: Cluster pointcloud + :return: List of planes containing pointcloud and model of the plane + """ + _, ind = cluster.remove_statistical_outlier(nb_neighbors=20, std_ratio=2.0) + outlier = cluster.select_by_index(ind) + + planes: list[Plane] = [] + while outlier.has_points() and len(outlier.points) > MIN_PLANE_POINTS: + plane_model, inliers = outlier.segment_plane(distance_threshold=0.0025, ransac_n=3, num_iterations=100) + inlier = outlier.select_by_index(inliers) + outlier = outlier.select_by_index(inliers, invert=True) + if len(inlier.points) > MIN_PLANE_POINTS and len(inlier.points) < MAX_PLANE_POINTS: + planes.append(Plane(inlier, plane_model)) + return planes + + def get_angles_between_planes(self, planes: list[Plane]) -> dict[int, dict[int, int]]: + """Creates table with angles between each plane. + + :param planes: List of planes + :return: Table with angles between each plane + """ + plane_angles: dict[int, dict[int, int]] = {} + + for i, (_, [a1, b1, c1, _]) in enumerate(planes): + plane_angles[i] = {} + for j, (_, [a2, b2, c2, _]) in enumerate(planes): + if i == j: + angle = 0 + else: + # Inspired by https://www.geeksforgeeks.org/angle-between-two-planes-in-3d/ + d = a1 * a2 + b1 * b2 + c1 * c2 + e1 = math.sqrt(a1 * a1 + b1 * b1 + c1 * c1) + e2 = math.sqrt(a2 * a2 + b2 * b2 + c2 * c2) + d = d / (e1 * e2) + angle = round(math.degrees(math.acos(d))) + plane_angles[i][j] = angle + return plane_angles + + def is_plane_perpendicular(self, angle: int) -> bool: + """Checks if angle of the plane is perpendicular. + + :param angle: Angle of the plane + :return: True if angle is perpendicular, False otherwise + """ + return angle >= COMPARE_PLANES_MIN_ANGLE and angle <= 180 - COMPARE_PLANES_MIN_ANGLE + + def is_point_on_plane(self, point: np.ndarray, plane_model: list[float]) -> bool: + """Checks if point is on the plane. + + :param point: Point with 3D coordinates + :param plane_model: Plane model + :return: True if point is on the plane, False otherwise + """ + return ( + abs(point[0] * plane_model[0] + point[1] * plane_model[1] + point[2] * plane_model[2] + plane_model[3]) + < 0.004 + ) + + def is_point_on_edge(self, point: np.ndarray, plane_models: list[list[float]]) -> bool: + """Checks, if point is on the intersection of two planes. + + :param point: Point with 3D coordinates + :param plane_models: Plane models of two planes forming an edge + :return: True if point is on the intersection, False otherwise + """ + return self.is_point_on_plane(point, plane_models[0]) and self.is_point_on_plane(point, plane_models[1]) + + def is_point_on_corner(self, point: np.ndarray, plane_models: list[list[float]]) -> bool: + """Checks, if point is the corner of cube (if point is on every edge) + + :param point: Point with 3D coordinates + :param plane_models: Plane models of three planes forming a corner + :return: True if point is the corner of cube + """ + return ( + self.is_point_on_edge(point, [plane_models[0], plane_models[1]]) + and self.is_point_on_edge(point, [plane_models[0], plane_models[2]]) + and self.is_point_on_edge(point, [plane_models[1], plane_models[2]]) + ) + + def find_candidates(self, angle_between_planes: dict[int, dict[int, int]]) -> list[list[int]]: + """Finds cube candidates from cluster pointcloud. + + :param angle_between_planes: Table with angles for each plane + :return: List of plane IDs, that can potentially form a cube + """ + + candidates: list[list[int]] = [] + + # Compare plane angles with each other + for reference_plane_1_ID in angle_between_planes.keys(): + for reference_plane_2_id in angle_between_planes[reference_plane_1_ID].keys(): + if reference_plane_1_ID == reference_plane_2_id: + continue + if self.is_plane_perpendicular(angle_between_planes[reference_plane_1_ID][reference_plane_2_id]): + # Add candidate with 2 sides if it isnt already added + if sorted([reference_plane_1_ID, reference_plane_2_id]) not in candidates: + candidates.append(sorted([reference_plane_1_ID, reference_plane_2_id])) + for reference_plane_3_ID in angle_between_planes[reference_plane_1_ID].keys(): + # Plane has 2 "perpendicular" planes + candidate = sorted([reference_plane_1_ID, reference_plane_2_id, reference_plane_3_ID]) + if ( + reference_plane_3_ID in [reference_plane_1_ID, reference_plane_2_id] + or candidate in candidates + ): + continue + + if self.is_plane_perpendicular( + angle_between_planes[reference_plane_1_ID][reference_plane_3_ID] + ) and self.is_plane_perpendicular( + angle_between_planes[reference_plane_2_id][reference_plane_3_ID] + ): + # All 3 planes are "perpendicular" to each other + candidates.insert(0, candidate) + return candidates + + def detect_cube(self, candidates: list[Plane], transform_cordinates: bool) -> Pose | None: + """Detects cube in cluster by comparing perpendicular planes. + + :param candidates: Planes that potentialy form a cube + :param transform_cordinates: Transform coordinates to arcor2 coordinate system + :return: Returns pose if cube is detected, None otherwise + """ + + cube_pointcloud = o3d.geometry.PointCloud() + for plane_pointcloud, _ in candidates: + cube_pointcloud += plane_pointcloud + + # Create bounding box and check distance between max and min bound + # If the distane is larger than 0.1, it probably isn't a cube + # This removes most of the false positive detections + bounding_box = o3d.geometry.OrientedBoundingBox.create_from_points(cube_pointcloud.points) + if np.linalg.norm(bounding_box.get_max_bound() - bounding_box.get_min_bound()) > 0.125: + return None + + points = np.asarray(cube_pointcloud.points) + + number_of_sides = len(candidates) + + # Get points of edges + edge_points: list = number_of_sides * [None] + for i in range(number_of_sides): + edge_points[i] = [ + point + for point in points + if self.is_point_on_edge(point, [candidates[i].model, candidates[(i + 1) % number_of_sides].model]) + ] + edge = o3d.geometry.PointCloud() + edge.points = o3d.utility.Vector3dVector(sum(edge_points, [])) + + if number_of_sides == 3: + # Cube has 3 sides, get corner position + corner = o3d.geometry.PointCloud() + corner.points = o3d.utility.Vector3dVector( + [point for point in points if self.is_point_on_corner(point, [plane.model for plane in candidates])] + ) + center = np.asarray(corner.get_center()) + else: + # Cube has 2 sides and only 1 edge, get position of center of the edge + center = np.asarray(edge.get_center()) + + vector: list = number_of_sides * [None] + vector_distance: list = number_of_sides * [0] + for i in range(number_of_sides): + if number_of_sides == 3: + edge_center = o3d.geometry.PointCloud() + edge_center.points = o3d.utility.Vector3dVector(edge_points[i]) + edge_center = edge_center.get_center() + else: + edge_center = candidates[i].pointcloud.get_center() + + # Calculate direction vector from corner to edge center + vector[i] = 3 * [None] + for j in range(3): + vector[i][j] = edge_center[j] - center[j] + + # Normalize vector + norm = np.linalg.norm(vector[i]) + if norm != 0: + vector[i] /= norm + + # Calculate distance from corner to edge center + vector_distance[i] = np.linalg.norm(center - np.asarray(edge_center)) + + # If the average distance from corner to edge center is larger than threshold, it probably isn't a cube + if abs(HALF_OF_CUBE_SIZE - np.average(vector_distance)) > 0.2: + return None + + # Calculate center coordinates by adding half the cube size to each side from the corner + for i in range(3): + for j in range(number_of_sides): + center[i] += vector[j][i] * HALF_OF_CUBE_SIZE + + candidates.sort(key=lambda candidate: candidate.pointcloud.get_center()[2]) + bounding_box = o3d.geometry.OrientedBoundingBox.create_from_points(candidates[0].pointcloud.points) + orientation = Orientation.from_quaternion( + quaternion.from_rotation_matrix(bounding_box.get_rotation_matrix_from_xyz(bounding_box.get_center())) + ) + + pose = Pose(Position(*center), Orientation(0, 0, orientation.z, 1)) + + # Transform coordinates to arcor2 coordinate system + if transform_cordinates: + kinect_pose = rest.call(rest.Method.GET, f"{URL_KINECT}/state/pose", return_type=Pose) + pose = tr.make_pose_abs(kinect_pose, pose) + + return pose diff --git a/src/python/arcor2_cube_detector/data/BUILD b/src/python/arcor2_cube_detector/data/BUILD new file mode 100644 index 00000000..e69de29b diff --git a/src/python/arcor2_cube_detector/data/dataset/0/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/0/annotation.csv new file mode 100644 index 00000000..02bb3d58 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/0/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +YELLOW,-0.24854,-0.02557,0.79296 +BLUE,-0.17298,-0.03175,0.79400 +RED,-0.07946,-0.03590,0.79998 +GREEN,-0.00022,-0.03653,0.80107 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/0/color.jpg b/src/python/arcor2_cube_detector/data/dataset/0/color.jpg new file mode 100644 index 00000000..fa62d3f0 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/0/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1784ec81144281d1754b4ead331c3e7ce9eaa5d1a9bffe1a7ddfdb4766ad9669 +size 437538 diff --git a/src/python/arcor2_cube_detector/data/dataset/0/depth.png b/src/python/arcor2_cube_detector/data/dataset/0/depth.png new file mode 100644 index 00000000..2346423c --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/0/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9a1f0f2140a8668d9384381ec433ef163c3761c3f60e56961e20442ac118fb98 +size 395994 diff --git a/src/python/arcor2_cube_detector/data/dataset/1/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/1/annotation.csv new file mode 100644 index 00000000..7153a436 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/1/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +YELLOW,-0.37422,-0.05063,0.79788 +BLUE,-0.32251,-0.05004,0.79989 +RED,0.17070,-0.05745,0.81494 +GREEN,0.22625,-0.05950,0.81605 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/1/color.jpg b/src/python/arcor2_cube_detector/data/dataset/1/color.jpg new file mode 100644 index 00000000..9030b538 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/1/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f57fb4a45596663d7ec0f8c698cb2917f72538ca7078e59a3c0af1fd3a2ba48d +size 434141 diff --git a/src/python/arcor2_cube_detector/data/dataset/1/depth.png b/src/python/arcor2_cube_detector/data/dataset/1/depth.png new file mode 100644 index 00000000..6468bc8f --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/1/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:39e5f1bcc0ffd62038dbc5d36d3b41d5673da0cfcf4f4686e8b34905eadc2cc9 +size 398673 diff --git a/src/python/arcor2_cube_detector/data/dataset/10/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/10/annotation.csv new file mode 100644 index 00000000..3c8bffa4 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/10/annotation.csv @@ -0,0 +1,9 @@ +color,x,y,z +RED,-0.27581,-0.05323,0.80193 +RED,-0.19223,-0.01048,0.78500 +YELLOW,-0.12190,-0.02447,0.79802 +YELLOW,-0.06958,-0.02287,0.79799 +GREEN,0.01224,-0.03870,0.80002 +GREEN,0.05624,-0.03937,0.80496 +BLUE,0.13288,-0.05381,0.81406 +BLUE,0.19807,-0.05435,0.81600 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/10/color.jpg b/src/python/arcor2_cube_detector/data/dataset/10/color.jpg new file mode 100644 index 00000000..4ddd5919 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/10/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97dda65d513f97fa54dfca681b56c6bd7e66f54c9bfea6e2b00940d4907398c1 +size 444743 diff --git a/src/python/arcor2_cube_detector/data/dataset/10/depth.png b/src/python/arcor2_cube_detector/data/dataset/10/depth.png new file mode 100644 index 00000000..2b212bb8 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/10/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c65b706124951e20b3a75f3ed8f11978460eabf2472ae66bac4b30421b11acb +size 399399 diff --git a/src/python/arcor2_cube_detector/data/dataset/11/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/11/annotation.csv new file mode 100644 index 00000000..f2d250b7 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/11/annotation.csv @@ -0,0 +1,9 @@ +color,x,y,z +YELLOW,-0.12977,-0.00068,0.78800 +BLUE,-0.10624,0.00141,0.79000 +GREEN,-0.07864,-0.00005,0.78500 +RED,-0.05020,-0.00077,0.79198 +YELLOW,-0.02455,-0.00374,0.79202 +BLUE,0.00030,-0.00575,0.79096 +GREEN,0.02670,-0.00593,0.78900 +RED,0.05533,-0.00387,0.80101 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/11/color.jpg b/src/python/arcor2_cube_detector/data/dataset/11/color.jpg new file mode 100644 index 00000000..356b71e0 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/11/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1f5ef3164c7805195bd1e65176eb8c5fabd64f3d407d371ae6bc1e1ef6f9957c +size 443068 diff --git a/src/python/arcor2_cube_detector/data/dataset/11/depth.png b/src/python/arcor2_cube_detector/data/dataset/11/depth.png new file mode 100644 index 00000000..99704bde --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/11/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50a921368f0910b75c8beab941fef65b647148e48459c646ccfc86350622a16d +size 392547 diff --git a/src/python/arcor2_cube_detector/data/dataset/12/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/12/annotation.csv new file mode 100644 index 00000000..ac60a437 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/12/annotation.csv @@ -0,0 +1,9 @@ +color,x,y,z +YELLOW,-0.32112,-0.24019,0.94104 +BLUE,-0.29562,-0.24322,0.94297 +GREEN,-0.27053,-0.24934,0.94403 +RED,-0.24553,-0.25633,0.95000 +YELLOW,-0.21938,-0.26502,0.95387 +BLUE,-0.19541,-0.27190,0.95699 +GREEN,-0.16919,-0.27575,0.96189 +RED,-0.14442,-0.28375,0.96594 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/12/color.jpg b/src/python/arcor2_cube_detector/data/dataset/12/color.jpg new file mode 100644 index 00000000..058d2907 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/12/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2002bad89b684f92a5ce8e376500fd5300d084a3592bc23f6b0ab18e245f9938 +size 443521 diff --git a/src/python/arcor2_cube_detector/data/dataset/12/depth.png b/src/python/arcor2_cube_detector/data/dataset/12/depth.png new file mode 100644 index 00000000..dfbbca3f --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/12/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d78847ceacad8d98b6dcfd1e09167106e7f0762d014fda11825bf173db1164b +size 393546 diff --git a/src/python/arcor2_cube_detector/data/dataset/13/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/13/annotation.csv new file mode 100644 index 00000000..6d2d1555 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/13/annotation.csv @@ -0,0 +1,6 @@ +color,x,y,z +RED,-0.21603,-0.04716,0.80100 +RED,-0.14710,-0.20010,0.93300 +RED,-0.02130,-0.02520,0.80800 +RED,0.00558,0.10320,0.81998 +RED,0.10774,-0.03445,0.80598 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/13/color.jpg b/src/python/arcor2_cube_detector/data/dataset/13/color.jpg new file mode 100644 index 00000000..5ea65950 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/13/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c6524f3964e3c1bcfe9ff30a29af523a53fcd789b0a91a3f88dff3e8393d074d +size 434363 diff --git a/src/python/arcor2_cube_detector/data/dataset/13/depth.png b/src/python/arcor2_cube_detector/data/dataset/13/depth.png new file mode 100644 index 00000000..08256a01 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/13/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:997b015d6936a70167f0415974b19614fcb2761da5ffc68634c81a564be8ce74 +size 398277 diff --git a/src/python/arcor2_cube_detector/data/dataset/14/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/14/annotation.csv new file mode 100644 index 00000000..885d3f29 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/14/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +BLUE,-0.30735,-0.05660,0.80000 +BLUE,-0.25376,-0.04771,0.79800 +BLUE,-0.19626,-0.04327,0.79800 +BLUE,-0.14325,-0.04530,0.80094 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/14/color.jpg b/src/python/arcor2_cube_detector/data/dataset/14/color.jpg new file mode 100644 index 00000000..be7ee7bf --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/14/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eef2e87f9d4e45bf0b69af23e503c97f29c703686e8f60109e36c8b08c434cf0 +size 434818 diff --git a/src/python/arcor2_cube_detector/data/dataset/14/depth.png b/src/python/arcor2_cube_detector/data/dataset/14/depth.png new file mode 100644 index 00000000..1e5e26e8 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/14/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fbd199c57f4459e3d1260f1a01d229deadf00624ffc510886638681e2cfebf8c +size 397797 diff --git a/src/python/arcor2_cube_detector/data/dataset/15/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/15/annotation.csv new file mode 100644 index 00000000..82be35f1 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/15/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +YELLOW,-0.18143,-0.13225,0.43900 +BLUE,-0.11206,-0.12982,0.43595 +RED,-0.04733,-0.13075,0.44094 +GREEN,0.02462,-0.12784,0.43795 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/15/color.jpg b/src/python/arcor2_cube_detector/data/dataset/15/color.jpg new file mode 100644 index 00000000..801fe5d2 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/15/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:69759b33410e13c4f719d4828132190a5c47ef918564e9cdcf831482cbb9de1c +size 430712 diff --git a/src/python/arcor2_cube_detector/data/dataset/15/depth.png b/src/python/arcor2_cube_detector/data/dataset/15/depth.png new file mode 100644 index 00000000..ead93464 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/15/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:028c6c216a9a0a3f102f8c610ab63b4e205105c466b621d43fc686932959ba00 +size 200506 diff --git a/src/python/arcor2_cube_detector/data/dataset/16/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/16/annotation.csv new file mode 100644 index 00000000..16f2a537 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/16/annotation.csv @@ -0,0 +1,4 @@ +color,x,y,z +YELLOW,-0.29776,-0.13967,0.44200 +BLUE,-0.24263,-0.13893,0.43881 +RED,0.21195,-0.12909,0.44004 diff --git a/src/python/arcor2_cube_detector/data/dataset/16/color.jpg b/src/python/arcor2_cube_detector/data/dataset/16/color.jpg new file mode 100644 index 00000000..22c22e73 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/16/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:722261669f9f232727b9bdd2fd4a3ce18ce90cd371f000460325d9c94614502f +size 423879 diff --git a/src/python/arcor2_cube_detector/data/dataset/16/depth.png b/src/python/arcor2_cube_detector/data/dataset/16/depth.png new file mode 100644 index 00000000..10926fd0 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/16/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:818ed3d55e7f224da6c67e0f3f5e8b687b7cc199ef05a5c2e35a87d8620d8260 +size 196481 diff --git a/src/python/arcor2_cube_detector/data/dataset/17/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/17/annotation.csv new file mode 100644 index 00000000..a94ff4ce --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/17/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +YELLOW,-0.17945,-0.12829,0.43700 +BLUE,-0.11340,-0.13128,0.43700 +RED,-0.04929,-0.12892,0.44600 +GREEN,0.01573,-0.13042,0.43700 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/17/color.jpg b/src/python/arcor2_cube_detector/data/dataset/17/color.jpg new file mode 100644 index 00000000..99640cb5 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/17/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:87f037e07e238b1beccf5415b625ba1107f33d5058efe5f001c81f975c8a6c4c +size 427266 diff --git a/src/python/arcor2_cube_detector/data/dataset/17/depth.png b/src/python/arcor2_cube_detector/data/dataset/17/depth.png new file mode 100644 index 00000000..f6efa2e0 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/17/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:723387f8af556375aa1e776dc2cdd53bd8873ee0756bc6a830f519de20400c79 +size 202771 diff --git a/src/python/arcor2_cube_detector/data/dataset/18/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/18/annotation.csv new file mode 100644 index 00000000..3f22cc5f --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/18/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +YELLOW,-0.09756,-0.13089,0.44093 +BLUE,-0.07300,-0.12902,0.43694 +RED,-0.04408,-0.12873,0.44396 +GREEN,-0.01808,-0.12854,0.43790 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/18/color.jpg b/src/python/arcor2_cube_detector/data/dataset/18/color.jpg new file mode 100644 index 00000000..b4782dc2 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/18/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83eebbb63089155fa950aee0e8bc8dd6eb6691c1abfafde6f1a5fce3c9d3d8e3 +size 424012 diff --git a/src/python/arcor2_cube_detector/data/dataset/18/depth.png b/src/python/arcor2_cube_detector/data/dataset/18/depth.png new file mode 100644 index 00000000..cdf1de2f --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/18/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d198dab1439938527527aec156077c464ab5f30c58b57aee0405478f2acaeea +size 194298 diff --git a/src/python/arcor2_cube_detector/data/dataset/19/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/19/annotation.csv new file mode 100644 index 00000000..d77f1e6d --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/19/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +YELLOW,-0.29426,-0.13825,0.44100 +BLUE,-0.26616,-0.13690,0.43700 +RED,-0.23751,-0.13605,0.44100 +GREEN,-0.21151,-0.13604,0.43900 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/19/color.jpg b/src/python/arcor2_cube_detector/data/dataset/19/color.jpg new file mode 100644 index 00000000..4a44cc4a --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/19/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1be129bb1cc8aa6850d027d4c61e50f7b8d8f29e407d18b6f78405077b142c68 +size 426483 diff --git a/src/python/arcor2_cube_detector/data/dataset/19/depth.png b/src/python/arcor2_cube_detector/data/dataset/19/depth.png new file mode 100644 index 00000000..8eaf7bca --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/19/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:34a202603a335b8165b84296d2f0e956691f4b9b6e27076a0ef5d53d50175ebd +size 194350 diff --git a/src/python/arcor2_cube_detector/data/dataset/2/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/2/annotation.csv new file mode 100644 index 00000000..22308dc2 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/2/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +YELLOW,-0.14445,-0.02228,0.80206 +BLUE,-0.07523,-0.02745,0.79897 +RED,-0.00516,-0.02365,0.80395 +GREEN,0.05038,-0.02988,0.80303 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/2/color.jpg b/src/python/arcor2_cube_detector/data/dataset/2/color.jpg new file mode 100644 index 00000000..6ac44ae5 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/2/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:45863b99863778432982b9a9812bebdf2b14b685e91e3ba83ae232b747244971 +size 445701 diff --git a/src/python/arcor2_cube_detector/data/dataset/2/depth.png b/src/python/arcor2_cube_detector/data/dataset/2/depth.png new file mode 100644 index 00000000..bca121e6 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/2/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:714757e3ca0bcd37683219d5c23c5f8a24e1c08a3cd89d10628ab685cda83309 +size 392800 diff --git a/src/python/arcor2_cube_detector/data/dataset/20/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/20/annotation.csv new file mode 100644 index 00000000..2fbc9e68 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/20/annotation.csv @@ -0,0 +1,4 @@ +color,x,y,z +YELLOW,0.18514,-0.10977,0.42800 +BLUE,0.21695,-0.12356,0.43300 +RED,0.24285,-0.13263,0.44800 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/20/color.jpg b/src/python/arcor2_cube_detector/data/dataset/20/color.jpg new file mode 100644 index 00000000..6e7e34a3 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/20/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7f55a31bebbb04bab05988510287f6fb4a59b7ee0b6508cd28fb2590578b1149 +size 429237 diff --git a/src/python/arcor2_cube_detector/data/dataset/20/depth.png b/src/python/arcor2_cube_detector/data/dataset/20/depth.png new file mode 100644 index 00000000..f1081500 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/20/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:33ff1d579fa2dca82187e89f6323a5890281751a408b228995c480ac20fe185c +size 192072 diff --git a/src/python/arcor2_cube_detector/data/dataset/21/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/21/annotation.csv new file mode 100644 index 00000000..8725b91d --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/21/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +YELLOW,-0.16882,-0.27622,0.59297 +BLUE,-0.09735,-0.27099,0.58797 +RED,-0.01577,-0.26573,0.58797 +GREEN,0.05624,-0.26315,0.58389 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/21/color.jpg b/src/python/arcor2_cube_detector/data/dataset/21/color.jpg new file mode 100644 index 00000000..199cd748 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/21/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4607d4875af279e71f9d323af26e3aacf9ea84d24134402c35b1886e3329a543 +size 426827 diff --git a/src/python/arcor2_cube_detector/data/dataset/21/depth.png b/src/python/arcor2_cube_detector/data/dataset/21/depth.png new file mode 100644 index 00000000..aaf3d0b2 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/21/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:72565d5941a580799c314083ff87af4ffc7e7319d2b504461c0d67dabd4f881b +size 191192 diff --git a/src/python/arcor2_cube_detector/data/dataset/22/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/22/annotation.csv new file mode 100644 index 00000000..5fecb675 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/22/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +YELLOW,-0.31056,-0.29889,0.60700 +BLUE,-0.22150,-0.30772,0.60994 +RED,0.17734,-0.32571,0.62311 +GREEN,0.26939,-0.31663,0.61611 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/22/color.jpg b/src/python/arcor2_cube_detector/data/dataset/22/color.jpg new file mode 100644 index 00000000..b997800f --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/22/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:43cd71b2a0df49963ca644032b8b15a9346cf260ba49769a29adeabc69d1a3a1 +size 427523 diff --git a/src/python/arcor2_cube_detector/data/dataset/22/depth.png b/src/python/arcor2_cube_detector/data/dataset/22/depth.png new file mode 100644 index 00000000..5287e2a2 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/22/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ab4c5083459577f8fbbc8e9bdc8b3669e22e0057f17d86d6b24989ce3e79eeeb +size 190801 diff --git a/src/python/arcor2_cube_detector/data/dataset/23/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/23/annotation.csv new file mode 100644 index 00000000..bfe62774 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/23/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +BLUE,-0.11969,0.07008,0.38694 +YELLOW,-0.06352,0.07310,0.39491 +RED,-0.00354,0.07290,0.38777 +GREEN,0.05709,0.07237,0.38608 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/23/color.jpg b/src/python/arcor2_cube_detector/data/dataset/23/color.jpg new file mode 100644 index 00000000..1f8cd508 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/23/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:358f81f9fe1a011b2ae5df836e148217c4c72b5d6f6f1fdcceec3f6788f8d40f +size 428360 diff --git a/src/python/arcor2_cube_detector/data/dataset/23/depth.png b/src/python/arcor2_cube_detector/data/dataset/23/depth.png new file mode 100644 index 00000000..848aca9b --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/23/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b8a0f9d12d92f87eec5c5411bc82beed55a9e63e3af8ae8e1e9f93233e6f7bd6 +size 192687 diff --git a/src/python/arcor2_cube_detector/data/dataset/24/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/24/annotation.csv new file mode 100644 index 00000000..842017a3 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/24/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +BLUE,-0.13695,0.06959,0.38797 +YELLOW,-0.06770,0.07479,0.39096 +RED,0.00313,0.07164,0.38999 +GREEN,0.06762,0.07224,0.38400 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/24/color.jpg b/src/python/arcor2_cube_detector/data/dataset/24/color.jpg new file mode 100644 index 00000000..418c5f72 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/24/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:79f6250ad927aea4fa7e597fabd1902ce6bba232fce458043cb2e1f44ed125c1 +size 434417 diff --git a/src/python/arcor2_cube_detector/data/dataset/24/depth.png b/src/python/arcor2_cube_detector/data/dataset/24/depth.png new file mode 100644 index 00000000..e65e25c2 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/24/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8251c3b29d135cd74559ef68bd1c92773a936e2ab9a2f94ac1a676cc727d8e6b +size 194682 diff --git a/src/python/arcor2_cube_detector/data/dataset/25/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/25/annotation.csv new file mode 100644 index 00000000..16bbb261 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/25/annotation.csv @@ -0,0 +1,9 @@ +color,x,y,z +RED,-0.28164,-0.15223,0.44900 +RED,-0.20287,-0.11513,0.42802 +YELLOW,-0.13259,-0.11343,0.42997 +YELLOW,-0.08207,-0.11522,0.43298 +GREEN,0.03014,-0.12698,0.43500 +GREEN,0.07544,-0.13026,0.43698 +BLUE,0.15897,-0.15013,0.44903 +BLUE,0.22912,-0.15181,0.44698 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/25/color.jpg b/src/python/arcor2_cube_detector/data/dataset/25/color.jpg new file mode 100644 index 00000000..75c3a371 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/25/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:70c51b5eae3922be0c6ff75a929428ad828897e217296966585b20e69d3efd98 +size 436597 diff --git a/src/python/arcor2_cube_detector/data/dataset/25/depth.png b/src/python/arcor2_cube_detector/data/dataset/25/depth.png new file mode 100644 index 00000000..fd0a7e23 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/25/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4444d3c4d00f91b0c4926c0d360b8861de2ca655e998ffca8b06b05aa07f8424 +size 210854 diff --git a/src/python/arcor2_cube_detector/data/dataset/26/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/26/annotation.csv new file mode 100644 index 00000000..ab7a3999 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/26/annotation.csv @@ -0,0 +1,9 @@ +color,x,y,z +YELLOW,-0.06053,-0.12870,0.44100 +BLUE,-0.03587,-0.12726,0.43903 +GREEN,-0.00976,-0.12870,0.43902 +RED,0.01733,-0.12973,0.44299 +YELLOW,0.04323,-0.13061,0.43994 +BLUE,0.06873,-0.13044,0.43700 +GREEN,0.09571,-0.12996,0.43700 +RED,0.12246,-0.13046,0.44000 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/26/color.jpg b/src/python/arcor2_cube_detector/data/dataset/26/color.jpg new file mode 100644 index 00000000..abca5be2 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/26/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d79e18de75561569f8dd02cbb566626aa79746111f0fa0c3283116a40f55528a +size 434036 diff --git a/src/python/arcor2_cube_detector/data/dataset/26/depth.png b/src/python/arcor2_cube_detector/data/dataset/26/depth.png new file mode 100644 index 00000000..27756736 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/26/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ff2361a530d8885cab6a7b6d219411fa03687e5e61250f57a5f055e8e82970e +size 199971 diff --git a/src/python/arcor2_cube_detector/data/dataset/27/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/27/annotation.csv new file mode 100644 index 00000000..e6890625 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/27/annotation.csv @@ -0,0 +1,9 @@ +color,x,y,z +YELLOW,-0.26823,-0.30058,0.60700 +BLUE,-0.23752,-0.30734,0.60900 +GREEN,-0.21103,-0.31309,0.61100 +RED,-0.18611,-0.32150,0.61800 +YELLOW,-0.16229,-0.32943,0.62403 +BLUE,-0.13523,-0.33349,0.62395 +GREEN,-0.11055,-0.34047,0.62794 +RED,-0.08791,-0.34771,0.63392 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/27/color.jpg b/src/python/arcor2_cube_detector/data/dataset/27/color.jpg new file mode 100644 index 00000000..b0039cac --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/27/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e1b5c55324d4a30da9fe0bbee0bd3b9a7d8c6e773e8b20dcea33acf62fbe0ad3 +size 439854 diff --git a/src/python/arcor2_cube_detector/data/dataset/27/depth.png b/src/python/arcor2_cube_detector/data/dataset/27/depth.png new file mode 100644 index 00000000..c94c47ed --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/27/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:206e58861250ef7ffd8694453efcf748dd0cf74c01ca09b6e607bf8d04697dc5 +size 188615 diff --git a/src/python/arcor2_cube_detector/data/dataset/28/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/28/annotation.csv new file mode 100644 index 00000000..3fe749e1 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/28/annotation.csv @@ -0,0 +1,6 @@ +color,x,y,z +RED,-0.17587,-0.27774,0.59400 +RED,-0.15920,-0.13169,0.43800 +RED,-0.01538,-0.13310,0.44200 +RED,-0.01367,0.05615,0.40097 +RED,0.14602,-0.13453,0.44004 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/28/color.jpg b/src/python/arcor2_cube_detector/data/dataset/28/color.jpg new file mode 100644 index 00000000..e1b2c37a --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/28/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2105b697aacfcc9a9fd29cb47cca58480a4e88807524c2c296b1299304199409 +size 438171 diff --git a/src/python/arcor2_cube_detector/data/dataset/28/depth.png b/src/python/arcor2_cube_detector/data/dataset/28/depth.png new file mode 100644 index 00000000..cbd55dbe --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/28/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b497263d9197cd9e991a8cf7df63de2dd81f029a7038fb1da94dee63c3c8a307 +size 200081 diff --git a/src/python/arcor2_cube_detector/data/dataset/29/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/29/annotation.csv new file mode 100644 index 00000000..c5e64004 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/29/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +BLUE,-0.23283,-0.13213,0.43499 +BLUE,-0.15993,-0.12741,0.43890 +BLUE,-0.08372,-0.12902,0.43699 +BLUE,-0.00983,-0.12621,0.43698 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/29/color.jpg b/src/python/arcor2_cube_detector/data/dataset/29/color.jpg new file mode 100644 index 00000000..05039fa0 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/29/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3db703a9dcaf1cbad110e727ac31986ab36b7ccd7b734550c7ed1f0c67d0520d +size 438317 diff --git a/src/python/arcor2_cube_detector/data/dataset/29/depth.png b/src/python/arcor2_cube_detector/data/dataset/29/depth.png new file mode 100644 index 00000000..b1b18ded --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/29/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:237a7b700e4515ca794ffd38993e0bc36e0d54a3ecd2f40b5d6fef036bb7c168 +size 200620 diff --git a/src/python/arcor2_cube_detector/data/dataset/3/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/3/annotation.csv new file mode 100644 index 00000000..a63a82b9 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/3/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +YELLOW,-0.09868,-0.03345,0.80100 +BLUE,-0.07039,-0.03276,0.79800 +RED,-0.04640,-0.03267,0.80300 +GREEN,-0.02044,-0.03297,0.80000 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/3/color.jpg b/src/python/arcor2_cube_detector/data/dataset/3/color.jpg new file mode 100644 index 00000000..94bfbb46 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/3/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:43789967552b699b35b62b0cf23542dbd8d3d4095fc57d0484d536d6c0ebaac2 +size 445389 diff --git a/src/python/arcor2_cube_detector/data/dataset/3/depth.png b/src/python/arcor2_cube_detector/data/dataset/3/depth.png new file mode 100644 index 00000000..e3729b8c --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/3/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a177ffb46c59e9e1f142d2fa0a5a3fe1eb66e621a294ced0222cef33e5a4d4fc +size 393633 diff --git a/src/python/arcor2_cube_detector/data/dataset/30/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/30/annotation.csv new file mode 100644 index 00000000..cbc4ff73 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/30/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +YELLOW,-0.24264,-0.17713,1.01800 +BLUE,-0.17235,-0.17363,1.01690 +RED,-0.10205,-0.17702,1.02398 +GREEN,-0.01730,-0.18014,1.02092 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/30/color.jpg b/src/python/arcor2_cube_detector/data/dataset/30/color.jpg new file mode 100644 index 00000000..a9193814 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/30/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0574b3213fe1b1b29a7871cbc8dd7bf951b62fbfa118905db0a21555a4e61601 +size 500267 diff --git a/src/python/arcor2_cube_detector/data/dataset/30/depth.png b/src/python/arcor2_cube_detector/data/dataset/30/depth.png new file mode 100644 index 00000000..79e79450 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/30/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0b8ffab072ef8af2535b4ead384550ceeae7748062322a85dc8270df96d56c8d +size 446462 diff --git a/src/python/arcor2_cube_detector/data/dataset/31/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/31/annotation.csv new file mode 100644 index 00000000..d60e531f --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/31/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +YELLOW,-0.29296,-0.17617,1.01579 +BLUE,-0.21561,-0.17287,1.01504 +RED,0.08411,-0.17110,1.02690 +GREEN,0.14932,-0.17444,1.02481 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/31/color.jpg b/src/python/arcor2_cube_detector/data/dataset/31/color.jpg new file mode 100644 index 00000000..9e582da0 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/31/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6cd1eb50927de6d41d609ab4d836ede6f01a466bcc9f2703d724a35f0d4a6578 +size 506592 diff --git a/src/python/arcor2_cube_detector/data/dataset/31/depth.png b/src/python/arcor2_cube_detector/data/dataset/31/depth.png new file mode 100644 index 00000000..f2b0ef0b --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/31/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:241a93eb4d4c1690c842ef87ac8f49497da1856adb191b8013a13d8d9991821a +size 451526 diff --git a/src/python/arcor2_cube_detector/data/dataset/32/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/32/annotation.csv new file mode 100644 index 00000000..71f65dbc --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/32/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +YELLOW,-0.21774,-0.16960,1.01513 +BLUE,-0.14892,-0.16869,1.01505 +RED,-0.06182,-0.17577,1.02077 +GREEN,0.01891,-0.17752,1.02003 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/32/color.jpg b/src/python/arcor2_cube_detector/data/dataset/32/color.jpg new file mode 100644 index 00000000..bc2fd403 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/32/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4dc712332d1161468d6d1720f696357f78093350e850b02c1df9d83d2c78a90c +size 497061 diff --git a/src/python/arcor2_cube_detector/data/dataset/32/depth.png b/src/python/arcor2_cube_detector/data/dataset/32/depth.png new file mode 100644 index 00000000..bbd60fec --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/32/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa73a6933dd94ff6bcfcdd0f429324e1e70e2cbf48e1839921b8940a493c95e2 +size 448571 diff --git a/src/python/arcor2_cube_detector/data/dataset/33/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/33/annotation.csv new file mode 100644 index 00000000..6f389fbc --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/33/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +YELLOW,-0.12356,-0.17530,1.02284 +BLUE,-0.09606,-0.17402,1.02178 +RED,-0.06996,-0.17526,1.02208 +GREEN,-0.04540,-0.17379,1.02114 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/33/color.jpg b/src/python/arcor2_cube_detector/data/dataset/33/color.jpg new file mode 100644 index 00000000..25a17db4 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/33/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c1955d41c166078e8ba10dddda890189f36c76a9a28c35d2206187f4180d0f64 +size 501492 diff --git a/src/python/arcor2_cube_detector/data/dataset/33/depth.png b/src/python/arcor2_cube_detector/data/dataset/33/depth.png new file mode 100644 index 00000000..94b74326 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/33/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cea1fad1ed419809d2f12992f25974bab19d15db5e062aada7d6c9da4576389e +size 448991 diff --git a/src/python/arcor2_cube_detector/data/dataset/34/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/34/annotation.csv new file mode 100644 index 00000000..4608c07c --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/34/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +YELLOW,-0.33918,-0.17566,1.01386 +BLUE,-0.31222,-0.17437,1.01396 +RED,-0.28507,-0.17461,1.01602 +GREEN,-0.25800,-0.17523,1.01066 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/34/color.jpg b/src/python/arcor2_cube_detector/data/dataset/34/color.jpg new file mode 100644 index 00000000..28f7f3c3 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/34/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b76f8d5c5202ce7b84869dff53d0d73c39e817b6f99e428610d4bd140b9ee718 +size 501663 diff --git a/src/python/arcor2_cube_detector/data/dataset/34/depth.png b/src/python/arcor2_cube_detector/data/dataset/34/depth.png new file mode 100644 index 00000000..7816a91f --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/34/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ff9643cdbf62e74d5f801a992af13bdda1d2514993496292edb3e9460f159a74 +size 446849 diff --git a/src/python/arcor2_cube_detector/data/dataset/35/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/35/annotation.csv new file mode 100644 index 00000000..e338bfd5 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/35/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +YELLOW,0.50438,-1.30457,2.28051 +BLUE,0.17035,-0.16648,1.02429 +RED,0.19628,-0.18131,1.02969 +GREEN,0.21643,-0.19571,1.03064 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/35/color.jpg b/src/python/arcor2_cube_detector/data/dataset/35/color.jpg new file mode 100644 index 00000000..b7a5810e --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/35/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8fbc6b5d150d37222e83ebb60fdb9935a9dab15ce9a80ff79b61489f0c108bd1 +size 501549 diff --git a/src/python/arcor2_cube_detector/data/dataset/35/depth.png b/src/python/arcor2_cube_detector/data/dataset/35/depth.png new file mode 100644 index 00000000..3f83b6ac --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/35/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7fb34c860322909042f8a6a538a408c8c4219d78862c0b9d0344b21fdcafba05 +size 449944 diff --git a/src/python/arcor2_cube_detector/data/dataset/36/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/36/annotation.csv new file mode 100644 index 00000000..520416b4 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/36/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +YELLOW,-0.12764,-0.32591,1.11083 +BLUE,-0.02926,-0.32696,1.11083 +RED,0.04759,-0.32699,1.11599 +GREEN,0.12265,-0.33108,1.11588 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/36/color.jpg b/src/python/arcor2_cube_detector/data/dataset/36/color.jpg new file mode 100644 index 00000000..5160be31 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/36/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c753d8db444d3447f0eb385f069be51a4f981717552c81399c6fb12f8b50f27f +size 499318 diff --git a/src/python/arcor2_cube_detector/data/dataset/36/depth.png b/src/python/arcor2_cube_detector/data/dataset/36/depth.png new file mode 100644 index 00000000..fa1b1daa --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/36/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:578a974bef762436c1aaa084e3cbc638dc0b50353871b8782cf4a16f749a46ee +size 449401 diff --git a/src/python/arcor2_cube_detector/data/dataset/37/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/37/annotation.csv new file mode 100644 index 00000000..dbf2cae0 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/37/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +YELLOW,-0.31963,-0.34182,1.10498 +BLUE,-0.23144,-0.35612,1.10988 +RED,0.25523,-0.43349,1.13807 +GREEN,0.40480,-0.43066,1.13776 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/37/color.jpg b/src/python/arcor2_cube_detector/data/dataset/37/color.jpg new file mode 100644 index 00000000..68f500ad --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/37/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:22de81bb92b751232f8cc28bfe571a5ac4435af966068167d3348047af80388c +size 500213 diff --git a/src/python/arcor2_cube_detector/data/dataset/37/depth.png b/src/python/arcor2_cube_detector/data/dataset/37/depth.png new file mode 100644 index 00000000..df476a87 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/37/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:71c858dfddb8707824d3bc60aa88487061d038c58f68d34cf6a8bd42772ed1a6 +size 450699 diff --git a/src/python/arcor2_cube_detector/data/dataset/38/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/38/annotation.csv new file mode 100644 index 00000000..3436dc0b --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/38/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +BLUE,-0.20766,0.06611,1.03194 +YELLOW,-0.12085,0.06757,1.04896 +RED,-0.03730,0.05926,1.03881 +GREEN,0.07170,0.05726,1.03800 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/38/color.jpg b/src/python/arcor2_cube_detector/data/dataset/38/color.jpg new file mode 100644 index 00000000..7acc21d8 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/38/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af96fb1a7448e937ee726b9f628babab7bfb10efede91c5b31a3815f73004b7e +size 489811 diff --git a/src/python/arcor2_cube_detector/data/dataset/38/depth.png b/src/python/arcor2_cube_detector/data/dataset/38/depth.png new file mode 100644 index 00000000..48a9c1a6 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/38/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d4cfb8fe475e15d7f2297b1b7c5eb0c72296b2c282f8b25917a939a61fd33836 +size 454021 diff --git a/src/python/arcor2_cube_detector/data/dataset/39/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/39/annotation.csv new file mode 100644 index 00000000..a28cd829 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/39/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +BLUE,-0.21661,0.05594,1.03201 +YELLOW,-0.11741,0.05467,1.03995 +RED,-0.02828,0.05594,1.03993 +GREEN,0.06574,0.05616,1.03809 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/39/color.jpg b/src/python/arcor2_cube_detector/data/dataset/39/color.jpg new file mode 100644 index 00000000..5775127c --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/39/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fdcce716ca51fd7f71c5a2f7235443b20055af06227f588bdc10a0f8e442b732 +size 490674 diff --git a/src/python/arcor2_cube_detector/data/dataset/39/depth.png b/src/python/arcor2_cube_detector/data/dataset/39/depth.png new file mode 100644 index 00000000..2426d590 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/39/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8142c00625cc1a49a887f8a225ce609ac5380f1ed8fb067cd008ce97946eb349 +size 451668 diff --git a/src/python/arcor2_cube_detector/data/dataset/4/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/4/annotation.csv new file mode 100644 index 00000000..199dd221 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/4/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +YELLOW,-0.36565,-0.04730,0.79600 +BLUE,-0.33920,-0.04670,0.79700 +RED,-0.31334,-0.04600,0.80000 +GREEN,-0.28204,-0.04751,0.79701 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/4/color.jpg b/src/python/arcor2_cube_detector/data/dataset/4/color.jpg new file mode 100644 index 00000000..9ab1c2cc --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/4/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:13b10fc9b89064e137c8a047feb642422a280d450b7ba0d5dbb8f3111cf94e5e +size 444842 diff --git a/src/python/arcor2_cube_detector/data/dataset/4/depth.png b/src/python/arcor2_cube_detector/data/dataset/4/depth.png new file mode 100644 index 00000000..180fd8ed --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/4/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7750a8157f54748371718f544e23b7ccaadcc60eb672c048d24999a87a7981bd +size 395724 diff --git a/src/python/arcor2_cube_detector/data/dataset/40/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/40/annotation.csv new file mode 100644 index 00000000..879883e5 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/40/annotation.csv @@ -0,0 +1,9 @@ +color,x,y,z +RED,-0.34595,-0.19034,1.01867 +RED,-0.28711,-0.14391,1.01686 +YELLOW,-0.20590,-0.14517,1.01294 +YELLOW,-0.15144,-0.14419,1.01394 +GREEN,-0.07482,-0.16792,1.02091 +GREEN,-0.02402,-0.16592,1.01801 +BLUE,0.09040,-0.19439,1.02883 +BLUE,0.15749,-0.19826,1.03182 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/40/color.jpg b/src/python/arcor2_cube_detector/data/dataset/40/color.jpg new file mode 100644 index 00000000..afc1f698 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/40/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:079811c11b5b47c8088c2e1bc2cc865613025e52b761205adeddb88ed93b151b +size 499764 diff --git a/src/python/arcor2_cube_detector/data/dataset/40/depth.png b/src/python/arcor2_cube_detector/data/dataset/40/depth.png new file mode 100644 index 00000000..5cd709a5 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/40/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7bb6fda13c64b89d4393b00c32155d38531c06dacdd5836e86e4e46b22b99574 +size 451185 diff --git a/src/python/arcor2_cube_detector/data/dataset/41/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/41/annotation.csv new file mode 100644 index 00000000..ee1ed64c --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/41/annotation.csv @@ -0,0 +1,9 @@ +color,x,y,z +YELLOW,-0.14063,-0.17277,1.01900 +BLUE,-0.11494,-0.17341,1.01701 +GREEN,-0.09061,-0.17292,1.01801 +RED,-0.06469,-0.17378,1.02200 +YELLOW,-0.03850,-0.17337,1.02200 +BLUE,-0.01159,-0.17227,1.01600 +GREEN,0.01297,-0.17254,1.01801 +RED,0.03954,-0.17150,1.02201 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/41/color.jpg b/src/python/arcor2_cube_detector/data/dataset/41/color.jpg new file mode 100644 index 00000000..56e60703 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/41/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d2669fb7db4671ab7ef262e9acdc4d6205243205801198c5768d2d3b3779b6a +size 492368 diff --git a/src/python/arcor2_cube_detector/data/dataset/41/depth.png b/src/python/arcor2_cube_detector/data/dataset/41/depth.png new file mode 100644 index 00000000..9d0d9f3d --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/41/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3069b11e43f6db9100262c0c837ee170563a8601ba3bf14a840c55fe5759013f +size 450543 diff --git a/src/python/arcor2_cube_detector/data/dataset/42/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/42/annotation.csv new file mode 100644 index 00000000..946499c2 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/42/annotation.csv @@ -0,0 +1,9 @@ +color,x,y,z +YELLOW,-0.29413,-0.35736,1.10692 +BLUE,-0.26697,-0.37302,1.10695 +GREEN,-0.24498,-0.38565,1.11092 +RED,-0.22381,-0.40020,1.11562 +YELLOW,-0.20261,-0.41666,1.12053 +BLUE,-0.18088,-0.42975,1.12094 +GREEN,-0.16123,-0.44333,1.12270 +RED,-0.13965,-0.45993,1.13072 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/42/color.jpg b/src/python/arcor2_cube_detector/data/dataset/42/color.jpg new file mode 100644 index 00000000..d6c0ecb0 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/42/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4250b5ac496cbfecc5065eda7657875f30cbb363653c00c6b392ff4b383376aa +size 495548 diff --git a/src/python/arcor2_cube_detector/data/dataset/42/depth.png b/src/python/arcor2_cube_detector/data/dataset/42/depth.png new file mode 100644 index 00000000..f958db97 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/42/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4620eefcf9d8d2ae21608a1687d8757d2734c488cb0056e88a3b6578df82ff9b +size 451978 diff --git a/src/python/arcor2_cube_detector/data/dataset/43/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/43/annotation.csv new file mode 100644 index 00000000..89842422 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/43/annotation.csv @@ -0,0 +1,6 @@ +color,x,y,z +RED,-0.22572,-0.16329,1.01270 +RED,-0.18630,-0.33550,1.11327 +RED,-0.03287,-0.17134,1.02292 +RED,0.04132,0.01186,1.05007 +RED,0.11268,-0.18442,1.02976 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/43/color.jpg b/src/python/arcor2_cube_detector/data/dataset/43/color.jpg new file mode 100644 index 00000000..e72bfa22 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/43/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e8adf1f39118ca484e7b3347b69a5a3d1f0a43edba406662044383433b0bb8c6 +size 495255 diff --git a/src/python/arcor2_cube_detector/data/dataset/43/depth.png b/src/python/arcor2_cube_detector/data/dataset/43/depth.png new file mode 100644 index 00000000..0efe887a --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/43/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:47930f19e37eb6cb60b790aa871660f4ab277e231811418c9e296577a016dfe8 +size 448380 diff --git a/src/python/arcor2_cube_detector/data/dataset/44/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/44/annotation.csv new file mode 100644 index 00000000..792a5876 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/44/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +BLUE,-0.19969,-0.17486,1.01471 +BLUE,-0.11560,-0.18025,1.01968 +BLUE,-0.00526,-0.17899,1.02463 +BLUE,0.09020,-0.16621,1.02370 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/44/color.jpg b/src/python/arcor2_cube_detector/data/dataset/44/color.jpg new file mode 100644 index 00000000..9c3bff0b --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/44/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:405e0c5d31ab5ecd8d33c1cf3188d334f09d0fe597a65312f06c1c253d98775f +size 494577 diff --git a/src/python/arcor2_cube_detector/data/dataset/44/depth.png b/src/python/arcor2_cube_detector/data/dataset/44/depth.png new file mode 100644 index 00000000..e93a36d8 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/44/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0da606d466aeabbf856b6812ea9bc1375bd6e8edcf408cda3fe09a3e60dea68b +size 448237 diff --git a/src/python/arcor2_cube_detector/data/dataset/5/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/5/annotation.csv new file mode 100644 index 00000000..bca9dd3c --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/5/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +YELLOW,0.17687,-0.01992,0.80382 +BLUE,0.20357,-0.04220,0.80713 +RED,0.22402,-0.05644,0.81568 +GREEN,0.24396,-0.06374,0.82985 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/5/color.jpg b/src/python/arcor2_cube_detector/data/dataset/5/color.jpg new file mode 100644 index 00000000..1cb40f8b --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/5/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:00c4ee76573f5c8c6b7323f7a71f9a37e0e04860a8d6babbbb59bdee3168b5ff +size 446408 diff --git a/src/python/arcor2_cube_detector/data/dataset/5/depth.png b/src/python/arcor2_cube_detector/data/dataset/5/depth.png new file mode 100644 index 00000000..5e1cccaa --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/5/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a9dd1aba820e0d8543c31802ad6537c3bb0fceb67dc49c92e2772ac4a2309dfd +size 394733 diff --git a/src/python/arcor2_cube_detector/data/dataset/6/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/6/annotation.csv new file mode 100644 index 00000000..d5fa456c --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/6/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +YELLOW,-0.18291,-0.19561,0.92999 +BLUE,-0.10142,-0.18821,0.92702 +RED,-0.03301,-0.19200,0.93102 +GREEN,0.04469,-0.19293,0.93100 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/6/color.jpg b/src/python/arcor2_cube_detector/data/dataset/6/color.jpg new file mode 100644 index 00000000..d8268fd8 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/6/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:77bae544773fd9cfab46da8a6b81e01fc53cc5c6793a217ddc6f5b73baf457d5 +size 448909 diff --git a/src/python/arcor2_cube_detector/data/dataset/6/depth.png b/src/python/arcor2_cube_detector/data/dataset/6/depth.png new file mode 100644 index 00000000..400d4743 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/6/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d6a4d8f32a7a5b25d92b81881da7652fb6f62336296052a6aa20eb31bf70dc4 +size 394559 diff --git a/src/python/arcor2_cube_detector/data/dataset/7/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/7/annotation.csv new file mode 100644 index 00000000..c9cfe805 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/7/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +YELLOW,-0.30125,-0.24612,0.94492 +BLUE,-0.18420,-0.23978,0.95088 +RED,0.16714,-0.24328,0.96471 +GREEN,0.27355,-0.25975,0.96981 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/7/color.jpg b/src/python/arcor2_cube_detector/data/dataset/7/color.jpg new file mode 100644 index 00000000..a20a7606 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/7/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:04dd167de4596d7f64d8ec34ab730852c439acc110d0fde885f28fdbb427fae8 +size 445535 diff --git a/src/python/arcor2_cube_detector/data/dataset/7/depth.png b/src/python/arcor2_cube_detector/data/dataset/7/depth.png new file mode 100644 index 00000000..1a661420 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/7/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:205a2587eb6b0ffc5c7f8468e60319abbfd2add288a43c79c29870a9685452e3 +size 395031 diff --git a/src/python/arcor2_cube_detector/data/dataset/8/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/8/annotation.csv new file mode 100644 index 00000000..94b0d25a --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/8/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +BLUE,-0.12964,0.11895,0.79682 +YELLOW,-0.06000,0.12030,0.80106 +RED,-0.00360,0.11845,0.80405 +GREEN,0.05577,0.11465,0.80100 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/8/color.jpg b/src/python/arcor2_cube_detector/data/dataset/8/color.jpg new file mode 100644 index 00000000..3c8259aa --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/8/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99b9ed34f0d35a8ba5e42ce32d4a55496d57d98e580445298fca7b6e21bbd793 +size 452680 diff --git a/src/python/arcor2_cube_detector/data/dataset/8/depth.png b/src/python/arcor2_cube_detector/data/dataset/8/depth.png new file mode 100644 index 00000000..cd9defab --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/8/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:410fa48ed27bd7562b461fd4b087b3624faa1756cf5578b2bf073de6a0fa63ac +size 395304 diff --git a/src/python/arcor2_cube_detector/data/dataset/9/annotation.csv b/src/python/arcor2_cube_detector/data/dataset/9/annotation.csv new file mode 100644 index 00000000..ba89ac83 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/9/annotation.csv @@ -0,0 +1,5 @@ +color,x,y,z +BLUE,-0.14371,0.12157,0.81800 +YELLOW,-0.07426,0.12157,0.81800 +RED,-0.00223,0.11399,0.80502 +GREEN,0.06038,0.11237,0.80201 \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/data/dataset/9/color.jpg b/src/python/arcor2_cube_detector/data/dataset/9/color.jpg new file mode 100644 index 00000000..cd0c03a9 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/9/color.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de4546b30196e59bba91761276bf52148f7441d700a9d932a4030905b6e6920c +size 451605 diff --git a/src/python/arcor2_cube_detector/data/dataset/9/depth.png b/src/python/arcor2_cube_detector/data/dataset/9/depth.png new file mode 100644 index 00000000..ef423b37 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/9/depth.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a293290cc2bc880d83e071d785b65b3d85caa637f3b808a883829444262a6793 +size 394739 diff --git a/src/python/arcor2_cube_detector/data/dataset/BUILD b/src/python/arcor2_cube_detector/data/dataset/BUILD new file mode 100644 index 00000000..58bef222 --- /dev/null +++ b/src/python/arcor2_cube_detector/data/dataset/BUILD @@ -0,0 +1,4 @@ +resources( + name="dataset", + sources=["*/color.jpg", "*/depth.png", "*/annotation.csv"], +) \ No newline at end of file diff --git a/src/python/arcor2_cube_detector/exceptions.py b/src/python/arcor2_cube_detector/exceptions.py new file mode 100644 index 00000000..f8ae361e --- /dev/null +++ b/src/python/arcor2_cube_detector/exceptions.py @@ -0,0 +1,13 @@ +from arcor2.flask import FlaskException, WebApiErrorFactory +from arcor2_cube_detector import __name__ as package_name + + +class CubeDetectorException(FlaskException): + service = package_name + + +class DetectorNotStarted(CubeDetectorException): + description = "Detector is not started." + + +WebApiError = WebApiErrorFactory.get_class(DetectorNotStarted) diff --git a/src/python/arcor2_cube_detector/py.typed b/src/python/arcor2_cube_detector/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/src/python/arcor2_cube_detector/scripts/BUILD b/src/python/arcor2_cube_detector/scripts/BUILD new file mode 100644 index 00000000..0de7ecd5 --- /dev/null +++ b/src/python/arcor2_cube_detector/scripts/BUILD @@ -0,0 +1,5 @@ +python_sources() + +arcor2_pex_binary(name="cube_detector") + +arcor2_pex_binary(name="dataset_evaluation", dependencies=["src/python/arcor2_cube_detector/data/dataset"]) diff --git a/src/python/arcor2_cube_detector/scripts/__init__.py b/src/python/arcor2_cube_detector/scripts/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/python/arcor2_cube_detector/scripts/cube_detector.py b/src/python/arcor2_cube_detector/scripts/cube_detector.py new file mode 100644 index 00000000..15f512cf --- /dev/null +++ b/src/python/arcor2_cube_detector/scripts/cube_detector.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python3 + +import argparse +import io +import os +import zipfile + +from flask import jsonify + +from arcor2 import env, rest +from arcor2.data.camera import CameraParameters +from arcor2.data.common import Pose, Position +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_cube_detector import version +from arcor2_cube_detector.cube_detector import Color, Cube, CubeDetector +from arcor2_cube_detector.exceptions import DetectorNotStarted, WebApiError + +logger = get_logger(__name__) + +URL = os.getenv("ARCOR2_CUBE_DETECTOR_URL", "http://0.0.0.0:5020") +URL_KINECT = os.getenv("ARCOR2_KINECT_AZURE_URL", "http://192.168.104.100:5017") +SERVICE_NAME = "Cube Detector Web API" + +app = create_app(__name__) + +_detector: CubeDetector | None = None +_mock: bool = False + + +@app.route("/detect/all", methods=["GET"]) +def detect_all() -> RespT: + """Detect cubes + --- + get: + description: Detects cubes in image. + tags: + - Synchronized + responses: + 200: + description: Ok + content: + application/json: + schema: + type: array + items: + $ref: Cube + 500: + description: "Error types: **General**, **KinectNotStarted**." + content: + application/json: + schema: + $ref: WebApiError + """ + if not _mock: + global _detector + + try: + kinect_started = rest.call(rest.Method.GET, f"{URL_KINECT}/state/started", return_type=bool) + except Arcor2Exception as e: + raise DetectorNotStarted("Detector is not started") from e + if not kinect_started: + raise DetectorNotStarted("Detector is not started") + + if _detector is None: + image = rest.get_image(f"{URL_KINECT}/color/image") + parameters = rest.call(rest.Method.GET, f"{URL_KINECT}/color/parameters", return_type=CameraParameters) + _detector = CubeDetector(parameters, image.width, image.height) + + synchronized = rest.call(rest.Method.GET, f"{URL_KINECT}/synchronized/image", return_type=io.BytesIO) + with zipfile.ZipFile(synchronized, mode="r") as zip: + color = zip.read("color.jpg") + depth = zip.read("depth.png") + color, depth = _detector.get_image_from_bytes(color, depth) + detected_cubes = _detector.detect_cubes(color, depth) + else: + detected_cubes = [Cube(Color.RED.name, Pose(Position(0, 0, 0))), Cube(Color.BLUE.name, Pose(Position(1, 1, 1)))] + + return jsonify(detected_cubes), 200 + + +def main() -> None: + parser = argparse.ArgumentParser(description=SERVICE_NAME) + parser.add_argument("-s", "--swagger", action="store_true", default=False) + parser.add_argument("-m", "--mock", action="store_true", default=env.get_bool("ARCOR2_CUBE_DETECTOR_MOCK")) + args = parser.parse_args() + + global _mock + _mock = args.mock + if _mock: + logger.info("Starting as a mock!") + + run_app(app, SERVICE_NAME, version(), port_from_url(URL), [WebApiError, Cube], args.swagger) + + +if __name__ == "__main__": + main() diff --git a/src/python/arcor2_cube_detector/scripts/dataset_evaluation.py b/src/python/arcor2_cube_detector/scripts/dataset_evaluation.py new file mode 100644 index 00000000..15cf69d0 --- /dev/null +++ b/src/python/arcor2_cube_detector/scripts/dataset_evaluation.py @@ -0,0 +1,190 @@ +#!/usr/bin/env python3 + +import argparse +import csv +import logging +import os +import time +from typing import Optional + +import numpy as np + +from arcor2.data.camera import CameraParameters +from arcor2.data.common import Pose, Position +from arcor2.logging import get_logger +from arcor2_cube_detector import get_data +from arcor2_cube_detector.cube_detector import Cube, CubeDetector + +logger = get_logger(__name__) + + +def evaluate(number_of_iterations: int, save_path: Optional[str] = None) -> None: + """Evaluates dataset a prints out summary. + + :param number_of_iterations: Dataset will be evaluated multiple times and the results will be averaged + :param save_path: Save evaluation details to CSV file in given path, defaults to None (= results won't be saved) + """ + cameraParameters = CameraParameters( + 907.80126953125, + 907.6754150390625, + 960.291259765625, + 552.93536376953125, + [0.447, -2.5, 0.00094, -0.00053, 1.432, 0.329, -2.332, 1.363], + ) + detector = CubeDetector(cameraParameters) + + correct_detections: list[list[int]] = [[] for _ in range(number_of_iterations)] + expected_detections: list[list[int]] = [[] for _ in range(number_of_iterations)] + false_positives: list[list[int]] = [[] for _ in range(number_of_iterations)] + detection_time: list[list[float]] = [[] for _ in range(number_of_iterations)] + iteration_time: list[float] = [] * number_of_iterations + + for iteration in range(number_of_iterations): + iteration_start = time.monotonic() + + path = get_data("dataset") + assert os.path.exists(path) + + # Get only numbered folders and sort them + folders = [folder for folder in os.listdir(path) if folder.isdigit()] + folders.sort(key=int) + + for folder in folders: + if not ( + os.path.exists(f"{path}/{folder}/color.jpg") + and os.path.exists(f"{path}/{folder}/depth.png") + and os.path.exists(f"{path}/{folder}/annotation.csv") + ): + continue + + detection_start = time.monotonic() + + # Load data and detect cubes + color, depth = detector.get_image_from_file( + get_data(f"dataset/{folder}/color.jpg"), get_data(f"dataset/{folder}/depth.png") + ) + detected_cubes = detector.detect_cubes(color, depth, transform_cordinates=False) + + # Load anotated cubes + expected_cubes: list[Cube] = [] + with open(get_data(f"dataset/{folder}/annotation.csv")) as annotation: + reader = csv.reader(annotation) + _ = next(reader) + for row in reader: + expected_cubes.append(Cube(row[0], Pose(Position(float(row[1]), float(row[2]), float(row[3]))))) + + logger.debug("") + logger.debug(f"Folder: {folder}") + logger.debug(f"Detected cubes: {len(detected_cubes)}") + + correctly_detected_cubes: list[int] = [] + + for cube in detected_cubes: + position = Position(*(round(pos, 5) for pos in cube.pose.position)) + for i, ex in enumerate(expected_cubes): + if cube.color == ex.color: + distance = np.linalg.norm( + np.array([cube.pose.position[0], cube.pose.position[1], cube.pose.position[2]]) + - np.array([ex.pose.position[0], ex.pose.position[1], ex.pose.position[2]]) + ) + if distance <= 0.025: + correctly_detected_cubes.append(i) + logger.debug(f"\t✅ MATCH | {cube.color} \t| {position}") + break + else: + logger.debug(f"\t❌ F. P. | {cube.color} \t| {position}") + + logger.debug(f"Expected cubes: {len(expected_cubes)}") + for i, cube in enumerate(expected_cubes): + logger.debug( + f"\t{'✅' if i in correctly_detected_cubes else '❌'} \t | {cube.color} \t| {cube.pose.position}" + ) + + logger.debug( + "Detected {}/{} cubes, {} false positives".format( + len(correctly_detected_cubes), + len(expected_cubes), + len(detected_cubes) - len(correctly_detected_cubes), + ) + ) + + correct_detections[iteration].append(len(correctly_detected_cubes)) + expected_detections[iteration].append(len(expected_cubes)) + false_positives[iteration].append(len(detected_cubes) - len(correctly_detected_cubes)) + detection_time[iteration].append(time.monotonic() - detection_start) + + logger.debug(f"Detection time: {(time.monotonic() - detection_start):.3f}s") + + iteration_time.append(time.monotonic() - iteration_start) + + # Print results + logger.info("===========================================") + logger.info("ITERATION\t|Detected/Expected|F.P.| Time ") + logger.info("===========================================") + for iteration in range(number_of_iterations): + total_correct_detections = sum(correct_detections[iteration]) + total_expected_detections = sum(expected_detections[iteration]) + logger.info( + "{}\t\t| {} / {} ({}%) | {} | {:.3f}s".format( + iteration + 1, + total_correct_detections, + total_expected_detections, + int((total_correct_detections / total_expected_detections) * 100), + sum(false_positives[iteration]), + iteration_time[iteration], + ) + ) + logger.info("===========================================") + avg_correct_detections = int(sum([sum(total) for total in correct_detections]) / number_of_iterations) + avg_expected_detections = int(sum([sum(total) for total in expected_detections]) / number_of_iterations) + logger.info( + "AVG\t| {} / {} ({}%) | {} | {:.3f}s".format( + avg_correct_detections, + avg_expected_detections, + int((avg_correct_detections / avg_expected_detections) * 100), + int(sum([sum(total) for total in false_positives]) / number_of_iterations), + sum(iteration_time) / number_of_iterations, + ) + ) + logger.info("===========================================") + + # Save detailed results to CSV file + if save_path: + with open(os.path.join(save_path, f"evaluation_{time.strftime('%Y%m%d_%H%M%S')}.csv"), "w") as file: + writer = csv.writer(file) + writer.writerow(["iteration", "folder", "detected", "expected", "false_positives", "time"]) + for iteration in range(number_of_iterations): + for folder_number in range(len(expected_detections[0])): + writer.writerow( + [ + iteration + 1, + folder_number, + correct_detections[iteration][folder_number], + expected_detections[iteration][folder_number], + false_positives[iteration][folder_number], + detection_time[iteration][folder_number], + ] + ) + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument( + "-d", + "--debug", + help="Set logging level to debug.", + action="store_const", + const=logging.DEBUG, + default=logging.INFO, + ) + parser.add_argument("-i", "--iterations", type=int, default=5) + parser.add_argument("-s", "--save", type=str, default=None) + + args = parser.parse_args() + logger.setLevel(args.debug) + + evaluate(args.iterations, args.save) + + +if __name__ == "__main__": + main() diff --git a/src/python/arcor2_cube_detector/tests/BUILD b/src/python/arcor2_cube_detector/tests/BUILD new file mode 100644 index 00000000..e2e39c28 --- /dev/null +++ b/src/python/arcor2_cube_detector/tests/BUILD @@ -0,0 +1,8 @@ +python_tests( + runtime_package_dependencies=[ + "src/python/arcor2_cube_detector/scripts:cube_detector", + ], + dependencies=[ + "src/python/arcor2_cube_detector/data/dataset:dataset", + ], +) diff --git a/src/python/arcor2_cube_detector/tests/__init__.py b/src/python/arcor2_cube_detector/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/python/arcor2_cube_detector/tests/test_dataset.py b/src/python/arcor2_cube_detector/tests/test_dataset.py new file mode 100644 index 00000000..74355381 --- /dev/null +++ b/src/python/arcor2_cube_detector/tests/test_dataset.py @@ -0,0 +1,66 @@ +import csv +import os + +import numpy as np + +from arcor2.data.camera import CameraParameters +from arcor2.data.common import Pose, Position +from arcor2_cube_detector import get_data +from arcor2_cube_detector.cube_detector import Cube, CubeDetector + + +def test_dataset() -> None: + camera_parameters = CameraParameters( + 907.80126953125, + 907.6754150390625, + 960.291259765625, + 552.93536376953125, + [0.447, -2.5, 0.00094, -0.00053, 1.432, 0.329, -2.332, 1.363], + ) + detector = CubeDetector(camera_parameters) + total_matches = 0 + total_expected = 0 + + path = get_data("dataset") + assert os.path.exists(path) + + for folder in os.listdir(path): + if not ( + os.path.exists(f"{path}/{folder}/color.jpg") + and os.path.exists(f"{path}/{folder}/depth.png") + and os.path.exists(f"{path}/{folder}/annotation.csv") + ): + continue + color, depth = detector.get_image_from_file( + get_data(f"dataset/{folder}/color.jpg"), get_data(f"dataset/{folder}/depth.png") + ) + assert color + assert depth + detected_cubes = detector.detect_cubes(color, depth, transform_cordinates=False) + expected_cubes: list[Cube] = [] + + matches = 0 + + with open(get_data(f"dataset/{folder}/annotation.csv")) as annotation: + assert annotation + reader = csv.reader(annotation) + _ = next(reader) + for row in reader: + expected_cubes.append(Cube(row[0], Pose(Position(float(row[1]), float(row[2]), float(row[3]))))) + + for cube in detected_cubes: + for ex in expected_cubes: + if cube.color == ex.color: + distance = np.linalg.norm( + np.array([cube.pose.position[0], cube.pose.position[1], cube.pose.position[2]]) + - np.array([ex.pose.position[0], ex.pose.position[1], ex.pose.position[2]]) + ) + if distance <= 0.025: + matches += 1 + break + + total_matches += matches + total_expected += len(expected_cubes) + + pass_percentage = int((total_matches / total_expected) * 100) + assert pass_percentage >= 70 diff --git a/src/python/arcor2_cube_detector/tests/test_openapi.py b/src/python/arcor2_cube_detector/tests/test_openapi.py new file mode 100644 index 00000000..b2de23e8 --- /dev/null +++ b/src/python/arcor2_cube_detector/tests/test_openapi.py @@ -0,0 +1,12 @@ +from subprocess import check_output + +import yaml +from openapi_spec_validator import validate_spec + + +def test_openapi() -> None: + validate_spec( + yaml.full_load( + check_output(["python", "src.python.arcor2_cube_detector.scripts/cube_detector.pex", "--swagger", "--mock"]) + ) + ) diff --git a/src/python/arcor2_cube_tracker/BUILD b/src/python/arcor2_cube_tracker/BUILD new file mode 100644 index 00000000..8c3842f3 --- /dev/null +++ b/src/python/arcor2_cube_tracker/BUILD @@ -0,0 +1,5 @@ +arcor2_python_distribution( + name="arcor2_cube_tracker", + description="Cube tracker", + binaries={"arcor2_cube_tracker": "src/python/arcor2_cube_tracker/scripts:cube_tracker"}, +) diff --git a/src/python/arcor2_cube_tracker/CHANGELOG.md b/src/python/arcor2_cube_tracker/CHANGELOG.md new file mode 100644 index 00000000..414255fd --- /dev/null +++ b/src/python/arcor2_cube_tracker/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), diff --git a/src/python/arcor2_cube_tracker/README.md b/src/python/arcor2_cube_tracker/README.md new file mode 100644 index 00000000..53d35905 --- /dev/null +++ b/src/python/arcor2_cube_tracker/README.md @@ -0,0 +1,15 @@ +# Cube Tracker Service + +## Usage Instructions + +- By default, the service runs on port 5021. + +## Environment variables + +- `ARCOR2_CUBE_TRACKER_URL=http://0.0.0.0:5021` - by default, the service listens on port 5021. +- `ARCOR2_CUBE_TRACKER_MOCK=1` - the service will start in a mock (simulator) mode. +- `ARCOR2_CUBE_TRACKER_INTERVAL=1.0` - cube detection interval +- `ARCOR2_CUBE_TRACKER_AVERAGE_POSITION=1` - average position when updating cubes +- `ARCOR2_CUBE_TRACKER_DEBUG=1` - switches logger to the `DEBUG` level. + + diff --git a/src/python/arcor2_cube_tracker/VERSION b/src/python/arcor2_cube_tracker/VERSION new file mode 100644 index 00000000..6c6aa7cb --- /dev/null +++ b/src/python/arcor2_cube_tracker/VERSION @@ -0,0 +1 @@ +0.1.0 \ No newline at end of file diff --git a/src/python/arcor2_cube_tracker/__init__.py b/src/python/arcor2_cube_tracker/__init__.py new file mode 100644 index 00000000..08e2039c --- /dev/null +++ b/src/python/arcor2_cube_tracker/__init__.py @@ -0,0 +1,9 @@ +import os + +from arcor2 import package_version + +_ROOT = os.path.abspath(os.path.dirname(__file__)) + + +def version() -> str: + return package_version(__name__) diff --git a/src/python/arcor2_cube_tracker/cube_tracker.py b/src/python/arcor2_cube_tracker/cube_tracker.py new file mode 100644 index 00000000..2e0ef3d3 --- /dev/null +++ b/src/python/arcor2_cube_tracker/cube_tracker.py @@ -0,0 +1,183 @@ +from dataclasses import dataclass +from enum import Enum +from typing import Optional + +import numpy as np +from dataclasses_jsonschema import JsonSchemaMixin + +from arcor2 import env +from arcor2.data.common import Pose, Position +from arcor2.logging import get_logger +from arcor2_cube_detector.cube_detector import Cube + +logger = get_logger(__name__) +if env.get_bool("ARCOR2_CUBE_TRACKER_DEBUG"): + logger.setLevel("DEBUG") + + +@dataclass +class StoredCube(JsonSchemaMixin): + cube: Cube + up_to_date: int + + +class DistanceType(Enum): + NEAREST = 0 + FARTHEST = 1 + + +class CubeTracker: + def __init__(self, average_position: bool = True) -> None: + self.stored_cubes: list[StoredCube] = [] + self.average_position = average_position + + def cubes_distance(self, pos1: Position, pos2: Position) -> np.float64: + """Returns distance between two cubes. + + :param pos1: Position 1 + :param pos2: Position 2 + :return: Distance between two positions + """ + p1 = np.array([pos1.x, pos1.y, pos1.z]) + p2 = np.array([pos2.x, pos2.y, pos2.z]) + distance = np.linalg.norm(p1 - p2) + return distance + + def index_of_nearest_cube(self, cube: Cube, searched_cubes: list[Cube]) -> int | None: + """Returns index of nearest cube from list. + + :param cube: Cube to which we are looking for the nearest cube + :param searched_cubes: List of cubes + :return: Index of nearest cube + """ + distances_between_cubes: list[tuple[int, np.float64]] = [] + for i, searched_cube in enumerate(searched_cubes): + if cube.color == searched_cube.color: + distances_between_cubes.append( + (i, self.cubes_distance(cube.pose.position, searched_cube.pose.position)) + ) + + if len(distances_between_cubes) == 0: + return None + + # Sort by distance + distances_between_cubes.sort(key=lambda x: x[1]) + + # Return index of nearest cube + return distances_between_cubes[0][0] + + def store_cubes(self, detected_cubes: list[Cube]): + """Stores cubes, + + :param detected_cubes: Cubes to store + """ + + logger.debug("STORE_CUBES INPUT:") + for cube in detected_cubes: + logger.debug(f"\t{cube.pose.position}") + + # Increment UpToDate index + # Remove cubes that haven't been detected in 5 iterations + for stored_cube in self.stored_cubes: + stored_cube.up_to_date += 1 + if stored_cube.up_to_date > 5: + self.stored_cubes.remove(stored_cube) + logger.debug(f"REMOVING {stored_cube.cube.pose.position}") + + # Copy of original list, because original list will be altered during the cycle + stored_cubes_copy = self.stored_cubes.copy() + # Flag if cubes were updated + updated_cubes = [False] * len(self.stored_cubes) + + while not all(updated_cubes) and detected_cubes: + for i, stored_cube in enumerate(stored_cubes_copy): + if updated_cubes[i]: + continue + nearest_cube = self.index_of_nearest_cube(stored_cube.cube, detected_cubes) + if nearest_cube is None: + # No other detected cubes with the same color + # Stored cube stays the same + updated_cubes[i] = True + continue + if i == self.index_of_nearest_cube( + detected_cubes[nearest_cube], [cube.cube for cube in stored_cubes_copy] + ): + logger.debug( + f"UPDATING {stored_cube.cube.pose.position} -> {detected_cubes[nearest_cube].pose.position}" + ) + # Both cubes are nearest to each other + # Update stored cube with detected cube + if self.average_position: + # Average position + self.stored_cubes[i].cube.pose.position = ( + stored_cube.cube.pose.position + detected_cubes[nearest_cube].pose.position + ) * 0.5 + self.stored_cubes[i].cube.pose.orientation = detected_cubes[nearest_cube].pose.orientation + else: + self.stored_cubes[i].cube = detected_cubes[nearest_cube] + self.stored_cubes[i].up_to_date = 0 + updated_cubes[i] = True + + # Remove detected cube from list because it cant no longer update other cubes + del detected_cubes[nearest_cube] + + # Add detected cubes, that didn't update any stored cube + for cube in detected_cubes: + self.stored_cubes.append(StoredCube(cube, 0)) + logger.debug(f"ADDING {cube.pose.position}") + + def get_stored_cubes(self, color: Optional[str] = None) -> list[Pose]: + """Returns stored cubes. + + :param color: Get only cubes of selected color, defaults to None + :return: Poses of cubes + """ + return [ + stored_cube.cube.pose + for stored_cube in self.stored_cubes + if color is None or stored_cube.cube.color == color + ] + + def get_cube_by_distance( + self, + distance_type: DistanceType, + position: Position, + offset: Position, + max_distance: float = 1, + color: Optional[str] = None, + ) -> Pose | None: + """Returns the nearest or farthest cube from the point of interest. + + :param distance_type: Select nearest or farthest cube + :param position: Point of interest + :param offset: Offset that is added to center of cube + :param max_distance: Maximum distance to consider, defaults to 1 + :param color: Color of cube, defaults to None + :return: Pose of the nearest cube + """ + # Calculate distance from point of intereset to each cube + cubes = [(cube.cube, self.cubes_distance(cube.cube.pose.position, position)) for cube in self.stored_cubes] + # Filter cubes by selected color and max distance + filtered_cubes = list( + filter( + lambda cube: (color is None or cube[0].color == color) and (cube[1] < max_distance), + cubes, + ) + ) + if len(filtered_cubes) == 0: + return None + + # Order by ascending distance + filtered_cubes.sort(key=lambda cube: cube[1]) + + # Reverse order for the farthest cube + if distance_type == DistanceType.FARTHEST: + filtered_cubes.reverse() + + # First cube in the list is nearest to/farthest from the point of interest + cube = filtered_cubes[0][0].pose + cube_with_offset = Pose(cube.position + offset, cube.orientation) + + logger.debug(f"RETURNING {distance_type.name} {cube_with_offset.position}") + + return cube_with_offset diff --git a/src/python/arcor2_cube_tracker/exceptions.py b/src/python/arcor2_cube_tracker/exceptions.py new file mode 100644 index 00000000..579e4990 --- /dev/null +++ b/src/python/arcor2_cube_tracker/exceptions.py @@ -0,0 +1,17 @@ +from arcor2.flask import FlaskException, General, WebApiErrorFactory +from arcor2_cube_tracker import __name__ as package_name + + +class CubeTrackerException(FlaskException): + service = package_name + + +class CubeTrackerGeneral(CubeTrackerException): + description = General.description + + +class NotFound(CubeTrackerException): + description = "Occurs when something is not found." + + +WebApiError = WebApiErrorFactory.get_class(NotFound, CubeTrackerGeneral) diff --git a/src/python/arcor2_cube_tracker/py.typed b/src/python/arcor2_cube_tracker/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/src/python/arcor2_cube_tracker/scripts/BUILD b/src/python/arcor2_cube_tracker/scripts/BUILD new file mode 100644 index 00000000..18639d61 --- /dev/null +++ b/src/python/arcor2_cube_tracker/scripts/BUILD @@ -0,0 +1,3 @@ +python_sources() + +arcor2_pex_binary(name="cube_tracker", dependencies=[]) diff --git a/src/python/arcor2_cube_tracker/scripts/__init__.py b/src/python/arcor2_cube_tracker/scripts/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/python/arcor2_cube_tracker/scripts/cube_tracker.py b/src/python/arcor2_cube_tracker/scripts/cube_tracker.py new file mode 100644 index 00000000..3dc64ef1 --- /dev/null +++ b/src/python/arcor2_cube_tracker/scripts/cube_tracker.py @@ -0,0 +1,430 @@ +#!/usr/bin/env python3 + +import argparse +import json +import os +import threading +import time + +from flask import Response, jsonify, request + +from arcor2 import env, rest +from arcor2.data.common import Pose, Position +from arcor2.flask import RespT, create_app, run_app +from arcor2.helpers import port_from_url +from arcor2.logging import get_logger +from arcor2_cube_detector.cube_detector import Cube +from arcor2_cube_tracker import version +from arcor2_cube_tracker.cube_tracker import CubeTracker, DistanceType +from arcor2_cube_tracker.exceptions import CubeTrackerGeneral, WebApiError + +logger = get_logger(__name__) + +URL = os.getenv("ARCOR2_CUBE_TRACKER_URL", "http://0.0.0.0:5021") +URL_DETECTOR = os.getenv("ARCOR2_CUBE_DETECTOR_URL", "http://0.0.0.0:5020") +SERVICE_NAME = "Object Tracker Web API" + +DETECTION_INTERVAL = env.get_float("ARCOR2_CUBE_TRACKER_INTERVAL", 1.0) + +app = create_app(__name__) + +_started = False +_mock = False +_tracker = CubeTracker(average_position=env.get_bool("ARCOR2_CUBE_TRACKER_AVERAGE_POSITION", True)) +_thread: None | threading.Thread = None + + +def thread_detect_cubes() -> None: + while _started: + t_start = time.monotonic() + try: + cubes = rest.call(rest.Method.GET, f"{URL_DETECTOR}/detect/all", list_return_type=Cube) + _tracker.store_cubes(cubes) + except Exception: + logger.warning("ERROR WHILE STORING CUBES") + t_total = time.monotonic() - t_start + + if t_total > DETECTION_INTERVAL: + logger.warning(f"Detection took longer than given interval ({t_total:.3f} > {DETECTION_INTERVAL})") + else: + time.sleep(DETECTION_INTERVAL - t_total) + + +@app.route("/state/start", methods=["PUT"]) +def put_start() -> RespT: + """Periodically call Object detector. + --- + put: + description: Start. + tags: + - State + responses: + 204: + description: Ok + 500: + description: "Error types: **General**" + content: + application/json: + schema: + $ref: WebApiError + """ + + global _started, _thread + if not _mock and not _started: + _started = True + _thread = threading.Thread(target=thread_detect_cubes, args=()) + _thread.start() + + return Response(status=204) + + +@app.route("/state/stop", methods=["PUT"]) +def put_stop() -> RespT: + """Stop detecting. + --- + put: + description: Stop. + tags: + - State + responses: + 204: + description: Ok + 500: + description: "Error types: **General**" + content: + application/json: + schema: + $ref: WebApiError + """ + + global _started, _thread + _started = False + if _thread and _thread.is_alive(): + _thread.join() + 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**" + content: + application/json: + schema: + $ref: WebApiError + """ + + global _started + return jsonify(_started), 200 + + +@app.route("/cubes/all", methods=["GET"]) +def get_cubes() -> RespT: + """Get cubes. + --- + get: + description: Get all cubes. + tags: + - Cubes (All) + parameters: + - in: query + name: color + schema: + type: string + enum: + - RED + - GREEN + - BLUE + - YELLOW + description: Color of the cube + responses: + 200: + description: Ok + content: + application/json: + schema: + type: array + items: + $ref: Pose + 500: + description: "Error types: **General**" + content: + application/json: + schema: + $ref: WebApiError + """ + color = request.args.get("color", default=None) + return jsonify(_tracker.get_stored_cubes(color)), 200 + + +@app.route("/cube/is-in-area", methods=["PUT"]) +def is_cube_in_area() -> RespT: + """Get cubes. + --- + put: + description: Check if cube is in the area + tags: + - Cube (Distance) + requestBody: + content: + application/json: + schema: + $ref: Position + parameters: + - in: query + name: max_distance + schema: + type: number + default: 1.0 + format: float + minimum: 0.0 + description: Maximum distance from the point of interest + - in: query + name: color + schema: + type: string + enum: + - RED + - GREEN + - BLUE + - YELLOW + description: Color of the cube + responses: + 200: + description: Ok + content: + application/json: + schema: + type: boolean + 500: + description: "Error types: **General**, **CubeTrackerGeneral**" + content: + application/json: + schema: + $ref: WebApiError + """ + if not isinstance(request.json, dict): + raise CubeTrackerGeneral("Body should be a JSON dict containing Position.") + position = Position.from_dict(request.json) + max_distance = float(request.args.get("max_distance", default=1)) + color = request.args.get("color", default=None) + if color == "ANY": + color = None + + cube = _tracker.get_cube_by_distance( + DistanceType.NEAREST, + position, + Position(0, 0, 0), + max_distance, + color, + ) + return Response(json.dumps(cube is not None)) + + +@app.route("/cube/nearest", methods=["PUT"]) +def get_cubes_nearest() -> RespT: + """Get cubes. + --- + put: + description: Get the nearest cube. + tags: + - Cube (Distance) + requestBody: + content: + application/json: + schema: + $ref: Position + parameters: + - in: query + name: max_distance + schema: + type: number + default: 1.0 + format: float + minimum: 0.0 + description: Maximum distance from the point of interest + - in: query + name: color + schema: + type: string + enum: + - RED + - GREEN + - BLUE + - YELLOW + description: Color of the cube + - in: query + name: offset_x + schema: + type: number + default: 0.0 + format: float + description: Offset from the cube center on x axis + - in: query + name: offset_y + schema: + type: number + default: 0.0 + format: float + description: Offset from the cube center on y axis + - in: query + name: offset_z + schema: + type: number + default: 0.0 + format: float + description: Offset from the cube center on z axis + responses: + 200: + description: Ok + content: + application/json: + schema: + $ref: Pose + 500: + description: "Error types: **General**, **CubeTrackerGeneral**" + content: + application/json: + schema: + $ref: WebApiError + """ + if not isinstance(request.json, dict): + raise CubeTrackerGeneral("Body should be a JSON dict containing Position.") + position = Position.from_dict(request.json) + max_distance = float(request.args.get("max_distance", default=1)) + color = request.args.get("color", default=None) + if color == "ANY": + color = None + offset = Position( + float(request.args.get("offset_x", default=0)), + float(request.args.get("offset_y", default=0)), + float(request.args.get("offset_z", default=0)), + ) + return ( + jsonify( + _tracker.get_cube_by_distance( + DistanceType.NEAREST, + position, + offset, + max_distance, + color, + ) + ), + 200, + ) + + +@app.route("/cube/farthest", methods=["PUT"]) +def get_cubes_farthest() -> RespT: + """Get cubes. + --- + put: + description: Get the farthest cube. + tags: + - Cube (Distance) + requestBody: + content: + application/json: + schema: + $ref: Position + parameters: + - in: query + name: max_distance + schema: + type: number + default: 1.0 + format: float + minimum: 0.0 + description: Maximum distance from the point of interest + - in: query + name: color + schema: + type: string + enum: + - RED + - GREEN + - BLUE + - YELLOW + description: Color of the cube + - in: query + name: offset_x + schema: + type: number + default: 0.0 + format: float + description: Offset from the cube center on x axis + - in: query + name: offset_y + schema: + type: number + default: 0.0 + format: float + description: Offset from the cube center on y axis + - in: query + name: offset_z + schema: + type: number + default: 0.0 + format: float + description: Offset from the cube center on z axis + responses: + 200: + description: Ok + content: + application/json: + schema: + $ref: Pose + 500: + description: "Error types: **General**, **CubeTrackerGeneral**" + content: + application/json: + schema: + $ref: WebApiError + """ + if not isinstance(request.json, dict): + raise CubeTrackerGeneral("Body should be a JSON dict containing Position.") + position = Position.from_dict(request.json) + max_distance = float(request.args.get("max_distance", default=1)) + color = request.args.get("color", default=None) + if color == "ANY": + color = None + offset = Position( + float(request.args.get("offset_x", default=0)), + float(request.args.get("offset_y", default=0)), + float(request.args.get("offset_z", default=0)), + ) + return ( + jsonify(_tracker.get_cube_by_distance(DistanceType.FARTHEST, position, offset, max_distance, color)), + 200, + ) + + +def main() -> None: + parser = argparse.ArgumentParser(description=SERVICE_NAME) + parser.add_argument("-s", "--swagger", action="store_true", default=False) + parser.add_argument("-m", "--mock", action="store_true", default=env.get_bool("ARCOR2_CUBE_TRACKER_MOCK")) + args = parser.parse_args() + + global _mock + _mock = args.mock + if _mock: + logger.info("Starting as a mock!") + + run_app(app, SERVICE_NAME, version(), port_from_url(URL), [WebApiError, Pose], args.swagger) + + +if __name__ == "__main__": + main() diff --git a/src/python/arcor2_cube_tracker/tests/BUILD b/src/python/arcor2_cube_tracker/tests/BUILD new file mode 100644 index 00000000..af350e36 --- /dev/null +++ b/src/python/arcor2_cube_tracker/tests/BUILD @@ -0,0 +1,5 @@ +python_tests( + runtime_package_dependencies=[ + "src/python/arcor2_cube_tracker/scripts:cube_tracker", + ] +) diff --git a/src/python/arcor2_cube_tracker/tests/test_openapi.py b/src/python/arcor2_cube_tracker/tests/test_openapi.py new file mode 100644 index 00000000..391e34f2 --- /dev/null +++ b/src/python/arcor2_cube_tracker/tests/test_openapi.py @@ -0,0 +1,12 @@ +from subprocess import check_output + +import yaml +from openapi_spec_validator import validate_spec + + +def test_openapi() -> None: + validate_spec( + yaml.full_load( + check_output(["python", "src.python.arcor2_cube_tracker.scripts/cube_tracker.pex", "--swagger", "--mock"]) + ) + ) diff --git a/src/python/arcor2_cube_tracker/tests/test_tracker.py b/src/python/arcor2_cube_tracker/tests/test_tracker.py new file mode 100644 index 00000000..e3c867f9 --- /dev/null +++ b/src/python/arcor2_cube_tracker/tests/test_tracker.py @@ -0,0 +1,217 @@ +from arcor2.data.common import Pose, Position +from arcor2_cube_detector.cube_detector import Color, Cube +from arcor2_cube_tracker.cube_tracker import CubeTracker, DistanceType, StoredCube + + +def test_cubes_distance() -> None: + tracker = CubeTracker() + + assert tracker.cubes_distance(Position(0, 0, 0), Position(1, 0, 0)) == 1 + + +def test_index_of_nearest_cube() -> None: + tracker = CubeTracker() + + cube1 = Cube(Color.RED.name, Pose(Position(0, 0, 0))) + cube2 = Cube(Color.YELLOW.name, Pose(Position(1, 2, 3))) + + cubes = [ + Cube(Color.RED.name, Pose(Position(5, 0, 0))), + Cube(Color.GREEN.name, Pose(Position(1, 0, 0))), + Cube(Color.BLUE.name, Pose(Position(0, -2, 0))), + Cube(Color.RED.name, Pose(Position(1, 1, 1))), + Cube(Color.RED.name, Pose(Position(0, 3, 3))), + Cube(Color.BLUE.name, Pose(Position(-1, -1, 1))), + ] + + assert tracker.index_of_nearest_cube(cube1, cubes) == 3 + assert tracker.index_of_nearest_cube(cube2, cubes) is None + + +def test_store_cubes_remove_outdated() -> None: + tracker = CubeTracker() + + assert len(tracker.stored_cubes) == 0 + + pos1 = Pose(Position(5, 0, 0)) + pos2 = Pose(Position(1, 0, 0)) + tracker.stored_cubes = [ + StoredCube(Cube(Color.RED.name, pos1), 4), + StoredCube(Cube(Color.GREEN.name, pos2), 5), + ] + + assert len(tracker.stored_cubes) == 2 + tracker.store_cubes([]) + assert len(tracker.stored_cubes) == 1 + tracker.store_cubes([]) + assert len(tracker.stored_cubes) == 0 + + +def test_store_cubes() -> None: + tracker = CubeTracker(average_position=False) + + tracker.store_cubes([Cube(Color.RED.name, Pose(Position(2, 0, 0))), Cube(Color.RED.name, Pose(Position(5, 0, 0)))]) + tracker.store_cubes( + [ + Cube(Color.RED.name, Pose(Position(0, 0, 0))), + Cube(Color.RED.name, Pose(Position(4, 0, 0))), + Cube(Color.RED.name, Pose(Position(7, 0, 0))), + ] + ) + assert len(tracker.stored_cubes) == 3 + assert tracker.stored_cubes[0] == StoredCube(Cube(Color.RED.name, Pose(Position(0, 0, 0))), 0) + assert tracker.stored_cubes[1] == StoredCube(Cube(Color.RED.name, Pose(Position(4, 0, 0))), 0) + assert tracker.stored_cubes[2] == StoredCube(Cube(Color.RED.name, Pose(Position(7, 0, 0))), 0) + tracker.stored_cubes = [] + + tracker.store_cubes([Cube(Color.BLUE.name, Pose(Position(1, 0, 0)))]) + assert len(tracker.stored_cubes) == 1 + assert tracker.stored_cubes[0] == StoredCube(Cube(Color.BLUE.name, Pose(Position(1, 0, 0))), 0) + + tracker.store_cubes([Cube(Color.BLUE.name, Pose(Position(1, 1, 0)))]) + assert len(tracker.stored_cubes) == 1 + assert tracker.stored_cubes[0] == StoredCube(Cube(Color.BLUE.name, Pose(Position(1, 1, 0))), 0) + + tracker.store_cubes( + [Cube(Color.BLUE.name, Pose(Position(1, 1, 0))), Cube(Color.BLUE.name, Pose(Position(0, 0, 5)))] + ) + assert len(tracker.stored_cubes) == 2 + assert tracker.stored_cubes[0] == StoredCube(Cube(Color.BLUE.name, Pose(Position(1, 1, 0))), 0) + assert tracker.stored_cubes[1] == StoredCube(Cube(Color.BLUE.name, Pose(Position(0, 0, 5))), 0) + + tracker.store_cubes([Cube(Color.BLUE.name, Pose(Position(0, 0, 3)))]) + assert len(tracker.stored_cubes) == 2 + assert tracker.stored_cubes[0] == StoredCube(Cube(Color.BLUE.name, Pose(Position(1, 1, 0))), 1) + assert tracker.stored_cubes[1] == StoredCube(Cube(Color.BLUE.name, Pose(Position(0, 0, 3))), 0) + + tracker.average_position = True + tracker.store_cubes([Cube(Color.BLUE.name, Pose(Position(1, 1, 1)))]) + assert tracker.stored_cubes[0] == StoredCube(Cube(Color.BLUE.name, Pose(Position(1, 1, 0.5))), 0) + + +def test_get_stored_cubes() -> None: + tracker = CubeTracker() + + assert tracker.get_stored_cubes() == [] + + pos1 = Pose(Position(5, 0, 0)) + pos2 = Pose(Position(1, 0, 0)) + + tracker.stored_cubes = [ + StoredCube(Cube(Color.RED.name, pos1), 1), + StoredCube(Cube(Color.GREEN.name, pos2), 0), + ] + + assert tracker.get_stored_cubes() == [pos1, pos2] + assert tracker.get_stored_cubes(Color.RED.name) == [pos1] + assert tracker.get_stored_cubes(Color.YELLOW.name) == [] + + +def test_get_cube_by_distance() -> None: + tracker = CubeTracker() + + pos = [ + Pose(Position(0, 0, 0)), + Pose(Position(1, 0, 0)), + Pose(Position(2, 0, 0)), + Pose(Position(0, 2, 0)), + Pose(Position(0, 0, -3)), + Pose(Position(5, 5, 5)), + ] + + tracker.stored_cubes = [ + StoredCube(Cube(Color.RED.name, pos[0]), 1), + StoredCube(Cube(Color.RED.name, pos[1]), 0), + StoredCube(Cube(Color.RED.name, pos[2]), 0), + StoredCube(Cube(Color.GREEN.name, pos[3]), 0), + StoredCube(Cube(Color.GREEN.name, pos[4]), 0), + StoredCube(Cube(Color.BLUE.name, pos[5]), 0), + ] + + assert ( + tracker.get_cube_by_distance( + distance_type=DistanceType.NEAREST, + position=Position(0, 0, 0), + offset=Position(0, 0, 0), + max_distance=10, + color=None, + ) + == pos[0] + ) + assert ( + tracker.get_cube_by_distance( + distance_type=DistanceType.FARTHEST, + position=Position(0, 0, 0), + offset=Position(0, 0, 0), + max_distance=10, + color=None, + ) + == pos[5] + ) + assert ( + tracker.get_cube_by_distance( + distance_type=DistanceType.FARTHEST, + position=Position(0, 0, 0), + offset=Position(0, 0, 0), + max_distance=1.5, + color=None, + ) + == pos[1] + ) + assert ( + tracker.get_cube_by_distance( + distance_type=DistanceType.NEAREST, + position=Position(0, 0, 0), + offset=Position(0, 0, 0), + max_distance=10, + color=Color.GREEN.name, + ) + == pos[3] + ) + assert ( + tracker.get_cube_by_distance( + distance_type=DistanceType.FARTHEST, + position=Position(0, 0, 0), + offset=Position(0, 0, 0), + max_distance=10, + color=Color.GREEN.name, + ) + == pos[4] + ) + assert ( + tracker.get_cube_by_distance( + distance_type=DistanceType.NEAREST, + position=Position(0, 0, 0), + offset=Position(0, 0, 0), + max_distance=10, + color=Color.YELLOW.name, + ) + is None + ) + assert ( + tracker.get_cube_by_distance( + distance_type=DistanceType.FARTHEST, + position=Position(-2, 0, 0), + offset=Position(0, 0, 0), + max_distance=1, + color=Color.RED.name, + ) + is None + ) + assert ( + tracker.get_cube_by_distance( + distance_type=DistanceType.FARTHEST, + position=Position(0, 0, 0), + offset=Position(0, 0, 0), + max_distance=10, + color=Color.RED.name, + ) + == pos[2] + ) + assert tracker.get_cube_by_distance( + distance_type=DistanceType.NEAREST, + position=Position(0, 0, 0), + offset=Position(5, 5, 5), + max_distance=10, + color=Color.RED.name, + ) == Pose(Position(5, 5, 5)) diff --git a/src/python/arcor2_fit_demo/object_types/cube_tracker.py b/src/python/arcor2_fit_demo/object_types/cube_tracker.py new file mode 100644 index 00000000..11b6edc5 --- /dev/null +++ b/src/python/arcor2_fit_demo/object_types/cube_tracker.py @@ -0,0 +1,151 @@ +from dataclasses import dataclass +from typing import Optional + +from arcor2 import rest +from arcor2.data.common import ActionMetadata, Pose, Position, StrEnum +from arcor2.object_types.abstract import Generic + +from .fit_common_mixin import FitCommonMixin, UrlSettings # noqa:ABS101 + + +class Color(StrEnum): + ANY: str = "ANY" + RED: str = "RED" + GREEN: str = "GREEN" + BLUE: str = "BLUE" + YELLOW: str = "YELLOW" + + +@dataclass +class CubeTrackerSettings(UrlSettings): + url: str = "http://fit-demo-cube-tracker:5021" + + +class CubeTracker(FitCommonMixin, Generic): + _ABSTRACT = False + + def __init__( + self, + obj_id: str, + name: str, + settings: CubeTrackerSettings, + ) -> None: + super(CubeTracker, self).__init__(obj_id, name, settings) + + if self._started(): + self._stop() + + self._start() + + def _start(self) -> None: + rest.call(rest.Method.PUT, f"{self.settings.url}/state/start") + + def _stop(self) -> None: + rest.call(rest.Method.PUT, f"{self.settings.url}/state/stop") + + def cleanup(self) -> None: + super(CubeTracker, self).cleanup() + self._stop() + + def is_cube_in_area( + self, + position: Position, + max_distance: float = 2, + color: Color = Color.ANY, + *, + an: Optional[str] = None, + ) -> bool: + """Gets the nearest cube to the point of interest. + + :param position: Point to which the nearest cube is searched + :param max_distance: Maximum distance between point and cube, defaults to 2 + :param color: Color of the cube, defaults to Color.ANY + :return: Pose of the nearest cube + """ + return rest.call( + rest.Method.PUT, + f"{self.settings.url}/cube/is-in-area", + body=position, + params={ + "max_distance": max_distance, + "color": color.name, + }, + raw_params=True, + return_type=bool, + ) + + def get_nearest_cube( + self, + position: Position, + offset_x: float = 0, + offset_y: float = 0, + offset_z: float = 0.0125, + max_distance: float = 2, + color: Color = Color.ANY, + *, + an: Optional[str] = None, + ) -> Pose: + """Gets the nearest cube to the point of interest. + + :param position: Point to which the nearest cube is searched + :param offset_x: Offset on x axis, defaults to 0 + :param offset_y: Offset on y axis, defaults to 0 + :param offset_z: Offset on z axis, defaults to 0.0125 + :param max_distance: Maximum distance between point and cube, defaults to 2 + :param color: Color of the cube, defaults to Color.ANY + :return: Pose of the nearest cube + """ + return rest.call( + rest.Method.PUT, + f"{self.settings.url}/cube/nearest", + body=position, + params={ + "max_distance": max_distance, + "offset_x": offset_x, + "offset_y": offset_y, + "offset_z": offset_z, + "color": color.name, + }, + raw_params=True, + return_type=Pose, + ) + + def get_farthest_cube( + self, + position: Position, + max_distance: float = 2, + offset_x: float = 0, + offset_y: float = 0, + offset_z: float = 0.0125, + color: Color = Color.ANY, + *, + an: Optional[str] = None, + ) -> Pose: + """Gets the farthest cube from the point of interest. + + :param position: Point to which the farthest cube is searched + :param offset_x: Offset on x axis, defaults to 0 + :param offset_y: Offset on y axis, defaults to 0 + :param offset_z: Offset on z axis, defaults to 0.0125 + :param max_distance: Maximum distance between point and cube, defaults to 2 + :param color: Color of the cube, defaults to Color.ANY + :return: Pose of the farthest cube + """ + return rest.call( + rest.Method.PUT, + f"{self.settings.url}/cube/farthest", + body=position, + params={ + "max_distance": max_distance, + "offset_x": offset_x, + "offset_y": offset_y, + "offset_z": offset_z, + "color": color.name, + }, + raw_params=True, + return_type=Pose, + ) + + is_cube_in_area.__action__ = ActionMetadata() # type: ignore + get_nearest_cube.__action__ = ActionMetadata() # type: ignore + get_farthest_cube.__action__ = ActionMetadata() # type: ignore diff --git a/src/python/arcor2_fit_demo/scripts/upload_objects.py b/src/python/arcor2_fit_demo/scripts/upload_objects.py index 0a378ba5..c3b37c0b 100755 --- a/src/python/arcor2_fit_demo/scripts/upload_objects.py +++ b/src/python/arcor2_fit_demo/scripts/upload_objects.py @@ -5,6 +5,7 @@ from arcor2_fit_demo import get_data from arcor2_fit_demo.object_types.abstract_dobot import AbstractDobot from arcor2_fit_demo.object_types.conveyor_belt import ConveyorBelt +from arcor2_fit_demo.object_types.cube_tracker import CubeTracker from arcor2_fit_demo.object_types.dobot_m1 import DobotM1 from arcor2_fit_demo.object_types.dobot_magician import DobotMagician from arcor2_fit_demo.object_types.fit_common_mixin import FitCommonMixin @@ -25,6 +26,7 @@ def main() -> None: Mesh(ConveyorBelt.__name__, ConveyorBelt.mesh_filename), file_to_upload=get_data(ConveyorBelt.mesh_filename), ) + upload_whatever(CubeTracker) upload_whatever(FitCommonMixin)