diff --git a/example_1/CMakeLists.txt b/example_1/CMakeLists.txt
index ef7ca3ecd..12496b88c 100644
--- a/example_1/CMakeLists.txt
+++ b/example_1/CMakeLists.txt
@@ -64,9 +64,13 @@ install(TARGETS ros2_control_demo_example_1
)
if(BUILD_TESTING)
- find_package(ament_cmake_gtest REQUIRED)
+ find_package(ament_cmake_pytest REQUIRED)
+
+ ament_add_pytest_test(example_1_urdf_xacro test/test_urdf_xacro.py)
+ ament_add_pytest_test(view_example_1_launch test/test_view_robot_launch.py)
endif()
+
## EXPORTS
ament_export_targets(export_ros2_control_demo_example_1 HAS_LIBRARY_TARGET)
ament_export_dependencies(${THIS_PACKAGE_INCLUDE_DEPENDS})
diff --git a/example_1/package.xml b/example_1/package.xml
index 8513ca3ee..141351687 100644
--- a/example_1/package.xml
+++ b/example_1/package.xml
@@ -33,7 +33,11 @@
rviz2
xacro
- ament_cmake_gtest
+ ament_cmake_pytest
+ launch_testing_ament_cmake
+ launch_testing_ros
+ liburdfdom-tools
+ xacro
ament_cmake
diff --git a/example_1/test/test_urdf_xacro.py b/example_1/test/test_urdf_xacro.py
new file mode 100644
index 000000000..03d9a5a3c
--- /dev/null
+++ b/example_1/test/test_urdf_xacro.py
@@ -0,0 +1,77 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import shutil
+import subprocess
+import tempfile
+
+from ament_index_python.packages import get_package_share_directory
+
+
+def test_urdf_xacro():
+ # General Arguments
+ description_package = "ros2_control_demo_example_1"
+ description_file = "rrbot.urdf.xacro"
+
+ description_file_path = os.path.join(
+ get_package_share_directory(description_package), "urdf", description_file
+ )
+
+ (_, tmp_urdf_output_file) = tempfile.mkstemp(suffix=".urdf")
+
+ # Compose `xacro` and `check_urdf` command
+ xacro_command = (
+ f"{shutil.which('xacro')}" f" {description_file_path}" f" > {tmp_urdf_output_file}"
+ )
+ check_urdf_command = f"{shutil.which('check_urdf')} {tmp_urdf_output_file}"
+
+ # Try to call processes but finally remove the temp file
+ try:
+ xacro_process = subprocess.run(
+ xacro_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert xacro_process.returncode == 0, " --- XACRO command failed ---"
+
+ check_urdf_process = subprocess.run(
+ check_urdf_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert (
+ check_urdf_process.returncode == 0
+ ), "\n --- URDF check failed! --- \nYour xacro does not unfold into a proper urdf robot description. Please check your xacro file."
+
+ finally:
+ os.remove(tmp_urdf_output_file)
+
+
+if __name__ == "__main__":
+ test_urdf_xacro()
diff --git a/example_1/test/test_view_robot_launch.py b/example_1/test/test_view_robot_launch.py
new file mode 100644
index 000000000..62cf83e68
--- /dev/null
+++ b/example_1/test/test_view_robot_launch.py
@@ -0,0 +1,54 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import pytest
+
+from ament_index_python.packages import get_package_share_directory
+from launch import LaunchDescription
+from launch.actions import IncludeLaunchDescription
+from launch.launch_description_sources import PythonLaunchDescriptionSource
+from launch_testing.actions import ReadyToTest
+
+
+# Executes the given launch file and checks if all nodes can be started
+@pytest.mark.rostest
+def generate_test_description():
+ launch_include = IncludeLaunchDescription(
+ PythonLaunchDescriptionSource(
+ os.path.join(
+ get_package_share_directory("ros2_control_demo_example_1"),
+ "launch/view_robot.launch.py",
+ )
+ ),
+ launch_arguments={"gui": "true"}.items(),
+ )
+
+ return LaunchDescription([launch_include, ReadyToTest()])
diff --git a/example_10/CMakeLists.txt b/example_10/CMakeLists.txt
index e2e4dd0d1..1b9079345 100644
--- a/example_10/CMakeLists.txt
+++ b/example_10/CMakeLists.txt
@@ -75,7 +75,10 @@ install(TARGETS ros2_control_demo_example_10
)
if(BUILD_TESTING)
- find_package(ament_cmake_gtest REQUIRED)
+ find_package(ament_cmake_pytest REQUIRED)
+
+ ament_add_pytest_test(example_10_urdf_xacro test/test_urdf_xacro.py)
+ ament_add_pytest_test(view_example_10_launch test/test_view_robot_launch.py)
endif()
## EXPORTS
diff --git a/example_10/package.xml b/example_10/package.xml
index d1a211eb7..e94c0a1e2 100644
--- a/example_10/package.xml
+++ b/example_10/package.xml
@@ -33,6 +33,11 @@
xacro
ament_cmake_gtest
+ ament_cmake_pytest
+ launch_testing_ament_cmake
+ launch_testing_ros
+ liburdfdom-tools
+ xacro
ament_cmake
diff --git a/example_10/test/test_urdf_xacro.py b/example_10/test/test_urdf_xacro.py
new file mode 100644
index 000000000..cc483532a
--- /dev/null
+++ b/example_10/test/test_urdf_xacro.py
@@ -0,0 +1,77 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import shutil
+import subprocess
+import tempfile
+
+from ament_index_python.packages import get_package_share_directory
+
+
+def test_urdf_xacro():
+ # General Arguments
+ description_package = "ros2_control_demo_example_10"
+ description_file = "rrbot.urdf.xacro"
+
+ description_file_path = os.path.join(
+ get_package_share_directory(description_package), "urdf", description_file
+ )
+
+ (_, tmp_urdf_output_file) = tempfile.mkstemp(suffix=".urdf")
+
+ # Compose `xacro` and `check_urdf` command
+ xacro_command = (
+ f"{shutil.which('xacro')}" f" {description_file_path}" f" > {tmp_urdf_output_file}"
+ )
+ check_urdf_command = f"{shutil.which('check_urdf')} {tmp_urdf_output_file}"
+
+ # Try to call processes but finally remove the temp file
+ try:
+ xacro_process = subprocess.run(
+ xacro_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert xacro_process.returncode == 0, " --- XACRO command failed ---"
+
+ check_urdf_process = subprocess.run(
+ check_urdf_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert (
+ check_urdf_process.returncode == 0
+ ), "\n --- URDF check failed! --- \nYour xacro does not unfold into a proper urdf robot description. Please check your xacro file."
+
+ finally:
+ os.remove(tmp_urdf_output_file)
+
+
+if __name__ == "__main__":
+ test_urdf_xacro()
diff --git a/example_10/test/test_view_robot_launch.py b/example_10/test/test_view_robot_launch.py
new file mode 100644
index 000000000..a2c067d31
--- /dev/null
+++ b/example_10/test/test_view_robot_launch.py
@@ -0,0 +1,54 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import pytest
+
+from ament_index_python.packages import get_package_share_directory
+from launch import LaunchDescription
+from launch.actions import IncludeLaunchDescription
+from launch.launch_description_sources import PythonLaunchDescriptionSource
+from launch_testing.actions import ReadyToTest
+
+
+# Executes the given launch file and checks if all nodes can be started
+@pytest.mark.rostest
+def generate_test_description():
+ launch_include = IncludeLaunchDescription(
+ PythonLaunchDescriptionSource(
+ os.path.join(
+ get_package_share_directory("ros2_control_demo_example_10"),
+ "launch/view_robot.launch.py",
+ )
+ ),
+ launch_arguments={"gui": "true"}.items(),
+ )
+
+ return LaunchDescription([launch_include, ReadyToTest()])
diff --git a/example_12/CMakeLists.txt b/example_12/CMakeLists.txt
index 63a2474bd..b5e6a53c5 100644
--- a/example_12/CMakeLists.txt
+++ b/example_12/CMakeLists.txt
@@ -105,7 +105,10 @@ install(TARGETS
)
if(BUILD_TESTING)
- find_package(ament_cmake_gtest REQUIRED)
+ find_package(ament_cmake_pytest REQUIRED)
+
+ ament_add_pytest_test(example_12_urdf_xacro test/test_urdf_xacro.py)
+ ament_add_pytest_test(view_example_12_launch test/test_view_robot_launch.py)
endif()
## EXPORTS
diff --git a/example_12/package.xml b/example_12/package.xml
index 4bd54219f..d14418cd9 100644
--- a/example_12/package.xml
+++ b/example_12/package.xml
@@ -29,12 +29,18 @@
joint_state_publisher_gui
joint_trajectory_controller
robot_state_publisher
+ ros2_control_demo_description
ros2_controllers_test_nodes
ros2controlcli
rviz2
xacro
ament_cmake_gtest
+ ament_cmake_pytest
+ launch_testing_ament_cmake
+ launch_testing_ros
+ liburdfdom-tools
+ xacro
ament_cmake
diff --git a/example_12/test/test_urdf_xacro.py b/example_12/test/test_urdf_xacro.py
new file mode 100644
index 000000000..1f9f486d4
--- /dev/null
+++ b/example_12/test/test_urdf_xacro.py
@@ -0,0 +1,77 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import shutil
+import subprocess
+import tempfile
+
+from ament_index_python.packages import get_package_share_directory
+
+
+def test_urdf_xacro():
+ # General Arguments
+ description_package = "ros2_control_demo_example_12"
+ description_file = "rrbot.urdf.xacro"
+
+ description_file_path = os.path.join(
+ get_package_share_directory(description_package), "urdf", description_file
+ )
+
+ (_, tmp_urdf_output_file) = tempfile.mkstemp(suffix=".urdf")
+
+ # Compose `xacro` and `check_urdf` command
+ xacro_command = (
+ f"{shutil.which('xacro')}" f" {description_file_path}" f" > {tmp_urdf_output_file}"
+ )
+ check_urdf_command = f"{shutil.which('check_urdf')} {tmp_urdf_output_file}"
+
+ # Try to call processes but finally remove the temp file
+ try:
+ xacro_process = subprocess.run(
+ xacro_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert xacro_process.returncode == 0, " --- XACRO command failed ---"
+
+ check_urdf_process = subprocess.run(
+ check_urdf_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert (
+ check_urdf_process.returncode == 0
+ ), "\n --- URDF check failed! --- \nYour xacro does not unfold into a proper urdf robot description. Please check your xacro file."
+
+ finally:
+ os.remove(tmp_urdf_output_file)
+
+
+if __name__ == "__main__":
+ test_urdf_xacro()
diff --git a/example_12/test/test_view_robot_launch.py b/example_12/test/test_view_robot_launch.py
new file mode 100644
index 000000000..7861b479a
--- /dev/null
+++ b/example_12/test/test_view_robot_launch.py
@@ -0,0 +1,54 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import pytest
+
+from ament_index_python.packages import get_package_share_directory
+from launch import LaunchDescription
+from launch.actions import IncludeLaunchDescription
+from launch.launch_description_sources import PythonLaunchDescriptionSource
+from launch_testing.actions import ReadyToTest
+
+
+# Executes the given launch file and checks if all nodes can be started
+@pytest.mark.rostest
+def generate_test_description():
+ launch_include = IncludeLaunchDescription(
+ PythonLaunchDescriptionSource(
+ os.path.join(
+ get_package_share_directory("ros2_control_demo_example_12"),
+ "launch/view_robot.launch.py",
+ )
+ ),
+ launch_arguments={"gui": "true"}.items(),
+ )
+
+ return LaunchDescription([launch_include, ReadyToTest()])
diff --git a/example_14/package.xml b/example_14/package.xml
index 2ec771b44..3b52728ab 100644
--- a/example_14/package.xml
+++ b/example_14/package.xml
@@ -31,6 +31,11 @@
xacro
ament_cmake_gtest
+ ament_cmake_pytest
+ launch_testing_ament_cmake
+ launch_testing_ros
+ liburdfdom-tools
+ xacro
ament_cmake
diff --git a/example_14/test/test_urdf_xacro.py b/example_14/test/test_urdf_xacro.py
new file mode 100644
index 000000000..60d784a7e
--- /dev/null
+++ b/example_14/test/test_urdf_xacro.py
@@ -0,0 +1,77 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import shutil
+import subprocess
+import tempfile
+
+from ament_index_python.packages import get_package_share_directory
+
+
+def test_urdf_xacro():
+ # General Arguments
+ description_package = "ros2_control_demo_example_14"
+ description_file = "rrbot.urdf.xacro"
+
+ description_file_path = os.path.join(
+ get_package_share_directory(description_package), "urdf", description_file
+ )
+
+ (_, tmp_urdf_output_file) = tempfile.mkstemp(suffix=".urdf")
+
+ # Compose `xacro` and `check_urdf` command
+ xacro_command = (
+ f"{shutil.which('xacro')}" f" {description_file_path}" f" > {tmp_urdf_output_file}"
+ )
+ check_urdf_command = f"{shutil.which('check_urdf')} {tmp_urdf_output_file}"
+
+ # Try to call processes but finally remove the temp file
+ try:
+ xacro_process = subprocess.run(
+ xacro_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert xacro_process.returncode == 0, " --- XACRO command failed ---"
+
+ check_urdf_process = subprocess.run(
+ check_urdf_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert (
+ check_urdf_process.returncode == 0
+ ), "\n --- URDF check failed! --- \nYour xacro does not unfold into a proper urdf robot description. Please check your xacro file."
+
+ finally:
+ os.remove(tmp_urdf_output_file)
+
+
+if __name__ == "__main__":
+ test_urdf_xacro()
diff --git a/example_14/test/test_view_robot_launch.py b/example_14/test/test_view_robot_launch.py
new file mode 100644
index 000000000..2f8e7a5ff
--- /dev/null
+++ b/example_14/test/test_view_robot_launch.py
@@ -0,0 +1,54 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import pytest
+
+from ament_index_python.packages import get_package_share_directory
+from launch import LaunchDescription
+from launch.actions import IncludeLaunchDescription
+from launch.launch_description_sources import PythonLaunchDescriptionSource
+from launch_testing.actions import ReadyToTest
+
+
+# Executes the given launch file and checks if all nodes can be started
+@pytest.mark.rostest
+def generate_test_description():
+ launch_include = IncludeLaunchDescription(
+ PythonLaunchDescriptionSource(
+ os.path.join(
+ get_package_share_directory("ros2_control_demo_example_14"),
+ "launch/view_robot.launch.py",
+ )
+ ),
+ launch_arguments={"gui": "true"}.items(),
+ )
+
+ return LaunchDescription([launch_include, ReadyToTest()])
diff --git a/example_2/CMakeLists.txt b/example_2/CMakeLists.txt
index 1c06f9166..cd19457e6 100644
--- a/example_2/CMakeLists.txt
+++ b/example_2/CMakeLists.txt
@@ -64,7 +64,10 @@ install(TARGETS ros2_control_demo_example_2
)
if(BUILD_TESTING)
- find_package(ament_cmake_gtest REQUIRED)
+ find_package(ament_cmake_pytest REQUIRED)
+
+ ament_add_pytest_test(example_2_urdf_xacro test/test_urdf_xacro.py)
+ ament_add_pytest_test(view_example_2_launch test/test_view_robot_launch.py)
endif()
## EXPORTS
diff --git a/example_2/package.xml b/example_2/package.xml
index ce70fa0b5..ef767ca3f 100644
--- a/example_2/package.xml
+++ b/example_2/package.xml
@@ -33,6 +33,11 @@
xacro
ament_cmake_gtest
+ ament_cmake_pytest
+ launch_testing_ament_cmake
+ launch_testing_ros
+ liburdfdom-tools
+ xacro
ament_cmake
diff --git a/example_2/test/test_urdf_xacro.py b/example_2/test/test_urdf_xacro.py
new file mode 100644
index 000000000..205e2635d
--- /dev/null
+++ b/example_2/test/test_urdf_xacro.py
@@ -0,0 +1,77 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import shutil
+import subprocess
+import tempfile
+
+from ament_index_python.packages import get_package_share_directory
+
+
+def test_urdf_xacro():
+ # General Arguments
+ description_package = "ros2_control_demo_example_2"
+ description_file = "diffbot.urdf.xacro"
+
+ description_file_path = os.path.join(
+ get_package_share_directory(description_package), "urdf", description_file
+ )
+
+ (_, tmp_urdf_output_file) = tempfile.mkstemp(suffix=".urdf")
+
+ # Compose `xacro` and `check_urdf` command
+ xacro_command = (
+ f"{shutil.which('xacro')}" f" {description_file_path}" f" > {tmp_urdf_output_file}"
+ )
+ check_urdf_command = f"{shutil.which('check_urdf')} {tmp_urdf_output_file}"
+
+ # Try to call processes but finally remove the temp file
+ try:
+ xacro_process = subprocess.run(
+ xacro_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert xacro_process.returncode == 0, " --- XACRO command failed ---"
+
+ check_urdf_process = subprocess.run(
+ check_urdf_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert (
+ check_urdf_process.returncode == 0
+ ), "\n --- URDF check failed! --- \nYour xacro does not unfold into a proper urdf robot description. Please check your xacro file."
+
+ finally:
+ os.remove(tmp_urdf_output_file)
+
+
+if __name__ == "__main__":
+ test_urdf_xacro()
diff --git a/example_2/test/test_view_robot_launch.py b/example_2/test/test_view_robot_launch.py
new file mode 100644
index 000000000..7b835cc30
--- /dev/null
+++ b/example_2/test/test_view_robot_launch.py
@@ -0,0 +1,54 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import pytest
+
+from ament_index_python.packages import get_package_share_directory
+from launch import LaunchDescription
+from launch.actions import IncludeLaunchDescription
+from launch.launch_description_sources import PythonLaunchDescriptionSource
+from launch_testing.actions import ReadyToTest
+
+
+# Executes the given launch file and checks if all nodes can be started
+@pytest.mark.rostest
+def generate_test_description():
+ launch_include = IncludeLaunchDescription(
+ PythonLaunchDescriptionSource(
+ os.path.join(
+ get_package_share_directory("ros2_control_demo_example_2"),
+ "launch/view_robot.launch.py",
+ )
+ ),
+ launch_arguments={"gui": "true"}.items(),
+ )
+
+ return LaunchDescription([launch_include, ReadyToTest()])
diff --git a/example_3/CMakeLists.txt b/example_3/CMakeLists.txt
index 55751e921..a48a3121f 100644
--- a/example_3/CMakeLists.txt
+++ b/example_3/CMakeLists.txt
@@ -64,7 +64,10 @@ install(TARGETS ros2_control_demo_example_3
)
if(BUILD_TESTING)
- find_package(ament_cmake_gtest REQUIRED)
+ find_package(ament_cmake_pytest REQUIRED)
+
+ ament_add_pytest_test(example_3_urdf_xacro test/test_urdf_xacro.py)
+ ament_add_pytest_test(view_example_3_launch test/test_view_robot_launch.py)
endif()
## EXPORTS
diff --git a/example_3/package.xml b/example_3/package.xml
index cb613e306..3c0a21687 100644
--- a/example_3/package.xml
+++ b/example_3/package.xml
@@ -31,6 +31,11 @@
xacro
ament_cmake_gtest
+ ament_cmake_pytest
+ launch_testing_ament_cmake
+ launch_testing_ros
+ liburdfdom-tools
+ xacro
ament_cmake
diff --git a/example_3/test/test_urdf_xacro.py b/example_3/test/test_urdf_xacro.py
new file mode 100644
index 000000000..d0cf5f2ec
--- /dev/null
+++ b/example_3/test/test_urdf_xacro.py
@@ -0,0 +1,77 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import shutil
+import subprocess
+import tempfile
+
+from ament_index_python.packages import get_package_share_directory
+
+
+def test_urdf_xacro():
+ # General Arguments
+ description_package = "ros2_control_demo_example_3"
+ description_file = "rrbot_system_multi_interface.urdf.xacro"
+
+ description_file_path = os.path.join(
+ get_package_share_directory(description_package), "urdf", description_file
+ )
+
+ (_, tmp_urdf_output_file) = tempfile.mkstemp(suffix=".urdf")
+
+ # Compose `xacro` and `check_urdf` command
+ xacro_command = (
+ f"{shutil.which('xacro')}" f" {description_file_path}" f" > {tmp_urdf_output_file}"
+ )
+ check_urdf_command = f"{shutil.which('check_urdf')} {tmp_urdf_output_file}"
+
+ # Try to call processes but finally remove the temp file
+ try:
+ xacro_process = subprocess.run(
+ xacro_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert xacro_process.returncode == 0, " --- XACRO command failed ---"
+
+ check_urdf_process = subprocess.run(
+ check_urdf_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert (
+ check_urdf_process.returncode == 0
+ ), "\n --- URDF check failed! --- \nYour xacro does not unfold into a proper urdf robot description. Please check your xacro file."
+
+ finally:
+ os.remove(tmp_urdf_output_file)
+
+
+if __name__ == "__main__":
+ test_urdf_xacro()
diff --git a/example_3/test/test_view_robot_launch.py b/example_3/test/test_view_robot_launch.py
new file mode 100644
index 000000000..7cc6ebf5c
--- /dev/null
+++ b/example_3/test/test_view_robot_launch.py
@@ -0,0 +1,54 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import pytest
+
+from ament_index_python.packages import get_package_share_directory
+from launch import LaunchDescription
+from launch.actions import IncludeLaunchDescription
+from launch.launch_description_sources import PythonLaunchDescriptionSource
+from launch_testing.actions import ReadyToTest
+
+
+# Executes the given launch file and checks if all nodes can be started
+@pytest.mark.rostest
+def generate_test_description():
+ launch_include = IncludeLaunchDescription(
+ PythonLaunchDescriptionSource(
+ os.path.join(
+ get_package_share_directory("ros2_control_demo_example_3"),
+ "launch/view_robot.launch.py",
+ )
+ ),
+ launch_arguments={"gui": "true"}.items(),
+ )
+
+ return LaunchDescription([launch_include, ReadyToTest()])
diff --git a/example_4/CMakeLists.txt b/example_4/CMakeLists.txt
index a56179387..b79f1e706 100644
--- a/example_4/CMakeLists.txt
+++ b/example_4/CMakeLists.txt
@@ -64,7 +64,10 @@ install(TARGETS ros2_control_demo_example_4
)
if(BUILD_TESTING)
- find_package(ament_cmake_gtest REQUIRED)
+ find_package(ament_cmake_pytest REQUIRED)
+
+ ament_add_pytest_test(example_4_urdf_xacro test/test_urdf_xacro.py)
+ ament_add_pytest_test(view_example_4_launch test/test_view_robot_launch.py)
endif()
## EXPORTS
diff --git a/example_4/package.xml b/example_4/package.xml
index 28eb1c63a..7ff6a1c2e 100644
--- a/example_4/package.xml
+++ b/example_4/package.xml
@@ -31,6 +31,11 @@
xacro
ament_cmake_gtest
+ ament_cmake_pytest
+ launch_testing_ament_cmake
+ launch_testing_ros
+ liburdfdom-tools
+ xacro
ament_cmake
diff --git a/example_4/test/test_urdf_xacro.py b/example_4/test/test_urdf_xacro.py
new file mode 100644
index 000000000..275b85437
--- /dev/null
+++ b/example_4/test/test_urdf_xacro.py
@@ -0,0 +1,77 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import shutil
+import subprocess
+import tempfile
+
+from ament_index_python.packages import get_package_share_directory
+
+
+def test_urdf_xacro():
+ # General Arguments
+ description_package = "ros2_control_demo_example_4"
+ description_file = "rrbot_system_with_sensor.urdf.xacro"
+
+ description_file_path = os.path.join(
+ get_package_share_directory(description_package), "urdf", description_file
+ )
+
+ (_, tmp_urdf_output_file) = tempfile.mkstemp(suffix=".urdf")
+
+ # Compose `xacro` and `check_urdf` command
+ xacro_command = (
+ f"{shutil.which('xacro')}" f" {description_file_path}" f" > {tmp_urdf_output_file}"
+ )
+ check_urdf_command = f"{shutil.which('check_urdf')} {tmp_urdf_output_file}"
+
+ # Try to call processes but finally remove the temp file
+ try:
+ xacro_process = subprocess.run(
+ xacro_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert xacro_process.returncode == 0, " --- XACRO command failed ---"
+
+ check_urdf_process = subprocess.run(
+ check_urdf_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert (
+ check_urdf_process.returncode == 0
+ ), "\n --- URDF check failed! --- \nYour xacro does not unfold into a proper urdf robot description. Please check your xacro file."
+
+ finally:
+ os.remove(tmp_urdf_output_file)
+
+
+if __name__ == "__main__":
+ test_urdf_xacro()
diff --git a/example_4/test/test_view_robot_launch.py b/example_4/test/test_view_robot_launch.py
new file mode 100644
index 000000000..8c2f81639
--- /dev/null
+++ b/example_4/test/test_view_robot_launch.py
@@ -0,0 +1,54 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import pytest
+
+from ament_index_python.packages import get_package_share_directory
+from launch import LaunchDescription
+from launch.actions import IncludeLaunchDescription
+from launch.launch_description_sources import PythonLaunchDescriptionSource
+from launch_testing.actions import ReadyToTest
+
+
+# Executes the given launch file and checks if all nodes can be started
+@pytest.mark.rostest
+def generate_test_description():
+ launch_include = IncludeLaunchDescription(
+ PythonLaunchDescriptionSource(
+ os.path.join(
+ get_package_share_directory("ros2_control_demo_example_4"),
+ "launch/view_robot.launch.py",
+ )
+ ),
+ launch_arguments={"gui": "true"}.items(),
+ )
+
+ return LaunchDescription([launch_include, ReadyToTest()])
diff --git a/example_5/CMakeLists.txt b/example_5/CMakeLists.txt
index 37fd35bbc..1eaa37ebd 100644
--- a/example_5/CMakeLists.txt
+++ b/example_5/CMakeLists.txt
@@ -65,7 +65,10 @@ install(TARGETS ros2_control_demo_example_5
)
if(BUILD_TESTING)
- find_package(ament_cmake_gtest REQUIRED)
+ find_package(ament_cmake_pytest REQUIRED)
+
+ ament_add_pytest_test(example_5_urdf_xacro test/test_urdf_xacro.py)
+ ament_add_pytest_test(view_example_5_launch test/test_view_robot_launch.py)
endif()
## EXPORTS
diff --git a/example_5/package.xml b/example_5/package.xml
index 062ff58d8..e22bf795f 100644
--- a/example_5/package.xml
+++ b/example_5/package.xml
@@ -31,6 +31,11 @@
xacro
ament_cmake_gtest
+ ament_cmake_pytest
+ launch_testing_ament_cmake
+ launch_testing_ros
+ liburdfdom-tools
+ xacro
ament_cmake
diff --git a/example_5/test/test_urdf_xacro.py b/example_5/test/test_urdf_xacro.py
new file mode 100644
index 000000000..85fd2c475
--- /dev/null
+++ b/example_5/test/test_urdf_xacro.py
@@ -0,0 +1,77 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import shutil
+import subprocess
+import tempfile
+
+from ament_index_python.packages import get_package_share_directory
+
+
+def test_urdf_xacro():
+ # General Arguments
+ description_package = "ros2_control_demo_example_5"
+ description_file = "rrbot_system_with_external_sensor.urdf.xacro"
+
+ description_file_path = os.path.join(
+ get_package_share_directory(description_package), "urdf", description_file
+ )
+
+ (_, tmp_urdf_output_file) = tempfile.mkstemp(suffix=".urdf")
+
+ # Compose `xacro` and `check_urdf` command
+ xacro_command = (
+ f"{shutil.which('xacro')}" f" {description_file_path}" f" > {tmp_urdf_output_file}"
+ )
+ check_urdf_command = f"{shutil.which('check_urdf')} {tmp_urdf_output_file}"
+
+ # Try to call processes but finally remove the temp file
+ try:
+ xacro_process = subprocess.run(
+ xacro_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert xacro_process.returncode == 0, " --- XACRO command failed ---"
+
+ check_urdf_process = subprocess.run(
+ check_urdf_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert (
+ check_urdf_process.returncode == 0
+ ), "\n --- URDF check failed! --- \nYour xacro does not unfold into a proper urdf robot description. Please check your xacro file."
+
+ finally:
+ os.remove(tmp_urdf_output_file)
+
+
+if __name__ == "__main__":
+ test_urdf_xacro()
diff --git a/example_5/test/test_view_robot_launch.py b/example_5/test/test_view_robot_launch.py
new file mode 100644
index 000000000..60667e710
--- /dev/null
+++ b/example_5/test/test_view_robot_launch.py
@@ -0,0 +1,54 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import pytest
+
+from ament_index_python.packages import get_package_share_directory
+from launch import LaunchDescription
+from launch.actions import IncludeLaunchDescription
+from launch.launch_description_sources import PythonLaunchDescriptionSource
+from launch_testing.actions import ReadyToTest
+
+
+# Executes the given launch file and checks if all nodes can be started
+@pytest.mark.rostest
+def generate_test_description():
+ launch_include = IncludeLaunchDescription(
+ PythonLaunchDescriptionSource(
+ os.path.join(
+ get_package_share_directory("ros2_control_demo_example_5"),
+ "launch/view_robot.launch.py",
+ )
+ ),
+ launch_arguments={"gui": "true"}.items(),
+ )
+
+ return LaunchDescription([launch_include, ReadyToTest()])
diff --git a/example_6/CMakeLists.txt b/example_6/CMakeLists.txt
index 4ed33d331..3ac52862d 100644
--- a/example_6/CMakeLists.txt
+++ b/example_6/CMakeLists.txt
@@ -64,7 +64,10 @@ install(TARGETS ros2_control_demo_example_6
)
if(BUILD_TESTING)
- find_package(ament_cmake_gtest REQUIRED)
+ find_package(ament_cmake_pytest REQUIRED)
+
+ ament_add_pytest_test(example_6_urdf_xacro test/test_urdf_xacro.py)
+ ament_add_pytest_test(view_example_6_launch test/test_view_robot_launch.py)
endif()
## EXPORTS
diff --git a/example_6/package.xml b/example_6/package.xml
index 1b89e08a2..856970fef 100644
--- a/example_6/package.xml
+++ b/example_6/package.xml
@@ -31,6 +31,11 @@
xacro
ament_cmake_gtest
+ ament_cmake_pytest
+ launch_testing_ament_cmake
+ launch_testing_ros
+ liburdfdom-tools
+ xacro
ament_cmake
diff --git a/example_6/test/test_urdf_xacro.py b/example_6/test/test_urdf_xacro.py
new file mode 100644
index 000000000..ac2703a07
--- /dev/null
+++ b/example_6/test/test_urdf_xacro.py
@@ -0,0 +1,77 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import shutil
+import subprocess
+import tempfile
+
+from ament_index_python.packages import get_package_share_directory
+
+
+def test_urdf_xacro():
+ # General Arguments
+ description_package = "ros2_control_demo_example_6"
+ description_file = "rrbot_modular_actuators.urdf.xacro"
+
+ description_file_path = os.path.join(
+ get_package_share_directory(description_package), "urdf", description_file
+ )
+
+ (_, tmp_urdf_output_file) = tempfile.mkstemp(suffix=".urdf")
+
+ # Compose `xacro` and `check_urdf` command
+ xacro_command = (
+ f"{shutil.which('xacro')}" f" {description_file_path}" f" > {tmp_urdf_output_file}"
+ )
+ check_urdf_command = f"{shutil.which('check_urdf')} {tmp_urdf_output_file}"
+
+ # Try to call processes but finally remove the temp file
+ try:
+ xacro_process = subprocess.run(
+ xacro_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert xacro_process.returncode == 0, " --- XACRO command failed ---"
+
+ check_urdf_process = subprocess.run(
+ check_urdf_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert (
+ check_urdf_process.returncode == 0
+ ), "\n --- URDF check failed! --- \nYour xacro does not unfold into a proper urdf robot description. Please check your xacro file."
+
+ finally:
+ os.remove(tmp_urdf_output_file)
+
+
+if __name__ == "__main__":
+ test_urdf_xacro()
diff --git a/example_6/test/test_view_robot_launch.py b/example_6/test/test_view_robot_launch.py
new file mode 100644
index 000000000..dc64aeeb3
--- /dev/null
+++ b/example_6/test/test_view_robot_launch.py
@@ -0,0 +1,54 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import pytest
+
+from ament_index_python.packages import get_package_share_directory
+from launch import LaunchDescription
+from launch.actions import IncludeLaunchDescription
+from launch.launch_description_sources import PythonLaunchDescriptionSource
+from launch_testing.actions import ReadyToTest
+
+
+# Executes the given launch file and checks if all nodes can be started
+@pytest.mark.rostest
+def generate_test_description():
+ launch_include = IncludeLaunchDescription(
+ PythonLaunchDescriptionSource(
+ os.path.join(
+ get_package_share_directory("ros2_control_demo_example_6"),
+ "launch/view_robot.launch.py",
+ )
+ ),
+ launch_arguments={"gui": "true"}.items(),
+ )
+
+ return LaunchDescription([launch_include, ReadyToTest()])
diff --git a/example_7/CMakeLists.txt b/example_7/CMakeLists.txt
index 713b6ef6a..16231d836 100644
--- a/example_7/CMakeLists.txt
+++ b/example_7/CMakeLists.txt
@@ -86,7 +86,6 @@ install(
DIRECTORY bringup/launch bringup/config
DESTINATION share/ros2_control_demo_example_7
)
-
install(
TARGETS send_trajectory
RUNTIME DESTINATION lib/ros2_control_demo_example_7
@@ -100,7 +99,10 @@ install(TARGETS ros2_control_demo_example_7
)
if(BUILD_TESTING)
- find_package(ament_cmake_gtest REQUIRED)
+ find_package(ament_cmake_pytest REQUIRED)
+
+ ament_add_pytest_test(example_7_urdf_xacro test/test_urdf_xacro.py)
+ ament_add_pytest_test(view_example_7_launch test/test_view_robot_launch.py)
endif()
## EXPORTS
diff --git a/example_7/package.xml b/example_7/package.xml
index 5f7703191..9bd69814b 100644
--- a/example_7/package.xml
+++ b/example_7/package.xml
@@ -40,6 +40,11 @@
xacro
ament_cmake_gtest
+ ament_cmake_pytest
+ launch_testing_ament_cmake
+ launch_testing_ros
+ liburdfdom-tools
+ xacro
ament_cmake
diff --git a/example_7/test/test_urdf_xacro.py b/example_7/test/test_urdf_xacro.py
new file mode 100644
index 000000000..5be2e3cf3
--- /dev/null
+++ b/example_7/test/test_urdf_xacro.py
@@ -0,0 +1,77 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import shutil
+import subprocess
+import tempfile
+
+from ament_index_python.packages import get_package_share_directory
+
+
+def test_urdf_xacro():
+ # General Arguments
+ description_package = "ros2_control_demo_example_7"
+ description_file = "r6bot.urdf.xacro"
+
+ description_file_path = os.path.join(
+ get_package_share_directory(description_package), "urdf", description_file
+ )
+
+ (_, tmp_urdf_output_file) = tempfile.mkstemp(suffix=".urdf")
+
+ # Compose `xacro` and `check_urdf` command
+ xacro_command = (
+ f"{shutil.which('xacro')}" f" {description_file_path}" f" > {tmp_urdf_output_file}"
+ )
+ check_urdf_command = f"{shutil.which('check_urdf')} {tmp_urdf_output_file}"
+
+ # Try to call processes but finally remove the temp file
+ try:
+ xacro_process = subprocess.run(
+ xacro_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert xacro_process.returncode == 0, " --- XACRO command failed ---"
+
+ check_urdf_process = subprocess.run(
+ check_urdf_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert (
+ check_urdf_process.returncode == 0
+ ), "\n --- URDF check failed! --- \nYour xacro does not unfold into a proper urdf robot description. Please check your xacro file."
+
+ finally:
+ os.remove(tmp_urdf_output_file)
+
+
+if __name__ == "__main__":
+ test_urdf_xacro()
diff --git a/example_7/test/test_view_robot_launch.py b/example_7/test/test_view_robot_launch.py
new file mode 100644
index 000000000..db1de3916
--- /dev/null
+++ b/example_7/test/test_view_robot_launch.py
@@ -0,0 +1,54 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import pytest
+
+from ament_index_python.packages import get_package_share_directory
+from launch import LaunchDescription
+from launch.actions import IncludeLaunchDescription
+from launch.launch_description_sources import PythonLaunchDescriptionSource
+from launch_testing.actions import ReadyToTest
+
+
+# Executes the given launch file and checks if all nodes can be started
+@pytest.mark.rostest
+def generate_test_description():
+ launch_include = IncludeLaunchDescription(
+ PythonLaunchDescriptionSource(
+ os.path.join(
+ get_package_share_directory("ros2_control_demo_example_7"),
+ "launch/view_r6bot.launch.py",
+ )
+ ),
+ launch_arguments={"gui": "true"}.items(),
+ )
+
+ return LaunchDescription([launch_include, ReadyToTest()])
diff --git a/example_8/CMakeLists.txt b/example_8/CMakeLists.txt
index 2ce4b3ed2..3b7688b9d 100644
--- a/example_8/CMakeLists.txt
+++ b/example_8/CMakeLists.txt
@@ -65,7 +65,10 @@ install(TARGETS ros2_control_demo_example_8
)
if(BUILD_TESTING)
- find_package(ament_cmake_gtest REQUIRED)
+ find_package(ament_cmake_pytest REQUIRED)
+
+ ament_add_pytest_test(example_8_urdf_xacro test/test_urdf_xacro.py)
+ ament_add_pytest_test(view_example_8_launch test/test_view_robot_launch.py)
endif()
## EXPORTS
diff --git a/example_8/package.xml b/example_8/package.xml
index e1d5e47da..275fc4aaa 100644
--- a/example_8/package.xml
+++ b/example_8/package.xml
@@ -34,6 +34,11 @@
xacro
ament_cmake_gtest
+ ament_cmake_pytest
+ launch_testing_ament_cmake
+ launch_testing_ros
+ liburdfdom-tools
+ xacro
ament_cmake
diff --git a/example_8/test/test_urdf_xacro.py b/example_8/test/test_urdf_xacro.py
new file mode 100644
index 000000000..7c09c0def
--- /dev/null
+++ b/example_8/test/test_urdf_xacro.py
@@ -0,0 +1,77 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import shutil
+import subprocess
+import tempfile
+
+from ament_index_python.packages import get_package_share_directory
+
+
+def test_urdf_xacro():
+ # General Arguments
+ description_package = "ros2_control_demo_example_8"
+ description_file = "rrbot_transmissions_system_position_only.urdf.xacro"
+
+ description_file_path = os.path.join(
+ get_package_share_directory(description_package), "urdf", description_file
+ )
+
+ (_, tmp_urdf_output_file) = tempfile.mkstemp(suffix=".urdf")
+
+ # Compose `xacro` and `check_urdf` command
+ xacro_command = (
+ f"{shutil.which('xacro')}" f" {description_file_path}" f" > {tmp_urdf_output_file}"
+ )
+ check_urdf_command = f"{shutil.which('check_urdf')} {tmp_urdf_output_file}"
+
+ # Try to call processes but finally remove the temp file
+ try:
+ xacro_process = subprocess.run(
+ xacro_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert xacro_process.returncode == 0, " --- XACRO command failed ---"
+
+ check_urdf_process = subprocess.run(
+ check_urdf_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert (
+ check_urdf_process.returncode == 0
+ ), "\n --- URDF check failed! --- \nYour xacro does not unfold into a proper urdf robot description. Please check your xacro file."
+
+ finally:
+ os.remove(tmp_urdf_output_file)
+
+
+if __name__ == "__main__":
+ test_urdf_xacro()
diff --git a/example_8/test/test_view_robot_launch.py b/example_8/test/test_view_robot_launch.py
new file mode 100644
index 000000000..12a097424
--- /dev/null
+++ b/example_8/test/test_view_robot_launch.py
@@ -0,0 +1,54 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import pytest
+
+from ament_index_python.packages import get_package_share_directory
+from launch import LaunchDescription
+from launch.actions import IncludeLaunchDescription
+from launch.launch_description_sources import PythonLaunchDescriptionSource
+from launch_testing.actions import ReadyToTest
+
+
+# Executes the given launch file and checks if all nodes can be started
+@pytest.mark.rostest
+def generate_test_description():
+ launch_include = IncludeLaunchDescription(
+ PythonLaunchDescriptionSource(
+ os.path.join(
+ get_package_share_directory("ros2_control_demo_example_8"),
+ "launch/view_robot.launch.py",
+ )
+ ),
+ launch_arguments={"gui": "true"}.items(),
+ )
+
+ return LaunchDescription([launch_include, ReadyToTest()])
diff --git a/example_9/CMakeLists.txt b/example_9/CMakeLists.txt
index c0ce90a5e..1c6980484 100644
--- a/example_9/CMakeLists.txt
+++ b/example_9/CMakeLists.txt
@@ -64,7 +64,10 @@ install(TARGETS ros2_control_demo_example_9
)
if(BUILD_TESTING)
- find_package(ament_cmake_gtest REQUIRED)
+ find_package(ament_cmake_pytest REQUIRED)
+
+ ament_add_pytest_test(example_9_urdf_xacro test/test_urdf_xacro.py)
+ ament_add_pytest_test(view_example_9_launch test/test_view_robot_launch.py)
endif()
## EXPORTS
diff --git a/example_9/package.xml b/example_9/package.xml
index cc7f7fc90..580b31746 100644
--- a/example_9/package.xml
+++ b/example_9/package.xml
@@ -36,6 +36,11 @@
xacro
ament_cmake_gtest
+ ament_cmake_pytest
+ launch_testing_ament_cmake
+ launch_testing_ros
+ liburdfdom-tools
+ xacro
ament_cmake
diff --git a/example_9/test/test_urdf_xacro.py b/example_9/test/test_urdf_xacro.py
new file mode 100644
index 000000000..a0ba60d90
--- /dev/null
+++ b/example_9/test/test_urdf_xacro.py
@@ -0,0 +1,77 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import shutil
+import subprocess
+import tempfile
+
+from ament_index_python.packages import get_package_share_directory
+
+
+def test_urdf_xacro():
+ # General Arguments
+ description_package = "ros2_control_demo_example_9"
+ description_file = "rrbot.urdf.xacro"
+
+ description_file_path = os.path.join(
+ get_package_share_directory(description_package), "urdf", description_file
+ )
+
+ (_, tmp_urdf_output_file) = tempfile.mkstemp(suffix=".urdf")
+
+ # Compose `xacro` and `check_urdf` command
+ xacro_command = (
+ f"{shutil.which('xacro')}" f" {description_file_path}" f" > {tmp_urdf_output_file}"
+ )
+ check_urdf_command = f"{shutil.which('check_urdf')} {tmp_urdf_output_file}"
+
+ # Try to call processes but finally remove the temp file
+ try:
+ xacro_process = subprocess.run(
+ xacro_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert xacro_process.returncode == 0, " --- XACRO command failed ---"
+
+ check_urdf_process = subprocess.run(
+ check_urdf_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True
+ )
+
+ assert (
+ check_urdf_process.returncode == 0
+ ), "\n --- URDF check failed! --- \nYour xacro does not unfold into a proper urdf robot description. Please check your xacro file."
+
+ finally:
+ os.remove(tmp_urdf_output_file)
+
+
+if __name__ == "__main__":
+ test_urdf_xacro()
diff --git a/example_9/test/test_view_robot_launch.py b/example_9/test/test_view_robot_launch.py
new file mode 100644
index 000000000..7ca47c9b7
--- /dev/null
+++ b/example_9/test/test_view_robot_launch.py
@@ -0,0 +1,54 @@
+# Copyright (c) 2022 FZI Forschungszentrum Informatik
+#
+# 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 the {copyright_holder} 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 HOLDER 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.
+#
+# Author: Lukas Sackewitz
+
+import os
+import pytest
+
+from ament_index_python.packages import get_package_share_directory
+from launch import LaunchDescription
+from launch.actions import IncludeLaunchDescription
+from launch.launch_description_sources import PythonLaunchDescriptionSource
+from launch_testing.actions import ReadyToTest
+
+
+# Executes the given launch file and checks if all nodes can be started
+@pytest.mark.rostest
+def generate_test_description():
+ launch_include = IncludeLaunchDescription(
+ PythonLaunchDescriptionSource(
+ os.path.join(
+ get_package_share_directory("ros2_control_demo_example_9"),
+ "launch/view_robot.launch.py",
+ )
+ ),
+ launch_arguments={"gui": "true"}.items(),
+ )
+
+ return LaunchDescription([launch_include, ReadyToTest()])