From 48821c1ab764122f055da7aa4b93164ce4bf6086 Mon Sep 17 00:00:00 2001 From: Felix Exner Date: Thu, 14 Dec 2023 09:58:24 +0000 Subject: [PATCH] Add tests for generated description --- ur_simulation_gazebo/CMakeLists.txt | 6 + ur_simulation_gazebo/package.xml | 6 + ur_simulation_gazebo/test/test_description.py | 118 ++++++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 ur_simulation_gazebo/test/test_description.py diff --git a/ur_simulation_gazebo/CMakeLists.txt b/ur_simulation_gazebo/CMakeLists.txt index 63e3125..2feeb10 100644 --- a/ur_simulation_gazebo/CMakeLists.txt +++ b/ur_simulation_gazebo/CMakeLists.txt @@ -7,4 +7,10 @@ install(DIRECTORY config launch urdf DESTINATION share/${PROJECT_NAME} ) +if(BUILD_TESTING) + find_package(ament_cmake_pytest REQUIRED) + + ament_add_pytest_test(description test/test_description.py) +endif() + ament_package() diff --git a/ur_simulation_gazebo/package.xml b/ur_simulation_gazebo/package.xml index 5c5a944..2802764 100644 --- a/ur_simulation_gazebo/package.xml +++ b/ur_simulation_gazebo/package.xml @@ -30,6 +30,12 @@ urdf xacro + ament_cmake_pytest + launch_testing_ament_cmake + launch_testing_ros + liburdfdom-tools + xacro + ament_cmake diff --git a/ur_simulation_gazebo/test/test_description.py b/ur_simulation_gazebo/test/test_description.py new file mode 100644 index 0000000..7db63b7 --- /dev/null +++ b/ur_simulation_gazebo/test/test_description.py @@ -0,0 +1,118 @@ +# Copyright (c) 2023 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 +import pytest + +from ament_index_python.packages import get_package_share_directory + + +@pytest.mark.parametrize( + "ur_type", ["ur3", "ur3e", "ur5", "ur5e", "ur10", "ur10e", "ur16e", "ur20"] +) +@pytest.mark.parametrize("prefix", ["", "my_ur_"]) +def test_ur_urdf_xacro(ur_type, prefix): + # Initialize Arguments + safety_limits = "true" + safety_pos_margin = "0.15" + safety_k_position = "20" + # General Arguments + description_package = "ur_description" + + joint_limit_params = os.path.join( + get_package_share_directory(description_package), "config", ur_type, "joint_limits.yaml" + ) + kinematics_params = os.path.join( + get_package_share_directory(description_package), + "config", + ur_type, + "default_kinematics.yaml", + ) + physical_params = os.path.join( + get_package_share_directory(description_package), + "config", + ur_type, + "physical_parameters.yaml", + ) + visual_params = os.path.join( + get_package_share_directory(description_package), + "config", + ur_type, + "visual_parameters.yaml", + ) + + description_file_path = os.path.join( + get_package_share_directory("ur_simulation_gazebo"), "urdf", "ur_gazebo.urdf.xacro" + ) + + (_, 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" joint_limit_params:={joint_limit_params}" + f" kinematics_params:={kinematics_params}" + f" physical_params:={physical_params}" + f" visual_params:={visual_params}" + f" safety_limits:={safety_limits}" + f" safety_pos_margin:={safety_pos_margin}" + f" safety_k_position:={safety_k_position}" + f" name:={ur_type}" + f" prefix:={prefix}" + 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_ur_urdf_xacro()