From 37b5d16c0e0a21b4487b8a32969dd8e68da08bdb Mon Sep 17 00:00:00 2001 From: Mosserl Date: Mon, 3 Apr 2023 11:29:04 +0200 Subject: [PATCH 01/30] Starting point of the implementation. All the ROS2 packages are currently empty. --- .../3D_printer_command/__init__.py | 0 3D_printer/3D_printer_command/package.xml | 18 +++++++++++++ .../resource/3D_printer_command | 0 3D_printer/3D_printer_command/setup.cfg | 4 +++ 3D_printer/3D_printer_command/setup.py | 25 +++++++++++++++++++ .../3D_printer_command/test/test_copyright.py | 23 +++++++++++++++++ .../3D_printer_command/test/test_flake8.py | 25 +++++++++++++++++++ .../3D_printer_command/test/test_pep257.py | 23 +++++++++++++++++ .../3D_printer_image_capture/__init__.py | 0 .../3D_printer_image_capture/package.xml | 18 +++++++++++++ .../resource/3D_printer_image_capture | 0 3D_printer/3D_printer_image_capture/setup.cfg | 4 +++ 3D_printer/3D_printer_image_capture/setup.py | 25 +++++++++++++++++++ .../test/test_copyright.py | 23 +++++++++++++++++ .../test/test_flake8.py | 25 +++++++++++++++++++ .../test/test_pep257.py | 23 +++++++++++++++++ .../3D_printer_messages/__init__.py | 0 3D_printer/3D_printer_messages/package.xml | 18 +++++++++++++ .../resource/3D_printer_messages | 0 3D_printer/3D_printer_messages/setup.cfg | 4 +++ 3D_printer/3D_printer_messages/setup.py | 25 +++++++++++++++++++ .../test/test_copyright.py | 23 +++++++++++++++++ .../3D_printer_messages/test/test_flake8.py | 25 +++++++++++++++++++ .../3D_printer_messages/test/test_pep257.py | 23 +++++++++++++++++ .../3D_printer_profile_measure/__init__.py | 0 .../3D_printer_profile_measure/package.xml | 18 +++++++++++++ .../resource/3D_printer_profile_measure | 0 .../3D_printer_profile_measure/setup.cfg | 4 +++ .../3D_printer_profile_measure/setup.py | 25 +++++++++++++++++++ .../test/test_copyright.py | 23 +++++++++++++++++ .../test/test_flake8.py | 25 +++++++++++++++++++ .../test/test_pep257.py | 23 +++++++++++++++++ .../3D_printer_command/__init__.py | 0 3D_printer/src/3D_printer_command/package.xml | 18 +++++++++++++ .../resource/3D_printer_command | 0 3D_printer/src/3D_printer_command/setup.cfg | 4 +++ 3D_printer/src/3D_printer_command/setup.py | 25 +++++++++++++++++++ .../3D_printer_command/test/test_copyright.py | 23 +++++++++++++++++ .../3D_printer_command/test/test_flake8.py | 25 +++++++++++++++++++ .../3D_printer_command/test/test_pep257.py | 23 +++++++++++++++++ .../3D_printer_image_capture/__init__.py | 0 .../src/3D_printer_image_capture/package.xml | 18 +++++++++++++ .../resource/3D_printer_image_capture | 0 .../src/3D_printer_image_capture/setup.cfg | 4 +++ .../src/3D_printer_image_capture/setup.py | 25 +++++++++++++++++++ .../test/test_copyright.py | 23 +++++++++++++++++ .../test/test_flake8.py | 25 +++++++++++++++++++ .../test/test_pep257.py | 23 +++++++++++++++++ .../3D_printer_messages/__init__.py | 0 .../src/3D_printer_messages/package.xml | 18 +++++++++++++ .../resource/3D_printer_messages | 0 3D_printer/src/3D_printer_messages/setup.cfg | 4 +++ 3D_printer/src/3D_printer_messages/setup.py | 25 +++++++++++++++++++ .../test/test_copyright.py | 23 +++++++++++++++++ .../3D_printer_messages/test/test_flake8.py | 25 +++++++++++++++++++ .../3D_printer_messages/test/test_pep257.py | 23 +++++++++++++++++ .../3D_printer_profile_measure/__init__.py | 0 .../3D_printer_profile_measure/package.xml | 18 +++++++++++++ .../resource/3D_printer_profile_measure | 0 .../src/3D_printer_profile_measure/setup.cfg | 4 +++ .../src/3D_printer_profile_measure/setup.py | 25 +++++++++++++++++++ .../test/test_copyright.py | 23 +++++++++++++++++ .../test/test_flake8.py | 25 +++++++++++++++++++ .../test/test_pep257.py | 23 +++++++++++++++++ 64 files changed, 944 insertions(+) create mode 100644 3D_printer/3D_printer_command/3D_printer_command/__init__.py create mode 100644 3D_printer/3D_printer_command/package.xml create mode 100644 3D_printer/3D_printer_command/resource/3D_printer_command create mode 100644 3D_printer/3D_printer_command/setup.cfg create mode 100644 3D_printer/3D_printer_command/setup.py create mode 100644 3D_printer/3D_printer_command/test/test_copyright.py create mode 100644 3D_printer/3D_printer_command/test/test_flake8.py create mode 100644 3D_printer/3D_printer_command/test/test_pep257.py create mode 100644 3D_printer/3D_printer_image_capture/3D_printer_image_capture/__init__.py create mode 100644 3D_printer/3D_printer_image_capture/package.xml create mode 100644 3D_printer/3D_printer_image_capture/resource/3D_printer_image_capture create mode 100644 3D_printer/3D_printer_image_capture/setup.cfg create mode 100644 3D_printer/3D_printer_image_capture/setup.py create mode 100644 3D_printer/3D_printer_image_capture/test/test_copyright.py create mode 100644 3D_printer/3D_printer_image_capture/test/test_flake8.py create mode 100644 3D_printer/3D_printer_image_capture/test/test_pep257.py create mode 100644 3D_printer/3D_printer_messages/3D_printer_messages/__init__.py create mode 100644 3D_printer/3D_printer_messages/package.xml create mode 100644 3D_printer/3D_printer_messages/resource/3D_printer_messages create mode 100644 3D_printer/3D_printer_messages/setup.cfg create mode 100644 3D_printer/3D_printer_messages/setup.py create mode 100644 3D_printer/3D_printer_messages/test/test_copyright.py create mode 100644 3D_printer/3D_printer_messages/test/test_flake8.py create mode 100644 3D_printer/3D_printer_messages/test/test_pep257.py create mode 100644 3D_printer/3D_printer_profile_measure/3D_printer_profile_measure/__init__.py create mode 100644 3D_printer/3D_printer_profile_measure/package.xml create mode 100644 3D_printer/3D_printer_profile_measure/resource/3D_printer_profile_measure create mode 100644 3D_printer/3D_printer_profile_measure/setup.cfg create mode 100644 3D_printer/3D_printer_profile_measure/setup.py create mode 100644 3D_printer/3D_printer_profile_measure/test/test_copyright.py create mode 100644 3D_printer/3D_printer_profile_measure/test/test_flake8.py create mode 100644 3D_printer/3D_printer_profile_measure/test/test_pep257.py create mode 100644 3D_printer/src/3D_printer_command/3D_printer_command/__init__.py create mode 100644 3D_printer/src/3D_printer_command/package.xml create mode 100644 3D_printer/src/3D_printer_command/resource/3D_printer_command create mode 100644 3D_printer/src/3D_printer_command/setup.cfg create mode 100644 3D_printer/src/3D_printer_command/setup.py create mode 100644 3D_printer/src/3D_printer_command/test/test_copyright.py create mode 100644 3D_printer/src/3D_printer_command/test/test_flake8.py create mode 100644 3D_printer/src/3D_printer_command/test/test_pep257.py create mode 100644 3D_printer/src/3D_printer_image_capture/3D_printer_image_capture/__init__.py create mode 100644 3D_printer/src/3D_printer_image_capture/package.xml create mode 100644 3D_printer/src/3D_printer_image_capture/resource/3D_printer_image_capture create mode 100644 3D_printer/src/3D_printer_image_capture/setup.cfg create mode 100644 3D_printer/src/3D_printer_image_capture/setup.py create mode 100644 3D_printer/src/3D_printer_image_capture/test/test_copyright.py create mode 100644 3D_printer/src/3D_printer_image_capture/test/test_flake8.py create mode 100644 3D_printer/src/3D_printer_image_capture/test/test_pep257.py create mode 100644 3D_printer/src/3D_printer_messages/3D_printer_messages/__init__.py create mode 100644 3D_printer/src/3D_printer_messages/package.xml create mode 100644 3D_printer/src/3D_printer_messages/resource/3D_printer_messages create mode 100644 3D_printer/src/3D_printer_messages/setup.cfg create mode 100644 3D_printer/src/3D_printer_messages/setup.py create mode 100644 3D_printer/src/3D_printer_messages/test/test_copyright.py create mode 100644 3D_printer/src/3D_printer_messages/test/test_flake8.py create mode 100644 3D_printer/src/3D_printer_messages/test/test_pep257.py create mode 100644 3D_printer/src/3D_printer_profile_measure/3D_printer_profile_measure/__init__.py create mode 100644 3D_printer/src/3D_printer_profile_measure/package.xml create mode 100644 3D_printer/src/3D_printer_profile_measure/resource/3D_printer_profile_measure create mode 100644 3D_printer/src/3D_printer_profile_measure/setup.cfg create mode 100644 3D_printer/src/3D_printer_profile_measure/setup.py create mode 100644 3D_printer/src/3D_printer_profile_measure/test/test_copyright.py create mode 100644 3D_printer/src/3D_printer_profile_measure/test/test_flake8.py create mode 100644 3D_printer/src/3D_printer_profile_measure/test/test_pep257.py diff --git a/3D_printer/3D_printer_command/3D_printer_command/__init__.py b/3D_printer/3D_printer_command/3D_printer_command/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/3D_printer_command/package.xml b/3D_printer/3D_printer_command/package.xml new file mode 100644 index 0000000..ed8ab6d --- /dev/null +++ b/3D_printer/3D_printer_command/package.xml @@ -0,0 +1,18 @@ + + + + 3D_printer_command + 0.0.0 + TODO: Package description + gulltor + TODO: License declaration + + ament_copyright + ament_flake8 + ament_pep257 + python3-pytest + + + ament_python + + diff --git a/3D_printer/3D_printer_command/resource/3D_printer_command b/3D_printer/3D_printer_command/resource/3D_printer_command new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/3D_printer_command/setup.cfg b/3D_printer/3D_printer_command/setup.cfg new file mode 100644 index 0000000..11a53c6 --- /dev/null +++ b/3D_printer/3D_printer_command/setup.cfg @@ -0,0 +1,4 @@ +[develop] +script-dir=$base/lib/3D_printer_command +[install] +install-scripts=$base/lib/3D_printer_command diff --git a/3D_printer/3D_printer_command/setup.py b/3D_printer/3D_printer_command/setup.py new file mode 100644 index 0000000..6b0bdc0 --- /dev/null +++ b/3D_printer/3D_printer_command/setup.py @@ -0,0 +1,25 @@ +from setuptools import setup + +package_name = '3D_printer_command' + +setup( + name=package_name, + version='0.0.0', + packages=[package_name], + data_files=[ + ('share/ament_index/resource_index/packages', + ['resource/' + package_name]), + ('share/' + package_name, ['package.xml']), + ], + install_requires=['setuptools'], + zip_safe=True, + maintainer='gulltor', + maintainer_email='mosserl@unistra.fr', + description='TODO: Package description', + license='TODO: License declaration', + tests_require=['pytest'], + entry_points={ + 'console_scripts': [ + ], + }, +) diff --git a/3D_printer/3D_printer_command/test/test_copyright.py b/3D_printer/3D_printer_command/test/test_copyright.py new file mode 100644 index 0000000..cc8ff03 --- /dev/null +++ b/3D_printer/3D_printer_command/test/test_copyright.py @@ -0,0 +1,23 @@ +# Copyright 2015 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_copyright.main import main +import pytest + + +@pytest.mark.copyright +@pytest.mark.linter +def test_copyright(): + rc = main(argv=['.', 'test']) + assert rc == 0, 'Found errors' diff --git a/3D_printer/3D_printer_command/test/test_flake8.py b/3D_printer/3D_printer_command/test/test_flake8.py new file mode 100644 index 0000000..27ee107 --- /dev/null +++ b/3D_printer/3D_printer_command/test/test_flake8.py @@ -0,0 +1,25 @@ +# Copyright 2017 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_flake8.main import main_with_errors +import pytest + + +@pytest.mark.flake8 +@pytest.mark.linter +def test_flake8(): + rc, errors = main_with_errors(argv=[]) + assert rc == 0, \ + 'Found %d code style errors / warnings:\n' % len(errors) + \ + '\n'.join(errors) diff --git a/3D_printer/3D_printer_command/test/test_pep257.py b/3D_printer/3D_printer_command/test/test_pep257.py new file mode 100644 index 0000000..b234a38 --- /dev/null +++ b/3D_printer/3D_printer_command/test/test_pep257.py @@ -0,0 +1,23 @@ +# Copyright 2015 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_pep257.main import main +import pytest + + +@pytest.mark.linter +@pytest.mark.pep257 +def test_pep257(): + rc = main(argv=['.', 'test']) + assert rc == 0, 'Found code style errors / warnings' diff --git a/3D_printer/3D_printer_image_capture/3D_printer_image_capture/__init__.py b/3D_printer/3D_printer_image_capture/3D_printer_image_capture/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/3D_printer_image_capture/package.xml b/3D_printer/3D_printer_image_capture/package.xml new file mode 100644 index 0000000..660ad94 --- /dev/null +++ b/3D_printer/3D_printer_image_capture/package.xml @@ -0,0 +1,18 @@ + + + + 3D_printer_image_capture + 0.0.0 + TODO: Package description + gulltor + TODO: License declaration + + ament_copyright + ament_flake8 + ament_pep257 + python3-pytest + + + ament_python + + diff --git a/3D_printer/3D_printer_image_capture/resource/3D_printer_image_capture b/3D_printer/3D_printer_image_capture/resource/3D_printer_image_capture new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/3D_printer_image_capture/setup.cfg b/3D_printer/3D_printer_image_capture/setup.cfg new file mode 100644 index 0000000..69b1eb9 --- /dev/null +++ b/3D_printer/3D_printer_image_capture/setup.cfg @@ -0,0 +1,4 @@ +[develop] +script-dir=$base/lib/3D_printer_image_capture +[install] +install-scripts=$base/lib/3D_printer_image_capture diff --git a/3D_printer/3D_printer_image_capture/setup.py b/3D_printer/3D_printer_image_capture/setup.py new file mode 100644 index 0000000..1992770 --- /dev/null +++ b/3D_printer/3D_printer_image_capture/setup.py @@ -0,0 +1,25 @@ +from setuptools import setup + +package_name = '3D_printer_image_capture' + +setup( + name=package_name, + version='0.0.0', + packages=[package_name], + data_files=[ + ('share/ament_index/resource_index/packages', + ['resource/' + package_name]), + ('share/' + package_name, ['package.xml']), + ], + install_requires=['setuptools'], + zip_safe=True, + maintainer='gulltor', + maintainer_email='mosserl@unistra.fr', + description='TODO: Package description', + license='TODO: License declaration', + tests_require=['pytest'], + entry_points={ + 'console_scripts': [ + ], + }, +) diff --git a/3D_printer/3D_printer_image_capture/test/test_copyright.py b/3D_printer/3D_printer_image_capture/test/test_copyright.py new file mode 100644 index 0000000..cc8ff03 --- /dev/null +++ b/3D_printer/3D_printer_image_capture/test/test_copyright.py @@ -0,0 +1,23 @@ +# Copyright 2015 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_copyright.main import main +import pytest + + +@pytest.mark.copyright +@pytest.mark.linter +def test_copyright(): + rc = main(argv=['.', 'test']) + assert rc == 0, 'Found errors' diff --git a/3D_printer/3D_printer_image_capture/test/test_flake8.py b/3D_printer/3D_printer_image_capture/test/test_flake8.py new file mode 100644 index 0000000..27ee107 --- /dev/null +++ b/3D_printer/3D_printer_image_capture/test/test_flake8.py @@ -0,0 +1,25 @@ +# Copyright 2017 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_flake8.main import main_with_errors +import pytest + + +@pytest.mark.flake8 +@pytest.mark.linter +def test_flake8(): + rc, errors = main_with_errors(argv=[]) + assert rc == 0, \ + 'Found %d code style errors / warnings:\n' % len(errors) + \ + '\n'.join(errors) diff --git a/3D_printer/3D_printer_image_capture/test/test_pep257.py b/3D_printer/3D_printer_image_capture/test/test_pep257.py new file mode 100644 index 0000000..b234a38 --- /dev/null +++ b/3D_printer/3D_printer_image_capture/test/test_pep257.py @@ -0,0 +1,23 @@ +# Copyright 2015 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_pep257.main import main +import pytest + + +@pytest.mark.linter +@pytest.mark.pep257 +def test_pep257(): + rc = main(argv=['.', 'test']) + assert rc == 0, 'Found code style errors / warnings' diff --git a/3D_printer/3D_printer_messages/3D_printer_messages/__init__.py b/3D_printer/3D_printer_messages/3D_printer_messages/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/3D_printer_messages/package.xml b/3D_printer/3D_printer_messages/package.xml new file mode 100644 index 0000000..30453fc --- /dev/null +++ b/3D_printer/3D_printer_messages/package.xml @@ -0,0 +1,18 @@ + + + + 3D_printer_messages + 0.0.0 + TODO: Package description + gulltor + TODO: License declaration + + ament_copyright + ament_flake8 + ament_pep257 + python3-pytest + + + ament_python + + diff --git a/3D_printer/3D_printer_messages/resource/3D_printer_messages b/3D_printer/3D_printer_messages/resource/3D_printer_messages new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/3D_printer_messages/setup.cfg b/3D_printer/3D_printer_messages/setup.cfg new file mode 100644 index 0000000..0bca323 --- /dev/null +++ b/3D_printer/3D_printer_messages/setup.cfg @@ -0,0 +1,4 @@ +[develop] +script-dir=$base/lib/3D_printer_messages +[install] +install-scripts=$base/lib/3D_printer_messages diff --git a/3D_printer/3D_printer_messages/setup.py b/3D_printer/3D_printer_messages/setup.py new file mode 100644 index 0000000..d64213d --- /dev/null +++ b/3D_printer/3D_printer_messages/setup.py @@ -0,0 +1,25 @@ +from setuptools import setup + +package_name = '3D_printer_messages' + +setup( + name=package_name, + version='0.0.0', + packages=[package_name], + data_files=[ + ('share/ament_index/resource_index/packages', + ['resource/' + package_name]), + ('share/' + package_name, ['package.xml']), + ], + install_requires=['setuptools'], + zip_safe=True, + maintainer='gulltor', + maintainer_email='mosserl@unistra.fr', + description='TODO: Package description', + license='TODO: License declaration', + tests_require=['pytest'], + entry_points={ + 'console_scripts': [ + ], + }, +) diff --git a/3D_printer/3D_printer_messages/test/test_copyright.py b/3D_printer/3D_printer_messages/test/test_copyright.py new file mode 100644 index 0000000..cc8ff03 --- /dev/null +++ b/3D_printer/3D_printer_messages/test/test_copyright.py @@ -0,0 +1,23 @@ +# Copyright 2015 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_copyright.main import main +import pytest + + +@pytest.mark.copyright +@pytest.mark.linter +def test_copyright(): + rc = main(argv=['.', 'test']) + assert rc == 0, 'Found errors' diff --git a/3D_printer/3D_printer_messages/test/test_flake8.py b/3D_printer/3D_printer_messages/test/test_flake8.py new file mode 100644 index 0000000..27ee107 --- /dev/null +++ b/3D_printer/3D_printer_messages/test/test_flake8.py @@ -0,0 +1,25 @@ +# Copyright 2017 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_flake8.main import main_with_errors +import pytest + + +@pytest.mark.flake8 +@pytest.mark.linter +def test_flake8(): + rc, errors = main_with_errors(argv=[]) + assert rc == 0, \ + 'Found %d code style errors / warnings:\n' % len(errors) + \ + '\n'.join(errors) diff --git a/3D_printer/3D_printer_messages/test/test_pep257.py b/3D_printer/3D_printer_messages/test/test_pep257.py new file mode 100644 index 0000000..b234a38 --- /dev/null +++ b/3D_printer/3D_printer_messages/test/test_pep257.py @@ -0,0 +1,23 @@ +# Copyright 2015 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_pep257.main import main +import pytest + + +@pytest.mark.linter +@pytest.mark.pep257 +def test_pep257(): + rc = main(argv=['.', 'test']) + assert rc == 0, 'Found code style errors / warnings' diff --git a/3D_printer/3D_printer_profile_measure/3D_printer_profile_measure/__init__.py b/3D_printer/3D_printer_profile_measure/3D_printer_profile_measure/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/3D_printer_profile_measure/package.xml b/3D_printer/3D_printer_profile_measure/package.xml new file mode 100644 index 0000000..4714468 --- /dev/null +++ b/3D_printer/3D_printer_profile_measure/package.xml @@ -0,0 +1,18 @@ + + + + 3D_printer_profile_measure + 0.0.0 + TODO: Package description + gulltor + TODO: License declaration + + ament_copyright + ament_flake8 + ament_pep257 + python3-pytest + + + ament_python + + diff --git a/3D_printer/3D_printer_profile_measure/resource/3D_printer_profile_measure b/3D_printer/3D_printer_profile_measure/resource/3D_printer_profile_measure new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/3D_printer_profile_measure/setup.cfg b/3D_printer/3D_printer_profile_measure/setup.cfg new file mode 100644 index 0000000..f963a88 --- /dev/null +++ b/3D_printer/3D_printer_profile_measure/setup.cfg @@ -0,0 +1,4 @@ +[develop] +script-dir=$base/lib/3D_printer_profile_measure +[install] +install-scripts=$base/lib/3D_printer_profile_measure diff --git a/3D_printer/3D_printer_profile_measure/setup.py b/3D_printer/3D_printer_profile_measure/setup.py new file mode 100644 index 0000000..4e3c0f6 --- /dev/null +++ b/3D_printer/3D_printer_profile_measure/setup.py @@ -0,0 +1,25 @@ +from setuptools import setup + +package_name = '3D_printer_profile_measure' + +setup( + name=package_name, + version='0.0.0', + packages=[package_name], + data_files=[ + ('share/ament_index/resource_index/packages', + ['resource/' + package_name]), + ('share/' + package_name, ['package.xml']), + ], + install_requires=['setuptools'], + zip_safe=True, + maintainer='gulltor', + maintainer_email='mosserl@unistra.fr', + description='TODO: Package description', + license='TODO: License declaration', + tests_require=['pytest'], + entry_points={ + 'console_scripts': [ + ], + }, +) diff --git a/3D_printer/3D_printer_profile_measure/test/test_copyright.py b/3D_printer/3D_printer_profile_measure/test/test_copyright.py new file mode 100644 index 0000000..cc8ff03 --- /dev/null +++ b/3D_printer/3D_printer_profile_measure/test/test_copyright.py @@ -0,0 +1,23 @@ +# Copyright 2015 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_copyright.main import main +import pytest + + +@pytest.mark.copyright +@pytest.mark.linter +def test_copyright(): + rc = main(argv=['.', 'test']) + assert rc == 0, 'Found errors' diff --git a/3D_printer/3D_printer_profile_measure/test/test_flake8.py b/3D_printer/3D_printer_profile_measure/test/test_flake8.py new file mode 100644 index 0000000..27ee107 --- /dev/null +++ b/3D_printer/3D_printer_profile_measure/test/test_flake8.py @@ -0,0 +1,25 @@ +# Copyright 2017 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_flake8.main import main_with_errors +import pytest + + +@pytest.mark.flake8 +@pytest.mark.linter +def test_flake8(): + rc, errors = main_with_errors(argv=[]) + assert rc == 0, \ + 'Found %d code style errors / warnings:\n' % len(errors) + \ + '\n'.join(errors) diff --git a/3D_printer/3D_printer_profile_measure/test/test_pep257.py b/3D_printer/3D_printer_profile_measure/test/test_pep257.py new file mode 100644 index 0000000..b234a38 --- /dev/null +++ b/3D_printer/3D_printer_profile_measure/test/test_pep257.py @@ -0,0 +1,23 @@ +# Copyright 2015 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_pep257.main import main +import pytest + + +@pytest.mark.linter +@pytest.mark.pep257 +def test_pep257(): + rc = main(argv=['.', 'test']) + assert rc == 0, 'Found code style errors / warnings' diff --git a/3D_printer/src/3D_printer_command/3D_printer_command/__init__.py b/3D_printer/src/3D_printer_command/3D_printer_command/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/src/3D_printer_command/package.xml b/3D_printer/src/3D_printer_command/package.xml new file mode 100644 index 0000000..ed8ab6d --- /dev/null +++ b/3D_printer/src/3D_printer_command/package.xml @@ -0,0 +1,18 @@ + + + + 3D_printer_command + 0.0.0 + TODO: Package description + gulltor + TODO: License declaration + + ament_copyright + ament_flake8 + ament_pep257 + python3-pytest + + + ament_python + + diff --git a/3D_printer/src/3D_printer_command/resource/3D_printer_command b/3D_printer/src/3D_printer_command/resource/3D_printer_command new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/src/3D_printer_command/setup.cfg b/3D_printer/src/3D_printer_command/setup.cfg new file mode 100644 index 0000000..11a53c6 --- /dev/null +++ b/3D_printer/src/3D_printer_command/setup.cfg @@ -0,0 +1,4 @@ +[develop] +script-dir=$base/lib/3D_printer_command +[install] +install-scripts=$base/lib/3D_printer_command diff --git a/3D_printer/src/3D_printer_command/setup.py b/3D_printer/src/3D_printer_command/setup.py new file mode 100644 index 0000000..6b0bdc0 --- /dev/null +++ b/3D_printer/src/3D_printer_command/setup.py @@ -0,0 +1,25 @@ +from setuptools import setup + +package_name = '3D_printer_command' + +setup( + name=package_name, + version='0.0.0', + packages=[package_name], + data_files=[ + ('share/ament_index/resource_index/packages', + ['resource/' + package_name]), + ('share/' + package_name, ['package.xml']), + ], + install_requires=['setuptools'], + zip_safe=True, + maintainer='gulltor', + maintainer_email='mosserl@unistra.fr', + description='TODO: Package description', + license='TODO: License declaration', + tests_require=['pytest'], + entry_points={ + 'console_scripts': [ + ], + }, +) diff --git a/3D_printer/src/3D_printer_command/test/test_copyright.py b/3D_printer/src/3D_printer_command/test/test_copyright.py new file mode 100644 index 0000000..cc8ff03 --- /dev/null +++ b/3D_printer/src/3D_printer_command/test/test_copyright.py @@ -0,0 +1,23 @@ +# Copyright 2015 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_copyright.main import main +import pytest + + +@pytest.mark.copyright +@pytest.mark.linter +def test_copyright(): + rc = main(argv=['.', 'test']) + assert rc == 0, 'Found errors' diff --git a/3D_printer/src/3D_printer_command/test/test_flake8.py b/3D_printer/src/3D_printer_command/test/test_flake8.py new file mode 100644 index 0000000..27ee107 --- /dev/null +++ b/3D_printer/src/3D_printer_command/test/test_flake8.py @@ -0,0 +1,25 @@ +# Copyright 2017 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_flake8.main import main_with_errors +import pytest + + +@pytest.mark.flake8 +@pytest.mark.linter +def test_flake8(): + rc, errors = main_with_errors(argv=[]) + assert rc == 0, \ + 'Found %d code style errors / warnings:\n' % len(errors) + \ + '\n'.join(errors) diff --git a/3D_printer/src/3D_printer_command/test/test_pep257.py b/3D_printer/src/3D_printer_command/test/test_pep257.py new file mode 100644 index 0000000..b234a38 --- /dev/null +++ b/3D_printer/src/3D_printer_command/test/test_pep257.py @@ -0,0 +1,23 @@ +# Copyright 2015 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_pep257.main import main +import pytest + + +@pytest.mark.linter +@pytest.mark.pep257 +def test_pep257(): + rc = main(argv=['.', 'test']) + assert rc == 0, 'Found code style errors / warnings' diff --git a/3D_printer/src/3D_printer_image_capture/3D_printer_image_capture/__init__.py b/3D_printer/src/3D_printer_image_capture/3D_printer_image_capture/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/src/3D_printer_image_capture/package.xml b/3D_printer/src/3D_printer_image_capture/package.xml new file mode 100644 index 0000000..660ad94 --- /dev/null +++ b/3D_printer/src/3D_printer_image_capture/package.xml @@ -0,0 +1,18 @@ + + + + 3D_printer_image_capture + 0.0.0 + TODO: Package description + gulltor + TODO: License declaration + + ament_copyright + ament_flake8 + ament_pep257 + python3-pytest + + + ament_python + + diff --git a/3D_printer/src/3D_printer_image_capture/resource/3D_printer_image_capture b/3D_printer/src/3D_printer_image_capture/resource/3D_printer_image_capture new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/src/3D_printer_image_capture/setup.cfg b/3D_printer/src/3D_printer_image_capture/setup.cfg new file mode 100644 index 0000000..69b1eb9 --- /dev/null +++ b/3D_printer/src/3D_printer_image_capture/setup.cfg @@ -0,0 +1,4 @@ +[develop] +script-dir=$base/lib/3D_printer_image_capture +[install] +install-scripts=$base/lib/3D_printer_image_capture diff --git a/3D_printer/src/3D_printer_image_capture/setup.py b/3D_printer/src/3D_printer_image_capture/setup.py new file mode 100644 index 0000000..1992770 --- /dev/null +++ b/3D_printer/src/3D_printer_image_capture/setup.py @@ -0,0 +1,25 @@ +from setuptools import setup + +package_name = '3D_printer_image_capture' + +setup( + name=package_name, + version='0.0.0', + packages=[package_name], + data_files=[ + ('share/ament_index/resource_index/packages', + ['resource/' + package_name]), + ('share/' + package_name, ['package.xml']), + ], + install_requires=['setuptools'], + zip_safe=True, + maintainer='gulltor', + maintainer_email='mosserl@unistra.fr', + description='TODO: Package description', + license='TODO: License declaration', + tests_require=['pytest'], + entry_points={ + 'console_scripts': [ + ], + }, +) diff --git a/3D_printer/src/3D_printer_image_capture/test/test_copyright.py b/3D_printer/src/3D_printer_image_capture/test/test_copyright.py new file mode 100644 index 0000000..cc8ff03 --- /dev/null +++ b/3D_printer/src/3D_printer_image_capture/test/test_copyright.py @@ -0,0 +1,23 @@ +# Copyright 2015 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_copyright.main import main +import pytest + + +@pytest.mark.copyright +@pytest.mark.linter +def test_copyright(): + rc = main(argv=['.', 'test']) + assert rc == 0, 'Found errors' diff --git a/3D_printer/src/3D_printer_image_capture/test/test_flake8.py b/3D_printer/src/3D_printer_image_capture/test/test_flake8.py new file mode 100644 index 0000000..27ee107 --- /dev/null +++ b/3D_printer/src/3D_printer_image_capture/test/test_flake8.py @@ -0,0 +1,25 @@ +# Copyright 2017 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_flake8.main import main_with_errors +import pytest + + +@pytest.mark.flake8 +@pytest.mark.linter +def test_flake8(): + rc, errors = main_with_errors(argv=[]) + assert rc == 0, \ + 'Found %d code style errors / warnings:\n' % len(errors) + \ + '\n'.join(errors) diff --git a/3D_printer/src/3D_printer_image_capture/test/test_pep257.py b/3D_printer/src/3D_printer_image_capture/test/test_pep257.py new file mode 100644 index 0000000..b234a38 --- /dev/null +++ b/3D_printer/src/3D_printer_image_capture/test/test_pep257.py @@ -0,0 +1,23 @@ +# Copyright 2015 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_pep257.main import main +import pytest + + +@pytest.mark.linter +@pytest.mark.pep257 +def test_pep257(): + rc = main(argv=['.', 'test']) + assert rc == 0, 'Found code style errors / warnings' diff --git a/3D_printer/src/3D_printer_messages/3D_printer_messages/__init__.py b/3D_printer/src/3D_printer_messages/3D_printer_messages/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/src/3D_printer_messages/package.xml b/3D_printer/src/3D_printer_messages/package.xml new file mode 100644 index 0000000..30453fc --- /dev/null +++ b/3D_printer/src/3D_printer_messages/package.xml @@ -0,0 +1,18 @@ + + + + 3D_printer_messages + 0.0.0 + TODO: Package description + gulltor + TODO: License declaration + + ament_copyright + ament_flake8 + ament_pep257 + python3-pytest + + + ament_python + + diff --git a/3D_printer/src/3D_printer_messages/resource/3D_printer_messages b/3D_printer/src/3D_printer_messages/resource/3D_printer_messages new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/src/3D_printer_messages/setup.cfg b/3D_printer/src/3D_printer_messages/setup.cfg new file mode 100644 index 0000000..0bca323 --- /dev/null +++ b/3D_printer/src/3D_printer_messages/setup.cfg @@ -0,0 +1,4 @@ +[develop] +script-dir=$base/lib/3D_printer_messages +[install] +install-scripts=$base/lib/3D_printer_messages diff --git a/3D_printer/src/3D_printer_messages/setup.py b/3D_printer/src/3D_printer_messages/setup.py new file mode 100644 index 0000000..d64213d --- /dev/null +++ b/3D_printer/src/3D_printer_messages/setup.py @@ -0,0 +1,25 @@ +from setuptools import setup + +package_name = '3D_printer_messages' + +setup( + name=package_name, + version='0.0.0', + packages=[package_name], + data_files=[ + ('share/ament_index/resource_index/packages', + ['resource/' + package_name]), + ('share/' + package_name, ['package.xml']), + ], + install_requires=['setuptools'], + zip_safe=True, + maintainer='gulltor', + maintainer_email='mosserl@unistra.fr', + description='TODO: Package description', + license='TODO: License declaration', + tests_require=['pytest'], + entry_points={ + 'console_scripts': [ + ], + }, +) diff --git a/3D_printer/src/3D_printer_messages/test/test_copyright.py b/3D_printer/src/3D_printer_messages/test/test_copyright.py new file mode 100644 index 0000000..cc8ff03 --- /dev/null +++ b/3D_printer/src/3D_printer_messages/test/test_copyright.py @@ -0,0 +1,23 @@ +# Copyright 2015 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_copyright.main import main +import pytest + + +@pytest.mark.copyright +@pytest.mark.linter +def test_copyright(): + rc = main(argv=['.', 'test']) + assert rc == 0, 'Found errors' diff --git a/3D_printer/src/3D_printer_messages/test/test_flake8.py b/3D_printer/src/3D_printer_messages/test/test_flake8.py new file mode 100644 index 0000000..27ee107 --- /dev/null +++ b/3D_printer/src/3D_printer_messages/test/test_flake8.py @@ -0,0 +1,25 @@ +# Copyright 2017 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_flake8.main import main_with_errors +import pytest + + +@pytest.mark.flake8 +@pytest.mark.linter +def test_flake8(): + rc, errors = main_with_errors(argv=[]) + assert rc == 0, \ + 'Found %d code style errors / warnings:\n' % len(errors) + \ + '\n'.join(errors) diff --git a/3D_printer/src/3D_printer_messages/test/test_pep257.py b/3D_printer/src/3D_printer_messages/test/test_pep257.py new file mode 100644 index 0000000..b234a38 --- /dev/null +++ b/3D_printer/src/3D_printer_messages/test/test_pep257.py @@ -0,0 +1,23 @@ +# Copyright 2015 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_pep257.main import main +import pytest + + +@pytest.mark.linter +@pytest.mark.pep257 +def test_pep257(): + rc = main(argv=['.', 'test']) + assert rc == 0, 'Found code style errors / warnings' diff --git a/3D_printer/src/3D_printer_profile_measure/3D_printer_profile_measure/__init__.py b/3D_printer/src/3D_printer_profile_measure/3D_printer_profile_measure/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/src/3D_printer_profile_measure/package.xml b/3D_printer/src/3D_printer_profile_measure/package.xml new file mode 100644 index 0000000..4714468 --- /dev/null +++ b/3D_printer/src/3D_printer_profile_measure/package.xml @@ -0,0 +1,18 @@ + + + + 3D_printer_profile_measure + 0.0.0 + TODO: Package description + gulltor + TODO: License declaration + + ament_copyright + ament_flake8 + ament_pep257 + python3-pytest + + + ament_python + + diff --git a/3D_printer/src/3D_printer_profile_measure/resource/3D_printer_profile_measure b/3D_printer/src/3D_printer_profile_measure/resource/3D_printer_profile_measure new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/src/3D_printer_profile_measure/setup.cfg b/3D_printer/src/3D_printer_profile_measure/setup.cfg new file mode 100644 index 0000000..f963a88 --- /dev/null +++ b/3D_printer/src/3D_printer_profile_measure/setup.cfg @@ -0,0 +1,4 @@ +[develop] +script-dir=$base/lib/3D_printer_profile_measure +[install] +install-scripts=$base/lib/3D_printer_profile_measure diff --git a/3D_printer/src/3D_printer_profile_measure/setup.py b/3D_printer/src/3D_printer_profile_measure/setup.py new file mode 100644 index 0000000..4e3c0f6 --- /dev/null +++ b/3D_printer/src/3D_printer_profile_measure/setup.py @@ -0,0 +1,25 @@ +from setuptools import setup + +package_name = '3D_printer_profile_measure' + +setup( + name=package_name, + version='0.0.0', + packages=[package_name], + data_files=[ + ('share/ament_index/resource_index/packages', + ['resource/' + package_name]), + ('share/' + package_name, ['package.xml']), + ], + install_requires=['setuptools'], + zip_safe=True, + maintainer='gulltor', + maintainer_email='mosserl@unistra.fr', + description='TODO: Package description', + license='TODO: License declaration', + tests_require=['pytest'], + entry_points={ + 'console_scripts': [ + ], + }, +) diff --git a/3D_printer/src/3D_printer_profile_measure/test/test_copyright.py b/3D_printer/src/3D_printer_profile_measure/test/test_copyright.py new file mode 100644 index 0000000..cc8ff03 --- /dev/null +++ b/3D_printer/src/3D_printer_profile_measure/test/test_copyright.py @@ -0,0 +1,23 @@ +# Copyright 2015 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_copyright.main import main +import pytest + + +@pytest.mark.copyright +@pytest.mark.linter +def test_copyright(): + rc = main(argv=['.', 'test']) + assert rc == 0, 'Found errors' diff --git a/3D_printer/src/3D_printer_profile_measure/test/test_flake8.py b/3D_printer/src/3D_printer_profile_measure/test/test_flake8.py new file mode 100644 index 0000000..27ee107 --- /dev/null +++ b/3D_printer/src/3D_printer_profile_measure/test/test_flake8.py @@ -0,0 +1,25 @@ +# Copyright 2017 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_flake8.main import main_with_errors +import pytest + + +@pytest.mark.flake8 +@pytest.mark.linter +def test_flake8(): + rc, errors = main_with_errors(argv=[]) + assert rc == 0, \ + 'Found %d code style errors / warnings:\n' % len(errors) + \ + '\n'.join(errors) diff --git a/3D_printer/src/3D_printer_profile_measure/test/test_pep257.py b/3D_printer/src/3D_printer_profile_measure/test/test_pep257.py new file mode 100644 index 0000000..b234a38 --- /dev/null +++ b/3D_printer/src/3D_printer_profile_measure/test/test_pep257.py @@ -0,0 +1,23 @@ +# Copyright 2015 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ament_pep257.main import main +import pytest + + +@pytest.mark.linter +@pytest.mark.pep257 +def test_pep257(): + rc = main(argv=['.', 'test']) + assert rc == 0, 'Found code style errors / warnings' From 6a31e58b7621cba2343c923a6e3bf1e9771becc1 Mon Sep 17 00:00:00 2001 From: Mosserl Date: Mon, 3 Apr 2023 19:08:27 +0200 Subject: [PATCH 02/30] Deleting some trash I've done --- .gitignore | 4 +++ .../3D_printer_command/__init__.py | 0 3D_printer/3D_printer_command/package.xml | 18 ------------- .../resource/3D_printer_command | 0 3D_printer/3D_printer_command/setup.cfg | 4 --- 3D_printer/3D_printer_command/setup.py | 25 ------------------- .../3D_printer_command/test/test_copyright.py | 23 ----------------- .../3D_printer_command/test/test_flake8.py | 25 ------------------- .../3D_printer_command/test/test_pep257.py | 23 ----------------- .../3D_printer_image_capture/__init__.py | 0 .../3D_printer_image_capture/package.xml | 18 ------------- .../resource/3D_printer_image_capture | 0 3D_printer/3D_printer_image_capture/setup.cfg | 4 --- 3D_printer/3D_printer_image_capture/setup.py | 25 ------------------- .../test/test_copyright.py | 23 ----------------- .../test/test_flake8.py | 25 ------------------- .../test/test_pep257.py | 23 ----------------- .../3D_printer_messages/__init__.py | 0 3D_printer/3D_printer_messages/package.xml | 18 ------------- .../resource/3D_printer_messages | 0 3D_printer/3D_printer_messages/setup.cfg | 4 --- 3D_printer/3D_printer_messages/setup.py | 25 ------------------- .../test/test_copyright.py | 23 ----------------- .../3D_printer_messages/test/test_flake8.py | 25 ------------------- .../3D_printer_messages/test/test_pep257.py | 23 ----------------- .../3D_printer_profile_measure/__init__.py | 0 .../3D_printer_profile_measure/package.xml | 18 ------------- .../resource/3D_printer_profile_measure | 0 .../3D_printer_profile_measure/setup.cfg | 4 --- .../3D_printer_profile_measure/setup.py | 25 ------------------- .../test/test_copyright.py | 23 ----------------- .../test/test_flake8.py | 25 ------------------- .../test/test_pep257.py | 23 ----------------- .../3D_printer_command/__init__.py | 0 3D_printer/src/3D_printer_command/package.xml | 18 ------------- .../resource/3D_printer_command | 0 3D_printer/src/3D_printer_command/setup.cfg | 4 --- 3D_printer/src/3D_printer_command/setup.py | 25 ------------------- .../3D_printer_command/test/test_copyright.py | 23 ----------------- .../3D_printer_command/test/test_flake8.py | 25 ------------------- .../3D_printer_command/test/test_pep257.py | 23 ----------------- .../3D_printer_image_capture/__init__.py | 0 .../src/3D_printer_image_capture/package.xml | 18 ------------- .../resource/3D_printer_image_capture | 0 .../src/3D_printer_image_capture/setup.cfg | 4 --- .../src/3D_printer_image_capture/setup.py | 25 ------------------- .../test/test_copyright.py | 23 ----------------- .../test/test_flake8.py | 25 ------------------- .../test/test_pep257.py | 23 ----------------- .../3D_printer_messages/__init__.py | 0 .../src/3D_printer_messages/package.xml | 18 ------------- .../resource/3D_printer_messages | 0 3D_printer/src/3D_printer_messages/setup.cfg | 4 --- 3D_printer/src/3D_printer_messages/setup.py | 25 ------------------- .../test/test_copyright.py | 23 ----------------- .../3D_printer_messages/test/test_flake8.py | 25 ------------------- .../3D_printer_messages/test/test_pep257.py | 23 ----------------- .../3D_printer_profile_measure/__init__.py | 0 .../3D_printer_profile_measure/package.xml | 18 ------------- .../resource/3D_printer_profile_measure | 0 .../src/3D_printer_profile_measure/setup.cfg | 4 --- .../src/3D_printer_profile_measure/setup.py | 25 ------------------- .../test/test_copyright.py | 23 ----------------- .../test/test_flake8.py | 25 ------------------- .../test/test_pep257.py | 23 ----------------- 65 files changed, 4 insertions(+), 944 deletions(-) delete mode 100644 3D_printer/3D_printer_command/3D_printer_command/__init__.py delete mode 100644 3D_printer/3D_printer_command/package.xml delete mode 100644 3D_printer/3D_printer_command/resource/3D_printer_command delete mode 100644 3D_printer/3D_printer_command/setup.cfg delete mode 100644 3D_printer/3D_printer_command/setup.py delete mode 100644 3D_printer/3D_printer_command/test/test_copyright.py delete mode 100644 3D_printer/3D_printer_command/test/test_flake8.py delete mode 100644 3D_printer/3D_printer_command/test/test_pep257.py delete mode 100644 3D_printer/3D_printer_image_capture/3D_printer_image_capture/__init__.py delete mode 100644 3D_printer/3D_printer_image_capture/package.xml delete mode 100644 3D_printer/3D_printer_image_capture/resource/3D_printer_image_capture delete mode 100644 3D_printer/3D_printer_image_capture/setup.cfg delete mode 100644 3D_printer/3D_printer_image_capture/setup.py delete mode 100644 3D_printer/3D_printer_image_capture/test/test_copyright.py delete mode 100644 3D_printer/3D_printer_image_capture/test/test_flake8.py delete mode 100644 3D_printer/3D_printer_image_capture/test/test_pep257.py delete mode 100644 3D_printer/3D_printer_messages/3D_printer_messages/__init__.py delete mode 100644 3D_printer/3D_printer_messages/package.xml delete mode 100644 3D_printer/3D_printer_messages/resource/3D_printer_messages delete mode 100644 3D_printer/3D_printer_messages/setup.cfg delete mode 100644 3D_printer/3D_printer_messages/setup.py delete mode 100644 3D_printer/3D_printer_messages/test/test_copyright.py delete mode 100644 3D_printer/3D_printer_messages/test/test_flake8.py delete mode 100644 3D_printer/3D_printer_messages/test/test_pep257.py delete mode 100644 3D_printer/3D_printer_profile_measure/3D_printer_profile_measure/__init__.py delete mode 100644 3D_printer/3D_printer_profile_measure/package.xml delete mode 100644 3D_printer/3D_printer_profile_measure/resource/3D_printer_profile_measure delete mode 100644 3D_printer/3D_printer_profile_measure/setup.cfg delete mode 100644 3D_printer/3D_printer_profile_measure/setup.py delete mode 100644 3D_printer/3D_printer_profile_measure/test/test_copyright.py delete mode 100644 3D_printer/3D_printer_profile_measure/test/test_flake8.py delete mode 100644 3D_printer/3D_printer_profile_measure/test/test_pep257.py delete mode 100644 3D_printer/src/3D_printer_command/3D_printer_command/__init__.py delete mode 100644 3D_printer/src/3D_printer_command/package.xml delete mode 100644 3D_printer/src/3D_printer_command/resource/3D_printer_command delete mode 100644 3D_printer/src/3D_printer_command/setup.cfg delete mode 100644 3D_printer/src/3D_printer_command/setup.py delete mode 100644 3D_printer/src/3D_printer_command/test/test_copyright.py delete mode 100644 3D_printer/src/3D_printer_command/test/test_flake8.py delete mode 100644 3D_printer/src/3D_printer_command/test/test_pep257.py delete mode 100644 3D_printer/src/3D_printer_image_capture/3D_printer_image_capture/__init__.py delete mode 100644 3D_printer/src/3D_printer_image_capture/package.xml delete mode 100644 3D_printer/src/3D_printer_image_capture/resource/3D_printer_image_capture delete mode 100644 3D_printer/src/3D_printer_image_capture/setup.cfg delete mode 100644 3D_printer/src/3D_printer_image_capture/setup.py delete mode 100644 3D_printer/src/3D_printer_image_capture/test/test_copyright.py delete mode 100644 3D_printer/src/3D_printer_image_capture/test/test_flake8.py delete mode 100644 3D_printer/src/3D_printer_image_capture/test/test_pep257.py delete mode 100644 3D_printer/src/3D_printer_messages/3D_printer_messages/__init__.py delete mode 100644 3D_printer/src/3D_printer_messages/package.xml delete mode 100644 3D_printer/src/3D_printer_messages/resource/3D_printer_messages delete mode 100644 3D_printer/src/3D_printer_messages/setup.cfg delete mode 100644 3D_printer/src/3D_printer_messages/setup.py delete mode 100644 3D_printer/src/3D_printer_messages/test/test_copyright.py delete mode 100644 3D_printer/src/3D_printer_messages/test/test_flake8.py delete mode 100644 3D_printer/src/3D_printer_messages/test/test_pep257.py delete mode 100644 3D_printer/src/3D_printer_profile_measure/3D_printer_profile_measure/__init__.py delete mode 100644 3D_printer/src/3D_printer_profile_measure/package.xml delete mode 100644 3D_printer/src/3D_printer_profile_measure/resource/3D_printer_profile_measure delete mode 100644 3D_printer/src/3D_printer_profile_measure/setup.cfg delete mode 100644 3D_printer/src/3D_printer_profile_measure/setup.py delete mode 100644 3D_printer/src/3D_printer_profile_measure/test/test_copyright.py delete mode 100644 3D_printer/src/3D_printer_profile_measure/test/test_flake8.py delete mode 100644 3D_printer/src/3D_printer_profile_measure/test/test_pep257.py diff --git a/.gitignore b/.gitignore index 02b6441..6bbd1e2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,7 @@ build/ log/ install/ .vscode/ +3D_Printer/build +3D_Printer/install +3D_Printer/log +3D_Printer/src/ros2_3d_printer_profile_capture/external \ No newline at end of file diff --git a/3D_printer/3D_printer_command/3D_printer_command/__init__.py b/3D_printer/3D_printer_command/3D_printer_command/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/3D_printer/3D_printer_command/package.xml b/3D_printer/3D_printer_command/package.xml deleted file mode 100644 index ed8ab6d..0000000 --- a/3D_printer/3D_printer_command/package.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - 3D_printer_command - 0.0.0 - TODO: Package description - gulltor - TODO: License declaration - - ament_copyright - ament_flake8 - ament_pep257 - python3-pytest - - - ament_python - - diff --git a/3D_printer/3D_printer_command/resource/3D_printer_command b/3D_printer/3D_printer_command/resource/3D_printer_command deleted file mode 100644 index e69de29..0000000 diff --git a/3D_printer/3D_printer_command/setup.cfg b/3D_printer/3D_printer_command/setup.cfg deleted file mode 100644 index 11a53c6..0000000 --- a/3D_printer/3D_printer_command/setup.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[develop] -script-dir=$base/lib/3D_printer_command -[install] -install-scripts=$base/lib/3D_printer_command diff --git a/3D_printer/3D_printer_command/setup.py b/3D_printer/3D_printer_command/setup.py deleted file mode 100644 index 6b0bdc0..0000000 --- a/3D_printer/3D_printer_command/setup.py +++ /dev/null @@ -1,25 +0,0 @@ -from setuptools import setup - -package_name = '3D_printer_command' - -setup( - name=package_name, - version='0.0.0', - packages=[package_name], - data_files=[ - ('share/ament_index/resource_index/packages', - ['resource/' + package_name]), - ('share/' + package_name, ['package.xml']), - ], - install_requires=['setuptools'], - zip_safe=True, - maintainer='gulltor', - maintainer_email='mosserl@unistra.fr', - description='TODO: Package description', - license='TODO: License declaration', - tests_require=['pytest'], - entry_points={ - 'console_scripts': [ - ], - }, -) diff --git a/3D_printer/3D_printer_command/test/test_copyright.py b/3D_printer/3D_printer_command/test/test_copyright.py deleted file mode 100644 index cc8ff03..0000000 --- a/3D_printer/3D_printer_command/test/test_copyright.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_copyright.main import main -import pytest - - -@pytest.mark.copyright -@pytest.mark.linter -def test_copyright(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found errors' diff --git a/3D_printer/3D_printer_command/test/test_flake8.py b/3D_printer/3D_printer_command/test/test_flake8.py deleted file mode 100644 index 27ee107..0000000 --- a/3D_printer/3D_printer_command/test/test_flake8.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2017 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_flake8.main import main_with_errors -import pytest - - -@pytest.mark.flake8 -@pytest.mark.linter -def test_flake8(): - rc, errors = main_with_errors(argv=[]) - assert rc == 0, \ - 'Found %d code style errors / warnings:\n' % len(errors) + \ - '\n'.join(errors) diff --git a/3D_printer/3D_printer_command/test/test_pep257.py b/3D_printer/3D_printer_command/test/test_pep257.py deleted file mode 100644 index b234a38..0000000 --- a/3D_printer/3D_printer_command/test/test_pep257.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_pep257.main import main -import pytest - - -@pytest.mark.linter -@pytest.mark.pep257 -def test_pep257(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found code style errors / warnings' diff --git a/3D_printer/3D_printer_image_capture/3D_printer_image_capture/__init__.py b/3D_printer/3D_printer_image_capture/3D_printer_image_capture/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/3D_printer/3D_printer_image_capture/package.xml b/3D_printer/3D_printer_image_capture/package.xml deleted file mode 100644 index 660ad94..0000000 --- a/3D_printer/3D_printer_image_capture/package.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - 3D_printer_image_capture - 0.0.0 - TODO: Package description - gulltor - TODO: License declaration - - ament_copyright - ament_flake8 - ament_pep257 - python3-pytest - - - ament_python - - diff --git a/3D_printer/3D_printer_image_capture/resource/3D_printer_image_capture b/3D_printer/3D_printer_image_capture/resource/3D_printer_image_capture deleted file mode 100644 index e69de29..0000000 diff --git a/3D_printer/3D_printer_image_capture/setup.cfg b/3D_printer/3D_printer_image_capture/setup.cfg deleted file mode 100644 index 69b1eb9..0000000 --- a/3D_printer/3D_printer_image_capture/setup.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[develop] -script-dir=$base/lib/3D_printer_image_capture -[install] -install-scripts=$base/lib/3D_printer_image_capture diff --git a/3D_printer/3D_printer_image_capture/setup.py b/3D_printer/3D_printer_image_capture/setup.py deleted file mode 100644 index 1992770..0000000 --- a/3D_printer/3D_printer_image_capture/setup.py +++ /dev/null @@ -1,25 +0,0 @@ -from setuptools import setup - -package_name = '3D_printer_image_capture' - -setup( - name=package_name, - version='0.0.0', - packages=[package_name], - data_files=[ - ('share/ament_index/resource_index/packages', - ['resource/' + package_name]), - ('share/' + package_name, ['package.xml']), - ], - install_requires=['setuptools'], - zip_safe=True, - maintainer='gulltor', - maintainer_email='mosserl@unistra.fr', - description='TODO: Package description', - license='TODO: License declaration', - tests_require=['pytest'], - entry_points={ - 'console_scripts': [ - ], - }, -) diff --git a/3D_printer/3D_printer_image_capture/test/test_copyright.py b/3D_printer/3D_printer_image_capture/test/test_copyright.py deleted file mode 100644 index cc8ff03..0000000 --- a/3D_printer/3D_printer_image_capture/test/test_copyright.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_copyright.main import main -import pytest - - -@pytest.mark.copyright -@pytest.mark.linter -def test_copyright(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found errors' diff --git a/3D_printer/3D_printer_image_capture/test/test_flake8.py b/3D_printer/3D_printer_image_capture/test/test_flake8.py deleted file mode 100644 index 27ee107..0000000 --- a/3D_printer/3D_printer_image_capture/test/test_flake8.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2017 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_flake8.main import main_with_errors -import pytest - - -@pytest.mark.flake8 -@pytest.mark.linter -def test_flake8(): - rc, errors = main_with_errors(argv=[]) - assert rc == 0, \ - 'Found %d code style errors / warnings:\n' % len(errors) + \ - '\n'.join(errors) diff --git a/3D_printer/3D_printer_image_capture/test/test_pep257.py b/3D_printer/3D_printer_image_capture/test/test_pep257.py deleted file mode 100644 index b234a38..0000000 --- a/3D_printer/3D_printer_image_capture/test/test_pep257.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_pep257.main import main -import pytest - - -@pytest.mark.linter -@pytest.mark.pep257 -def test_pep257(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found code style errors / warnings' diff --git a/3D_printer/3D_printer_messages/3D_printer_messages/__init__.py b/3D_printer/3D_printer_messages/3D_printer_messages/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/3D_printer/3D_printer_messages/package.xml b/3D_printer/3D_printer_messages/package.xml deleted file mode 100644 index 30453fc..0000000 --- a/3D_printer/3D_printer_messages/package.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - 3D_printer_messages - 0.0.0 - TODO: Package description - gulltor - TODO: License declaration - - ament_copyright - ament_flake8 - ament_pep257 - python3-pytest - - - ament_python - - diff --git a/3D_printer/3D_printer_messages/resource/3D_printer_messages b/3D_printer/3D_printer_messages/resource/3D_printer_messages deleted file mode 100644 index e69de29..0000000 diff --git a/3D_printer/3D_printer_messages/setup.cfg b/3D_printer/3D_printer_messages/setup.cfg deleted file mode 100644 index 0bca323..0000000 --- a/3D_printer/3D_printer_messages/setup.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[develop] -script-dir=$base/lib/3D_printer_messages -[install] -install-scripts=$base/lib/3D_printer_messages diff --git a/3D_printer/3D_printer_messages/setup.py b/3D_printer/3D_printer_messages/setup.py deleted file mode 100644 index d64213d..0000000 --- a/3D_printer/3D_printer_messages/setup.py +++ /dev/null @@ -1,25 +0,0 @@ -from setuptools import setup - -package_name = '3D_printer_messages' - -setup( - name=package_name, - version='0.0.0', - packages=[package_name], - data_files=[ - ('share/ament_index/resource_index/packages', - ['resource/' + package_name]), - ('share/' + package_name, ['package.xml']), - ], - install_requires=['setuptools'], - zip_safe=True, - maintainer='gulltor', - maintainer_email='mosserl@unistra.fr', - description='TODO: Package description', - license='TODO: License declaration', - tests_require=['pytest'], - entry_points={ - 'console_scripts': [ - ], - }, -) diff --git a/3D_printer/3D_printer_messages/test/test_copyright.py b/3D_printer/3D_printer_messages/test/test_copyright.py deleted file mode 100644 index cc8ff03..0000000 --- a/3D_printer/3D_printer_messages/test/test_copyright.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_copyright.main import main -import pytest - - -@pytest.mark.copyright -@pytest.mark.linter -def test_copyright(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found errors' diff --git a/3D_printer/3D_printer_messages/test/test_flake8.py b/3D_printer/3D_printer_messages/test/test_flake8.py deleted file mode 100644 index 27ee107..0000000 --- a/3D_printer/3D_printer_messages/test/test_flake8.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2017 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_flake8.main import main_with_errors -import pytest - - -@pytest.mark.flake8 -@pytest.mark.linter -def test_flake8(): - rc, errors = main_with_errors(argv=[]) - assert rc == 0, \ - 'Found %d code style errors / warnings:\n' % len(errors) + \ - '\n'.join(errors) diff --git a/3D_printer/3D_printer_messages/test/test_pep257.py b/3D_printer/3D_printer_messages/test/test_pep257.py deleted file mode 100644 index b234a38..0000000 --- a/3D_printer/3D_printer_messages/test/test_pep257.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_pep257.main import main -import pytest - - -@pytest.mark.linter -@pytest.mark.pep257 -def test_pep257(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found code style errors / warnings' diff --git a/3D_printer/3D_printer_profile_measure/3D_printer_profile_measure/__init__.py b/3D_printer/3D_printer_profile_measure/3D_printer_profile_measure/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/3D_printer/3D_printer_profile_measure/package.xml b/3D_printer/3D_printer_profile_measure/package.xml deleted file mode 100644 index 4714468..0000000 --- a/3D_printer/3D_printer_profile_measure/package.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - 3D_printer_profile_measure - 0.0.0 - TODO: Package description - gulltor - TODO: License declaration - - ament_copyright - ament_flake8 - ament_pep257 - python3-pytest - - - ament_python - - diff --git a/3D_printer/3D_printer_profile_measure/resource/3D_printer_profile_measure b/3D_printer/3D_printer_profile_measure/resource/3D_printer_profile_measure deleted file mode 100644 index e69de29..0000000 diff --git a/3D_printer/3D_printer_profile_measure/setup.cfg b/3D_printer/3D_printer_profile_measure/setup.cfg deleted file mode 100644 index f963a88..0000000 --- a/3D_printer/3D_printer_profile_measure/setup.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[develop] -script-dir=$base/lib/3D_printer_profile_measure -[install] -install-scripts=$base/lib/3D_printer_profile_measure diff --git a/3D_printer/3D_printer_profile_measure/setup.py b/3D_printer/3D_printer_profile_measure/setup.py deleted file mode 100644 index 4e3c0f6..0000000 --- a/3D_printer/3D_printer_profile_measure/setup.py +++ /dev/null @@ -1,25 +0,0 @@ -from setuptools import setup - -package_name = '3D_printer_profile_measure' - -setup( - name=package_name, - version='0.0.0', - packages=[package_name], - data_files=[ - ('share/ament_index/resource_index/packages', - ['resource/' + package_name]), - ('share/' + package_name, ['package.xml']), - ], - install_requires=['setuptools'], - zip_safe=True, - maintainer='gulltor', - maintainer_email='mosserl@unistra.fr', - description='TODO: Package description', - license='TODO: License declaration', - tests_require=['pytest'], - entry_points={ - 'console_scripts': [ - ], - }, -) diff --git a/3D_printer/3D_printer_profile_measure/test/test_copyright.py b/3D_printer/3D_printer_profile_measure/test/test_copyright.py deleted file mode 100644 index cc8ff03..0000000 --- a/3D_printer/3D_printer_profile_measure/test/test_copyright.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_copyright.main import main -import pytest - - -@pytest.mark.copyright -@pytest.mark.linter -def test_copyright(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found errors' diff --git a/3D_printer/3D_printer_profile_measure/test/test_flake8.py b/3D_printer/3D_printer_profile_measure/test/test_flake8.py deleted file mode 100644 index 27ee107..0000000 --- a/3D_printer/3D_printer_profile_measure/test/test_flake8.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2017 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_flake8.main import main_with_errors -import pytest - - -@pytest.mark.flake8 -@pytest.mark.linter -def test_flake8(): - rc, errors = main_with_errors(argv=[]) - assert rc == 0, \ - 'Found %d code style errors / warnings:\n' % len(errors) + \ - '\n'.join(errors) diff --git a/3D_printer/3D_printer_profile_measure/test/test_pep257.py b/3D_printer/3D_printer_profile_measure/test/test_pep257.py deleted file mode 100644 index b234a38..0000000 --- a/3D_printer/3D_printer_profile_measure/test/test_pep257.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_pep257.main import main -import pytest - - -@pytest.mark.linter -@pytest.mark.pep257 -def test_pep257(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found code style errors / warnings' diff --git a/3D_printer/src/3D_printer_command/3D_printer_command/__init__.py b/3D_printer/src/3D_printer_command/3D_printer_command/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/3D_printer/src/3D_printer_command/package.xml b/3D_printer/src/3D_printer_command/package.xml deleted file mode 100644 index ed8ab6d..0000000 --- a/3D_printer/src/3D_printer_command/package.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - 3D_printer_command - 0.0.0 - TODO: Package description - gulltor - TODO: License declaration - - ament_copyright - ament_flake8 - ament_pep257 - python3-pytest - - - ament_python - - diff --git a/3D_printer/src/3D_printer_command/resource/3D_printer_command b/3D_printer/src/3D_printer_command/resource/3D_printer_command deleted file mode 100644 index e69de29..0000000 diff --git a/3D_printer/src/3D_printer_command/setup.cfg b/3D_printer/src/3D_printer_command/setup.cfg deleted file mode 100644 index 11a53c6..0000000 --- a/3D_printer/src/3D_printer_command/setup.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[develop] -script-dir=$base/lib/3D_printer_command -[install] -install-scripts=$base/lib/3D_printer_command diff --git a/3D_printer/src/3D_printer_command/setup.py b/3D_printer/src/3D_printer_command/setup.py deleted file mode 100644 index 6b0bdc0..0000000 --- a/3D_printer/src/3D_printer_command/setup.py +++ /dev/null @@ -1,25 +0,0 @@ -from setuptools import setup - -package_name = '3D_printer_command' - -setup( - name=package_name, - version='0.0.0', - packages=[package_name], - data_files=[ - ('share/ament_index/resource_index/packages', - ['resource/' + package_name]), - ('share/' + package_name, ['package.xml']), - ], - install_requires=['setuptools'], - zip_safe=True, - maintainer='gulltor', - maintainer_email='mosserl@unistra.fr', - description='TODO: Package description', - license='TODO: License declaration', - tests_require=['pytest'], - entry_points={ - 'console_scripts': [ - ], - }, -) diff --git a/3D_printer/src/3D_printer_command/test/test_copyright.py b/3D_printer/src/3D_printer_command/test/test_copyright.py deleted file mode 100644 index cc8ff03..0000000 --- a/3D_printer/src/3D_printer_command/test/test_copyright.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_copyright.main import main -import pytest - - -@pytest.mark.copyright -@pytest.mark.linter -def test_copyright(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found errors' diff --git a/3D_printer/src/3D_printer_command/test/test_flake8.py b/3D_printer/src/3D_printer_command/test/test_flake8.py deleted file mode 100644 index 27ee107..0000000 --- a/3D_printer/src/3D_printer_command/test/test_flake8.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2017 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_flake8.main import main_with_errors -import pytest - - -@pytest.mark.flake8 -@pytest.mark.linter -def test_flake8(): - rc, errors = main_with_errors(argv=[]) - assert rc == 0, \ - 'Found %d code style errors / warnings:\n' % len(errors) + \ - '\n'.join(errors) diff --git a/3D_printer/src/3D_printer_command/test/test_pep257.py b/3D_printer/src/3D_printer_command/test/test_pep257.py deleted file mode 100644 index b234a38..0000000 --- a/3D_printer/src/3D_printer_command/test/test_pep257.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_pep257.main import main -import pytest - - -@pytest.mark.linter -@pytest.mark.pep257 -def test_pep257(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found code style errors / warnings' diff --git a/3D_printer/src/3D_printer_image_capture/3D_printer_image_capture/__init__.py b/3D_printer/src/3D_printer_image_capture/3D_printer_image_capture/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/3D_printer/src/3D_printer_image_capture/package.xml b/3D_printer/src/3D_printer_image_capture/package.xml deleted file mode 100644 index 660ad94..0000000 --- a/3D_printer/src/3D_printer_image_capture/package.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - 3D_printer_image_capture - 0.0.0 - TODO: Package description - gulltor - TODO: License declaration - - ament_copyright - ament_flake8 - ament_pep257 - python3-pytest - - - ament_python - - diff --git a/3D_printer/src/3D_printer_image_capture/resource/3D_printer_image_capture b/3D_printer/src/3D_printer_image_capture/resource/3D_printer_image_capture deleted file mode 100644 index e69de29..0000000 diff --git a/3D_printer/src/3D_printer_image_capture/setup.cfg b/3D_printer/src/3D_printer_image_capture/setup.cfg deleted file mode 100644 index 69b1eb9..0000000 --- a/3D_printer/src/3D_printer_image_capture/setup.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[develop] -script-dir=$base/lib/3D_printer_image_capture -[install] -install-scripts=$base/lib/3D_printer_image_capture diff --git a/3D_printer/src/3D_printer_image_capture/setup.py b/3D_printer/src/3D_printer_image_capture/setup.py deleted file mode 100644 index 1992770..0000000 --- a/3D_printer/src/3D_printer_image_capture/setup.py +++ /dev/null @@ -1,25 +0,0 @@ -from setuptools import setup - -package_name = '3D_printer_image_capture' - -setup( - name=package_name, - version='0.0.0', - packages=[package_name], - data_files=[ - ('share/ament_index/resource_index/packages', - ['resource/' + package_name]), - ('share/' + package_name, ['package.xml']), - ], - install_requires=['setuptools'], - zip_safe=True, - maintainer='gulltor', - maintainer_email='mosserl@unistra.fr', - description='TODO: Package description', - license='TODO: License declaration', - tests_require=['pytest'], - entry_points={ - 'console_scripts': [ - ], - }, -) diff --git a/3D_printer/src/3D_printer_image_capture/test/test_copyright.py b/3D_printer/src/3D_printer_image_capture/test/test_copyright.py deleted file mode 100644 index cc8ff03..0000000 --- a/3D_printer/src/3D_printer_image_capture/test/test_copyright.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_copyright.main import main -import pytest - - -@pytest.mark.copyright -@pytest.mark.linter -def test_copyright(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found errors' diff --git a/3D_printer/src/3D_printer_image_capture/test/test_flake8.py b/3D_printer/src/3D_printer_image_capture/test/test_flake8.py deleted file mode 100644 index 27ee107..0000000 --- a/3D_printer/src/3D_printer_image_capture/test/test_flake8.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2017 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_flake8.main import main_with_errors -import pytest - - -@pytest.mark.flake8 -@pytest.mark.linter -def test_flake8(): - rc, errors = main_with_errors(argv=[]) - assert rc == 0, \ - 'Found %d code style errors / warnings:\n' % len(errors) + \ - '\n'.join(errors) diff --git a/3D_printer/src/3D_printer_image_capture/test/test_pep257.py b/3D_printer/src/3D_printer_image_capture/test/test_pep257.py deleted file mode 100644 index b234a38..0000000 --- a/3D_printer/src/3D_printer_image_capture/test/test_pep257.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_pep257.main import main -import pytest - - -@pytest.mark.linter -@pytest.mark.pep257 -def test_pep257(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found code style errors / warnings' diff --git a/3D_printer/src/3D_printer_messages/3D_printer_messages/__init__.py b/3D_printer/src/3D_printer_messages/3D_printer_messages/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/3D_printer/src/3D_printer_messages/package.xml b/3D_printer/src/3D_printer_messages/package.xml deleted file mode 100644 index 30453fc..0000000 --- a/3D_printer/src/3D_printer_messages/package.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - 3D_printer_messages - 0.0.0 - TODO: Package description - gulltor - TODO: License declaration - - ament_copyright - ament_flake8 - ament_pep257 - python3-pytest - - - ament_python - - diff --git a/3D_printer/src/3D_printer_messages/resource/3D_printer_messages b/3D_printer/src/3D_printer_messages/resource/3D_printer_messages deleted file mode 100644 index e69de29..0000000 diff --git a/3D_printer/src/3D_printer_messages/setup.cfg b/3D_printer/src/3D_printer_messages/setup.cfg deleted file mode 100644 index 0bca323..0000000 --- a/3D_printer/src/3D_printer_messages/setup.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[develop] -script-dir=$base/lib/3D_printer_messages -[install] -install-scripts=$base/lib/3D_printer_messages diff --git a/3D_printer/src/3D_printer_messages/setup.py b/3D_printer/src/3D_printer_messages/setup.py deleted file mode 100644 index d64213d..0000000 --- a/3D_printer/src/3D_printer_messages/setup.py +++ /dev/null @@ -1,25 +0,0 @@ -from setuptools import setup - -package_name = '3D_printer_messages' - -setup( - name=package_name, - version='0.0.0', - packages=[package_name], - data_files=[ - ('share/ament_index/resource_index/packages', - ['resource/' + package_name]), - ('share/' + package_name, ['package.xml']), - ], - install_requires=['setuptools'], - zip_safe=True, - maintainer='gulltor', - maintainer_email='mosserl@unistra.fr', - description='TODO: Package description', - license='TODO: License declaration', - tests_require=['pytest'], - entry_points={ - 'console_scripts': [ - ], - }, -) diff --git a/3D_printer/src/3D_printer_messages/test/test_copyright.py b/3D_printer/src/3D_printer_messages/test/test_copyright.py deleted file mode 100644 index cc8ff03..0000000 --- a/3D_printer/src/3D_printer_messages/test/test_copyright.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_copyright.main import main -import pytest - - -@pytest.mark.copyright -@pytest.mark.linter -def test_copyright(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found errors' diff --git a/3D_printer/src/3D_printer_messages/test/test_flake8.py b/3D_printer/src/3D_printer_messages/test/test_flake8.py deleted file mode 100644 index 27ee107..0000000 --- a/3D_printer/src/3D_printer_messages/test/test_flake8.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2017 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_flake8.main import main_with_errors -import pytest - - -@pytest.mark.flake8 -@pytest.mark.linter -def test_flake8(): - rc, errors = main_with_errors(argv=[]) - assert rc == 0, \ - 'Found %d code style errors / warnings:\n' % len(errors) + \ - '\n'.join(errors) diff --git a/3D_printer/src/3D_printer_messages/test/test_pep257.py b/3D_printer/src/3D_printer_messages/test/test_pep257.py deleted file mode 100644 index b234a38..0000000 --- a/3D_printer/src/3D_printer_messages/test/test_pep257.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_pep257.main import main -import pytest - - -@pytest.mark.linter -@pytest.mark.pep257 -def test_pep257(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found code style errors / warnings' diff --git a/3D_printer/src/3D_printer_profile_measure/3D_printer_profile_measure/__init__.py b/3D_printer/src/3D_printer_profile_measure/3D_printer_profile_measure/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/3D_printer/src/3D_printer_profile_measure/package.xml b/3D_printer/src/3D_printer_profile_measure/package.xml deleted file mode 100644 index 4714468..0000000 --- a/3D_printer/src/3D_printer_profile_measure/package.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - 3D_printer_profile_measure - 0.0.0 - TODO: Package description - gulltor - TODO: License declaration - - ament_copyright - ament_flake8 - ament_pep257 - python3-pytest - - - ament_python - - diff --git a/3D_printer/src/3D_printer_profile_measure/resource/3D_printer_profile_measure b/3D_printer/src/3D_printer_profile_measure/resource/3D_printer_profile_measure deleted file mode 100644 index e69de29..0000000 diff --git a/3D_printer/src/3D_printer_profile_measure/setup.cfg b/3D_printer/src/3D_printer_profile_measure/setup.cfg deleted file mode 100644 index f963a88..0000000 --- a/3D_printer/src/3D_printer_profile_measure/setup.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[develop] -script-dir=$base/lib/3D_printer_profile_measure -[install] -install-scripts=$base/lib/3D_printer_profile_measure diff --git a/3D_printer/src/3D_printer_profile_measure/setup.py b/3D_printer/src/3D_printer_profile_measure/setup.py deleted file mode 100644 index 4e3c0f6..0000000 --- a/3D_printer/src/3D_printer_profile_measure/setup.py +++ /dev/null @@ -1,25 +0,0 @@ -from setuptools import setup - -package_name = '3D_printer_profile_measure' - -setup( - name=package_name, - version='0.0.0', - packages=[package_name], - data_files=[ - ('share/ament_index/resource_index/packages', - ['resource/' + package_name]), - ('share/' + package_name, ['package.xml']), - ], - install_requires=['setuptools'], - zip_safe=True, - maintainer='gulltor', - maintainer_email='mosserl@unistra.fr', - description='TODO: Package description', - license='TODO: License declaration', - tests_require=['pytest'], - entry_points={ - 'console_scripts': [ - ], - }, -) diff --git a/3D_printer/src/3D_printer_profile_measure/test/test_copyright.py b/3D_printer/src/3D_printer_profile_measure/test/test_copyright.py deleted file mode 100644 index cc8ff03..0000000 --- a/3D_printer/src/3D_printer_profile_measure/test/test_copyright.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_copyright.main import main -import pytest - - -@pytest.mark.copyright -@pytest.mark.linter -def test_copyright(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found errors' diff --git a/3D_printer/src/3D_printer_profile_measure/test/test_flake8.py b/3D_printer/src/3D_printer_profile_measure/test/test_flake8.py deleted file mode 100644 index 27ee107..0000000 --- a/3D_printer/src/3D_printer_profile_measure/test/test_flake8.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2017 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_flake8.main import main_with_errors -import pytest - - -@pytest.mark.flake8 -@pytest.mark.linter -def test_flake8(): - rc, errors = main_with_errors(argv=[]) - assert rc == 0, \ - 'Found %d code style errors / warnings:\n' % len(errors) + \ - '\n'.join(errors) diff --git a/3D_printer/src/3D_printer_profile_measure/test/test_pep257.py b/3D_printer/src/3D_printer_profile_measure/test/test_pep257.py deleted file mode 100644 index b234a38..0000000 --- a/3D_printer/src/3D_printer_profile_measure/test/test_pep257.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2015 Open Source Robotics Foundation, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from ament_pep257.main import main -import pytest - - -@pytest.mark.linter -@pytest.mark.pep257 -def test_pep257(): - rc = main(argv=['.', 'test']) - assert rc == 0, 'Found code style errors / warnings' From 3ebf12ba917d50b6957829de9c3bf9a6120e815c Mon Sep 17 00:00:00 2001 From: Mosserl Date: Mon, 3 Apr 2023 19:09:26 +0200 Subject: [PATCH 03/30] Update .gitignore --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 6bbd1e2..915d803 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,4 @@ install/ .vscode/ 3D_Printer/build 3D_Printer/install -3D_Printer/log -3D_Printer/src/ros2_3d_printer_profile_capture/external \ No newline at end of file +3D_Printer/log \ No newline at end of file From 8f128fee622401cb4ea1db66faee29c8f66c4f5b Mon Sep 17 00:00:00 2001 From: Mosserl Date: Mon, 3 Apr 2023 19:13:54 +0200 Subject: [PATCH 04/30] Here is the beginning of something ! everything compil and nothing work. I will test it tomorrow ! We are going do do great things. --- .../ros2_3d_printer_control/CMakeLists.txt | 45 ++ .../ros2_3d_printer_control/nodes/__init__.py | 0 .../nodes/printer_control_node.py | 19 + .../src/ros2_3d_printer_control/package.xml | 18 + .../CMakeLists.txt | 45 ++ .../nodes/__init__.py | 0 .../nodes/gcode_monitor_node.py | 19 + .../ros2_3d_printer_gcode_monitor/package.xml | 18 + .../CMakeLists.txt | 45 ++ .../nodes/__init__.py | 0 .../nodes/image_capture_node.py | 34 ++ .../ros2_3d_printer_image_capture/package.xml | 18 + .../ros2_3d_printer_messages/CMakeLists.txt | 47 ++ .../src/ros2_3d_printer_messages/package.xml | 19 + .../srv/GcodeCommand.srv | 3 + .../srv/ImageCommand.srv | 3 + .../srv/ProfileCommand.srv | 6 + .../CMakeLists.txt | 120 +++++ .../package.xml | 22 + .../src/driver/CMakeLists.txt | 65 +++ .../src/driver/gocatorSensor.cpp | 424 ++++++++++++++++++ .../src/driver/gocatorSensor.h | 187 ++++++++ .../src/nodes/gocatorSensorNode.cpp | 64 +++ .../src/ros2_gocator_msgs/CMakeLists.txt | 28 ++ 3D_printer/src/ros2_gocator_msgs/README.md | 0 3D_printer/src/ros2_gocator_msgs/package.xml | 19 + .../ros2_gocator_msgs/srv/GocatorPTCloud.srv | 5 + 27 files changed, 1273 insertions(+) create mode 100644 3D_printer/src/ros2_3d_printer_control/CMakeLists.txt create mode 100644 3D_printer/src/ros2_3d_printer_control/nodes/__init__.py create mode 100644 3D_printer/src/ros2_3d_printer_control/nodes/printer_control_node.py create mode 100644 3D_printer/src/ros2_3d_printer_control/package.xml create mode 100644 3D_printer/src/ros2_3d_printer_gcode_monitor/CMakeLists.txt create mode 100644 3D_printer/src/ros2_3d_printer_gcode_monitor/nodes/__init__.py create mode 100644 3D_printer/src/ros2_3d_printer_gcode_monitor/nodes/gcode_monitor_node.py create mode 100644 3D_printer/src/ros2_3d_printer_gcode_monitor/package.xml create mode 100644 3D_printer/src/ros2_3d_printer_image_capture/CMakeLists.txt create mode 100644 3D_printer/src/ros2_3d_printer_image_capture/nodes/__init__.py create mode 100644 3D_printer/src/ros2_3d_printer_image_capture/nodes/image_capture_node.py create mode 100644 3D_printer/src/ros2_3d_printer_image_capture/package.xml create mode 100644 3D_printer/src/ros2_3d_printer_messages/CMakeLists.txt create mode 100644 3D_printer/src/ros2_3d_printer_messages/package.xml create mode 100644 3D_printer/src/ros2_3d_printer_messages/srv/GcodeCommand.srv create mode 100644 3D_printer/src/ros2_3d_printer_messages/srv/ImageCommand.srv create mode 100644 3D_printer/src/ros2_3d_printer_messages/srv/ProfileCommand.srv create mode 100644 3D_printer/src/ros2_3d_printer_profile_capture/CMakeLists.txt create mode 100644 3D_printer/src/ros2_3d_printer_profile_capture/package.xml create mode 100644 3D_printer/src/ros2_3d_printer_profile_capture/src/driver/CMakeLists.txt create mode 100644 3D_printer/src/ros2_3d_printer_profile_capture/src/driver/gocatorSensor.cpp create mode 100644 3D_printer/src/ros2_3d_printer_profile_capture/src/driver/gocatorSensor.h create mode 100644 3D_printer/src/ros2_3d_printer_profile_capture/src/nodes/gocatorSensorNode.cpp create mode 100644 3D_printer/src/ros2_gocator_msgs/CMakeLists.txt create mode 100644 3D_printer/src/ros2_gocator_msgs/README.md create mode 100644 3D_printer/src/ros2_gocator_msgs/package.xml create mode 100644 3D_printer/src/ros2_gocator_msgs/srv/GocatorPTCloud.srv diff --git a/3D_printer/src/ros2_3d_printer_control/CMakeLists.txt b/3D_printer/src/ros2_3d_printer_control/CMakeLists.txt new file mode 100644 index 0000000..00bf963 --- /dev/null +++ b/3D_printer/src/ros2_3d_printer_control/CMakeLists.txt @@ -0,0 +1,45 @@ +cmake_minimum_required(VERSION 3.5) +project(ros2_3d_printer_control) + +# Default to C99 +if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 99) +endif() + +# Default to C++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# find dependencies +find_package(ament_cmake REQUIRED) +find_package(rclcpp REQUIRED) +find_package(std_msgs REQUIRED) + +# Install the python module for this package +ament_python_install_package(nodes/) + +if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + # the following line skips the linter which checks for copyrights + # uncomment the line when a copyright and license is not present in all source files + #set(ament_cmake_copyright_FOUND TRUE) + # the following line skips cpplint (only works in a git repo) + # uncomment the line when this package is not in a git repo + #set(ament_cmake_cpplint_FOUND TRUE) + ament_lint_auto_find_test_dependencies() +endif() + +# Install python scripts + +install( + PROGRAMS + nodes/printer_control_node.py + DESTINATION lib/${PROJECT_NAME} +) + +ament_package() diff --git a/3D_printer/src/ros2_3d_printer_control/nodes/__init__.py b/3D_printer/src/ros2_3d_printer_control/nodes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/src/ros2_3d_printer_control/nodes/printer_control_node.py b/3D_printer/src/ros2_3d_printer_control/nodes/printer_control_node.py new file mode 100644 index 0000000..d71bf1a --- /dev/null +++ b/3D_printer/src/ros2_3d_printer_control/nodes/printer_control_node.py @@ -0,0 +1,19 @@ +import rclpy +from rclpy.action import ActionClient +from rclpy.node import Node + +from 3D_printer_messages.srv import profileCommand +from 3D_printer_messages.srv import gcodeCommand +from 3D_printer_messages.srv import imageCommand + + +class PrinterControlNode(Node): + def __init__(self): + super().__init__('3D_printer_control') + + +if __name__ == '__main__': + rclpy.init() + image_capture_node = PrinterControlNode(0) + rclpy.spin(image_capture_node) + rclpy.shutdown() \ No newline at end of file diff --git a/3D_printer/src/ros2_3d_printer_control/package.xml b/3D_printer/src/ros2_3d_printer_control/package.xml new file mode 100644 index 0000000..ca8e873 --- /dev/null +++ b/3D_printer/src/ros2_3d_printer_control/package.xml @@ -0,0 +1,18 @@ + + + + ros2_3d_printer_control + 0.0.0 + TODO: Package description + gulltor + TODO: License declaration + + ament_cmake + + ament_lint_auto + ament_lint_common + + + ament_cmake + + diff --git a/3D_printer/src/ros2_3d_printer_gcode_monitor/CMakeLists.txt b/3D_printer/src/ros2_3d_printer_gcode_monitor/CMakeLists.txt new file mode 100644 index 0000000..85efde5 --- /dev/null +++ b/3D_printer/src/ros2_3d_printer_gcode_monitor/CMakeLists.txt @@ -0,0 +1,45 @@ +cmake_minimum_required(VERSION 3.5) +project(ros2_3d_printer_gcode_monitor) + +# Default to C99 +if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 99) +endif() + +# Default to C++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# find dependencies +find_package(ament_cmake REQUIRED) +find_package(rclcpp REQUIRED) +find_package(std_msgs REQUIRED) + +# Install the python module for this package +ament_python_install_package(nodes/) + +if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + # the following line skips the linter which checks for copyrights + # uncomment the line when a copyright and license is not present in all source files + #set(ament_cmake_copyright_FOUND TRUE) + # the following line skips cpplint (only works in a git repo) + # uncomment the line when this package is not in a git repo + #set(ament_cmake_cpplint_FOUND TRUE) + ament_lint_auto_find_test_dependencies() +endif() + +# Install python scripts + +install( + PROGRAMS + nodes/gcode_monitor_node.py + DESTINATION lib/${PROJECT_NAME} +) + +ament_package() diff --git a/3D_printer/src/ros2_3d_printer_gcode_monitor/nodes/__init__.py b/3D_printer/src/ros2_3d_printer_gcode_monitor/nodes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/src/ros2_3d_printer_gcode_monitor/nodes/gcode_monitor_node.py b/3D_printer/src/ros2_3d_printer_gcode_monitor/nodes/gcode_monitor_node.py new file mode 100644 index 0000000..45c38ff --- /dev/null +++ b/3D_printer/src/ros2_3d_printer_gcode_monitor/nodes/gcode_monitor_node.py @@ -0,0 +1,19 @@ +import rclpy +from rclpy.action import ActionClient +from rclpy.node import Node + +from 3D_printer_messages.srv import profileCommand +from 3D_printer_messages.srv import gcodeCommand +from 3D_printer_messages.srv import imageCommand + + +class ProfileCaptureNode(Node): + def __init__(self): + super().__init__('3D_printer_profile_capture') + + +if __name__ == '__main__': + rclpy.init() + image_capture_node = ProfileCaptureNode(0) + rclpy.spin(image_capture_node) + rclpy.shutdown() \ No newline at end of file diff --git a/3D_printer/src/ros2_3d_printer_gcode_monitor/package.xml b/3D_printer/src/ros2_3d_printer_gcode_monitor/package.xml new file mode 100644 index 0000000..859903b --- /dev/null +++ b/3D_printer/src/ros2_3d_printer_gcode_monitor/package.xml @@ -0,0 +1,18 @@ + + + + ros2_3d_printer_gcode_monitor + 0.0.0 + TODO: Package description + gulltor + TODO: License declaration + + ament_cmake + + ament_lint_auto + ament_lint_common + + + ament_cmake + + diff --git a/3D_printer/src/ros2_3d_printer_image_capture/CMakeLists.txt b/3D_printer/src/ros2_3d_printer_image_capture/CMakeLists.txt new file mode 100644 index 0000000..0df93f2 --- /dev/null +++ b/3D_printer/src/ros2_3d_printer_image_capture/CMakeLists.txt @@ -0,0 +1,45 @@ +cmake_minimum_required(VERSION 3.5) +project(ros2_3d_printer_image_capture) + +# Default to C99 +if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 99) +endif() + +# Default to C++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# find dependencies +find_package(ament_cmake REQUIRED) +find_package(rclcpp REQUIRED) +find_package(std_msgs REQUIRED) + +# Install the python module for this package +ament_python_install_package(nodes/) + +if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + # the following line skips the linter which checks for copyrights + # uncomment the line when a copyright and license is not present in all source files + #set(ament_cmake_copyright_FOUND TRUE) + # the following line skips cpplint (only works in a git repo) + # uncomment the line when this package is not in a git repo + #set(ament_cmake_cpplint_FOUND TRUE) + ament_lint_auto_find_test_dependencies() +endif() + +# Install python scripts + +install( + PROGRAMS + nodes/image_capture_node.py + DESTINATION lib/${PROJECT_NAME} +) + +ament_package() diff --git a/3D_printer/src/ros2_3d_printer_image_capture/nodes/__init__.py b/3D_printer/src/ros2_3d_printer_image_capture/nodes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/src/ros2_3d_printer_image_capture/nodes/image_capture_node.py b/3D_printer/src/ros2_3d_printer_image_capture/nodes/image_capture_node.py new file mode 100644 index 0000000..8f83e1c --- /dev/null +++ b/3D_printer/src/ros2_3d_printer_image_capture/nodes/image_capture_node.py @@ -0,0 +1,34 @@ +import rclpy +from rclpy.action import ActionClient +from rclpy.node import Node + +from 3D_printer_messages.srv import profileCommand +from 3D_printer_messages.srv import gcodeCommand +from 3D_printer_messages.srv import imageCommand +import cv2 + + + +class ImageCaptureNode(Node): + def __init__(self,cameraNumber = 0): + super().__init__('3D_printer_image_capture') + self.webcam = cv2.VideoCapture("/dev/video"+str(cameraNumber)) # Be carefull with the number after video + self.imageService = self.create_service(imageCommand, 'ask_capture_image', self.takePicture) + + + def __del__(self): + webcam.release() + + def takePicture(self,request, response): + check, frame = webcam.read() + cv2.imwrite(filename='/home/gulltor/Ramsai_Robotics/images/'+request.filename+'.jpg', img=frame) + + response.confirmation = True + return response + + +if __name__ == '__main__': + rclpy.init() + image_capture_node = ImageCaptureNode(0) + rclpy.spin(image_capture_node) + rclpy.shutdown() \ No newline at end of file diff --git a/3D_printer/src/ros2_3d_printer_image_capture/package.xml b/3D_printer/src/ros2_3d_printer_image_capture/package.xml new file mode 100644 index 0000000..30f2022 --- /dev/null +++ b/3D_printer/src/ros2_3d_printer_image_capture/package.xml @@ -0,0 +1,18 @@ + + + + ros2_3d_printer_image_capture + 0.0.0 + TODO: Package description + gulltor + TODO: License declaration + + ament_cmake + + ament_lint_auto + ament_lint_common + + + ament_cmake + + diff --git a/3D_printer/src/ros2_3d_printer_messages/CMakeLists.txt b/3D_printer/src/ros2_3d_printer_messages/CMakeLists.txt new file mode 100644 index 0000000..60c14f5 --- /dev/null +++ b/3D_printer/src/ros2_3d_printer_messages/CMakeLists.txt @@ -0,0 +1,47 @@ +cmake_minimum_required(VERSION 3.5) +project(ros2_3d_printer_messages) + +# Default to C99 +if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 99) +endif() + +# Default to C++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# find dependencies +find_package(ament_cmake REQUIRED) +# uncomment the following section in order to fill in +# further dependencies manually. +# find_package( REQUIRED) +find_package(ament_cmake REQUIRED) +find_package(builtin_interfaces REQUIRED) +find_package(rosidl_default_generators REQUIRED) +find_package(std_msgs REQUIRED) +find_package(sensor_msgs REQUIRED) + + +if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + # the following line skips the linter which checks for copyrights + # uncomment the line when a copyright and license is not present in all source files + #set(ament_cmake_copyright_FOUND TRUE) + # the following line skips cpplint (only works in a git repo) + # uncomment the line when this package is not in a git repo + #set(ament_cmake_cpplint_FOUND TRUE) + ament_lint_auto_find_test_dependencies() +endif() + +rosidl_generate_interfaces(${PROJECT_NAME} + "srv/ProfileCommand.srv" + "srv/GcodeCommand.srv" + "srv/ImageCommand.srv" + ) + +ament_package() diff --git a/3D_printer/src/ros2_3d_printer_messages/package.xml b/3D_printer/src/ros2_3d_printer_messages/package.xml new file mode 100644 index 0000000..31d7fdb --- /dev/null +++ b/3D_printer/src/ros2_3d_printer_messages/package.xml @@ -0,0 +1,19 @@ + + +ros2_3d_printer_messages +0.0.0 +Messages form communication with GOCATOR systems +m.bednarczyk +TODO: License declaration +ament_cmake +ament_lint_auto +ament_lint_common +std_msgs +sensor_msgs +builtin_interfaces +rosidl_default_generators +rosidl_interface_packages + +ament_cmake + + \ No newline at end of file diff --git a/3D_printer/src/ros2_3d_printer_messages/srv/GcodeCommand.srv b/3D_printer/src/ros2_3d_printer_messages/srv/GcodeCommand.srv new file mode 100644 index 0000000..72b6cf5 --- /dev/null +++ b/3D_printer/src/ros2_3d_printer_messages/srv/GcodeCommand.srv @@ -0,0 +1,3 @@ +string[] gcode_strings +--- +bool validation \ No newline at end of file diff --git a/3D_printer/src/ros2_3d_printer_messages/srv/ImageCommand.srv b/3D_printer/src/ros2_3d_printer_messages/srv/ImageCommand.srv new file mode 100644 index 0000000..65ce60f --- /dev/null +++ b/3D_printer/src/ros2_3d_printer_messages/srv/ImageCommand.srv @@ -0,0 +1,3 @@ +string filename +--- +bool confirmation \ No newline at end of file diff --git a/3D_printer/src/ros2_3d_printer_messages/srv/ProfileCommand.srv b/3D_printer/src/ros2_3d_printer_messages/srv/ProfileCommand.srv new file mode 100644 index 0000000..dd07f00 --- /dev/null +++ b/3D_printer/src/ros2_3d_printer_messages/srv/ProfileCommand.srv @@ -0,0 +1,6 @@ +float64 y_min +float64 y_max +float64 z_upper +float64 step +--- +bool validation \ No newline at end of file diff --git a/3D_printer/src/ros2_3d_printer_profile_capture/CMakeLists.txt b/3D_printer/src/ros2_3d_printer_profile_capture/CMakeLists.txt new file mode 100644 index 0000000..61fdde7 --- /dev/null +++ b/3D_printer/src/ros2_3d_printer_profile_capture/CMakeLists.txt @@ -0,0 +1,120 @@ +cmake_minimum_required(VERSION 3.5) +project(ros2_3d_printer_profile_capture) + +# Default to C99 +if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 99) +endif() + +# Default to C++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# find dependencies +find_package(ament_cmake REQUIRED) +find_package(rclcpp REQUIRED) +# find_package(rclpy REQUIRED) +find_package(std_msgs REQUIRED) +find_package(sensor_msgs REQUIRED) +find_package(rosidl_default_generators REQUIRED) +find_package(ros2_gocator_msgs REQUIRED) +find_package(pcl_conversions REQUIRED) + +# Find point cloud Library +FIND_PACKAGE(PCL REQUIRED COMPONENTS) +INCLUDE_DIRECTORIES(${PCL_INCLUDE_DIRS}) +LINK_DIRECTORIES(${PCL_LIBRARY_DIRS}) +ADD_DEFINITIONS(${PCL_DEFINITIONS}) + +# Set GO_SDK include paths (That could be part of a FindGocator.cmake) +SET(GO_SDK_4 ${CMAKE_CURRENT_SOURCE_DIR}/external/GO_SDK) +FIND_PATH( + GOCATOR_INCLUDES + NAMES GoSdk/GoSdk.h + PATHS ${GO_SDK_4}/Gocator/GoSdk) +FIND_PATH( + KAPI_INCLUDES + NAMES kApi/kApi.h + PATHS ${GO_SDK_4}/Platform/kApi) +INCLUDE_DIRECTORIES(${GOCATOR_INCLUDES} ${KAPI_INCLUDES}) + +# Set GO_SDK libs (That could be part of a FindGocator.cmake) +FIND_LIBRARY( + GOCATOR_LIBRARIES + NAMES GoSdk + PATHS ${GO_SDK_4}/lib/linux_x64d) +FIND_LIBRARY( + KAPI_LIBRARIES + NAMES kApi + PATHS ${GO_SDK_4}/lib/linux_x64d) + +# Set source files +SET(LIB_SRCS + src/driver/gocatorSensor.cpp) + +# Set header files +SET(LIB_HDRS + src/driver/gocatorSensor.h) + +INCLUDE_DIRECTORIES(${LIB_HDRS}) + +# Install the python module for this package +# ament_python_install_package(script/) +# ament_python_install_package(nodes/) + + + +################################################################################ +# Declare ROS messages, services and actions +################################################################################ + +add_executable( gocator_sensor_node src/nodes/gocatorSensorNode.cpp ${LIB_HDRS} ${LIB_SRCS} ) +target_link_libraries (gocator_sensor_node ${GOCATOR_LIBRARIES} ${KAPI_LIBRARIES} ${Boost_SYSTEM_LIBRARY}) + +ament_target_dependencies(gocator_sensor_node rclcpp sensor_msgs std_msgs ros2_gocator_msgs pcl_conversions) + + +# Install C++ headers +#install( +# DIRECTORY ${PROJECT_NAME}/include +# ${LIB_DIR}/include +# DESTINATION include/${PROJECT_NAME} +# FILES_MATCHING PATTERN "*.hpp" +#) + +install(TARGETS + gocator_sensor_node + DESTINATION lib/${PROJECT_NAME}) + +if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + # the following line skips the linter which checks for copyrights + # uncomment the line when a copyright and license is not present in all source files + #set(ament_cmake_copyright_FOUND TRUE) + # the following line skips cpplint (only works in a git repo) + # uncomment the line when this package is not in a git repo + #set(ament_cmake_cpplint_FOUND TRUE) + ament_lint_auto_find_test_dependencies() +endif() + + +# Install python scripts +# install( +# DIRECTORY external/GO_SDK/lib/linux_x64d/ #launch param script +# DESTINATION share/${PROJECT_NAME}/external/GO_SDK/lib/linux_x64d/ +# ) + +# install( +# PROGRAMS +# script/tcpSocket.py +# script/udpSocket.py +# nodes/iiwa_command_node.py +# DESTINATION lib/${PROJECT_NAME} +# ) + +ament_package() diff --git a/3D_printer/src/ros2_3d_printer_profile_capture/package.xml b/3D_printer/src/ros2_3d_printer_profile_capture/package.xml new file mode 100644 index 0000000..0156baf --- /dev/null +++ b/3D_printer/src/ros2_3d_printer_profile_capture/package.xml @@ -0,0 +1,22 @@ + + +ros2_3d_printer_profile_capture +0.0.0 +Messages form communication with GOCATOR systems +m.bednarczyk +TODO: License declaration +ament_cmake +ament_lint_auto +ament_lint_common +std_msgs +sensor_msgs +gocator_msgs + +builtin_interfaces +pcl_conversions +rosidl_default_generators +rosidl_interface_packages + +ament_cmake + + \ No newline at end of file diff --git a/3D_printer/src/ros2_3d_printer_profile_capture/src/driver/CMakeLists.txt b/3D_printer/src/ros2_3d_printer_profile_capture/src/driver/CMakeLists.txt new file mode 100644 index 0000000..c32dfc2 --- /dev/null +++ b/3D_printer/src/ros2_3d_printer_profile_capture/src/driver/CMakeLists.txt @@ -0,0 +1,65 @@ +# Pre-requisites about cmake itself +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) + +# Project name and the type of project +PROJECT(gocatorSensor) + +# DEBUG/RELEASE +IF (NOT CMAKE_BUILD_TYPE) + SET(CMAKE_BUILD_TYPE "RELEASE") +ENDIF (NOT CMAKE_BUILD_TYPE) + +# Default to C99 +if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 99) +endif() + +# Default to C++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# Find point cloud Library +FIND_PACKAGE(PCL REQUIRED COMPONENTS) +INCLUDE_DIRECTORIES(${PCL_INCLUDE_DIRS}) +LINK_DIRECTORIES(${PCL_LIBRARY_DIRS}) +ADD_DEFINITIONS(${PCL_DEFINITIONS}) + +# Set GO_SDK include paths (That could be part of a FindGocator.cmake) +SET(GO_SDK_4 ${CMAKE_CURRENT_SOURCE_DIR}/../../external/GO_SDK) +FIND_PATH( + GOCATOR_INCLUDES + NAMES GoSdk/GoSdk.h + PATHS ${GO_SDK_4}/Gocator/GoSdk) +FIND_PATH( + KAPI_INCLUDES + NAMES kApi/kApi.h + PATHS ${GO_SDK_4}/Platform/kApi) +INCLUDE_DIRECTORIES(${GOCATOR_INCLUDES} ${KAPI_INCLUDES}) + +# Set GO_SDK libs (That could be part of a FindGocator.cmake) +FIND_LIBRARY( + GOCATOR_LIBRARIES + NAMES GoSdk + PATHS ${GO_SDK_4}/lib/linux_x64d/) +FIND_LIBRARY( + KAPI_LIBRARIES + NAMES kApi + PATHS ${GO_SDK_4}/lib/linux_x64d/) + +# Set source files +SET(SRCS + gocatorSensor.cpp) + +# Set header files +SET(HDRS + gocatorSensor.h) + +#Build library +ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${GOCATOR_LIBRARIES} ${KAPI_LIBRARIES} ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES}) + diff --git a/3D_printer/src/ros2_3d_printer_profile_capture/src/driver/gocatorSensor.cpp b/3D_printer/src/ros2_3d_printer_profile_capture/src/driver/gocatorSensor.cpp new file mode 100644 index 0000000..f633b1c --- /dev/null +++ b/3D_printer/src/ros2_3d_printer_profile_capture/src/driver/gocatorSensor.cpp @@ -0,0 +1,424 @@ +#include "gocatorSensor.h" + +GocatorSensor::Device::Device(const std::string & _ip_address) +{ + kStatus status; + kIpAddress ipAddress; + kChar model_name[50]; + + //init all GO API objects + go_api_ = kNULL; + go_system_ = kNULL; + go_sensor_ = kNULL; + go_setup_ = kNULL; + go_dataset_ = kNULL; + go_stamp_ptr_ = kNULL; + + // construct Gocator API Library + if ((status = GoSdk_Construct(&go_api_)) != kOK) + { + std::cout << "Device(). Error: GoSdk_Construct: " << status << std::endl; + status_ = DEVICE_NOT_FOUND; + return; + } + + // construct GoSystem object + if ((status = GoSystem_Construct(&go_system_, kNULL)) != kOK) + { + std::cout << "Device(). Error: GoSystem_Construct: " << status << std::endl; + status_ = DEVICE_NOT_FOUND; + return; + } + + // obtain GoSensor object by sensor IP address + kIpAddress_Parse(&ipAddress, _ip_address.c_str()); + if ((status = GoSystem_FindSensorByIpAddress(go_system_, &ipAddress, &go_sensor_)) != kOK) + { + std::cout << "Device(). Error: GoSystem_FindSensorByIpAddress: " << status << std::endl; + status_ = DEVICE_NOT_FOUND; + return; + } + + //Success case. Set status and device fixed params (ip, model name and serial number ). + status_ = DEVICE_FOUND; + device_params_.ip_address_ = _ip_address; + + // create connection to GoSensor object + if ((status = GoSensor_Connect(go_sensor_)) != kOK) + { + std::cout << "Device(). Error: GoSensor_Connect: " << status << std::endl; + status_ = DEVICE_NOT_CONNECT; + return; + } + status_ = DEVICE_CONNECT; + + // enable sensor data channel + if ((status = GoSystem_EnableData(go_system_, kTRUE)) != kOK) + { + std::cout << "Device(). Error: GoSensor_EnableData: " << status << std::endl; + return; + } + + // retrieve setup handle + if ((go_setup_ = GoSensor_Setup(go_sensor_)) == kNULL) + { + std::cout << "Device(). Error: GoSensor_Setup: Invalid Handle" << std::endl; + return; + } + + //Obtain camera model + if ((status = GoSensor_Model(go_sensor_, model_name, 50)) != kOK ) + { + std::cout << "Device(). Error: GoSensor_Model: " << status << std::endl; + return; + } + device_params_.model_name_ = model_name; + + //Obtain camera Serial number + device_params_.sn_ = (unsigned int)GoSensor_Id(go_sensor_); + + //Obtain exposure + capture_params_.exposure_time_ = GoSetup_Exposure(go_setup_, GO_ROLE_MAIN); + + //Obtain spacing interval + capture_params_.spacing_interval_ = GoSetup_SpacingInterval(go_setup_, GO_ROLE_MAIN); + + //print info + std::cout << "Found Sensor: " << std::endl; + device_params_.print(); +} + +GocatorSensor::Device::~Device() +{ + kStatus status; + + // destroy handles + GoDestroy(go_system_); + GoDestroy(go_api_); + + //bye bye message + std::cout << "~Device(). Gocator Sensor Stopped and Device Object Destroyed." << std::endl; +} + +int GocatorSensor::Device::configure(const CaptureParams & _configs) +{ + kStatus status; + + //set exposure + if ((status = GoSetup_SetExposure(go_setup_, GO_ROLE_MAIN, _configs.exposure_time_)) != kOK ) + { + std::cout << "configure(): Error setting Exposure Time to " << _configs.exposure_time_ << std::endl; + return -1; + } + + //set spacing interval + if ((status = GoSetup_SetSpacingInterval(go_setup_, GO_ROLE_MAIN, _configs.spacing_interval_)) != kOK ) + { + std::cout << "configure(): Error setting Spacing Interval to " << _configs.spacing_interval_ << std::endl; + return -1; + } + + //set this->capture_params_ with true values from camera + capture_params_.exposure_time_ = GoSetup_Exposure(go_setup_, GO_ROLE_MAIN); + capture_params_.spacing_interval_ = GoSetup_SpacingInterval(go_setup_, GO_ROLE_MAIN); + + //print + std::cout << "Configuration Setings: " << std::endl; + capture_params_.print(); + + //return + return 1; +} + +int GocatorSensor::Device::start() +{ + kStatus status; + + // start Gocator sensor + if ((status = GoSystem_Start(go_system_)) != kOK) + { + std::cout << "Device(). Error: GoSystem_Start: " << status << std::endl; + return -1; + } + + //message to std out + //std::cout << "Gocator running ... " << std::endl; + + //set this->status_ + this->status_ = DEVICE_RUNNING; + + //return success + return 1; +} + +int GocatorSensor::Device::stop() +{ + kStatus status; + + // stop Gocator sensor + if ((status = GoSystem_Stop(go_system_)) != kOK) + { + std::cout << "~Device(). Error: GoSystem_Stop: " << status << std::endl; + return -1; + } + + //message to std out + //std::cout << "... Gocator stopped" << std::endl << std::endl; + + //set this->status_ + this->status_ = DEVICE_CONNECT; + + //return success + return 1; +} + +int GocatorSensor::Device::getCurrentSnapshot(pcl::PointCloud & _p_cloud) +{ + +} + +int GocatorSensor::Device::getSingleSnapshot(pcl::PointCloud & _p_cloud) +{ + +} + +int GocatorSensor::Device::getProfile(pcl::PointCloud & _p_cloud) +{ + unsigned int i, j, k, arrayIndex; + GoDataSet dataset = kNULL; + std::vector profileBuffer; + GoStamp *stamp =kNULL; + GoDataMsg dataObj; + k32u profilePointCount; + if (GoSystem_ReceiveData(go_system_, &dataset, RECEIVE_TIMEOUT) == kOK) + { + printf("Data message received:\n"); + printf("Dataset count: %u\n", (k32u)GoDataSet_Count(dataset)); + // each result can have multiple data items + // loop through all items in result message + for (i = 0; i < GoDataSet_Count(dataset); ++i) + { + dataObj = GoDataSet_At(dataset, i); + //Retrieve GoStamp message + switch(GoDataMsg_Type(dataObj)) + { + case GO_DATA_MESSAGE_TYPE_STAMP: + { + GoStampMsg stampMsg = dataObj; + + printf("Stamp Message batch count: %u\n", (k32u)GoStampMsg_Count(stampMsg)); + for (j = 0; j < GoStampMsg_Count(stampMsg); ++j) + { + stamp = GoStampMsg_At(stampMsg, j); + printf(" Timestamp: %llu\n", stamp->timestamp); + printf(" Encoder: %lld\n", stamp->encoder); + printf(" Frame index: %llu\n", stamp->frameIndex); + } + } + break; + case GO_DATA_MESSAGE_TYPE_UNIFORM_PROFILE: + { + GoResampledProfileMsg profileMsg = dataObj; + + printf("Resampled Profile Message batch count: %u\n", (k32u)GoResampledProfileMsg_Count(profileMsg)); + + _p_cloud.height = GoResampledProfileMsg_Count(profileMsg); + _p_cloud.width = GoResampledProfileMsg_Width(profileMsg); + _p_cloud.resize(_p_cloud.height*_p_cloud.width); + + for (k = 0; k < GoResampledProfileMsg_Count(profileMsg); ++k) + { + unsigned int validPointCount = 0; + short* data = GoResampledProfileMsg_At(profileMsg, k); + double XResolution = NM_TO_MM(GoResampledProfileMsg_XResolution(profileMsg)); + double ZResolution = NM_TO_MM(GoResampledProfileMsg_ZResolution(profileMsg)); + double XOffset = UM_TO_MM(GoResampledProfileMsg_XOffset(profileMsg)); + double ZOffset = UM_TO_MM(GoResampledProfileMsg_ZOffset(profileMsg)); + + // profileBuffer.resize(GoResampledProfileMsg_Width(profileMsg)); + + + // translate 16-bit range data to engineering units and copy profiles to memory array + for (arrayIndex = 0; arrayIndex < GoResampledProfileMsg_Width(profileMsg); ++arrayIndex) + { + + if (data[arrayIndex] != INVALID_RANGE_16BIT ) + { + // profileBuffer[arrayIndex].x = XOffset + XResolution * arrayIndex; + // profileBuffer[arrayIndex].z = ZOffset + ZResolution * data[arrayIndex]; + _p_cloud.points.at(k*_p_cloud.width+arrayIndex).x = XOffset + XResolution * arrayIndex; + _p_cloud.points.at(k*_p_cloud.width+arrayIndex).z = ZOffset + ZResolution * data[arrayIndex]; + validPointCount++; + } + else + { + // profileBuffer[arrayIndex].x = XOffset + XResolution * arrayIndex; + // profileBuffer[arrayIndex].z = INVALID_RANGE_DOUBLE; + _p_cloud.points.at(k*_p_cloud.width+arrayIndex).x = XOffset + XResolution * arrayIndex; + _p_cloud.points.at(k*_p_cloud.width+arrayIndex).z = INVALID_RANGE_DOUBLE; + } + + + } + + printf(" Profile Valid Point %d out of max %d\n", validPointCount, profilePointCount); + } + } + break; + case GO_DATA_MESSAGE_TYPE_PROFILE_POINT_CLOUD: // Note this is NON resampled profile + { + GoProfileMsg profileMsg = dataObj; + + printf("Profile Message batch count: %u\n", (k32u)GoProfileMsg_Count(profileMsg)); + + _p_cloud.height = GoProfileMsg_Count(profileMsg); + _p_cloud.width = GoProfileMsg_Width(profileMsg); + _p_cloud.resize(_p_cloud.height*_p_cloud.width); + + for (k = 0; k < GoProfileMsg_Count(profileMsg); ++k) + { + kPoint16s* data = GoProfileMsg_At(profileMsg, k); + unsigned int validPointCount = 0; + double XResolution = NM_TO_MM(GoProfileMsg_XResolution(profileMsg)); + double ZResolution = NM_TO_MM(GoProfileMsg_ZResolution(profileMsg)); + double XOffset = UM_TO_MM(GoProfileMsg_XOffset(profileMsg)); + double ZOffset = UM_TO_MM(GoProfileMsg_ZOffset(profileMsg)); + + // profileBuffer.resize(GoResampledProfileMsg_Width(profileMsg)); + + //translate 16-bit range data to engineering units and copy profiles to memory array + for (arrayIndex = 0; arrayIndex < GoProfileMsg_Width(profileMsg); ++arrayIndex) + { + if (data[arrayIndex].x != INVALID_RANGE_16BIT) + { + // profileBuffer[arrayIndex].x = XOffset + XResolution * data[arrayIndex].x; + // profileBuffer[arrayIndex].z = ZOffset + ZResolution * data[arrayIndex].y; + _p_cloud.points.at(k*_p_cloud.width+arrayIndex).x = XOffset + XResolution * data[arrayIndex].x; + _p_cloud.points.at(k*_p_cloud.width+arrayIndex).z = ZOffset + ZResolution * data[arrayIndex].y; + validPointCount++; + } + else + { + // profileBuffer[arrayIndex].x = INVALID_RANGE_DOUBLE; + // profileBuffer[arrayIndex].z = INVALID_RANGE_DOUBLE; + _p_cloud.points.at(k*_p_cloud.width+arrayIndex).x = INVALID_RANGE_DOUBLE; + _p_cloud.points.at(k*_p_cloud.width+arrayIndex).z = INVALID_RANGE_DOUBLE; + } + } + printf(" Profile Valid Point %d out of max %d\n", validPointCount, profilePointCount); + } + } + break; + case GO_DATA_MESSAGE_TYPE_PROFILE_INTENSITY: + { + unsigned int validPointCount = 0; + GoProfileIntensityMsg intensityMsg = dataObj; + printf("Intensity Message batch count: %u\n", (k32u)GoProfileIntensityMsg_Count(intensityMsg)); + + profileBuffer.resize(GoProfileIntensityMsg_Count(intensityMsg)); + + for (k = 0; k < GoProfileIntensityMsg_Count(intensityMsg); ++k) + { + unsigned char* data = GoProfileIntensityMsg_At(intensityMsg, k); + for (arrayIndex = 0; arrayIndex < GoProfileIntensityMsg_Width(intensityMsg); ++arrayIndex) + { + profileBuffer[arrayIndex].intensity = data[arrayIndex]; + } + } + } + break; + } + } + GoDestroy(dataset); + } + else + { + printf ("Error: No data received during the waiting period\n"); + } + return 1; +} + +void GocatorSensor::Device::getDeviceHealth(std::string & _health_str) const +{ + //local variables + GoDataSet health_data = kNULL; + GoHealthMsg health_msg =kNULL; + GoIndicator *health_indicator = kNULL; + std::ostringstream sstr; + + //get health from device + if ( (GoSystem_ReceiveHealth(go_system_, &health_data, RECEIVE_TIMEOUT)) == kOK ) + { + for (unsigned int ii = 0; ii < GoDataSet_Count(health_data); ii++) + { + health_msg = GoDataSet_At(health_data, ii); + for (unsigned int jj = 0; jj < GoHealthMsg_Count(health_msg); jj++) + { + health_indicator = GoHealthMsg_At(health_msg, jj); + sstr << "Indicator[" << jj << "]:\n" + << "\tId: " << health_indicator->id << "\n" + << "\tInstance: " << health_indicator->instance << "\n" + << "\tValue: " << health_indicator->value << "\n"; + } + } + GoDestroy(health_msg); + } + + _health_str = sstr.str(); +} + +void GocatorSensor::Device::getTemperature(double & _internal_temp, double & _projector_temp, double & _laser_temp) const +{ + //local variables + GoDataSet health_data = kNULL; + GoHealthMsg health_msg =kNULL; + GoIndicator *health_indicator = kNULL; + //k32u instance; + + //get health dataset from device + if ( (GoSystem_ReceiveHealth(go_system_, &health_data, RECEIVE_TIMEOUT)) == kOK ) + { + for (unsigned int ii = 0; ii < GoDataSet_Count(health_data); ii++) + { + //get the health message + health_msg = GoDataSet_At(health_data, ii); + + //find in the message the internal temperature indicator, and set the value + health_indicator = GoHealthMsg_Find(health_msg, GO_HEALTH_TEMPERATURE, 0); + if (health_indicator != kNULL) _internal_temp = health_indicator->value; + else _internal_temp = -100.; + + //find in the message the projector temperature indicator, and set the value + health_indicator = GoHealthMsg_Find(health_msg, GO_HEALTH_PROJECTOR_TEMPERATURE, 0); + if (health_indicator != kNULL) _projector_temp = health_indicator->value; + else _projector_temp = -100.; + + //find in the message the projector temperature indicator, and set the value + health_indicator = GoHealthMsg_Find(health_msg, GO_HEALTH_LASER_TEMPERATURE, 0); + if (health_indicator != kNULL) _laser_temp = health_indicator->value; + else _laser_temp = -100.; + } + GoDestroy(health_msg); + } + +} + +int GocatorSensor::Device::close() +{ + +} + +void GocatorSensor::Device::printDeviceData() const +{ + +} + +void GocatorSensor::Device::sendTrigger() const { + printf("sending trigger \n"); + kStatus status = GoSensor_Trigger(go_sensor_); + if (status != kOK) + { + printf("Error: GoSensor_Connect:%d\n", status); + return; + } +} diff --git a/3D_printer/src/ros2_3d_printer_profile_capture/src/driver/gocatorSensor.h b/3D_printer/src/ros2_3d_printer_profile_capture/src/driver/gocatorSensor.h new file mode 100644 index 0000000..d7fda34 --- /dev/null +++ b/3D_printer/src/ros2_3d_printer_profile_capture/src/driver/gocatorSensor.h @@ -0,0 +1,187 @@ +#ifndef GocatorSensor_H +#define GocatorSensor_H + +//std c/c++ +#include +#include +#include +#include + +//GoSdk +#include + +//PCL +#include +#include + +//constants +#define SENSOR_IP "192.168.1.10" // sensor IP address +#define RECEIVE_TIMEOUT 20000000 // timeout for snapshot acquisition +#define INVALID_RANGE_16BIT ((signed short)0x8000) // gocator transmits range data as 16-bit signed integers. 0x8000 signifies invalid range data. +#define DOUBLE_MAX ((k64f)1.7976931348623157e+308) // 64-bit double - largest positive value. +#define INVALID_RANGE_DOUBLE ((k64f)-DOUBLE_MAX) // floating point value to represent invalid range data. +#define NM_TO_MM(VALUE) (((k64f)(VALUE))/1000000.0) +#define UM_TO_MM(VALUE) (((k64f)(VALUE))/1000.0) + +namespace GocatorSensor +{ + +typedef struct ProfilePoint +{ + double x; // x-coordinate in engineering units (mm) - position along laser line + double z; // z-coordinate in engineering units (mm) - height (at the given x position) + unsigned char intensity; +} ProfilePoint; + +//status values +enum {DEVICE_NOT_FOUND=0,DEVICE_FOUND,DEVICE_NOT_CONNECT,DEVICE_CONNECT,DEVICE_RUNNING}; + +//device parameters struct +struct DeviceParams +{ + std::string ip_address_; + std::string model_name_; + unsigned int sn_; + + void print() const + { + std::cout << "\tIP ad: \t" << ip_address_ << std::endl; + std::cout << "\tModel: \t" << model_name_ << std::endl; + std::cout << "\tSN: \t" << sn_ << std::endl; + } +}; + +//device configuration struct +struct CaptureParams +{ + double exposure_time_; //in useconds + double spacing_interval_; //in millimeters + + void print() const + { + std::cout << "\texposure [us]: \t" << exposure_time_ << std::endl; + std::cout << "\tspacing [mm]: \t" << spacing_interval_ << std::endl; + } +}; + +//Device class +class Device +{ +protected: + //current point cloud. Maybe not necessary to be here! + //pcl::PointCloud::Ptr p_cloud_; //p_cloud_ = new pcl::PointCloud + + //driver status + unsigned int status_; + + //device fixed params + DeviceParams device_params_; + + //device configuration + CaptureParams capture_params_; + + //GO API objects + kAssembly go_api_; + GoSystem go_system_; + GoSensor go_sensor_; + GoSetup go_setup_; + GoDataSet go_dataset_; + GoStamp *go_stamp_ptr_; + +public: + /** \brief Constructor + * + * Constructor. Sets params_ struct. + * + **/ + Device(const std::string & _ip_address); + + /** \brief Destructor + * + * Destructor + * + **/ + ~Device(); + + /** \brief Connect to a pysical device given an ip address + * + * Connect to a pysical device given an ip address + * + **/ +// int connect(); + + /** \brief Set/get device parameters to/from the camera + * + * Set/get device parameters to/from the camera + * + **/ + int configure(const CaptureParams & _configs); + + /** \brief Start device data acquisition + * + * Start device data acquisition + * + **/ + int start(); + + /** \brief Stop device dat acquisition + * + * Stop device data acquisition + * + **/ + int stop(); + + /** \brief Get the current snapshot + * + * Get the current snapshot, when in continuous acquisition + * + **/ + int getCurrentSnapshot(pcl::PointCloud & _p_cloud); + + /** \brief Get a single snapshot in the same thread + * + * Get a single snapshot in the same thread + * + **/ + int getSingleSnapshot(pcl::PointCloud & _p_cloud); + + int getProfile(pcl::PointCloud & _p_cloud); + + + /** \brief Returns all health data as a string + * + * Returns all health data as a string + * + **/ + void getDeviceHealth(std::string & _health_str) const; + + /** \brief Returns three device temperatures + * + * Returns three device temperatures: internal, projector and laser + * + **/ + void getTemperature(double & _internal_temp, double & _projector_temp, double & _laser_temp) const; + + /** \brief Close the connection to a physical device + * + * Close the connection to a physical device + * + **/ + int close(); + + /** \brief Print the device configuration + * + * Print the device configuration + * + **/ + void printDeviceData() const; + + /** \brief Send a trigger signal + * + **/ + void sendTrigger() const; +};//close class +}//close namespace + +#endif + diff --git a/3D_printer/src/ros2_3d_printer_profile_capture/src/nodes/gocatorSensorNode.cpp b/3D_printer/src/ros2_3d_printer_profile_capture/src/nodes/gocatorSensorNode.cpp new file mode 100644 index 0000000..b861fde --- /dev/null +++ b/3D_printer/src/ros2_3d_printer_profile_capture/src/nodes/gocatorSensorNode.cpp @@ -0,0 +1,64 @@ +#include +#include +#include +#include + +#include "rclcpp/rclcpp.hpp" +#include "pcl_conversions/pcl_conversions.h" +#include "std_msgs/msg/empty.hpp" +#include "ros2_gocator_msgs/srv/gocator_pt_cloud.hpp" +#include "../driver/gocatorSensor.h" + + +using namespace std::chrono_literals; + +class GocatorSensorNode : public rclcpp::Node +{ + public: + GocatorSensorNode() + : Node("gocatorSensorNode") + { + gsensor_ = new GocatorSensor::Device(SENSOR_IP); + capture_params_.exposure_time_ = 40000; + capture_params_.spacing_interval_ = 0.1; + gsensor_->configure(capture_params_); + + service_ = this->create_service("gocator_get_profile", std::bind(&GocatorSensorNode::profile_snapshot, this, std::placeholders::_1, std::placeholders::_2)); + // publisher_ = this->create_publisher("gocatorPTCloud_topic", 10); + } + + private: + void profile_snapshot(std::shared_ptr request, + std::shared_ptr response) + { + pcl::PointCloud cloud; + RCLCPP_INFO(this->get_logger(),"Processing service request!"); + gsensor_->start(); + gsensor_->sendTrigger(); + if ( gsensor_->getProfile(cloud) == 1 ) + { + auto pcloud = sensor_msgs::msg::PointCloud2(); + pcl::toROSMsg(cloud,pcloud); + pcloud.header.frame_id = "gocator_sensor"; + pcloud.header.stamp = this->get_clock()->now(); + + // publisher_->publish(pcloud); + + response->pcloud = pcloud; + } + + } + + rclcpp::Service::SharedPtr service_; + rclcpp::Publisher::SharedPtr publisher_; + GocatorSensor::Device *gsensor_; + GocatorSensor::CaptureParams capture_params_; +}; + +int main(int argc, char * argv[]) +{ + rclcpp::init(argc, argv); + rclcpp::spin(std::make_shared()); + rclcpp::shutdown(); + return 0; +} \ No newline at end of file diff --git a/3D_printer/src/ros2_gocator_msgs/CMakeLists.txt b/3D_printer/src/ros2_gocator_msgs/CMakeLists.txt new file mode 100644 index 0000000..8c0a879 --- /dev/null +++ b/3D_printer/src/ros2_gocator_msgs/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.5) +project(ros2_gocator_msgs) + + +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + + +find_package(ament_cmake REQUIRED) +find_package(builtin_interfaces REQUIRED) +find_package(rosidl_default_generators REQUIRED) +find_package(std_msgs REQUIRED) +find_package(sensor_msgs REQUIRED) + + +rosidl_generate_interfaces(${PROJECT_NAME} + "srv/GocatorPTCloud.srv" + DEPENDENCIES builtin_interfaces std_msgs sensor_msgs +) + +ament_export_dependencies(rosidl_default_runtime) + +ament_package() diff --git a/3D_printer/src/ros2_gocator_msgs/README.md b/3D_printer/src/ros2_gocator_msgs/README.md new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/src/ros2_gocator_msgs/package.xml b/3D_printer/src/ros2_gocator_msgs/package.xml new file mode 100644 index 0000000..680a651 --- /dev/null +++ b/3D_printer/src/ros2_gocator_msgs/package.xml @@ -0,0 +1,19 @@ + + +ros2_gocator_msgs +0.0.0 +Messages form communication with GOCATOR systems +m.bednarczyk +TODO: License declaration +ament_cmake +ament_lint_auto +ament_lint_common +std_msgs +sensor_msgs +builtin_interfaces +rosidl_default_generators +rosidl_interface_packages + +ament_cmake + + diff --git a/3D_printer/src/ros2_gocator_msgs/srv/GocatorPTCloud.srv b/3D_printer/src/ros2_gocator_msgs/srv/GocatorPTCloud.srv new file mode 100644 index 0000000..9f7446e --- /dev/null +++ b/3D_printer/src/ros2_gocator_msgs/srv/GocatorPTCloud.srv @@ -0,0 +1,5 @@ +std_msgs/Empty request +--- +sensor_msgs/PointCloud2 pcloud + + From 918cd85e63995014236c86f4c83451188bed7bdf Mon Sep 17 00:00:00 2001 From: Mosserl Date: Tue, 4 Apr 2023 11:05:19 +0200 Subject: [PATCH 05/30] A new service arrive allowing the user to add a camera to the printing process. The applications of such a node are simply to get a history of the printing process. --- .../nodes/printer_control_node.py | 28 +++++++++++++++---- .../nodes/image_capture_node.py | 20 ++++++------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/3D_printer/src/ros2_3d_printer_control/nodes/printer_control_node.py b/3D_printer/src/ros2_3d_printer_control/nodes/printer_control_node.py index d71bf1a..70949ad 100644 --- a/3D_printer/src/ros2_3d_printer_control/nodes/printer_control_node.py +++ b/3D_printer/src/ros2_3d_printer_control/nodes/printer_control_node.py @@ -1,19 +1,35 @@ +#!/usr/bin/env python3 import rclpy from rclpy.action import ActionClient from rclpy.node import Node -from 3D_printer_messages.srv import profileCommand -from 3D_printer_messages.srv import gcodeCommand -from 3D_printer_messages.srv import imageCommand +from ros2_3d_printer_messages.srv import ProfileCommand +from ros2_3d_printer_messages.srv import GcodeCommand +from ros2_3d_printer_messages.srv import ImageCommand class PrinterControlNode(Node): def __init__(self): - super().__init__('3D_printer_control') + super().__init__('printer_control') + self.client_image_capture = self.create_client(ImageCommand, 'ask_capture_image') + while not self.client_image_capture.wait_for_service(timeout_sec=1.0): + self.get_logger().info('image capture service not available, waiting again...') + self.req_image_capture = ImageCommand.Request() + + def sendImageCaptureRequest(self,filename): + self.req_image_capture.filename = filename + self.future_image_capture = self.client_image_capture.call_async(self.req_image_capture) + while rclpy.ok(): + rclpy.spin_once(self) + if self.future_image_capture.done(): + self.get_logger().info('capture finished') + break + if __name__ == '__main__': rclpy.init() - image_capture_node = PrinterControlNode(0) - rclpy.spin(image_capture_node) + printer_control_node = PrinterControlNode() + for i in range(0,10): + printer_control_node.sendImageCaptureRequest('impressions/test/image_test_'+str(i)) rclpy.shutdown() \ No newline at end of file diff --git a/3D_printer/src/ros2_3d_printer_image_capture/nodes/image_capture_node.py b/3D_printer/src/ros2_3d_printer_image_capture/nodes/image_capture_node.py index 8f83e1c..aba486b 100644 --- a/3D_printer/src/ros2_3d_printer_image_capture/nodes/image_capture_node.py +++ b/3D_printer/src/ros2_3d_printer_image_capture/nodes/image_capture_node.py @@ -1,28 +1,28 @@ +#!/usr/bin/env python3 import rclpy from rclpy.action import ActionClient from rclpy.node import Node -from 3D_printer_messages.srv import profileCommand -from 3D_printer_messages.srv import gcodeCommand -from 3D_printer_messages.srv import imageCommand +from ros2_3d_printer_messages.srv import ProfileCommand +from ros2_3d_printer_messages.srv import GcodeCommand +from ros2_3d_printer_messages.srv import ImageCommand import cv2 class ImageCaptureNode(Node): def __init__(self,cameraNumber = 0): - super().__init__('3D_printer_image_capture') + super().__init__('printer_image_capture') self.webcam = cv2.VideoCapture("/dev/video"+str(cameraNumber)) # Be carefull with the number after video - self.imageService = self.create_service(imageCommand, 'ask_capture_image', self.takePicture) + self.imageService = self.create_service(ImageCommand, 'ask_capture_image', self.takePicture) - def __del__(self): - webcam.release() + self.webcam.release() def takePicture(self,request, response): - check, frame = webcam.read() - cv2.imwrite(filename='/home/gulltor/Ramsai_Robotics/images/'+request.filename+'.jpg', img=frame) - + check, frame = self.webcam.read() + cv2.imwrite(filename='/home/gulltor/Ramsai_Robotics/'+request.filename+'.jpg', img=frame) + self.get_logger().info('image acquired : /home/gulltor/Ramsai_Robotics/'+request.filename+'.jpg') response.confirmation = True return response From 69778dd6b9a6ba4219b5216ce1849a6bc909506e Mon Sep 17 00:00:00 2001 From: Mosserl Date: Tue, 4 Apr 2023 18:31:35 +0200 Subject: [PATCH 06/30] Deleting renamed files --- .../CMakeLists.txt | 2 +- .../nodes/__init__.py | 0 .../nodes/gcode_monitor_node.py | 114 +++++ .../package.xml | 2 +- .../CMakeLists.txt | 2 +- .../ros2_3d_printer_control/CMakeLists.txt | 45 -- .../nodes/printer_control_node.py | 35 -- .../nodes/__init__.py | 0 .../nodes/gcode_monitor_node.py | 19 - .../ros2_3d_printer_gcode_monitor/package.xml | 18 - .../CMakeLists.txt | 45 -- .../nodes/__init__.py | 0 .../nodes/image_capture_node.py | 34 -- .../ros2_3d_printer_image_capture/package.xml | 18 - .../ros2_3d_printer_messages/CMakeLists.txt | 47 -- .../src/ros2_3d_printer_messages/package.xml | 19 - .../srv/GcodeCommand.srv | 3 - .../srv/ImageCommand.srv | 3 - .../srv/ProfileCommand.srv | 6 - .../CMakeLists.txt | 120 ----- .../package.xml | 22 - .../src/driver/CMakeLists.txt | 65 --- .../src/driver/gocatorSensor.cpp | 424 ------------------ .../src/driver/gocatorSensor.h | 187 -------- .../src/nodes/gocatorSensorNode.cpp | 64 --- 3D_printer/src/ros2_gocator_msgs/README.md | 0 3D_printer/src/ros2_gocator_msgs/package.xml | 19 - .../ros2_gocator_msgs/srv/GocatorPTCloud.srv | 5 - 28 files changed, 117 insertions(+), 1201 deletions(-) rename 3D_printer/src/{ros2_3d_printer_gcode_monitor => printer3d_driver}/CMakeLists.txt (96%) rename 3D_printer/src/{ros2_3d_printer_control => printer3d_driver}/nodes/__init__.py (100%) create mode 100644 3D_printer/src/printer3d_driver/nodes/gcode_monitor_node.py rename 3D_printer/src/{ros2_3d_printer_control => printer3d_driver}/package.xml (93%) rename 3D_printer/src/{ros2_gocator_msgs => printer3d_gocator_msgs}/CMakeLists.txt (95%) delete mode 100644 3D_printer/src/ros2_3d_printer_control/CMakeLists.txt delete mode 100644 3D_printer/src/ros2_3d_printer_control/nodes/printer_control_node.py delete mode 100644 3D_printer/src/ros2_3d_printer_gcode_monitor/nodes/__init__.py delete mode 100644 3D_printer/src/ros2_3d_printer_gcode_monitor/nodes/gcode_monitor_node.py delete mode 100644 3D_printer/src/ros2_3d_printer_gcode_monitor/package.xml delete mode 100644 3D_printer/src/ros2_3d_printer_image_capture/CMakeLists.txt delete mode 100644 3D_printer/src/ros2_3d_printer_image_capture/nodes/__init__.py delete mode 100644 3D_printer/src/ros2_3d_printer_image_capture/nodes/image_capture_node.py delete mode 100644 3D_printer/src/ros2_3d_printer_image_capture/package.xml delete mode 100644 3D_printer/src/ros2_3d_printer_messages/CMakeLists.txt delete mode 100644 3D_printer/src/ros2_3d_printer_messages/package.xml delete mode 100644 3D_printer/src/ros2_3d_printer_messages/srv/GcodeCommand.srv delete mode 100644 3D_printer/src/ros2_3d_printer_messages/srv/ImageCommand.srv delete mode 100644 3D_printer/src/ros2_3d_printer_messages/srv/ProfileCommand.srv delete mode 100644 3D_printer/src/ros2_3d_printer_profile_capture/CMakeLists.txt delete mode 100644 3D_printer/src/ros2_3d_printer_profile_capture/package.xml delete mode 100644 3D_printer/src/ros2_3d_printer_profile_capture/src/driver/CMakeLists.txt delete mode 100644 3D_printer/src/ros2_3d_printer_profile_capture/src/driver/gocatorSensor.cpp delete mode 100644 3D_printer/src/ros2_3d_printer_profile_capture/src/driver/gocatorSensor.h delete mode 100644 3D_printer/src/ros2_3d_printer_profile_capture/src/nodes/gocatorSensorNode.cpp delete mode 100644 3D_printer/src/ros2_gocator_msgs/README.md delete mode 100644 3D_printer/src/ros2_gocator_msgs/package.xml delete mode 100644 3D_printer/src/ros2_gocator_msgs/srv/GocatorPTCloud.srv diff --git a/3D_printer/src/ros2_3d_printer_gcode_monitor/CMakeLists.txt b/3D_printer/src/printer3d_driver/CMakeLists.txt similarity index 96% rename from 3D_printer/src/ros2_3d_printer_gcode_monitor/CMakeLists.txt rename to 3D_printer/src/printer3d_driver/CMakeLists.txt index 85efde5..cdc146b 100644 --- a/3D_printer/src/ros2_3d_printer_gcode_monitor/CMakeLists.txt +++ b/3D_printer/src/printer3d_driver/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.5) -project(ros2_3d_printer_gcode_monitor) +project(printer3d_driver) # Default to C99 if(NOT CMAKE_C_STANDARD) diff --git a/3D_printer/src/ros2_3d_printer_control/nodes/__init__.py b/3D_printer/src/printer3d_driver/nodes/__init__.py similarity index 100% rename from 3D_printer/src/ros2_3d_printer_control/nodes/__init__.py rename to 3D_printer/src/printer3d_driver/nodes/__init__.py diff --git a/3D_printer/src/printer3d_driver/nodes/gcode_monitor_node.py b/3D_printer/src/printer3d_driver/nodes/gcode_monitor_node.py new file mode 100644 index 0000000..25961b8 --- /dev/null +++ b/3D_printer/src/printer3d_driver/nodes/gcode_monitor_node.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python3 +import rclpy +from rclpy.action import ActionClient +from rclpy.node import Node + +import time +import serial +import numpy as np + +from printer3d_msgs.srv import ProfileCommand +from printer3d_msgs.srv import GcodeCommand +from printer3d_msgs.srv import ImageCommand + +def openSerialPort(port, baud): + #open the serial port + print('Opening Serial Port...') + try: + s = serial.Serial(port, baud) + if (s.isOpen() == True): + print(port + " has opened successfully.") + return s + else: + print(port + " has failed to open.") + exit() + except: + print("An error occurred while opening " + port) + exit() + +def removeComment(string): + if (string.find(';') == -1): + return string + else: + return string[:string.index(';')] + + +class GcodeMonitorNode(Node): + def __init__(self): + super().__init__('printer_gcode_monitor') + + self.serialPort = openSerialPort('/dev/ttyACM0', 250000) + self.serialPort.write("\n\n".encode('ascii')) + time.sleep(2) + + self.gcodeService = self.create_service(GcodeCommand, 'send_gcode', self.execute_gcode_sending) + + + def execute_gcode_sending(self, request, response): + + gcode = request.gcode_strings + + self.get_logger().info('Executing Gcode') + + #self.get_logger().info('Gcode Received with a length of : '+str(len(gcode))) + + feedback = 0.0 + + self.serialPort.flushInput() + self.i = 0 + self.total = len(gcode) + self.increment = 0.0 + + for line in gcode: + + # feedback publication + + feedback = (self.i/self.total)*100 + if feedback - self.increment > 1: + self.increment = feedback + #self.get_logger().info('Progression : '+str(feedback)) + + # Gcode Sending + + l = removeComment(line) + l = l.strip() + self.i += 1 + if (l.isspace() == False and len(l) > 0): + if ' E' in l: + self.lastExtrusionSended = float(l.split('E')[1]) + #self.get_logger().info('extrusion changed : '+str(feedback)) + self.serialPort.write((l + "\n").encode('ascii')) + grbl_out = self.serialPort.readline() # wait for response from printer + grbl_out = grbl_out.strip().decode('ascii') + while 'ok' not in grbl_out: + grbl_out = self.serialPort.readline() # wait for response from printer + grbl_out = grbl_out.strip().decode('ascii') + + + self.serialPort.write(("M400\n").encode('ascii')) + grbl_out = self.serialPort.readline() # wait for response from printer + grbl_out = grbl_out.strip().decode('ascii') + while 'ok' not in grbl_out: + grbl_out = self.serialPort.readline() # wait for response from printer + grbl_out = grbl_out.strip().decode('ascii') + + + self.serialPort.write(("M400\n").encode('ascii')) + grbl_out = self.serialPort.readline() # wait for response from printer + grbl_out = grbl_out.strip().decode('ascii') + while 'ok' not in grbl_out: + grbl_out = self.serialPort.readline() # wait for response from printer + grbl_out = grbl_out.strip().decode('ascii') + + + self.get_logger().info('gcode sending completely finished') + response.validation = True + + return response + + +if __name__ == '__main__': + rclpy.init() + gcode_monitor_node = GcodeMonitorNode() + rclpy.spin(gcode_monitor_node) + rclpy.shutdown() \ No newline at end of file diff --git a/3D_printer/src/ros2_3d_printer_control/package.xml b/3D_printer/src/printer3d_driver/package.xml similarity index 93% rename from 3D_printer/src/ros2_3d_printer_control/package.xml rename to 3D_printer/src/printer3d_driver/package.xml index ca8e873..55b63bd 100644 --- a/3D_printer/src/ros2_3d_printer_control/package.xml +++ b/3D_printer/src/printer3d_driver/package.xml @@ -1,7 +1,7 @@ - ros2_3d_printer_control + printer3d_driver 0.0.0 TODO: Package description gulltor diff --git a/3D_printer/src/ros2_gocator_msgs/CMakeLists.txt b/3D_printer/src/printer3d_gocator_msgs/CMakeLists.txt similarity index 95% rename from 3D_printer/src/ros2_gocator_msgs/CMakeLists.txt rename to 3D_printer/src/printer3d_gocator_msgs/CMakeLists.txt index 8c0a879..2b65034 100644 --- a/3D_printer/src/ros2_gocator_msgs/CMakeLists.txt +++ b/3D_printer/src/printer3d_gocator_msgs/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.5) -project(ros2_gocator_msgs) +project(printer3d_gocator_msgs) if(NOT CMAKE_CXX_STANDARD) diff --git a/3D_printer/src/ros2_3d_printer_control/CMakeLists.txt b/3D_printer/src/ros2_3d_printer_control/CMakeLists.txt deleted file mode 100644 index 00bf963..0000000 --- a/3D_printer/src/ros2_3d_printer_control/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -cmake_minimum_required(VERSION 3.5) -project(ros2_3d_printer_control) - -# Default to C99 -if(NOT CMAKE_C_STANDARD) - set(CMAKE_C_STANDARD 99) -endif() - -# Default to C++14 -if(NOT CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 14) -endif() - -if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") - add_compile_options(-Wall -Wextra -Wpedantic) -endif() - -# find dependencies -find_package(ament_cmake REQUIRED) -find_package(rclcpp REQUIRED) -find_package(std_msgs REQUIRED) - -# Install the python module for this package -ament_python_install_package(nodes/) - -if(BUILD_TESTING) - find_package(ament_lint_auto REQUIRED) - # the following line skips the linter which checks for copyrights - # uncomment the line when a copyright and license is not present in all source files - #set(ament_cmake_copyright_FOUND TRUE) - # the following line skips cpplint (only works in a git repo) - # uncomment the line when this package is not in a git repo - #set(ament_cmake_cpplint_FOUND TRUE) - ament_lint_auto_find_test_dependencies() -endif() - -# Install python scripts - -install( - PROGRAMS - nodes/printer_control_node.py - DESTINATION lib/${PROJECT_NAME} -) - -ament_package() diff --git a/3D_printer/src/ros2_3d_printer_control/nodes/printer_control_node.py b/3D_printer/src/ros2_3d_printer_control/nodes/printer_control_node.py deleted file mode 100644 index 70949ad..0000000 --- a/3D_printer/src/ros2_3d_printer_control/nodes/printer_control_node.py +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python3 -import rclpy -from rclpy.action import ActionClient -from rclpy.node import Node - -from ros2_3d_printer_messages.srv import ProfileCommand -from ros2_3d_printer_messages.srv import GcodeCommand -from ros2_3d_printer_messages.srv import ImageCommand - - -class PrinterControlNode(Node): - def __init__(self): - super().__init__('printer_control') - self.client_image_capture = self.create_client(ImageCommand, 'ask_capture_image') - while not self.client_image_capture.wait_for_service(timeout_sec=1.0): - self.get_logger().info('image capture service not available, waiting again...') - self.req_image_capture = ImageCommand.Request() - - def sendImageCaptureRequest(self,filename): - self.req_image_capture.filename = filename - self.future_image_capture = self.client_image_capture.call_async(self.req_image_capture) - while rclpy.ok(): - rclpy.spin_once(self) - if self.future_image_capture.done(): - self.get_logger().info('capture finished') - break - - - -if __name__ == '__main__': - rclpy.init() - printer_control_node = PrinterControlNode() - for i in range(0,10): - printer_control_node.sendImageCaptureRequest('impressions/test/image_test_'+str(i)) - rclpy.shutdown() \ No newline at end of file diff --git a/3D_printer/src/ros2_3d_printer_gcode_monitor/nodes/__init__.py b/3D_printer/src/ros2_3d_printer_gcode_monitor/nodes/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/3D_printer/src/ros2_3d_printer_gcode_monitor/nodes/gcode_monitor_node.py b/3D_printer/src/ros2_3d_printer_gcode_monitor/nodes/gcode_monitor_node.py deleted file mode 100644 index 45c38ff..0000000 --- a/3D_printer/src/ros2_3d_printer_gcode_monitor/nodes/gcode_monitor_node.py +++ /dev/null @@ -1,19 +0,0 @@ -import rclpy -from rclpy.action import ActionClient -from rclpy.node import Node - -from 3D_printer_messages.srv import profileCommand -from 3D_printer_messages.srv import gcodeCommand -from 3D_printer_messages.srv import imageCommand - - -class ProfileCaptureNode(Node): - def __init__(self): - super().__init__('3D_printer_profile_capture') - - -if __name__ == '__main__': - rclpy.init() - image_capture_node = ProfileCaptureNode(0) - rclpy.spin(image_capture_node) - rclpy.shutdown() \ No newline at end of file diff --git a/3D_printer/src/ros2_3d_printer_gcode_monitor/package.xml b/3D_printer/src/ros2_3d_printer_gcode_monitor/package.xml deleted file mode 100644 index 859903b..0000000 --- a/3D_printer/src/ros2_3d_printer_gcode_monitor/package.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - ros2_3d_printer_gcode_monitor - 0.0.0 - TODO: Package description - gulltor - TODO: License declaration - - ament_cmake - - ament_lint_auto - ament_lint_common - - - ament_cmake - - diff --git a/3D_printer/src/ros2_3d_printer_image_capture/CMakeLists.txt b/3D_printer/src/ros2_3d_printer_image_capture/CMakeLists.txt deleted file mode 100644 index 0df93f2..0000000 --- a/3D_printer/src/ros2_3d_printer_image_capture/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -cmake_minimum_required(VERSION 3.5) -project(ros2_3d_printer_image_capture) - -# Default to C99 -if(NOT CMAKE_C_STANDARD) - set(CMAKE_C_STANDARD 99) -endif() - -# Default to C++14 -if(NOT CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 14) -endif() - -if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") - add_compile_options(-Wall -Wextra -Wpedantic) -endif() - -# find dependencies -find_package(ament_cmake REQUIRED) -find_package(rclcpp REQUIRED) -find_package(std_msgs REQUIRED) - -# Install the python module for this package -ament_python_install_package(nodes/) - -if(BUILD_TESTING) - find_package(ament_lint_auto REQUIRED) - # the following line skips the linter which checks for copyrights - # uncomment the line when a copyright and license is not present in all source files - #set(ament_cmake_copyright_FOUND TRUE) - # the following line skips cpplint (only works in a git repo) - # uncomment the line when this package is not in a git repo - #set(ament_cmake_cpplint_FOUND TRUE) - ament_lint_auto_find_test_dependencies() -endif() - -# Install python scripts - -install( - PROGRAMS - nodes/image_capture_node.py - DESTINATION lib/${PROJECT_NAME} -) - -ament_package() diff --git a/3D_printer/src/ros2_3d_printer_image_capture/nodes/__init__.py b/3D_printer/src/ros2_3d_printer_image_capture/nodes/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/3D_printer/src/ros2_3d_printer_image_capture/nodes/image_capture_node.py b/3D_printer/src/ros2_3d_printer_image_capture/nodes/image_capture_node.py deleted file mode 100644 index aba486b..0000000 --- a/3D_printer/src/ros2_3d_printer_image_capture/nodes/image_capture_node.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env python3 -import rclpy -from rclpy.action import ActionClient -from rclpy.node import Node - -from ros2_3d_printer_messages.srv import ProfileCommand -from ros2_3d_printer_messages.srv import GcodeCommand -from ros2_3d_printer_messages.srv import ImageCommand -import cv2 - - - -class ImageCaptureNode(Node): - def __init__(self,cameraNumber = 0): - super().__init__('printer_image_capture') - self.webcam = cv2.VideoCapture("/dev/video"+str(cameraNumber)) # Be carefull with the number after video - self.imageService = self.create_service(ImageCommand, 'ask_capture_image', self.takePicture) - - def __del__(self): - self.webcam.release() - - def takePicture(self,request, response): - check, frame = self.webcam.read() - cv2.imwrite(filename='/home/gulltor/Ramsai_Robotics/'+request.filename+'.jpg', img=frame) - self.get_logger().info('image acquired : /home/gulltor/Ramsai_Robotics/'+request.filename+'.jpg') - response.confirmation = True - return response - - -if __name__ == '__main__': - rclpy.init() - image_capture_node = ImageCaptureNode(0) - rclpy.spin(image_capture_node) - rclpy.shutdown() \ No newline at end of file diff --git a/3D_printer/src/ros2_3d_printer_image_capture/package.xml b/3D_printer/src/ros2_3d_printer_image_capture/package.xml deleted file mode 100644 index 30f2022..0000000 --- a/3D_printer/src/ros2_3d_printer_image_capture/package.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - ros2_3d_printer_image_capture - 0.0.0 - TODO: Package description - gulltor - TODO: License declaration - - ament_cmake - - ament_lint_auto - ament_lint_common - - - ament_cmake - - diff --git a/3D_printer/src/ros2_3d_printer_messages/CMakeLists.txt b/3D_printer/src/ros2_3d_printer_messages/CMakeLists.txt deleted file mode 100644 index 60c14f5..0000000 --- a/3D_printer/src/ros2_3d_printer_messages/CMakeLists.txt +++ /dev/null @@ -1,47 +0,0 @@ -cmake_minimum_required(VERSION 3.5) -project(ros2_3d_printer_messages) - -# Default to C99 -if(NOT CMAKE_C_STANDARD) - set(CMAKE_C_STANDARD 99) -endif() - -# Default to C++14 -if(NOT CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 14) -endif() - -if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") - add_compile_options(-Wall -Wextra -Wpedantic) -endif() - -# find dependencies -find_package(ament_cmake REQUIRED) -# uncomment the following section in order to fill in -# further dependencies manually. -# find_package( REQUIRED) -find_package(ament_cmake REQUIRED) -find_package(builtin_interfaces REQUIRED) -find_package(rosidl_default_generators REQUIRED) -find_package(std_msgs REQUIRED) -find_package(sensor_msgs REQUIRED) - - -if(BUILD_TESTING) - find_package(ament_lint_auto REQUIRED) - # the following line skips the linter which checks for copyrights - # uncomment the line when a copyright and license is not present in all source files - #set(ament_cmake_copyright_FOUND TRUE) - # the following line skips cpplint (only works in a git repo) - # uncomment the line when this package is not in a git repo - #set(ament_cmake_cpplint_FOUND TRUE) - ament_lint_auto_find_test_dependencies() -endif() - -rosidl_generate_interfaces(${PROJECT_NAME} - "srv/ProfileCommand.srv" - "srv/GcodeCommand.srv" - "srv/ImageCommand.srv" - ) - -ament_package() diff --git a/3D_printer/src/ros2_3d_printer_messages/package.xml b/3D_printer/src/ros2_3d_printer_messages/package.xml deleted file mode 100644 index 31d7fdb..0000000 --- a/3D_printer/src/ros2_3d_printer_messages/package.xml +++ /dev/null @@ -1,19 +0,0 @@ - - -ros2_3d_printer_messages -0.0.0 -Messages form communication with GOCATOR systems -m.bednarczyk -TODO: License declaration -ament_cmake -ament_lint_auto -ament_lint_common -std_msgs -sensor_msgs -builtin_interfaces -rosidl_default_generators -rosidl_interface_packages - -ament_cmake - - \ No newline at end of file diff --git a/3D_printer/src/ros2_3d_printer_messages/srv/GcodeCommand.srv b/3D_printer/src/ros2_3d_printer_messages/srv/GcodeCommand.srv deleted file mode 100644 index 72b6cf5..0000000 --- a/3D_printer/src/ros2_3d_printer_messages/srv/GcodeCommand.srv +++ /dev/null @@ -1,3 +0,0 @@ -string[] gcode_strings ---- -bool validation \ No newline at end of file diff --git a/3D_printer/src/ros2_3d_printer_messages/srv/ImageCommand.srv b/3D_printer/src/ros2_3d_printer_messages/srv/ImageCommand.srv deleted file mode 100644 index 65ce60f..0000000 --- a/3D_printer/src/ros2_3d_printer_messages/srv/ImageCommand.srv +++ /dev/null @@ -1,3 +0,0 @@ -string filename ---- -bool confirmation \ No newline at end of file diff --git a/3D_printer/src/ros2_3d_printer_messages/srv/ProfileCommand.srv b/3D_printer/src/ros2_3d_printer_messages/srv/ProfileCommand.srv deleted file mode 100644 index dd07f00..0000000 --- a/3D_printer/src/ros2_3d_printer_messages/srv/ProfileCommand.srv +++ /dev/null @@ -1,6 +0,0 @@ -float64 y_min -float64 y_max -float64 z_upper -float64 step ---- -bool validation \ No newline at end of file diff --git a/3D_printer/src/ros2_3d_printer_profile_capture/CMakeLists.txt b/3D_printer/src/ros2_3d_printer_profile_capture/CMakeLists.txt deleted file mode 100644 index 61fdde7..0000000 --- a/3D_printer/src/ros2_3d_printer_profile_capture/CMakeLists.txt +++ /dev/null @@ -1,120 +0,0 @@ -cmake_minimum_required(VERSION 3.5) -project(ros2_3d_printer_profile_capture) - -# Default to C99 -if(NOT CMAKE_C_STANDARD) - set(CMAKE_C_STANDARD 99) -endif() - -# Default to C++14 -if(NOT CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 14) -endif() - -if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") - add_compile_options(-Wall -Wextra -Wpedantic) -endif() - -# find dependencies -find_package(ament_cmake REQUIRED) -find_package(rclcpp REQUIRED) -# find_package(rclpy REQUIRED) -find_package(std_msgs REQUIRED) -find_package(sensor_msgs REQUIRED) -find_package(rosidl_default_generators REQUIRED) -find_package(ros2_gocator_msgs REQUIRED) -find_package(pcl_conversions REQUIRED) - -# Find point cloud Library -FIND_PACKAGE(PCL REQUIRED COMPONENTS) -INCLUDE_DIRECTORIES(${PCL_INCLUDE_DIRS}) -LINK_DIRECTORIES(${PCL_LIBRARY_DIRS}) -ADD_DEFINITIONS(${PCL_DEFINITIONS}) - -# Set GO_SDK include paths (That could be part of a FindGocator.cmake) -SET(GO_SDK_4 ${CMAKE_CURRENT_SOURCE_DIR}/external/GO_SDK) -FIND_PATH( - GOCATOR_INCLUDES - NAMES GoSdk/GoSdk.h - PATHS ${GO_SDK_4}/Gocator/GoSdk) -FIND_PATH( - KAPI_INCLUDES - NAMES kApi/kApi.h - PATHS ${GO_SDK_4}/Platform/kApi) -INCLUDE_DIRECTORIES(${GOCATOR_INCLUDES} ${KAPI_INCLUDES}) - -# Set GO_SDK libs (That could be part of a FindGocator.cmake) -FIND_LIBRARY( - GOCATOR_LIBRARIES - NAMES GoSdk - PATHS ${GO_SDK_4}/lib/linux_x64d) -FIND_LIBRARY( - KAPI_LIBRARIES - NAMES kApi - PATHS ${GO_SDK_4}/lib/linux_x64d) - -# Set source files -SET(LIB_SRCS - src/driver/gocatorSensor.cpp) - -# Set header files -SET(LIB_HDRS - src/driver/gocatorSensor.h) - -INCLUDE_DIRECTORIES(${LIB_HDRS}) - -# Install the python module for this package -# ament_python_install_package(script/) -# ament_python_install_package(nodes/) - - - -################################################################################ -# Declare ROS messages, services and actions -################################################################################ - -add_executable( gocator_sensor_node src/nodes/gocatorSensorNode.cpp ${LIB_HDRS} ${LIB_SRCS} ) -target_link_libraries (gocator_sensor_node ${GOCATOR_LIBRARIES} ${KAPI_LIBRARIES} ${Boost_SYSTEM_LIBRARY}) - -ament_target_dependencies(gocator_sensor_node rclcpp sensor_msgs std_msgs ros2_gocator_msgs pcl_conversions) - - -# Install C++ headers -#install( -# DIRECTORY ${PROJECT_NAME}/include -# ${LIB_DIR}/include -# DESTINATION include/${PROJECT_NAME} -# FILES_MATCHING PATTERN "*.hpp" -#) - -install(TARGETS - gocator_sensor_node - DESTINATION lib/${PROJECT_NAME}) - -if(BUILD_TESTING) - find_package(ament_lint_auto REQUIRED) - # the following line skips the linter which checks for copyrights - # uncomment the line when a copyright and license is not present in all source files - #set(ament_cmake_copyright_FOUND TRUE) - # the following line skips cpplint (only works in a git repo) - # uncomment the line when this package is not in a git repo - #set(ament_cmake_cpplint_FOUND TRUE) - ament_lint_auto_find_test_dependencies() -endif() - - -# Install python scripts -# install( -# DIRECTORY external/GO_SDK/lib/linux_x64d/ #launch param script -# DESTINATION share/${PROJECT_NAME}/external/GO_SDK/lib/linux_x64d/ -# ) - -# install( -# PROGRAMS -# script/tcpSocket.py -# script/udpSocket.py -# nodes/iiwa_command_node.py -# DESTINATION lib/${PROJECT_NAME} -# ) - -ament_package() diff --git a/3D_printer/src/ros2_3d_printer_profile_capture/package.xml b/3D_printer/src/ros2_3d_printer_profile_capture/package.xml deleted file mode 100644 index 0156baf..0000000 --- a/3D_printer/src/ros2_3d_printer_profile_capture/package.xml +++ /dev/null @@ -1,22 +0,0 @@ - - -ros2_3d_printer_profile_capture -0.0.0 -Messages form communication with GOCATOR systems -m.bednarczyk -TODO: License declaration -ament_cmake -ament_lint_auto -ament_lint_common -std_msgs -sensor_msgs -gocator_msgs - -builtin_interfaces -pcl_conversions -rosidl_default_generators -rosidl_interface_packages - -ament_cmake - - \ No newline at end of file diff --git a/3D_printer/src/ros2_3d_printer_profile_capture/src/driver/CMakeLists.txt b/3D_printer/src/ros2_3d_printer_profile_capture/src/driver/CMakeLists.txt deleted file mode 100644 index c32dfc2..0000000 --- a/3D_printer/src/ros2_3d_printer_profile_capture/src/driver/CMakeLists.txt +++ /dev/null @@ -1,65 +0,0 @@ -# Pre-requisites about cmake itself -CMAKE_MINIMUM_REQUIRED(VERSION 3.5) - -# Project name and the type of project -PROJECT(gocatorSensor) - -# DEBUG/RELEASE -IF (NOT CMAKE_BUILD_TYPE) - SET(CMAKE_BUILD_TYPE "RELEASE") -ENDIF (NOT CMAKE_BUILD_TYPE) - -# Default to C99 -if(NOT CMAKE_C_STANDARD) - set(CMAKE_C_STANDARD 99) -endif() - -# Default to C++14 -if(NOT CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 14) -endif() - -if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") - add_compile_options(-Wall -Wextra -Wpedantic) -endif() - -# Find point cloud Library -FIND_PACKAGE(PCL REQUIRED COMPONENTS) -INCLUDE_DIRECTORIES(${PCL_INCLUDE_DIRS}) -LINK_DIRECTORIES(${PCL_LIBRARY_DIRS}) -ADD_DEFINITIONS(${PCL_DEFINITIONS}) - -# Set GO_SDK include paths (That could be part of a FindGocator.cmake) -SET(GO_SDK_4 ${CMAKE_CURRENT_SOURCE_DIR}/../../external/GO_SDK) -FIND_PATH( - GOCATOR_INCLUDES - NAMES GoSdk/GoSdk.h - PATHS ${GO_SDK_4}/Gocator/GoSdk) -FIND_PATH( - KAPI_INCLUDES - NAMES kApi/kApi.h - PATHS ${GO_SDK_4}/Platform/kApi) -INCLUDE_DIRECTORIES(${GOCATOR_INCLUDES} ${KAPI_INCLUDES}) - -# Set GO_SDK libs (That could be part of a FindGocator.cmake) -FIND_LIBRARY( - GOCATOR_LIBRARIES - NAMES GoSdk - PATHS ${GO_SDK_4}/lib/linux_x64d/) -FIND_LIBRARY( - KAPI_LIBRARIES - NAMES kApi - PATHS ${GO_SDK_4}/lib/linux_x64d/) - -# Set source files -SET(SRCS - gocatorSensor.cpp) - -# Set header files -SET(HDRS - gocatorSensor.h) - -#Build library -ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS}) -TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${GOCATOR_LIBRARIES} ${KAPI_LIBRARIES} ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES}) - diff --git a/3D_printer/src/ros2_3d_printer_profile_capture/src/driver/gocatorSensor.cpp b/3D_printer/src/ros2_3d_printer_profile_capture/src/driver/gocatorSensor.cpp deleted file mode 100644 index f633b1c..0000000 --- a/3D_printer/src/ros2_3d_printer_profile_capture/src/driver/gocatorSensor.cpp +++ /dev/null @@ -1,424 +0,0 @@ -#include "gocatorSensor.h" - -GocatorSensor::Device::Device(const std::string & _ip_address) -{ - kStatus status; - kIpAddress ipAddress; - kChar model_name[50]; - - //init all GO API objects - go_api_ = kNULL; - go_system_ = kNULL; - go_sensor_ = kNULL; - go_setup_ = kNULL; - go_dataset_ = kNULL; - go_stamp_ptr_ = kNULL; - - // construct Gocator API Library - if ((status = GoSdk_Construct(&go_api_)) != kOK) - { - std::cout << "Device(). Error: GoSdk_Construct: " << status << std::endl; - status_ = DEVICE_NOT_FOUND; - return; - } - - // construct GoSystem object - if ((status = GoSystem_Construct(&go_system_, kNULL)) != kOK) - { - std::cout << "Device(). Error: GoSystem_Construct: " << status << std::endl; - status_ = DEVICE_NOT_FOUND; - return; - } - - // obtain GoSensor object by sensor IP address - kIpAddress_Parse(&ipAddress, _ip_address.c_str()); - if ((status = GoSystem_FindSensorByIpAddress(go_system_, &ipAddress, &go_sensor_)) != kOK) - { - std::cout << "Device(). Error: GoSystem_FindSensorByIpAddress: " << status << std::endl; - status_ = DEVICE_NOT_FOUND; - return; - } - - //Success case. Set status and device fixed params (ip, model name and serial number ). - status_ = DEVICE_FOUND; - device_params_.ip_address_ = _ip_address; - - // create connection to GoSensor object - if ((status = GoSensor_Connect(go_sensor_)) != kOK) - { - std::cout << "Device(). Error: GoSensor_Connect: " << status << std::endl; - status_ = DEVICE_NOT_CONNECT; - return; - } - status_ = DEVICE_CONNECT; - - // enable sensor data channel - if ((status = GoSystem_EnableData(go_system_, kTRUE)) != kOK) - { - std::cout << "Device(). Error: GoSensor_EnableData: " << status << std::endl; - return; - } - - // retrieve setup handle - if ((go_setup_ = GoSensor_Setup(go_sensor_)) == kNULL) - { - std::cout << "Device(). Error: GoSensor_Setup: Invalid Handle" << std::endl; - return; - } - - //Obtain camera model - if ((status = GoSensor_Model(go_sensor_, model_name, 50)) != kOK ) - { - std::cout << "Device(). Error: GoSensor_Model: " << status << std::endl; - return; - } - device_params_.model_name_ = model_name; - - //Obtain camera Serial number - device_params_.sn_ = (unsigned int)GoSensor_Id(go_sensor_); - - //Obtain exposure - capture_params_.exposure_time_ = GoSetup_Exposure(go_setup_, GO_ROLE_MAIN); - - //Obtain spacing interval - capture_params_.spacing_interval_ = GoSetup_SpacingInterval(go_setup_, GO_ROLE_MAIN); - - //print info - std::cout << "Found Sensor: " << std::endl; - device_params_.print(); -} - -GocatorSensor::Device::~Device() -{ - kStatus status; - - // destroy handles - GoDestroy(go_system_); - GoDestroy(go_api_); - - //bye bye message - std::cout << "~Device(). Gocator Sensor Stopped and Device Object Destroyed." << std::endl; -} - -int GocatorSensor::Device::configure(const CaptureParams & _configs) -{ - kStatus status; - - //set exposure - if ((status = GoSetup_SetExposure(go_setup_, GO_ROLE_MAIN, _configs.exposure_time_)) != kOK ) - { - std::cout << "configure(): Error setting Exposure Time to " << _configs.exposure_time_ << std::endl; - return -1; - } - - //set spacing interval - if ((status = GoSetup_SetSpacingInterval(go_setup_, GO_ROLE_MAIN, _configs.spacing_interval_)) != kOK ) - { - std::cout << "configure(): Error setting Spacing Interval to " << _configs.spacing_interval_ << std::endl; - return -1; - } - - //set this->capture_params_ with true values from camera - capture_params_.exposure_time_ = GoSetup_Exposure(go_setup_, GO_ROLE_MAIN); - capture_params_.spacing_interval_ = GoSetup_SpacingInterval(go_setup_, GO_ROLE_MAIN); - - //print - std::cout << "Configuration Setings: " << std::endl; - capture_params_.print(); - - //return - return 1; -} - -int GocatorSensor::Device::start() -{ - kStatus status; - - // start Gocator sensor - if ((status = GoSystem_Start(go_system_)) != kOK) - { - std::cout << "Device(). Error: GoSystem_Start: " << status << std::endl; - return -1; - } - - //message to std out - //std::cout << "Gocator running ... " << std::endl; - - //set this->status_ - this->status_ = DEVICE_RUNNING; - - //return success - return 1; -} - -int GocatorSensor::Device::stop() -{ - kStatus status; - - // stop Gocator sensor - if ((status = GoSystem_Stop(go_system_)) != kOK) - { - std::cout << "~Device(). Error: GoSystem_Stop: " << status << std::endl; - return -1; - } - - //message to std out - //std::cout << "... Gocator stopped" << std::endl << std::endl; - - //set this->status_ - this->status_ = DEVICE_CONNECT; - - //return success - return 1; -} - -int GocatorSensor::Device::getCurrentSnapshot(pcl::PointCloud & _p_cloud) -{ - -} - -int GocatorSensor::Device::getSingleSnapshot(pcl::PointCloud & _p_cloud) -{ - -} - -int GocatorSensor::Device::getProfile(pcl::PointCloud & _p_cloud) -{ - unsigned int i, j, k, arrayIndex; - GoDataSet dataset = kNULL; - std::vector profileBuffer; - GoStamp *stamp =kNULL; - GoDataMsg dataObj; - k32u profilePointCount; - if (GoSystem_ReceiveData(go_system_, &dataset, RECEIVE_TIMEOUT) == kOK) - { - printf("Data message received:\n"); - printf("Dataset count: %u\n", (k32u)GoDataSet_Count(dataset)); - // each result can have multiple data items - // loop through all items in result message - for (i = 0; i < GoDataSet_Count(dataset); ++i) - { - dataObj = GoDataSet_At(dataset, i); - //Retrieve GoStamp message - switch(GoDataMsg_Type(dataObj)) - { - case GO_DATA_MESSAGE_TYPE_STAMP: - { - GoStampMsg stampMsg = dataObj; - - printf("Stamp Message batch count: %u\n", (k32u)GoStampMsg_Count(stampMsg)); - for (j = 0; j < GoStampMsg_Count(stampMsg); ++j) - { - stamp = GoStampMsg_At(stampMsg, j); - printf(" Timestamp: %llu\n", stamp->timestamp); - printf(" Encoder: %lld\n", stamp->encoder); - printf(" Frame index: %llu\n", stamp->frameIndex); - } - } - break; - case GO_DATA_MESSAGE_TYPE_UNIFORM_PROFILE: - { - GoResampledProfileMsg profileMsg = dataObj; - - printf("Resampled Profile Message batch count: %u\n", (k32u)GoResampledProfileMsg_Count(profileMsg)); - - _p_cloud.height = GoResampledProfileMsg_Count(profileMsg); - _p_cloud.width = GoResampledProfileMsg_Width(profileMsg); - _p_cloud.resize(_p_cloud.height*_p_cloud.width); - - for (k = 0; k < GoResampledProfileMsg_Count(profileMsg); ++k) - { - unsigned int validPointCount = 0; - short* data = GoResampledProfileMsg_At(profileMsg, k); - double XResolution = NM_TO_MM(GoResampledProfileMsg_XResolution(profileMsg)); - double ZResolution = NM_TO_MM(GoResampledProfileMsg_ZResolution(profileMsg)); - double XOffset = UM_TO_MM(GoResampledProfileMsg_XOffset(profileMsg)); - double ZOffset = UM_TO_MM(GoResampledProfileMsg_ZOffset(profileMsg)); - - // profileBuffer.resize(GoResampledProfileMsg_Width(profileMsg)); - - - // translate 16-bit range data to engineering units and copy profiles to memory array - for (arrayIndex = 0; arrayIndex < GoResampledProfileMsg_Width(profileMsg); ++arrayIndex) - { - - if (data[arrayIndex] != INVALID_RANGE_16BIT ) - { - // profileBuffer[arrayIndex].x = XOffset + XResolution * arrayIndex; - // profileBuffer[arrayIndex].z = ZOffset + ZResolution * data[arrayIndex]; - _p_cloud.points.at(k*_p_cloud.width+arrayIndex).x = XOffset + XResolution * arrayIndex; - _p_cloud.points.at(k*_p_cloud.width+arrayIndex).z = ZOffset + ZResolution * data[arrayIndex]; - validPointCount++; - } - else - { - // profileBuffer[arrayIndex].x = XOffset + XResolution * arrayIndex; - // profileBuffer[arrayIndex].z = INVALID_RANGE_DOUBLE; - _p_cloud.points.at(k*_p_cloud.width+arrayIndex).x = XOffset + XResolution * arrayIndex; - _p_cloud.points.at(k*_p_cloud.width+arrayIndex).z = INVALID_RANGE_DOUBLE; - } - - - } - - printf(" Profile Valid Point %d out of max %d\n", validPointCount, profilePointCount); - } - } - break; - case GO_DATA_MESSAGE_TYPE_PROFILE_POINT_CLOUD: // Note this is NON resampled profile - { - GoProfileMsg profileMsg = dataObj; - - printf("Profile Message batch count: %u\n", (k32u)GoProfileMsg_Count(profileMsg)); - - _p_cloud.height = GoProfileMsg_Count(profileMsg); - _p_cloud.width = GoProfileMsg_Width(profileMsg); - _p_cloud.resize(_p_cloud.height*_p_cloud.width); - - for (k = 0; k < GoProfileMsg_Count(profileMsg); ++k) - { - kPoint16s* data = GoProfileMsg_At(profileMsg, k); - unsigned int validPointCount = 0; - double XResolution = NM_TO_MM(GoProfileMsg_XResolution(profileMsg)); - double ZResolution = NM_TO_MM(GoProfileMsg_ZResolution(profileMsg)); - double XOffset = UM_TO_MM(GoProfileMsg_XOffset(profileMsg)); - double ZOffset = UM_TO_MM(GoProfileMsg_ZOffset(profileMsg)); - - // profileBuffer.resize(GoResampledProfileMsg_Width(profileMsg)); - - //translate 16-bit range data to engineering units and copy profiles to memory array - for (arrayIndex = 0; arrayIndex < GoProfileMsg_Width(profileMsg); ++arrayIndex) - { - if (data[arrayIndex].x != INVALID_RANGE_16BIT) - { - // profileBuffer[arrayIndex].x = XOffset + XResolution * data[arrayIndex].x; - // profileBuffer[arrayIndex].z = ZOffset + ZResolution * data[arrayIndex].y; - _p_cloud.points.at(k*_p_cloud.width+arrayIndex).x = XOffset + XResolution * data[arrayIndex].x; - _p_cloud.points.at(k*_p_cloud.width+arrayIndex).z = ZOffset + ZResolution * data[arrayIndex].y; - validPointCount++; - } - else - { - // profileBuffer[arrayIndex].x = INVALID_RANGE_DOUBLE; - // profileBuffer[arrayIndex].z = INVALID_RANGE_DOUBLE; - _p_cloud.points.at(k*_p_cloud.width+arrayIndex).x = INVALID_RANGE_DOUBLE; - _p_cloud.points.at(k*_p_cloud.width+arrayIndex).z = INVALID_RANGE_DOUBLE; - } - } - printf(" Profile Valid Point %d out of max %d\n", validPointCount, profilePointCount); - } - } - break; - case GO_DATA_MESSAGE_TYPE_PROFILE_INTENSITY: - { - unsigned int validPointCount = 0; - GoProfileIntensityMsg intensityMsg = dataObj; - printf("Intensity Message batch count: %u\n", (k32u)GoProfileIntensityMsg_Count(intensityMsg)); - - profileBuffer.resize(GoProfileIntensityMsg_Count(intensityMsg)); - - for (k = 0; k < GoProfileIntensityMsg_Count(intensityMsg); ++k) - { - unsigned char* data = GoProfileIntensityMsg_At(intensityMsg, k); - for (arrayIndex = 0; arrayIndex < GoProfileIntensityMsg_Width(intensityMsg); ++arrayIndex) - { - profileBuffer[arrayIndex].intensity = data[arrayIndex]; - } - } - } - break; - } - } - GoDestroy(dataset); - } - else - { - printf ("Error: No data received during the waiting period\n"); - } - return 1; -} - -void GocatorSensor::Device::getDeviceHealth(std::string & _health_str) const -{ - //local variables - GoDataSet health_data = kNULL; - GoHealthMsg health_msg =kNULL; - GoIndicator *health_indicator = kNULL; - std::ostringstream sstr; - - //get health from device - if ( (GoSystem_ReceiveHealth(go_system_, &health_data, RECEIVE_TIMEOUT)) == kOK ) - { - for (unsigned int ii = 0; ii < GoDataSet_Count(health_data); ii++) - { - health_msg = GoDataSet_At(health_data, ii); - for (unsigned int jj = 0; jj < GoHealthMsg_Count(health_msg); jj++) - { - health_indicator = GoHealthMsg_At(health_msg, jj); - sstr << "Indicator[" << jj << "]:\n" - << "\tId: " << health_indicator->id << "\n" - << "\tInstance: " << health_indicator->instance << "\n" - << "\tValue: " << health_indicator->value << "\n"; - } - } - GoDestroy(health_msg); - } - - _health_str = sstr.str(); -} - -void GocatorSensor::Device::getTemperature(double & _internal_temp, double & _projector_temp, double & _laser_temp) const -{ - //local variables - GoDataSet health_data = kNULL; - GoHealthMsg health_msg =kNULL; - GoIndicator *health_indicator = kNULL; - //k32u instance; - - //get health dataset from device - if ( (GoSystem_ReceiveHealth(go_system_, &health_data, RECEIVE_TIMEOUT)) == kOK ) - { - for (unsigned int ii = 0; ii < GoDataSet_Count(health_data); ii++) - { - //get the health message - health_msg = GoDataSet_At(health_data, ii); - - //find in the message the internal temperature indicator, and set the value - health_indicator = GoHealthMsg_Find(health_msg, GO_HEALTH_TEMPERATURE, 0); - if (health_indicator != kNULL) _internal_temp = health_indicator->value; - else _internal_temp = -100.; - - //find in the message the projector temperature indicator, and set the value - health_indicator = GoHealthMsg_Find(health_msg, GO_HEALTH_PROJECTOR_TEMPERATURE, 0); - if (health_indicator != kNULL) _projector_temp = health_indicator->value; - else _projector_temp = -100.; - - //find in the message the projector temperature indicator, and set the value - health_indicator = GoHealthMsg_Find(health_msg, GO_HEALTH_LASER_TEMPERATURE, 0); - if (health_indicator != kNULL) _laser_temp = health_indicator->value; - else _laser_temp = -100.; - } - GoDestroy(health_msg); - } - -} - -int GocatorSensor::Device::close() -{ - -} - -void GocatorSensor::Device::printDeviceData() const -{ - -} - -void GocatorSensor::Device::sendTrigger() const { - printf("sending trigger \n"); - kStatus status = GoSensor_Trigger(go_sensor_); - if (status != kOK) - { - printf("Error: GoSensor_Connect:%d\n", status); - return; - } -} diff --git a/3D_printer/src/ros2_3d_printer_profile_capture/src/driver/gocatorSensor.h b/3D_printer/src/ros2_3d_printer_profile_capture/src/driver/gocatorSensor.h deleted file mode 100644 index d7fda34..0000000 --- a/3D_printer/src/ros2_3d_printer_profile_capture/src/driver/gocatorSensor.h +++ /dev/null @@ -1,187 +0,0 @@ -#ifndef GocatorSensor_H -#define GocatorSensor_H - -//std c/c++ -#include -#include -#include -#include - -//GoSdk -#include - -//PCL -#include -#include - -//constants -#define SENSOR_IP "192.168.1.10" // sensor IP address -#define RECEIVE_TIMEOUT 20000000 // timeout for snapshot acquisition -#define INVALID_RANGE_16BIT ((signed short)0x8000) // gocator transmits range data as 16-bit signed integers. 0x8000 signifies invalid range data. -#define DOUBLE_MAX ((k64f)1.7976931348623157e+308) // 64-bit double - largest positive value. -#define INVALID_RANGE_DOUBLE ((k64f)-DOUBLE_MAX) // floating point value to represent invalid range data. -#define NM_TO_MM(VALUE) (((k64f)(VALUE))/1000000.0) -#define UM_TO_MM(VALUE) (((k64f)(VALUE))/1000.0) - -namespace GocatorSensor -{ - -typedef struct ProfilePoint -{ - double x; // x-coordinate in engineering units (mm) - position along laser line - double z; // z-coordinate in engineering units (mm) - height (at the given x position) - unsigned char intensity; -} ProfilePoint; - -//status values -enum {DEVICE_NOT_FOUND=0,DEVICE_FOUND,DEVICE_NOT_CONNECT,DEVICE_CONNECT,DEVICE_RUNNING}; - -//device parameters struct -struct DeviceParams -{ - std::string ip_address_; - std::string model_name_; - unsigned int sn_; - - void print() const - { - std::cout << "\tIP ad: \t" << ip_address_ << std::endl; - std::cout << "\tModel: \t" << model_name_ << std::endl; - std::cout << "\tSN: \t" << sn_ << std::endl; - } -}; - -//device configuration struct -struct CaptureParams -{ - double exposure_time_; //in useconds - double spacing_interval_; //in millimeters - - void print() const - { - std::cout << "\texposure [us]: \t" << exposure_time_ << std::endl; - std::cout << "\tspacing [mm]: \t" << spacing_interval_ << std::endl; - } -}; - -//Device class -class Device -{ -protected: - //current point cloud. Maybe not necessary to be here! - //pcl::PointCloud::Ptr p_cloud_; //p_cloud_ = new pcl::PointCloud - - //driver status - unsigned int status_; - - //device fixed params - DeviceParams device_params_; - - //device configuration - CaptureParams capture_params_; - - //GO API objects - kAssembly go_api_; - GoSystem go_system_; - GoSensor go_sensor_; - GoSetup go_setup_; - GoDataSet go_dataset_; - GoStamp *go_stamp_ptr_; - -public: - /** \brief Constructor - * - * Constructor. Sets params_ struct. - * - **/ - Device(const std::string & _ip_address); - - /** \brief Destructor - * - * Destructor - * - **/ - ~Device(); - - /** \brief Connect to a pysical device given an ip address - * - * Connect to a pysical device given an ip address - * - **/ -// int connect(); - - /** \brief Set/get device parameters to/from the camera - * - * Set/get device parameters to/from the camera - * - **/ - int configure(const CaptureParams & _configs); - - /** \brief Start device data acquisition - * - * Start device data acquisition - * - **/ - int start(); - - /** \brief Stop device dat acquisition - * - * Stop device data acquisition - * - **/ - int stop(); - - /** \brief Get the current snapshot - * - * Get the current snapshot, when in continuous acquisition - * - **/ - int getCurrentSnapshot(pcl::PointCloud & _p_cloud); - - /** \brief Get a single snapshot in the same thread - * - * Get a single snapshot in the same thread - * - **/ - int getSingleSnapshot(pcl::PointCloud & _p_cloud); - - int getProfile(pcl::PointCloud & _p_cloud); - - - /** \brief Returns all health data as a string - * - * Returns all health data as a string - * - **/ - void getDeviceHealth(std::string & _health_str) const; - - /** \brief Returns three device temperatures - * - * Returns three device temperatures: internal, projector and laser - * - **/ - void getTemperature(double & _internal_temp, double & _projector_temp, double & _laser_temp) const; - - /** \brief Close the connection to a physical device - * - * Close the connection to a physical device - * - **/ - int close(); - - /** \brief Print the device configuration - * - * Print the device configuration - * - **/ - void printDeviceData() const; - - /** \brief Send a trigger signal - * - **/ - void sendTrigger() const; -};//close class -}//close namespace - -#endif - diff --git a/3D_printer/src/ros2_3d_printer_profile_capture/src/nodes/gocatorSensorNode.cpp b/3D_printer/src/ros2_3d_printer_profile_capture/src/nodes/gocatorSensorNode.cpp deleted file mode 100644 index b861fde..0000000 --- a/3D_printer/src/ros2_3d_printer_profile_capture/src/nodes/gocatorSensorNode.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include -#include -#include - -#include "rclcpp/rclcpp.hpp" -#include "pcl_conversions/pcl_conversions.h" -#include "std_msgs/msg/empty.hpp" -#include "ros2_gocator_msgs/srv/gocator_pt_cloud.hpp" -#include "../driver/gocatorSensor.h" - - -using namespace std::chrono_literals; - -class GocatorSensorNode : public rclcpp::Node -{ - public: - GocatorSensorNode() - : Node("gocatorSensorNode") - { - gsensor_ = new GocatorSensor::Device(SENSOR_IP); - capture_params_.exposure_time_ = 40000; - capture_params_.spacing_interval_ = 0.1; - gsensor_->configure(capture_params_); - - service_ = this->create_service("gocator_get_profile", std::bind(&GocatorSensorNode::profile_snapshot, this, std::placeholders::_1, std::placeholders::_2)); - // publisher_ = this->create_publisher("gocatorPTCloud_topic", 10); - } - - private: - void profile_snapshot(std::shared_ptr request, - std::shared_ptr response) - { - pcl::PointCloud cloud; - RCLCPP_INFO(this->get_logger(),"Processing service request!"); - gsensor_->start(); - gsensor_->sendTrigger(); - if ( gsensor_->getProfile(cloud) == 1 ) - { - auto pcloud = sensor_msgs::msg::PointCloud2(); - pcl::toROSMsg(cloud,pcloud); - pcloud.header.frame_id = "gocator_sensor"; - pcloud.header.stamp = this->get_clock()->now(); - - // publisher_->publish(pcloud); - - response->pcloud = pcloud; - } - - } - - rclcpp::Service::SharedPtr service_; - rclcpp::Publisher::SharedPtr publisher_; - GocatorSensor::Device *gsensor_; - GocatorSensor::CaptureParams capture_params_; -}; - -int main(int argc, char * argv[]) -{ - rclcpp::init(argc, argv); - rclcpp::spin(std::make_shared()); - rclcpp::shutdown(); - return 0; -} \ No newline at end of file diff --git a/3D_printer/src/ros2_gocator_msgs/README.md b/3D_printer/src/ros2_gocator_msgs/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/3D_printer/src/ros2_gocator_msgs/package.xml b/3D_printer/src/ros2_gocator_msgs/package.xml deleted file mode 100644 index 680a651..0000000 --- a/3D_printer/src/ros2_gocator_msgs/package.xml +++ /dev/null @@ -1,19 +0,0 @@ - - -ros2_gocator_msgs -0.0.0 -Messages form communication with GOCATOR systems -m.bednarczyk -TODO: License declaration -ament_cmake -ament_lint_auto -ament_lint_common -std_msgs -sensor_msgs -builtin_interfaces -rosidl_default_generators -rosidl_interface_packages - -ament_cmake - - diff --git a/3D_printer/src/ros2_gocator_msgs/srv/GocatorPTCloud.srv b/3D_printer/src/ros2_gocator_msgs/srv/GocatorPTCloud.srv deleted file mode 100644 index 9f7446e..0000000 --- a/3D_printer/src/ros2_gocator_msgs/srv/GocatorPTCloud.srv +++ /dev/null @@ -1,5 +0,0 @@ -std_msgs/Empty request ---- -sensor_msgs/PointCloud2 pcloud - - From 2bd1f9b5f8588af731925744d150c542b1772d71 Mon Sep 17 00:00:00 2001 From: Mosserl Date: Tue, 4 Apr 2023 18:33:21 +0200 Subject: [PATCH 07/30] end of the day. The four packages are working. The printing routine must be coded. --- .../src/printer3d_gocator_msgs/README.md | 0 .../src/printer3d_gocator_msgs/package.xml | 19 ++ .../srv/GocatorPTCloud.srv | 5 + .../printer3d_image_capture/CMakeLists.txt | 45 ++++ .../printer3d_image_capture/nodes/__init__.py | 0 .../nodes/image_capture_node.py | 34 +++ .../src/printer3d_image_capture/package.xml | 18 ++ .../src/printer3d_manager/CMakeLists.txt | 53 +++++ .../src/printer3d_manager/launch/__init__.py | 0 .../launch/launch_printer3d.py | 24 ++ .../src/printer3d_manager/nodes/__init__.py | 0 .../printer3d_manager/nodes/point_cloud2.py | 210 ++++++++++++++++++ .../nodes/printer_control_node.py | 146 ++++++++++++ .../src/printer3d_manager/nodes/utility.py | 61 +++++ 3D_printer/src/printer3d_manager/package.xml | 18 ++ 3D_printer/src/printer3d_msgs/CMakeLists.txt | 47 ++++ 3D_printer/src/printer3d_msgs/package.xml | 19 ++ .../src/printer3d_msgs/srv/GcodeCommand.srv | 3 + .../src/printer3d_msgs/srv/ImageCommand.srv | 3 + .../src/printer3d_msgs/srv/ProfileCommand.srv | 6 + 20 files changed, 711 insertions(+) create mode 100644 3D_printer/src/printer3d_gocator_msgs/README.md create mode 100644 3D_printer/src/printer3d_gocator_msgs/package.xml create mode 100644 3D_printer/src/printer3d_gocator_msgs/srv/GocatorPTCloud.srv create mode 100644 3D_printer/src/printer3d_image_capture/CMakeLists.txt create mode 100644 3D_printer/src/printer3d_image_capture/nodes/__init__.py create mode 100644 3D_printer/src/printer3d_image_capture/nodes/image_capture_node.py create mode 100644 3D_printer/src/printer3d_image_capture/package.xml create mode 100644 3D_printer/src/printer3d_manager/CMakeLists.txt create mode 100644 3D_printer/src/printer3d_manager/launch/__init__.py create mode 100644 3D_printer/src/printer3d_manager/launch/launch_printer3d.py create mode 100644 3D_printer/src/printer3d_manager/nodes/__init__.py create mode 100644 3D_printer/src/printer3d_manager/nodes/point_cloud2.py create mode 100644 3D_printer/src/printer3d_manager/nodes/printer_control_node.py create mode 100644 3D_printer/src/printer3d_manager/nodes/utility.py create mode 100644 3D_printer/src/printer3d_manager/package.xml create mode 100644 3D_printer/src/printer3d_msgs/CMakeLists.txt create mode 100644 3D_printer/src/printer3d_msgs/package.xml create mode 100644 3D_printer/src/printer3d_msgs/srv/GcodeCommand.srv create mode 100644 3D_printer/src/printer3d_msgs/srv/ImageCommand.srv create mode 100644 3D_printer/src/printer3d_msgs/srv/ProfileCommand.srv diff --git a/3D_printer/src/printer3d_gocator_msgs/README.md b/3D_printer/src/printer3d_gocator_msgs/README.md new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/src/printer3d_gocator_msgs/package.xml b/3D_printer/src/printer3d_gocator_msgs/package.xml new file mode 100644 index 0000000..01f1942 --- /dev/null +++ b/3D_printer/src/printer3d_gocator_msgs/package.xml @@ -0,0 +1,19 @@ + + +printer3d_gocator_msgs +0.0.0 +Messages form communication with GOCATOR systems +m.bednarczyk +TODO: License declaration +ament_cmake +ament_lint_auto +ament_lint_common +std_msgs +sensor_msgs +builtin_interfaces +rosidl_default_generators +rosidl_interface_packages + +ament_cmake + + diff --git a/3D_printer/src/printer3d_gocator_msgs/srv/GocatorPTCloud.srv b/3D_printer/src/printer3d_gocator_msgs/srv/GocatorPTCloud.srv new file mode 100644 index 0000000..9f7446e --- /dev/null +++ b/3D_printer/src/printer3d_gocator_msgs/srv/GocatorPTCloud.srv @@ -0,0 +1,5 @@ +std_msgs/Empty request +--- +sensor_msgs/PointCloud2 pcloud + + diff --git a/3D_printer/src/printer3d_image_capture/CMakeLists.txt b/3D_printer/src/printer3d_image_capture/CMakeLists.txt new file mode 100644 index 0000000..de49c2d --- /dev/null +++ b/3D_printer/src/printer3d_image_capture/CMakeLists.txt @@ -0,0 +1,45 @@ +cmake_minimum_required(VERSION 3.5) +project(printer3d_image_capture) + +# Default to C99 +if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 99) +endif() + +# Default to C++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# find dependencies +find_package(ament_cmake REQUIRED) +find_package(rclcpp REQUIRED) +find_package(std_msgs REQUIRED) + +# Install the python module for this package +ament_python_install_package(nodes/) + +if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + # the following line skips the linter which checks for copyrights + # uncomment the line when a copyright and license is not present in all source files + #set(ament_cmake_copyright_FOUND TRUE) + # the following line skips cpplint (only works in a git repo) + # uncomment the line when this package is not in a git repo + #set(ament_cmake_cpplint_FOUND TRUE) + ament_lint_auto_find_test_dependencies() +endif() + +# Install python scripts + +install( + PROGRAMS + nodes/image_capture_node.py + DESTINATION lib/${PROJECT_NAME} +) + +ament_package() diff --git a/3D_printer/src/printer3d_image_capture/nodes/__init__.py b/3D_printer/src/printer3d_image_capture/nodes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/src/printer3d_image_capture/nodes/image_capture_node.py b/3D_printer/src/printer3d_image_capture/nodes/image_capture_node.py new file mode 100644 index 0000000..312fbef --- /dev/null +++ b/3D_printer/src/printer3d_image_capture/nodes/image_capture_node.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +import rclpy +from rclpy.action import ActionClient +from rclpy.node import Node + +from printer3d_msgs.srv import ProfileCommand +from printer3d_msgs.srv import GcodeCommand +from printer3d_msgs.srv import ImageCommand +import cv2 + + + +class ImageCaptureNode(Node): + def __init__(self,cameraNumber = 0): + super().__init__('printer_image_capture') + self.webcam = cv2.VideoCapture("/dev/video"+str(cameraNumber)) # Be carefull with the number after video + self.imageService = self.create_service(ImageCommand, 'ask_capture_image', self.takePicture) + + def __del__(self): + self.webcam.release() + + def takePicture(self, request, response): + check, frame = self.webcam.read() + cv2.imwrite(filename='/home/gulltor/Ramsai_Robotics/'+request.filename+'.jpg', img=frame) + self.get_logger().info('image acquired : /home/gulltor/Ramsai_Robotics/'+request.filename+'.jpg') + response.confirmation = True + return response + + +if __name__ == '__main__': + rclpy.init() + image_capture_node = ImageCaptureNode(0) + rclpy.spin(image_capture_node) + rclpy.shutdown() \ No newline at end of file diff --git a/3D_printer/src/printer3d_image_capture/package.xml b/3D_printer/src/printer3d_image_capture/package.xml new file mode 100644 index 0000000..c897737 --- /dev/null +++ b/3D_printer/src/printer3d_image_capture/package.xml @@ -0,0 +1,18 @@ + + + + printer3d_image_capture + 0.0.0 + TODO: Package description + gulltor + TODO: License declaration + + ament_cmake + + ament_lint_auto + ament_lint_common + + + ament_cmake + + diff --git a/3D_printer/src/printer3d_manager/CMakeLists.txt b/3D_printer/src/printer3d_manager/CMakeLists.txt new file mode 100644 index 0000000..4b476f1 --- /dev/null +++ b/3D_printer/src/printer3d_manager/CMakeLists.txt @@ -0,0 +1,53 @@ +cmake_minimum_required(VERSION 3.5) +project(printer3d_manager) + +# Default to C99 +if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 99) +endif() + +# Default to C++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# find dependencies +find_package(ament_cmake REQUIRED) +find_package(rclcpp REQUIRED) +find_package(std_msgs REQUIRED) + +# Install the python module for this package +ament_python_install_package(nodes/) + +if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + # the following line skips the linter which checks for copyrights + # uncomment the line when a copyright and license is not present in all source files + #set(ament_cmake_copyright_FOUND TRUE) + # the following line skips cpplint (only works in a git repo) + # uncomment the line when this package is not in a git repo + #set(ament_cmake_cpplint_FOUND TRUE) + ament_lint_auto_find_test_dependencies() +endif() + +# Install python scripts + +install( + PROGRAMS + nodes/printer_control_node.py + nodes/utility.py + nodes/point_cloud2.py + DESTINATION lib/${PROJECT_NAME} +) + +# Install launch files. +install(DIRECTORY + launch + DESTINATION share/${PROJECT_NAME}/ +) + +ament_package() diff --git a/3D_printer/src/printer3d_manager/launch/__init__.py b/3D_printer/src/printer3d_manager/launch/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/src/printer3d_manager/launch/launch_printer3d.py b/3D_printer/src/printer3d_manager/launch/launch_printer3d.py new file mode 100644 index 0000000..e7ae616 --- /dev/null +++ b/3D_printer/src/printer3d_manager/launch/launch_printer3d.py @@ -0,0 +1,24 @@ +from launch import LaunchDescription +from launch_ros.actions import Node + +def generate_launch_description(): + return LaunchDescription([ + Node( + package='printer3d_manager', + namespace='printer1', + executable='printer_control_node', + name='printer_control_node' + ), + Node( + package='printer3d_image_capture', + namespace='printer1', + executable='image_capture_node', + name='image_capture_node' + ), + Node( + package='printer3d_profile_capture', + namespace='printer1', + executable='gocatorSensorNode', + name='profile_capture_node' + ) + ]) \ No newline at end of file diff --git a/3D_printer/src/printer3d_manager/nodes/__init__.py b/3D_printer/src/printer3d_manager/nodes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/3D_printer/src/printer3d_manager/nodes/point_cloud2.py b/3D_printer/src/printer3d_manager/nodes/point_cloud2.py new file mode 100644 index 0000000..dd7172e --- /dev/null +++ b/3D_printer/src/printer3d_manager/nodes/point_cloud2.py @@ -0,0 +1,210 @@ +#!/usr/bin/env python3 + +# Software License Agreement (BSD License) +# +# Copyright (c) 2008, Willow Garage, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of Willow Garage, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +""" +Serialization of sensor_msgs.PointCloud2 messages. + +Author: Tim Field +ROS2 port by Sebastian Grans (2020) +""" + +import sys + +from collections import namedtuple +import ctypes +import math +import struct + +from sensor_msgs.msg import PointCloud2, PointField + +_DATATYPES = {} +_DATATYPES[PointField.INT8] = ('b', 1) +_DATATYPES[PointField.UINT8] = ('B', 1) +_DATATYPES[PointField.INT16] = ('h', 2) +_DATATYPES[PointField.UINT16] = ('H', 2) +_DATATYPES[PointField.INT32] = ('i', 4) +_DATATYPES[PointField.UINT32] = ('I', 4) +_DATATYPES[PointField.FLOAT32] = ('f', 4) +_DATATYPES[PointField.FLOAT64] = ('d', 8) + +def read_points(cloud, field_names=None, skip_nans=False, uvs=[]): + """ + Read points from a L{sensor_msgs.PointCloud2} message. + + @param cloud: The point cloud to read from. + @type cloud: L{sensor_msgs.PointCloud2} + @param field_names: The names of fields to read. If None, read all fields. [default: None] + @type field_names: iterable + @param skip_nans: If True, then don't return any point with a NaN value. + @type skip_nans: bool [default: False] + @param uvs: If specified, then only return the points at the given coordinates. [default: empty list] + @type uvs: iterable + @return: Generator which yields a list of values for each point. + @rtype: generator + """ + assert isinstance(cloud, PointCloud2), 'cloud is not a sensor_msgs.msg.PointCloud2' + fmt = _get_struct_fmt(cloud.is_bigendian, cloud.fields, field_names) + width, height, point_step, row_step, data, isnan = cloud.width, cloud.height, \ + cloud.point_step, cloud.row_step, \ + cloud.data, math.isnan + unpack_from = struct.Struct(fmt).unpack_from + + if skip_nans: + if uvs: + for u, v in uvs: + p = unpack_from(data, (row_step * v) + (point_step * u)) + has_nan = False + for pv in p: + if isnan(pv): + has_nan = True + break + if not has_nan: + yield p + else: + for v in range(height): + offset = row_step * v + for u in range(width): + p = unpack_from(data, offset) + has_nan = False + for pv in p: + if isnan(pv): + has_nan = True + break + if not has_nan: + yield p + offset += point_step + else: + if uvs: + for u, v in uvs: + yield unpack_from(data, (row_step * v) + (point_step * u)) + else: + for v in range(height): + offset = row_step * v + for u in range(width): + yield unpack_from(data, offset) + offset += point_step + +def read_points_list(cloud, field_names=None, skip_nans=False, uvs=[]): + """ + Read points from a L{sensor_msgs.PointCloud2} message. + + This function returns a list of namedtuples. It operates on top of the read_points method. For more efficient access use read_points directly. + + @param cloud: The point cloud to read from. + @type cloud: L{sensor_msgs.PointCloud2} + @param field_names: The names of fields to read. If None, read all fields. [default: None] + @type field_names: iterable + @param skip_nans: If True, then don't return any point with a NaN value. + @type skip_nans: bool [default: False] + @param uvs: If specified, then only return the points at the given coordinates. [default: empty list] + @type uvs: iterable + @return: List of namedtuples containing the values for each point + @rtype: list + """ + assert isinstance(cloud, PointCloud2), 'cloud is not a sensor_msgs.msg.PointCloud2' + + if field_names is None: + field_names = [f.name for f in cloud.fields] + + Point = namedtuple("Point", field_names) + + return [Point._make(l) for l in read_points(cloud, field_names, skip_nans, uvs)] + +def create_cloud(header, fields, points): + """ + Create a L{sensor_msgs.msg.PointCloud2} message. + + @param header: The point cloud header. + @type header: L{std_msgs.msg.Header} + @param fields: The point cloud fields. + @type fields: iterable of L{sensor_msgs.msg.PointField} + @param points: The point cloud points. + @type points: list of iterables, i.e. one iterable for each point, with the + elements of each iterable being the values of the fields for + that point (in the same order as the fields parameter) + @return: The point cloud. + @rtype: L{sensor_msgs.msg.PointCloud2} + """ + cloud_struct = struct.Struct(_get_struct_fmt(False, fields)) + + buff = ctypes.create_string_buffer(cloud_struct.size * len(points)) + + point_step, pack_into = cloud_struct.size, cloud_struct.pack_into + offset = 0 + for p in points: + pack_into(buff, offset, *p) + offset += point_step + + return PointCloud2(header=header, + height=1, + width=len(points), + is_dense=False, + is_bigendian=False, + fields=fields, + point_step=cloud_struct.size, + row_step=cloud_struct.size * len(points), + data=buff.raw) + +def create_cloud_xyz32(header, points): + """ + Create a L{sensor_msgs.msg.PointCloud2} message with 3 float32 fields (x, y, z). + + @param header: The point cloud header. + @type header: L{std_msgs.msg.Header} + @param points: The point cloud points. + @type points: iterable + @return: The point cloud. + @rtype: L{sensor_msgs.msg.PointCloud2} + """ + + fields = [PointField(name='x', offset=0, datatype=PointField.FLOAT32, count=1), + PointField(name='y', offset=4, datatype=PointField.FLOAT32, count=1), + PointField(name='z', offset=8, datatype=PointField.FLOAT32, count=1)] + return create_cloud(header, fields, points) + +def _get_struct_fmt(is_bigendian, fields, field_names=None): + fmt = '>' if is_bigendian else '<' + offset = 0 + for field in (f for f in sorted(fields, key=lambda f: f.offset) if field_names is None or f.name in field_names): + if offset < field.offset: + fmt += 'x' * (field.offset - offset) + offset = field.offset + if field.datatype not in _DATATYPES: + print('Skipping unknown PointField datatype [%d]' % field.datatype, file=sys.stderr) + else: + datatype_fmt, datatype_length = _DATATYPES[field.datatype] + fmt += field.count * datatype_fmt + offset += field.count * datatype_length + + return fmt diff --git a/3D_printer/src/printer3d_manager/nodes/printer_control_node.py b/3D_printer/src/printer3d_manager/nodes/printer_control_node.py new file mode 100644 index 0000000..5b450d5 --- /dev/null +++ b/3D_printer/src/printer3d_manager/nodes/printer_control_node.py @@ -0,0 +1,146 @@ +#!/usr/bin/env python3 +import rclpy +from rclpy.action import ActionClient +from rclpy.node import Node + +from printer3d_msgs.srv import ProfileCommand +from printer3d_msgs.srv import GcodeCommand +from printer3d_msgs.srv import ImageCommand +from printer3d_gocator_msgs.srv import GocatorPTCloud + +from utility import * + +from sensor_msgs.msg import PointCloud2 +import point_cloud2 as pc2 +import os + + +class PrinterControlNode(Node): + def __init__(self, historyFilename): + super().__init__('printer_control') + + + """Initialisation of the printing process workspace""" + + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename) + except: + pass + + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/gcode') + except: + pass + + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/scan') + except: + pass + + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/photos') + except: + pass + + # access to the image capture service + + self.client_image_capture = self.create_client(ImageCommand, 'ask_capture_image') + while not self.client_image_capture.wait_for_service(timeout_sec=1.0): + self.get_logger().info('image capture service not available, waiting again...') + self.req_image_capture = ImageCommand.Request() + + # access to the profile measure service + + self.client_profile_measure = self.create_client(GocatorPTCloud, 'gocator_get_profile') + while not self.client_profile_measure.wait_for_service(timeout_sec=1.0): + self.get_logger().info('profile measure service not available, waiting again...') + self.req_profile_measure = GocatorPTCloud.Request() + + # access to the printer driver service + + self.client_printer_driver = self.create_client(GcodeCommand, 'send_gcode') + while not self.client_printer_driver.wait_for_service(timeout_sec=1.0): + self.get_logger().info('profile measure service not available, waiting again...') + self.req_printer_driver = GcodeCommand.Request() + + + def loadGcode(self,gcodeFilename): + fileFullGcode = open(file,'r') + rawGode = fichier.readlines() + fileFullGcode.close() + + (self.xMin,self.yMin,self.zMin,self.xMax,self.yMax,self.zMax) = getBordersGcode(rawGode) + self.gcodeLayers = work_on_gcode_file(gco) + + def scanCurrentLayer(self): + return 0 + + def printCurrentLayer(self): + return 0 + + def takeCurrentLayerPhoto(self): + return 0 + + def sendImageCaptureRequest(self,filename): + + """ Request an image capture using a webcam through the 'ask_image_capture' service """ + + self.req_image_capture.filename = filename + self.future_image_capture = self.client_image_capture.call_async(self.req_image_capture) + while rclpy.ok(): + rclpy.spin_once(self) + if self.future_image_capture.done(): + self.get_logger().info('capture finished') + break + + def sendProfileMeasureRequest(self): + + """ Request a profile measure using a Gocator 2140 profile sensor through the 'gocator_get_profile' service """ + + profile_line = [] + self.future_profile_measure = self.client_profile_measure.call_async(self.req_profile_measure) + while rclpy.ok(): + rclpy.spin_once(self) + if self.future_profile_measure.done(): + try: + self.response = self.future_profile_measure.result() + except Exception as e: + self.get_logger().info('Service call failed %r' % (e,)) + else: + pcloud = self.response.pcloud + self.flag_datas_used = True + + gen = pc2.read_points(pcloud, skip_nans=True) + profile = list(gen) + + for points in profile: + profile_line.append([[points[0],0,points[2]]]) + break + self.get_logger().info('scan finished') + return profile_line + + def sendGcodeSendingRequest(self,gcode): + + """ Request the sending of a certain gcode list tanken as input through the 'send_gcode' service """ + + self.req_printer_driver.gcode_strings = gcode + self.future_printer_driver = self.client_printer_driver.call_async(self.req_printer_driver) + while rclpy.ok(): + rclpy.spin_once(self) + if self.future_printer_driver.done(): + self.get_logger().info('gcode sended') + break + +if __name__ == '__main__': + gcodeExample = ['G28\n','G1 F3000 X10 Y10 Z10\n','G28\n'] + + rclpy.init() + printer_control_node = PrinterControlNode('impression_test') + for i in range(0,10): + printer_control_node.sendImageCaptureRequest('impressions/test/image_test_'+str(i)) + printer_control_node.sendGcodeSendingRequest(gcodeExample) + profile = printer_control_node.sendProfileMeasureRequest() + print(type(profile)) + print(len(profile)) + print(profile) + rclpy.shutdown() \ No newline at end of file diff --git a/3D_printer/src/printer3d_manager/nodes/utility.py b/3D_printer/src/printer3d_manager/nodes/utility.py new file mode 100644 index 0000000..3e9b832 --- /dev/null +++ b/3D_printer/src/printer3d_manager/nodes/utility.py @@ -0,0 +1,61 @@ +def work_on_gcode_file(sequence): + length = len(sequence) + + delimiter = ';LAYER:' + final_delimiter = '; Default end code' + + layers = [[]] + + for line in sequence: + + if (delimiter not in line) and (final_delimiter not in line): + if line[0]!=';': + layers[-1].append(line) + else: + layers.append([]) + return layers + +def getBordersGcode(sequence): + zMax = 0 + xMax = 0 + yMax = 0 + zMin = 2000 + yMin = 2000 + xMin = 2000 + + # remove initialisation + + completeSequence = work_on_gcode_file(sequence) + innerSequence = [] + for i in range(1,len(completeSequence)-1): + innerSequence = innerSequence+completeSequence[i] + + for line in innerSequence: + if 'Z' in line and ';' not in line: + z = line.split('Z')[1] + z = z.split(' ')[0] + z = z.split('\n')[0] + z = float(z) + if z>zMax: + zMax = z + if zyMax: + yMax = y + if yxMax: + xMax = x + if x + + + printer3d_manager + 0.0.0 + TODO: Package description + gulltor + TODO: License declaration + + ament_cmake + + ament_lint_auto + ament_lint_common + + + ament_cmake + + diff --git a/3D_printer/src/printer3d_msgs/CMakeLists.txt b/3D_printer/src/printer3d_msgs/CMakeLists.txt new file mode 100644 index 0000000..627fa5f --- /dev/null +++ b/3D_printer/src/printer3d_msgs/CMakeLists.txt @@ -0,0 +1,47 @@ +cmake_minimum_required(VERSION 3.5) +project(printer3d_msgs) + +# Default to C99 +if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 99) +endif() + +# Default to C++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# find dependencies +find_package(ament_cmake REQUIRED) +# uncomment the following section in order to fill in +# further dependencies manually. +# find_package( REQUIRED) +find_package(ament_cmake REQUIRED) +find_package(builtin_interfaces REQUIRED) +find_package(rosidl_default_generators REQUIRED) +find_package(std_msgs REQUIRED) +find_package(sensor_msgs REQUIRED) + + +if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + # the following line skips the linter which checks for copyrights + # uncomment the line when a copyright and license is not present in all source files + #set(ament_cmake_copyright_FOUND TRUE) + # the following line skips cpplint (only works in a git repo) + # uncomment the line when this package is not in a git repo + #set(ament_cmake_cpplint_FOUND TRUE) + ament_lint_auto_find_test_dependencies() +endif() + +rosidl_generate_interfaces(${PROJECT_NAME} + "srv/ProfileCommand.srv" + "srv/GcodeCommand.srv" + "srv/ImageCommand.srv" + ) + +ament_package() diff --git a/3D_printer/src/printer3d_msgs/package.xml b/3D_printer/src/printer3d_msgs/package.xml new file mode 100644 index 0000000..c98e055 --- /dev/null +++ b/3D_printer/src/printer3d_msgs/package.xml @@ -0,0 +1,19 @@ + + +printer3d_msgs +0.0.0 +Messages form communication with GOCATOR systems +m.bednarczyk +TODO: License declaration +ament_cmake +ament_lint_auto +ament_lint_common +std_msgs +sensor_msgs +builtin_interfaces +rosidl_default_generators +rosidl_interface_packages + +ament_cmake + + \ No newline at end of file diff --git a/3D_printer/src/printer3d_msgs/srv/GcodeCommand.srv b/3D_printer/src/printer3d_msgs/srv/GcodeCommand.srv new file mode 100644 index 0000000..72b6cf5 --- /dev/null +++ b/3D_printer/src/printer3d_msgs/srv/GcodeCommand.srv @@ -0,0 +1,3 @@ +string[] gcode_strings +--- +bool validation \ No newline at end of file diff --git a/3D_printer/src/printer3d_msgs/srv/ImageCommand.srv b/3D_printer/src/printer3d_msgs/srv/ImageCommand.srv new file mode 100644 index 0000000..65ce60f --- /dev/null +++ b/3D_printer/src/printer3d_msgs/srv/ImageCommand.srv @@ -0,0 +1,3 @@ +string filename +--- +bool confirmation \ No newline at end of file diff --git a/3D_printer/src/printer3d_msgs/srv/ProfileCommand.srv b/3D_printer/src/printer3d_msgs/srv/ProfileCommand.srv new file mode 100644 index 0000000..dd07f00 --- /dev/null +++ b/3D_printer/src/printer3d_msgs/srv/ProfileCommand.srv @@ -0,0 +1,6 @@ +float64 y_min +float64 y_max +float64 z_upper +float64 step +--- +bool validation \ No newline at end of file From 66759543a3a35d78cdc15dda0bcdfc5b8f18d53f Mon Sep 17 00:00:00 2001 From: Mosserl Date: Tue, 4 Apr 2023 18:37:51 +0200 Subject: [PATCH 08/30] I've found how to add the right filepath in the gitignore for the external gocator sdk. Thus I can save the printer3d_profile_capture package --- .gitignore | 3 +- .../nodes/printer_control_node.py | 6 +- .../printer3d_profile_capture/CMakeLists.txt | 120 +++++ .../src/printer3d_profile_capture/package.xml | 22 + .../src/driver/CMakeLists.txt | 65 +++ .../src/driver/gocatorSensor.cpp | 424 ++++++++++++++++++ .../src/driver/gocatorSensor.h | 187 ++++++++ .../src/nodes/gocatorSensorNode.cpp | 64 +++ 8 files changed, 886 insertions(+), 5 deletions(-) create mode 100644 3D_printer/src/printer3d_profile_capture/CMakeLists.txt create mode 100644 3D_printer/src/printer3d_profile_capture/package.xml create mode 100644 3D_printer/src/printer3d_profile_capture/src/driver/CMakeLists.txt create mode 100644 3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp create mode 100644 3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.h create mode 100644 3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp diff --git a/.gitignore b/.gitignore index 915d803..c9597fe 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ install/ .vscode/ 3D_Printer/build 3D_Printer/install -3D_Printer/log \ No newline at end of file +3D_Printer/log +3D_printer/src/printer3d_profile_capture/external \ No newline at end of file diff --git a/3D_printer/src/printer3d_manager/nodes/printer_control_node.py b/3D_printer/src/printer3d_manager/nodes/printer_control_node.py index 5b450d5..bf0cc58 100644 --- a/3D_printer/src/printer3d_manager/nodes/printer_control_node.py +++ b/3D_printer/src/printer3d_manager/nodes/printer_control_node.py @@ -122,7 +122,7 @@ def sendProfileMeasureRequest(self): def sendGcodeSendingRequest(self,gcode): """ Request the sending of a certain gcode list tanken as input through the 'send_gcode' service """ - + self.req_printer_driver.gcode_strings = gcode self.future_printer_driver = self.client_printer_driver.call_async(self.req_printer_driver) while rclpy.ok(): @@ -140,7 +140,5 @@ def sendGcodeSendingRequest(self,gcode): printer_control_node.sendImageCaptureRequest('impressions/test/image_test_'+str(i)) printer_control_node.sendGcodeSendingRequest(gcodeExample) profile = printer_control_node.sendProfileMeasureRequest() - print(type(profile)) - print(len(profile)) - print(profile) + rclpy.shutdown() \ No newline at end of file diff --git a/3D_printer/src/printer3d_profile_capture/CMakeLists.txt b/3D_printer/src/printer3d_profile_capture/CMakeLists.txt new file mode 100644 index 0000000..6cc5cfb --- /dev/null +++ b/3D_printer/src/printer3d_profile_capture/CMakeLists.txt @@ -0,0 +1,120 @@ +cmake_minimum_required(VERSION 3.5) +project(printer3d_profile_capture) + +# Default to C99 +if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 99) +endif() + +# Default to C++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# find dependencies +find_package(ament_cmake REQUIRED) +find_package(rclcpp REQUIRED) +# find_package(rclpy REQUIRED) +find_package(std_msgs REQUIRED) +find_package(sensor_msgs REQUIRED) +find_package(rosidl_default_generators REQUIRED) +find_package(printer3d_gocator_msgs REQUIRED) +find_package(pcl_conversions REQUIRED) + +# Find point cloud Library +FIND_PACKAGE(PCL REQUIRED COMPONENTS) +INCLUDE_DIRECTORIES(${PCL_INCLUDE_DIRS}) +LINK_DIRECTORIES(${PCL_LIBRARY_DIRS}) +ADD_DEFINITIONS(${PCL_DEFINITIONS}) + +# Set GO_SDK include paths (That could be part of a FindGocator.cmake) +SET(GO_SDK_4 ${CMAKE_CURRENT_SOURCE_DIR}/external/GO_SDK) +FIND_PATH( + GOCATOR_INCLUDES + NAMES GoSdk/GoSdk.h + PATHS ${GO_SDK_4}/Gocator/GoSdk) +FIND_PATH( + KAPI_INCLUDES + NAMES kApi/kApi.h + PATHS ${GO_SDK_4}/Platform/kApi) +INCLUDE_DIRECTORIES(${GOCATOR_INCLUDES} ${KAPI_INCLUDES}) + +# Set GO_SDK libs (That could be part of a FindGocator.cmake) +FIND_LIBRARY( + GOCATOR_LIBRARIES + NAMES GoSdk + PATHS ${GO_SDK_4}/lib/linux_x64d) +FIND_LIBRARY( + KAPI_LIBRARIES + NAMES kApi + PATHS ${GO_SDK_4}/lib/linux_x64d) + +# Set source files +SET(LIB_SRCS + src/driver/gocatorSensor.cpp) + +# Set header files +SET(LIB_HDRS + src/driver/gocatorSensor.h) + +INCLUDE_DIRECTORIES(${LIB_HDRS}) + +# Install the python module for this package +# ament_python_install_package(script/) +# ament_python_install_package(nodes/) + + + +################################################################################ +# Declare ROS messages, services and actions +################################################################################ + +add_executable( gocator_sensor_node src/nodes/gocatorSensorNode.cpp ${LIB_HDRS} ${LIB_SRCS} ) +target_link_libraries (gocator_sensor_node ${GOCATOR_LIBRARIES} ${KAPI_LIBRARIES} ${Boost_SYSTEM_LIBRARY}) + +ament_target_dependencies(gocator_sensor_node rclcpp sensor_msgs std_msgs printer3d_gocator_msgs pcl_conversions) + + +# Install C++ headers +#install( +# DIRECTORY ${PROJECT_NAME}/include +# ${LIB_DIR}/include +# DESTINATION include/${PROJECT_NAME} +# FILES_MATCHING PATTERN "*.hpp" +#) + +install(TARGETS + gocator_sensor_node + DESTINATION lib/${PROJECT_NAME}) + +if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + # the following line skips the linter which checks for copyrights + # uncomment the line when a copyright and license is not present in all source files + #set(ament_cmake_copyright_FOUND TRUE) + # the following line skips cpplint (only works in a git repo) + # uncomment the line when this package is not in a git repo + #set(ament_cmake_cpplint_FOUND TRUE) + ament_lint_auto_find_test_dependencies() +endif() + + +# Install python scripts +# install( +# DIRECTORY external/GO_SDK/lib/linux_x64d/ #launch param script +# DESTINATION share/${PROJECT_NAME}/external/GO_SDK/lib/linux_x64d/ +# ) + +# install( +# PROGRAMS +# script/tcpSocket.py +# script/udpSocket.py +# nodes/iiwa_command_node.py +# DESTINATION lib/${PROJECT_NAME} +# ) + +ament_package() diff --git a/3D_printer/src/printer3d_profile_capture/package.xml b/3D_printer/src/printer3d_profile_capture/package.xml new file mode 100644 index 0000000..c245a19 --- /dev/null +++ b/3D_printer/src/printer3d_profile_capture/package.xml @@ -0,0 +1,22 @@ + + +printer3d_profile_capture +0.0.0 +Messages form communication with GOCATOR systems +m.bednarczyk +TODO: License declaration +ament_cmake +ament_lint_auto +ament_lint_common +std_msgs +sensor_msgs +printer3d_gocator_msgs + +builtin_interfaces +pcl_conversions +rosidl_default_generators +rosidl_interface_packages + +ament_cmake + + \ No newline at end of file diff --git a/3D_printer/src/printer3d_profile_capture/src/driver/CMakeLists.txt b/3D_printer/src/printer3d_profile_capture/src/driver/CMakeLists.txt new file mode 100644 index 0000000..c32dfc2 --- /dev/null +++ b/3D_printer/src/printer3d_profile_capture/src/driver/CMakeLists.txt @@ -0,0 +1,65 @@ +# Pre-requisites about cmake itself +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) + +# Project name and the type of project +PROJECT(gocatorSensor) + +# DEBUG/RELEASE +IF (NOT CMAKE_BUILD_TYPE) + SET(CMAKE_BUILD_TYPE "RELEASE") +ENDIF (NOT CMAKE_BUILD_TYPE) + +# Default to C99 +if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 99) +endif() + +# Default to C++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# Find point cloud Library +FIND_PACKAGE(PCL REQUIRED COMPONENTS) +INCLUDE_DIRECTORIES(${PCL_INCLUDE_DIRS}) +LINK_DIRECTORIES(${PCL_LIBRARY_DIRS}) +ADD_DEFINITIONS(${PCL_DEFINITIONS}) + +# Set GO_SDK include paths (That could be part of a FindGocator.cmake) +SET(GO_SDK_4 ${CMAKE_CURRENT_SOURCE_DIR}/../../external/GO_SDK) +FIND_PATH( + GOCATOR_INCLUDES + NAMES GoSdk/GoSdk.h + PATHS ${GO_SDK_4}/Gocator/GoSdk) +FIND_PATH( + KAPI_INCLUDES + NAMES kApi/kApi.h + PATHS ${GO_SDK_4}/Platform/kApi) +INCLUDE_DIRECTORIES(${GOCATOR_INCLUDES} ${KAPI_INCLUDES}) + +# Set GO_SDK libs (That could be part of a FindGocator.cmake) +FIND_LIBRARY( + GOCATOR_LIBRARIES + NAMES GoSdk + PATHS ${GO_SDK_4}/lib/linux_x64d/) +FIND_LIBRARY( + KAPI_LIBRARIES + NAMES kApi + PATHS ${GO_SDK_4}/lib/linux_x64d/) + +# Set source files +SET(SRCS + gocatorSensor.cpp) + +# Set header files +SET(HDRS + gocatorSensor.h) + +#Build library +ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${GOCATOR_LIBRARIES} ${KAPI_LIBRARIES} ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES}) + diff --git a/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp b/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp new file mode 100644 index 0000000..f633b1c --- /dev/null +++ b/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp @@ -0,0 +1,424 @@ +#include "gocatorSensor.h" + +GocatorSensor::Device::Device(const std::string & _ip_address) +{ + kStatus status; + kIpAddress ipAddress; + kChar model_name[50]; + + //init all GO API objects + go_api_ = kNULL; + go_system_ = kNULL; + go_sensor_ = kNULL; + go_setup_ = kNULL; + go_dataset_ = kNULL; + go_stamp_ptr_ = kNULL; + + // construct Gocator API Library + if ((status = GoSdk_Construct(&go_api_)) != kOK) + { + std::cout << "Device(). Error: GoSdk_Construct: " << status << std::endl; + status_ = DEVICE_NOT_FOUND; + return; + } + + // construct GoSystem object + if ((status = GoSystem_Construct(&go_system_, kNULL)) != kOK) + { + std::cout << "Device(). Error: GoSystem_Construct: " << status << std::endl; + status_ = DEVICE_NOT_FOUND; + return; + } + + // obtain GoSensor object by sensor IP address + kIpAddress_Parse(&ipAddress, _ip_address.c_str()); + if ((status = GoSystem_FindSensorByIpAddress(go_system_, &ipAddress, &go_sensor_)) != kOK) + { + std::cout << "Device(). Error: GoSystem_FindSensorByIpAddress: " << status << std::endl; + status_ = DEVICE_NOT_FOUND; + return; + } + + //Success case. Set status and device fixed params (ip, model name and serial number ). + status_ = DEVICE_FOUND; + device_params_.ip_address_ = _ip_address; + + // create connection to GoSensor object + if ((status = GoSensor_Connect(go_sensor_)) != kOK) + { + std::cout << "Device(). Error: GoSensor_Connect: " << status << std::endl; + status_ = DEVICE_NOT_CONNECT; + return; + } + status_ = DEVICE_CONNECT; + + // enable sensor data channel + if ((status = GoSystem_EnableData(go_system_, kTRUE)) != kOK) + { + std::cout << "Device(). Error: GoSensor_EnableData: " << status << std::endl; + return; + } + + // retrieve setup handle + if ((go_setup_ = GoSensor_Setup(go_sensor_)) == kNULL) + { + std::cout << "Device(). Error: GoSensor_Setup: Invalid Handle" << std::endl; + return; + } + + //Obtain camera model + if ((status = GoSensor_Model(go_sensor_, model_name, 50)) != kOK ) + { + std::cout << "Device(). Error: GoSensor_Model: " << status << std::endl; + return; + } + device_params_.model_name_ = model_name; + + //Obtain camera Serial number + device_params_.sn_ = (unsigned int)GoSensor_Id(go_sensor_); + + //Obtain exposure + capture_params_.exposure_time_ = GoSetup_Exposure(go_setup_, GO_ROLE_MAIN); + + //Obtain spacing interval + capture_params_.spacing_interval_ = GoSetup_SpacingInterval(go_setup_, GO_ROLE_MAIN); + + //print info + std::cout << "Found Sensor: " << std::endl; + device_params_.print(); +} + +GocatorSensor::Device::~Device() +{ + kStatus status; + + // destroy handles + GoDestroy(go_system_); + GoDestroy(go_api_); + + //bye bye message + std::cout << "~Device(). Gocator Sensor Stopped and Device Object Destroyed." << std::endl; +} + +int GocatorSensor::Device::configure(const CaptureParams & _configs) +{ + kStatus status; + + //set exposure + if ((status = GoSetup_SetExposure(go_setup_, GO_ROLE_MAIN, _configs.exposure_time_)) != kOK ) + { + std::cout << "configure(): Error setting Exposure Time to " << _configs.exposure_time_ << std::endl; + return -1; + } + + //set spacing interval + if ((status = GoSetup_SetSpacingInterval(go_setup_, GO_ROLE_MAIN, _configs.spacing_interval_)) != kOK ) + { + std::cout << "configure(): Error setting Spacing Interval to " << _configs.spacing_interval_ << std::endl; + return -1; + } + + //set this->capture_params_ with true values from camera + capture_params_.exposure_time_ = GoSetup_Exposure(go_setup_, GO_ROLE_MAIN); + capture_params_.spacing_interval_ = GoSetup_SpacingInterval(go_setup_, GO_ROLE_MAIN); + + //print + std::cout << "Configuration Setings: " << std::endl; + capture_params_.print(); + + //return + return 1; +} + +int GocatorSensor::Device::start() +{ + kStatus status; + + // start Gocator sensor + if ((status = GoSystem_Start(go_system_)) != kOK) + { + std::cout << "Device(). Error: GoSystem_Start: " << status << std::endl; + return -1; + } + + //message to std out + //std::cout << "Gocator running ... " << std::endl; + + //set this->status_ + this->status_ = DEVICE_RUNNING; + + //return success + return 1; +} + +int GocatorSensor::Device::stop() +{ + kStatus status; + + // stop Gocator sensor + if ((status = GoSystem_Stop(go_system_)) != kOK) + { + std::cout << "~Device(). Error: GoSystem_Stop: " << status << std::endl; + return -1; + } + + //message to std out + //std::cout << "... Gocator stopped" << std::endl << std::endl; + + //set this->status_ + this->status_ = DEVICE_CONNECT; + + //return success + return 1; +} + +int GocatorSensor::Device::getCurrentSnapshot(pcl::PointCloud & _p_cloud) +{ + +} + +int GocatorSensor::Device::getSingleSnapshot(pcl::PointCloud & _p_cloud) +{ + +} + +int GocatorSensor::Device::getProfile(pcl::PointCloud & _p_cloud) +{ + unsigned int i, j, k, arrayIndex; + GoDataSet dataset = kNULL; + std::vector profileBuffer; + GoStamp *stamp =kNULL; + GoDataMsg dataObj; + k32u profilePointCount; + if (GoSystem_ReceiveData(go_system_, &dataset, RECEIVE_TIMEOUT) == kOK) + { + printf("Data message received:\n"); + printf("Dataset count: %u\n", (k32u)GoDataSet_Count(dataset)); + // each result can have multiple data items + // loop through all items in result message + for (i = 0; i < GoDataSet_Count(dataset); ++i) + { + dataObj = GoDataSet_At(dataset, i); + //Retrieve GoStamp message + switch(GoDataMsg_Type(dataObj)) + { + case GO_DATA_MESSAGE_TYPE_STAMP: + { + GoStampMsg stampMsg = dataObj; + + printf("Stamp Message batch count: %u\n", (k32u)GoStampMsg_Count(stampMsg)); + for (j = 0; j < GoStampMsg_Count(stampMsg); ++j) + { + stamp = GoStampMsg_At(stampMsg, j); + printf(" Timestamp: %llu\n", stamp->timestamp); + printf(" Encoder: %lld\n", stamp->encoder); + printf(" Frame index: %llu\n", stamp->frameIndex); + } + } + break; + case GO_DATA_MESSAGE_TYPE_UNIFORM_PROFILE: + { + GoResampledProfileMsg profileMsg = dataObj; + + printf("Resampled Profile Message batch count: %u\n", (k32u)GoResampledProfileMsg_Count(profileMsg)); + + _p_cloud.height = GoResampledProfileMsg_Count(profileMsg); + _p_cloud.width = GoResampledProfileMsg_Width(profileMsg); + _p_cloud.resize(_p_cloud.height*_p_cloud.width); + + for (k = 0; k < GoResampledProfileMsg_Count(profileMsg); ++k) + { + unsigned int validPointCount = 0; + short* data = GoResampledProfileMsg_At(profileMsg, k); + double XResolution = NM_TO_MM(GoResampledProfileMsg_XResolution(profileMsg)); + double ZResolution = NM_TO_MM(GoResampledProfileMsg_ZResolution(profileMsg)); + double XOffset = UM_TO_MM(GoResampledProfileMsg_XOffset(profileMsg)); + double ZOffset = UM_TO_MM(GoResampledProfileMsg_ZOffset(profileMsg)); + + // profileBuffer.resize(GoResampledProfileMsg_Width(profileMsg)); + + + // translate 16-bit range data to engineering units and copy profiles to memory array + for (arrayIndex = 0; arrayIndex < GoResampledProfileMsg_Width(profileMsg); ++arrayIndex) + { + + if (data[arrayIndex] != INVALID_RANGE_16BIT ) + { + // profileBuffer[arrayIndex].x = XOffset + XResolution * arrayIndex; + // profileBuffer[arrayIndex].z = ZOffset + ZResolution * data[arrayIndex]; + _p_cloud.points.at(k*_p_cloud.width+arrayIndex).x = XOffset + XResolution * arrayIndex; + _p_cloud.points.at(k*_p_cloud.width+arrayIndex).z = ZOffset + ZResolution * data[arrayIndex]; + validPointCount++; + } + else + { + // profileBuffer[arrayIndex].x = XOffset + XResolution * arrayIndex; + // profileBuffer[arrayIndex].z = INVALID_RANGE_DOUBLE; + _p_cloud.points.at(k*_p_cloud.width+arrayIndex).x = XOffset + XResolution * arrayIndex; + _p_cloud.points.at(k*_p_cloud.width+arrayIndex).z = INVALID_RANGE_DOUBLE; + } + + + } + + printf(" Profile Valid Point %d out of max %d\n", validPointCount, profilePointCount); + } + } + break; + case GO_DATA_MESSAGE_TYPE_PROFILE_POINT_CLOUD: // Note this is NON resampled profile + { + GoProfileMsg profileMsg = dataObj; + + printf("Profile Message batch count: %u\n", (k32u)GoProfileMsg_Count(profileMsg)); + + _p_cloud.height = GoProfileMsg_Count(profileMsg); + _p_cloud.width = GoProfileMsg_Width(profileMsg); + _p_cloud.resize(_p_cloud.height*_p_cloud.width); + + for (k = 0; k < GoProfileMsg_Count(profileMsg); ++k) + { + kPoint16s* data = GoProfileMsg_At(profileMsg, k); + unsigned int validPointCount = 0; + double XResolution = NM_TO_MM(GoProfileMsg_XResolution(profileMsg)); + double ZResolution = NM_TO_MM(GoProfileMsg_ZResolution(profileMsg)); + double XOffset = UM_TO_MM(GoProfileMsg_XOffset(profileMsg)); + double ZOffset = UM_TO_MM(GoProfileMsg_ZOffset(profileMsg)); + + // profileBuffer.resize(GoResampledProfileMsg_Width(profileMsg)); + + //translate 16-bit range data to engineering units and copy profiles to memory array + for (arrayIndex = 0; arrayIndex < GoProfileMsg_Width(profileMsg); ++arrayIndex) + { + if (data[arrayIndex].x != INVALID_RANGE_16BIT) + { + // profileBuffer[arrayIndex].x = XOffset + XResolution * data[arrayIndex].x; + // profileBuffer[arrayIndex].z = ZOffset + ZResolution * data[arrayIndex].y; + _p_cloud.points.at(k*_p_cloud.width+arrayIndex).x = XOffset + XResolution * data[arrayIndex].x; + _p_cloud.points.at(k*_p_cloud.width+arrayIndex).z = ZOffset + ZResolution * data[arrayIndex].y; + validPointCount++; + } + else + { + // profileBuffer[arrayIndex].x = INVALID_RANGE_DOUBLE; + // profileBuffer[arrayIndex].z = INVALID_RANGE_DOUBLE; + _p_cloud.points.at(k*_p_cloud.width+arrayIndex).x = INVALID_RANGE_DOUBLE; + _p_cloud.points.at(k*_p_cloud.width+arrayIndex).z = INVALID_RANGE_DOUBLE; + } + } + printf(" Profile Valid Point %d out of max %d\n", validPointCount, profilePointCount); + } + } + break; + case GO_DATA_MESSAGE_TYPE_PROFILE_INTENSITY: + { + unsigned int validPointCount = 0; + GoProfileIntensityMsg intensityMsg = dataObj; + printf("Intensity Message batch count: %u\n", (k32u)GoProfileIntensityMsg_Count(intensityMsg)); + + profileBuffer.resize(GoProfileIntensityMsg_Count(intensityMsg)); + + for (k = 0; k < GoProfileIntensityMsg_Count(intensityMsg); ++k) + { + unsigned char* data = GoProfileIntensityMsg_At(intensityMsg, k); + for (arrayIndex = 0; arrayIndex < GoProfileIntensityMsg_Width(intensityMsg); ++arrayIndex) + { + profileBuffer[arrayIndex].intensity = data[arrayIndex]; + } + } + } + break; + } + } + GoDestroy(dataset); + } + else + { + printf ("Error: No data received during the waiting period\n"); + } + return 1; +} + +void GocatorSensor::Device::getDeviceHealth(std::string & _health_str) const +{ + //local variables + GoDataSet health_data = kNULL; + GoHealthMsg health_msg =kNULL; + GoIndicator *health_indicator = kNULL; + std::ostringstream sstr; + + //get health from device + if ( (GoSystem_ReceiveHealth(go_system_, &health_data, RECEIVE_TIMEOUT)) == kOK ) + { + for (unsigned int ii = 0; ii < GoDataSet_Count(health_data); ii++) + { + health_msg = GoDataSet_At(health_data, ii); + for (unsigned int jj = 0; jj < GoHealthMsg_Count(health_msg); jj++) + { + health_indicator = GoHealthMsg_At(health_msg, jj); + sstr << "Indicator[" << jj << "]:\n" + << "\tId: " << health_indicator->id << "\n" + << "\tInstance: " << health_indicator->instance << "\n" + << "\tValue: " << health_indicator->value << "\n"; + } + } + GoDestroy(health_msg); + } + + _health_str = sstr.str(); +} + +void GocatorSensor::Device::getTemperature(double & _internal_temp, double & _projector_temp, double & _laser_temp) const +{ + //local variables + GoDataSet health_data = kNULL; + GoHealthMsg health_msg =kNULL; + GoIndicator *health_indicator = kNULL; + //k32u instance; + + //get health dataset from device + if ( (GoSystem_ReceiveHealth(go_system_, &health_data, RECEIVE_TIMEOUT)) == kOK ) + { + for (unsigned int ii = 0; ii < GoDataSet_Count(health_data); ii++) + { + //get the health message + health_msg = GoDataSet_At(health_data, ii); + + //find in the message the internal temperature indicator, and set the value + health_indicator = GoHealthMsg_Find(health_msg, GO_HEALTH_TEMPERATURE, 0); + if (health_indicator != kNULL) _internal_temp = health_indicator->value; + else _internal_temp = -100.; + + //find in the message the projector temperature indicator, and set the value + health_indicator = GoHealthMsg_Find(health_msg, GO_HEALTH_PROJECTOR_TEMPERATURE, 0); + if (health_indicator != kNULL) _projector_temp = health_indicator->value; + else _projector_temp = -100.; + + //find in the message the projector temperature indicator, and set the value + health_indicator = GoHealthMsg_Find(health_msg, GO_HEALTH_LASER_TEMPERATURE, 0); + if (health_indicator != kNULL) _laser_temp = health_indicator->value; + else _laser_temp = -100.; + } + GoDestroy(health_msg); + } + +} + +int GocatorSensor::Device::close() +{ + +} + +void GocatorSensor::Device::printDeviceData() const +{ + +} + +void GocatorSensor::Device::sendTrigger() const { + printf("sending trigger \n"); + kStatus status = GoSensor_Trigger(go_sensor_); + if (status != kOK) + { + printf("Error: GoSensor_Connect:%d\n", status); + return; + } +} diff --git a/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.h b/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.h new file mode 100644 index 0000000..d7fda34 --- /dev/null +++ b/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.h @@ -0,0 +1,187 @@ +#ifndef GocatorSensor_H +#define GocatorSensor_H + +//std c/c++ +#include +#include +#include +#include + +//GoSdk +#include + +//PCL +#include +#include + +//constants +#define SENSOR_IP "192.168.1.10" // sensor IP address +#define RECEIVE_TIMEOUT 20000000 // timeout for snapshot acquisition +#define INVALID_RANGE_16BIT ((signed short)0x8000) // gocator transmits range data as 16-bit signed integers. 0x8000 signifies invalid range data. +#define DOUBLE_MAX ((k64f)1.7976931348623157e+308) // 64-bit double - largest positive value. +#define INVALID_RANGE_DOUBLE ((k64f)-DOUBLE_MAX) // floating point value to represent invalid range data. +#define NM_TO_MM(VALUE) (((k64f)(VALUE))/1000000.0) +#define UM_TO_MM(VALUE) (((k64f)(VALUE))/1000.0) + +namespace GocatorSensor +{ + +typedef struct ProfilePoint +{ + double x; // x-coordinate in engineering units (mm) - position along laser line + double z; // z-coordinate in engineering units (mm) - height (at the given x position) + unsigned char intensity; +} ProfilePoint; + +//status values +enum {DEVICE_NOT_FOUND=0,DEVICE_FOUND,DEVICE_NOT_CONNECT,DEVICE_CONNECT,DEVICE_RUNNING}; + +//device parameters struct +struct DeviceParams +{ + std::string ip_address_; + std::string model_name_; + unsigned int sn_; + + void print() const + { + std::cout << "\tIP ad: \t" << ip_address_ << std::endl; + std::cout << "\tModel: \t" << model_name_ << std::endl; + std::cout << "\tSN: \t" << sn_ << std::endl; + } +}; + +//device configuration struct +struct CaptureParams +{ + double exposure_time_; //in useconds + double spacing_interval_; //in millimeters + + void print() const + { + std::cout << "\texposure [us]: \t" << exposure_time_ << std::endl; + std::cout << "\tspacing [mm]: \t" << spacing_interval_ << std::endl; + } +}; + +//Device class +class Device +{ +protected: + //current point cloud. Maybe not necessary to be here! + //pcl::PointCloud::Ptr p_cloud_; //p_cloud_ = new pcl::PointCloud + + //driver status + unsigned int status_; + + //device fixed params + DeviceParams device_params_; + + //device configuration + CaptureParams capture_params_; + + //GO API objects + kAssembly go_api_; + GoSystem go_system_; + GoSensor go_sensor_; + GoSetup go_setup_; + GoDataSet go_dataset_; + GoStamp *go_stamp_ptr_; + +public: + /** \brief Constructor + * + * Constructor. Sets params_ struct. + * + **/ + Device(const std::string & _ip_address); + + /** \brief Destructor + * + * Destructor + * + **/ + ~Device(); + + /** \brief Connect to a pysical device given an ip address + * + * Connect to a pysical device given an ip address + * + **/ +// int connect(); + + /** \brief Set/get device parameters to/from the camera + * + * Set/get device parameters to/from the camera + * + **/ + int configure(const CaptureParams & _configs); + + /** \brief Start device data acquisition + * + * Start device data acquisition + * + **/ + int start(); + + /** \brief Stop device dat acquisition + * + * Stop device data acquisition + * + **/ + int stop(); + + /** \brief Get the current snapshot + * + * Get the current snapshot, when in continuous acquisition + * + **/ + int getCurrentSnapshot(pcl::PointCloud & _p_cloud); + + /** \brief Get a single snapshot in the same thread + * + * Get a single snapshot in the same thread + * + **/ + int getSingleSnapshot(pcl::PointCloud & _p_cloud); + + int getProfile(pcl::PointCloud & _p_cloud); + + + /** \brief Returns all health data as a string + * + * Returns all health data as a string + * + **/ + void getDeviceHealth(std::string & _health_str) const; + + /** \brief Returns three device temperatures + * + * Returns three device temperatures: internal, projector and laser + * + **/ + void getTemperature(double & _internal_temp, double & _projector_temp, double & _laser_temp) const; + + /** \brief Close the connection to a physical device + * + * Close the connection to a physical device + * + **/ + int close(); + + /** \brief Print the device configuration + * + * Print the device configuration + * + **/ + void printDeviceData() const; + + /** \brief Send a trigger signal + * + **/ + void sendTrigger() const; +};//close class +}//close namespace + +#endif + diff --git a/3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp b/3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp new file mode 100644 index 0000000..d459e9f --- /dev/null +++ b/3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp @@ -0,0 +1,64 @@ +#include +#include +#include +#include + +#include "rclcpp/rclcpp.hpp" +#include "pcl_conversions/pcl_conversions.h" +#include "std_msgs/msg/empty.hpp" +#include "printer3d_gocator_msgs/srv/gocator_pt_cloud.hpp" +#include "../driver/gocatorSensor.h" + + +using namespace std::chrono_literals; + +class GocatorSensorNode : public rclcpp::Node +{ + public: + GocatorSensorNode() + : Node("gocatorSensorNode") + { + gsensor_ = new GocatorSensor::Device(SENSOR_IP); + capture_params_.exposure_time_ = 40000; + capture_params_.spacing_interval_ = 0.1; + gsensor_->configure(capture_params_); + + service_ = this->create_service("gocator_get_profile", std::bind(&GocatorSensorNode::profile_snapshot, this, std::placeholders::_1, std::placeholders::_2)); + // publisher_ = this->create_publisher("gocatorPTCloud_topic", 10); + } + + private: + void profile_snapshot(std::shared_ptr request, + std::shared_ptr response) + { + pcl::PointCloud cloud; + RCLCPP_INFO(this->get_logger(),"Processing service request!"); + gsensor_->start(); + gsensor_->sendTrigger(); + if ( gsensor_->getProfile(cloud) == 1 ) + { + auto pcloud = sensor_msgs::msg::PointCloud2(); + pcl::toROSMsg(cloud,pcloud); + pcloud.header.frame_id = "gocator_sensor"; + pcloud.header.stamp = this->get_clock()->now(); + + // publisher_->publish(pcloud); + + response->pcloud = pcloud; + } + + } + + rclcpp::Service::SharedPtr service_; + rclcpp::Publisher::SharedPtr publisher_; + GocatorSensor::Device *gsensor_; + GocatorSensor::CaptureParams capture_params_; +}; + +int main(int argc, char * argv[]) +{ + rclcpp::init(argc, argv); + rclcpp::spin(std::make_shared()); + rclcpp::shutdown(); + return 0; +} \ No newline at end of file From f72c716c6de144da0a1ae49bf523913735996c1e Mon Sep 17 00:00:00 2001 From: Mosserl Date: Fri, 14 Apr 2023 17:54:37 +0200 Subject: [PATCH 09/30] base before precommit --- .../nodes/image_capture_node.py | 12 +- .../src/printer3d_manager/CMakeLists.txt | 1 + .../nodes/printer3d_constant.py | 14 +++ .../nodes/printer_control_node.py | 110 +++++++++++++++--- .../src/printer3d_manager/nodes/utility.py | 38 ++++++ 5 files changed, 151 insertions(+), 24 deletions(-) create mode 100644 3D_printer/src/printer3d_manager/nodes/printer3d_constant.py diff --git a/3D_printer/src/printer3d_image_capture/nodes/image_capture_node.py b/3D_printer/src/printer3d_image_capture/nodes/image_capture_node.py index 312fbef..980651b 100644 --- a/3D_printer/src/printer3d_image_capture/nodes/image_capture_node.py +++ b/3D_printer/src/printer3d_image_capture/nodes/image_capture_node.py @@ -13,22 +13,24 @@ class ImageCaptureNode(Node): def __init__(self,cameraNumber = 0): super().__init__('printer_image_capture') - self.webcam = cv2.VideoCapture("/dev/video"+str(cameraNumber)) # Be carefull with the number after video + self.cameraNumber = cameraNumber self.imageService = self.create_service(ImageCommand, 'ask_capture_image', self.takePicture) def __del__(self): self.webcam.release() def takePicture(self, request, response): - check, frame = self.webcam.read() - cv2.imwrite(filename='/home/gulltor/Ramsai_Robotics/'+request.filename+'.jpg', img=frame) - self.get_logger().info('image acquired : /home/gulltor/Ramsai_Robotics/'+request.filename+'.jpg') + webcam = cv2.VideoCapture("/dev/video"+str(self.cameraNumber)) # Be carefull with the number after video + check, frame = webcam.read() + webcam.release() + cv2.imwrite(filename=request.filename, img=frame) + self.get_logger().info('image acquired : '+request.filename) response.confirmation = True return response if __name__ == '__main__': rclpy.init() - image_capture_node = ImageCaptureNode(0) + image_capture_node = ImageCaptureNode(2) rclpy.spin(image_capture_node) rclpy.shutdown() \ No newline at end of file diff --git a/3D_printer/src/printer3d_manager/CMakeLists.txt b/3D_printer/src/printer3d_manager/CMakeLists.txt index 4b476f1..f8fde58 100644 --- a/3D_printer/src/printer3d_manager/CMakeLists.txt +++ b/3D_printer/src/printer3d_manager/CMakeLists.txt @@ -39,6 +39,7 @@ endif() install( PROGRAMS nodes/printer_control_node.py + nodes/printer3d_constant.py nodes/utility.py nodes/point_cloud2.py DESTINATION lib/${PROJECT_NAME} diff --git a/3D_printer/src/printer3d_manager/nodes/printer3d_constant.py b/3D_printer/src/printer3d_manager/nodes/printer3d_constant.py new file mode 100644 index 0000000..61b21c1 --- /dev/null +++ b/3D_printer/src/printer3d_manager/nodes/printer3d_constant.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python3 + +XMIN = 0 +XMAX = 190 + +YMIN = 0 +YMAX = 219 + +ZMIN = 0 +ZMAX = 60 + +GAP = 26 + +YPOSPHOTO = 200 \ No newline at end of file diff --git a/3D_printer/src/printer3d_manager/nodes/printer_control_node.py b/3D_printer/src/printer3d_manager/nodes/printer_control_node.py index bf0cc58..6c01055 100644 --- a/3D_printer/src/printer3d_manager/nodes/printer_control_node.py +++ b/3D_printer/src/printer3d_manager/nodes/printer_control_node.py @@ -2,26 +2,25 @@ import rclpy from rclpy.action import ActionClient from rclpy.node import Node - from printer3d_msgs.srv import ProfileCommand from printer3d_msgs.srv import GcodeCommand from printer3d_msgs.srv import ImageCommand from printer3d_gocator_msgs.srv import GocatorPTCloud - from utility import * - +import printer3d_constant from sensor_msgs.msg import PointCloud2 import point_cloud2 as pc2 import os +import numpy as np + class PrinterControlNode(Node): def __init__(self, historyFilename): super().__init__('printer_control') - """Initialisation of the printing process workspace""" - + self.historyFilename = historyFilename try: os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename) except: @@ -63,22 +62,92 @@ def __init__(self, historyFilename): self.get_logger().info('profile measure service not available, waiting again...') self.req_printer_driver = GcodeCommand.Request() + self.imageNumber = 0 + self.scanNumber = 0 + def loadGcode(self,gcodeFilename): - fileFullGcode = open(file,'r') - rawGode = fichier.readlines() + fileFullGcode = open(gcodeFilename,'r') + rawGode = fileFullGcode.readlines() fileFullGcode.close() (self.xMin,self.yMin,self.zMin,self.xMax,self.yMax,self.zMax) = getBordersGcode(rawGode) - self.gcodeLayers = work_on_gcode_file(gco) - - def scanCurrentLayer(self): - return 0 + self.get_logger().info('xMin : '+str(self.xMin)) + self.get_logger().info('xMax : '+str(self.xMax)) + self.get_logger().info('yMin : '+str(self.yMin)) + self.get_logger().info('yMax : '+str(self.yMax)) + self.get_logger().info('zMin : '+str(self.zMin)) + self.get_logger().info('zMax : '+str(self.zMax)) + + assert self.xMin >= printer3d_constant.XMIN + assert self.xMax <= printer3d_constant.XMAX + + assert self.yMin >= printer3d_constant.YMIN + assert self.yMax <= printer3d_constant.YMAX + + assert self.zMin >= printer3d_constant.ZMIN + assert self.zMax <= printer3d_constant.ZMAX + self.gcodeLayers = work_on_gcode_file(rawGode) + + return self.gcodeLayers + + def verifyGcodeBeforeSending(self,gcodeToVerify): + + (self.xMin,self.yMin,self.zMin,self.xMax,self.yMax,self.zMax) = getBordersSimpleGcode(gcodeToVerify) + testXMin = self.xMin >= printer3d_constant.XMIN + testXMax = self.xMax <= printer3d_constant.XMAX + + testYMin = self.yMin >= printer3d_constant.YMIN + testYMax = self.yMax <= printer3d_constant.YMAX + + testZMin = self.zMin >= printer3d_constant.ZMIN + testZMax = self.zMax <= printer3d_constant.ZMAX + + if testXMin == False or testXMax == False or testYMin == False or testYMax == False or testZMin == False or testZMax == False: + return False + else: + return True + + def scanCurrentLayer(self,printedLayer): + (layerXMin,layerYMin,layerZMin,layerXMax,layerYMax,layerZMax) = getBordersSimpleGcode(printedLayer) + + gcodeScan = [[]] + margin = 10 + + Yinit = layerYMin - printer3d_constant.GAP + Yfinal = layerYMax - printer3d_constant.GAP + step = 0.3 + + gcodeScan[0].append('G1 Z'+str(layerZMax+1)+'\n') + gcodeScan[0].append('G28 X0 Y0\n') + gcodeScan[0].append('G1 Y'+str(Yinit-(margin/2))+' F1200\n') + length = int((Yfinal-Yinit+margin)/step) + + self.get_logger().info('scanning begin :') + self.get_logger().info('Yinit :' + str(Yinit)) + self.get_logger().info('Yfinal :'+ str(Yfinal)) + self.get_logger().info('length :'+ str(length)) + + for i in range(1,length): + gcodeScan.append([]) + gcodeScan[-1].append('G1 Y'+str(Yinit-(margin/2)+(i*step))+'\n') + surface = [] + for mouvements in gcodeScan: + self.sendGcodeSendingRequest(mouvements) + profileLine = self.sendProfileMeasureRequest() + surface.append(profileLine) + np.save('/home/gulltor/Ramsai_Robotics/history/'+self.historyFilename+'/scan/layer_scan_'+str(self.scanNumber)+'.npy',np.array(surface)) + self.scanNumber += 1 + return surface def printCurrentLayer(self): return 0 def takeCurrentLayerPhoto(self): + gcodeMoveToPos = ['G28 X0 Y0\n','G1 Y'+str(printer3d_constant.YPOSPHOTO)+'\n'] + self.sendGcodeSendingRequest(gcodeMoveToPos) + self.sendImageCaptureRequest('/home/gulltor/Ramsai_Robotics/history/'+self.historyFilename+'/photos/layer_photo_'+str(self.imageNumber)+'.jpg') + self.imageNumber += 1 return 0 def sendImageCaptureRequest(self,filename): @@ -123,6 +192,8 @@ def sendGcodeSendingRequest(self,gcode): """ Request the sending of a certain gcode list tanken as input through the 'send_gcode' service """ + assert self.verifyGcodeBeforeSending(gcode) == True + self.req_printer_driver.gcode_strings = gcode self.future_printer_driver = self.client_printer_driver.call_async(self.req_printer_driver) while rclpy.ok(): @@ -132,13 +203,14 @@ def sendGcodeSendingRequest(self,gcode): break if __name__ == '__main__': - gcodeExample = ['G28\n','G1 F3000 X10 Y10 Z10\n','G28\n'] - + gcodeExample = ['G1 F3000 X10 Y100 Z1\n','G1 F3000 X120 Y120 Z1\n','G1 F3000 X120 Y100 Z1\n','G1 F3000 X10 Y100 Z1\n'] + carriageReturn = ['G28\n'] rclpy.init() - printer_control_node = PrinterControlNode('impression_test') - for i in range(0,10): - printer_control_node.sendImageCaptureRequest('impressions/test/image_test_'+str(i)) - printer_control_node.sendGcodeSendingRequest(gcodeExample) - profile = printer_control_node.sendProfileMeasureRequest() - + printer_control_node = PrinterControlNode('test_impression_scan') + printer_control_node.sendGcodeSendingRequest(carriageReturn) + gcode = printer_control_node.loadGcode('/home/gulltor/Ramsai_Robotics/Gcodes/test_impression.gcode') + for i in range(0,len(gcode)): + printer_control_node.sendGcodeSendingRequest(gcode[i]) + printer_control_node.takeCurrentLayerPhoto() + printer_control_node.scanCurrentLayer(gcodeExample) rclpy.shutdown() \ No newline at end of file diff --git a/3D_printer/src/printer3d_manager/nodes/utility.py b/3D_printer/src/printer3d_manager/nodes/utility.py index 3e9b832..b915b3d 100644 --- a/3D_printer/src/printer3d_manager/nodes/utility.py +++ b/3D_printer/src/printer3d_manager/nodes/utility.py @@ -58,4 +58,42 @@ def getBordersGcode(sequence): xMax = x if xzMax: + zMax = z + if zyMax: + yMax = y + if yxMax: + xMax = x + if x Date: Mon, 17 Apr 2023 15:06:59 +0200 Subject: [PATCH 10/30] Necessary updates to compil the different nodes using ROS2 Humble --- 3D_printer/src/printer3d_driver/CMakeLists.txt | 2 +- 3D_printer/src/printer3d_image_capture/CMakeLists.txt | 2 +- 3D_printer/src/printer3d_manager/CMakeLists.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/3D_printer/src/printer3d_driver/CMakeLists.txt b/3D_printer/src/printer3d_driver/CMakeLists.txt index cdc146b..11cf739 100644 --- a/3D_printer/src/printer3d_driver/CMakeLists.txt +++ b/3D_printer/src/printer3d_driver/CMakeLists.txt @@ -21,7 +21,7 @@ find_package(rclcpp REQUIRED) find_package(std_msgs REQUIRED) # Install the python module for this package -ament_python_install_package(nodes/) +# ament_python_install_package(nodes/) if(BUILD_TESTING) find_package(ament_lint_auto REQUIRED) diff --git a/3D_printer/src/printer3d_image_capture/CMakeLists.txt b/3D_printer/src/printer3d_image_capture/CMakeLists.txt index de49c2d..c9edda1 100644 --- a/3D_printer/src/printer3d_image_capture/CMakeLists.txt +++ b/3D_printer/src/printer3d_image_capture/CMakeLists.txt @@ -21,7 +21,7 @@ find_package(rclcpp REQUIRED) find_package(std_msgs REQUIRED) # Install the python module for this package -ament_python_install_package(nodes/) +# ament_python_install_package(nodes/) if(BUILD_TESTING) find_package(ament_lint_auto REQUIRED) diff --git a/3D_printer/src/printer3d_manager/CMakeLists.txt b/3D_printer/src/printer3d_manager/CMakeLists.txt index f8fde58..085cd2d 100644 --- a/3D_printer/src/printer3d_manager/CMakeLists.txt +++ b/3D_printer/src/printer3d_manager/CMakeLists.txt @@ -21,7 +21,7 @@ find_package(rclcpp REQUIRED) find_package(std_msgs REQUIRED) # Install the python module for this package -ament_python_install_package(nodes/) +# ament_python_install_package(nodes/) if(BUILD_TESTING) find_package(ament_lint_auto REQUIRED) From 241a868ad5c1705b6244d90225784a1077657b08 Mon Sep 17 00:00:00 2001 From: Mosserl Date: Tue, 18 Apr 2023 16:58:43 +0200 Subject: [PATCH 11/30] added some calibration code plus adjusting some hyperparameters --- .../printer3d_image_capture/CMakeLists.txt | 1 + .../nodes/image_capture_calibration.py | 55 +++++ .../src/printer3d_manager/CMakeLists.txt | 1 + .../nodes/printer3d_constant.py | 2 +- .../nodes/printer_control_node.py | 15 +- .../nodes/printer_control_test.py | 215 ++++++++++++++++++ .../src/nodes/gocatorSensorNode.cpp | 2 +- 7 files changed, 281 insertions(+), 10 deletions(-) create mode 100644 3D_printer/src/printer3d_image_capture/nodes/image_capture_calibration.py create mode 100644 3D_printer/src/printer3d_manager/nodes/printer_control_test.py diff --git a/3D_printer/src/printer3d_image_capture/CMakeLists.txt b/3D_printer/src/printer3d_image_capture/CMakeLists.txt index c9edda1..6b97e20 100644 --- a/3D_printer/src/printer3d_image_capture/CMakeLists.txt +++ b/3D_printer/src/printer3d_image_capture/CMakeLists.txt @@ -38,6 +38,7 @@ endif() install( PROGRAMS + nodes/image_capture_calibration.py nodes/image_capture_node.py DESTINATION lib/${PROJECT_NAME} ) diff --git a/3D_printer/src/printer3d_image_capture/nodes/image_capture_calibration.py b/3D_printer/src/printer3d_image_capture/nodes/image_capture_calibration.py new file mode 100644 index 0000000..a7f05ec --- /dev/null +++ b/3D_printer/src/printer3d_image_capture/nodes/image_capture_calibration.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +import rclpy +from rclpy.action import ActionClient +from rclpy.node import Node + +from printer3d_msgs.srv import ProfileCommand +from printer3d_msgs.srv import GcodeCommand +from printer3d_msgs.srv import ImageCommand +import cv2 + +YPOSPHOTO = 200 + +class ImageCaptureNode(Node): + def __init__(self,cameraNumber = 0): + super().__init__('printer_image_capture') + self.cameraNumber = cameraNumber + + self.client_printer_driver = self.create_client(GcodeCommand, 'send_gcode') + while not self.client_printer_driver.wait_for_service(timeout_sec=1.0): + self.get_logger().info('profile measure service not available, waiting again...') + self.req_printer_driver = GcodeCommand.Request() + + def __del__(self): + self.webcam.release() + + def showVideo(self): + self.webcam = cv2.VideoCapture("/dev/video"+str(self.cameraNumber)) # Be carefull with the number after video + while(True): + check, frame = self.webcam.read() + cv2.imshow('frame', frame) + if cv2.waitKey(1) & 0xFF == ord('q'): + break + self.webcam.release() + cv2.destroyAllWindows() + return 0 + + def sendGcodeSendingRequest(self,gcode): + + """ Request the sending of a certain gcode list tanken as input through the 'send_gcode' service """ + self.req_printer_driver.gcode_strings = gcode + self.future_printer_driver = self.client_printer_driver.call_async(self.req_printer_driver) + while rclpy.ok(): + rclpy.spin_once(self) + if self.future_printer_driver.done(): + self.get_logger().info('gcode sended') + break + + +if __name__ == '__main__': + rclpy.init() + image_capture_node = ImageCaptureNode(2) + gcode = ['G28\n','G1 Y'+str(YPOSPHOTO)+' F2400\n'] + image_capture_node.sendGcodeSendingRequest(gcode) + image_capture_node.showVideo() + rclpy.shutdown() \ No newline at end of file diff --git a/3D_printer/src/printer3d_manager/CMakeLists.txt b/3D_printer/src/printer3d_manager/CMakeLists.txt index 085cd2d..b6bb8d1 100644 --- a/3D_printer/src/printer3d_manager/CMakeLists.txt +++ b/3D_printer/src/printer3d_manager/CMakeLists.txt @@ -39,6 +39,7 @@ endif() install( PROGRAMS nodes/printer_control_node.py + nodes/printer_control_test.py nodes/printer3d_constant.py nodes/utility.py nodes/point_cloud2.py diff --git a/3D_printer/src/printer3d_manager/nodes/printer3d_constant.py b/3D_printer/src/printer3d_manager/nodes/printer3d_constant.py index 61b21c1..0e5cc9d 100644 --- a/3D_printer/src/printer3d_manager/nodes/printer3d_constant.py +++ b/3D_printer/src/printer3d_manager/nodes/printer3d_constant.py @@ -9,6 +9,6 @@ ZMIN = 0 ZMAX = 60 -GAP = 26 +GAP = 31.5 YPOSPHOTO = 200 \ No newline at end of file diff --git a/3D_printer/src/printer3d_manager/nodes/printer_control_node.py b/3D_printer/src/printer3d_manager/nodes/printer_control_node.py index 6c01055..e1bf8f7 100644 --- a/3D_printer/src/printer3d_manager/nodes/printer_control_node.py +++ b/3D_printer/src/printer3d_manager/nodes/printer_control_node.py @@ -112,7 +112,7 @@ def scanCurrentLayer(self,printedLayer): (layerXMin,layerYMin,layerZMin,layerXMax,layerYMax,layerZMax) = getBordersSimpleGcode(printedLayer) gcodeScan = [[]] - margin = 10 + margin = 25 Yinit = layerYMin - printer3d_constant.GAP Yfinal = layerYMax - printer3d_constant.GAP @@ -144,7 +144,7 @@ def printCurrentLayer(self): return 0 def takeCurrentLayerPhoto(self): - gcodeMoveToPos = ['G28 X0 Y0\n','G1 Y'+str(printer3d_constant.YPOSPHOTO)+'\n'] + gcodeMoveToPos = ['G28 X0 Y0\n','G1 Y'+str(printer3d_constant.YPOSPHOTO)+' F2400\n'] self.sendGcodeSendingRequest(gcodeMoveToPos) self.sendImageCaptureRequest('/home/gulltor/Ramsai_Robotics/history/'+self.historyFilename+'/photos/layer_photo_'+str(self.imageNumber)+'.jpg') self.imageNumber += 1 @@ -203,14 +203,13 @@ def sendGcodeSendingRequest(self,gcode): break if __name__ == '__main__': - gcodeExample = ['G1 F3000 X10 Y100 Z1\n','G1 F3000 X120 Y120 Z1\n','G1 F3000 X120 Y100 Z1\n','G1 F3000 X10 Y100 Z1\n'] carriageReturn = ['G28\n'] rclpy.init() - printer_control_node = PrinterControlNode('test_impression_scan') + printer_control_node = PrinterControlNode('impression_base_2') printer_control_node.sendGcodeSendingRequest(carriageReturn) - gcode = printer_control_node.loadGcode('/home/gulltor/Ramsai_Robotics/Gcodes/test_impression.gcode') - for i in range(0,len(gcode)): - printer_control_node.sendGcodeSendingRequest(gcode[i]) + gcode = printer_control_node.loadGcode('/home/gulltor/Ramsai_Robotics/Gcodes/piece_test_base.gcode') + for i in range(90,len(gcode)): + # printer_control_node.sendGcodeSendingRequest(gcode[i]) printer_control_node.takeCurrentLayerPhoto() - printer_control_node.scanCurrentLayer(gcodeExample) + printer_control_node.scanCurrentLayer(gcode[i]) rclpy.shutdown() \ No newline at end of file diff --git a/3D_printer/src/printer3d_manager/nodes/printer_control_test.py b/3D_printer/src/printer3d_manager/nodes/printer_control_test.py new file mode 100644 index 0000000..4a75fe6 --- /dev/null +++ b/3D_printer/src/printer3d_manager/nodes/printer_control_test.py @@ -0,0 +1,215 @@ +#!/usr/bin/env python3 +import rclpy +from rclpy.action import ActionClient +from rclpy.node import Node +from printer3d_msgs.srv import ProfileCommand +from printer3d_msgs.srv import GcodeCommand +from printer3d_msgs.srv import ImageCommand +from printer3d_gocator_msgs.srv import GocatorPTCloud +from utility import * +import printer3d_constant +from sensor_msgs.msg import PointCloud2 +import point_cloud2 as pc2 +import os +import numpy as np + + + +class PrinterControlNode(Node): + def __init__(self, historyFilename): + super().__init__('printer_control') + + """Initialisation of the printing process workspace""" + self.historyFilename = historyFilename + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename) + except: + pass + + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/gcode') + except: + pass + + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/scan') + except: + pass + + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/photos') + except: + pass + + # access to the image capture service + + self.client_image_capture = self.create_client(ImageCommand, 'ask_capture_image') + while not self.client_image_capture.wait_for_service(timeout_sec=1.0): + self.get_logger().info('image capture service not available, waiting again...') + self.req_image_capture = ImageCommand.Request() + + # access to the profile measure service + + self.client_profile_measure = self.create_client(GocatorPTCloud, 'gocator_get_profile') + while not self.client_profile_measure.wait_for_service(timeout_sec=1.0): + self.get_logger().info('profile measure service not available, waiting again...') + self.req_profile_measure = GocatorPTCloud.Request() + + # access to the printer driver service + + self.client_printer_driver = self.create_client(GcodeCommand, 'send_gcode') + while not self.client_printer_driver.wait_for_service(timeout_sec=1.0): + self.get_logger().info('profile measure service not available, waiting again...') + self.req_printer_driver = GcodeCommand.Request() + + self.imageNumber = 0 + self.scanNumber = 0 + + + def loadGcode(self,gcodeFilename): + fileFullGcode = open(gcodeFilename,'r') + rawGode = fileFullGcode.readlines() + fileFullGcode.close() + + (self.xMin,self.yMin,self.zMin,self.xMax,self.yMax,self.zMax) = getBordersGcode(rawGode) + self.get_logger().info('xMin : '+str(self.xMin)) + self.get_logger().info('xMax : '+str(self.xMax)) + self.get_logger().info('yMin : '+str(self.yMin)) + self.get_logger().info('yMax : '+str(self.yMax)) + self.get_logger().info('zMin : '+str(self.zMin)) + self.get_logger().info('zMax : '+str(self.zMax)) + + assert self.xMin >= printer3d_constant.XMIN + assert self.xMax <= printer3d_constant.XMAX + + assert self.yMin >= printer3d_constant.YMIN + assert self.yMax <= printer3d_constant.YMAX + + assert self.zMin >= printer3d_constant.ZMIN + assert self.zMax <= printer3d_constant.ZMAX + self.gcodeLayers = work_on_gcode_file(rawGode) + + return self.gcodeLayers + + def verifyGcodeBeforeSending(self,gcodeToVerify): + + (self.xMin,self.yMin,self.zMin,self.xMax,self.yMax,self.zMax) = getBordersSimpleGcode(gcodeToVerify) + testXMin = self.xMin >= printer3d_constant.XMIN + testXMax = self.xMax <= printer3d_constant.XMAX + + testYMin = self.yMin >= printer3d_constant.YMIN + testYMax = self.yMax <= printer3d_constant.YMAX + + testZMin = self.zMin >= printer3d_constant.ZMIN + testZMax = self.zMax <= printer3d_constant.ZMAX + + if testXMin == False or testXMax == False or testYMin == False or testYMax == False or testZMin == False or testZMax == False: + return False + else: + return True + + def scanCurrentLayer(self,printedLayer): + (layerXMin,layerYMin,layerZMin,layerXMax,layerYMax,layerZMax) = getBordersSimpleGcode(printedLayer) + + gcodeScan = [[]] + margin = 20 + + Yinit = layerYMin - printer3d_constant.GAP + Yfinal = layerYMax - printer3d_constant.GAP + step = 0.3 + + gcodeScan[0].append('G1 Z'+str(layerZMax+1)+'\n') + gcodeScan[0].append('G28 X0 Y0\n') + gcodeScan[0].append('G1 Y'+str(Yinit-(margin/2))+' F1200\n') + length = int((Yfinal-Yinit+margin)/step) + + self.get_logger().info('scanning begin :') + self.get_logger().info('Yinit :' + str(Yinit)) + self.get_logger().info('Yfinal :'+ str(Yfinal)) + self.get_logger().info('length :'+ str(length)) + + for i in range(1,length): + gcodeScan.append([]) + gcodeScan[-1].append('G1 Y'+str(Yinit-(margin/2)+(i*step))+'\n') + surface = [] + for mouvements in gcodeScan: + self.sendGcodeSendingRequest(mouvements) + profileLine = self.sendProfileMeasureRequest() + surface.append(profileLine) + np.save('/home/gulltor/Ramsai_Robotics/history/'+self.historyFilename+'/scan/layer_scan_'+str(self.scanNumber)+'.npy',np.array(surface)) + self.scanNumber += 1 + return surface + + def printCurrentLayer(self): + return 0 + + def takeCurrentLayerPhoto(self): + gcodeMoveToPos = ['G28 X0 Y0\n','G1 Y'+str(printer3d_constant.YPOSPHOTO)+' F2400\n'] + self.sendGcodeSendingRequest(gcodeMoveToPos) + self.sendImageCaptureRequest('/home/gulltor/Ramsai_Robotics/history/'+self.historyFilename+'/photos/layer_photo_'+str(self.imageNumber)+'.jpg') + self.imageNumber += 1 + return 0 + + def sendImageCaptureRequest(self,filename): + + """ Request an image capture using a webcam through the 'ask_image_capture' service """ + + self.req_image_capture.filename = filename + self.future_image_capture = self.client_image_capture.call_async(self.req_image_capture) + while rclpy.ok(): + rclpy.spin_once(self) + if self.future_image_capture.done(): + self.get_logger().info('capture finished') + break + + def sendProfileMeasureRequest(self): + + """ Request a profile measure using a Gocator 2140 profile sensor through the 'gocator_get_profile' service """ + + profile_line = [] + self.future_profile_measure = self.client_profile_measure.call_async(self.req_profile_measure) + while rclpy.ok(): + rclpy.spin_once(self) + if self.future_profile_measure.done(): + try: + self.response = self.future_profile_measure.result() + except Exception as e: + self.get_logger().info('Service call failed %r' % (e,)) + else: + pcloud = self.response.pcloud + self.flag_datas_used = True + + gen = pc2.read_points(pcloud, skip_nans=True) + profile = list(gen) + + for points in profile: + profile_line.append([[points[0],0,points[2]]]) + break + self.get_logger().info('scan finished') + return profile_line + + def sendGcodeSendingRequest(self,gcode): + + """ Request the sending of a certain gcode list tanken as input through the 'send_gcode' service """ + + assert self.verifyGcodeBeforeSending(gcode) == True + + self.req_printer_driver.gcode_strings = gcode + self.future_printer_driver = self.client_printer_driver.call_async(self.req_printer_driver) + while rclpy.ok(): + rclpy.spin_once(self) + if self.future_printer_driver.done(): + self.get_logger().info('gcode sended') + break + +if __name__ == '__main__': + carriageReturn = ['G28\n'] + rclpy.init() + printer_control_node = PrinterControlNode('test_impression_base') + # printer_control_node.sendGcodeSendingRequest(carriageReturn) + gcode = printer_control_node.loadGcode('/home/gulltor/Ramsai_Robotics/Gcodes/piece_test_base.gcode') + for i in range(0,3): + printer_control_node.sendGcodeSendingRequest(gcode[i]) + printer_control_node.takeCurrentLayerPhoto() + printer_control_node.scanCurrentLayer(gcode[i]) + rclpy.shutdown() \ No newline at end of file diff --git a/3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp b/3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp index d459e9f..abc9295 100644 --- a/3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp +++ b/3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp @@ -19,7 +19,7 @@ class GocatorSensorNode : public rclcpp::Node : Node("gocatorSensorNode") { gsensor_ = new GocatorSensor::Device(SENSOR_IP); - capture_params_.exposure_time_ = 40000; + capture_params_.exposure_time_ = 110; capture_params_.spacing_interval_ = 0.1; gsensor_->configure(capture_params_); From 5e251ed6d23596413ef8443e65e6d3d7831287b4 Mon Sep 17 00:00:00 2001 From: MosserLoic Date: Tue, 18 Apr 2023 17:22:17 +0200 Subject: [PATCH 12/30] precommit run --- .gitignore | 2 +- .../nodes/gcode_monitor_node.py | 10 +- .../srv/GocatorPTCloud.srv | 2 - .../nodes/image_capture_calibration.py | 6 +- .../nodes/image_capture_node.py | 6 +- .../launch/launch_printer3d.py | 2 +- .../printer3d_manager/nodes/point_cloud2.py | 10 +- .../nodes/printer3d_constant.py | 2 +- .../nodes/printer_control_node.py | 20 +- .../nodes/printer_control_test.py | 20 +- .../src/printer3d_manager/nodes/utility.py | 4 +- 3D_printer/src/printer3d_msgs/package.xml | 2 +- .../src/printer3d_msgs/srv/GcodeCommand.srv | 2 +- .../src/printer3d_msgs/srv/ImageCommand.srv | 2 +- .../src/printer3d_msgs/srv/ProfileCommand.srv | 2 +- .../printer3d_profile_capture/CMakeLists.txt | 14 +- .../src/printer3d_profile_capture/package.xml | 2 +- .../src/driver/CMakeLists.txt | 19 +- .../src/driver/gocatorSensor.cpp | 726 +++++++++--------- .../src/driver/gocatorSensor.h | 291 +++---- .../src/nodes/gocatorSensorNode.cpp | 74 +- 21 files changed, 606 insertions(+), 612 deletions(-) diff --git a/.gitignore b/.gitignore index c9597fe..98fb702 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,4 @@ install/ 3D_Printer/build 3D_Printer/install 3D_Printer/log -3D_printer/src/printer3d_profile_capture/external \ No newline at end of file +3D_printer/src/printer3d_profile_capture/external diff --git a/3D_printer/src/printer3d_driver/nodes/gcode_monitor_node.py b/3D_printer/src/printer3d_driver/nodes/gcode_monitor_node.py index 25961b8..d6218c5 100644 --- a/3D_printer/src/printer3d_driver/nodes/gcode_monitor_node.py +++ b/3D_printer/src/printer3d_driver/nodes/gcode_monitor_node.py @@ -38,7 +38,7 @@ def __init__(self): super().__init__('printer_gcode_monitor') self.serialPort = openSerialPort('/dev/ttyACM0', 250000) - self.serialPort.write("\n\n".encode('ascii')) + self.serialPort.write(b"\n\n") time.sleep(2) self.gcodeService = self.create_service(GcodeCommand, 'send_gcode', self.execute_gcode_sending) @@ -52,7 +52,7 @@ def execute_gcode_sending(self, request, response): #self.get_logger().info('Gcode Received with a length of : '+str(len(gcode))) - feedback = 0.0 + feedback = 0.0 self.serialPort.flushInput() self.i = 0 @@ -85,7 +85,7 @@ def execute_gcode_sending(self, request, response): grbl_out = grbl_out.strip().decode('ascii') - self.serialPort.write(("M400\n").encode('ascii')) + self.serialPort.write(b"M400\n") grbl_out = self.serialPort.readline() # wait for response from printer grbl_out = grbl_out.strip().decode('ascii') while 'ok' not in grbl_out: @@ -93,7 +93,7 @@ def execute_gcode_sending(self, request, response): grbl_out = grbl_out.strip().decode('ascii') - self.serialPort.write(("M400\n").encode('ascii')) + self.serialPort.write(b"M400\n") grbl_out = self.serialPort.readline() # wait for response from printer grbl_out = grbl_out.strip().decode('ascii') while 'ok' not in grbl_out: @@ -111,4 +111,4 @@ def execute_gcode_sending(self, request, response): rclpy.init() gcode_monitor_node = GcodeMonitorNode() rclpy.spin(gcode_monitor_node) - rclpy.shutdown() \ No newline at end of file + rclpy.shutdown() diff --git a/3D_printer/src/printer3d_gocator_msgs/srv/GocatorPTCloud.srv b/3D_printer/src/printer3d_gocator_msgs/srv/GocatorPTCloud.srv index 9f7446e..f05eb7c 100644 --- a/3D_printer/src/printer3d_gocator_msgs/srv/GocatorPTCloud.srv +++ b/3D_printer/src/printer3d_gocator_msgs/srv/GocatorPTCloud.srv @@ -1,5 +1,3 @@ std_msgs/Empty request --- sensor_msgs/PointCloud2 pcloud - - diff --git a/3D_printer/src/printer3d_image_capture/nodes/image_capture_calibration.py b/3D_printer/src/printer3d_image_capture/nodes/image_capture_calibration.py index a7f05ec..b58cd0b 100644 --- a/3D_printer/src/printer3d_image_capture/nodes/image_capture_calibration.py +++ b/3D_printer/src/printer3d_image_capture/nodes/image_capture_calibration.py @@ -6,7 +6,7 @@ from printer3d_msgs.srv import ProfileCommand from printer3d_msgs.srv import GcodeCommand from printer3d_msgs.srv import ImageCommand -import cv2 +import cv2 YPOSPHOTO = 200 @@ -22,7 +22,7 @@ def __init__(self,cameraNumber = 0): def __del__(self): self.webcam.release() - + def showVideo(self): self.webcam = cv2.VideoCapture("/dev/video"+str(self.cameraNumber)) # Be carefull with the number after video while(True): @@ -52,4 +52,4 @@ def sendGcodeSendingRequest(self,gcode): gcode = ['G28\n','G1 Y'+str(YPOSPHOTO)+' F2400\n'] image_capture_node.sendGcodeSendingRequest(gcode) image_capture_node.showVideo() - rclpy.shutdown() \ No newline at end of file + rclpy.shutdown() diff --git a/3D_printer/src/printer3d_image_capture/nodes/image_capture_node.py b/3D_printer/src/printer3d_image_capture/nodes/image_capture_node.py index 980651b..8cb0eec 100644 --- a/3D_printer/src/printer3d_image_capture/nodes/image_capture_node.py +++ b/3D_printer/src/printer3d_image_capture/nodes/image_capture_node.py @@ -6,7 +6,7 @@ from printer3d_msgs.srv import ProfileCommand from printer3d_msgs.srv import GcodeCommand from printer3d_msgs.srv import ImageCommand -import cv2 +import cv2 @@ -18,7 +18,7 @@ def __init__(self,cameraNumber = 0): def __del__(self): self.webcam.release() - + def takePicture(self, request, response): webcam = cv2.VideoCapture("/dev/video"+str(self.cameraNumber)) # Be carefull with the number after video check, frame = webcam.read() @@ -33,4 +33,4 @@ def takePicture(self, request, response): rclpy.init() image_capture_node = ImageCaptureNode(2) rclpy.spin(image_capture_node) - rclpy.shutdown() \ No newline at end of file + rclpy.shutdown() diff --git a/3D_printer/src/printer3d_manager/launch/launch_printer3d.py b/3D_printer/src/printer3d_manager/launch/launch_printer3d.py index e7ae616..a91e120 100644 --- a/3D_printer/src/printer3d_manager/launch/launch_printer3d.py +++ b/3D_printer/src/printer3d_manager/launch/launch_printer3d.py @@ -21,4 +21,4 @@ def generate_launch_description(): executable='gocatorSensorNode', name='profile_capture_node' ) - ]) \ No newline at end of file + ]) diff --git a/3D_printer/src/printer3d_manager/nodes/point_cloud2.py b/3D_printer/src/printer3d_manager/nodes/point_cloud2.py index dd7172e..4a42b69 100644 --- a/3D_printer/src/printer3d_manager/nodes/point_cloud2.py +++ b/3D_printer/src/printer3d_manager/nodes/point_cloud2.py @@ -118,9 +118,9 @@ def read_points(cloud, field_names=None, skip_nans=False, uvs=[]): def read_points_list(cloud, field_names=None, skip_nans=False, uvs=[]): """ Read points from a L{sensor_msgs.PointCloud2} message. - - This function returns a list of namedtuples. It operates on top of the read_points method. For more efficient access use read_points directly. - + + This function returns a list of namedtuples. It operates on top of the read_points method. For more efficient access use read_points directly. + @param cloud: The point cloud to read from. @type cloud: L{sensor_msgs.PointCloud2} @param field_names: The names of fields to read. If None, read all fields. [default: None] @@ -151,7 +151,7 @@ def create_cloud(header, fields, points): @type fields: iterable of L{sensor_msgs.msg.PointField} @param points: The point cloud points. @type points: list of iterables, i.e. one iterable for each point, with the - elements of each iterable being the values of the fields for + elements of each iterable being the values of the fields for that point (in the same order as the fields parameter) @return: The point cloud. @rtype: L{sensor_msgs.msg.PointCloud2} @@ -182,7 +182,7 @@ def create_cloud_xyz32(header, points): @param header: The point cloud header. @type header: L{std_msgs.msg.Header} - @param points: The point cloud points. + @param points: The point cloud points. @type points: iterable @return: The point cloud. @rtype: L{sensor_msgs.msg.PointCloud2} diff --git a/3D_printer/src/printer3d_manager/nodes/printer3d_constant.py b/3D_printer/src/printer3d_manager/nodes/printer3d_constant.py index 0e5cc9d..0a95ed1 100644 --- a/3D_printer/src/printer3d_manager/nodes/printer3d_constant.py +++ b/3D_printer/src/printer3d_manager/nodes/printer3d_constant.py @@ -11,4 +11,4 @@ GAP = 31.5 -YPOSPHOTO = 200 \ No newline at end of file +YPOSPHOTO = 200 diff --git a/3D_printer/src/printer3d_manager/nodes/printer_control_node.py b/3D_printer/src/printer3d_manager/nodes/printer_control_node.py index e1bf8f7..377bc55 100644 --- a/3D_printer/src/printer3d_manager/nodes/printer_control_node.py +++ b/3D_printer/src/printer3d_manager/nodes/printer_control_node.py @@ -8,7 +8,7 @@ from printer3d_gocator_msgs.srv import GocatorPTCloud from utility import * import printer3d_constant -from sensor_msgs.msg import PointCloud2 +from sensor_msgs.msg import PointCloud2 import point_cloud2 as pc2 import os import numpy as np @@ -17,7 +17,7 @@ class PrinterControlNode(Node): def __init__(self, historyFilename): - super().__init__('printer_control') + super().__init__('printer_control') """Initialisation of the printing process workspace""" self.historyFilename = historyFilename @@ -67,7 +67,7 @@ def __init__(self, historyFilename): def loadGcode(self,gcodeFilename): - fileFullGcode = open(gcodeFilename,'r') + fileFullGcode = open(gcodeFilename) rawGode = fileFullGcode.readlines() fileFullGcode.close() @@ -104,7 +104,7 @@ def verifyGcodeBeforeSending(self,gcodeToVerify): testZMax = self.zMax <= printer3d_constant.ZMAX if testXMin == False or testXMax == False or testYMin == False or testYMax == False or testZMin == False or testZMax == False: - return False + return False else: return True @@ -132,8 +132,8 @@ def scanCurrentLayer(self,printedLayer): gcodeScan.append([]) gcodeScan[-1].append('G1 Y'+str(Yinit-(margin/2)+(i*step))+'\n') surface = [] - for mouvements in gcodeScan: - self.sendGcodeSendingRequest(mouvements) + for movements in gcodeScan: + self.sendGcodeSendingRequest(movements) profileLine = self.sendProfileMeasureRequest() surface.append(profileLine) np.save('/home/gulltor/Ramsai_Robotics/history/'+self.historyFilename+'/scan/layer_scan_'+str(self.scanNumber)+'.npy',np.array(surface)) @@ -174,11 +174,11 @@ def sendProfileMeasureRequest(self): try: self.response = self.future_profile_measure.result() except Exception as e: - self.get_logger().info('Service call failed %r' % (e,)) + self.get_logger().info('Service call failed {!r}'.format(e)) else: pcloud = self.response.pcloud self.flag_datas_used = True - + gen = pc2.read_points(pcloud, skip_nans=True) profile = list(gen) @@ -186,7 +186,7 @@ def sendProfileMeasureRequest(self): profile_line.append([[points[0],0,points[2]]]) break self.get_logger().info('scan finished') - return profile_line + return profile_line def sendGcodeSendingRequest(self,gcode): @@ -212,4 +212,4 @@ def sendGcodeSendingRequest(self,gcode): # printer_control_node.sendGcodeSendingRequest(gcode[i]) printer_control_node.takeCurrentLayerPhoto() printer_control_node.scanCurrentLayer(gcode[i]) - rclpy.shutdown() \ No newline at end of file + rclpy.shutdown() diff --git a/3D_printer/src/printer3d_manager/nodes/printer_control_test.py b/3D_printer/src/printer3d_manager/nodes/printer_control_test.py index 4a75fe6..3f7aee0 100644 --- a/3D_printer/src/printer3d_manager/nodes/printer_control_test.py +++ b/3D_printer/src/printer3d_manager/nodes/printer_control_test.py @@ -8,7 +8,7 @@ from printer3d_gocator_msgs.srv import GocatorPTCloud from utility import * import printer3d_constant -from sensor_msgs.msg import PointCloud2 +from sensor_msgs.msg import PointCloud2 import point_cloud2 as pc2 import os import numpy as np @@ -17,7 +17,7 @@ class PrinterControlNode(Node): def __init__(self, historyFilename): - super().__init__('printer_control') + super().__init__('printer_control') """Initialisation of the printing process workspace""" self.historyFilename = historyFilename @@ -67,7 +67,7 @@ def __init__(self, historyFilename): def loadGcode(self,gcodeFilename): - fileFullGcode = open(gcodeFilename,'r') + fileFullGcode = open(gcodeFilename) rawGode = fileFullGcode.readlines() fileFullGcode.close() @@ -104,7 +104,7 @@ def verifyGcodeBeforeSending(self,gcodeToVerify): testZMax = self.zMax <= printer3d_constant.ZMAX if testXMin == False or testXMax == False or testYMin == False or testYMax == False or testZMin == False or testZMax == False: - return False + return False else: return True @@ -132,8 +132,8 @@ def scanCurrentLayer(self,printedLayer): gcodeScan.append([]) gcodeScan[-1].append('G1 Y'+str(Yinit-(margin/2)+(i*step))+'\n') surface = [] - for mouvements in gcodeScan: - self.sendGcodeSendingRequest(mouvements) + for movements in gcodeScan: + self.sendGcodeSendingRequest(movements) profileLine = self.sendProfileMeasureRequest() surface.append(profileLine) np.save('/home/gulltor/Ramsai_Robotics/history/'+self.historyFilename+'/scan/layer_scan_'+str(self.scanNumber)+'.npy',np.array(surface)) @@ -174,11 +174,11 @@ def sendProfileMeasureRequest(self): try: self.response = self.future_profile_measure.result() except Exception as e: - self.get_logger().info('Service call failed %r' % (e,)) + self.get_logger().info('Service call failed {!r}'.format(e)) else: pcloud = self.response.pcloud self.flag_datas_used = True - + gen = pc2.read_points(pcloud, skip_nans=True) profile = list(gen) @@ -186,7 +186,7 @@ def sendProfileMeasureRequest(self): profile_line.append([[points[0],0,points[2]]]) break self.get_logger().info('scan finished') - return profile_line + return profile_line def sendGcodeSendingRequest(self,gcode): @@ -212,4 +212,4 @@ def sendGcodeSendingRequest(self,gcode): printer_control_node.sendGcodeSendingRequest(gcode[i]) printer_control_node.takeCurrentLayerPhoto() printer_control_node.scanCurrentLayer(gcode[i]) - rclpy.shutdown() \ No newline at end of file + rclpy.shutdown() diff --git a/3D_printer/src/printer3d_manager/nodes/utility.py b/3D_printer/src/printer3d_manager/nodes/utility.py index b915b3d..735514f 100644 --- a/3D_printer/src/printer3d_manager/nodes/utility.py +++ b/3D_printer/src/printer3d_manager/nodes/utility.py @@ -7,7 +7,7 @@ def work_on_gcode_file(sequence): layers = [[]] for line in sequence: - + if (delimiter not in line) and (final_delimiter not in line): if line[0]!=';': layers[-1].append(line) @@ -96,4 +96,4 @@ def getBordersSimpleGcode(simpleGcode): xMax = x if x ament_cmake - \ No newline at end of file + diff --git a/3D_printer/src/printer3d_msgs/srv/GcodeCommand.srv b/3D_printer/src/printer3d_msgs/srv/GcodeCommand.srv index 72b6cf5..c1509c0 100644 --- a/3D_printer/src/printer3d_msgs/srv/GcodeCommand.srv +++ b/3D_printer/src/printer3d_msgs/srv/GcodeCommand.srv @@ -1,3 +1,3 @@ string[] gcode_strings --- -bool validation \ No newline at end of file +bool validation diff --git a/3D_printer/src/printer3d_msgs/srv/ImageCommand.srv b/3D_printer/src/printer3d_msgs/srv/ImageCommand.srv index 65ce60f..8e5725f 100644 --- a/3D_printer/src/printer3d_msgs/srv/ImageCommand.srv +++ b/3D_printer/src/printer3d_msgs/srv/ImageCommand.srv @@ -1,3 +1,3 @@ string filename --- -bool confirmation \ No newline at end of file +bool confirmation diff --git a/3D_printer/src/printer3d_msgs/srv/ProfileCommand.srv b/3D_printer/src/printer3d_msgs/srv/ProfileCommand.srv index dd07f00..d1db3c3 100644 --- a/3D_printer/src/printer3d_msgs/srv/ProfileCommand.srv +++ b/3D_printer/src/printer3d_msgs/srv/ProfileCommand.srv @@ -3,4 +3,4 @@ float64 y_max float64 z_upper float64 step --- -bool validation \ No newline at end of file +bool validation diff --git a/3D_printer/src/printer3d_profile_capture/CMakeLists.txt b/3D_printer/src/printer3d_profile_capture/CMakeLists.txt index 6cc5cfb..5dd6f98 100644 --- a/3D_printer/src/printer3d_profile_capture/CMakeLists.txt +++ b/3D_printer/src/printer3d_profile_capture/CMakeLists.txt @@ -32,7 +32,7 @@ LINK_DIRECTORIES(${PCL_LIBRARY_DIRS}) ADD_DEFINITIONS(${PCL_DEFINITIONS}) # Set GO_SDK include paths (That could be part of a FindGocator.cmake) -SET(GO_SDK_4 ${CMAKE_CURRENT_SOURCE_DIR}/external/GO_SDK) +SET(GO_SDK_4 ${CMAKE_CURRENT_SOURCE_DIR}/external/GO_SDK) FIND_PATH( GOCATOR_INCLUDES NAMES GoSdk/GoSdk.h @@ -47,18 +47,18 @@ INCLUDE_DIRECTORIES(${GOCATOR_INCLUDES} ${KAPI_INCLUDES}) FIND_LIBRARY( GOCATOR_LIBRARIES NAMES GoSdk - PATHS ${GO_SDK_4}/lib/linux_x64d) + PATHS ${GO_SDK_4}/lib/linux_x64d) FIND_LIBRARY( KAPI_LIBRARIES NAMES kApi - PATHS ${GO_SDK_4}/lib/linux_x64d) + PATHS ${GO_SDK_4}/lib/linux_x64d) -# Set source files -SET(LIB_SRCS +# Set source files +SET(LIB_SRCS src/driver/gocatorSensor.cpp) -# Set header files -SET(LIB_HDRS +# Set header files +SET(LIB_HDRS src/driver/gocatorSensor.h) INCLUDE_DIRECTORIES(${LIB_HDRS}) diff --git a/3D_printer/src/printer3d_profile_capture/package.xml b/3D_printer/src/printer3d_profile_capture/package.xml index c245a19..1087359 100644 --- a/3D_printer/src/printer3d_profile_capture/package.xml +++ b/3D_printer/src/printer3d_profile_capture/package.xml @@ -19,4 +19,4 @@ ament_cmake - \ No newline at end of file + diff --git a/3D_printer/src/printer3d_profile_capture/src/driver/CMakeLists.txt b/3D_printer/src/printer3d_profile_capture/src/driver/CMakeLists.txt index c32dfc2..b4bd2d4 100644 --- a/3D_printer/src/printer3d_profile_capture/src/driver/CMakeLists.txt +++ b/3D_printer/src/printer3d_profile_capture/src/driver/CMakeLists.txt @@ -6,7 +6,7 @@ PROJECT(gocatorSensor) # DEBUG/RELEASE IF (NOT CMAKE_BUILD_TYPE) - SET(CMAKE_BUILD_TYPE "RELEASE") + SET(CMAKE_BUILD_TYPE "RELEASE") ENDIF (NOT CMAKE_BUILD_TYPE) # Default to C99 @@ -30,7 +30,7 @@ LINK_DIRECTORIES(${PCL_LIBRARY_DIRS}) ADD_DEFINITIONS(${PCL_DEFINITIONS}) # Set GO_SDK include paths (That could be part of a FindGocator.cmake) -SET(GO_SDK_4 ${CMAKE_CURRENT_SOURCE_DIR}/../../external/GO_SDK) +SET(GO_SDK_4 ${CMAKE_CURRENT_SOURCE_DIR}/../../external/GO_SDK) FIND_PATH( GOCATOR_INCLUDES NAMES GoSdk/GoSdk.h @@ -45,21 +45,20 @@ INCLUDE_DIRECTORIES(${GOCATOR_INCLUDES} ${KAPI_INCLUDES}) FIND_LIBRARY( GOCATOR_LIBRARIES NAMES GoSdk - PATHS ${GO_SDK_4}/lib/linux_x64d/) + PATHS ${GO_SDK_4}/lib/linux_x64d/) FIND_LIBRARY( KAPI_LIBRARIES NAMES kApi - PATHS ${GO_SDK_4}/lib/linux_x64d/) + PATHS ${GO_SDK_4}/lib/linux_x64d/) -# Set source files -SET(SRCS +# Set source files +SET(SRCS gocatorSensor.cpp) -# Set header files -SET(HDRS +# Set header files +SET(HDRS gocatorSensor.h) -#Build library +#Build library ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS}) TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${GOCATOR_LIBRARIES} ${KAPI_LIBRARIES} ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES}) - diff --git a/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp b/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp index f633b1c..8e0d953 100644 --- a/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp +++ b/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp @@ -2,423 +2,415 @@ GocatorSensor::Device::Device(const std::string & _ip_address) { - kStatus status; - kIpAddress ipAddress; - kChar model_name[50]; - - //init all GO API objects - go_api_ = kNULL; - go_system_ = kNULL; - go_sensor_ = kNULL; - go_setup_ = kNULL; - go_dataset_ = kNULL; - go_stamp_ptr_ = kNULL; - - // construct Gocator API Library - if ((status = GoSdk_Construct(&go_api_)) != kOK) - { - std::cout << "Device(). Error: GoSdk_Construct: " << status << std::endl; - status_ = DEVICE_NOT_FOUND; - return; - } - - // construct GoSystem object - if ((status = GoSystem_Construct(&go_system_, kNULL)) != kOK) - { - std::cout << "Device(). Error: GoSystem_Construct: " << status << std::endl; - status_ = DEVICE_NOT_FOUND; - return; - } - - // obtain GoSensor object by sensor IP address - kIpAddress_Parse(&ipAddress, _ip_address.c_str()); - if ((status = GoSystem_FindSensorByIpAddress(go_system_, &ipAddress, &go_sensor_)) != kOK) - { - std::cout << "Device(). Error: GoSystem_FindSensorByIpAddress: " << status << std::endl; - status_ = DEVICE_NOT_FOUND; - return; - } - - //Success case. Set status and device fixed params (ip, model name and serial number ). - status_ = DEVICE_FOUND; - device_params_.ip_address_ = _ip_address; - - // create connection to GoSensor object - if ((status = GoSensor_Connect(go_sensor_)) != kOK) - { - std::cout << "Device(). Error: GoSensor_Connect: " << status << std::endl; - status_ = DEVICE_NOT_CONNECT; - return; - } - status_ = DEVICE_CONNECT; - - // enable sensor data channel - if ((status = GoSystem_EnableData(go_system_, kTRUE)) != kOK) - { - std::cout << "Device(). Error: GoSensor_EnableData: " << status << std::endl; - return; - } - - // retrieve setup handle - if ((go_setup_ = GoSensor_Setup(go_sensor_)) == kNULL) - { - std::cout << "Device(). Error: GoSensor_Setup: Invalid Handle" << std::endl; - return; - } - - //Obtain camera model - if ((status = GoSensor_Model(go_sensor_, model_name, 50)) != kOK ) - { - std::cout << "Device(). Error: GoSensor_Model: " << status << std::endl; - return; - } - device_params_.model_name_ = model_name; - - //Obtain camera Serial number - device_params_.sn_ = (unsigned int)GoSensor_Id(go_sensor_); - - //Obtain exposure - capture_params_.exposure_time_ = GoSetup_Exposure(go_setup_, GO_ROLE_MAIN); - - //Obtain spacing interval - capture_params_.spacing_interval_ = GoSetup_SpacingInterval(go_setup_, GO_ROLE_MAIN); - - //print info - std::cout << "Found Sensor: " << std::endl; - device_params_.print(); + kStatus status; + kIpAddress ipAddress; + kChar model_name[50]; + + //init all GO API objects + go_api_ = kNULL; + go_system_ = kNULL; + go_sensor_ = kNULL; + go_setup_ = kNULL; + go_dataset_ = kNULL; + go_stamp_ptr_ = kNULL; + + // construct Gocator API Library + if ((status = GoSdk_Construct(&go_api_)) != kOK) { + std::cout << "Device(). Error: GoSdk_Construct: " << status << std::endl; + status_ = DEVICE_NOT_FOUND; + return; + } + + // construct GoSystem object + if ((status = GoSystem_Construct(&go_system_, kNULL)) != kOK) { + std::cout << "Device(). Error: GoSystem_Construct: " << status << std::endl; + status_ = DEVICE_NOT_FOUND; + return; + } + + // obtain GoSensor object by sensor IP address + kIpAddress_Parse(&ipAddress, _ip_address.c_str()); + if ((status = GoSystem_FindSensorByIpAddress(go_system_, &ipAddress, &go_sensor_)) != kOK) { + std::cout << "Device(). Error: GoSystem_FindSensorByIpAddress: " << status << std::endl; + status_ = DEVICE_NOT_FOUND; + return; + } + + //Success case. Set status and device fixed params (ip, model name and serial number ). + status_ = DEVICE_FOUND; + device_params_.ip_address_ = _ip_address; + + // create connection to GoSensor object + if ((status = GoSensor_Connect(go_sensor_)) != kOK) { + std::cout << "Device(). Error: GoSensor_Connect: " << status << std::endl; + status_ = DEVICE_NOT_CONNECT; + return; + } + status_ = DEVICE_CONNECT; + + // enable sensor data channel + if ((status = GoSystem_EnableData(go_system_, kTRUE)) != kOK) { + std::cout << "Device(). Error: GoSensor_EnableData: " << status << std::endl; + return; + } + + // retrieve setup handle + if ((go_setup_ = GoSensor_Setup(go_sensor_)) == kNULL) { + std::cout << "Device(). Error: GoSensor_Setup: Invalid Handle" << std::endl; + return; + } + + //Obtain camera model + if ((status = GoSensor_Model(go_sensor_, model_name, 50)) != kOK) { + std::cout << "Device(). Error: GoSensor_Model: " << status << std::endl; + return; + } + device_params_.model_name_ = model_name; + + //Obtain camera Serial number + device_params_.sn_ = (unsigned int)GoSensor_Id(go_sensor_); + + //Obtain exposure + capture_params_.exposure_time_ = GoSetup_Exposure(go_setup_, GO_ROLE_MAIN); + + //Obtain spacing interval + capture_params_.spacing_interval_ = GoSetup_SpacingInterval(go_setup_, GO_ROLE_MAIN); + + //print info + std::cout << "Found Sensor: " << std::endl; + device_params_.print(); } GocatorSensor::Device::~Device() { - kStatus status; - - // destroy handles - GoDestroy(go_system_); - GoDestroy(go_api_); - - //bye bye message - std::cout << "~Device(). Gocator Sensor Stopped and Device Object Destroyed." << std::endl; + kStatus status; + + // destroy handles + GoDestroy(go_system_); + GoDestroy(go_api_); + + //bye bye message + std::cout << "~Device(). Gocator Sensor Stopped and Device Object Destroyed." << std::endl; } int GocatorSensor::Device::configure(const CaptureParams & _configs) { - kStatus status; - - //set exposure - if ((status = GoSetup_SetExposure(go_setup_, GO_ROLE_MAIN, _configs.exposure_time_)) != kOK ) - { - std::cout << "configure(): Error setting Exposure Time to " << _configs.exposure_time_ << std::endl; - return -1; - } - - //set spacing interval - if ((status = GoSetup_SetSpacingInterval(go_setup_, GO_ROLE_MAIN, _configs.spacing_interval_)) != kOK ) - { - std::cout << "configure(): Error setting Spacing Interval to " << _configs.spacing_interval_ << std::endl; - return -1; - } - - //set this->capture_params_ with true values from camera - capture_params_.exposure_time_ = GoSetup_Exposure(go_setup_, GO_ROLE_MAIN); - capture_params_.spacing_interval_ = GoSetup_SpacingInterval(go_setup_, GO_ROLE_MAIN); - - //print - std::cout << "Configuration Setings: " << std::endl; - capture_params_.print(); - - //return - return 1; + kStatus status; + + //set exposure + if ((status = GoSetup_SetExposure(go_setup_, GO_ROLE_MAIN, _configs.exposure_time_)) != kOK) { + std::cout << "configure(): Error setting Exposure Time to " << _configs.exposure_time_ << + std::endl; + return -1; + } + + //set spacing interval + if ((status = + GoSetup_SetSpacingInterval(go_setup_, GO_ROLE_MAIN, _configs.spacing_interval_)) != kOK) + { + std::cout << "configure(): Error setting Spacing Interval to " << _configs.spacing_interval_ << + std::endl; + return -1; + } + + //set this->capture_params_ with true values from camera + capture_params_.exposure_time_ = GoSetup_Exposure(go_setup_, GO_ROLE_MAIN); + capture_params_.spacing_interval_ = GoSetup_SpacingInterval(go_setup_, GO_ROLE_MAIN); + + //print + std::cout << "Configuration Settings: " << std::endl; + capture_params_.print(); + + //return + return 1; } int GocatorSensor::Device::start() { - kStatus status; - - // start Gocator sensor - if ((status = GoSystem_Start(go_system_)) != kOK) - { - std::cout << "Device(). Error: GoSystem_Start: " << status << std::endl; - return -1; - } + kStatus status; + + // start Gocator sensor + if ((status = GoSystem_Start(go_system_)) != kOK) { + std::cout << "Device(). Error: GoSystem_Start: " << status << std::endl; + return -1; + } + + //message to std out + //std::cout << "Gocator running ... " << std::endl; - //message to std out - //std::cout << "Gocator running ... " << std::endl; - - //set this->status_ - this->status_ = DEVICE_RUNNING; - - //return success - return 1; + //set this->status_ + this->status_ = DEVICE_RUNNING; + + //return success + return 1; } int GocatorSensor::Device::stop() { - kStatus status; - - // stop Gocator sensor - if ((status = GoSystem_Stop(go_system_)) != kOK) - { - std::cout << "~Device(). Error: GoSystem_Stop: " << status << std::endl; - return -1; - } + kStatus status; + + // stop Gocator sensor + if ((status = GoSystem_Stop(go_system_)) != kOK) { + std::cout << "~Device(). Error: GoSystem_Stop: " << status << std::endl; + return -1; + } + + //message to std out + //std::cout << "... Gocator stopped" << std::endl << std::endl; - //message to std out - //std::cout << "... Gocator stopped" << std::endl << std::endl; - - //set this->status_ - this->status_ = DEVICE_CONNECT; - - //return success - return 1; + //set this->status_ + this->status_ = DEVICE_CONNECT; + + //return success + return 1; } -int GocatorSensor::Device::getCurrentSnapshot(pcl::PointCloud & _p_cloud) +int GocatorSensor::Device::getCurrentSnapshot(pcl::PointCloud & _p_cloud) { - + } int GocatorSensor::Device::getSingleSnapshot(pcl::PointCloud & _p_cloud) { - + } int GocatorSensor::Device::getProfile(pcl::PointCloud & _p_cloud) { - unsigned int i, j, k, arrayIndex; - GoDataSet dataset = kNULL; - std::vector profileBuffer; - GoStamp *stamp =kNULL; - GoDataMsg dataObj; - k32u profilePointCount; - if (GoSystem_ReceiveData(go_system_, &dataset, RECEIVE_TIMEOUT) == kOK) - { - printf("Data message received:\n"); - printf("Dataset count: %u\n", (k32u)GoDataSet_Count(dataset)); - // each result can have multiple data items - // loop through all items in result message - for (i = 0; i < GoDataSet_Count(dataset); ++i) - { - dataObj = GoDataSet_At(dataset, i); - //Retrieve GoStamp message - switch(GoDataMsg_Type(dataObj)) - { - case GO_DATA_MESSAGE_TYPE_STAMP: - { - GoStampMsg stampMsg = dataObj; - - printf("Stamp Message batch count: %u\n", (k32u)GoStampMsg_Count(stampMsg)); - for (j = 0; j < GoStampMsg_Count(stampMsg); ++j) - { - stamp = GoStampMsg_At(stampMsg, j); - printf(" Timestamp: %llu\n", stamp->timestamp); - printf(" Encoder: %lld\n", stamp->encoder); - printf(" Frame index: %llu\n", stamp->frameIndex); - } - } - break; - case GO_DATA_MESSAGE_TYPE_UNIFORM_PROFILE: - { - GoResampledProfileMsg profileMsg = dataObj; - - printf("Resampled Profile Message batch count: %u\n", (k32u)GoResampledProfileMsg_Count(profileMsg)); - - _p_cloud.height = GoResampledProfileMsg_Count(profileMsg); - _p_cloud.width = GoResampledProfileMsg_Width(profileMsg); - _p_cloud.resize(_p_cloud.height*_p_cloud.width); - - for (k = 0; k < GoResampledProfileMsg_Count(profileMsg); ++k) - { - unsigned int validPointCount = 0; - short* data = GoResampledProfileMsg_At(profileMsg, k); - double XResolution = NM_TO_MM(GoResampledProfileMsg_XResolution(profileMsg)); - double ZResolution = NM_TO_MM(GoResampledProfileMsg_ZResolution(profileMsg)); - double XOffset = UM_TO_MM(GoResampledProfileMsg_XOffset(profileMsg)); - double ZOffset = UM_TO_MM(GoResampledProfileMsg_ZOffset(profileMsg)); - - // profileBuffer.resize(GoResampledProfileMsg_Width(profileMsg)); - - - // translate 16-bit range data to engineering units and copy profiles to memory array - for (arrayIndex = 0; arrayIndex < GoResampledProfileMsg_Width(profileMsg); ++arrayIndex) - { - - if (data[arrayIndex] != INVALID_RANGE_16BIT ) - { - // profileBuffer[arrayIndex].x = XOffset + XResolution * arrayIndex; - // profileBuffer[arrayIndex].z = ZOffset + ZResolution * data[arrayIndex]; - _p_cloud.points.at(k*_p_cloud.width+arrayIndex).x = XOffset + XResolution * arrayIndex; - _p_cloud.points.at(k*_p_cloud.width+arrayIndex).z = ZOffset + ZResolution * data[arrayIndex]; - validPointCount++; - } - else - { - // profileBuffer[arrayIndex].x = XOffset + XResolution * arrayIndex; - // profileBuffer[arrayIndex].z = INVALID_RANGE_DOUBLE; - _p_cloud.points.at(k*_p_cloud.width+arrayIndex).x = XOffset + XResolution * arrayIndex; - _p_cloud.points.at(k*_p_cloud.width+arrayIndex).z = INVALID_RANGE_DOUBLE; - } - - - } - - printf(" Profile Valid Point %d out of max %d\n", validPointCount, profilePointCount); - } - } - break; - case GO_DATA_MESSAGE_TYPE_PROFILE_POINT_CLOUD: // Note this is NON resampled profile - { - GoProfileMsg profileMsg = dataObj; - - printf("Profile Message batch count: %u\n", (k32u)GoProfileMsg_Count(profileMsg)); - - _p_cloud.height = GoProfileMsg_Count(profileMsg); - _p_cloud.width = GoProfileMsg_Width(profileMsg); - _p_cloud.resize(_p_cloud.height*_p_cloud.width); - - for (k = 0; k < GoProfileMsg_Count(profileMsg); ++k) - { - kPoint16s* data = GoProfileMsg_At(profileMsg, k); - unsigned int validPointCount = 0; - double XResolution = NM_TO_MM(GoProfileMsg_XResolution(profileMsg)); - double ZResolution = NM_TO_MM(GoProfileMsg_ZResolution(profileMsg)); - double XOffset = UM_TO_MM(GoProfileMsg_XOffset(profileMsg)); - double ZOffset = UM_TO_MM(GoProfileMsg_ZOffset(profileMsg)); - - // profileBuffer.resize(GoResampledProfileMsg_Width(profileMsg)); - - //translate 16-bit range data to engineering units and copy profiles to memory array - for (arrayIndex = 0; arrayIndex < GoProfileMsg_Width(profileMsg); ++arrayIndex) - { - if (data[arrayIndex].x != INVALID_RANGE_16BIT) - { - // profileBuffer[arrayIndex].x = XOffset + XResolution * data[arrayIndex].x; - // profileBuffer[arrayIndex].z = ZOffset + ZResolution * data[arrayIndex].y; - _p_cloud.points.at(k*_p_cloud.width+arrayIndex).x = XOffset + XResolution * data[arrayIndex].x; - _p_cloud.points.at(k*_p_cloud.width+arrayIndex).z = ZOffset + ZResolution * data[arrayIndex].y; - validPointCount++; - } - else - { - // profileBuffer[arrayIndex].x = INVALID_RANGE_DOUBLE; - // profileBuffer[arrayIndex].z = INVALID_RANGE_DOUBLE; - _p_cloud.points.at(k*_p_cloud.width+arrayIndex).x = INVALID_RANGE_DOUBLE; - _p_cloud.points.at(k*_p_cloud.width+arrayIndex).z = INVALID_RANGE_DOUBLE; - } - } - printf(" Profile Valid Point %d out of max %d\n", validPointCount, profilePointCount); - } + unsigned int i, j, k, arrayIndex; + GoDataSet dataset = kNULL; + std::vector profileBuffer; + GoStamp * stamp = kNULL; + GoDataMsg dataObj; + k32u profilePointCount; + if (GoSystem_ReceiveData(go_system_, &dataset, RECEIVE_TIMEOUT) == kOK) { + printf("Data message received:\n"); + printf("Dataset count: %u\n", (k32u)GoDataSet_Count(dataset)); + // each result can have multiple data items + // loop through all items in result message + for (i = 0; i < GoDataSet_Count(dataset); ++i) { + dataObj = GoDataSet_At(dataset, i); + //Retrieve GoStamp message + switch (GoDataMsg_Type(dataObj)) { + case GO_DATA_MESSAGE_TYPE_STAMP: + { + GoStampMsg stampMsg = dataObj; + + printf("Stamp Message batch count: %u\n", (k32u)GoStampMsg_Count(stampMsg)); + for (j = 0; j < GoStampMsg_Count(stampMsg); ++j) { + stamp = GoStampMsg_At(stampMsg, j); + printf(" Timestamp: %llu\n", stamp->timestamp); + printf(" Encoder: %lld\n", stamp->encoder); + printf(" Frame index: %llu\n", stamp->frameIndex); + } + } + break; + case GO_DATA_MESSAGE_TYPE_UNIFORM_PROFILE: + { + GoResampledProfileMsg profileMsg = dataObj; + + printf( + "Resampled Profile Message batch count: %u\n", + (k32u)GoResampledProfileMsg_Count(profileMsg)); + + _p_cloud.height = GoResampledProfileMsg_Count(profileMsg); + _p_cloud.width = GoResampledProfileMsg_Width(profileMsg); + _p_cloud.resize(_p_cloud.height * _p_cloud.width); + + for (k = 0; k < GoResampledProfileMsg_Count(profileMsg); ++k) { + unsigned int validPointCount = 0; + short * data = GoResampledProfileMsg_At(profileMsg, k); + double XResolution = NM_TO_MM(GoResampledProfileMsg_XResolution(profileMsg)); + double ZResolution = NM_TO_MM(GoResampledProfileMsg_ZResolution(profileMsg)); + double XOffset = UM_TO_MM(GoResampledProfileMsg_XOffset(profileMsg)); + double ZOffset = UM_TO_MM(GoResampledProfileMsg_ZOffset(profileMsg)); + + // profileBuffer.resize(GoResampledProfileMsg_Width(profileMsg)); + + + // translate 16-bit range data to engineering units and copy profiles to memory array + for (arrayIndex = 0; arrayIndex < GoResampledProfileMsg_Width(profileMsg); + ++arrayIndex) + { + + if (data[arrayIndex] != INVALID_RANGE_16BIT) { + // profileBuffer[arrayIndex].x = XOffset + XResolution * arrayIndex; + // profileBuffer[arrayIndex].z = ZOffset + ZResolution * data[arrayIndex]; + _p_cloud.points.at(k * _p_cloud.width + arrayIndex).x = XOffset + XResolution * + arrayIndex; + _p_cloud.points.at(k * _p_cloud.width + arrayIndex).z = ZOffset + ZResolution * + data[arrayIndex]; + validPointCount++; + } else { + // profileBuffer[arrayIndex].x = XOffset + XResolution * arrayIndex; + // profileBuffer[arrayIndex].z = INVALID_RANGE_DOUBLE; + _p_cloud.points.at(k * _p_cloud.width + arrayIndex).x = XOffset + XResolution * + arrayIndex; + _p_cloud.points.at(k * _p_cloud.width + arrayIndex).z = INVALID_RANGE_DOUBLE; } - break; - case GO_DATA_MESSAGE_TYPE_PROFILE_INTENSITY: - { - unsigned int validPointCount = 0; - GoProfileIntensityMsg intensityMsg = dataObj; - printf("Intensity Message batch count: %u\n", (k32u)GoProfileIntensityMsg_Count(intensityMsg)); - - profileBuffer.resize(GoProfileIntensityMsg_Count(intensityMsg)); - - for (k = 0; k < GoProfileIntensityMsg_Count(intensityMsg); ++k) - { - unsigned char* data = GoProfileIntensityMsg_At(intensityMsg, k); - for (arrayIndex = 0; arrayIndex < GoProfileIntensityMsg_Width(intensityMsg); ++arrayIndex) - { - profileBuffer[arrayIndex].intensity = data[arrayIndex]; - } - } + + + } + + printf( + " Profile Valid Point %d out of max %d\n", validPointCount, + profilePointCount); + } + } + break; + case GO_DATA_MESSAGE_TYPE_PROFILE_POINT_CLOUD: // Note this is NON resampled profile + { + GoProfileMsg profileMsg = dataObj; + + printf("Profile Message batch count: %u\n", (k32u)GoProfileMsg_Count(profileMsg)); + + _p_cloud.height = GoProfileMsg_Count(profileMsg); + _p_cloud.width = GoProfileMsg_Width(profileMsg); + _p_cloud.resize(_p_cloud.height * _p_cloud.width); + + for (k = 0; k < GoProfileMsg_Count(profileMsg); ++k) { + kPoint16s * data = GoProfileMsg_At(profileMsg, k); + unsigned int validPointCount = 0; + double XResolution = NM_TO_MM(GoProfileMsg_XResolution(profileMsg)); + double ZResolution = NM_TO_MM(GoProfileMsg_ZResolution(profileMsg)); + double XOffset = UM_TO_MM(GoProfileMsg_XOffset(profileMsg)); + double ZOffset = UM_TO_MM(GoProfileMsg_ZOffset(profileMsg)); + + // profileBuffer.resize(GoResampledProfileMsg_Width(profileMsg)); + + //translate 16-bit range data to engineering units and copy profiles to memory array + for (arrayIndex = 0; arrayIndex < GoProfileMsg_Width(profileMsg); ++arrayIndex) { + if (data[arrayIndex].x != INVALID_RANGE_16BIT) { + // profileBuffer[arrayIndex].x = XOffset + XResolution * data[arrayIndex].x; + // profileBuffer[arrayIndex].z = ZOffset + ZResolution * data[arrayIndex].y; + _p_cloud.points.at(k * _p_cloud.width + arrayIndex).x = XOffset + XResolution * + data[arrayIndex].x; + _p_cloud.points.at(k * _p_cloud.width + arrayIndex).z = ZOffset + ZResolution * + data[arrayIndex].y; + validPointCount++; + } else { + // profileBuffer[arrayIndex].x = INVALID_RANGE_DOUBLE; + // profileBuffer[arrayIndex].z = INVALID_RANGE_DOUBLE; + _p_cloud.points.at(k * _p_cloud.width + arrayIndex).x = INVALID_RANGE_DOUBLE; + _p_cloud.points.at(k * _p_cloud.width + arrayIndex).z = INVALID_RANGE_DOUBLE; } - break; + } + printf( + " Profile Valid Point %d out of max %d\n", validPointCount, + profilePointCount); } - } - GoDestroy(dataset); - } - else - { - printf ("Error: No data received during the waiting period\n"); + } + break; + case GO_DATA_MESSAGE_TYPE_PROFILE_INTENSITY: + { + unsigned int validPointCount = 0; + GoProfileIntensityMsg intensityMsg = dataObj; + printf( + "Intensity Message batch count: %u\n", + (k32u)GoProfileIntensityMsg_Count(intensityMsg)); + + profileBuffer.resize(GoProfileIntensityMsg_Count(intensityMsg)); + + for (k = 0; k < GoProfileIntensityMsg_Count(intensityMsg); ++k) { + unsigned char * data = GoProfileIntensityMsg_At(intensityMsg, k); + for (arrayIndex = 0; arrayIndex < GoProfileIntensityMsg_Width(intensityMsg); + ++arrayIndex) + { + profileBuffer[arrayIndex].intensity = data[arrayIndex]; + } + } + } + break; + } } - return 1; + GoDestroy(dataset); + } else { + printf("Error: No data received during the waiting period\n"); + } + return 1; } void GocatorSensor::Device::getDeviceHealth(std::string & _health_str) const { - //local variables - GoDataSet health_data = kNULL; - GoHealthMsg health_msg =kNULL; - GoIndicator *health_indicator = kNULL; - std::ostringstream sstr; - - //get health from device - if ( (GoSystem_ReceiveHealth(go_system_, &health_data, RECEIVE_TIMEOUT)) == kOK ) - { - for (unsigned int ii = 0; ii < GoDataSet_Count(health_data); ii++) - { - health_msg = GoDataSet_At(health_data, ii); - for (unsigned int jj = 0; jj < GoHealthMsg_Count(health_msg); jj++) - { - health_indicator = GoHealthMsg_At(health_msg, jj); - sstr << "Indicator[" << jj << "]:\n" - << "\tId: " << health_indicator->id << "\n" - << "\tInstance: " << health_indicator->instance << "\n" - << "\tValue: " << health_indicator->value << "\n"; - } - } - GoDestroy(health_msg); + //local variables + GoDataSet health_data = kNULL; + GoHealthMsg health_msg = kNULL; + GoIndicator * health_indicator = kNULL; + std::ostringstream sstr; + + //get health from device + if ( (GoSystem_ReceiveHealth(go_system_, &health_data, RECEIVE_TIMEOUT)) == kOK) { + for (unsigned int ii = 0; ii < GoDataSet_Count(health_data); ii++) { + health_msg = GoDataSet_At(health_data, ii); + for (unsigned int jj = 0; jj < GoHealthMsg_Count(health_msg); jj++) { + health_indicator = GoHealthMsg_At(health_msg, jj); + sstr << "Indicator[" << jj << "]:\n" + << "\tId: " << health_indicator->id << "\n" + << "\tInstance: " << health_indicator->instance << "\n" + << "\tValue: " << health_indicator->value << "\n"; + } } - - _health_str = sstr.str(); + GoDestroy(health_msg); + } + + _health_str = sstr.str(); } -void GocatorSensor::Device::getTemperature(double & _internal_temp, double & _projector_temp, double & _laser_temp) const +void GocatorSensor::Device::getTemperature( + double & _internal_temp, double & _projector_temp, + double & _laser_temp) const { - //local variables - GoDataSet health_data = kNULL; - GoHealthMsg health_msg =kNULL; - GoIndicator *health_indicator = kNULL; - //k32u instance; - - //get health dataset from device - if ( (GoSystem_ReceiveHealth(go_system_, &health_data, RECEIVE_TIMEOUT)) == kOK ) - { - for (unsigned int ii = 0; ii < GoDataSet_Count(health_data); ii++) - { - //get the health message - health_msg = GoDataSet_At(health_data, ii); - - //find in the message the internal temperature indicator, and set the value - health_indicator = GoHealthMsg_Find(health_msg, GO_HEALTH_TEMPERATURE, 0); - if (health_indicator != kNULL) _internal_temp = health_indicator->value; - else _internal_temp = -100.; - - //find in the message the projector temperature indicator, and set the value - health_indicator = GoHealthMsg_Find(health_msg, GO_HEALTH_PROJECTOR_TEMPERATURE, 0); - if (health_indicator != kNULL) _projector_temp = health_indicator->value; - else _projector_temp = -100.; - - //find in the message the projector temperature indicator, and set the value - health_indicator = GoHealthMsg_Find(health_msg, GO_HEALTH_LASER_TEMPERATURE, 0); - if (health_indicator != kNULL) _laser_temp = health_indicator->value; - else _laser_temp = -100.; - } - GoDestroy(health_msg); + //local variables + GoDataSet health_data = kNULL; + GoHealthMsg health_msg = kNULL; + GoIndicator * health_indicator = kNULL; + //k32u instance; + + //get health dataset from device + if ( (GoSystem_ReceiveHealth(go_system_, &health_data, RECEIVE_TIMEOUT)) == kOK) { + for (unsigned int ii = 0; ii < GoDataSet_Count(health_data); ii++) { + //get the health message + health_msg = GoDataSet_At(health_data, ii); + + //find in the message the internal temperature indicator, and set the value + health_indicator = GoHealthMsg_Find(health_msg, GO_HEALTH_TEMPERATURE, 0); + if (health_indicator != kNULL) {_internal_temp = health_indicator->value;} else { + _internal_temp = -100.; + } + + //find in the message the projector temperature indicator, and set the value + health_indicator = GoHealthMsg_Find(health_msg, GO_HEALTH_PROJECTOR_TEMPERATURE, 0); + if (health_indicator != kNULL) {_projector_temp = health_indicator->value;} else { + _projector_temp = -100.; + } + + //find in the message the projector temperature indicator, and set the value + health_indicator = GoHealthMsg_Find(health_msg, GO_HEALTH_LASER_TEMPERATURE, 0); + if (health_indicator != kNULL) {_laser_temp = health_indicator->value;} else { + _laser_temp = -100.; + } } - + GoDestroy(health_msg); + } + } int GocatorSensor::Device::close() { - + } void GocatorSensor::Device::printDeviceData() const { - + } -void GocatorSensor::Device::sendTrigger() const { - printf("sending trigger \n"); - kStatus status = GoSensor_Trigger(go_sensor_); - if (status != kOK) - { - printf("Error: GoSensor_Connect:%d\n", status); - return; - } +void GocatorSensor::Device::sendTrigger() const +{ + printf("sending trigger \n"); + kStatus status = GoSensor_Trigger(go_sensor_); + if (status != kOK) { + printf("Error: GoSensor_Connect:%d\n", status); + return; + } } diff --git a/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.h b/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.h index d7fda34..685a9c6 100644 --- a/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.h +++ b/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.h @@ -17,171 +17,172 @@ //constants #define SENSOR_IP "192.168.1.10" // sensor IP address #define RECEIVE_TIMEOUT 20000000 // timeout for snapshot acquisition -#define INVALID_RANGE_16BIT ((signed short)0x8000) // gocator transmits range data as 16-bit signed integers. 0x8000 signifies invalid range data. -#define DOUBLE_MAX ((k64f)1.7976931348623157e+308) // 64-bit double - largest positive value. -#define INVALID_RANGE_DOUBLE ((k64f)-DOUBLE_MAX) // floating point value to represent invalid range data. -#define NM_TO_MM(VALUE) (((k64f)(VALUE))/1000000.0) -#define UM_TO_MM(VALUE) (((k64f)(VALUE))/1000.0) +#define INVALID_RANGE_16BIT ((signed short)0x8000) // gocator transmits range data as 16-bit signed integers. 0x8000 signifies invalid range data. +#define DOUBLE_MAX ((k64f)1.7976931348623157e+308) // 64-bit double - largest positive value. +#define INVALID_RANGE_DOUBLE ((k64f) - DOUBLE_MAX) // floating point value to represent invalid range data. +#define NM_TO_MM(VALUE) (((k64f)(VALUE)) / 1000000.0) +#define UM_TO_MM(VALUE) (((k64f)(VALUE)) / 1000.0) namespace GocatorSensor { -typedef struct ProfilePoint -{ + typedef struct ProfilePoint + { double x; // x-coordinate in engineering units (mm) - position along laser line double z; // z-coordinate in engineering units (mm) - height (at the given x position) unsigned char intensity; -} ProfilePoint; + } ProfilePoint; //status values -enum {DEVICE_NOT_FOUND=0,DEVICE_FOUND,DEVICE_NOT_CONNECT,DEVICE_CONNECT,DEVICE_RUNNING}; - + enum {DEVICE_NOT_FOUND=0, DEVICE_FOUND, DEVICE_NOT_CONNECT, DEVICE_CONNECT, DEVICE_RUNNING}; + //device parameters struct -struct DeviceParams -{ - std::string ip_address_; - std::string model_name_; - unsigned int sn_; - - void print() const - { - std::cout << "\tIP ad: \t" << ip_address_ << std::endl; - std::cout << "\tModel: \t" << model_name_ << std::endl; - std::cout << "\tSN: \t" << sn_ << std::endl; - } -}; + struct DeviceParams + { + std::string ip_address_; + std::string model_name_; + unsigned int sn_; + + void print() const + { + std::cout << "\tIP ad: \t" << ip_address_ << std::endl; + std::cout << "\tModel: \t" << model_name_ << std::endl; + std::cout << "\tSN: \t" << sn_ << std::endl; + } + }; //device configuration struct -struct CaptureParams -{ - double exposure_time_; //in useconds + struct CaptureParams + { + double exposure_time_; //in useconds double spacing_interval_; //in millimeters - + void print() const { - std::cout << "\texposure [us]: \t" << exposure_time_ << std::endl; - std::cout << "\tspacing [mm]: \t" << spacing_interval_ << std::endl; + std::cout << "\texposure [us]: \t" << exposure_time_ << std::endl; + std::cout << "\tspacing [mm]: \t" << spacing_interval_ << std::endl; } -}; + }; //Device class -class Device -{ + class Device + { protected: - //current point cloud. Maybe not necessary to be here! - //pcl::PointCloud::Ptr p_cloud_; //p_cloud_ = new pcl::PointCloud - - //driver status - unsigned int status_; - - //device fixed params - DeviceParams device_params_; - - //device configuration - CaptureParams capture_params_; - - //GO API objects - kAssembly go_api_; - GoSystem go_system_; - GoSensor go_sensor_; - GoSetup go_setup_; - GoDataSet go_dataset_; - GoStamp *go_stamp_ptr_; - + //current point cloud. Maybe not necessary to be here! + //pcl::PointCloud::Ptr p_cloud_; //p_cloud_ = new pcl::PointCloud + + //driver status + unsigned int status_; + + //device fixed params + DeviceParams device_params_; + + //device configuration + CaptureParams capture_params_; + + //GO API objects + kAssembly go_api_; + GoSystem go_system_; + GoSensor go_sensor_; + GoSetup go_setup_; + GoDataSet go_dataset_; + GoStamp * go_stamp_ptr_; + public: - /** \brief Constructor - * - * Constructor. Sets params_ struct. - * - **/ - Device(const std::string & _ip_address); - - /** \brief Destructor - * - * Destructor - * - **/ - ~Device(); - - /** \brief Connect to a pysical device given an ip address - * - * Connect to a pysical device given an ip address - * - **/ -// int connect(); - - /** \brief Set/get device parameters to/from the camera - * - * Set/get device parameters to/from the camera - * - **/ - int configure(const CaptureParams & _configs); - - /** \brief Start device data acquisition - * - * Start device data acquisition - * - **/ - int start(); - - /** \brief Stop device dat acquisition - * - * Stop device data acquisition - * - **/ - int stop(); - - /** \brief Get the current snapshot - * - * Get the current snapshot, when in continuous acquisition - * - **/ - int getCurrentSnapshot(pcl::PointCloud & _p_cloud); - - /** \brief Get a single snapshot in the same thread - * - * Get a single snapshot in the same thread - * - **/ - int getSingleSnapshot(pcl::PointCloud & _p_cloud); - - int getProfile(pcl::PointCloud & _p_cloud); - - - /** \brief Returns all health data as a string - * - * Returns all health data as a string - * - **/ - void getDeviceHealth(std::string & _health_str) const; - - /** \brief Returns three device temperatures - * - * Returns three device temperatures: internal, projector and laser - * - **/ - void getTemperature(double & _internal_temp, double & _projector_temp, double & _laser_temp) const; - - /** \brief Close the connection to a physical device - * - * Close the connection to a physical device - * - **/ - int close(); - - /** \brief Print the device configuration - * - * Print the device configuration - * - **/ - void printDeviceData() const; - - /** \brief Send a trigger signal - * - **/ - void sendTrigger() const; -};//close class + /** \brief Constructor + * + * Constructor. Sets params_ struct. + * + **/ + Device(const std::string & _ip_address); + + /** \brief Destructor + * + * Destructor + * + **/ + ~Device(); + + /** \brief Connect to a pysical device given an ip address + * + * Connect to a pysical device given an ip address + * + **/ +// int connect(); + + /** \brief Set/get device parameters to/from the camera + * + * Set/get device parameters to/from the camera + * + **/ + int configure(const CaptureParams & _configs); + + /** \brief Start device data acquisition + * + * Start device data acquisition + * + **/ + int start(); + + /** \brief Stop device dat acquisition + * + * Stop device data acquisition + * + **/ + int stop(); + + /** \brief Get the current snapshot + * + * Get the current snapshot, when in continuous acquisition + * + **/ + int getCurrentSnapshot(pcl::PointCloud < pcl::PointXYZ > & _p_cloud); + + /** \brief Get a single snapshot in the same thread + * + * Get a single snapshot in the same thread + * + **/ + int getSingleSnapshot(pcl::PointCloud < pcl::PointXYZ > & _p_cloud); + + int getProfile(pcl::PointCloud < pcl::PointXYZ > & _p_cloud); + + + /** \brief Returns all health data as a string + * + * Returns all health data as a string + * + **/ + void getDeviceHealth(std::string & _health_str) const; + + /** \brief Returns three device temperatures + * + * Returns three device temperatures: internal, projector and laser + * + **/ + void getTemperature( + double & _internal_temp, double & _projector_temp, + double & _laser_temp) const; + + /** \brief Close the connection to a physical device + * + * Close the connection to a physical device + * + **/ + int close(); + + /** \brief Print the device configuration + * + * Print the device configuration + * + **/ + void printDeviceData() const; + + /** \brief Send a trigger signal + * + **/ + void sendTrigger() const; + };//close class }//close namespace #endif - diff --git a/3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp b/3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp index abc9295..54d80c5 100644 --- a/3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp +++ b/3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp @@ -6,7 +6,7 @@ #include "rclcpp/rclcpp.hpp" #include "pcl_conversions/pcl_conversions.h" #include "std_msgs/msg/empty.hpp" -#include "printer3d_gocator_msgs/srv/gocator_pt_cloud.hpp" +#include "printer3d_gocator_msgs/srv/gocator_pt_cloud.hpp" #include "../driver/gocatorSensor.h" @@ -14,45 +14,49 @@ using namespace std::chrono_literals; class GocatorSensorNode : public rclcpp::Node { - public: - GocatorSensorNode() - : Node("gocatorSensorNode") - { - gsensor_ = new GocatorSensor::Device(SENSOR_IP); - capture_params_.exposure_time_ = 110; - capture_params_.spacing_interval_ = 0.1; - gsensor_->configure(capture_params_); +public: + GocatorSensorNode() + : Node("gocatorSensorNode") + { + gsensor_ = new GocatorSensor::Device(SENSOR_IP); + capture_params_.exposure_time_ = 110; + capture_params_.spacing_interval_ = 0.1; + gsensor_->configure(capture_params_); - service_ = this->create_service("gocator_get_profile", std::bind(&GocatorSensorNode::profile_snapshot, this, std::placeholders::_1, std::placeholders::_2)); - // publisher_ = this->create_publisher("gocatorPTCloud_topic", 10); - } + service_ = this->create_service( + "gocator_get_profile", + std::bind( + &GocatorSensorNode::profile_snapshot, this, std::placeholders::_1, + std::placeholders::_2)); + // publisher_ = this->create_publisher("gocatorPTCloud_topic", 10); + } - private: - void profile_snapshot(std::shared_ptr request, - std::shared_ptr response) - { - pcl::PointCloud cloud; - RCLCPP_INFO(this->get_logger(),"Processing service request!"); - gsensor_->start(); - gsensor_->sendTrigger(); - if ( gsensor_->getProfile(cloud) == 1 ) - { - auto pcloud = sensor_msgs::msg::PointCloud2(); - pcl::toROSMsg(cloud,pcloud); - pcloud.header.frame_id = "gocator_sensor"; - pcloud.header.stamp = this->get_clock()->now(); +private: + void profile_snapshot( + std::shared_ptr request, + std::shared_ptr response) + { + pcl::PointCloud cloud; + RCLCPP_INFO(this->get_logger(), "Processing service request!"); + gsensor_->start(); + gsensor_->sendTrigger(); + if (gsensor_->getProfile(cloud) == 1) { + auto pcloud = sensor_msgs::msg::PointCloud2(); + pcl::toROSMsg(cloud, pcloud); + pcloud.header.frame_id = "gocator_sensor"; + pcloud.header.stamp = this->get_clock()->now(); - // publisher_->publish(pcloud); + // publisher_->publish(pcloud); - response->pcloud = pcloud; - } + response->pcloud = pcloud; + } - } + } - rclcpp::Service::SharedPtr service_; - rclcpp::Publisher::SharedPtr publisher_; - GocatorSensor::Device *gsensor_; - GocatorSensor::CaptureParams capture_params_; + rclcpp::Service::SharedPtr service_; + rclcpp::Publisher::SharedPtr publisher_; + GocatorSensor::Device * gsensor_; + GocatorSensor::CaptureParams capture_params_; }; int main(int argc, char * argv[]) @@ -61,4 +65,4 @@ int main(int argc, char * argv[]) rclcpp::spin(std::make_shared()); rclcpp::shutdown(); return 0; -} \ No newline at end of file +} From 512cd16a31e7c948b7b9662a0c9bd799adc921bd Mon Sep 17 00:00:00 2001 From: MosserLoic Date: Tue, 18 Apr 2023 19:50:29 +0200 Subject: [PATCH 13/30] manually add corrections to the code precommit fail on clang-format and ament_cpplint --- .../nodes/gcode_monitor_node.py | 180 ++++---- .../nodes/image_capture_calibration.py | 85 ++-- .../nodes/image_capture_node.py | 50 ++- .../launch/launch_printer3d.py | 16 + .../printer3d_manager/nodes/point_cloud2.py | 119 ++---- .../nodes/printer3d_constant.py | 13 + .../nodes/printer_control_node.py | 384 ++++++++--------- .../nodes/printer_control_test.py | 387 +++++++++--------- .../src/printer3d_manager/nodes/utility.py | 187 +++++---- 3D_printer/src/printer3d_msgs/CMakeLists.txt | 4 +- .../printer3d_profile_capture/CMakeLists.txt | 28 +- .../src/driver/CMakeLists.txt | 40 +- .../src/driver/gocatorSensor.cpp | 87 ++-- .../src/driver/gocatorSensor.h | 80 ++-- .../src/nodes/gocatorSensorNode.cpp | 18 +- 15 files changed, 850 insertions(+), 828 deletions(-) diff --git a/3D_printer/src/printer3d_driver/nodes/gcode_monitor_node.py b/3D_printer/src/printer3d_driver/nodes/gcode_monitor_node.py index d6218c5..44782a4 100644 --- a/3D_printer/src/printer3d_driver/nodes/gcode_monitor_node.py +++ b/3D_printer/src/printer3d_driver/nodes/gcode_monitor_node.py @@ -1,110 +1,104 @@ #!/usr/bin/env python3 +# Copyright 2023 ICube Laboratory, University of Strasbourg +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import rclpy -from rclpy.action import ActionClient from rclpy.node import Node - import time import serial -import numpy as np - -from printer3d_msgs.srv import ProfileCommand from printer3d_msgs.srv import GcodeCommand -from printer3d_msgs.srv import ImageCommand -def openSerialPort(port, baud): - #open the serial port - print('Opening Serial Port...') - try: - s = serial.Serial(port, baud) - if (s.isOpen() == True): - print(port + " has opened successfully.") - return s - else: - print(port + " has failed to open.") - exit() - except: - print("An error occurred while opening " + port) - exit() -def removeComment(string): - if (string.find(';') == -1): - return string +def openSerialPort(port, baud): + # open the serial port + print('Opening Serial Port...') + try: + s = serial.Serial(port, baud) + if (s.isOpen() is True): + print(port + " has opened successfully.") + return s else: - return string[:string.index(';')] - - -class GcodeMonitorNode(Node): - def __init__(self): - super().__init__('printer_gcode_monitor') - - self.serialPort = openSerialPort('/dev/ttyACM0', 250000) - self.serialPort.write(b"\n\n") - time.sleep(2) - - self.gcodeService = self.create_service(GcodeCommand, 'send_gcode', self.execute_gcode_sending) - - - def execute_gcode_sending(self, request, response): - - gcode = request.gcode_strings - - self.get_logger().info('Executing Gcode') + print(port + " has failed to open.") + exit() + except Exception: + print("An error occurred while opening " + port) + exit() - #self.get_logger().info('Gcode Received with a length of : '+str(len(gcode))) - feedback = 0.0 - - self.serialPort.flushInput() - self.i = 0 - self.total = len(gcode) - self.increment = 0.0 - - for line in gcode: - - # feedback publication - - feedback = (self.i/self.total)*100 - if feedback - self.increment > 1: - self.increment = feedback - #self.get_logger().info('Progression : '+str(feedback)) - - # Gcode Sending - - l = removeComment(line) - l = l.strip() - self.i += 1 - if (l.isspace() == False and len(l) > 0): - if ' E' in l: - self.lastExtrusionSended = float(l.split('E')[1]) - #self.get_logger().info('extrusion changed : '+str(feedback)) - self.serialPort.write((l + "\n").encode('ascii')) - grbl_out = self.serialPort.readline() # wait for response from printer - grbl_out = grbl_out.strip().decode('ascii') - while 'ok' not in grbl_out: - grbl_out = self.serialPort.readline() # wait for response from printer - grbl_out = grbl_out.strip().decode('ascii') - - - self.serialPort.write(b"M400\n") - grbl_out = self.serialPort.readline() # wait for response from printer - grbl_out = grbl_out.strip().decode('ascii') - while 'ok' not in grbl_out: - grbl_out = self.serialPort.readline() # wait for response from printer - grbl_out = grbl_out.strip().decode('ascii') +def removeComment(string): + if (string.find(';') == -1): + return string + else: + return string[:string.index(';')] - self.serialPort.write(b"M400\n") - grbl_out = self.serialPort.readline() # wait for response from printer +class GcodeMonitorNode(Node): + def __init__(self): + super().__init__('printer_gcode_monitor') + self.serialPort = openSerialPort('/dev/ttyACM0', 250000) + self.serialPort.write(b"\n\n") + time.sleep(2) + self.gcodeService = self.create_service(GcodeCommand, 'send_gcode', self.execute_gcode_sending) + + def execute_gcode_sending(self, request, response): + gcode = request.gcode_strings + self.get_logger().info('Executing Gcode') + feedback = 0.0 + self.serialPort.flushInput() + self.i = 0 + self.total = len(gcode) + self.increment = 0.0 + + for line in gcode: + # feedback publication + feedback = (self.i/self.total)*100 + if feedback - self.increment > 1: + self.increment = feedback + + # Gcode Sending + + line = removeComment(line) + line = line.strip() + self.i += 1 + if (line.isspace() is False and len(line) > 0): + if ' E' in line: + self.lastExtrusionSended = float(line.split('E')[1]) + self.serialPort.write((line + "\n").encode('ascii')) + grbl_out = self.serialPort.readline() # wait for response from printer grbl_out = grbl_out.strip().decode('ascii') - while 'ok' not in grbl_out: - grbl_out = self.serialPort.readline() # wait for response from printer - grbl_out = grbl_out.strip().decode('ascii') - - - self.get_logger().info('gcode sending completely finished') - response.validation = True - - return response + while 'ok' not in grbl_out: + grbl_out = self.serialPort.readline() # wait for response from printer + grbl_out = grbl_out.strip().decode('ascii') + + self.serialPort.write(b"M400\n") + grbl_out = self.serialPort.readline() # wait for response from printer + grbl_out = grbl_out.strip().decode('ascii') + while 'ok' not in grbl_out: + grbl_out = self.serialPort.readline() # wait for response from printer + grbl_out = grbl_out.strip().decode('ascii') + + self.serialPort.write(b"M400\n") + grbl_out = self.serialPort.readline() # wait for response from printer + grbl_out = grbl_out.strip().decode('ascii') + while 'ok' not in grbl_out: + grbl_out = self.serialPort.readline() # wait for response from printer + grbl_out = grbl_out.strip().decode('ascii') + + self.get_logger().info('gcode sending completely finished') + response.validation = True + + return response if __name__ == '__main__': diff --git a/3D_printer/src/printer3d_image_capture/nodes/image_capture_calibration.py b/3D_printer/src/printer3d_image_capture/nodes/image_capture_calibration.py index b58cd0b..160445c 100644 --- a/3D_printer/src/printer3d_image_capture/nodes/image_capture_calibration.py +++ b/3D_printer/src/printer3d_image_capture/nodes/image_capture_calibration.py @@ -1,55 +1,64 @@ #!/usr/bin/env python3 +# Copyright 2023 ICube Laboratory, University of Strasbourg +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import rclpy -from rclpy.action import ActionClient from rclpy.node import Node - -from printer3d_msgs.srv import ProfileCommand from printer3d_msgs.srv import GcodeCommand -from printer3d_msgs.srv import ImageCommand import cv2 YPOSPHOTO = 200 + class ImageCaptureNode(Node): - def __init__(self,cameraNumber = 0): - super().__init__('printer_image_capture') - self.cameraNumber = cameraNumber - - self.client_printer_driver = self.create_client(GcodeCommand, 'send_gcode') - while not self.client_printer_driver.wait_for_service(timeout_sec=1.0): - self.get_logger().info('profile measure service not available, waiting again...') - self.req_printer_driver = GcodeCommand.Request() - - def __del__(self): - self.webcam.release() - - def showVideo(self): - self.webcam = cv2.VideoCapture("/dev/video"+str(self.cameraNumber)) # Be carefull with the number after video - while(True): - check, frame = self.webcam.read() - cv2.imshow('frame', frame) - if cv2.waitKey(1) & 0xFF == ord('q'): - break - self.webcam.release() - cv2.destroyAllWindows() - return 0 - - def sendGcodeSendingRequest(self,gcode): - - """ Request the sending of a certain gcode list tanken as input through the 'send_gcode' service """ - self.req_printer_driver.gcode_strings = gcode - self.future_printer_driver = self.client_printer_driver.call_async(self.req_printer_driver) - while rclpy.ok(): - rclpy.spin_once(self) - if self.future_printer_driver.done(): - self.get_logger().info('gcode sended') - break + def __init__(self, cam=0): + super().__init__('printer_image_capture') + self.cameraNumber = cam + + self.client_printer_driver = self.create_client(GcodeCommand, 'send_gcode') + while not self.client_printer_driver.wait_for_service(timeout_sec=1.0): + self.get_logger().info('profile measure service not available, waiting again...') + self.req_printer_driver = GcodeCommand.Request() + + def __del__(self): + self.webcam.release() + + def showVideo(self): + self.webcam = cv2.VideoCapture("/dev/video" + str(self.cameraNumber)) # Be careful with the number after video + while (True): + check, frame = self.webcam.read() + cv2.imshow('frame', frame) + if cv2.waitKey(1) & 0xFF == ord('q'): + break + self.webcam.release() + cv2.destroyAllWindows() + return 0 + + def sendGcodeSendingRequest(self, gcode): + self.req_printer_driver.gcode_strings = gcode + self.future_printer_driver = self.client_printer_driver.call_async(self.req_printer_driver) + while rclpy.ok(): + rclpy.spin_once(self) + if self.future_printer_driver.done(): + self.get_logger().info('gcode sended') + break if __name__ == '__main__': rclpy.init() image_capture_node = ImageCaptureNode(2) - gcode = ['G28\n','G1 Y'+str(YPOSPHOTO)+' F2400\n'] + gcode = ['G28\n', 'G1 Y'+str(YPOSPHOTO)+' F2400\n'] image_capture_node.sendGcodeSendingRequest(gcode) image_capture_node.showVideo() rclpy.shutdown() diff --git a/3D_printer/src/printer3d_image_capture/nodes/image_capture_node.py b/3D_printer/src/printer3d_image_capture/nodes/image_capture_node.py index 8cb0eec..635dcd3 100644 --- a/3D_printer/src/printer3d_image_capture/nodes/image_capture_node.py +++ b/3D_printer/src/printer3d_image_capture/nodes/image_capture_node.py @@ -1,32 +1,42 @@ #!/usr/bin/env python3 +# Copyright 2023 ICube Laboratory, University of Strasbourg +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import rclpy -from rclpy.action import ActionClient from rclpy.node import Node -from printer3d_msgs.srv import ProfileCommand -from printer3d_msgs.srv import GcodeCommand from printer3d_msgs.srv import ImageCommand import cv2 - class ImageCaptureNode(Node): - def __init__(self,cameraNumber = 0): - super().__init__('printer_image_capture') - self.cameraNumber = cameraNumber - self.imageService = self.create_service(ImageCommand, 'ask_capture_image', self.takePicture) - - def __del__(self): - self.webcam.release() - - def takePicture(self, request, response): - webcam = cv2.VideoCapture("/dev/video"+str(self.cameraNumber)) # Be carefull with the number after video - check, frame = webcam.read() - webcam.release() - cv2.imwrite(filename=request.filename, img=frame) - self.get_logger().info('image acquired : '+request.filename) - response.confirmation = True - return response + def __init__(self, cam=0): + super().__init__('printer_image_capture') + self.cameraNumber = cam + self.imageService = self.create_service(ImageCommand, 'ask_capture_image', self.takePicture) + + def __del__(self): + self.webcam.release() + + def takePicture(self, request, response): + webcam = cv2.VideoCapture("/dev/video"+str(self.cameraNumber)) # Be careful with the number after video + check, frame = webcam.read() + webcam.release() + cv2.imwrite(filename=request.filename, img=frame) + self.get_logger().info('image acquired : '+request.filename) + response.confirmation = True + return response if __name__ == '__main__': diff --git a/3D_printer/src/printer3d_manager/launch/launch_printer3d.py b/3D_printer/src/printer3d_manager/launch/launch_printer3d.py index a91e120..84efb95 100644 --- a/3D_printer/src/printer3d_manager/launch/launch_printer3d.py +++ b/3D_printer/src/printer3d_manager/launch/launch_printer3d.py @@ -1,6 +1,22 @@ +#!/usr/bin/env python3 +# Copyright 2023 ICube Laboratory, University of Strasbourg +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from launch import LaunchDescription from launch_ros.actions import Node + def generate_launch_description(): return LaunchDescription([ Node( diff --git a/3D_printer/src/printer3d_manager/nodes/point_cloud2.py b/3D_printer/src/printer3d_manager/nodes/point_cloud2.py index 4a42b69..588cd21 100644 --- a/3D_printer/src/printer3d_manager/nodes/point_cloud2.py +++ b/3D_printer/src/printer3d_manager/nodes/point_cloud2.py @@ -1,36 +1,17 @@ #!/usr/bin/env python3 - -# Software License Agreement (BSD License) -# -# Copyright (c) 2008, Willow Garage, Inc. -# All rights reserved. +# Copyright 2023 ICube Laboratory, University of Strasbourg # -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at # -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of Willow Garage, Inc. nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. +# http://www.apache.org/licenses/LICENSE-2.0 # -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ Serialization of sensor_msgs.PointCloud2 messages. @@ -49,35 +30,22 @@ from sensor_msgs.msg import PointCloud2, PointField _DATATYPES = {} -_DATATYPES[PointField.INT8] = ('b', 1) -_DATATYPES[PointField.UINT8] = ('B', 1) -_DATATYPES[PointField.INT16] = ('h', 2) -_DATATYPES[PointField.UINT16] = ('H', 2) -_DATATYPES[PointField.INT32] = ('i', 4) -_DATATYPES[PointField.UINT32] = ('I', 4) +_DATATYPES[PointField.INT8] = ('b', 1) +_DATATYPES[PointField.UINT8] = ('B', 1) +_DATATYPES[PointField.INT16] = ('h', 2) +_DATATYPES[PointField.UINT16] = ('H', 2) +_DATATYPES[PointField.INT32] = ('i', 4) +_DATATYPES[PointField.UINT32] = ('I', 4) _DATATYPES[PointField.FLOAT32] = ('f', 4) _DATATYPES[PointField.FLOAT64] = ('d', 8) + def read_points(cloud, field_names=None, skip_nans=False, uvs=[]): - """ - Read points from a L{sensor_msgs.PointCloud2} message. - - @param cloud: The point cloud to read from. - @type cloud: L{sensor_msgs.PointCloud2} - @param field_names: The names of fields to read. If None, read all fields. [default: None] - @type field_names: iterable - @param skip_nans: If True, then don't return any point with a NaN value. - @type skip_nans: bool [default: False] - @param uvs: If specified, then only return the points at the given coordinates. [default: empty list] - @type uvs: iterable - @return: Generator which yields a list of values for each point. - @rtype: generator - """ assert isinstance(cloud, PointCloud2), 'cloud is not a sensor_msgs.msg.PointCloud2' fmt = _get_struct_fmt(cloud.is_bigendian, cloud.fields, field_names) width, height, point_step, row_step, data, isnan = cloud.width, cloud.height, \ - cloud.point_step, cloud.row_step, \ - cloud.data, math.isnan + cloud.point_step, cloud.row_step, \ + cloud.data, math.isnan unpack_from = struct.Struct(fmt).unpack_from if skip_nans: @@ -115,23 +83,8 @@ def read_points(cloud, field_names=None, skip_nans=False, uvs=[]): yield unpack_from(data, offset) offset += point_step + def read_points_list(cloud, field_names=None, skip_nans=False, uvs=[]): - """ - Read points from a L{sensor_msgs.PointCloud2} message. - - This function returns a list of namedtuples. It operates on top of the read_points method. For more efficient access use read_points directly. - - @param cloud: The point cloud to read from. - @type cloud: L{sensor_msgs.PointCloud2} - @param field_names: The names of fields to read. If None, read all fields. [default: None] - @type field_names: iterable - @param skip_nans: If True, then don't return any point with a NaN value. - @type skip_nans: bool [default: False] - @param uvs: If specified, then only return the points at the given coordinates. [default: empty list] - @type uvs: iterable - @return: List of namedtuples containing the values for each point - @rtype: list - """ assert isinstance(cloud, PointCloud2), 'cloud is not a sensor_msgs.msg.PointCloud2' if field_names is None: @@ -139,23 +92,10 @@ def read_points_list(cloud, field_names=None, skip_nans=False, uvs=[]): Point = namedtuple("Point", field_names) - return [Point._make(l) for l in read_points(cloud, field_names, skip_nans, uvs)] + return [Point._make(lines) for lines in read_points(cloud, field_names, skip_nans, uvs)] + def create_cloud(header, fields, points): - """ - Create a L{sensor_msgs.msg.PointCloud2} message. - - @param header: The point cloud header. - @type header: L{std_msgs.msg.Header} - @param fields: The point cloud fields. - @type fields: iterable of L{sensor_msgs.msg.PointField} - @param points: The point cloud points. - @type points: list of iterables, i.e. one iterable for each point, with the - elements of each iterable being the values of the fields for - that point (in the same order as the fields parameter) - @return: The point cloud. - @rtype: L{sensor_msgs.msg.PointCloud2} - """ cloud_struct = struct.Struct(_get_struct_fmt(False, fields)) buff = ctypes.create_string_buffer(cloud_struct.size * len(points)) @@ -176,23 +116,14 @@ def create_cloud(header, fields, points): row_step=cloud_struct.size * len(points), data=buff.raw) -def create_cloud_xyz32(header, points): - """ - Create a L{sensor_msgs.msg.PointCloud2} message with 3 float32 fields (x, y, z). - - @param header: The point cloud header. - @type header: L{std_msgs.msg.Header} - @param points: The point cloud points. - @type points: iterable - @return: The point cloud. - @rtype: L{sensor_msgs.msg.PointCloud2} - """ +def create_cloud_xyz32(header, points): fields = [PointField(name='x', offset=0, datatype=PointField.FLOAT32, count=1), PointField(name='y', offset=4, datatype=PointField.FLOAT32, count=1), PointField(name='z', offset=8, datatype=PointField.FLOAT32, count=1)] return create_cloud(header, fields, points) + def _get_struct_fmt(is_bigendian, fields, field_names=None): fmt = '>' if is_bigendian else '<' offset = 0 @@ -204,7 +135,7 @@ def _get_struct_fmt(is_bigendian, fields, field_names=None): print('Skipping unknown PointField datatype [%d]' % field.datatype, file=sys.stderr) else: datatype_fmt, datatype_length = _DATATYPES[field.datatype] - fmt += field.count * datatype_fmt + fmt += field.count * datatype_fmt offset += field.count * datatype_length return fmt diff --git a/3D_printer/src/printer3d_manager/nodes/printer3d_constant.py b/3D_printer/src/printer3d_manager/nodes/printer3d_constant.py index 0a95ed1..bc8d76a 100644 --- a/3D_printer/src/printer3d_manager/nodes/printer3d_constant.py +++ b/3D_printer/src/printer3d_manager/nodes/printer3d_constant.py @@ -1,4 +1,17 @@ #!/usr/bin/env python3 +# Copyright 2023 ICube Laboratory, University of Strasbourg +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. XMIN = 0 XMAX = 190 diff --git a/3D_printer/src/printer3d_manager/nodes/printer_control_node.py b/3D_printer/src/printer3d_manager/nodes/printer_control_node.py index 377bc55..72b4fed 100644 --- a/3D_printer/src/printer3d_manager/nodes/printer_control_node.py +++ b/3D_printer/src/printer3d_manager/nodes/printer_control_node.py @@ -1,215 +1,215 @@ #!/usr/bin/env python3 +# Copyright 2023 ICube Laboratory, University of Strasbourg +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import rclpy -from rclpy.action import ActionClient from rclpy.node import Node -from printer3d_msgs.srv import ProfileCommand from printer3d_msgs.srv import GcodeCommand from printer3d_msgs.srv import ImageCommand from printer3d_gocator_msgs.srv import GocatorPTCloud -from utility import * +from utility import getBordersSimpleGcode, getBordersGcode, work_on_gcode_file import printer3d_constant -from sensor_msgs.msg import PointCloud2 import point_cloud2 as pc2 import os import numpy as np - class PrinterControlNode(Node): - def __init__(self, historyFilename): - super().__init__('printer_control') - - """Initialisation of the printing process workspace""" - self.historyFilename = historyFilename - try: - os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename) - except: - pass - - try: - os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/gcode') - except: - pass + def __init__(self, historyFilename): + super().__init__('printer_control') - try: - os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/scan') - except: - pass + """Initialisation of the printing process workspace""" + self.historyFilename = historyFilename + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename) + except Exception: + pass + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/gcode') + except Exception: + pass + + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/scan') + except Exception: + pass + + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/photos') + except Exception: + pass + + # access to the image capture service + + self.client_image_capture = self.create_client(ImageCommand, 'ask_capture_image') + while not self.client_image_capture.wait_for_service(timeout_sec=1.0): + self.get_logger().info('image capture service not available, waiting again...') + self.req_image_capture = ImageCommand.Request() + + # access to the profile measure service + + self.client_profile_measure = self.create_client(GocatorPTCloud, 'gocator_get_profile') + while not self.client_profile_measure.wait_for_service(timeout_sec=1.0): + self.get_logger().info('profile measure service not available, waiting again...') + self.req_profile_measure = GocatorPTCloud.Request() + + # access to the printer driver service + + self.client_printer_driver = self.create_client(GcodeCommand, 'send_gcode') + while not self.client_printer_driver.wait_for_service(timeout_sec=1.0): + self.get_logger().info('profile measure service not available, waiting again...') + self.req_printer_driver = GcodeCommand.Request() + + self.imageNumber = 0 + self.scanNumber = 0 + + def loadGcode(self, gcodeFilename): + fileFullGcode = open(gcodeFilename) + rawGode = fileFullGcode.readlines() + fileFullGcode.close() + + (self.xMin, self.yMin, self.zMin, self.xMax, self.yMax, self.zMax) = getBordersGcode(rawGode) + self.get_logger().info('xMin : ' + str(self.xMin)) + self.get_logger().info('xMax : ' + str(self.xMax)) + self.get_logger().info('yMin : ' + str(self.yMin)) + self.get_logger().info('yMax : ' + str(self.yMax)) + self.get_logger().info('zMin : ' + str(self.zMin)) + self.get_logger().info('zMax : ' + str(self.zMax)) + + assert self.xMin >= printer3d_constant.XMIN + assert self.xMax <= printer3d_constant.XMAX + + assert self.yMin >= printer3d_constant.YMIN + assert self.yMax <= printer3d_constant.YMAX + + assert self.zMin >= printer3d_constant.ZMIN + assert self.zMax <= printer3d_constant.ZMAX + self.gcodeLayers = work_on_gcode_file(rawGode) + + return self.gcodeLayers + + def verifyGcodeBeforeSending(self, gcodeToVerify): + (self.xMin, self.yMin, self.zMin, self.xMax, self.yMax, self.zMax) = getBordersSimpleGcode(gcodeToVerify) + testXMin = self.xMin >= printer3d_constant.XMIN + testXMax = self.xMax <= printer3d_constant.XMAX + + testYMin = self.yMin >= printer3d_constant.YMIN + testYMax = self.yMax <= printer3d_constant.YMAX + + testZMin = self.zMin >= printer3d_constant.ZMIN + testZMax = self.zMax <= printer3d_constant.ZMAX + + if testXMin is False or testXMax is False or testYMin is False or testYMax is False or testZMin is False or testZMax is False: + return False + else: + return True + + def scanCurrentLayer(self, printedLayer): + (layerXMin, layerYMin, layerZMin, layerXMax, layerYMax, layerZMax) = getBordersSimpleGcode(printedLayer) + + gcodeScan = [[]] + margin = 25 + + Yinit = layerYMin - printer3d_constant.GAP + Yfinal = layerYMax - printer3d_constant.GAP + step = 0.3 + + gcodeScan[0].append('G1 Z' + str(layerZMax+1)+'\n') + gcodeScan[0].append('G28 X0 Y0\n') + gcodeScan[0].append('G1 Y' + str(Yinit-(margin/2)) + ' F1200\n') + length = int((Yfinal-Yinit+margin)/step) + + self.get_logger().info('scanning begin :') + self.get_logger().info('Yinit :' + str(Yinit)) + self.get_logger().info('Yfinal :' + str(Yfinal)) + self.get_logger().info('length :' + str(length)) + + for i in range(1, length): + gcodeScan.append([]) + gcodeScan[-1].append('G1 Y' + str(Yinit-(margin/2)+(i*step))+'\n') + surface = [] + for movements in gcodeScan: + self.sendGcodeSendingRequest(movements) + profileLine = self.sendProfileMeasureRequest() + surface.append(profileLine) + np.save('/home/gulltor/Ramsai_Robotics/history/'+self.historyFilename+'/scan/layer_scan_'+str(self.scanNumber)+'.npy', np.array(surface)) + self.scanNumber += 1 + return surface + + def printCurrentLayer(self): + return 0 + + def takeCurrentLayerPhoto(self): + gcodeMoveToPos = ['G28 X0 Y0\n', 'G1 Y' + str(printer3d_constant.YPOSPHOTO) + ' F2400\n'] + self.sendGcodeSendingRequest(gcodeMoveToPos) + self.sendImageCaptureRequest('/home/gulltor/Ramsai_Robotics/history/'+self.historyFilename+'/photos/layer_photo_'+str(self.imageNumber)+'.jpg') + self.imageNumber += 1 + return 0 + + def sendImageCaptureRequest(self, filename): + self.req_image_capture.filename = filename + self.future_image_capture = self.client_image_capture.call_async(self.req_image_capture) + while rclpy.ok(): + rclpy.spin_once(self) + if self.future_image_capture.done(): + self.get_logger().info('capture finished') + break + + def sendProfileMeasureRequest(self): + profile_line = [] + self.future_profile_measure = self.client_profile_measure.call_async(self.req_profile_measure) + while rclpy.ok(): + rclpy.spin_once(self) + if self.future_profile_measure.done(): try: - os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/photos') - except: - pass - - # access to the image capture service - - self.client_image_capture = self.create_client(ImageCommand, 'ask_capture_image') - while not self.client_image_capture.wait_for_service(timeout_sec=1.0): - self.get_logger().info('image capture service not available, waiting again...') - self.req_image_capture = ImageCommand.Request() - - # access to the profile measure service - - self.client_profile_measure = self.create_client(GocatorPTCloud, 'gocator_get_profile') - while not self.client_profile_measure.wait_for_service(timeout_sec=1.0): - self.get_logger().info('profile measure service not available, waiting again...') - self.req_profile_measure = GocatorPTCloud.Request() - - # access to the printer driver service - - self.client_printer_driver = self.create_client(GcodeCommand, 'send_gcode') - while not self.client_printer_driver.wait_for_service(timeout_sec=1.0): - self.get_logger().info('profile measure service not available, waiting again...') - self.req_printer_driver = GcodeCommand.Request() - - self.imageNumber = 0 - self.scanNumber = 0 - - - def loadGcode(self,gcodeFilename): - fileFullGcode = open(gcodeFilename) - rawGode = fileFullGcode.readlines() - fileFullGcode.close() - - (self.xMin,self.yMin,self.zMin,self.xMax,self.yMax,self.zMax) = getBordersGcode(rawGode) - self.get_logger().info('xMin : '+str(self.xMin)) - self.get_logger().info('xMax : '+str(self.xMax)) - self.get_logger().info('yMin : '+str(self.yMin)) - self.get_logger().info('yMax : '+str(self.yMax)) - self.get_logger().info('zMin : '+str(self.zMin)) - self.get_logger().info('zMax : '+str(self.zMax)) - - assert self.xMin >= printer3d_constant.XMIN - assert self.xMax <= printer3d_constant.XMAX - - assert self.yMin >= printer3d_constant.YMIN - assert self.yMax <= printer3d_constant.YMAX - - assert self.zMin >= printer3d_constant.ZMIN - assert self.zMax <= printer3d_constant.ZMAX - self.gcodeLayers = work_on_gcode_file(rawGode) - - return self.gcodeLayers + self.response = self.future_profile_measure.result() + except Exception as e: + self.get_logger().info(f'Service call failed {e!r}') + else: + pcloud = self.response.pcloud + self.flag_datas_used = True - def verifyGcodeBeforeSending(self,gcodeToVerify): + gen = pc2.read_points(pcloud, skip_nans=True) + profile = list(gen) - (self.xMin,self.yMin,self.zMin,self.xMax,self.yMax,self.zMax) = getBordersSimpleGcode(gcodeToVerify) - testXMin = self.xMin >= printer3d_constant.XMIN - testXMax = self.xMax <= printer3d_constant.XMAX + for points in profile: + profile_line.append([[points[0], 0, points[2]]]) + break + self.get_logger().info('scan finished') + return profile_line - testYMin = self.yMin >= printer3d_constant.YMIN - testYMax = self.yMax <= printer3d_constant.YMAX + def sendGcodeSendingRequest(self, gcode): + assert self.verifyGcodeBeforeSending(gcode) is True - testZMin = self.zMin >= printer3d_constant.ZMIN - testZMax = self.zMax <= printer3d_constant.ZMAX + self.req_printer_driver.gcode_strings = gcode + self.future_printer_driver = self.client_printer_driver.call_async(self.req_printer_driver) + while rclpy.ok(): + rclpy.spin_once(self) + if self.future_printer_driver.done(): + self.get_logger().info('gcode sended') + break - if testXMin == False or testXMax == False or testYMin == False or testYMax == False or testZMin == False or testZMax == False: - return False - else: - return True - - def scanCurrentLayer(self,printedLayer): - (layerXMin,layerYMin,layerZMin,layerXMax,layerYMax,layerZMax) = getBordersSimpleGcode(printedLayer) - - gcodeScan = [[]] - margin = 25 - - Yinit = layerYMin - printer3d_constant.GAP - Yfinal = layerYMax - printer3d_constant.GAP - step = 0.3 - - gcodeScan[0].append('G1 Z'+str(layerZMax+1)+'\n') - gcodeScan[0].append('G28 X0 Y0\n') - gcodeScan[0].append('G1 Y'+str(Yinit-(margin/2))+' F1200\n') - length = int((Yfinal-Yinit+margin)/step) - - self.get_logger().info('scanning begin :') - self.get_logger().info('Yinit :' + str(Yinit)) - self.get_logger().info('Yfinal :'+ str(Yfinal)) - self.get_logger().info('length :'+ str(length)) - - for i in range(1,length): - gcodeScan.append([]) - gcodeScan[-1].append('G1 Y'+str(Yinit-(margin/2)+(i*step))+'\n') - surface = [] - for movements in gcodeScan: - self.sendGcodeSendingRequest(movements) - profileLine = self.sendProfileMeasureRequest() - surface.append(profileLine) - np.save('/home/gulltor/Ramsai_Robotics/history/'+self.historyFilename+'/scan/layer_scan_'+str(self.scanNumber)+'.npy',np.array(surface)) - self.scanNumber += 1 - return surface - - def printCurrentLayer(self): - return 0 - - def takeCurrentLayerPhoto(self): - gcodeMoveToPos = ['G28 X0 Y0\n','G1 Y'+str(printer3d_constant.YPOSPHOTO)+' F2400\n'] - self.sendGcodeSendingRequest(gcodeMoveToPos) - self.sendImageCaptureRequest('/home/gulltor/Ramsai_Robotics/history/'+self.historyFilename+'/photos/layer_photo_'+str(self.imageNumber)+'.jpg') - self.imageNumber += 1 - return 0 - - def sendImageCaptureRequest(self,filename): - - """ Request an image capture using a webcam through the 'ask_image_capture' service """ - - self.req_image_capture.filename = filename - self.future_image_capture = self.client_image_capture.call_async(self.req_image_capture) - while rclpy.ok(): - rclpy.spin_once(self) - if self.future_image_capture.done(): - self.get_logger().info('capture finished') - break - - def sendProfileMeasureRequest(self): - - """ Request a profile measure using a Gocator 2140 profile sensor through the 'gocator_get_profile' service """ - - profile_line = [] - self.future_profile_measure = self.client_profile_measure.call_async(self.req_profile_measure) - while rclpy.ok(): - rclpy.spin_once(self) - if self.future_profile_measure.done(): - try: - self.response = self.future_profile_measure.result() - except Exception as e: - self.get_logger().info('Service call failed {!r}'.format(e)) - else: - pcloud = self.response.pcloud - self.flag_datas_used = True - - gen = pc2.read_points(pcloud, skip_nans=True) - profile = list(gen) - - for points in profile: - profile_line.append([[points[0],0,points[2]]]) - break - self.get_logger().info('scan finished') - return profile_line - - def sendGcodeSendingRequest(self,gcode): - - """ Request the sending of a certain gcode list tanken as input through the 'send_gcode' service """ - - assert self.verifyGcodeBeforeSending(gcode) == True - - self.req_printer_driver.gcode_strings = gcode - self.future_printer_driver = self.client_printer_driver.call_async(self.req_printer_driver) - while rclpy.ok(): - rclpy.spin_once(self) - if self.future_printer_driver.done(): - self.get_logger().info('gcode sended') - break if __name__ == '__main__': - carriageReturn = ['G28\n'] - rclpy.init() - printer_control_node = PrinterControlNode('impression_base_2') - printer_control_node.sendGcodeSendingRequest(carriageReturn) - gcode = printer_control_node.loadGcode('/home/gulltor/Ramsai_Robotics/Gcodes/piece_test_base.gcode') - for i in range(90,len(gcode)): - # printer_control_node.sendGcodeSendingRequest(gcode[i]) - printer_control_node.takeCurrentLayerPhoto() - printer_control_node.scanCurrentLayer(gcode[i]) - rclpy.shutdown() + carriageReturn = ['G28\n'] + rclpy.init() + printer_control_node = PrinterControlNode('impression_base_2') + printer_control_node.sendGcodeSendingRequest(carriageReturn) + gcode = printer_control_node.loadGcode('/home/gulltor/Ramsai_Robotics/Gcodes/piece_test_base.gcode') + for i in range(90, len(gcode)): + # printer_control_node.sendGcodeSendingRequest(gcode[i]) + printer_control_node.takeCurrentLayerPhoto() + printer_control_node.scanCurrentLayer(gcode[i]) + rclpy.shutdown() diff --git a/3D_printer/src/printer3d_manager/nodes/printer_control_test.py b/3D_printer/src/printer3d_manager/nodes/printer_control_test.py index 3f7aee0..aeb1a0c 100644 --- a/3D_printer/src/printer3d_manager/nodes/printer_control_test.py +++ b/3D_printer/src/printer3d_manager/nodes/printer_control_test.py @@ -1,215 +1,214 @@ #!/usr/bin/env python3 +# Copyright 2023 ICube Laboratory, University of Strasbourg +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + import rclpy -from rclpy.action import ActionClient from rclpy.node import Node -from printer3d_msgs.srv import ProfileCommand from printer3d_msgs.srv import GcodeCommand from printer3d_msgs.srv import ImageCommand from printer3d_gocator_msgs.srv import GocatorPTCloud -from utility import * +from utility import getBordersSimpleGcode, getBordersGcode, work_on_gcode_file import printer3d_constant -from sensor_msgs.msg import PointCloud2 import point_cloud2 as pc2 import os import numpy as np - class PrinterControlNode(Node): - def __init__(self, historyFilename): - super().__init__('printer_control') - - """Initialisation of the printing process workspace""" - self.historyFilename = historyFilename - try: - os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename) - except: - pass - - try: - os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/gcode') - except: - pass - + def __init__(self, historyFilename): + super().__init__('printer_control') + """Initialisation of the printing process workspace""" + self.historyFilename = historyFilename + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename) + except Exception: + pass + + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/gcode') + except Exception: + pass + + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/scan') + except Exception: + pass + + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/photos') + except Exception: + pass + + # access to the image capture service + + self.client_image_capture = self.create_client(ImageCommand, 'ask_capture_image') + while not self.client_image_capture.wait_for_service(timeout_sec=1.0): + self.get_logger().info('image capture service not available, waiting again...') + self.req_image_capture = ImageCommand.Request() + + # access to the profile measure service + + self.client_profile_measure = self.create_client(GocatorPTCloud, 'gocator_get_profile') + while not self.client_profile_measure.wait_for_service(timeout_sec=1.0): + self.get_logger().info('profile measure service not available, waiting again...') + self.req_profile_measure = GocatorPTCloud.Request() + + # access to the printer driver service + + self.client_printer_driver = self.create_client(GcodeCommand, 'send_gcode') + while not self.client_printer_driver.wait_for_service(timeout_sec=1.0): + self.get_logger().info('profile measure service not available, waiting again...') + self.req_printer_driver = GcodeCommand.Request() + + self.imageNumber = 0 + self.scanNumber = 0 + + def loadGcode(self, gcodeFilename): + fileFullGcode = open(gcodeFilename) + rawGode = fileFullGcode.readlines() + fileFullGcode.close() + + (self.xMin, self.yMin, self.zMin, self.xMax, self.yMax, self.zMax) = getBordersGcode(rawGode) + self.get_logger().info('xMin : '+str(self.xMin)) + self.get_logger().info('xMax : '+str(self.xMax)) + self.get_logger().info('yMin : '+str(self.yMin)) + self.get_logger().info('yMax : '+str(self.yMax)) + self.get_logger().info('zMin : '+str(self.zMin)) + self.get_logger().info('zMax : '+str(self.zMax)) + + assert self.xMin >= printer3d_constant.XMIN + assert self.xMax <= printer3d_constant.XMAX + + assert self.yMin >= printer3d_constant.YMIN + assert self.yMax <= printer3d_constant.YMAX + + assert self.zMin >= printer3d_constant.ZMIN + assert self.zMax <= printer3d_constant.ZMAX + self.gcodeLayers = work_on_gcode_file(rawGode) + + return self.gcodeLayers + + def verifyGcodeBeforeSending(self, gcodeToVerify): + (self.xMin, self.yMin, self.zMin, self.xMax, self.yMax, self.zMax) = getBordersSimpleGcode(gcodeToVerify) + testXMin = self.xMin >= printer3d_constant.XMIN + testXMax = self.xMax <= printer3d_constant.XMAX + + testYMin = self.yMin >= printer3d_constant.YMIN + testYMax = self.yMax <= printer3d_constant.YMAX + + testZMin = self.zMin >= printer3d_constant.ZMIN + testZMax = self.zMax <= printer3d_constant.ZMAX + + if testXMin is False or testXMax is False or testYMin is False or testYMax is False or testZMin is False or testZMax is False: + return False + else: + return True + + def scanCurrentLayer(self, printedLayer): + (layerXMin, layerYMin, layerZMin, layerXMax, layerYMax, layerZMax) = getBordersSimpleGcode(printedLayer) + + gcodeScan = [[]] + margin = 20 + + Yinit = layerYMin - printer3d_constant.GAP + Yfinal = layerYMax - printer3d_constant.GAP + step = 0.3 + + gcodeScan[0].append('G1 Z' + str(layerZMax+1)+'\n') + gcodeScan[0].append('G28 X0 Y0\n') + gcodeScan[0].append('G1 Y' + str(Yinit-(margin/2))+' F1200\n') + length = int((Yfinal-Yinit+margin)/step) + + self.get_logger().info('scanning begin :') + self.get_logger().info('Yinit :' + str(Yinit)) + self.get_logger().info('Yfinal :' + str(Yfinal)) + self.get_logger().info('length :' + str(length)) + + for i in range(1, length): + gcodeScan.append([]) + gcodeScan[-1].append('G1 Y'+str(Yinit-(margin/2)+(i*step))+'\n') + surface = [] + for movements in gcodeScan: + self.sendGcodeSendingRequest(movements) + profileLine = self.sendProfileMeasureRequest() + surface.append(profileLine) + np.save('/home/gulltor/Ramsai_Robotics/history/'+self.historyFilename+'/scan/layer_scan_'+str(self.scanNumber)+'.npy', np.array(surface)) + self.scanNumber += 1 + return surface + + def printCurrentLayer(self): + return 0 + + def takeCurrentLayerPhoto(self): + gcodeMoveToPos = ['G28 X0 Y0\n', 'G1 Y'+str(printer3d_constant.YPOSPHOTO)+' F2400\n'] + self.sendGcodeSendingRequest(gcodeMoveToPos) + self.sendImageCaptureRequest('/home/gulltor/Ramsai_Robotics/history/'+self.historyFilename+'/photos/layer_photo_'+str(self.imageNumber)+'.jpg') + self.imageNumber += 1 + return 0 + + def sendImageCaptureRequest(self, filename): + self.req_image_capture.filename = filename + self.future_image_capture = self.client_image_capture.call_async(self.req_image_capture) + while rclpy.ok(): + rclpy.spin_once(self) + if self.future_image_capture.done(): + self.get_logger().info('capture finished') + break + + def sendProfileMeasureRequest(self): + profile_line = [] + self.future_profile_measure = self.client_profile_measure.call_async(self.req_profile_measure) + while rclpy.ok(): + rclpy.spin_once(self) + if self.future_profile_measure.done(): try: - os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/scan') - except: - pass - - try: - os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/photos') - except: - pass - - # access to the image capture service - - self.client_image_capture = self.create_client(ImageCommand, 'ask_capture_image') - while not self.client_image_capture.wait_for_service(timeout_sec=1.0): - self.get_logger().info('image capture service not available, waiting again...') - self.req_image_capture = ImageCommand.Request() - - # access to the profile measure service - - self.client_profile_measure = self.create_client(GocatorPTCloud, 'gocator_get_profile') - while not self.client_profile_measure.wait_for_service(timeout_sec=1.0): - self.get_logger().info('profile measure service not available, waiting again...') - self.req_profile_measure = GocatorPTCloud.Request() - - # access to the printer driver service - - self.client_printer_driver = self.create_client(GcodeCommand, 'send_gcode') - while not self.client_printer_driver.wait_for_service(timeout_sec=1.0): - self.get_logger().info('profile measure service not available, waiting again...') - self.req_printer_driver = GcodeCommand.Request() - - self.imageNumber = 0 - self.scanNumber = 0 - - - def loadGcode(self,gcodeFilename): - fileFullGcode = open(gcodeFilename) - rawGode = fileFullGcode.readlines() - fileFullGcode.close() - - (self.xMin,self.yMin,self.zMin,self.xMax,self.yMax,self.zMax) = getBordersGcode(rawGode) - self.get_logger().info('xMin : '+str(self.xMin)) - self.get_logger().info('xMax : '+str(self.xMax)) - self.get_logger().info('yMin : '+str(self.yMin)) - self.get_logger().info('yMax : '+str(self.yMax)) - self.get_logger().info('zMin : '+str(self.zMin)) - self.get_logger().info('zMax : '+str(self.zMax)) - - assert self.xMin >= printer3d_constant.XMIN - assert self.xMax <= printer3d_constant.XMAX - - assert self.yMin >= printer3d_constant.YMIN - assert self.yMax <= printer3d_constant.YMAX - - assert self.zMin >= printer3d_constant.ZMIN - assert self.zMax <= printer3d_constant.ZMAX - self.gcodeLayers = work_on_gcode_file(rawGode) - - return self.gcodeLayers + self.response = self.future_profile_measure.result() + except Exception as e: + self.get_logger().info(f'Service call failed {e!r}') + else: + pcloud = self.response.pcloud + self.flag_datas_used = True - def verifyGcodeBeforeSending(self,gcodeToVerify): + gen = pc2.read_points(pcloud, skip_nans=True) + profile = list(gen) - (self.xMin,self.yMin,self.zMin,self.xMax,self.yMax,self.zMax) = getBordersSimpleGcode(gcodeToVerify) - testXMin = self.xMin >= printer3d_constant.XMIN - testXMax = self.xMax <= printer3d_constant.XMAX + for points in profile: + profile_line.append([[points[0], 0, points[2]]]) + break + self.get_logger().info('scan finished') + return profile_line - testYMin = self.yMin >= printer3d_constant.YMIN - testYMax = self.yMax <= printer3d_constant.YMAX + def sendGcodeSendingRequest(self, gcode): + assert self.verifyGcodeBeforeSending(gcode) is True - testZMin = self.zMin >= printer3d_constant.ZMIN - testZMax = self.zMax <= printer3d_constant.ZMAX + self.req_printer_driver.gcode_strings = gcode + self.future_printer_driver = self.client_printer_driver.call_async(self.req_printer_driver) + while rclpy.ok(): + rclpy.spin_once(self) + if self.future_printer_driver.done(): + self.get_logger().info('gcode sended') + break - if testXMin == False or testXMax == False or testYMin == False or testYMax == False or testZMin == False or testZMax == False: - return False - else: - return True - - def scanCurrentLayer(self,printedLayer): - (layerXMin,layerYMin,layerZMin,layerXMax,layerYMax,layerZMax) = getBordersSimpleGcode(printedLayer) - - gcodeScan = [[]] - margin = 20 - - Yinit = layerYMin - printer3d_constant.GAP - Yfinal = layerYMax - printer3d_constant.GAP - step = 0.3 - - gcodeScan[0].append('G1 Z'+str(layerZMax+1)+'\n') - gcodeScan[0].append('G28 X0 Y0\n') - gcodeScan[0].append('G1 Y'+str(Yinit-(margin/2))+' F1200\n') - length = int((Yfinal-Yinit+margin)/step) - - self.get_logger().info('scanning begin :') - self.get_logger().info('Yinit :' + str(Yinit)) - self.get_logger().info('Yfinal :'+ str(Yfinal)) - self.get_logger().info('length :'+ str(length)) - - for i in range(1,length): - gcodeScan.append([]) - gcodeScan[-1].append('G1 Y'+str(Yinit-(margin/2)+(i*step))+'\n') - surface = [] - for movements in gcodeScan: - self.sendGcodeSendingRequest(movements) - profileLine = self.sendProfileMeasureRequest() - surface.append(profileLine) - np.save('/home/gulltor/Ramsai_Robotics/history/'+self.historyFilename+'/scan/layer_scan_'+str(self.scanNumber)+'.npy',np.array(surface)) - self.scanNumber += 1 - return surface - - def printCurrentLayer(self): - return 0 - - def takeCurrentLayerPhoto(self): - gcodeMoveToPos = ['G28 X0 Y0\n','G1 Y'+str(printer3d_constant.YPOSPHOTO)+' F2400\n'] - self.sendGcodeSendingRequest(gcodeMoveToPos) - self.sendImageCaptureRequest('/home/gulltor/Ramsai_Robotics/history/'+self.historyFilename+'/photos/layer_photo_'+str(self.imageNumber)+'.jpg') - self.imageNumber += 1 - return 0 - - def sendImageCaptureRequest(self,filename): - - """ Request an image capture using a webcam through the 'ask_image_capture' service """ - - self.req_image_capture.filename = filename - self.future_image_capture = self.client_image_capture.call_async(self.req_image_capture) - while rclpy.ok(): - rclpy.spin_once(self) - if self.future_image_capture.done(): - self.get_logger().info('capture finished') - break - - def sendProfileMeasureRequest(self): - - """ Request a profile measure using a Gocator 2140 profile sensor through the 'gocator_get_profile' service """ - - profile_line = [] - self.future_profile_measure = self.client_profile_measure.call_async(self.req_profile_measure) - while rclpy.ok(): - rclpy.spin_once(self) - if self.future_profile_measure.done(): - try: - self.response = self.future_profile_measure.result() - except Exception as e: - self.get_logger().info('Service call failed {!r}'.format(e)) - else: - pcloud = self.response.pcloud - self.flag_datas_used = True - - gen = pc2.read_points(pcloud, skip_nans=True) - profile = list(gen) - - for points in profile: - profile_line.append([[points[0],0,points[2]]]) - break - self.get_logger().info('scan finished') - return profile_line - - def sendGcodeSendingRequest(self,gcode): - - """ Request the sending of a certain gcode list tanken as input through the 'send_gcode' service """ - - assert self.verifyGcodeBeforeSending(gcode) == True - - self.req_printer_driver.gcode_strings = gcode - self.future_printer_driver = self.client_printer_driver.call_async(self.req_printer_driver) - while rclpy.ok(): - rclpy.spin_once(self) - if self.future_printer_driver.done(): - self.get_logger().info('gcode sended') - break if __name__ == '__main__': - carriageReturn = ['G28\n'] - rclpy.init() - printer_control_node = PrinterControlNode('test_impression_base') - # printer_control_node.sendGcodeSendingRequest(carriageReturn) - gcode = printer_control_node.loadGcode('/home/gulltor/Ramsai_Robotics/Gcodes/piece_test_base.gcode') - for i in range(0,3): - printer_control_node.sendGcodeSendingRequest(gcode[i]) - printer_control_node.takeCurrentLayerPhoto() - printer_control_node.scanCurrentLayer(gcode[i]) - rclpy.shutdown() + carriageReturn = ['G28\n'] + rclpy.init() + printer_control_node = PrinterControlNode('test_impression_base') + # printer_control_node.sendGcodeSendingRequest(carriageReturn) + gcode = printer_control_node.loadGcode('/home/gulltor/Ramsai_Robotics/Gcodes/piece_test_base.gcode') + for i in range(0, 3): + printer_control_node.sendGcodeSendingRequest(gcode[i]) + printer_control_node.takeCurrentLayerPhoto() + printer_control_node.scanCurrentLayer(gcode[i]) + rclpy.shutdown() diff --git a/3D_printer/src/printer3d_manager/nodes/utility.py b/3D_printer/src/printer3d_manager/nodes/utility.py index 735514f..c60d4ab 100644 --- a/3D_printer/src/printer3d_manager/nodes/utility.py +++ b/3D_printer/src/printer3d_manager/nodes/utility.py @@ -1,99 +1,114 @@ +# Copyright 2023 ICube Laboratory, University of Strasbourg +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + def work_on_gcode_file(sequence): - length = len(sequence) - delimiter = ';LAYER:' - final_delimiter = '; Default end code' + delimiter = ';LAYER:' + final_delimiter = '; Default end code' + layers = [[]] - layers = [[]] + for line in sequence: + if (delimiter not in line) and (final_delimiter not in line): + if line[0] != ';': + layers[-1].append(line) + else: + layers.append([]) - for line in sequence: + return layers - if (delimiter not in line) and (final_delimiter not in line): - if line[0]!=';': - layers[-1].append(line) - else: - layers.append([]) - return layers def getBordersGcode(sequence): - zMax = 0 - xMax = 0 - yMax = 0 - zMin = 2000 - yMin = 2000 - xMin = 2000 + zMax = 0 + xMax = 0 + yMax = 0 + zMin = 2000 + yMin = 2000 + xMin = 2000 + + # remove initialisation - # remove initialisation + completeSequence = work_on_gcode_file(sequence) + innerSequence = [] + for i in range(1, len(completeSequence)-1): + innerSequence = innerSequence+completeSequence[i] - completeSequence = work_on_gcode_file(sequence) - innerSequence = [] - for i in range(1,len(completeSequence)-1): - innerSequence = innerSequence+completeSequence[i] + for line in innerSequence: + if 'Z' in line and ';' not in line: + z = line.split('Z')[1] + z = z.split(' ')[0] + z = z.split('\n')[0] + z = float(z) + if z > zMax: + zMax = z + if z < zMin: + zMin = z + if 'Y' in line and ';' not in line: + y = line.split('Y')[1] + y = y.split(' ')[0] + y = y.split('\n')[0] + y = float(y) + if y > yMax: + yMax = y + if y < yMin: + yMin = y + if 'X' in line and ';' not in line: + x = line.split('X')[1] + x = x.split(' ')[0] + x = x.split('\n')[0] + x = float(x) + if x > xMax: + xMax = x + if x < xMin: + xMin = x + return (xMin, yMin, zMin, xMax, yMax, zMax) - for line in innerSequence: - if 'Z' in line and ';' not in line: - z = line.split('Z')[1] - z = z.split(' ')[0] - z = z.split('\n')[0] - z = float(z) - if z>zMax: - zMax = z - if zyMax: - yMax = y - if yxMax: - xMax = x - if xzMax: - zMax = z - if zyMax: - yMax = y - if yxMax: - xMax = x - if x zMax: + zMax = z + if z < zMin: + zMin = z + if 'Y' in line and ';' not in line: + y = line.split('Y')[1] + y = y.split(' ')[0] + y = y.split('\n')[0] + y = float(y) + if y > yMax: + yMax = y + if y < yMin: + yMin = y + if 'X' in line and ';' not in line: + x = line.split('X')[1] + x = x.split(' ')[0] + x = x.split('\n')[0] + x = float(x) + if x > xMax: + xMax = x + if x < xMin: + xMin = x + return (xMin, yMin, zMin, xMax, yMax, zMax) diff --git a/3D_printer/src/printer3d_msgs/CMakeLists.txt b/3D_printer/src/printer3d_msgs/CMakeLists.txt index 627fa5f..88bce6c 100644 --- a/3D_printer/src/printer3d_msgs/CMakeLists.txt +++ b/3D_printer/src/printer3d_msgs/CMakeLists.txt @@ -38,10 +38,10 @@ if(BUILD_TESTING) ament_lint_auto_find_test_dependencies() endif() -rosidl_generate_interfaces(${PROJECT_NAME} +rosidl_generate_interfaces( ${PROJECT_NAME} "srv/ProfileCommand.srv" "srv/GcodeCommand.srv" "srv/ImageCommand.srv" - ) +) ament_package() diff --git a/3D_printer/src/printer3d_profile_capture/CMakeLists.txt b/3D_printer/src/printer3d_profile_capture/CMakeLists.txt index 5dd6f98..969b36e 100644 --- a/3D_printer/src/printer3d_profile_capture/CMakeLists.txt +++ b/3D_printer/src/printer3d_profile_capture/CMakeLists.txt @@ -26,42 +26,42 @@ find_package(printer3d_gocator_msgs REQUIRED) find_package(pcl_conversions REQUIRED) # Find point cloud Library -FIND_PACKAGE(PCL REQUIRED COMPONENTS) -INCLUDE_DIRECTORIES(${PCL_INCLUDE_DIRS}) -LINK_DIRECTORIES(${PCL_LIBRARY_DIRS}) -ADD_DEFINITIONS(${PCL_DEFINITIONS}) +find_package(PCL REQUIRED COMPONENTS) +include_directories(${PCL_INCLUDE_DIRS}) +link_directories(${PCL_LIBRARY_DIRS}) +add_definitions(${PCL_DEFINITIONS}) # Set GO_SDK include paths (That could be part of a FindGocator.cmake) -SET(GO_SDK_4 ${CMAKE_CURRENT_SOURCE_DIR}/external/GO_SDK) -FIND_PATH( +set(GO_SDK_4 ${CMAKE_CURRENT_SOURCE_DIR}/external/GO_SDK) +find_path( GOCATOR_INCLUDES NAMES GoSdk/GoSdk.h PATHS ${GO_SDK_4}/Gocator/GoSdk) -FIND_PATH( +find_path( KAPI_INCLUDES NAMES kApi/kApi.h PATHS ${GO_SDK_4}/Platform/kApi) -INCLUDE_DIRECTORIES(${GOCATOR_INCLUDES} ${KAPI_INCLUDES}) +include_directories(${GOCATOR_INCLUDES} ${KAPI_INCLUDES}) # Set GO_SDK libs (That could be part of a FindGocator.cmake) -FIND_LIBRARY( +find_library( GOCATOR_LIBRARIES NAMES GoSdk PATHS ${GO_SDK_4}/lib/linux_x64d) -FIND_LIBRARY( +find_library( KAPI_LIBRARIES NAMES kApi PATHS ${GO_SDK_4}/lib/linux_x64d) # Set source files -SET(LIB_SRCS +set(LIB_SRCS src/driver/gocatorSensor.cpp) # Set header files -SET(LIB_HDRS +set(LIB_HDRS src/driver/gocatorSensor.h) -INCLUDE_DIRECTORIES(${LIB_HDRS}) +include_directories(${LIB_HDRS}) # Install the python module for this package # ament_python_install_package(script/) @@ -74,7 +74,7 @@ INCLUDE_DIRECTORIES(${LIB_HDRS}) ################################################################################ add_executable( gocator_sensor_node src/nodes/gocatorSensorNode.cpp ${LIB_HDRS} ${LIB_SRCS} ) -target_link_libraries (gocator_sensor_node ${GOCATOR_LIBRARIES} ${KAPI_LIBRARIES} ${Boost_SYSTEM_LIBRARY}) +target_link_libraries(gocator_sensor_node ${GOCATOR_LIBRARIES} ${KAPI_LIBRARIES} ${Boost_SYSTEM_LIBRARY}) ament_target_dependencies(gocator_sensor_node rclcpp sensor_msgs std_msgs printer3d_gocator_msgs pcl_conversions) diff --git a/3D_printer/src/printer3d_profile_capture/src/driver/CMakeLists.txt b/3D_printer/src/printer3d_profile_capture/src/driver/CMakeLists.txt index b4bd2d4..d3dae06 100644 --- a/3D_printer/src/printer3d_profile_capture/src/driver/CMakeLists.txt +++ b/3D_printer/src/printer3d_profile_capture/src/driver/CMakeLists.txt @@ -1,13 +1,13 @@ # Pre-requisites about cmake itself -CMAKE_MINIMUM_REQUIRED(VERSION 3.5) +cmake_minimum_required(VERSION 3.5) # Project name and the type of project -PROJECT(gocatorSensor) +project(gocatorSensor) # DEBUG/RELEASE -IF (NOT CMAKE_BUILD_TYPE) - SET(CMAKE_BUILD_TYPE "RELEASE") -ENDIF (NOT CMAKE_BUILD_TYPE) +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "RELEASE") +endif() # Default to C99 if(NOT CMAKE_C_STANDARD) @@ -24,41 +24,39 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") endif() # Find point cloud Library -FIND_PACKAGE(PCL REQUIRED COMPONENTS) -INCLUDE_DIRECTORIES(${PCL_INCLUDE_DIRS}) -LINK_DIRECTORIES(${PCL_LIBRARY_DIRS}) -ADD_DEFINITIONS(${PCL_DEFINITIONS}) +find_package(PCL REQUIRED COMPONENTS) +include_directories(${PCL_INCLUDE_DIRS}) +link_directories(${PCL_LIBRARY_DIRS}) +add_definitions(${PCL_DEFINITIONS}) # Set GO_SDK include paths (That could be part of a FindGocator.cmake) -SET(GO_SDK_4 ${CMAKE_CURRENT_SOURCE_DIR}/../../external/GO_SDK) -FIND_PATH( +set(GO_SDK_4 ${CMAKE_CURRENT_SOURCE_DIR}/../../external/GO_SDK) +find_path( GOCATOR_INCLUDES NAMES GoSdk/GoSdk.h PATHS ${GO_SDK_4}/Gocator/GoSdk) -FIND_PATH( +find_path( KAPI_INCLUDES NAMES kApi/kApi.h PATHS ${GO_SDK_4}/Platform/kApi) -INCLUDE_DIRECTORIES(${GOCATOR_INCLUDES} ${KAPI_INCLUDES}) +include_directories(${GOCATOR_INCLUDES} ${KAPI_INCLUDES}) # Set GO_SDK libs (That could be part of a FindGocator.cmake) -FIND_LIBRARY( +find_library( GOCATOR_LIBRARIES NAMES GoSdk PATHS ${GO_SDK_4}/lib/linux_x64d/) -FIND_LIBRARY( +find_library( KAPI_LIBRARIES NAMES kApi PATHS ${GO_SDK_4}/lib/linux_x64d/) # Set source files -SET(SRCS - gocatorSensor.cpp) +set(SRCS gocatorSensor.cpp) # Set header files -SET(HDRS - gocatorSensor.h) +set(HDRS gocatorSensor.h) #Build library -ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS}) -TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${GOCATOR_LIBRARIES} ${KAPI_LIBRARIES} ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES}) +add_library(${PROJECT_NAME} SHARED ${SRCS}) +target_link_libraries(${PROJECT_NAME} ${GOCATOR_LIBRARIES} ${KAPI_LIBRARIES} ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES}) diff --git a/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp b/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp index 8e0d953..ffbfdf2 100644 --- a/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp +++ b/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp @@ -1,3 +1,17 @@ +// Copyright 2023 ICube Laboratory, University of Strasbourg +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include "gocatorSensor.h" GocatorSensor::Device::Device(const std::string & _ip_address) @@ -6,7 +20,7 @@ GocatorSensor::Device::Device(const std::string & _ip_address) kIpAddress ipAddress; kChar model_name[50]; - //init all GO API objects + // init all GO API objects go_api_ = kNULL; go_system_ = kNULL; go_sensor_ = kNULL; @@ -36,7 +50,7 @@ GocatorSensor::Device::Device(const std::string & _ip_address) return; } - //Success case. Set status and device fixed params (ip, model name and serial number ). + // Success case. Set status and device fixed params (ip, model name and serial number ). status_ = DEVICE_FOUND; device_params_.ip_address_ = _ip_address; @@ -60,23 +74,23 @@ GocatorSensor::Device::Device(const std::string & _ip_address) return; } - //Obtain camera model + // Obtain camera model if ((status = GoSensor_Model(go_sensor_, model_name, 50)) != kOK) { std::cout << "Device(). Error: GoSensor_Model: " << status << std::endl; return; } device_params_.model_name_ = model_name; - //Obtain camera Serial number + // Obtain camera Serial number device_params_.sn_ = (unsigned int)GoSensor_Id(go_sensor_); - //Obtain exposure + // Obtain exposure capture_params_.exposure_time_ = GoSetup_Exposure(go_setup_, GO_ROLE_MAIN); - //Obtain spacing interval + // Obtain spacing interval capture_params_.spacing_interval_ = GoSetup_SpacingInterval(go_setup_, GO_ROLE_MAIN); - //print info + // print info std::cout << "Found Sensor: " << std::endl; device_params_.print(); } @@ -89,7 +103,7 @@ GocatorSensor::Device::~Device() GoDestroy(go_system_); GoDestroy(go_api_); - //bye bye message + // bye bye message std::cout << "~Device(). Gocator Sensor Stopped and Device Object Destroyed." << std::endl; } @@ -97,14 +111,14 @@ int GocatorSensor::Device::configure(const CaptureParams & _configs) { kStatus status; - //set exposure + // set exposure if ((status = GoSetup_SetExposure(go_setup_, GO_ROLE_MAIN, _configs.exposure_time_)) != kOK) { std::cout << "configure(): Error setting Exposure Time to " << _configs.exposure_time_ << std::endl; return -1; } - //set spacing interval + // set spacing interval if ((status = GoSetup_SetSpacingInterval(go_setup_, GO_ROLE_MAIN, _configs.spacing_interval_)) != kOK) { @@ -113,15 +127,15 @@ int GocatorSensor::Device::configure(const CaptureParams & _configs) return -1; } - //set this->capture_params_ with true values from camera + // set this->capture_params_ with true values from camera capture_params_.exposure_time_ = GoSetup_Exposure(go_setup_, GO_ROLE_MAIN); capture_params_.spacing_interval_ = GoSetup_SpacingInterval(go_setup_, GO_ROLE_MAIN); - //print + // print std::cout << "Configuration Settings: " << std::endl; capture_params_.print(); - //return + // return return 1; } @@ -135,13 +149,13 @@ int GocatorSensor::Device::start() return -1; } - //message to std out - //std::cout << "Gocator running ... " << std::endl; + // message to std out + // std::cout << "Gocator running ... " << std::endl; - //set this->status_ + // set this->status_ this->status_ = DEVICE_RUNNING; - //return success + // return success return 1; } @@ -155,24 +169,22 @@ int GocatorSensor::Device::stop() return -1; } - //message to std out - //std::cout << "... Gocator stopped" << std::endl << std::endl; + // message to std out + // std::cout << "... Gocator stopped" << std::endl << std::endl; - //set this->status_ + // set this->status_ this->status_ = DEVICE_CONNECT; - //return success + // return success return 1; } int GocatorSensor::Device::getCurrentSnapshot(pcl::PointCloud & _p_cloud) { - } int GocatorSensor::Device::getSingleSnapshot(pcl::PointCloud & _p_cloud) { - } int GocatorSensor::Device::getProfile(pcl::PointCloud & _p_cloud) @@ -190,7 +202,7 @@ int GocatorSensor::Device::getProfile(pcl::PointCloud & _p_cloud) // loop through all items in result message for (i = 0; i < GoDataSet_Count(dataset); ++i) { dataObj = GoDataSet_At(dataset, i); - //Retrieve GoStamp message + // Retrieve GoStamp message switch (GoDataMsg_Type(dataObj)) { case GO_DATA_MESSAGE_TYPE_STAMP: { @@ -232,7 +244,6 @@ int GocatorSensor::Device::getProfile(pcl::PointCloud & _p_cloud) for (arrayIndex = 0; arrayIndex < GoResampledProfileMsg_Width(profileMsg); ++arrayIndex) { - if (data[arrayIndex] != INVALID_RANGE_16BIT) { // profileBuffer[arrayIndex].x = XOffset + XResolution * arrayIndex; // profileBuffer[arrayIndex].z = ZOffset + ZResolution * data[arrayIndex]; @@ -248,10 +259,7 @@ int GocatorSensor::Device::getProfile(pcl::PointCloud & _p_cloud) arrayIndex; _p_cloud.points.at(k * _p_cloud.width + arrayIndex).z = INVALID_RANGE_DOUBLE; } - - } - printf( " Profile Valid Point %d out of max %d\n", validPointCount, profilePointCount); @@ -278,7 +286,7 @@ int GocatorSensor::Device::getProfile(pcl::PointCloud & _p_cloud) // profileBuffer.resize(GoResampledProfileMsg_Width(profileMsg)); - //translate 16-bit range data to engineering units and copy profiles to memory array + // translate 16-bit range data to engineering units and copy profiles to memory array for (arrayIndex = 0; arrayIndex < GoProfileMsg_Width(profileMsg); ++arrayIndex) { if (data[arrayIndex].x != INVALID_RANGE_16BIT) { // profileBuffer[arrayIndex].x = XOffset + XResolution * data[arrayIndex].x; @@ -332,13 +340,13 @@ int GocatorSensor::Device::getProfile(pcl::PointCloud & _p_cloud) void GocatorSensor::Device::getDeviceHealth(std::string & _health_str) const { - //local variables + // local variables GoDataSet health_data = kNULL; GoHealthMsg health_msg = kNULL; GoIndicator * health_indicator = kNULL; std::ostringstream sstr; - //get health from device + // get health from device if ( (GoSystem_ReceiveHealth(go_system_, &health_data, RECEIVE_TIMEOUT)) == kOK) { for (unsigned int ii = 0; ii < GoDataSet_Count(health_data); ii++) { health_msg = GoDataSet_At(health_data, ii); @@ -360,31 +368,31 @@ void GocatorSensor::Device::getTemperature( double & _internal_temp, double & _projector_temp, double & _laser_temp) const { - //local variables + // local variables GoDataSet health_data = kNULL; GoHealthMsg health_msg = kNULL; GoIndicator * health_indicator = kNULL; - //k32u instance; + // k32u instance; - //get health dataset from device + // get health dataset from device if ( (GoSystem_ReceiveHealth(go_system_, &health_data, RECEIVE_TIMEOUT)) == kOK) { for (unsigned int ii = 0; ii < GoDataSet_Count(health_data); ii++) { - //get the health message + // get the health message health_msg = GoDataSet_At(health_data, ii); - //find in the message the internal temperature indicator, and set the value + // find in the message the internal temperature indicator, and set the value health_indicator = GoHealthMsg_Find(health_msg, GO_HEALTH_TEMPERATURE, 0); if (health_indicator != kNULL) {_internal_temp = health_indicator->value;} else { _internal_temp = -100.; } - //find in the message the projector temperature indicator, and set the value + // find in the message the projector temperature indicator, and set the value health_indicator = GoHealthMsg_Find(health_msg, GO_HEALTH_PROJECTOR_TEMPERATURE, 0); if (health_indicator != kNULL) {_projector_temp = health_indicator->value;} else { _projector_temp = -100.; } - //find in the message the projector temperature indicator, and set the value + // find in the message the projector temperature indicator, and set the value health_indicator = GoHealthMsg_Find(health_msg, GO_HEALTH_LASER_TEMPERATURE, 0); if (health_indicator != kNULL) {_laser_temp = health_indicator->value;} else { _laser_temp = -100.; @@ -392,17 +400,14 @@ void GocatorSensor::Device::getTemperature( } GoDestroy(health_msg); } - } int GocatorSensor::Device::close() { - } void GocatorSensor::Device::printDeviceData() const { - } void GocatorSensor::Device::sendTrigger() const diff --git a/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.h b/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.h index 685a9c6..9a17874 100644 --- a/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.h +++ b/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.h @@ -1,25 +1,42 @@ -#ifndef GocatorSensor_H -#define GocatorSensor_H - -//std c/c++ +// Copyright 2023 ICube Laboratory, University of Strasbourg +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef DRIVER__GOCATORSENSOR_H_ +#define DRIVER__GOCATORSENSOR_H_ + +// std c/c++ #include #include #include #include +#include -//GoSdk +// GoSdk #include -//PCL +// PCL #include #include -//constants -#define SENSOR_IP "192.168.1.10" // sensor IP address -#define RECEIVE_TIMEOUT 20000000 // timeout for snapshot acquisition -#define INVALID_RANGE_16BIT ((signed short)0x8000) // gocator transmits range data as 16-bit signed integers. 0x8000 signifies invalid range data. -#define DOUBLE_MAX ((k64f)1.7976931348623157e+308) // 64-bit double - largest positive value. -#define INVALID_RANGE_DOUBLE ((k64f) - DOUBLE_MAX) // floating point value to represent invalid range data. +// constants +#define SENSOR_IP "192.168.1.10" // sensor IP address +#define RECEIVE_TIMEOUT 20000000 // timeout for snapshot acquisition +#define INVALID_RANGE_16BIT ((signed short)0x8000) // gocator transmits range data +// as 16-bit signed integers. 0x8000 signifies invalid range data. +#define DOUBLE_MAX ((k64f)1.7976931348623157e+308) // 64-bit double - largest positive value. +#define INVALID_RANGE_DOUBLE ((k64f) - DOUBLE_MAX) // floating point value to +// represent invalid range data. #define NM_TO_MM(VALUE) (((k64f)(VALUE)) / 1000000.0) #define UM_TO_MM(VALUE) (((k64f)(VALUE)) / 1000.0) @@ -28,15 +45,15 @@ namespace GocatorSensor typedef struct ProfilePoint { - double x; // x-coordinate in engineering units (mm) - position along laser line - double z; // z-coordinate in engineering units (mm) - height (at the given x position) + double x; // x-coordinate in engineering units (mm) - position along laser line + double z; // z-coordinate in engineering units (mm) - height (at the given x position) unsigned char intensity; } ProfilePoint; -//status values - enum {DEVICE_NOT_FOUND=0, DEVICE_FOUND, DEVICE_NOT_CONNECT, DEVICE_CONNECT, DEVICE_RUNNING}; +// status values + enum {DEVICE_NOT_FOUND = 0, DEVICE_FOUND, DEVICE_NOT_CONNECT, DEVICE_CONNECT, DEVICE_RUNNING}; -//device parameters struct +// device parameters struct struct DeviceParams { std::string ip_address_; @@ -51,11 +68,11 @@ namespace GocatorSensor } }; -//device configuration struct +// device configuration struct struct CaptureParams { - double exposure_time_; //in useconds - double spacing_interval_; //in millimeters + double exposure_time_; // in useconds + double spacing_interval_; // in millimeters void print() const { @@ -64,23 +81,24 @@ namespace GocatorSensor } }; -//Device class +// Device class class Device { protected: - //current point cloud. Maybe not necessary to be here! - //pcl::PointCloud::Ptr p_cloud_; //p_cloud_ = new pcl::PointCloud + // current point cloud. Maybe not necessary to be here! + // pcl::PointCloud::Ptr p_cloud_; + // p_cloud_ = new pcl::PointCloud - //driver status + // driver status unsigned int status_; - //device fixed params + // device fixed params DeviceParams device_params_; - //device configuration + // device configuration CaptureParams capture_params_; - //GO API objects + // GO API objects kAssembly go_api_; GoSystem go_system_; GoSensor go_sensor_; @@ -94,7 +112,7 @@ namespace GocatorSensor * Constructor. Sets params_ struct. * **/ - Device(const std::string & _ip_address); + explicit Device(const std::string & _ip_address); /** \brief Destructor * @@ -182,7 +200,7 @@ namespace GocatorSensor * **/ void sendTrigger() const; - };//close class -}//close namespace + }; +} // namespace GocatorSensor -#endif +#endif // DRIVER__GOCATORSENSOR_H_ diff --git a/3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp b/3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp index 54d80c5..017c5e3 100644 --- a/3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp +++ b/3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp @@ -1,3 +1,17 @@ +// Copyright 2023 ICube Laboratory, University of Strasbourg +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include #include #include @@ -28,7 +42,8 @@ class GocatorSensorNode : public rclcpp::Node std::bind( &GocatorSensorNode::profile_snapshot, this, std::placeholders::_1, std::placeholders::_2)); - // publisher_ = this->create_publisher("gocatorPTCloud_topic", 10); + // publisher_ = this->create_publisher("gocatorPTCloud_topic", 10); } private: @@ -50,7 +65,6 @@ class GocatorSensorNode : public rclcpp::Node response->pcloud = pcloud; } - } rclcpp::Service::SharedPtr service_; From df3d465185ad062f165e03842093cee8b1f837ac Mon Sep 17 00:00:00 2001 From: MosserLoic Date: Wed, 19 Apr 2023 14:20:05 +0200 Subject: [PATCH 14/30] precommit and uncrustify are chellenging each other --- .pre-commit-config.yaml | 2 +- .../src/driver/gocatorSensor.cpp | 2 +- .../src/driver/gocatorSensor.h | 301 +++++++++--------- 3 files changed, 152 insertions(+), 153 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2abcec7..4fe783d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -138,7 +138,7 @@ repos: # Spellcheck in comments and docs # skipping of *.svg files is not working... - repo: https://github.com/codespell-project/codespell - rev: v2.2.2 + rev: v2.2.4 hooks: - id: codespell args: ['--write-changes'] diff --git a/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp b/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp index ffbfdf2..a23a5fe 100644 --- a/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp +++ b/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp @@ -231,7 +231,7 @@ int GocatorSensor::Device::getProfile(pcl::PointCloud & _p_cloud) for (k = 0; k < GoResampledProfileMsg_Count(profileMsg); ++k) { unsigned int validPointCount = 0; - short * data = GoResampledProfileMsg_At(profileMsg, k); + __int16 * data = GoResampledProfileMsg_At(profileMsg, k); double XResolution = NM_TO_MM(GoResampledProfileMsg_XResolution(profileMsg)); double ZResolution = NM_TO_MM(GoResampledProfileMsg_ZResolution(profileMsg)); double XOffset = UM_TO_MM(GoResampledProfileMsg_XOffset(profileMsg)); diff --git a/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.h b/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.h index 9a17874..277774a 100644 --- a/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.h +++ b/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.h @@ -15,6 +15,12 @@ #ifndef DRIVER__GOCATORSENSOR_H_ #define DRIVER__GOCATORSENSOR_H_ +// GoSdk +#include +// PCL +#include +#include + // std c/c++ #include #include @@ -22,17 +28,10 @@ #include #include -// GoSdk -#include - -// PCL -#include -#include - // constants #define SENSOR_IP "192.168.1.10" // sensor IP address #define RECEIVE_TIMEOUT 20000000 // timeout for snapshot acquisition -#define INVALID_RANGE_16BIT ((signed short)0x8000) // gocator transmits range data +#define INVALID_RANGE_16BIT ((__int16)0x8000) // gocator transmits range data // as 16-bit signed integers. 0x8000 signifies invalid range data. #define DOUBLE_MAX ((k64f)1.7976931348623157e+308) // 64-bit double - largest positive value. #define INVALID_RANGE_DOUBLE ((k64f) - DOUBLE_MAX) // floating point value to @@ -40,167 +39,167 @@ #define NM_TO_MM(VALUE) (((k64f)(VALUE)) / 1000000.0) #define UM_TO_MM(VALUE) (((k64f)(VALUE)) / 1000.0) -namespace GocatorSensor +namespace gocator_sensor { - typedef struct ProfilePoint - { - double x; // x-coordinate in engineering units (mm) - position along laser line - double z; // z-coordinate in engineering units (mm) - height (at the given x position) - unsigned char intensity; - } ProfilePoint; +typedef struct ProfilePoint +{ + double x; // x-coordinate in engineering units (mm) - position along laser line + double z; // z-coordinate in engineering units (mm) - height (at the given x position) + unsigned char intensity; +} ProfilePoint; // status values - enum {DEVICE_NOT_FOUND = 0, DEVICE_FOUND, DEVICE_NOT_CONNECT, DEVICE_CONNECT, DEVICE_RUNNING}; +enum {DEVICE_NOT_FOUND = 0, DEVICE_FOUND, DEVICE_NOT_CONNECT, DEVICE_CONNECT, DEVICE_RUNNING}; // device parameters struct - struct DeviceParams +struct DeviceParams +{ + std::string ip_address_; + std::string model_name_; + unsigned int sn_; + + void print() const { - std::string ip_address_; - std::string model_name_; - unsigned int sn_; - - void print() const - { - std::cout << "\tIP ad: \t" << ip_address_ << std::endl; - std::cout << "\tModel: \t" << model_name_ << std::endl; - std::cout << "\tSN: \t" << sn_ << std::endl; - } - }; + std::cout << "\tIP ad: \t" << ip_address_ << std::endl; + std::cout << "\tModel: \t" << model_name_ << std::endl; + std::cout << "\tSN: \t" << sn_ << std::endl; + } +}; // device configuration struct - struct CaptureParams +struct CaptureParams +{ + double exposure_time_; // in useconds + double spacing_interval_; // in millimeters + void print() const { - double exposure_time_; // in useconds - double spacing_interval_; // in millimeters - - void print() const - { - std::cout << "\texposure [us]: \t" << exposure_time_ << std::endl; - std::cout << "\tspacing [mm]: \t" << spacing_interval_ << std::endl; - } - }; + std::cout << "\texposure [us]: \t" << exposure_time_ << std::endl; + std::cout << "\tspacing [mm]: \t" << spacing_interval_ << std::endl; + } +}; // Device class - class Device - { +class Device +{ protected: - // current point cloud. Maybe not necessary to be here! - // pcl::PointCloud::Ptr p_cloud_; - // p_cloud_ = new pcl::PointCloud + // current point cloud. Maybe not necessary to be here! + // pcl::PointCloud::Ptr p_cloud_; + // p_cloud_ = new pcl::PointCloud - // driver status - unsigned int status_; + // driver status + unsigned int status_; - // device fixed params - DeviceParams device_params_; + // device fixed params + DeviceParams device_params_; - // device configuration - CaptureParams capture_params_; + // device configuration + CaptureParams capture_params_; - // GO API objects - kAssembly go_api_; - GoSystem go_system_; - GoSensor go_sensor_; - GoSetup go_setup_; - GoDataSet go_dataset_; - GoStamp * go_stamp_ptr_; + // GO API objects + kAssembly go_api_; + GoSystem go_system_; + GoSensor go_sensor_; + GoSetup go_setup_; + GoDataSet go_dataset_; + GoStamp * go_stamp_ptr_; public: - /** \brief Constructor - * - * Constructor. Sets params_ struct. - * - **/ - explicit Device(const std::string & _ip_address); - - /** \brief Destructor - * - * Destructor - * - **/ - ~Device(); - - /** \brief Connect to a pysical device given an ip address - * - * Connect to a pysical device given an ip address - * - **/ -// int connect(); - - /** \brief Set/get device parameters to/from the camera - * - * Set/get device parameters to/from the camera - * - **/ - int configure(const CaptureParams & _configs); - - /** \brief Start device data acquisition - * - * Start device data acquisition - * - **/ - int start(); - - /** \brief Stop device dat acquisition - * - * Stop device data acquisition - * - **/ - int stop(); - - /** \brief Get the current snapshot - * - * Get the current snapshot, when in continuous acquisition - * - **/ - int getCurrentSnapshot(pcl::PointCloud < pcl::PointXYZ > & _p_cloud); - - /** \brief Get a single snapshot in the same thread - * - * Get a single snapshot in the same thread - * - **/ - int getSingleSnapshot(pcl::PointCloud < pcl::PointXYZ > & _p_cloud); - - int getProfile(pcl::PointCloud < pcl::PointXYZ > & _p_cloud); - - - /** \brief Returns all health data as a string - * - * Returns all health data as a string - * - **/ - void getDeviceHealth(std::string & _health_str) const; - - /** \brief Returns three device temperatures - * - * Returns three device temperatures: internal, projector and laser - * - **/ - void getTemperature( - double & _internal_temp, double & _projector_temp, - double & _laser_temp) const; - - /** \brief Close the connection to a physical device - * - * Close the connection to a physical device - * - **/ - int close(); - - /** \brief Print the device configuration - * - * Print the device configuration - * - **/ - void printDeviceData() const; - - /** \brief Send a trigger signal - * - **/ - void sendTrigger() const; - }; -} // namespace GocatorSensor + /** \brief Constructor + * + * Constructor. Sets params_ struct. + * + **/ + explicit Device(const std::string & _ip_address); + + /** \brief Destructor + * + * Destructor + * + **/ + ~Device(); + + /** \brief Connect to a pysical device given an ip address + * + * Connect to a pysical device given an ip address + * + **/ + // int connect(); + + /** \brief Set/get device parameters to/from the camera + * + * Set/get device parameters to/from the camera + * + **/ + int configure(const CaptureParams & _configs); + + /** \brief Start device data acquisition + * + * Start device data acquisition + * + **/ + int start(); + + /** \brief Stop device dat acquisition + * + * Stop device data acquisition + * + **/ + int stop(); + + /** \brief Get the current snapshot + * + * Get the current snapshot, when in continuous acquisition + * + **/ + int getCurrentSnapshot(pcl::PointCloud < pcl::PointXYZ > & _p_cloud); + + /** \brief Get a single snapshot in the same thread + * + * Get a single snapshot in the same thread + * + **/ + int getSingleSnapshot(pcl::PointCloud < pcl::PointXYZ > & _p_cloud); + + int getProfile(pcl::PointCloud < pcl::PointXYZ > & _p_cloud); + + + /** \brief Returns all health data as a string + * + * Returns all health data as a string + * + **/ + void getDeviceHealth(std::string & _health_str) const; + + /** \brief Returns three device temperatures + * + * Returns three device temperatures: internal, projector and laser + * + **/ + void getTemperature( + double & _internal_temp, double & _projector_temp, + double & _laser_temp) const; + + /** \brief Close the connection to a physical device + * + * Close the connection to a physical device + * + **/ + int close(); + + /** \brief Print the device configuration + * + * Print the device configuration + * + **/ + void printDeviceData() const; + + /** \brief Send a trigger signal + * + **/ + void sendTrigger() const; +}; + +} // namespace gocator_sensor #endif // DRIVER__GOCATORSENSOR_H_ From 0bf90cae371a52a3e40b55d25cdfe65196e1c5cf Mon Sep 17 00:00:00 2001 From: MosserLoic Date: Wed, 19 Apr 2023 14:21:48 +0200 Subject: [PATCH 15/30] changed Namespace in gocatorNode --- .../src/driver/gocatorSensor.cpp | 26 +++++++++---------- .../src/nodes/gocatorSensorNode.cpp | 6 ++--- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp b/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp index a23a5fe..89a6b5f 100644 --- a/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp +++ b/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp @@ -14,7 +14,7 @@ #include "gocatorSensor.h" -GocatorSensor::Device::Device(const std::string & _ip_address) +gocator_sensor::Device::Device(const std::string & _ip_address) { kStatus status; kIpAddress ipAddress; @@ -95,7 +95,7 @@ GocatorSensor::Device::Device(const std::string & _ip_address) device_params_.print(); } -GocatorSensor::Device::~Device() +gocator_sensor::Device::~Device() { kStatus status; @@ -107,7 +107,7 @@ GocatorSensor::Device::~Device() std::cout << "~Device(). Gocator Sensor Stopped and Device Object Destroyed." << std::endl; } -int GocatorSensor::Device::configure(const CaptureParams & _configs) +int gocator_sensor::Device::configure(const CaptureParams & _configs) { kStatus status; @@ -139,7 +139,7 @@ int GocatorSensor::Device::configure(const CaptureParams & _configs) return 1; } -int GocatorSensor::Device::start() +int gocator_sensor::Device::start() { kStatus status; @@ -159,7 +159,7 @@ int GocatorSensor::Device::start() return 1; } -int GocatorSensor::Device::stop() +int gocator_sensor::Device::stop() { kStatus status; @@ -179,15 +179,15 @@ int GocatorSensor::Device::stop() return 1; } -int GocatorSensor::Device::getCurrentSnapshot(pcl::PointCloud & _p_cloud) +int gocator_sensor::Device::getCurrentSnapshot(pcl::PointCloud & _p_cloud) { } -int GocatorSensor::Device::getSingleSnapshot(pcl::PointCloud & _p_cloud) +int gocator_sensor::Device::getSingleSnapshot(pcl::PointCloud & _p_cloud) { } -int GocatorSensor::Device::getProfile(pcl::PointCloud & _p_cloud) +int gocator_sensor::Device::getProfile(pcl::PointCloud & _p_cloud) { unsigned int i, j, k, arrayIndex; GoDataSet dataset = kNULL; @@ -338,7 +338,7 @@ int GocatorSensor::Device::getProfile(pcl::PointCloud & _p_cloud) return 1; } -void GocatorSensor::Device::getDeviceHealth(std::string & _health_str) const +void gocator_sensor::Device::getDeviceHealth(std::string & _health_str) const { // local variables GoDataSet health_data = kNULL; @@ -364,7 +364,7 @@ void GocatorSensor::Device::getDeviceHealth(std::string & _health_str) const _health_str = sstr.str(); } -void GocatorSensor::Device::getTemperature( +void gocator_sensor::Device::getTemperature( double & _internal_temp, double & _projector_temp, double & _laser_temp) const { @@ -402,15 +402,15 @@ void GocatorSensor::Device::getTemperature( } } -int GocatorSensor::Device::close() +int gocator_sensor::Device::close() { } -void GocatorSensor::Device::printDeviceData() const +void gocator_sensor::Device::printDeviceData() const { } -void GocatorSensor::Device::sendTrigger() const +void gocator_sensor::Device::sendTrigger() const { printf("sending trigger \n"); kStatus status = GoSensor_Trigger(go_sensor_); diff --git a/3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp b/3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp index 017c5e3..8ce3373 100644 --- a/3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp +++ b/3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp @@ -32,7 +32,7 @@ class GocatorSensorNode : public rclcpp::Node GocatorSensorNode() : Node("gocatorSensorNode") { - gsensor_ = new GocatorSensor::Device(SENSOR_IP); + gsensor_ = new gocator_sensor::Device(SENSOR_IP); capture_params_.exposure_time_ = 110; capture_params_.spacing_interval_ = 0.1; gsensor_->configure(capture_params_); @@ -69,8 +69,8 @@ class GocatorSensorNode : public rclcpp::Node rclcpp::Service::SharedPtr service_; rclcpp::Publisher::SharedPtr publisher_; - GocatorSensor::Device * gsensor_; - GocatorSensor::CaptureParams capture_params_; + gocator_sensor::Device * gsensor_; + gocator_sensor::CaptureParams capture_params_; }; int main(int argc, char * argv[]) From ec2a5491c5422cfd7221e6523b9394023f09e456 Mon Sep 17 00:00:00 2001 From: Mosserl Date: Wed, 19 Apr 2023 17:43:14 +0200 Subject: [PATCH 16/30] Error colcon build --- 3D_printer/erreur.txt | 15 +++++++++++++++ .../printer3d_manager/nodes/printer3d_constant.py | 2 +- .../nodes/printer_control_node.py | 12 ++++++------ 3 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 3D_printer/erreur.txt diff --git a/3D_printer/erreur.txt b/3D_printer/erreur.txt new file mode 100644 index 0000000..48aa6c1 --- /dev/null +++ b/3D_printer/erreur.txt @@ -0,0 +1,15 @@ +Starting >>> printer3d_gocator_msgs +Starting >>> printer3d_driver +Starting >>> printer3d_image_capture +Starting >>> printer3d_manager +Finished <<< printer3d_driver [0.27s] +Starting >>> printer3d_msgs +Finished <<< printer3d_manager [0.30s] +Finished <<< printer3d_image_capture [0.33s] +Finished <<< printer3d_gocator_msgs [0.85s] +Starting >>> printer3d_profile_capture +Finished <<< printer3d_msgs [0.82s] + +Summary: 5 packages finished [5.00s] + 1 package failed: printer3d_profile_capture + 1 package had stderr output: printer3d_profile_capture diff --git a/3D_printer/src/printer3d_manager/nodes/printer3d_constant.py b/3D_printer/src/printer3d_manager/nodes/printer3d_constant.py index bc8d76a..295ce40 100644 --- a/3D_printer/src/printer3d_manager/nodes/printer3d_constant.py +++ b/3D_printer/src/printer3d_manager/nodes/printer3d_constant.py @@ -20,7 +20,7 @@ YMAX = 219 ZMIN = 0 -ZMAX = 60 +ZMAX = 58 GAP = 31.5 diff --git a/3D_printer/src/printer3d_manager/nodes/printer_control_node.py b/3D_printer/src/printer3d_manager/nodes/printer_control_node.py index 72b4fed..db1120f 100644 --- a/3D_printer/src/printer3d_manager/nodes/printer_control_node.py +++ b/3D_printer/src/printer3d_manager/nodes/printer_control_node.py @@ -187,7 +187,6 @@ def sendProfileMeasureRequest(self): for points in profile: profile_line.append([[points[0], 0, points[2]]]) break - self.get_logger().info('scan finished') return profile_line def sendGcodeSendingRequest(self, gcode): @@ -198,18 +197,19 @@ def sendGcodeSendingRequest(self, gcode): while rclpy.ok(): rclpy.spin_once(self) if self.future_printer_driver.done(): - self.get_logger().info('gcode sended') break - if __name__ == '__main__': carriageReturn = ['G28\n'] rclpy.init() - printer_control_node = PrinterControlNode('impression_base_2') + printer_control_node = PrinterControlNode('impression_base_50_pourcents') printer_control_node.sendGcodeSendingRequest(carriageReturn) gcode = printer_control_node.loadGcode('/home/gulltor/Ramsai_Robotics/Gcodes/piece_test_base.gcode') - for i in range(90, len(gcode)): - # printer_control_node.sendGcodeSendingRequest(gcode[i]) + for i in range(0, len(gcode)-1): + printer_control_node.get_logger.info('lancement de la couche '+str(i+1)+' sur '+str(len(gcode)-1)) + printer_control_node.sendGcodeSendingRequest(gcode[i]) + printer_control_node.get_logger.info('fin de la couche '+str(i+1)+' sur '+str(len(gcode))) printer_control_node.takeCurrentLayerPhoto() printer_control_node.scanCurrentLayer(gcode[i]) + rclpy.shutdown() From a8dd51261f358776e7c2ae906d45169bf81d2ee2 Mon Sep 17 00:00:00 2001 From: MosserLoic Date: Wed, 19 Apr 2023 17:58:59 +0200 Subject: [PATCH 17/30] colcon error corrected --- 3D_printer/erreur.txt | 15 - .../nodes/gcode_monitor_node.py | 40 ++- .../nodes/image_capture_calibration.py | 34 ++- .../src/driver/gocatorSensor.cpp | 2 +- .../src/driver/gocatorSensor.h | 282 +++++++++--------- 5 files changed, 214 insertions(+), 159 deletions(-) delete mode 100644 3D_printer/erreur.txt diff --git a/3D_printer/erreur.txt b/3D_printer/erreur.txt deleted file mode 100644 index 48aa6c1..0000000 --- a/3D_printer/erreur.txt +++ /dev/null @@ -1,15 +0,0 @@ -Starting >>> printer3d_gocator_msgs -Starting >>> printer3d_driver -Starting >>> printer3d_image_capture -Starting >>> printer3d_manager -Finished <<< printer3d_driver [0.27s] -Starting >>> printer3d_msgs -Finished <<< printer3d_manager [0.30s] -Finished <<< printer3d_image_capture [0.33s] -Finished <<< printer3d_gocator_msgs [0.85s] -Starting >>> printer3d_profile_capture -Finished <<< printer3d_msgs [0.82s] - -Summary: 5 packages finished [5.00s] - 1 package failed: printer3d_profile_capture - 1 package had stderr output: printer3d_profile_capture diff --git a/3D_printer/src/printer3d_driver/nodes/gcode_monitor_node.py b/3D_printer/src/printer3d_driver/nodes/gcode_monitor_node.py index 44782a4..aa06713 100644 --- a/3D_printer/src/printer3d_driver/nodes/gcode_monitor_node.py +++ b/3D_printer/src/printer3d_driver/nodes/gcode_monitor_node.py @@ -21,7 +21,19 @@ def openSerialPort(port, baud): - # open the serial port + """ + Handle the opening of the serial port and exit if the port haven't been opened. + + Args: + ------- + port (string): supposed to be "COM" plus the number associated to the + baud (int): baudrate of the port communication (commonly 9600, 115200, 250000 ...) + + Returns + ------- + pyserial object: an object allowing to send and receive data through USB + + """ print('Opening Serial Port...') try: s = serial.Serial(port, baud) @@ -37,6 +49,18 @@ def openSerialPort(port, baud): def removeComment(string): + """ + Remove the comments from a gcode line stored as a string. + + Args + ------- + string (string): gcode line with a possible comment inside + + Returns + ------- + string: input string without comment + + """ if (string.find(';') == -1): return string else: @@ -45,6 +69,7 @@ def removeComment(string): class GcodeMonitorNode(Node): def __init__(self): + """Gcodemonitornode class constructor.""" super().__init__('printer_gcode_monitor') self.serialPort = openSerialPort('/dev/ttyACM0', 250000) self.serialPort.write(b"\n\n") @@ -52,6 +77,19 @@ def __init__(self): self.gcodeService = self.create_service(GcodeCommand, 'send_gcode', self.execute_gcode_sending) def execute_gcode_sending(self, request, response): + """ + Execute this function of the service send_gcode provided by this ROS2 node. + + Args + ------- + request (list of string): list of gcode lines to be sended through the serial communication + response (bool): True + + Returns + ------- + bool: True + + """ gcode = request.gcode_strings self.get_logger().info('Executing Gcode') feedback = 0.0 diff --git a/3D_printer/src/printer3d_image_capture/nodes/image_capture_calibration.py b/3D_printer/src/printer3d_image_capture/nodes/image_capture_calibration.py index 160445c..46323c2 100644 --- a/3D_printer/src/printer3d_image_capture/nodes/image_capture_calibration.py +++ b/3D_printer/src/printer3d_image_capture/nodes/image_capture_calibration.py @@ -19,22 +19,46 @@ import cv2 YPOSPHOTO = 200 +""" + Imagecapturenode class constructor. + Parameters + ---------- + cam : int + camera number and specifically designed for linux systems. Defaults to 0. + + """ class ImageCaptureNode(Node): def __init__(self, cam=0): + """ + Imagecapturenode class constructor. + + Args: + ---- + cam (int, optional): _description_. Defaults to 0. + + """ super().__init__('printer_image_capture') self.cameraNumber = cam - self.client_printer_driver = self.create_client(GcodeCommand, 'send_gcode') while not self.client_printer_driver.wait_for_service(timeout_sec=1.0): self.get_logger().info('profile measure service not available, waiting again...') self.req_printer_driver = GcodeCommand.Request() def __del__(self): + """Imagecapturenode destructor. Release the camera.""" self.webcam.release() def showVideo(self): + """ + Show the image captured by the camera continuously. Can be stopped by pressing q. + + Returns + ------- + int: returns 0 + + """ self.webcam = cv2.VideoCapture("/dev/video" + str(self.cameraNumber)) # Be careful with the number after video while (True): check, frame = self.webcam.read() @@ -46,6 +70,14 @@ def showVideo(self): return 0 def sendGcodeSendingRequest(self, gcode): + """ + Ask for the sending of the gcode line "gcode" through the ROS2 service "send_gcode". + + Args: + ---- + gcode: list of gcode lines + + """ self.req_printer_driver.gcode_strings = gcode self.future_printer_driver = self.client_printer_driver.call_async(self.req_printer_driver) while rclpy.ok(): diff --git a/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp b/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp index 89a6b5f..3877eeb 100644 --- a/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp +++ b/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.cpp @@ -231,7 +231,7 @@ int gocator_sensor::Device::getProfile(pcl::PointCloud & _p_cloud for (k = 0; k < GoResampledProfileMsg_Count(profileMsg); ++k) { unsigned int validPointCount = 0; - __int16 * data = GoResampledProfileMsg_At(profileMsg, k); + short * data = GoResampledProfileMsg_At(profileMsg, k); double XResolution = NM_TO_MM(GoResampledProfileMsg_XResolution(profileMsg)); double ZResolution = NM_TO_MM(GoResampledProfileMsg_ZResolution(profileMsg)); double XOffset = UM_TO_MM(GoResampledProfileMsg_XOffset(profileMsg)); diff --git a/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.h b/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.h index 277774a..1421df0 100644 --- a/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.h +++ b/3D_printer/src/printer3d_profile_capture/src/driver/gocatorSensor.h @@ -31,7 +31,7 @@ // constants #define SENSOR_IP "192.168.1.10" // sensor IP address #define RECEIVE_TIMEOUT 20000000 // timeout for snapshot acquisition -#define INVALID_RANGE_16BIT ((__int16)0x8000) // gocator transmits range data +#define INVALID_RANGE_16BIT ((short)0x8000) // gocator transmits range data // as 16-bit signed integers. 0x8000 signifies invalid range data. #define DOUBLE_MAX ((k64f)1.7976931348623157e+308) // 64-bit double - largest positive value. #define INVALID_RANGE_DOUBLE ((k64f) - DOUBLE_MAX) // floating point value to @@ -42,163 +42,163 @@ namespace gocator_sensor { -typedef struct ProfilePoint -{ - double x; // x-coordinate in engineering units (mm) - position along laser line - double z; // z-coordinate in engineering units (mm) - height (at the given x position) - unsigned char intensity; -} ProfilePoint; + typedef struct ProfilePoint + { + double x; // x-coordinate in engineering units (mm) - position along laser line + double z; // z-coordinate in engineering units (mm) - height (at the given x position) + unsigned char intensity; + } ProfilePoint; // status values -enum {DEVICE_NOT_FOUND = 0, DEVICE_FOUND, DEVICE_NOT_CONNECT, DEVICE_CONNECT, DEVICE_RUNNING}; + enum {DEVICE_NOT_FOUND = 0, DEVICE_FOUND, DEVICE_NOT_CONNECT, DEVICE_CONNECT, DEVICE_RUNNING}; // device parameters struct -struct DeviceParams -{ - std::string ip_address_; - std::string model_name_; - unsigned int sn_; - - void print() const + struct DeviceParams { - std::cout << "\tIP ad: \t" << ip_address_ << std::endl; - std::cout << "\tModel: \t" << model_name_ << std::endl; - std::cout << "\tSN: \t" << sn_ << std::endl; - } -}; + std::string ip_address_; + std::string model_name_; + unsigned int sn_; + + void print() const + { + std::cout << "\tIP ad: \t" << ip_address_ << std::endl; + std::cout << "\tModel: \t" << model_name_ << std::endl; + std::cout << "\tSN: \t" << sn_ << std::endl; + } + }; // device configuration struct -struct CaptureParams -{ - double exposure_time_; // in useconds - double spacing_interval_; // in millimeters - void print() const + struct CaptureParams { - std::cout << "\texposure [us]: \t" << exposure_time_ << std::endl; - std::cout << "\tspacing [mm]: \t" << spacing_interval_ << std::endl; - } -}; + double exposure_time_; // in useconds + double spacing_interval_; // in millimeters + void print() const + { + std::cout << "\texposure [us]: \t" << exposure_time_ << std::endl; + std::cout << "\tspacing [mm]: \t" << spacing_interval_ << std::endl; + } + }; // Device class -class Device -{ + class Device + { protected: - // current point cloud. Maybe not necessary to be here! - // pcl::PointCloud::Ptr p_cloud_; - // p_cloud_ = new pcl::PointCloud + // current point cloud. Maybe not necessary to be here! + // pcl::PointCloud::Ptr p_cloud_; + // p_cloud_ = new pcl::PointCloud - // driver status - unsigned int status_; + // driver status + unsigned int status_; - // device fixed params - DeviceParams device_params_; + // device fixed params + DeviceParams device_params_; - // device configuration - CaptureParams capture_params_; + // device configuration + CaptureParams capture_params_; - // GO API objects - kAssembly go_api_; - GoSystem go_system_; - GoSensor go_sensor_; - GoSetup go_setup_; - GoDataSet go_dataset_; - GoStamp * go_stamp_ptr_; + // GO API objects + kAssembly go_api_; + GoSystem go_system_; + GoSensor go_sensor_; + GoSetup go_setup_; + GoDataSet go_dataset_; + GoStamp * go_stamp_ptr_; public: - /** \brief Constructor - * - * Constructor. Sets params_ struct. - * - **/ - explicit Device(const std::string & _ip_address); - - /** \brief Destructor - * - * Destructor - * - **/ - ~Device(); - - /** \brief Connect to a pysical device given an ip address - * - * Connect to a pysical device given an ip address - * - **/ - // int connect(); - - /** \brief Set/get device parameters to/from the camera - * - * Set/get device parameters to/from the camera - * - **/ - int configure(const CaptureParams & _configs); - - /** \brief Start device data acquisition - * - * Start device data acquisition - * - **/ - int start(); - - /** \brief Stop device dat acquisition - * - * Stop device data acquisition - * - **/ - int stop(); - - /** \brief Get the current snapshot - * - * Get the current snapshot, when in continuous acquisition - * - **/ - int getCurrentSnapshot(pcl::PointCloud < pcl::PointXYZ > & _p_cloud); - - /** \brief Get a single snapshot in the same thread - * - * Get a single snapshot in the same thread - * - **/ - int getSingleSnapshot(pcl::PointCloud < pcl::PointXYZ > & _p_cloud); - - int getProfile(pcl::PointCloud < pcl::PointXYZ > & _p_cloud); - - - /** \brief Returns all health data as a string - * - * Returns all health data as a string - * - **/ - void getDeviceHealth(std::string & _health_str) const; - - /** \brief Returns three device temperatures - * - * Returns three device temperatures: internal, projector and laser - * - **/ - void getTemperature( - double & _internal_temp, double & _projector_temp, - double & _laser_temp) const; - - /** \brief Close the connection to a physical device - * - * Close the connection to a physical device - * - **/ - int close(); - - /** \brief Print the device configuration - * - * Print the device configuration - * - **/ - void printDeviceData() const; - - /** \brief Send a trigger signal - * - **/ - void sendTrigger() const; -}; + /** \brief Constructor + * + * Constructor. Sets params_ struct. + * + **/ + explicit Device(const std::string & _ip_address); + + /** \brief Destructor + * + * Destructor + * + **/ + ~Device(); + + /** \brief Connect to a physical device given an ip address + * + * Connect to a physical device given an ip address + * + **/ + // int connect(); + + /** \brief Set/get device parameters to/from the camera + * + * Set/get device parameters to/from the camera + * + **/ + int configure(const CaptureParams & _configs); + + /** \brief Start device data acquisition + * + * Start device data acquisition + * + **/ + int start(); + + /** \brief Stop device dat acquisition + * + * Stop device data acquisition + * + **/ + int stop(); + + /** \brief Get the current snapshot + * + * Get the current snapshot, when in continuous acquisition + * + **/ + int getCurrentSnapshot(pcl::PointCloud < pcl::PointXYZ > & _p_cloud); + + /** \brief Get a single snapshot in the same thread + * + * Get a single snapshot in the same thread + * + **/ + int getSingleSnapshot(pcl::PointCloud < pcl::PointXYZ > & _p_cloud); + + int getProfile(pcl::PointCloud < pcl::PointXYZ > & _p_cloud); + + + /** \brief Returns all health data as a string + * + * Returns all health data as a string + * + **/ + void getDeviceHealth(std::string & _health_str) const; + + /** \brief Returns three device temperatures + * + * Returns three device temperatures: internal, projector and laser + * + **/ + void getTemperature( + double & _internal_temp, double & _projector_temp, + double & _laser_temp) const; + + /** \brief Close the connection to a physical device + * + * Close the connection to a physical device + * + **/ + int close(); + + /** \brief Print the device configuration + * + * Print the device configuration + * + **/ + void printDeviceData() const; + + /** \brief Send a trigger signal + * + **/ + void sendTrigger() const; + }; } // namespace gocator_sensor From 5b27cf45ddf5c3fd450ebdbba4e698d46871e01c Mon Sep 17 00:00:00 2001 From: Mosser_Loic Date: Wed, 30 Aug 2023 11:33:39 +0200 Subject: [PATCH 18/30] split driver features with launch files --- .../launch_basic_print.cpython-310.pyc | Bin 0 -> 594 bytes 3D_printer/launch/launch_basic_print.py | 18 ++ .../launch/launch_print_with_image_capture.py | 24 +++ ...h_print_with_image_capture_plus_scanner.py | 30 +++ .../src/printer3d_manager/CMakeLists.txt | 5 +- .../nodes/printer_imageCapture_node.py | 151 ++++++++++++++ .../printer3d_manager/nodes/printer_node.py | 127 ++++++++++++ ...y => printer_scanner_imageCapture_node.py} | 0 .../nodes/printer_scanner_node.py | 190 ++++++++++++++++++ 9 files changed, 544 insertions(+), 1 deletion(-) create mode 100644 3D_printer/launch/__pycache__/launch_basic_print.cpython-310.pyc create mode 100644 3D_printer/launch/launch_basic_print.py create mode 100644 3D_printer/launch/launch_print_with_image_capture.py create mode 100644 3D_printer/launch/launch_print_with_image_capture_plus_scanner.py create mode 100644 3D_printer/src/printer3d_manager/nodes/printer_imageCapture_node.py create mode 100644 3D_printer/src/printer3d_manager/nodes/printer_node.py rename 3D_printer/src/printer3d_manager/nodes/{printer_control_node.py => printer_scanner_imageCapture_node.py} (100%) create mode 100644 3D_printer/src/printer3d_manager/nodes/printer_scanner_node.py diff --git a/3D_printer/launch/__pycache__/launch_basic_print.cpython-310.pyc b/3D_printer/launch/__pycache__/launch_basic_print.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bdd847ec1d0d7061824d6ceced14b37cb8c7b0d6 GIT binary patch literal 594 zcmZWmJx{|h5Vc)5{ZLCkpc9NNS-P+ygajk%!qz2neO8D_?8r$GbcK~4!e8>r#Ka8h zz&TAnBrfvPz3212)5Y}rU4jvkZ#ZUze0p*isF7#( zH!|nYyeDDsg_R_vZgeM>T0Y#WLfRxR6Qfb&GXqNcio<9lxxrJpl%%9Uf%&e`eCNml zXh9n~p2h5yqDyz?hPh32sq6(rV3Q|h-AS!Pu|$`sP#Tn7O*SkuIw_5fG+s^f7dQSd zhupPtAs7>!6HEA_T z$gE$nZ6JIQd*pKuzmv4uUbGNJBBQFgpZYXbT3J!5sJ@5&dO5x;&JY;ge|*h?E#vFp z#}2Vz7B*e5X;9g_aox?DVk)HnS4A~aRlT2TlMS$gYhPvtmZ`d;-Zenzksj@_Kj*!n A6#xJL literal 0 HcmV?d00001 diff --git a/3D_printer/launch/launch_basic_print.py b/3D_printer/launch/launch_basic_print.py new file mode 100644 index 0000000..1b0b9e3 --- /dev/null +++ b/3D_printer/launch/launch_basic_print.py @@ -0,0 +1,18 @@ +from launch import LaunchDescription +from launch_ros.actions import Node + +def generate_launch_description(): + return LaunchDescription([ + Node( + package='printer3d_driver', + namespace='printer_gcode_sender', + executable='gcode_monitor_node.py', + name='gcode_monitor_node' + ), + Node( + package='printer3d_manager', + namespace='printer_manager', + executable='printer_node.py', + name='printer_control_node' + ) + ]) \ No newline at end of file diff --git a/3D_printer/launch/launch_print_with_image_capture.py b/3D_printer/launch/launch_print_with_image_capture.py new file mode 100644 index 0000000..63ac3f8 --- /dev/null +++ b/3D_printer/launch/launch_print_with_image_capture.py @@ -0,0 +1,24 @@ +from launch import LaunchDescription +from launch_ros.actions import Node + +def generate_launch_description(): + return LaunchDescription([ + Node( + package='printer3d_driver', + namespace='printer_gcode_sender', + executable='gcode_monitor_node.py', + name='gcode_monitor_node' + ), + Node( + package='printer3d_image_capture', + namespace='printer_image_capture', + executable='image_capture_node.py', + name='image_capture_node' + ), + Node( + package='printer3d_manager', + namespace='printer_manager', + executable='printer_imageCapture_node.py', + name='printer_control_node' + ) + ]) \ No newline at end of file diff --git a/3D_printer/launch/launch_print_with_image_capture_plus_scanner.py b/3D_printer/launch/launch_print_with_image_capture_plus_scanner.py new file mode 100644 index 0000000..edd9cfd --- /dev/null +++ b/3D_printer/launch/launch_print_with_image_capture_plus_scanner.py @@ -0,0 +1,30 @@ +from launch import LaunchDescription +from launch_ros.actions import Node + +def generate_launch_description(): + return LaunchDescription([ + Node( + package='printer3d_driver', + namespace='printer_gcode_sender', + executable='gcode_monitor_node.py', + name='gcode_monitor_node' + ), + Node( + package='printer3d_image_capture', + namespace='printer_image_capture', + executable='image_capture_node.py', + name='image_capture_node' + ), + Node( + package='printer3d_profile_capture', + namespace='printer_gocator_communication', + executable='gocator_sensor_node.py', + name='gocator_sensor_node' + ), + Node( + package='printer3d_manager', + namespace='printer_manager', + executable='printer_scanner_imageCapture_node.py', + name='printer_control_node' + ) + ]) \ No newline at end of file diff --git a/3D_printer/src/printer3d_manager/CMakeLists.txt b/3D_printer/src/printer3d_manager/CMakeLists.txt index b6bb8d1..a2e0bfc 100644 --- a/3D_printer/src/printer3d_manager/CMakeLists.txt +++ b/3D_printer/src/printer3d_manager/CMakeLists.txt @@ -38,7 +38,10 @@ endif() install( PROGRAMS - nodes/printer_control_node.py + nodes/printer_node.py + nodes/printer_imageCapture_node.py + nodes/printer_scanner_node.py + nodes/printer_scanner_imageCapture_node.py nodes/printer_control_test.py nodes/printer3d_constant.py nodes/utility.py diff --git a/3D_printer/src/printer3d_manager/nodes/printer_imageCapture_node.py b/3D_printer/src/printer3d_manager/nodes/printer_imageCapture_node.py new file mode 100644 index 0000000..94e82da --- /dev/null +++ b/3D_printer/src/printer3d_manager/nodes/printer_imageCapture_node.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python3 +# Copyright 2023 ICube Laboratory, University of Strasbourg +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import rclpy +from rclpy.node import Node +from printer3d_msgs.srv import GcodeCommand +from printer3d_msgs.srv import ImageCommand +from utility import getBordersSimpleGcode, getBordersGcode, work_on_gcode_file +import printer3d_constant +import os +import numpy as np + + +class PrinterControlNode(Node): + def __init__(self, historyFilename): + super().__init__('printer_control') + + """Initialisation of the printing process workspace""" + self.historyFilename = historyFilename + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename) + except Exception: + pass + + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/gcode') + except Exception: + pass + + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/scan') + except Exception: + pass + + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/photos') + except Exception: + pass + + # access to the image capture service + + self.client_image_capture = self.create_client(ImageCommand, 'ask_capture_image') + while not self.client_image_capture.wait_for_service(timeout_sec=1.0): + self.get_logger().info('image capture service not available, waiting again...') + self.req_image_capture = ImageCommand.Request() + + # access to the printer driver service + + self.client_printer_driver = self.create_client(GcodeCommand, 'send_gcode') + while not self.client_printer_driver.wait_for_service(timeout_sec=1.0): + self.get_logger().info('profile measure service not available, waiting again...') + self.req_printer_driver = GcodeCommand.Request() + + self.imageNumber = 0 + self.scanNumber = 0 + + def loadGcode(self, gcodeFilename): + fileFullGcode = open(gcodeFilename) + rawGode = fileFullGcode.readlines() + fileFullGcode.close() + + (self.xMin, self.yMin, self.zMin, self.xMax, self.yMax, self.zMax) = getBordersGcode(rawGode) + self.get_logger().info('xMin : ' + str(self.xMin)) + self.get_logger().info('xMax : ' + str(self.xMax)) + self.get_logger().info('yMin : ' + str(self.yMin)) + self.get_logger().info('yMax : ' + str(self.yMax)) + self.get_logger().info('zMin : ' + str(self.zMin)) + self.get_logger().info('zMax : ' + str(self.zMax)) + + assert self.xMin >= printer3d_constant.XMIN + assert self.xMax <= printer3d_constant.XMAX + + assert self.yMin >= printer3d_constant.YMIN + assert self.yMax <= printer3d_constant.YMAX + + assert self.zMin >= printer3d_constant.ZMIN + assert self.zMax <= printer3d_constant.ZMAX + self.gcodeLayers = work_on_gcode_file(rawGode) + + return self.gcodeLayers + + def verifyGcodeBeforeSending(self, gcodeToVerify): + (self.xMin, self.yMin, self.zMin, self.xMax, self.yMax, self.zMax) = getBordersSimpleGcode(gcodeToVerify) + testXMin = self.xMin >= printer3d_constant.XMIN + testXMax = self.xMax <= printer3d_constant.XMAX + + testYMin = self.yMin >= printer3d_constant.YMIN + testYMax = self.yMax <= printer3d_constant.YMAX + + testZMin = self.zMin >= printer3d_constant.ZMIN + testZMax = self.zMax <= printer3d_constant.ZMAX + + if testXMin is False or testXMax is False or testYMin is False or testYMax is False or testZMin is False or testZMax is False: + return False + else: + return True + + def printCurrentLayer(self): + return 0 + + def takeCurrentLayerPhoto(self): + gcodeMoveToPos = ['G28 X0 Y0\n', 'G1 Y' + str(printer3d_constant.YPOSPHOTO) + ' F2400\n'] + self.sendGcodeSendingRequest(gcodeMoveToPos) + self.sendImageCaptureRequest('/home/gulltor/Ramsai_Robotics/history/'+self.historyFilename+'/photos/layer_photo_'+str(self.imageNumber)+'.jpg') + self.imageNumber += 1 + return 0 + + def sendImageCaptureRequest(self, filename): + self.req_image_capture.filename = filename + self.future_image_capture = self.client_image_capture.call_async(self.req_image_capture) + while rclpy.ok(): + rclpy.spin_once(self) + if self.future_image_capture.done(): + self.get_logger().info('capture finished') + break + + def sendGcodeSendingRequest(self, gcode): + assert self.verifyGcodeBeforeSending(gcode) is True + + self.req_printer_driver.gcode_strings = gcode + self.future_printer_driver = self.client_printer_driver.call_async(self.req_printer_driver) + while rclpy.ok(): + rclpy.spin_once(self) + if self.future_printer_driver.done(): + break + +if __name__ == '__main__': + carriageReturn = ['G28\n'] + rclpy.init() + printer_control_node = PrinterControlNode('impression_base_50_pourcents') + printer_control_node.sendGcodeSendingRequest(carriageReturn) + gcode = printer_control_node.loadGcode('/home/gulltor/Ramsai_Robotics/Gcodes/piece_test_base.gcode') + for i in range(0, len(gcode)-1): + printer_control_node.get_logger.info('lancement de la couche '+str(i+1)+' sur '+str(len(gcode)-1)) + printer_control_node.sendGcodeSendingRequest(gcode[i]) + printer_control_node.get_logger.info('fin de la couche '+str(i+1)+' sur '+str(len(gcode))) + printer_control_node.takeCurrentLayerPhoto() + + rclpy.shutdown() diff --git a/3D_printer/src/printer3d_manager/nodes/printer_node.py b/3D_printer/src/printer3d_manager/nodes/printer_node.py new file mode 100644 index 0000000..ea2b66b --- /dev/null +++ b/3D_printer/src/printer3d_manager/nodes/printer_node.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python3 +# Copyright 2023 ICube Laboratory, University of Strasbourg +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import rclpy +from rclpy.node import Node +from printer3d_msgs.srv import GcodeCommand +from utility import getBordersSimpleGcode, getBordersGcode, work_on_gcode_file +import printer3d_constant +import os +import numpy as np + + +class PrinterControlNode(Node): + def __init__(self, historyFilename): + super().__init__('printer_control') + + """Initialisation of the printing process workspace""" + self.historyFilename = historyFilename + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename) + except Exception: + pass + + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/gcode') + except Exception: + pass + + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/scan') + except Exception: + pass + + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/photos') + except Exception: + pass + + # access to the printer driver service + + self.client_printer_driver = self.create_client(GcodeCommand, 'send_gcode') + while not self.client_printer_driver.wait_for_service(timeout_sec=1.0): + self.get_logger().info('profile measure service not available, waiting again...') + self.req_printer_driver = GcodeCommand.Request() + + self.imageNumber = 0 + self.scanNumber = 0 + + def loadGcode(self, gcodeFilename): + fileFullGcode = open(gcodeFilename) + rawGode = fileFullGcode.readlines() + fileFullGcode.close() + + (self.xMin, self.yMin, self.zMin, self.xMax, self.yMax, self.zMax) = getBordersGcode(rawGode) + self.get_logger().info('xMin : ' + str(self.xMin)) + self.get_logger().info('xMax : ' + str(self.xMax)) + self.get_logger().info('yMin : ' + str(self.yMin)) + self.get_logger().info('yMax : ' + str(self.yMax)) + self.get_logger().info('zMin : ' + str(self.zMin)) + self.get_logger().info('zMax : ' + str(self.zMax)) + + assert self.xMin >= printer3d_constant.XMIN + assert self.xMax <= printer3d_constant.XMAX + + assert self.yMin >= printer3d_constant.YMIN + assert self.yMax <= printer3d_constant.YMAX + + assert self.zMin >= printer3d_constant.ZMIN + assert self.zMax <= printer3d_constant.ZMAX + self.gcodeLayers = work_on_gcode_file(rawGode) + + return self.gcodeLayers + + def verifyGcodeBeforeSending(self, gcodeToVerify): + (self.xMin, self.yMin, self.zMin, self.xMax, self.yMax, self.zMax) = getBordersSimpleGcode(gcodeToVerify) + testXMin = self.xMin >= printer3d_constant.XMIN + testXMax = self.xMax <= printer3d_constant.XMAX + + testYMin = self.yMin >= printer3d_constant.YMIN + testYMax = self.yMax <= printer3d_constant.YMAX + + testZMin = self.zMin >= printer3d_constant.ZMIN + testZMax = self.zMax <= printer3d_constant.ZMAX + + if testXMin is False or testXMax is False or testYMin is False or testYMax is False or testZMin is False or testZMax is False: + return False + else: + return True + + + def printCurrentLayer(self): + return 0 + + def sendGcodeSendingRequest(self, gcode): + assert self.verifyGcodeBeforeSending(gcode) is True + + self.req_printer_driver.gcode_strings = gcode + self.future_printer_driver = self.client_printer_driver.call_async(self.req_printer_driver) + while rclpy.ok(): + rclpy.spin_once(self) + if self.future_printer_driver.done(): + break + +if __name__ == '__main__': + carriageReturn = ['G28\n'] + rclpy.init() + printer_control_node = PrinterControlNode('impression_base_50_pourcents') + printer_control_node.sendGcodeSendingRequest(carriageReturn) + gcode = printer_control_node.loadGcode('/home/gulltor/Ramsai_Robotics/Gcodes/piece_test_base.gcode') + for i in range(0, len(gcode)-1): + printer_control_node.get_logger.info('lancement de la couche '+str(i+1)+' sur '+str(len(gcode)-1)) + printer_control_node.sendGcodeSendingRequest(gcode[i]) + printer_control_node.get_logger.info('fin de la couche '+str(i+1)+' sur '+str(len(gcode))) + + rclpy.shutdown() diff --git a/3D_printer/src/printer3d_manager/nodes/printer_control_node.py b/3D_printer/src/printer3d_manager/nodes/printer_scanner_imageCapture_node.py similarity index 100% rename from 3D_printer/src/printer3d_manager/nodes/printer_control_node.py rename to 3D_printer/src/printer3d_manager/nodes/printer_scanner_imageCapture_node.py diff --git a/3D_printer/src/printer3d_manager/nodes/printer_scanner_node.py b/3D_printer/src/printer3d_manager/nodes/printer_scanner_node.py new file mode 100644 index 0000000..c83bbf2 --- /dev/null +++ b/3D_printer/src/printer3d_manager/nodes/printer_scanner_node.py @@ -0,0 +1,190 @@ +#!/usr/bin/env python3 +# Copyright 2023 ICube Laboratory, University of Strasbourg +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import rclpy +from rclpy.node import Node +from printer3d_msgs.srv import GcodeCommand +from printer3d_gocator_msgs.srv import GocatorPTCloud +from utility import getBordersSimpleGcode, getBordersGcode, work_on_gcode_file +import printer3d_constant +import point_cloud2 as pc2 +import os +import numpy as np + + +class PrinterControlNode(Node): + def __init__(self, historyFilename): + super().__init__('printer_control') + + """Initialisation of the printing process workspace""" + self.historyFilename = historyFilename + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename) + except Exception: + pass + + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/gcode') + except Exception: + pass + + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/scan') + except Exception: + pass + + try: + os.mkdir('/home/gulltor/Ramsai_Robotics/history/'+historyFilename+'/photos') + except Exception: + pass + + # access to the profile measure service + + self.client_profile_measure = self.create_client(GocatorPTCloud, 'gocator_get_profile') + while not self.client_profile_measure.wait_for_service(timeout_sec=1.0): + self.get_logger().info('profile measure service not available, waiting again...') + self.req_profile_measure = GocatorPTCloud.Request() + + # access to the printer driver service + + self.client_printer_driver = self.create_client(GcodeCommand, 'send_gcode') + while not self.client_printer_driver.wait_for_service(timeout_sec=1.0): + self.get_logger().info('profile measure service not available, waiting again...') + self.req_printer_driver = GcodeCommand.Request() + + self.imageNumber = 0 + self.scanNumber = 0 + + def loadGcode(self, gcodeFilename): + fileFullGcode = open(gcodeFilename) + rawGode = fileFullGcode.readlines() + fileFullGcode.close() + + (self.xMin, self.yMin, self.zMin, self.xMax, self.yMax, self.zMax) = getBordersGcode(rawGode) + self.get_logger().info('xMin : ' + str(self.xMin)) + self.get_logger().info('xMax : ' + str(self.xMax)) + self.get_logger().info('yMin : ' + str(self.yMin)) + self.get_logger().info('yMax : ' + str(self.yMax)) + self.get_logger().info('zMin : ' + str(self.zMin)) + self.get_logger().info('zMax : ' + str(self.zMax)) + + assert self.xMin >= printer3d_constant.XMIN + assert self.xMax <= printer3d_constant.XMAX + + assert self.yMin >= printer3d_constant.YMIN + assert self.yMax <= printer3d_constant.YMAX + + assert self.zMin >= printer3d_constant.ZMIN + assert self.zMax <= printer3d_constant.ZMAX + self.gcodeLayers = work_on_gcode_file(rawGode) + + return self.gcodeLayers + + def verifyGcodeBeforeSending(self, gcodeToVerify): + (self.xMin, self.yMin, self.zMin, self.xMax, self.yMax, self.zMax) = getBordersSimpleGcode(gcodeToVerify) + testXMin = self.xMin >= printer3d_constant.XMIN + testXMax = self.xMax <= printer3d_constant.XMAX + + testYMin = self.yMin >= printer3d_constant.YMIN + testYMax = self.yMax <= printer3d_constant.YMAX + + testZMin = self.zMin >= printer3d_constant.ZMIN + testZMax = self.zMax <= printer3d_constant.ZMAX + + if testXMin is False or testXMax is False or testYMin is False or testYMax is False or testZMin is False or testZMax is False: + return False + else: + return True + + def scanCurrentLayer(self, printedLayer): + (layerXMin, layerYMin, layerZMin, layerXMax, layerYMax, layerZMax) = getBordersSimpleGcode(printedLayer) + + gcodeScan = [[]] + margin = 25 + + Yinit = layerYMin - printer3d_constant.GAP + Yfinal = layerYMax - printer3d_constant.GAP + step = 0.3 + + gcodeScan[0].append('G1 Z' + str(layerZMax+1)+'\n') + gcodeScan[0].append('G28 X0 Y0\n') + gcodeScan[0].append('G1 Y' + str(Yinit-(margin/2)) + ' F1200\n') + length = int((Yfinal-Yinit+margin)/step) + + self.get_logger().info('scanning begin :') + self.get_logger().info('Yinit :' + str(Yinit)) + self.get_logger().info('Yfinal :' + str(Yfinal)) + self.get_logger().info('length :' + str(length)) + + for i in range(1, length): + gcodeScan.append([]) + gcodeScan[-1].append('G1 Y' + str(Yinit-(margin/2)+(i*step))+'\n') + surface = [] + for movements in gcodeScan: + self.sendGcodeSendingRequest(movements) + profileLine = self.sendProfileMeasureRequest() + surface.append(profileLine) + np.save('/home/gulltor/Ramsai_Robotics/history/'+self.historyFilename+'/scan/layer_scan_'+str(self.scanNumber)+'.npy', np.array(surface)) + self.scanNumber += 1 + return surface + + def printCurrentLayer(self): + return 0 + + def sendProfileMeasureRequest(self): + profile_line = [] + self.future_profile_measure = self.client_profile_measure.call_async(self.req_profile_measure) + while rclpy.ok(): + rclpy.spin_once(self) + if self.future_profile_measure.done(): + try: + self.response = self.future_profile_measure.result() + except Exception as e: + self.get_logger().info(f'Service call failed {e!r}') + else: + pcloud = self.response.pcloud + self.flag_datas_used = True + + gen = pc2.read_points(pcloud, skip_nans=True) + profile = list(gen) + + for points in profile: + profile_line.append([[points[0], 0, points[2]]]) + break + return profile_line + + def sendGcodeSendingRequest(self, gcode): + assert self.verifyGcodeBeforeSending(gcode) is True + + self.req_printer_driver.gcode_strings = gcode + self.future_printer_driver = self.client_printer_driver.call_async(self.req_printer_driver) + while rclpy.ok(): + rclpy.spin_once(self) + if self.future_printer_driver.done(): + break + +if __name__ == '__main__': + carriageReturn = ['G28\n'] + rclpy.init() + printer_control_node = PrinterControlNode('impression_base_50_pourcents') + printer_control_node.sendGcodeSendingRequest(carriageReturn) + gcode = printer_control_node.loadGcode('/home/gulltor/Ramsai_Robotics/Gcodes/piece_test_base.gcode') + for i in range(0, len(gcode)-1): + printer_control_node.get_logger.info('lancement de la couche '+str(i+1)+' sur '+str(len(gcode)-1)) + printer_control_node.sendGcodeSendingRequest(gcode[i]) + printer_control_node.get_logger.info('fin de la couche '+str(i+1)+' sur '+str(len(gcode))) + printer_control_node.scanCurrentLayer(gcode[i]) + + rclpy.shutdown() From 490e7abeed0fd6bbab81011d069540e82067c93a Mon Sep 17 00:00:00 2001 From: Mosser_Loic Date: Wed, 30 Aug 2023 15:21:35 +0200 Subject: [PATCH 19/30] add config YAML file to printer manager pkg --- .../launch_basic_print.cpython-310.pyc | Bin 594 -> 0 bytes .../src/printer3d_manager/CMakeLists.txt | 6 +++ .../src/printer3d_manager/config/params.yaml | 4 ++ .../src/printer3d_manager/launch/__init__.py | 0 .../launch_basic_print.cpython-310.pyc | Bin 0 -> 968 bytes .../launch/launch_basic_print.py | 15 ++++++- .../launch/launch_print_with_image_capture.py | 14 +++++- ...h_print_with_image_capture_plus_scanner.py | 15 ++++++- .../launch/launch_printer3d.py | 40 ------------------ .../nodes/printer_imageCapture_node.py | 27 +++++++----- .../printer3d_manager/nodes/printer_node.py | 27 +++++++----- .../printer_scanner_imageCapture_node.py | 31 ++++++++------ .../nodes/printer_scanner_node.py | 27 +++++++----- 13 files changed, 120 insertions(+), 86 deletions(-) delete mode 100644 3D_printer/launch/__pycache__/launch_basic_print.cpython-310.pyc create mode 100644 3D_printer/src/printer3d_manager/config/params.yaml delete mode 100644 3D_printer/src/printer3d_manager/launch/__init__.py create mode 100644 3D_printer/src/printer3d_manager/launch/__pycache__/launch_basic_print.cpython-310.pyc rename 3D_printer/{ => src/printer3d_manager}/launch/launch_basic_print.py (53%) rename 3D_printer/{ => src/printer3d_manager}/launch/launch_print_with_image_capture.py (62%) rename 3D_printer/{ => src/printer3d_manager}/launch/launch_print_with_image_capture_plus_scanner.py (68%) delete mode 100644 3D_printer/src/printer3d_manager/launch/launch_printer3d.py diff --git a/3D_printer/launch/__pycache__/launch_basic_print.cpython-310.pyc b/3D_printer/launch/__pycache__/launch_basic_print.cpython-310.pyc deleted file mode 100644 index bdd847ec1d0d7061824d6ceced14b37cb8c7b0d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 594 zcmZWmJx{|h5Vc)5{ZLCkpc9NNS-P+ygajk%!qz2neO8D_?8r$GbcK~4!e8>r#Ka8h zz&TAnBrfvPz3212)5Y}rU4jvkZ#ZUze0p*isF7#( zH!|nYyeDDsg_R_vZgeM>T0Y#WLfRxR6Qfb&GXqNcio<9lxxrJpl%%9Uf%&e`eCNml zXh9n~p2h5yqDyz?hPh32sq6(rV3Q|h-AS!Pu|$`sP#Tn7O*SkuIw_5fG+s^f7dQSd zhupPtAs7>!6HEA_T z$gE$nZ6JIQd*pKuzmv4uUbGNJBBQFgpZYXbT3J!5sJ@5&dO5x;&JY;ge|*h?E#vFp z#}2Vz7B*e5X;9g_aox?DVk)HnS4A~aRlT2TlMS$gYhPvtmZ`d;-Zenzksj@_Kj*!n A6#xJL diff --git a/3D_printer/src/printer3d_manager/CMakeLists.txt b/3D_printer/src/printer3d_manager/CMakeLists.txt index a2e0bfc..b7ca69d 100644 --- a/3D_printer/src/printer3d_manager/CMakeLists.txt +++ b/3D_printer/src/printer3d_manager/CMakeLists.txt @@ -55,4 +55,10 @@ install(DIRECTORY DESTINATION share/${PROJECT_NAME}/ ) +# Install YAML config files. +install(DIRECTORY + config + DESTINATION share/${PROJECT_NAME}/ +) + ament_package() diff --git a/3D_printer/src/printer3d_manager/config/params.yaml b/3D_printer/src/printer3d_manager/config/params.yaml new file mode 100644 index 0000000..14ccafd --- /dev/null +++ b/3D_printer/src/printer3d_manager/config/params.yaml @@ -0,0 +1,4 @@ +printer3d_manager: + ros__parameters: + history_file_dir: "'/home/gulltor/printing_history'" + gcode_file_dir: "/home/gulltor/gcodeSample/test.gcode" \ No newline at end of file diff --git a/3D_printer/src/printer3d_manager/launch/__init__.py b/3D_printer/src/printer3d_manager/launch/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/3D_printer/src/printer3d_manager/launch/__pycache__/launch_basic_print.cpython-310.pyc b/3D_printer/src/printer3d_manager/launch/__pycache__/launch_basic_print.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c03e3dda4369608aebbf4da896afbfe7b8db8ab GIT binary patch literal 968 zcmZWnOK%e~5VpPEN4A@m6e>}*a7DR902R=3t|I~ z7nlRbs+J(xGm??|A&FGPVRgyw83(1y#e!X!q{AV5ki*SSq z5dD)x8A)-9_x}>=ElZ-mNwk(TOn*f`^nLiP-*M40Yg?q-UOfT83|QfJ+O&ncJ%C8s zyo3>+=FQZOl^m>QV_FFGZAho@dgc?i9o=B}z~+)Cwc?XXJj0+Fk8*}GoZ$p0BmV$p Cv Date: Wed, 30 Aug 2023 17:20:08 +0200 Subject: [PATCH 20/30] adding a point processing package --- .../CMakeLists.txt | 45 ++++++++++++++++ .../nodes/__init__.py | 0 .../nodes/point_cloud_processing_node.py | 54 +++++++++++++++++++ .../package.xml | 18 +++++++ 4 files changed, 117 insertions(+) create mode 100755 3D_printer/src/printer3d_pointCloud_processing/CMakeLists.txt create mode 100755 3D_printer/src/printer3d_pointCloud_processing/nodes/__init__.py create mode 100755 3D_printer/src/printer3d_pointCloud_processing/nodes/point_cloud_processing_node.py create mode 100755 3D_printer/src/printer3d_pointCloud_processing/package.xml diff --git a/3D_printer/src/printer3d_pointCloud_processing/CMakeLists.txt b/3D_printer/src/printer3d_pointCloud_processing/CMakeLists.txt new file mode 100755 index 0000000..2285557 --- /dev/null +++ b/3D_printer/src/printer3d_pointCloud_processing/CMakeLists.txt @@ -0,0 +1,45 @@ +cmake_minimum_required(VERSION 3.5) +project(printer3d_point_cloud_processing) + +# Default to C99 +if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 99) +endif() + +# Default to C++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# find dependencies +find_package(ament_cmake REQUIRED) +find_package(rclcpp REQUIRED) +find_package(std_msgs REQUIRED) + +# Install the python module for this package +# ament_python_install_package(nodes/) + +if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + # the following line skips the linter which checks for copyrights + # uncomment the line when a copyright and license is not present in all source files + #set(ament_cmake_copyright_FOUND TRUE) + # the following line skips cpplint (only works in a git repo) + # uncomment the line when this package is not in a git repo + #set(ament_cmake_cpplint_FOUND TRUE) + ament_lint_auto_find_test_dependencies() +endif() + +# Install python scripts + +install( + PROGRAMS + nodes/point_cloud_processing_node.py + DESTINATION lib/${PROJECT_NAME} +) + +ament_package() diff --git a/3D_printer/src/printer3d_pointCloud_processing/nodes/__init__.py b/3D_printer/src/printer3d_pointCloud_processing/nodes/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/3D_printer/src/printer3d_pointCloud_processing/nodes/point_cloud_processing_node.py b/3D_printer/src/printer3d_pointCloud_processing/nodes/point_cloud_processing_node.py new file mode 100755 index 0000000..fec0dcc --- /dev/null +++ b/3D_printer/src/printer3d_pointCloud_processing/nodes/point_cloud_processing_node.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +# Copyright 2023 ICube Laboratory, University of Strasbourg +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import rclpy +from rclpy.node import Node +from printer3d_msgs.srv import GcodeCommand +import numpy as np +import pyvista as pv +import matplotlib.pyplot as plt +import matplotlib + +matplotlib.use('GTK3agg',force=True) + + + +class PointCloudProcessingNode(Node): + def __init__(self): + """PointCloudProcessingNode class constructor.""" + super().__init__('point_cloud_processing_node') + + def load_scan(self,fileName): + data = np.squeeze(np.load(fileName)) + print(type(data)) + print(data.shape) + data = np.squeeze(data) + plt.figure() + plt.plot(data[0][:][2]) + plt.show() + print(data.shape) + return 0 + + def extract_reference_base_change(self): + return 0 + + + +if __name__ == '__main__': + rclpy.init() + print(plt.get_backend()) + point_cloud_processing_node = PointCloudProcessingNode() + scan = point_cloud_processing_node.load_scan("/home/gulltor/impression_base_avec_retraction_20_pourcents/scan/layer_scan_0.npy") + rclpy.shutdown() diff --git a/3D_printer/src/printer3d_pointCloud_processing/package.xml b/3D_printer/src/printer3d_pointCloud_processing/package.xml new file mode 100755 index 0000000..5d20ba4 --- /dev/null +++ b/3D_printer/src/printer3d_pointCloud_processing/package.xml @@ -0,0 +1,18 @@ + + + + printer3d_point_cloud_processing + 0.0.0 + TODO: Package description + gulltor + TODO: License declaration + + ament_cmake + + ament_lint_auto + ament_lint_common + + + ament_cmake + + From f211c11d08b8d4453dd6713fd6e012e14af8712a Mon Sep 17 00:00:00 2001 From: Mosserl Date: Tue, 5 Sep 2023 15:04:37 +0200 Subject: [PATCH 21/30] Point processing package dev on 5 of September --- .../src/printer3d_manager/config/params.yaml | 4 +- .../launch_basic_print.cpython-310.pyc | Bin 968 -> 941 bytes .../src/printer3d_manager/nodes/utility.py | 3 + .../CMakeLists.txt | 10 ++ .../config/params.yaml | 4 + .../nodes/point_cloud_processing_node.py | 108 ++++++++++++++++-- 6 files changed, 116 insertions(+), 13 deletions(-) create mode 100644 3D_printer/src/printer3d_pointCloud_processing/config/params.yaml diff --git a/3D_printer/src/printer3d_manager/config/params.yaml b/3D_printer/src/printer3d_manager/config/params.yaml index 14ccafd..c29ef49 100644 --- a/3D_printer/src/printer3d_manager/config/params.yaml +++ b/3D_printer/src/printer3d_manager/config/params.yaml @@ -1,4 +1,4 @@ printer3d_manager: ros__parameters: - history_file_dir: "'/home/gulltor/printing_history'" - gcode_file_dir: "/home/gulltor/gcodeSample/test.gcode" \ No newline at end of file + history_file_dir: "/home/gulltor/Ramsai_Robotics/history/test_printing_history" + gcode_file_dir: "/home/gulltor/Ramsai_Robotics/Gcodes/piece_test_base.gcode" \ No newline at end of file diff --git a/3D_printer/src/printer3d_manager/launch/__pycache__/launch_basic_print.cpython-310.pyc b/3D_printer/src/printer3d_manager/launch/__pycache__/launch_basic_print.cpython-310.pyc index 9c03e3dda4369608aebbf4da896afbfe7b8db8ab..b9c3feb3a08e37f149f43cffd499cb99ad1a8cd5 100644 GIT binary patch delta 178 zcmX@XzLuRgpO=@50SFd4d`Ou(k#|31#l*AHPAM$SO#QsIj3ulK*lHLTGS)JMGo&!E z0AVvTBSRjCAw#izIU^$j2u1>N33~}g3Tp~m3VRAi3TH1%3CCtDMq@@s&dGU9Vw1a> zEE%OIA7!!;(*xSX#>mFV1cWSqdDwUuW&SfUPnKquWt5$4$s8;t4pdMi3nHXZ37N^u Gn3Vvzts?&b delta 204 zcmZ3>euAAhpO=@50SFRp->2-F$h)7hW8zuqpk_u!h7#5qh7^`&rhdU%#uBy#>@|!F z8EctJSZbI+vf&IV3@kv{%*@D;$6?4&tX>Wj1;I!lF5xKQOkqu7OJPspNa5^dDdF6# z#c0gP$Tc~RNsNuPpeQr1WO6Z+6{F1Lbxbx=MnDI!F|si-0U^s@4mKVpE=Dd!nSV?y dlbB^0self.filter_coordinates[0][0] and treatedPointCloud[i,0]self.filter_coordinates[0][1] and treatedPointCloud[i,1]-10000: + outputPointCloud.append(inputPointCloud[i,:]) + return np.array(outputPointCloud) + + def plot_point_cloud(self,inputPointCloud): + data = self.remove_inf_value(inputPointCloud) + data = self.decimate_point_cloud(data, 0.95) + x = data[:,0] + y = data[:,1] + z = data[:,2] + + fig = plt.figure(figsize=(8, 8)) + ax = fig.add_subplot(111, projection='3d',aspect='auto') + im = ax.scatter(x, y, z, c=z) + plt.xlabel('x (mm)') + plt.ylabel('y (mm)') + fig.colorbar(im) + ax.set_xlim(min([min(x), min(y), min(z)]), max([max(x), max(y), max(z)])) + ax.set_ylim(min([min(x), min(y), min(z)]), max([max(x), max(y), max(z)])) + ax.set_zlim(min([min(x), min(y), min(z)]), max([max(x), max(y), max(z)])) + plt.show() return 0 + def ask_for_limits(self,inputPointCloud): + data = self.remove_inf_value(inputPointCloud) + data = self.decimate_point_cloud(data, 0.95) + x = data[:,0] + y = data[:,1] + z = data[:,2] + fig = plt.figure(figsize=(8, 8)) + ax = fig.add_subplot(111,aspect='equal') + im = ax.scatter(x, y, c=z,s=1) + plt.xlabel('x (mm)') + plt.ylabel('y (mm)') + fig.colorbar(im) + ax.set_xlim(min(x)-10, max(x)+10) + ax.set_ylim(min(y)-10, max(y)+10) + cid = fig.canvas.mpl_connect('button_press_event', onclick) + plt.show() + global coords + self.filter_coordinates = coords + coords = [] + return 0 + def extract_reference_base_change(self): + return 0 if __name__ == '__main__': rclpy.init() - print(plt.get_backend()) point_cloud_processing_node = PointCloudProcessingNode() - scan = point_cloud_processing_node.load_scan("/home/gulltor/impression_base_avec_retraction_20_pourcents/scan/layer_scan_0.npy") + scan = point_cloud_processing_node.load_scan("/home/gulltor/Ramsai_Robotics/history/impression_base_avec_retraction_20_pourcents/scan/layer_scan_4.npy") + point_cloud_processing_node.ask_for_limits(scan) + filtered_scan = point_cloud_processing_node.filter_point_cloud(scan) rclpy.shutdown() From d1325c051528d1e6de4a19dbfe023afc63848e94 Mon Sep 17 00:00:00 2001 From: MosserLoic Date: Tue, 5 Sep 2023 17:19:51 +0200 Subject: [PATCH 22/30] correction of namespace error + beggining of retraction implementation --- .../src/printer3d_manager/config/params.yaml | 2 +- .../launch_basic_print.cpython-310.pyc | Bin 941 -> 949 bytes .../launch_print_with_scan.cpython-310.pyc | Bin 0 -> 1051 bytes .../launch/launch_basic_print.py | 4 +- .../launch/launch_print_with_image_capture.py | 6 +-- ...h_print_with_image_capture_plus_scanner.py | 8 ++-- .../launch/launch_print_with_scan.py | 38 ++++++++++++++++ .../nodes/printer_imageCapture_node.py | 21 ++++++++- .../printer3d_manager/nodes/printer_node.py | 26 +++++++++-- .../printer_scanner_imageCapture_node.py | 25 ++++++++-- .../nodes/printer_scanner_node.py | 43 +++++++++++++----- .../src/printer3d_manager/nodes/utility.py | 27 ++++++++++- 12 files changed, 170 insertions(+), 30 deletions(-) create mode 100644 3D_printer/src/printer3d_manager/launch/__pycache__/launch_print_with_scan.cpython-310.pyc create mode 100644 3D_printer/src/printer3d_manager/launch/launch_print_with_scan.py diff --git a/3D_printer/src/printer3d_manager/config/params.yaml b/3D_printer/src/printer3d_manager/config/params.yaml index c29ef49..0996137 100644 --- a/3D_printer/src/printer3d_manager/config/params.yaml +++ b/3D_printer/src/printer3d_manager/config/params.yaml @@ -1,4 +1,4 @@ printer3d_manager: ros__parameters: history_file_dir: "/home/gulltor/Ramsai_Robotics/history/test_printing_history" - gcode_file_dir: "/home/gulltor/Ramsai_Robotics/Gcodes/piece_test_base.gcode" \ No newline at end of file + gcode_file_dir: "/home/gulltor/Ramsai_Robotics/Gcodes/test_gcode.gcode" \ No newline at end of file diff --git a/3D_printer/src/printer3d_manager/launch/__pycache__/launch_basic_print.cpython-310.pyc b/3D_printer/src/printer3d_manager/launch/__pycache__/launch_basic_print.cpython-310.pyc index b9c3feb3a08e37f149f43cffd499cb99ad1a8cd5..bfca343888b05562a8939171ad72a256a52c300b 100644 GIT binary patch delta 164 zcmZ3>zLlLfpO=@50SJnnzNbvu$g998%a+2G!d=6Z!YIj*!XwF$&X~g6%bL#A%oxm| z$v4@H(OyuXpeQr1Br`8PzMv>SIkmWW@;t`i$xKYEm8F0t{W2;pO4bJ}Ni8x?iO)^U uOH5BK($7gO%}dVEpS+nVi&18>9J8Oi5KwiI7>JMo5g^S-g!JTYW+edh(kbBp delta 157 zcmdnWzLuRgpO=@50SFd4d`OwPkyn9HmMeujg{Ouog;A0rg;$axoiT;4mo=TKnK76_ zlYg=oqrIp|K~ZL2NorAidUAeBYJ72OUP@}wE=H6g0qY>jj(2 zbn;x7ROgk=l>{d}R9wJwHxo9gSo(%#A~6%DMZ$9}QmgdrF!d3xR{#fJ|1;R;Jt&Kg z@g=bV#|z8}53Yi9Wa$~yvLGLN=h(I`!!vw^&&ex5KtUEzzidB1X72=0c{ze@Bir_s z^N6>3=YoRO1#6ARjfKJL@%1ypaUb!GKFToPyl7>?0t3#iL$_7wTw0+Y@}y)EkZ2dC zN{;hvzE&~KN;90XvT#_t&DB+|^S5ww>B(i5R9dCNnE6hY0y#;kWDYbW5{zLrbKC#A z2h>Fkd9EW_DGXS`b;YSjrt%|x@x1p6upsfI1054|H(reH$9edUDY8{m8-nh|mL>Wgb zW+#pwt6XXrQRJwqgmko~uVdI)B!yyJ`%%??A_jpD{XIN(-6iEm!1PC??}7LGBcs#( z74)V#`$avF%>!tM<|QY&oz&<&)i9L+l3B=BUrqRGcq0gG9)k*ThzSV&6^Ajt`TMUZZi_O)8*n$Ws5Cm>Qwm1rnjaTyk-mR5LqKa@aK8 o)FkO02&emA`M@>w8|pszT>D9>__PoQ7%b!a5Th8!xD67MKb-F>`v3p{ literal 0 HcmV?d00001 diff --git a/3D_printer/src/printer3d_manager/launch/launch_basic_print.py b/3D_printer/src/printer3d_manager/launch/launch_basic_print.py index b110f78..c878822 100644 --- a/3D_printer/src/printer3d_manager/launch/launch_basic_print.py +++ b/3D_printer/src/printer3d_manager/launch/launch_basic_print.py @@ -17,13 +17,13 @@ def generate_launch_description(): return LaunchDescription([ Node( package='printer3d_driver', - namespace='printer_gcode_sender', + namespace='printing_process', executable='gcode_monitor_node.py', name='gcode_monitor_node' ), Node( package='printer3d_manager', - namespace='printer_manager', + namespace='printing_process', executable='printer_node.py', name='printer_control_node', parameters = [configYaml['printer3d_manager']['ros__parameters']] diff --git a/3D_printer/src/printer3d_manager/launch/launch_print_with_image_capture.py b/3D_printer/src/printer3d_manager/launch/launch_print_with_image_capture.py index 080b708..0c43205 100644 --- a/3D_printer/src/printer3d_manager/launch/launch_print_with_image_capture.py +++ b/3D_printer/src/printer3d_manager/launch/launch_print_with_image_capture.py @@ -16,19 +16,19 @@ def generate_launch_description(): return LaunchDescription([ Node( package='printer3d_driver', - namespace='printer_gcode_sender', + namespace='printing_process', executable='gcode_monitor_node.py', name='gcode_monitor_node' ), Node( package='printer3d_image_capture', - namespace='printer_image_capture', + namespace='printing_process', executable='image_capture_node.py', name='image_capture_node' ), Node( package='printer3d_manager', - namespace='printer_manager', + namespace='printing_process', executable='printer_imageCapture_node.py', name='printer_control_node', parameters = [configYaml['printer3d_manager']['ros__parameters']] diff --git a/3D_printer/src/printer3d_manager/launch/launch_print_with_image_capture_plus_scanner.py b/3D_printer/src/printer3d_manager/launch/launch_print_with_image_capture_plus_scanner.py index d654abb..42605c8 100644 --- a/3D_printer/src/printer3d_manager/launch/launch_print_with_image_capture_plus_scanner.py +++ b/3D_printer/src/printer3d_manager/launch/launch_print_with_image_capture_plus_scanner.py @@ -17,25 +17,25 @@ def generate_launch_description(): return LaunchDescription([ Node( package='printer3d_driver', - namespace='printer_gcode_sender', + namespace='printing_process', executable='gcode_monitor_node.py', name='gcode_monitor_node' ), Node( package='printer3d_image_capture', - namespace='printer_image_capture', + namespace='printing_process', executable='image_capture_node.py', name='image_capture_node' ), Node( package='printer3d_profile_capture', - namespace='printer_gocator_communication', + namespace='printing_process', executable='gocator_sensor_node.py', name='gocator_sensor_node' ), Node( package='printer3d_manager', - namespace='printer_manager', + namespace='printing_process', executable='printer_scanner_imageCapture_node.py', name='printer_control_node', parameters = [configYaml['printer3d_manager']['ros__parameters']] diff --git a/3D_printer/src/printer3d_manager/launch/launch_print_with_scan.py b/3D_printer/src/printer3d_manager/launch/launch_print_with_scan.py new file mode 100644 index 0000000..f78ab25 --- /dev/null +++ b/3D_printer/src/printer3d_manager/launch/launch_print_with_scan.py @@ -0,0 +1,38 @@ +from launch import LaunchDescription +from launch_ros.actions import Node +from ament_index_python.packages import get_package_share_directory +import os +import yaml + +def generate_launch_description(): + config = os.path.join( + get_package_share_directory('printer3d_manager'), + 'config', + 'params.yaml' + ) + + with open(config, 'r') as f: + configYaml = yaml.safe_load(f) + return LaunchDescription([ + Node( + package='printer3d_driver', + namespace='printing_process', + executable='gcode_monitor_node.py', + name='gcode_monitor_node' + ), + Node( + package='printer3d_profile_capture', + namespace='printing_process', + executable='gocator_sensor_node', + name='gocator_sensor' + ), + Node( + package='printer3d_manager', + namespace='printing_process', + executable='printer_scanner_node.py', + name='printer_control_node', + parameters = [configYaml['printer3d_manager']['ros__parameters']] + ) + ]) + + \ No newline at end of file diff --git a/3D_printer/src/printer3d_manager/nodes/printer_imageCapture_node.py b/3D_printer/src/printer3d_manager/nodes/printer_imageCapture_node.py index 625500f..ac8fe07 100644 --- a/3D_printer/src/printer3d_manager/nodes/printer_imageCapture_node.py +++ b/3D_printer/src/printer3d_manager/nodes/printer_imageCapture_node.py @@ -17,7 +17,7 @@ from rclpy.node import Node from printer3d_msgs.srv import GcodeCommand from printer3d_msgs.srv import ImageCommand -from utility import getBordersSimpleGcode, getBordersGcode, work_on_gcode_file +from utility import getBordersSimpleGcode, getBordersGcode, work_on_gcode_file, follow_gcode_coordinates import printer3d_constant import os import numpy as np @@ -73,6 +73,11 @@ def __init__(self): self.imageNumber = 0 self.scanNumber = 0 + self.last_x_value = 0 + self.last_y_value = 0 + self.last_z_value = 0 + self.last_e_value = 0 + def loadGcode(self, gcodeFilename): fileFullGcode = open(self.gcodeFileDir) rawGode = fileFullGcode.readlines() @@ -132,10 +137,24 @@ def sendImageCaptureRequest(self, filename): if self.future_image_capture.done(): self.get_logger().info('capture finished') break + + def printLastPositions(self): + self.get_logger().info("Last Position : ("+str(self.last_x_value)+", "+str(self.last_y_value)+", "+str(self.last_z_value)+", "+str(self.last_e_value)+")\n") + return 0 def sendGcodeSendingRequest(self, gcode): assert self.verifyGcodeBeforeSending(gcode) is True + (changed_x,changed_y,changed_z,changed_e) = follow_gcode_coordinates(gcode) + if changed_x != None: + self.last_x_value = changed_x + if changed_y != None: + self.last_y_value = changed_y + if changed_z != None: + self.last_z_value = changed_z + if changed_e != None: + self.last_e_value = changed_e + self.req_printer_driver.gcode_strings = gcode self.future_printer_driver = self.client_printer_driver.call_async(self.req_printer_driver) while rclpy.ok(): diff --git a/3D_printer/src/printer3d_manager/nodes/printer_node.py b/3D_printer/src/printer3d_manager/nodes/printer_node.py index a75537f..7363393 100644 --- a/3D_printer/src/printer3d_manager/nodes/printer_node.py +++ b/3D_printer/src/printer3d_manager/nodes/printer_node.py @@ -16,7 +16,7 @@ import rclpy from rclpy.node import Node from printer3d_msgs.srv import GcodeCommand -from utility import getBordersSimpleGcode, getBordersGcode, work_on_gcode_file +from utility import getBordersSimpleGcode, getBordersGcode, work_on_gcode_file, follow_gcode_coordinates import printer3d_constant import os import numpy as np @@ -63,6 +63,11 @@ def __init__(self): self.imageNumber = 0 self.scanNumber = 0 + self.last_x_value = 0 + self.last_y_value = 0 + self.last_z_value = 0 + self.last_e_value = 0 + def loadGcode(self): fileFullGcode = open(self.gcodeFileDir) rawGode = fileFullGcode.readlines() @@ -108,9 +113,23 @@ def verifyGcodeBeforeSending(self, gcodeToVerify): def printCurrentLayer(self): return 0 + def printLastPositions(self): + self.get_logger().info("Last Position : ("+str(self.last_x_value)+", "+str(self.last_y_value)+", "+str(self.last_z_value)+", "+str(self.last_e_value)+")\n") + return 0 + def sendGcodeSendingRequest(self, gcode): assert self.verifyGcodeBeforeSending(gcode) is True + (changed_x,changed_y,changed_z,changed_e) = follow_gcode_coordinates(gcode) + if changed_x != None: + self.last_x_value = changed_x + if changed_y != None: + self.last_y_value = changed_y + if changed_z != None: + self.last_z_value = changed_z + if changed_e != None: + self.last_e_value = changed_e + self.req_printer_driver.gcode_strings = gcode self.future_printer_driver = self.client_printer_driver.call_async(self.req_printer_driver) while rclpy.ok(): @@ -125,8 +144,9 @@ def sendGcodeSendingRequest(self, gcode): printer_control_node.sendGcodeSendingRequest(carriageReturn) gcode = printer_control_node.loadGcode() for i in range(0, len(gcode)-1): - printer_control_node.get_logger.info('lancement de la couche '+str(i+1)+' sur '+str(len(gcode)-1)) + printer_control_node.get_logger().info('lancement de la couche '+str(i+1)+' sur '+str(len(gcode)-1)) printer_control_node.sendGcodeSendingRequest(gcode[i]) - printer_control_node.get_logger.info('fin de la couche '+str(i+1)+' sur '+str(len(gcode))) + printer_control_node.printLastPositions() + printer_control_node.get_logger().info('fin de la couche '+str(i+1)+' sur '+str(len(gcode))) rclpy.shutdown() diff --git a/3D_printer/src/printer3d_manager/nodes/printer_scanner_imageCapture_node.py b/3D_printer/src/printer3d_manager/nodes/printer_scanner_imageCapture_node.py index ead8c13..0612d68 100644 --- a/3D_printer/src/printer3d_manager/nodes/printer_scanner_imageCapture_node.py +++ b/3D_printer/src/printer3d_manager/nodes/printer_scanner_imageCapture_node.py @@ -18,7 +18,7 @@ from printer3d_msgs.srv import GcodeCommand from printer3d_msgs.srv import ImageCommand from printer3d_gocator_msgs.srv import GocatorPTCloud -from utility import getBordersSimpleGcode, getBordersGcode, work_on_gcode_file +from utility import getBordersSimpleGcode, getBordersGcode, work_on_gcode_file, follow_gcode_coordinates import printer3d_constant import point_cloud2 as pc2 import os @@ -82,6 +82,11 @@ def __init__(self): self.imageNumber = 0 self.scanNumber = 0 + self.last_x_value = 0 + self.last_y_value = 0 + self.last_z_value = 0 + self.last_e_value = 0 + def loadGcode(self): fileFullGcode = open(self.gcodeFileDir) rawGode = fileFullGcode.readlines() @@ -196,9 +201,23 @@ def sendProfileMeasureRequest(self): break return profile_line + def printLastPositions(self): + self.get_logger().info("Last Position : ("+str(self.last_x_value)+", "+str(self.last_y_value)+", "+str(self.last_z_value)+", "+str(self.last_e_value)+")\n") + return 0 + def sendGcodeSendingRequest(self, gcode): assert self.verifyGcodeBeforeSending(gcode) is True + (changed_x,changed_y,changed_z,changed_e) = follow_gcode_coordinates(gcode) + if changed_x != None: + self.last_x_value = changed_x + if changed_y != None: + self.last_y_value = changed_y + if changed_z != None: + self.last_z_value = changed_z + if changed_e != None: + self.last_e_value = changed_e + self.req_printer_driver.gcode_strings = gcode self.future_printer_driver = self.client_printer_driver.call_async(self.req_printer_driver) while rclpy.ok(): @@ -213,9 +232,9 @@ def sendGcodeSendingRequest(self, gcode): printer_control_node.sendGcodeSendingRequest(carriageReturn) gcode = printer_control_node.loadGcode() for i in range(0, len(gcode)-1): - printer_control_node.get_logger.info('lancement de la couche '+str(i+1)+' sur '+str(len(gcode)-1)) + printer_control_node.get_logger().info('lancement de la couche '+str(i+1)+' sur '+str(len(gcode)-1)) printer_control_node.sendGcodeSendingRequest(gcode[i]) - printer_control_node.get_logger.info('fin de la couche '+str(i+1)+' sur '+str(len(gcode))) + printer_control_node.get_logger().info('fin de la couche '+str(i+1)+' sur '+str(len(gcode))) printer_control_node.takeCurrentLayerPhoto() printer_control_node.scanCurrentLayer(gcode[i]) diff --git a/3D_printer/src/printer3d_manager/nodes/printer_scanner_node.py b/3D_printer/src/printer3d_manager/nodes/printer_scanner_node.py index fbfd4de..0474361 100644 --- a/3D_printer/src/printer3d_manager/nodes/printer_scanner_node.py +++ b/3D_printer/src/printer3d_manager/nodes/printer_scanner_node.py @@ -17,7 +17,7 @@ from rclpy.node import Node from printer3d_msgs.srv import GcodeCommand from printer3d_gocator_msgs.srv import GocatorPTCloud -from utility import getBordersSimpleGcode, getBordersGcode, work_on_gcode_file +from utility import getBordersSimpleGcode, getBordersGcode, work_on_gcode_file, follow_gcode_coordinates import printer3d_constant import point_cloud2 as pc2 import os @@ -57,13 +57,6 @@ def __init__(self): except Exception: pass - # access to the profile measure service - - self.client_profile_measure = self.create_client(GocatorPTCloud, 'gocator_get_profile') - while not self.client_profile_measure.wait_for_service(timeout_sec=1.0): - self.get_logger().info('profile measure service not available, waiting again...') - self.req_profile_measure = GocatorPTCloud.Request() - # access to the printer driver service self.client_printer_driver = self.create_client(GcodeCommand, 'send_gcode') @@ -71,14 +64,25 @@ def __init__(self): self.get_logger().info('profile measure service not available, waiting again...') self.req_printer_driver = GcodeCommand.Request() + # access to the profile measure service + + self.client_profile_measure = self.create_client(GocatorPTCloud, 'gocator_get_profile') + while not self.client_profile_measure.wait_for_service(timeout_sec=1.0): + self.get_logger().info('profile measure service not available, waiting again...') + self.req_profile_measure = GocatorPTCloud.Request() + self.imageNumber = 0 self.scanNumber = 0 - def loadGcode(self, gcodeFilename): + self.last_x_value = 0 + self.last_y_value = 0 + self.last_z_value = 0 + self.last_e_value = 0 + + def loadGcode(self): fileFullGcode = open(self.gcodeFileDir) rawGode = fileFullGcode.readlines() fileFullGcode.close() - (self.xMin, self.yMin, self.zMin, self.xMax, self.yMax, self.zMax) = getBordersGcode(rawGode) self.get_logger().info('xMin : ' + str(self.xMin)) self.get_logger().info('xMax : ' + str(self.xMax)) @@ -172,9 +176,23 @@ def sendProfileMeasureRequest(self): break return profile_line + def printLastPositions(self): + self.get_logger().info("Last Position : ("+str(self.last_x_value)+", "+str(self.last_y_value)+", "+str(self.last_z_value)+", "+str(self.last_e_value)+")\n") + return 0 + def sendGcodeSendingRequest(self, gcode): assert self.verifyGcodeBeforeSending(gcode) is True + (changed_x,changed_y,changed_z,changed_e) = follow_gcode_coordinates(gcode) + if changed_x != None: + self.last_x_value = changed_x + if changed_y != None: + self.last_y_value = changed_y + if changed_z != None: + self.last_z_value = changed_z + if changed_e != None: + self.last_e_value = changed_e + self.req_printer_driver.gcode_strings = gcode self.future_printer_driver = self.client_printer_driver.call_async(self.req_printer_driver) while rclpy.ok(): @@ -189,9 +207,10 @@ def sendGcodeSendingRequest(self, gcode): printer_control_node.sendGcodeSendingRequest(carriageReturn) gcode = printer_control_node.loadGcode() for i in range(0, len(gcode)-1): - printer_control_node.get_logger.info('lancement de la couche '+str(i+1)+' sur '+str(len(gcode)-1)) + printer_control_node.get_logger().info('lancement de la couche '+str(i+1)+' sur '+str(len(gcode)-1)) printer_control_node.sendGcodeSendingRequest(gcode[i]) - printer_control_node.get_logger.info('fin de la couche '+str(i+1)+' sur '+str(len(gcode))) + printer_control_node.printLastPositions() + printer_control_node.get_logger().info('fin de la couche '+str(i+1)+' sur '+str(len(gcode))) printer_control_node.scanCurrentLayer(gcode[i]) rclpy.shutdown() diff --git a/3D_printer/src/printer3d_manager/nodes/utility.py b/3D_printer/src/printer3d_manager/nodes/utility.py index 9437039..ad63631 100644 --- a/3D_printer/src/printer3d_manager/nodes/utility.py +++ b/3D_printer/src/printer3d_manager/nodes/utility.py @@ -114,4 +114,29 @@ def getBordersSimpleGcode(simpleGcode): return (xMin, yMin, zMin, xMax, yMax, zMax) def follow_gcode_coordinates(gcodeLines): - return 0 \ No newline at end of file + lastX = None + lastY = None + lastZ = None + lastE = None + for line in gcodeLines: + if 'X' in line: + splittedLine = line.split(' ') + for elements in splittedLine: + if elements[0] == 'X': + lastX = float(elements[1:]) + if 'Y' in line: + splittedLine = line.split(' ') + for elements in splittedLine: + if elements[0] == 'Y': + lastY = float(elements[1:]) + if 'Z' in line: + splittedLine = line.split(' ') + for elements in splittedLine: + if elements[0] == 'Z': + lastZ = float(elements[1:]) + if 'E' in line: + splittedLine = line.split(' ') + for elements in splittedLine: + if elements[0] == 'E': + lastE = float(elements[1:]) + return (lastX,lastY,lastZ,lastE) \ No newline at end of file From d1532bf78ded38fd7de68d6e841c932e319398d1 Mon Sep 17 00:00:00 2001 From: MosserLoic Date: Wed, 6 Sep 2023 15:53:50 +0200 Subject: [PATCH 23/30] successfully integrated retraction of filament before scanning and image capture --- .../nodes/gcode_monitor_node.py | 4 +- .../src/printer3d_manager/config/params.yaml | 4 +- .../launch_print_with_scan.cpython-310.pyc | Bin 1051 -> 1053 bytes .../nodes/printer3d_constant.py | 1 + .../printer3d_manager/nodes/printer_node.py | 2 +- .../printer_scanner_imageCapture_node.py | 76 +++++++++++------- .../nodes/printer_scanner_node.py | 44 ++++++---- .../src/nodes/gocatorSensorNode.cpp | 2 +- 8 files changed, 83 insertions(+), 50 deletions(-) diff --git a/3D_printer/src/printer3d_driver/nodes/gcode_monitor_node.py b/3D_printer/src/printer3d_driver/nodes/gcode_monitor_node.py index aa06713..95ff83d 100644 --- a/3D_printer/src/printer3d_driver/nodes/gcode_monitor_node.py +++ b/3D_printer/src/printer3d_driver/nodes/gcode_monitor_node.py @@ -91,7 +91,7 @@ def execute_gcode_sending(self, request, response): """ gcode = request.gcode_strings - self.get_logger().info('Executing Gcode') + # self.get_logger().info('Executing Gcode') feedback = 0.0 self.serialPort.flushInput() self.i = 0 @@ -133,7 +133,7 @@ def execute_gcode_sending(self, request, response): grbl_out = self.serialPort.readline() # wait for response from printer grbl_out = grbl_out.strip().decode('ascii') - self.get_logger().info('gcode sending completely finished') + # self.get_logger().info('gcode sending completely finished') response.validation = True return response diff --git a/3D_printer/src/printer3d_manager/config/params.yaml b/3D_printer/src/printer3d_manager/config/params.yaml index 0996137..2247748 100644 --- a/3D_printer/src/printer3d_manager/config/params.yaml +++ b/3D_printer/src/printer3d_manager/config/params.yaml @@ -1,4 +1,4 @@ printer3d_manager: ros__parameters: - history_file_dir: "/home/gulltor/Ramsai_Robotics/history/test_printing_history" - gcode_file_dir: "/home/gulltor/Ramsai_Robotics/Gcodes/test_gcode.gcode" \ No newline at end of file + history_file_dir: "/home/gulltor/Ramsai_Robotics/history/test_retraction" + gcode_file_dir: "/home/gulltor/Ramsai_Robotics/Gcodes/impression_piece_ecroulement.gcode" \ No newline at end of file diff --git a/3D_printer/src/printer3d_manager/launch/__pycache__/launch_print_with_scan.cpython-310.pyc b/3D_printer/src/printer3d_manager/launch/__pycache__/launch_print_with_scan.cpython-310.pyc index 137c0d86eb5dc2d803144483053adce70693c052..5d8b2ab2d2ae1797a090a40af550bca5cbdcc466 100644 GIT binary patch delta 28 icmbQuF_(iYpO=@50SNS+HgdgWVz$uJ-~5G1oe=<5Mh0d8 delta 26 gcmbQsF`I)cpO=@50SNZkZRC2%#Avqp8= printer3d_constant.XMIN assert self.xMax <= printer3d_constant.XMAX @@ -143,19 +158,24 @@ def scanCurrentLayer(self, printedLayer): gcodeScan[0].append('G1 Y' + str(Yinit-(margin/2)) + ' F1200\n') length = int((Yfinal-Yinit+margin)/step) - self.get_logger().info('scanning begin :') - self.get_logger().info('Yinit :' + str(Yinit)) - self.get_logger().info('Yfinal :' + str(Yfinal)) - self.get_logger().info('length :' + str(length)) + self.get_logger().info('scanning begin') + # self.get_logger().info('Yinit :' + str(Yinit)) + # self.get_logger().info('Yfinal :' + str(Yfinal)) + # self.get_logger().info('length :' + str(length)) for i in range(1, length): gcodeScan.append([]) gcodeScan[-1].append('G1 Y' + str(Yinit-(margin/2)+(i*step))+'\n') surface = [] + iterator = 0 for movements in gcodeScan: - self.sendGcodeSendingRequest(movements) + if iterator == 0: + self.sendGcodeSendingRequest(movements, True) + else: + self.sendGcodeSendingRequest(movements) profileLine = self.sendProfileMeasureRequest() surface.append(profileLine) + iterator += 1 np.save(self.historyFileDir+'/scan/layer_scan_'+str(self.scanNumber)+'.npy', np.array(surface)) self.scanNumber += 1 return surface @@ -163,22 +183,6 @@ def scanCurrentLayer(self, printedLayer): def printCurrentLayer(self): return 0 - def takeCurrentLayerPhoto(self): - gcodeMoveToPos = ['G28 X0 Y0\n', 'G1 Y' + str(printer3d_constant.YPOSPHOTO) + ' F2400\n'] - self.sendGcodeSendingRequest(gcodeMoveToPos) - self.sendImageCaptureRequest(self.historyFileDir+'/photos/layer_photo_'+str(self.imageNumber)+'.jpg') - self.imageNumber += 1 - return 0 - - def sendImageCaptureRequest(self, filename): - self.req_image_capture.filename = filename - self.future_image_capture = self.client_image_capture.call_async(self.req_image_capture) - while rclpy.ok(): - rclpy.spin_once(self) - if self.future_image_capture.done(): - self.get_logger().info('capture finished') - break - def sendProfileMeasureRequest(self): profile_line = [] self.future_profile_measure = self.client_profile_measure.call_async(self.req_profile_measure) @@ -205,7 +209,7 @@ def printLastPositions(self): self.get_logger().info("Last Position : ("+str(self.last_x_value)+", "+str(self.last_y_value)+", "+str(self.last_z_value)+", "+str(self.last_e_value)+")\n") return 0 - def sendGcodeSendingRequest(self, gcode): + def sendGcodeSendingRequest(self, gcode, with_retraction = False): assert self.verifyGcodeBeforeSending(gcode) is True (changed_x,changed_y,changed_z,changed_e) = follow_gcode_coordinates(gcode) @@ -218,7 +222,18 @@ def sendGcodeSendingRequest(self, gcode): if changed_e != None: self.last_e_value = changed_e - self.req_printer_driver.gcode_strings = gcode + if with_retraction: + self.get_logger().info("retraction enclenchée") + self.req_printer_driver.gcode_strings = ['G1 F60 E'+str(self.last_e_value-printer3d_constant.RETRACTION_VALUE)+'\n']+gcode+['G1 F60 E'+str(self.last_e_value)+'\n'] + else: + self.req_printer_driver.gcode_strings = gcode + + fichier_sauvegarde = open(self.historyFileDir+'/gcode/sendedGcode.gcode','a') + for lines in self.req_printer_driver.gcode_strings: + fichier_sauvegarde.write(lines) + fichier_sauvegarde.close() + + self.future_printer_driver = self.client_printer_driver.call_async(self.req_printer_driver) while rclpy.ok(): rclpy.spin_once(self) @@ -234,6 +249,7 @@ def sendGcodeSendingRequest(self, gcode): for i in range(0, len(gcode)-1): printer_control_node.get_logger().info('lancement de la couche '+str(i+1)+' sur '+str(len(gcode)-1)) printer_control_node.sendGcodeSendingRequest(gcode[i]) + printer_control_node.printLastPositions() printer_control_node.get_logger().info('fin de la couche '+str(i+1)+' sur '+str(len(gcode))) printer_control_node.takeCurrentLayerPhoto() printer_control_node.scanCurrentLayer(gcode[i]) diff --git a/3D_printer/src/printer3d_manager/nodes/printer_scanner_node.py b/3D_printer/src/printer3d_manager/nodes/printer_scanner_node.py index 0474361..cbee0e1 100644 --- a/3D_printer/src/printer3d_manager/nodes/printer_scanner_node.py +++ b/3D_printer/src/printer3d_manager/nodes/printer_scanner_node.py @@ -84,12 +84,12 @@ def loadGcode(self): rawGode = fileFullGcode.readlines() fileFullGcode.close() (self.xMin, self.yMin, self.zMin, self.xMax, self.yMax, self.zMax) = getBordersGcode(rawGode) - self.get_logger().info('xMin : ' + str(self.xMin)) - self.get_logger().info('xMax : ' + str(self.xMax)) - self.get_logger().info('yMin : ' + str(self.yMin)) - self.get_logger().info('yMax : ' + str(self.yMax)) - self.get_logger().info('zMin : ' + str(self.zMin)) - self.get_logger().info('zMax : ' + str(self.zMax)) + # self.get_logger().info('xMin : ' + str(self.xMin)) + # self.get_logger().info('xMax : ' + str(self.xMax)) + # self.get_logger().info('yMin : ' + str(self.yMin)) + # self.get_logger().info('yMax : ' + str(self.yMax)) + # self.get_logger().info('zMin : ' + str(self.zMin)) + # self.get_logger().info('zMax : ' + str(self.zMax)) assert self.xMin >= printer3d_constant.XMIN assert self.xMax <= printer3d_constant.XMAX @@ -134,19 +134,24 @@ def scanCurrentLayer(self, printedLayer): gcodeScan[0].append('G1 Y' + str(Yinit-(margin/2)) + ' F1200\n') length = int((Yfinal-Yinit+margin)/step) - self.get_logger().info('scanning begin :') - self.get_logger().info('Yinit :' + str(Yinit)) - self.get_logger().info('Yfinal :' + str(Yfinal)) - self.get_logger().info('length :' + str(length)) + self.get_logger().info('scanning begin') + # self.get_logger().info('Yinit :' + str(Yinit)) + # self.get_logger().info('Yfinal :' + str(Yfinal)) + # self.get_logger().info('length :' + str(length)) for i in range(1, length): gcodeScan.append([]) gcodeScan[-1].append('G1 Y' + str(Yinit-(margin/2)+(i*step))+'\n') surface = [] + iterator = 0 for movements in gcodeScan: - self.sendGcodeSendingRequest(movements) + if iterator == 0: + self.sendGcodeSendingRequest(movements, True) + else: + self.sendGcodeSendingRequest(movements) profileLine = self.sendProfileMeasureRequest() surface.append(profileLine) + iterator += 1 np.save(self.historyFileDir+'/scan/layer_scan_'+str(self.scanNumber)+'.npy', np.array(surface)) self.scanNumber += 1 return surface @@ -180,7 +185,7 @@ def printLastPositions(self): self.get_logger().info("Last Position : ("+str(self.last_x_value)+", "+str(self.last_y_value)+", "+str(self.last_z_value)+", "+str(self.last_e_value)+")\n") return 0 - def sendGcodeSendingRequest(self, gcode): + def sendGcodeSendingRequest(self, gcode, with_retraction = False): assert self.verifyGcodeBeforeSending(gcode) is True (changed_x,changed_y,changed_z,changed_e) = follow_gcode_coordinates(gcode) @@ -193,7 +198,18 @@ def sendGcodeSendingRequest(self, gcode): if changed_e != None: self.last_e_value = changed_e - self.req_printer_driver.gcode_strings = gcode + if with_retraction: + self.get_logger().info("retraction enclenchée") + self.req_printer_driver.gcode_strings = ['G1 F60 E'+str(self.last_e_value-printer3d_constant.RETRACTION_VALUE)+'\n']+gcode+['G1 F60 E'+str(self.last_e_value)+'\n'] + else: + self.req_printer_driver.gcode_strings = gcode + + fichier_sauvegarde = open(self.historyFileDir+'/gcode/sendedGcode.gcode','a') + for lines in self.req_printer_driver.gcode_strings: + fichier_sauvegarde.write(lines) + fichier_sauvegarde.close() + + self.future_printer_driver = self.client_printer_driver.call_async(self.req_printer_driver) while rclpy.ok(): rclpy.spin_once(self) @@ -210,7 +226,7 @@ def sendGcodeSendingRequest(self, gcode): printer_control_node.get_logger().info('lancement de la couche '+str(i+1)+' sur '+str(len(gcode)-1)) printer_control_node.sendGcodeSendingRequest(gcode[i]) printer_control_node.printLastPositions() - printer_control_node.get_logger().info('fin de la couche '+str(i+1)+' sur '+str(len(gcode))) + printer_control_node.get_logger().info('fin de la couche '+str(i+1)+' sur '+str(len(gcode)-1)) printer_control_node.scanCurrentLayer(gcode[i]) rclpy.shutdown() diff --git a/3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp b/3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp index 8ce3373..3b4c1f8 100644 --- a/3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp +++ b/3D_printer/src/printer3d_profile_capture/src/nodes/gocatorSensorNode.cpp @@ -52,7 +52,7 @@ class GocatorSensorNode : public rclcpp::Node std::shared_ptr response) { pcl::PointCloud cloud; - RCLCPP_INFO(this->get_logger(), "Processing service request!"); + // RCLCPP_INFO(this->get_logger(), "Processing service request!"); gsensor_->start(); gsensor_->sendTrigger(); if (gsensor_->getProfile(cloud) == 1) { From 32979758f25320d44aa773ed7114f6e1a9bd8a3a Mon Sep 17 00:00:00 2001 From: MosserLoic Date: Thu, 7 Sep 2023 09:31:12 +0200 Subject: [PATCH 24/30] gcode capture code used for paper (update 1) --- .../nodes/image_capture_calibration.py | 2 +- .../nodes/image_capture_node.py | 2 +- .../src/printer3d_manager/config/params.yaml | 2 +- ...th_image_capture_plus_scanner.cpython-310.pyc | Bin 0 -> 1166 bytes ...unch_print_with_image_capture_plus_scanner.py | 2 +- .../nodes/printer_scanner_imageCapture_node.py | 15 +++++++++------ 6 files changed, 13 insertions(+), 10 deletions(-) create mode 100644 3D_printer/src/printer3d_manager/launch/__pycache__/launch_print_with_image_capture_plus_scanner.cpython-310.pyc diff --git a/3D_printer/src/printer3d_image_capture/nodes/image_capture_calibration.py b/3D_printer/src/printer3d_image_capture/nodes/image_capture_calibration.py index 46323c2..d5665e0 100644 --- a/3D_printer/src/printer3d_image_capture/nodes/image_capture_calibration.py +++ b/3D_printer/src/printer3d_image_capture/nodes/image_capture_calibration.py @@ -89,7 +89,7 @@ def sendGcodeSendingRequest(self, gcode): if __name__ == '__main__': rclpy.init() - image_capture_node = ImageCaptureNode(2) + image_capture_node = ImageCaptureNode(0) gcode = ['G28\n', 'G1 Y'+str(YPOSPHOTO)+' F2400\n'] image_capture_node.sendGcodeSendingRequest(gcode) image_capture_node.showVideo() diff --git a/3D_printer/src/printer3d_image_capture/nodes/image_capture_node.py b/3D_printer/src/printer3d_image_capture/nodes/image_capture_node.py index 635dcd3..caf9f44 100644 --- a/3D_printer/src/printer3d_image_capture/nodes/image_capture_node.py +++ b/3D_printer/src/printer3d_image_capture/nodes/image_capture_node.py @@ -41,6 +41,6 @@ def takePicture(self, request, response): if __name__ == '__main__': rclpy.init() - image_capture_node = ImageCaptureNode(2) + image_capture_node = ImageCaptureNode(0) rclpy.spin(image_capture_node) rclpy.shutdown() diff --git a/3D_printer/src/printer3d_manager/config/params.yaml b/3D_printer/src/printer3d_manager/config/params.yaml index 2247748..b0082eb 100644 --- a/3D_printer/src/printer3d_manager/config/params.yaml +++ b/3D_printer/src/printer3d_manager/config/params.yaml @@ -1,4 +1,4 @@ printer3d_manager: ros__parameters: - history_file_dir: "/home/gulltor/Ramsai_Robotics/history/test_retraction" + history_file_dir: "/home/gulltor/Ramsai_Robotics/history/impression_piece_ecroulement" gcode_file_dir: "/home/gulltor/Ramsai_Robotics/Gcodes/impression_piece_ecroulement.gcode" \ No newline at end of file diff --git a/3D_printer/src/printer3d_manager/launch/__pycache__/launch_print_with_image_capture_plus_scanner.cpython-310.pyc b/3D_printer/src/printer3d_manager/launch/__pycache__/launch_print_with_image_capture_plus_scanner.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..92ac26b9c7af0399836915d646d9e7e1dc449b8b GIT binary patch literal 1166 zcmah|y>AmS6u0l3yCl8PFA6F}lz}BnD#ThLq#`Dig#k6o$()_bl{@=nJG6<~DJ%>X z3x7a6@-KO1Vqiyn2%ayOrl1I z#Bh!ZJiyr9z1%DOfnVMIoD_{gqq>tk7zFT6@^BEc1`FP!L6ebJs2hF-FQ|*{`b#<% z$>=%PiONcoNdZdImyE-AC*>wCY4Vn)Jk}$sc+4`z6C>56pEwVT<-=tK&H)_#34}pM z_`)+j!!yi0=3n|}$dFUWW#)bCoMF?r2u|@OKJ#8f1qAjC@)ym=Nbep)Rc;@`F`;R? z%vs2qtaVNRwE?ZLs74(?w_wlTFrZbocIq*_joA7&N-^6wZ=_^~q3X@PT`yH83|CKB zTu=dZDH|kG46}5)Qc^_=-J8%Nw^-S=r72U{JFuKSn=uBKX4iArrK^V zeL$weEWh$%H&dBVm#gMN*C|gQ)%LMYs1RJmmCu8D;HyZt7gj)+Q8KR{?5dJFhA9E= zI1sD54do_5MNV{_xCO$tuUWLLC$%LdH6u%oWF{1GCPbE8SW@xd(sanRISLI309%#7wmF6fQRe5@Ds zyB@;u0~6Fh7L|jTE&q`a0_qna0vuouHu)U|5x)P&^BtOR^2-bUcaJdn8GKU@!Bw|q zgL$N?V!Kg?1$uilaet<+Sg<=lG?b7D#!upMVn$N*>dDd-k?Ib(Q}>*3jw^buiCxgy Y=6)gBIOk6>Anke;p$JE~2|M!s0viBQ&;S4c literal 0 HcmV?d00001 diff --git a/3D_printer/src/printer3d_manager/launch/launch_print_with_image_capture_plus_scanner.py b/3D_printer/src/printer3d_manager/launch/launch_print_with_image_capture_plus_scanner.py index 42605c8..91cf014 100644 --- a/3D_printer/src/printer3d_manager/launch/launch_print_with_image_capture_plus_scanner.py +++ b/3D_printer/src/printer3d_manager/launch/launch_print_with_image_capture_plus_scanner.py @@ -30,7 +30,7 @@ def generate_launch_description(): Node( package='printer3d_profile_capture', namespace='printing_process', - executable='gocator_sensor_node.py', + executable='gocator_sensor_node', name='gocator_sensor_node' ), Node( diff --git a/3D_printer/src/printer3d_manager/nodes/printer_scanner_imageCapture_node.py b/3D_printer/src/printer3d_manager/nodes/printer_scanner_imageCapture_node.py index 81b2ae1..08a6995 100644 --- a/3D_printer/src/printer3d_manager/nodes/printer_scanner_imageCapture_node.py +++ b/3D_printer/src/printer3d_manager/nodes/printer_scanner_imageCapture_node.py @@ -89,7 +89,7 @@ def __init__(self): def takeCurrentLayerPhoto(self): gcodeMoveToPos = ['G28 X0 Y0\n', 'G1 Y' + str(printer3d_constant.YPOSPHOTO) + ' F2400\n'] - self.sendGcodeSendingRequest(gcodeMoveToPos) + self.sendGcodeSendingRequest(gcodeMoveToPos,True,False) self.sendImageCaptureRequest(self.historyFileDir+'/photos/layer_photo_'+str(self.imageNumber)+'.jpg') self.imageNumber += 1 return 0 @@ -167,10 +167,10 @@ def scanCurrentLayer(self, printedLayer): gcodeScan.append([]) gcodeScan[-1].append('G1 Y' + str(Yinit-(margin/2)+(i*step))+'\n') surface = [] - iterator = 0 + iterator = len(gcodeScan) for movements in gcodeScan: - if iterator == 0: - self.sendGcodeSendingRequest(movements, True) + if iterator == len(gcodeScan)-1: + self.sendGcodeSendingRequest(movements, False, True) else: self.sendGcodeSendingRequest(movements) profileLine = self.sendProfileMeasureRequest() @@ -209,7 +209,7 @@ def printLastPositions(self): self.get_logger().info("Last Position : ("+str(self.last_x_value)+", "+str(self.last_y_value)+", "+str(self.last_z_value)+", "+str(self.last_e_value)+")\n") return 0 - def sendGcodeSendingRequest(self, gcode, with_retraction = False): + def sendGcodeSendingRequest(self, gcode, with_retraction = False, with_extrusion = False): assert self.verifyGcodeBeforeSending(gcode) is True (changed_x,changed_y,changed_z,changed_e) = follow_gcode_coordinates(gcode) @@ -224,7 +224,10 @@ def sendGcodeSendingRequest(self, gcode, with_retraction = False): if with_retraction: self.get_logger().info("retraction enclenchée") - self.req_printer_driver.gcode_strings = ['G1 F60 E'+str(self.last_e_value-printer3d_constant.RETRACTION_VALUE)+'\n']+gcode+['G1 F60 E'+str(self.last_e_value)+'\n'] + self.req_printer_driver.gcode_strings = ['G1 F60 E'+str(self.last_e_value-printer3d_constant.RETRACTION_VALUE)+'\n']+gcode + elif with_extrusion: + self.get_logger().info("extrusion enclenchée") + self.req_printer_driver.gcode_strings = gcode+['G1 F60 E'+str(self.last_e_value)+'\n'] else: self.req_printer_driver.gcode_strings = gcode From 1d51c9d3abfa5b5c172f94b155d1dc8af43242f3 Mon Sep 17 00:00:00 2001 From: MosserLoic Date: Fri, 8 Sep 2023 09:48:22 +0200 Subject: [PATCH 25/30] gcode capture code used for paper (update 2) --- 3D_printer/src/printer3d_manager/config/params.yaml | 2 +- .../nodes/printer_scanner_imageCapture_node.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/3D_printer/src/printer3d_manager/config/params.yaml b/3D_printer/src/printer3d_manager/config/params.yaml index b0082eb..15b2024 100644 --- a/3D_printer/src/printer3d_manager/config/params.yaml +++ b/3D_printer/src/printer3d_manager/config/params.yaml @@ -1,4 +1,4 @@ printer3d_manager: ros__parameters: - history_file_dir: "/home/gulltor/Ramsai_Robotics/history/impression_piece_ecroulement" + history_file_dir: "/home/gulltor/Ramsai_Robotics/history/impression_piece_ecroulement_2" gcode_file_dir: "/home/gulltor/Ramsai_Robotics/Gcodes/impression_piece_ecroulement.gcode" \ No newline at end of file diff --git a/3D_printer/src/printer3d_manager/nodes/printer_scanner_imageCapture_node.py b/3D_printer/src/printer3d_manager/nodes/printer_scanner_imageCapture_node.py index 08a6995..9ebd558 100644 --- a/3D_printer/src/printer3d_manager/nodes/printer_scanner_imageCapture_node.py +++ b/3D_printer/src/printer3d_manager/nodes/printer_scanner_imageCapture_node.py @@ -255,6 +255,9 @@ def sendGcodeSendingRequest(self, gcode, with_retraction = False, with_extrusion printer_control_node.printLastPositions() printer_control_node.get_logger().info('fin de la couche '+str(i+1)+' sur '+str(len(gcode))) printer_control_node.takeCurrentLayerPhoto() - printer_control_node.scanCurrentLayer(gcode[i]) + if i == 0: + printer_control_node.scanCurrentLayer(gcode[i+1]) + else: + printer_control_node.scanCurrentLayer(gcode[i]) rclpy.shutdown() From 2f43aff34b4da8120881b9cf51e6f40811a0cd32 Mon Sep 17 00:00:00 2001 From: MosserLoic Date: Fri, 3 May 2024 15:37:06 +0200 Subject: [PATCH 26/30] Keyence package add to the repo --- .gitignore | 1 + .../CMakeLists.txt | 58 +++ .../LICENSE | 202 ++++++++ .../config/params.yaml | 10 + .../launch/launch_keyence_commands.py | 30 ++ .../package.xml | 18 + .../src/nodes/keyence_commands_node.py | 82 +++ .../src/printer3d_keyence_msgs/CMakeLists.txt | 45 ++ .../src/printer3d_keyence_msgs/package.xml | 18 + .../srv/KeyenceControlCommands.srv | 3 + .../srv/SaveProfilesCommand.srv | 3 + .../CMakeLists.txt | 61 +++ .../printer3d_keyence_profile_capture/LICENSE | 202 ++++++++ .../config/params.yaml | 10 + .../launch/launch_keyence_control.py | 24 + .../package.xml | 18 + .../src/nodes/keyence_control_node.py | 473 ++++++++++++++++++ .../src/printer3d_manager/config/params.yaml | 6 +- .../printer3d_profile_capture/CMakeLists.txt | 4 +- 19 files changed, 1264 insertions(+), 4 deletions(-) create mode 100644 3D_printer/src/printer3d_keyence_data_acquisition_test/CMakeLists.txt create mode 100644 3D_printer/src/printer3d_keyence_data_acquisition_test/LICENSE create mode 100644 3D_printer/src/printer3d_keyence_data_acquisition_test/config/params.yaml create mode 100644 3D_printer/src/printer3d_keyence_data_acquisition_test/launch/launch_keyence_commands.py create mode 100644 3D_printer/src/printer3d_keyence_data_acquisition_test/package.xml create mode 100644 3D_printer/src/printer3d_keyence_data_acquisition_test/src/nodes/keyence_commands_node.py create mode 100644 3D_printer/src/printer3d_keyence_msgs/CMakeLists.txt create mode 100644 3D_printer/src/printer3d_keyence_msgs/package.xml create mode 100644 3D_printer/src/printer3d_keyence_msgs/srv/KeyenceControlCommands.srv create mode 100644 3D_printer/src/printer3d_keyence_msgs/srv/SaveProfilesCommand.srv create mode 100644 3D_printer/src/printer3d_keyence_profile_capture/CMakeLists.txt create mode 100644 3D_printer/src/printer3d_keyence_profile_capture/LICENSE create mode 100644 3D_printer/src/printer3d_keyence_profile_capture/config/params.yaml create mode 100644 3D_printer/src/printer3d_keyence_profile_capture/launch/launch_keyence_control.py create mode 100644 3D_printer/src/printer3d_keyence_profile_capture/package.xml create mode 100644 3D_printer/src/printer3d_keyence_profile_capture/src/nodes/keyence_control_node.py diff --git a/.gitignore b/.gitignore index 98fb702..d24b115 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ install/ 3D_Printer/install 3D_Printer/log 3D_printer/src/printer3d_profile_capture/external +3D_printer/src/printer3d_keyence_profile_capture/src/driver \ No newline at end of file diff --git a/3D_printer/src/printer3d_keyence_data_acquisition_test/CMakeLists.txt b/3D_printer/src/printer3d_keyence_data_acquisition_test/CMakeLists.txt new file mode 100644 index 0000000..51dc00b --- /dev/null +++ b/3D_printer/src/printer3d_keyence_data_acquisition_test/CMakeLists.txt @@ -0,0 +1,58 @@ +cmake_minimum_required(VERSION 3.8) +project(printer3d_keyence_data_acquisition_test) + +# Default to C99 +if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 99) +endif() + +# Default to C++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# find dependencies +find_package(ament_cmake REQUIRED) +find_package(rclcpp REQUIRED) +# find_package(rclpy REQUIRED) +find_package(std_msgs REQUIRED) +find_package(rosidl_default_generators REQUIRED) +# find_package(keyence_msgs REQUIRED) +# uncomment the following section in order to fill in +# further dependencies manually. +# find_package( REQUIRED) + +install(PROGRAMS + src/nodes/keyence_commands_node.py + + DESTINATION lib/${PROJECT_NAME}) + +# Install launch files. +install(DIRECTORY +launch +DESTINATION share/${PROJECT_NAME}/ +) + +# Install YAML config files. +install(DIRECTORY + config + DESTINATION share/${PROJECT_NAME}/ +) + +if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + # the following line skips the linter which checks for copyrights + # comment the line when a copyright and license is added to all source files + # set(ament_cmake_copyright_FOUND TRUE) + # the following line skips cpplint (only works in a git repo) + # comment the line when this package is in a git repo and when + # a copyright and license is added to all source files + # set(ament_cmake_cpplint_FOUND TRUE) + ament_lint_auto_find_test_dependencies() +endif() + +ament_package() diff --git a/3D_printer/src/printer3d_keyence_data_acquisition_test/LICENSE b/3D_printer/src/printer3d_keyence_data_acquisition_test/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/3D_printer/src/printer3d_keyence_data_acquisition_test/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/3D_printer/src/printer3d_keyence_data_acquisition_test/config/params.yaml b/3D_printer/src/printer3d_keyence_data_acquisition_test/config/params.yaml new file mode 100644 index 0000000..090cf76 --- /dev/null +++ b/3D_printer/src/printer3d_keyence_data_acquisition_test/config/params.yaml @@ -0,0 +1,10 @@ +keyence_controler: + ros__parameters: + deviceId: 0 + abyIpAddress_1: 192 + abyIpAddress_2: 168 + abyIpAddress_3: 0 + abyIpAddress_4: 1 + wPortNo: 24691 + HighSpeedPortNo: 24692 + \ No newline at end of file diff --git a/3D_printer/src/printer3d_keyence_data_acquisition_test/launch/launch_keyence_commands.py b/3D_printer/src/printer3d_keyence_data_acquisition_test/launch/launch_keyence_commands.py new file mode 100644 index 0000000..8dbbb92 --- /dev/null +++ b/3D_printer/src/printer3d_keyence_data_acquisition_test/launch/launch_keyence_commands.py @@ -0,0 +1,30 @@ +from launch import LaunchDescription +from launch_ros.actions import Node +from ament_index_python.packages import get_package_share_directory +import os +import yaml + +def generate_launch_description(): + config = os.path.join( + get_package_share_directory('keyence_profile_service_caller'), + 'config', + 'params.yaml' + ) + + with open(config, 'r') as f: + configYaml = yaml.safe_load(f) + + return LaunchDescription([ + Node( + package='keyence_controler', + namespace='measure_process', + executable='keyence_control_node.py', + name='keyence_control_node' + ), + Node( + package='keyence_profile_service_caller', + namespace='measure_process', + executable='keyence_commands_node.py', + name='keyence_commands_node' + ) + ]) \ No newline at end of file diff --git a/3D_printer/src/printer3d_keyence_data_acquisition_test/package.xml b/3D_printer/src/printer3d_keyence_data_acquisition_test/package.xml new file mode 100644 index 0000000..d1ef5b5 --- /dev/null +++ b/3D_printer/src/printer3d_keyence_data_acquisition_test/package.xml @@ -0,0 +1,18 @@ + + + + printer3d_keyence_data_acquisition_test + 0.0.0 + ROS2 package to test communication commands. + Mosser Loic + Apache-2.0 + + ament_cmake + + ament_lint_auto + ament_lint_common + + + ament_cmake + + diff --git a/3D_printer/src/printer3d_keyence_data_acquisition_test/src/nodes/keyence_commands_node.py b/3D_printer/src/printer3d_keyence_data_acquisition_test/src/nodes/keyence_commands_node.py new file mode 100644 index 0000000..01fa996 --- /dev/null +++ b/3D_printer/src/printer3d_keyence_data_acquisition_test/src/nodes/keyence_commands_node.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python3 +# Copyright 2023 ICube Laboratory, University of Strasbourg +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import rclpy +from rclpy.node import Node +import time +import ctypes +import sys +import numpy as np +from printer3d_keyence_msgs.srv import KeyenceControlCommands, SaveProfilesCommand + +class KeyenceCommandNode(Node): + def __init__(self): + """KeyenceCommandNode class constructor.""" + super().__init__('printer3d_keyence_data_acquisition_test') + + self.client_keyence_control_service = self.create_client(KeyenceControlCommands, 'keyence_control_commands') + while not self.client_keyence_control_service.wait_for_service(timeout_sec=1.0): + self.get_logger().info('keyence control service not available, waiting again...') + self.req_keyence_control = KeyenceControlCommands.Request() + + self.client_saving_buffer_service = self.create_client(SaveProfilesCommand, 'saving_buffer') + while not self.client_saving_buffer_service.wait_for_service(timeout_sec=1.0): + self.get_logger().info('buffer saving service not available, waiting again...') + self.req_saving_buffer = SaveProfilesCommand.Request() + + def send_command(self,command): + self.req_keyence_control.order = command + self.future_keyence_control = self.client_keyence_control_service.call_async(self.req_keyence_control) + while rclpy.ok(): + rclpy.spin_once(self) + if self.future_keyence_control.done(): + self.get_logger().info('command executed') + return 0 + + def ask_for_buffer_saving(self,filename): + self.req_saving_buffer.filenametosave = filename + self.future_buffer_saving = self.client_saving_buffer_service.call_async(self.req_saving_buffer) + while rclpy.ok(): + rclpy.spin_once(self) + if self.future_buffer_saving.done(): + self.get_logger().info('command executed') + return 0 + + def sendImageCaptureRequest(self, filename): + self.req_image_capture.filename = filename + self.future_image_capture = self.client_image_capture.call_async(self.req_image_capture) + while rclpy.ok(): + rclpy.spin_once(self) + if self.future_image_capture.done(): + self.get_logger().info('capture finished') + break + +if __name__ == '__main__': + rclpy.init() + + keyence_command_node = KeyenceCommandNode() + keyence_command_node.send_command('laser_on') + keyence_command_node.send_command('buffer_flush') + keyence_command_node.get_logger().info("10 secondes pour acquerir des profils") + time.sleep(10) + keyence_command_node.get_logger().info("lancement sauvegarde") + keyence_command_node.send_command('laser_off') + keyence_command_node.ask_for_buffer_saving('/home/gulltor/Desktop/Keyence_control/LJ-X8000A_PyLib_1_3_0_2/ros2_keyence_controler/profiles.npy') + keyence_command_node.send_command('laser_on') + + + + + rclpy.shutdown() \ No newline at end of file diff --git a/3D_printer/src/printer3d_keyence_msgs/CMakeLists.txt b/3D_printer/src/printer3d_keyence_msgs/CMakeLists.txt new file mode 100644 index 0000000..cdb0f23 --- /dev/null +++ b/3D_printer/src/printer3d_keyence_msgs/CMakeLists.txt @@ -0,0 +1,45 @@ +cmake_minimum_required(VERSION 3.5) +project(printer3d_keyence_msgs) + +# Default to C99 +if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 99) +endif() + +# Default to C++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# find dependencies +find_package(ament_cmake REQUIRED) +# uncomment the following section in order to fill in +# further dependencies manually. +# find_package( REQUIRED) +find_package(ament_cmake REQUIRED) +find_package(builtin_interfaces REQUIRED) +find_package(rosidl_default_generators REQUIRED) +find_package(std_msgs REQUIRED) + + +if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + # the following line skips the linter which checks for copyrights + # uncomment the line when a copyright and license is not present in all source files + #set(ament_cmake_copyright_FOUND TRUE) + # the following line skips cpplint (only works in a git repo) + # uncomment the line when this package is not in a git repo + #set(ament_cmake_cpplint_FOUND TRUE) + ament_lint_auto_find_test_dependencies() +endif() + +rosidl_generate_interfaces( ${PROJECT_NAME} + "srv/KeyenceControlCommands.srv" + "srv/SaveProfilesCommand.srv" +) + +ament_package() diff --git a/3D_printer/src/printer3d_keyence_msgs/package.xml b/3D_printer/src/printer3d_keyence_msgs/package.xml new file mode 100644 index 0000000..f117516 --- /dev/null +++ b/3D_printer/src/printer3d_keyence_msgs/package.xml @@ -0,0 +1,18 @@ + + +printer3d_keyence_msgs +0.0.0 +Messages for communication with Keyence systems +mosserl +TODO: License declaration +ament_cmake +ament_lint_auto +ament_lint_common +std_msgs +builtin_interfaces +rosidl_default_generators +rosidl_interface_packages + +ament_cmake + + diff --git a/3D_printer/src/printer3d_keyence_msgs/srv/KeyenceControlCommands.srv b/3D_printer/src/printer3d_keyence_msgs/srv/KeyenceControlCommands.srv new file mode 100644 index 0000000..a1526b2 --- /dev/null +++ b/3D_printer/src/printer3d_keyence_msgs/srv/KeyenceControlCommands.srv @@ -0,0 +1,3 @@ +string order +--- +bool validation diff --git a/3D_printer/src/printer3d_keyence_msgs/srv/SaveProfilesCommand.srv b/3D_printer/src/printer3d_keyence_msgs/srv/SaveProfilesCommand.srv new file mode 100644 index 0000000..abfcde3 --- /dev/null +++ b/3D_printer/src/printer3d_keyence_msgs/srv/SaveProfilesCommand.srv @@ -0,0 +1,3 @@ +string filenametosave +--- +bool confirmation diff --git a/3D_printer/src/printer3d_keyence_profile_capture/CMakeLists.txt b/3D_printer/src/printer3d_keyence_profile_capture/CMakeLists.txt new file mode 100644 index 0000000..4d01be7 --- /dev/null +++ b/3D_printer/src/printer3d_keyence_profile_capture/CMakeLists.txt @@ -0,0 +1,61 @@ +cmake_minimum_required(VERSION 3.8) +project(printer3d_keyence_profile_capture) + +# Default to C99 +if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 99) +endif() + +# Default to C++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# find dependencies +find_package(ament_cmake REQUIRED) +find_package(rclcpp REQUIRED) +# find_package(rclpy REQUIRED) +find_package(std_msgs REQUIRED) +find_package(sensor_msgs REQUIRED) +find_package(rosidl_default_generators REQUIRED) +# find_package(keyence_msgs REQUIRED) +# uncomment the following section in order to fill in +# further dependencies manually. +# find_package( REQUIRED) + +install(PROGRAMS + src/nodes/keyence_control_node.py + src/driver/PYTHON/LJXAwrap.py + src/driver/PYTHON/libljxacom.so + src/driver/PYTHON/LJXAwrap.py + DESTINATION lib/${PROJECT_NAME}) + +# Install launch files. +install(DIRECTORY +launch +DESTINATION share/${PROJECT_NAME}/ +) + +# Install YAML config files. +install(DIRECTORY + config + DESTINATION share/${PROJECT_NAME}/ +) + +if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + # the following line skips the linter which checks for copyrights + # comment the line when a copyright and license is added to all source files + # set(ament_cmake_copyright_FOUND TRUE) + # the following line skips cpplint (only works in a git repo) + # comment the line when this package is in a git repo and when + # a copyright and license is added to all source files + # set(ament_cmake_cpplint_FOUND TRUE) + ament_lint_auto_find_test_dependencies() +endif() + +ament_package() diff --git a/3D_printer/src/printer3d_keyence_profile_capture/LICENSE b/3D_printer/src/printer3d_keyence_profile_capture/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/3D_printer/src/printer3d_keyence_profile_capture/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/3D_printer/src/printer3d_keyence_profile_capture/config/params.yaml b/3D_printer/src/printer3d_keyence_profile_capture/config/params.yaml new file mode 100644 index 0000000..090cf76 --- /dev/null +++ b/3D_printer/src/printer3d_keyence_profile_capture/config/params.yaml @@ -0,0 +1,10 @@ +keyence_controler: + ros__parameters: + deviceId: 0 + abyIpAddress_1: 192 + abyIpAddress_2: 168 + abyIpAddress_3: 0 + abyIpAddress_4: 1 + wPortNo: 24691 + HighSpeedPortNo: 24692 + \ No newline at end of file diff --git a/3D_printer/src/printer3d_keyence_profile_capture/launch/launch_keyence_control.py b/3D_printer/src/printer3d_keyence_profile_capture/launch/launch_keyence_control.py new file mode 100644 index 0000000..c8126ca --- /dev/null +++ b/3D_printer/src/printer3d_keyence_profile_capture/launch/launch_keyence_control.py @@ -0,0 +1,24 @@ +from launch import LaunchDescription +from launch_ros.actions import Node +from ament_index_python.packages import get_package_share_directory +import os +import yaml + +def generate_launch_description(): + config = os.path.join( + get_package_share_directory('keyence_controler'), + 'config', + 'params.yaml' + ) + + with open(config, 'r') as f: + configYaml = yaml.safe_load(f) + + return LaunchDescription([ + Node( + package='keyence_controler', + namespace='measure_process', + executable='keyence_control_node.py', + name='keyence_control_node' + ) + ]) \ No newline at end of file diff --git a/3D_printer/src/printer3d_keyence_profile_capture/package.xml b/3D_printer/src/printer3d_keyence_profile_capture/package.xml new file mode 100644 index 0000000..4f24649 --- /dev/null +++ b/3D_printer/src/printer3d_keyence_profile_capture/package.xml @@ -0,0 +1,18 @@ + + + + printer3d_keyence_profile_capture + 0.0.0 + ROS2 package to control a Keyence LJ-X8080. Will work with all the LJ-X sensors of Keyence. + Mosser Loic + Apache-2.0 + + ament_cmake + + ament_lint_auto + ament_lint_common + + + ament_cmake + + diff --git a/3D_printer/src/printer3d_keyence_profile_capture/src/nodes/keyence_control_node.py b/3D_printer/src/printer3d_keyence_profile_capture/src/nodes/keyence_control_node.py new file mode 100644 index 0000000..f917604 --- /dev/null +++ b/3D_printer/src/printer3d_keyence_profile_capture/src/nodes/keyence_control_node.py @@ -0,0 +1,473 @@ +#!/usr/bin/env python3 +# Copyright 2023 ICube Laboratory, University of Strasbourg +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import LJXAwrap +import rclpy +from rclpy.node import Node +import time +import ctypes +import sys +import numpy as np +from printer3d_keyence_msgs.srv import KeyenceControlCommands,SaveProfilesCommand + +class KeyenceControlNode(Node): + def __init__(self): + """KeyenceControlNode class constructor.""" + super().__init__('printer3d_keyence_profile_capture') + + self.declare_parameter('deviceId', 0) + self.declare_parameter('abyIpAddress_1', 192) + self.declare_parameter('abyIpAddress_2', 168) + self.declare_parameter('abyIpAddress_3', 0) + self.declare_parameter('abyIpAddress_4', 1) + self.declare_parameter('wPortNo', 24691) + self.declare_parameter('HighSpeedPortNo', 24692) + + self.deviceId = self.get_parameter('deviceId').get_parameter_value().integer_value + self.ethernetConfig = LJXAwrap.LJX8IF_ETHERNET_CONFIG() + self.ethernetConfig.abyIpAddress[0] = self.get_parameter('abyIpAddress_1').get_parameter_value().integer_value + self.ethernetConfig.abyIpAddress[1] = self.get_parameter('abyIpAddress_2').get_parameter_value().integer_value + self.ethernetConfig.abyIpAddress[2] = self.get_parameter('abyIpAddress_3').get_parameter_value().integer_value + self.ethernetConfig.abyIpAddress[3] = self.get_parameter('abyIpAddress_4').get_parameter_value().integer_value + self.ethernetConfig.wPortNo = self.get_parameter('wPortNo').get_parameter_value().integer_value + self.HighSpeedPortNo = self.get_parameter('HighSpeedPortNo').get_parameter_value().integer_value + + self.res = LJXAwrap.LJX8IF_EthernetOpen(self.deviceId, self.ethernetConfig) + self.get_logger().info("LJXAwrap.LJX8IF_EthernetOpen:" + str(hex(self.res))) + if self.res != 0: + self.get_logger().info('Failed to connect to the Keyence sensor') + sys.exit() + + # LJ-X 8080 + headmodel = ctypes.create_string_buffer(32) + self.res = LJXAwrap.LJX8IF_GetHeadModel(self.deviceId, headmodel) + self.get_logger().info('LJXAwrap.LJX8IF_GetHeadModel:'+str(hex(self.res))+'='+str(headmodel.value)) + + # LJ-X 8080 serial number + controllerSerial = ctypes.create_string_buffer(16) + headSerial = ctypes.create_string_buffer(16) + res = LJXAwrap.LJX8IF_GetSerialNumber(self.deviceId, + controllerSerial, headSerial) + self.get_logger().info('LJXAwrap.LJX8IF_GetSerialNumber:'+str(hex(self.res))+'='+str(controllerSerial.value)+'='+str(headSerial.value)) + + LJXAwrap.LJX8IF_ClearMemory(self.deviceId) + + self.keyenceControlService = self.create_service(KeyenceControlCommands, 'keyence_control_commands', self.control_service_routine) + self.savingBufferService = self.create_service(SaveProfilesCommand, 'saving_buffer', self.profile_saving_service_routine) + + def select_job(self,job_number): + programNo_get = ctypes.c_ubyte() + self.res = LJXAwrap.LJX8IF_GetActiveProgram(self.deviceId, programNo_get) + if programNo_get.value != job_number: + programNo_set = job_number + res = LJXAwrap.LJX8IF_ChangeActiveProgram(self.deviceId, programNo_set) + return 0 + + def enable_laser(self): + LJXAwrap.LJX8IF_ControlLaser(self.deviceId, 1) + return 0 + + def disable_laser(self): + LJXAwrap.LJX8IF_ControlLaser(self.deviceId, 0) + return 0 + + def get_attention_status(self): + attentionStatus = ctypes.c_ushort() + self.res = LJXAwrap.LJX8IF_GetAttentionStatus(self.deviceId, attentionStatus) + self.get_logger().info("LJXAwrap.LJX8IF_GetAttentionStatus:"+ str(hex(self.res))+"="+ str(bin(attentionStatus.value))) + return 0 + + def ask_for_a_profile(self): + + self.get_logger().info("LJXAwrap.LJX8IF_Trigger : " + str(hex(LJXAwrap.LJX8IF_Trigger(self.deviceId)))) + + # Change according to your controller settings. + xpointNum = 3200 # Number of X points per one profile. + withLumi = 1 # 1: luminance data exists, 0: not exists. + + # Specifies the position, etc. of the profiles to get. + self.req = LJXAwrap.LJX8IF_GET_PROFILE_REQUEST() + self.req.byTargetBank = 0x0 # 0: active bank + self.req.byPositionMode = 0x0 # 0: from current position + self.req.dwGetProfileNo = 0x0 # use when position mode is "POSITION_SPEC" + self.req.byGetProfileCount = 1 # the number of profiles to read. + self.req.byErase = 0 # 0: Do not erase + + self.rsp = LJXAwrap.LJX8IF_GET_PROFILE_RESPONSE() + + self.profinfo = LJXAwrap.LJX8IF_PROFILE_INFO() + + # Calculate the buffer size to store the received profile data. + self.dataSize = ctypes.sizeof(LJXAwrap.LJX8IF_PROFILE_HEADER) + self.dataSize += ctypes.sizeof(LJXAwrap.LJX8IF_PROFILE_FOOTER) + self.dataSize += ctypes.sizeof(ctypes.c_uint) * xpointNum * (1 + withLumi) + self.dataSize *= self.req.byGetProfileCount + + dataNumIn4byte = int(self.dataSize / ctypes.sizeof(ctypes.c_uint)) + self.profdata = (ctypes.c_int * dataNumIn4byte)() + + # Send command. + self.res = LJXAwrap.LJX8IF_GetProfile(self.deviceId, + self.req, + self.rsp, + self.profinfo, + self.profdata, + self.dataSize) + + self.get_logger().info("LJXAwrap.LJX8IF_GetProfile:" + str(hex(self.res))) + + if self.res != 0: + self.get_logger().info("Failed to get profile.") + sys.exit() + + headerSize = ctypes.sizeof(LJXAwrap.LJX8IF_PROFILE_HEADER) + addressOffset_height = int(headerSize / ctypes.sizeof(ctypes.c_uint)) + addressOffset_lumi = addressOffset_height + self.profinfo.wProfileDataCount + + profile_data = [[None, None, None] for i in range(self.profinfo.wProfileDataCount)] + + for i in range(self.profinfo.wProfileDataCount): + # Conver X data to the actual length in millimeters + x_val_mm = (self.profinfo.lXStart + self.profinfo.lXPitch * i) / 100.0 # um + x_val_mm /= 1000.0 # mm + + # Conver Z data to the actual length in millimeters + z_val = self.profdata[addressOffset_height + i] + + if z_val <= -2147483645: # invalid value + z_val_mm = None + else: + z_val_mm = z_val / 100.0 # um + z_val_mm /= 1000.0 # mm + + # Luminance data + lumi_val = self.profdata[addressOffset_lumi + i] + + profile_data[i][0] = x_val_mm + profile_data[i][1] = z_val_mm + profile_data[i][2] = lumi_val + + profile_data = np.array(profile_data) + + return profile_data + + def get_profile_number(self, number): + # Change according to your controller settings. + xpointNum = 3200 # Number of X points per one profile. + withLumi = 1 # 1: luminance data exists, 0: not exists. + + # Specifies the position, etc. of the profiles to get. + self.req = LJXAwrap.LJX8IF_GET_PROFILE_REQUEST() + self.req.byTargetBank = 0x0 # 0: active bank + self.req.byPositionMode = 0x2 # 2: specify position + self.req.dwGetProfileNo = number # use when position mode is "POSITION_SPEC" + self.req.byGetProfileCount = 1 # the number of profiles to read. + self.req.byErase = 0 # 0: Do not erase + + self.rsp = LJXAwrap.LJX8IF_GET_PROFILE_RESPONSE() + + self.profinfo = LJXAwrap.LJX8IF_PROFILE_INFO() + + # Calculate the buffer size to store the received profile data. + self.dataSize = ctypes.sizeof(LJXAwrap.LJX8IF_PROFILE_HEADER) + self.dataSize += ctypes.sizeof(LJXAwrap.LJX8IF_PROFILE_FOOTER) + self.dataSize += ctypes.sizeof(ctypes.c_uint) * xpointNum * (1 + withLumi) + self.dataSize *= self.req.byGetProfileCount + + dataNumIn4byte = int(self.dataSize / ctypes.sizeof(ctypes.c_uint)) + self.profdata = (ctypes.c_int * dataNumIn4byte)() + + # Send command. + self.res = LJXAwrap.LJX8IF_GetProfile(self.deviceId, + self.req, + self.rsp, + self.profinfo, + self.profdata, + self.dataSize) + if self.res != 0: + self.get_logger().info("Failed to get profile.") + sys.exit() + + headerSize = ctypes.sizeof(LJXAwrap.LJX8IF_PROFILE_HEADER) + addressOffset_height = int(headerSize / ctypes.sizeof(ctypes.c_uint)) + addressOffset_lumi = addressOffset_height + self.profinfo.wProfileDataCount + + profile_data = [[None, None, None] for i in range(self.profinfo.wProfileDataCount)] + + for i in range(self.profinfo.wProfileDataCount): + # Conver X data to the actual length in millimeters + x_val_mm = (self.profinfo.lXStart + self.profinfo.lXPitch * i) / 100.0 # um + x_val_mm /= 1000.0 # mm + + # Conver Z data to the actual length in millimeters + z_val = self.profdata[addressOffset_height + i] + + if z_val <= -2147483645: # invalid value + z_val_mm = None + else: + z_val_mm = z_val / 100.0 # um + z_val_mm /= 1000.0 # mm + + # Luminance data + lumi_val = self.profdata[addressOffset_lumi + i] + + profile_data[i][0] = x_val_mm + profile_data[i][1] = z_val_mm + profile_data[i][2] = lumi_val + + profile_data = np.array(profile_data) + + return profile_data + + def what_number_have_last_acquired_profile(self): + # Change according to your controller settings. + xpointNum = 3200 # Number of X points per one profile. + withLumi = 1 # 1: luminance data exists, 0: not exists. + + # Specifies the position, etc. of the profiles to get. + self.req = LJXAwrap.LJX8IF_GET_PROFILE_REQUEST() + self.req.byTargetBank = 0x0 # 0: active bank + self.req.byPositionMode = 0x0 # 0: from current position + self.req.dwGetProfileNo = 0x0 # use when position mode is "POSITION_SPEC" + self.req.byGetProfileCount = 1 # the number of profiles to read. + self.req.byErase = 0 # 0: Do not erase + + self.rsp = LJXAwrap.LJX8IF_GET_PROFILE_RESPONSE() + + self.profinfo = LJXAwrap.LJX8IF_PROFILE_INFO() + + # Calculate the buffer size to store the received profile data. + self.dataSize = ctypes.sizeof(LJXAwrap.LJX8IF_PROFILE_HEADER) + self.dataSize += ctypes.sizeof(LJXAwrap.LJX8IF_PROFILE_FOOTER) + self.dataSize += ctypes.sizeof(ctypes.c_uint) * xpointNum * (1 + withLumi) + self.dataSize *= self.req.byGetProfileCount + + dataNumIn4byte = int(self.dataSize / ctypes.sizeof(ctypes.c_uint)) + self.profdata = (ctypes.c_int * dataNumIn4byte)() + + # Send command. + self.res = LJXAwrap.LJX8IF_GetProfile(self.deviceId, + self.req, + self.rsp, + self.profinfo, + self.profdata, + self.dataSize) + + self.get_logger().info("LJXAwrap.LJX8IF_GetProfile:" + str(hex(self.res))) + if self.res != 0: + self.get_logger().info("No profile available") + return -1 + else: + return self.rsp.dwGetTopProfileNo + + def get_oldest_profile(self,with_suppression = True): + # Change according to your controller settings. + xpointNum = 3200 # Number of X points per one profile. + withLumi = 1 # 1: luminance data exists, 0: not exists. + + # Specifies the position, etc. of the profiles to get. + self.req = LJXAwrap.LJX8IF_GET_PROFILE_REQUEST() + self.req.byTargetBank = 0x0 # 0: active bank + self.req.byPositionMode = 0x1 # 1: from oldest position + self.req.dwGetProfileNo = 0x0 # use when position mode is "POSITION_SPEC" + self.req.byGetProfileCount = 1 # the number of profiles to read. + self.req.byErase = 1 # 0: Do not erase + + self.rsp = LJXAwrap.LJX8IF_GET_PROFILE_RESPONSE() + + self.profinfo = LJXAwrap.LJX8IF_PROFILE_INFO() + + # Calculate the buffer size to store the received profile data. + self.dataSize = ctypes.sizeof(LJXAwrap.LJX8IF_PROFILE_HEADER) + self.dataSize += ctypes.sizeof(LJXAwrap.LJX8IF_PROFILE_FOOTER) + self.dataSize += ctypes.sizeof(ctypes.c_uint) * xpointNum * (1 + withLumi) + self.dataSize *= self.req.byGetProfileCount + + dataNumIn4byte = int(self.dataSize / ctypes.sizeof(ctypes.c_uint)) + self.profdata = (ctypes.c_int * dataNumIn4byte)() + + # Send command. + self.res = LJXAwrap.LJX8IF_GetProfile(self.deviceId, + self.req, + self.rsp, + self.profinfo, + self.profdata, + self.dataSize) + + self.get_logger().info("LJXAwrap.LJX8IF_GetProfile:" + str(hex(self.res))) + + if self.res != 0: + self.get_logger().info("Failed to get profile.") + sys.exit() + + headerSize = ctypes.sizeof(LJXAwrap.LJX8IF_PROFILE_HEADER) + addressOffset_height = int(headerSize / ctypes.sizeof(ctypes.c_uint)) + addressOffset_lumi = addressOffset_height + self.profinfo.wProfileDataCount + + profile_data = [[None, None, None] for i in range(self.profinfo.wProfileDataCount)] + + for i in range(self.profinfo.wProfileDataCount): + # Conver X data to the actual length in millimeters + x_val_mm = (self.profinfo.lXStart + self.profinfo.lXPitch * i) / 100.0 # um + x_val_mm /= 1000.0 # mm + + # Conver Z data to the actual length in millimeters + z_val = self.profdata[addressOffset_height + i] + + if z_val <= -2147483645: # invalid value + z_val_mm = None + else: + z_val_mm = z_val / 100.0 # um + z_val_mm /= 1000.0 # mm + + # Luminance data + lumi_val = self.profdata[addressOffset_lumi + i] + + profile_data[i][0] = x_val_mm + profile_data[i][1] = z_val_mm + profile_data[i][2] = lumi_val + + profile_data = np.array(profile_data) + + return profile_data + + def flush_buffer_from_profiles(self): + LJXAwrap.LJX8IF_ClearMemory(self.deviceId) + return 0 + + def control_service_routine(self, request, response): + + command = request.order + + if command == "laser_on": + self.enable_laser() + self.get_logger().info("Laser ON") + response.validation = True + elif command == "laser_off": + self.disable_laser() + self.get_logger().info("Laser OFF") + + response.validation = True + elif command == "buffer_flush": + self.flush_buffer_from_profiles() + self.get_logger().info("Buffer Flushed") + response.validation = True + else: + response.validation = False + + + return response + + def callback_s_a(self, p_header, p_height, p_lumi, luminance_enable, xpointnum, profnum, notify, user): + if (notify == 0) or (notify == 0x10000): + if profnum != 0: + if self.image_available is False: + for i in range(xpointnum * profnum): + self.z_val[i + (xpointnum * profnum * nb_measure)] = p_height[i] + if luminance_enable == 1: + self.lumi_val[i + (xpointnum * profnum * nb_measure)] = p_lumi[i] + self.ysize_acquired = profnum + self.image_available = True + return + + def get_all_available_profiles_fast_transmission(self,nombre): + self.image_available = False + self.ysize_acquired = 0 + self.z_val = [] + self.ysize = nombre + self.lumi_val = [] + + # Initialize Hi-Speed Communication + self.my_callback_s_a = LJXAwrap.LJX8IF_CALLBACK_SIMPLE_ARRAY(self.callback_s_a) + + self.res = LJXAwrap.LJX8IF_InitializeHighSpeedDataCommunicationSimpleArray( + self.deviceId, + self.ethernetConfig, + self.HighSpeedPortNo, + self.my_callback_s_a, + self.ysize, + 0) + + if self.res != 0: + sys.exit() + + # PreStart Hi-Speed Communication + self.req = LJXAwrap.LJX8IF_HIGH_SPEED_PRE_START_REQ() + self.req.bySendPosition = 2 + self.profinfo = LJXAwrap.LJX8IF_PROFILE_INFO() + + self.res = LJXAwrap.LJX8IF_PreStartHighSpeedDataCommunication( + self.deviceId, + self.req, + self.profinfo) + + if self.res != 0: + sys.exit() + + # allocate the memory + self.xsize = self.profinfo.wProfileDataCount + self.z_val = [None] * self.xsize * self.ysize + self.lumi_val = [None] * self.xsize * self.ysize + + # Start Hi-Speed Communication + image_available = False + res = LJXAwrap.LJX8IF_StartHighSpeedDataCommunication(self.deviceId) + print("LJXAwrap.LJX8IF_StartHighSpeedDataCommunication:", hex(res)) + if res != 0: + print("\nExit the program.") + sys.exit() + + LJXAwrap.LJX8IF_StartMeasure(self.deviceId) + + test = True + timeout_sec = 10 + start_time = time.time() + while test == True: + if image_available: + test = False + if time.time() - start_time > timeout_sec: + test = False + + self.res = LJXAwrap.LJX8IF_StopHighSpeedDataCommunication(self.deviceId) + self.res = LJXAwrap.LJX8IF_FinalizeHighSpeedDataCommunication(self.deviceId) + return 0 + + def profile_saving_service_routine(self, request, response): + self.disable_laser() + filename_where_to_save = request.filenametosave + + number_of_profiles = self.what_number_have_last_acquired_profile() + 1 + + # Mode ligne par ligne + #profile_list = [None]*number_of_profiles + #for i in range(0,number_of_profiles): + # profile_list[i] = self.get_profile_number(i) + + self.get_all_available_profiles_fast_transmission(number_of_profiles) + + profiles = np.array(self.z_val) + self.get_logger().info("taile du tableau sauvegarde : " + str(profiles.shape)) + np.save(filename_where_to_save,profiles) + self.enable_laser() + response.confirmation = True + return response + +if __name__ == '__main__': + rclpy.init() + keyence_control_node = KeyenceControlNode() + keyence_control_node.select_job(7) + rclpy.spin(keyence_control_node) + rclpy.shutdown() + diff --git a/3D_printer/src/printer3d_manager/config/params.yaml b/3D_printer/src/printer3d_manager/config/params.yaml index 15b2024..4d20779 100644 --- a/3D_printer/src/printer3d_manager/config/params.yaml +++ b/3D_printer/src/printer3d_manager/config/params.yaml @@ -1,4 +1,6 @@ printer3d_manager: ros__parameters: - history_file_dir: "/home/gulltor/Ramsai_Robotics/history/impression_piece_ecroulement_2" - gcode_file_dir: "/home/gulltor/Ramsai_Robotics/Gcodes/impression_piece_ecroulement.gcode" \ No newline at end of file + history_file_dir: "/home/gulltor/Ramsai_Robotics/history/impression_demonstration_mercredi_13_mars" + gcode_file_dir: "/home/gulltor/Ramsai_Robotics/Gcodes/piece_test_base.gcode" + + \ No newline at end of file diff --git a/3D_printer/src/printer3d_profile_capture/CMakeLists.txt b/3D_printer/src/printer3d_profile_capture/CMakeLists.txt index 969b36e..6910fd9 100644 --- a/3D_printer/src/printer3d_profile_capture/CMakeLists.txt +++ b/3D_printer/src/printer3d_profile_capture/CMakeLists.txt @@ -95,10 +95,10 @@ if(BUILD_TESTING) find_package(ament_lint_auto REQUIRED) # the following line skips the linter which checks for copyrights # uncomment the line when a copyright and license is not present in all source files - #set(ament_cmake_copyright_FOUND TRUE) + # set(ament_cmake_copyright_FOUND TRUE) # the following line skips cpplint (only works in a git repo) # uncomment the line when this package is not in a git repo - #set(ament_cmake_cpplint_FOUND TRUE) + # set(ament_cmake_cpplint_FOUND TRUE) ament_lint_auto_find_test_dependencies() endif() From f0f2ab44a523a1f4b8a0dd179cef5a66e835b20c Mon Sep 17 00:00:00 2001 From: MosserLoic Date: Fri, 3 May 2024 15:38:33 +0200 Subject: [PATCH 27/30] adding __pycache__ to .gitignore --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d24b115..23da480 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,6 @@ install/ 3D_Printer/install 3D_Printer/log 3D_printer/src/printer3d_profile_capture/external -3D_printer/src/printer3d_keyence_profile_capture/src/driver \ No newline at end of file +3D_printer/src/printer3d_keyence_profile_capture/src/driver +3D_printer/src/printer3d_keyence_profile_capture/launch/__pycache__ +3D_printer/src/printer3d_keyence_data_acquisition_test/launch/__pycache__ \ No newline at end of file From 2707ecfeee6f35473f5f75a2bc8df9707ec42398 Mon Sep 17 00:00:00 2001 From: MosserLoic Date: Fri, 3 May 2024 15:57:15 +0200 Subject: [PATCH 28/30] node launch update --- .../launch/launch_keyence_commands.py | 6 +++--- .../src/nodes/keyence_commands_node.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/3D_printer/src/printer3d_keyence_data_acquisition_test/launch/launch_keyence_commands.py b/3D_printer/src/printer3d_keyence_data_acquisition_test/launch/launch_keyence_commands.py index 8dbbb92..049c02e 100644 --- a/3D_printer/src/printer3d_keyence_data_acquisition_test/launch/launch_keyence_commands.py +++ b/3D_printer/src/printer3d_keyence_data_acquisition_test/launch/launch_keyence_commands.py @@ -6,7 +6,7 @@ def generate_launch_description(): config = os.path.join( - get_package_share_directory('keyence_profile_service_caller'), + get_package_share_directory('printer3d_keyence_data_acquisition_test'), 'config', 'params.yaml' ) @@ -16,13 +16,13 @@ def generate_launch_description(): return LaunchDescription([ Node( - package='keyence_controler', + package='printer3d_keyence_profile_capture', namespace='measure_process', executable='keyence_control_node.py', name='keyence_control_node' ), Node( - package='keyence_profile_service_caller', + package='printer3d_keyence_data_acquisition_test', namespace='measure_process', executable='keyence_commands_node.py', name='keyence_commands_node' diff --git a/3D_printer/src/printer3d_keyence_data_acquisition_test/src/nodes/keyence_commands_node.py b/3D_printer/src/printer3d_keyence_data_acquisition_test/src/nodes/keyence_commands_node.py index 01fa996..d803457 100644 --- a/3D_printer/src/printer3d_keyence_data_acquisition_test/src/nodes/keyence_commands_node.py +++ b/3D_printer/src/printer3d_keyence_data_acquisition_test/src/nodes/keyence_commands_node.py @@ -73,7 +73,7 @@ def sendImageCaptureRequest(self, filename): time.sleep(10) keyence_command_node.get_logger().info("lancement sauvegarde") keyence_command_node.send_command('laser_off') - keyence_command_node.ask_for_buffer_saving('/home/gulltor/Desktop/Keyence_control/LJ-X8000A_PyLib_1_3_0_2/ros2_keyence_controler/profiles.npy') + keyence_command_node.ask_for_buffer_saving('/home/gulltor/Ramsai_Robotics/Keyence_data/profiles.npy') keyence_command_node.send_command('laser_on') From b31c871c1ce22325c8fe503d527103595bf756ae Mon Sep 17 00:00:00 2001 From: MosserLoic Date: Fri, 3 May 2024 18:55:38 +0200 Subject: [PATCH 29/30] Point_cloud processing work --- .../nodes/point_cloud_processing_node.py | 178 ++++++++++++++++-- 1 file changed, 160 insertions(+), 18 deletions(-) diff --git a/3D_printer/src/printer3d_pointCloud_processing/nodes/point_cloud_processing_node.py b/3D_printer/src/printer3d_pointCloud_processing/nodes/point_cloud_processing_node.py index 14a2db3..5a041f7 100755 --- a/3D_printer/src/printer3d_pointCloud_processing/nodes/point_cloud_processing_node.py +++ b/3D_printer/src/printer3d_pointCloud_processing/nodes/point_cloud_processing_node.py @@ -19,8 +19,9 @@ import numpy as np import pyvista as pv import matplotlib.pyplot as plt -import matplotlib +import matplotlib as mpl import random +import pyransac3d as pyrsc """ parametres du noeuds ROS, à mettre dans un fichier de config a la fin""" basic_limit_for_reflexions = 12 @@ -42,6 +43,12 @@ class PointCloudProcessingNode(Node): def __init__(self): """PointCloudProcessingNode class constructor.""" super().__init__('point_cloud_processing_node') + self.xinf = -100000 + self.xsup = 100000 + self.x1 = -100000 + self.x2 = 100000 + self.y1 = -100000 + self.y2 = 100000 def load_scan(self,fileName): data = np.squeeze(np.load(fileName)) @@ -53,13 +60,7 @@ def load_scan(self,fileName): data[i,j,1] = i*0.3 return data - def decimate_point_cloud(self,inputPointCloud,decimationRate): - shapes = inputPointCloud.shape - interPointCloud = self.flatten_point_cloud(inputPointCloud) - indexList = [i for i in range(0,interPointCloud.shape[0])] - deletedElementsIndex = random.sample(indexList,int(len(indexList)*decimationRate)) - outputPointCloud = np.delete(interPointCloud, deletedElementsIndex,axis=0) - return outputPointCloud + def flatten_point_cloud(self,inputPointCloud): if len(inputPointCloud.shape) == 2: @@ -68,16 +69,25 @@ def flatten_point_cloud(self,inputPointCloud): outputPointCloud = np.reshape(inputPointCloud,(inputPointCloud.shape[0]*inputPointCloud.shape[1],inputPointCloud.shape[2])) return outputPointCloud - def filter_point_cloud(self,inputPointCloud): + def remove_non_used_plate_points(self,inputPointCloud): treatedPointCloud = self.remove_inf_value(inputPointCloud) shapes = treatedPointCloud.shape savedPoints = [] for i in range(0,shapes[0]): - if treatedPointCloud[i,0]>self.filter_coordinates[0][0] and treatedPointCloud[i,0]self.filter_coordinates[0][1] and treatedPointCloud[i,1]self.xinf and treatedPointCloud[i,0]self.x1 and treatedPointCloud[i,0]self.y1 and treatedPointCloud[i,1] 0: + best_eq[3] = -best_eq[3] + + if best_eq[2]<0: + self.rotation_matrix[2,0] = -best_eq[0] + self.rotation_matrix[2,1] = -best_eq[1] + self.rotation_matrix[2,2] = -best_eq[2] + self.translation_matrix[2] = best_eq[3] + self.zVector = best_eq[0:3] + self.zVector[0] = -self.zVector[0] + self.zVector[1] = -self.zVector[1] + self.zVector[2] = -self.zVector[2] + else: + self.rotation_matrix[2,0] = best_eq[0] + self.rotation_matrix[2,1] = best_eq[1] + self.rotation_matrix[2,2] = best_eq[2] + self.translation_matrix[2] = best_eq[3] + self.zVector = best_eq[0:3] + + self.xVector = plate_point_cloud[10,:]-plate_point_cloud[0,:] + self.xVector /= np.sqrt(self.xVector[0]**2+self.xVector[1]**2+self.xVector[2]**2) + + self.yVector = [0, 0, 0] + + self.yVector[0] = self.zVector[1]*self.xVector[2] - self.zVector[2]*self.xVector[1] + self.yVector[1] = self.zVector[2]*self.xVector[0] - self.zVector[0]*self.xVector[2] + self.yVector[2] = self.zVector[0]*self.xVector[1] - self.zVector[1]*self.xVector[0] + + self.rotation_matrix[0,0] = self.xVector[0] + self.rotation_matrix[0,1] = self.xVector[1] + self.rotation_matrix[0,2] = self.xVector[2] + + self.rotation_matrix[1,0] = self.yVector[0] + self.rotation_matrix[1,1] = self.yVector[1] + self.rotation_matrix[1,2] = self.yVector[2] + + return 0 + + def tranform_point_cloud(self,inputPointCloud): + outputPointCloud = np.zeros(inputPointCloud.shape) + + inputShape = inputPointCloud.shape + for i in range(0,inputShape[0]): + outputPointCloud[i,:] = np.dot(self.rotation_matrix, inputPointCloud[i,:]) - self.translation_matrix + + return outputPointCloud + + def decimate_point_cloud(self,inputPointCloud,decimationRate): + shapes = inputPointCloud.shape + interPointCloud = self.flatten_point_cloud(inputPointCloud) + indexList = [i for i in range(0,interPointCloud.shape[0])] + deletedElementsIndex = random.sample(indexList,int(len(indexList)*decimationRate)) + outputPointCloud = np.delete(interPointCloud, deletedElementsIndex,axis=0) + return outputPointCloud + + def ask_for_plate_limits(self,inputPointCloud): + data = self.remove_inf_value(inputPointCloud) + data = self.decimate_point_cloud(data, 0.95) + x = data[:,0] + y = data[:,1] + z = data[:,2] + fig = plt.figure(figsize=(8, 8)) + ax = fig.add_subplot(111,aspect='equal') + im = ax.scatter(x, y, c=z,s=1) + plt.xlabel('x (mm)') + plt.ylabel('y (mm)') + fig.colorbar(im) + ax.set_xlim(min(x)-10, max(x)+10) + ax.set_ylim(min(y)-10, max(y)+10) + cid = fig.canvas.mpl_connect('button_press_event', onclick) + plt.show() + global coords + self.xinf = coords[0][0] + self.xsup = coords[1][0] + self.get_logger().info("xinf : "+str(self.xinf)) + self.get_logger().info("xsup : "+str(self.xsup)) + coords = [] + return 0 - def ask_for_limits(self,inputPointCloud): + def ask_for_points_of_plate(self,inputPointCloud): data = self.remove_inf_value(inputPointCloud) data = self.decimate_point_cloud(data, 0.95) x = data[:,0] @@ -124,7 +239,14 @@ def ask_for_limits(self,inputPointCloud): cid = fig.canvas.mpl_connect('button_press_event', onclick) plt.show() global coords - self.filter_coordinates = coords + self.x1 = coords[0][0] + self.x2 = coords[1][0] + self.y1 = coords[0][1] + self.y2 = coords[1][1] + self.get_logger().info("x1 : "+str(self.x1)) + self.get_logger().info("x2 : "+str(self.x2)) + self.get_logger().info("y1 : "+str(self.y1)) + self.get_logger().info("y2 : "+str(self.y2)) coords = [] return 0 @@ -134,7 +256,27 @@ def extract_reference_base_change(self): if __name__ == '__main__': rclpy.init() point_cloud_processing_node = PointCloudProcessingNode() - scan = point_cloud_processing_node.load_scan("/home/gulltor/Ramsai_Robotics/history/impression_base_avec_retraction_20_pourcents/scan/layer_scan_4.npy") - point_cloud_processing_node.ask_for_limits(scan) - filtered_scan = point_cloud_processing_node.filter_point_cloud(scan) + reference_layer = point_cloud_processing_node.load_scan("/home/gulltor/Ramsai_Robotics/history/impression_base_avec_retraction_20_pourcents/scan/layer_scan_0.npy") + layer_3 = point_cloud_processing_node.load_scan("/home/gulltor/Ramsai_Robotics/history/impression_base_avec_retraction_20_pourcents/scan/layer_scan_3.npy") + layer_3 = point_cloud_processing_node.remove_value_above(layer_3, -70) + + #point_cloud_processing_node.ask_for_plate_limits(layer_3) + point_cloud_processing_node.xinf = -40.311554355006095 + point_cloud_processing_node.xsup = 4 + filtered_scan = point_cloud_processing_node.remove_non_used_plate_points(layer_3) + reference_layer_filtered = point_cloud_processing_node.remove_non_used_plate_points(reference_layer) + point_cloud_processing_node.transformation_creation(reference_layer_filtered) + layer_3_transformed = point_cloud_processing_node.tranform_point_cloud(filtered_scan) + point_cloud_processing_node.plot_point_cloud(layer_3_transformed) + """ + point_cloud_processing_node.ask_for_points_of_plate(filtered_scan) + layer_points = point_cloud_processing_node.select_layer_points(filtered_scan) + point_cloud_processing_node.barycentre_calculation(layer_points) + point_cloud_processing_node.plot_point_cloud(layer_points) + point_cloud_list = [None]*122 + for i in range(0,122): + point_cloud_list[i] = point_cloud_processing_node.load_scan('/home/gulltor/Ramsai_Robotics/history/impression_base_avec_retraction_20_pourcents/scan/layer_scan_'+str(i)+'.npy') + point_cloud_list[i] = point_cloud_processing_node.remove_non_used_plate_points(point_cloud_list[i]) + point_cloud_processing_node.get_logger().info('layer : '+str(i)) + """ rclpy.shutdown() From c793a58b3534bfe18443a14f87f5ddd6e83a8e5d Mon Sep 17 00:00:00 2001 From: MosserLoic Date: Mon, 6 May 2024 16:21:54 +0200 Subject: [PATCH 30/30] Readme update + pointcloud processing --- .../nodes/point_cloud_processing_node.py | 97 ++++++++++++++++--- README.md | 62 ++++++++++++ 2 files changed, 146 insertions(+), 13 deletions(-) diff --git a/3D_printer/src/printer3d_pointCloud_processing/nodes/point_cloud_processing_node.py b/3D_printer/src/printer3d_pointCloud_processing/nodes/point_cloud_processing_node.py index 5a041f7..fd2c980 100755 --- a/3D_printer/src/printer3d_pointCloud_processing/nodes/point_cloud_processing_node.py +++ b/3D_printer/src/printer3d_pointCloud_processing/nodes/point_cloud_processing_node.py @@ -22,6 +22,7 @@ import matplotlib as mpl import random import pyransac3d as pyrsc +from math import sqrt """ parametres du noeuds ROS, à mettre dans un fichier de config a la fin""" basic_limit_for_reflexions = 12 @@ -60,8 +61,6 @@ def load_scan(self,fileName): data[i,j,1] = i*0.3 return data - - def flatten_point_cloud(self,inputPointCloud): if len(inputPointCloud.shape) == 2: outputPointCloud = inputPointCloud @@ -79,16 +78,69 @@ def remove_non_used_plate_points(self,inputPointCloud): savedPoints = np.array(savedPoints) return savedPoints - def select_layer_points(self,inputPointCloud): + def find_layer_barycentre(self, inputPointCloud, epsilon): + treatedPointCloud = self.remove_inf_value(inputPointCloud) shapes = treatedPointCloud.shape savedPoints = [] + for i in range(0,shapes[0]): if treatedPointCloud[i,0]>self.x1 and treatedPointCloud[i,0]self.y1 and treatedPointCloud[i,1]zMoy-epsilon and treatedPointCloud[i,2] xDomain[0] \ + and treatedPointCloud[i,0] < xDomain[1] \ + and treatedPointCloud[i,1] > yDomain[0] \ + and treatedPointCloud[i,1] < yDomain[1]: + savedPoints.append(treatedPointCloud[i,:]) + savedPoints = np.array(savedPoints) return savedPoints + def get_Mj(self,layerPointCloud, layerNumber, layerHeight): + shapes = layerPointCloud.shape + Mj = 0 + for i in range(0,shapes[0]): + Mj += layerPointCloud[i,2] + return (Mj/shapes[0])-(layerHeight*layerNumber) + + def get_Sj(self,layerPointCloud,Mj): + shapes = layerPointCloud.shape + Sj = 0 + for i in range(0,shapes[0]): + Sj += (layerPointCloud[i,2]-Mj)**2 + Sj /= shapes[0] + return sqrt(Sj) + def remove_inf_value(self,inputPointCloud): inputPointCloud = self.flatten_point_cloud(inputPointCloud) shapes = inputPointCloud.shape @@ -183,11 +235,9 @@ def transformation_creation(self,plate_point_cloud): def tranform_point_cloud(self,inputPointCloud): outputPointCloud = np.zeros(inputPointCloud.shape) - inputShape = inputPointCloud.shape for i in range(0,inputShape[0]): outputPointCloud[i,:] = np.dot(self.rotation_matrix, inputPointCloud[i,:]) - self.translation_matrix - return outputPointCloud def decimate_point_cloud(self,inputPointCloud,decimationRate): @@ -263,20 +313,41 @@ def extract_reference_base_change(self): #point_cloud_processing_node.ask_for_plate_limits(layer_3) point_cloud_processing_node.xinf = -40.311554355006095 point_cloud_processing_node.xsup = 4 - filtered_scan = point_cloud_processing_node.remove_non_used_plate_points(layer_3) - reference_layer_filtered = point_cloud_processing_node.remove_non_used_plate_points(reference_layer) + + filtered_scan = point_cloud_processing_node.remove_non_used_plate_points(layer_3) + + reference_layer_filtered = point_cloud_processing_node.remove_non_used_plate_points(reference_layer) + point_cloud_processing_node.transformation_creation(reference_layer_filtered) - layer_3_transformed = point_cloud_processing_node.tranform_point_cloud(filtered_scan) + + layer_3_transformed = point_cloud_processing_node.tranform_point_cloud(filtered_scan) + point_cloud_processing_node.plot_point_cloud(layer_3_transformed) - """ + point_cloud_processing_node.ask_for_points_of_plate(filtered_scan) - layer_points = point_cloud_processing_node.select_layer_points(filtered_scan) - point_cloud_processing_node.barycentre_calculation(layer_points) - point_cloud_processing_node.plot_point_cloud(layer_points) + [xg, yg] = point_cloud_processing_node.find_layer_barycentre(filtered_scan, 0.04) + print("( ",xg," , ",yg," )") + + point_cloud_list = [None]*122 + Mj = [None]*122 + Sj = [None]*122 + for i in range(0,122): point_cloud_list[i] = point_cloud_processing_node.load_scan('/home/gulltor/Ramsai_Robotics/history/impression_base_avec_retraction_20_pourcents/scan/layer_scan_'+str(i)+'.npy') point_cloud_list[i] = point_cloud_processing_node.remove_non_used_plate_points(point_cloud_list[i]) + point_cloud_list[i] = point_cloud_processing_node.select_points_of_layer(point_cloud_list[i], [xg-7, xg+7], [yg-7, yg+7]) + Mj[i] = point_cloud_processing_node.get_Mj(point_cloud_list[i], i, 0.41) + Sj[i] = point_cloud_processing_node.get_Sj(point_cloud_list[i],Mj[i]) point_cloud_processing_node.get_logger().info('layer : '+str(i)) - """ + + plt.figure() + plt.plot(Mj) + plt.show() + + plt.figure() + plt.plot(Sj) + plt.show() + + rclpy.shutdown() diff --git a/README.md b/README.md index beee04b..a641071 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,64 @@ # RAMSAI Github repository for the ANR RAMSAI project. + +# ROS2 keyence communication interface +## printer3d_keyence_profile_capture +This interface have been developped with ROS2 to propose a standard interface with Keyence LJ-X profilometer. It has been coded using Python language and integrates the python software delivered by Keyence to manage the communication with the profilometer. + +The software developped by Keyence have been initialy coded using C++. The python library implements a wrapper of this C++ library and load dynamic library (libljxacom.so in linux) and (LJX8_IF.dll in windows) + +Therefore, to have this package working, you need to get this external library and to put in the **./src/printer3d_keyence_profile_capture/src/driver** folder as shown in this file path description: + +``` +├── src +│ ├── printer3d_keyence_profile_capture +│ │ ├── src +│ │ | ├── driver +│ │ | ├── nodes +│ │ ├── launch +│ │ ├── config +│ │ ├── CMakeLists.txt +│ │ ├── LICENSE +│ │ ├── package.xml +│ ├── printer3d_keyence_msgs +│ ├── printer3d_keyence_profile_service_caller +├── README.md +└── .gitignore +``` + +The external library is composed of the following folders and files : + +``` +├── driver +│ ├── include +│ │ ├── LJX8_ErrorCode.h +│ │ ├── LJX8_IF_Linux.h +│ │ ├── LJXA_ACQ.h +│ ├── libsrc +│ │ ├── LJX8_IF_Linux.cpp +│ │ ├── LJXA_ACQ.cpp +│ │ ├── ProfileDataConvert.cpp +│ │ ├── ProfileDataConvert.h +│ ├── PYTHON +│ │ ├── libljxacom.so +│ │ ├── LJX8_IF.dll +│ │ ├── LJXAwrap.py +│ │ ├── Makefile +├── nodes +``` + +Once those files have been added to the **./src/printer3d_keyence_profile_capture/src/driver** folder. Open a terminal in the **./src/printer3d_keyence_profile_capture/src/driver/PYTHON** folder and make: + +``` +cd ./src/printer3d_keyence_profile_capture/src/driver/PYTHON +make +cd ../../../../../ +``` + +Once this initialisation have been done. Build the complete package and launch the service demonstrator node: + +``` +colcon build +source install/setup.bash +ros2 launch ./src/printer3d_keyence_profile_service_caller/launch/launch_keyence_commands.py +```