diff --git a/.github/workflows/package_xml.yml b/.github/workflows/package_xml.yml new file mode 100644 index 000000000..4bd4a9aa0 --- /dev/null +++ b/.github/workflows/package_xml.yml @@ -0,0 +1,11 @@ +name: Validate package.xml + +on: + pull_request: + +jobs: + package-xml: + runs-on: ubuntu-latest + name: Validate package.xml + steps: + - uses: gazebo-tooling/action-gz-ci/validate_package_xml@jammy diff --git a/Changelog.md b/Changelog.md index 3216b1855..44167531a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,22 @@ ## libsdformat 14.X +### libsdformat 14.2.0 (2024-04-23) + +1. Fix trivial warning on 24.04 for JointAxis_TEST.cc + * [Pull request #1402](https://github.com/gazebosim/sdformat/pull/1402) + +1. Add package.xml, fix `gz sdf` tests on Windows + * [Pull request #1374](https://github.com/gazebosim/sdformat/pull/1374) + +1. Backport mesh optimization feature + * [Pull request #1398](https://github.com/gazebosim/sdformat/pull/1398) + * [Pull request #1386](https://github.com/gazebosim/sdformat/pull/1386) + * [Pull request #1382](https://github.com/gazebosim/sdformat/pull/1382) + +1. Param_TEST: Check return values of Param::Get/Set + * [Pull request #1394](https://github.com/gazebosim/sdformat/pull/1394) + ### libsdformat 14.1.1 (2024-03-28) 1. Fix warning with pybind11 2.12 diff --git a/package.xml b/package.xml new file mode 100644 index 000000000..2cfe9abe1 --- /dev/null +++ b/package.xml @@ -0,0 +1,32 @@ + + + sdformat15 + 15.0.0 + SDFormat is an XML file format that describes environments, objects, and robots +in a manner suitable for robotic applications + + Addisu Z. Taddese + Steve Peters + + Apache License 2.0 + + https://github.com/gazebosim/sdformat + + cmake + gz-cmake4 + gz-math8 + gz-utils3 + tinyxml2 + liburdfdom-dev + pybind11-dev + + gz-tools2 + + libxml2-utils + python3-psutil + python3-pytest + + + cmake + + diff --git a/src/Console.cc b/src/Console.cc index d9ec8d044..558f10d87 100644 --- a/src/Console.cc +++ b/src/Console.cc @@ -34,13 +34,7 @@ using namespace sdf; static std::shared_ptr myself; static std::mutex g_instance_mutex; -/// \todo Output disabled for windows, to allow tests to pass. We should -/// disable output just for tests on windows. -#ifndef _WIN32 static bool g_quiet = false; -#else -static bool g_quiet = true; -#endif static Console::ConsoleStream g_NullStream(nullptr); diff --git a/src/JointAxis_TEST.cc b/src/JointAxis_TEST.cc index 0e04be6fd..bc612c689 100644 --- a/src/JointAxis_TEST.cc +++ b/src/JointAxis_TEST.cc @@ -226,58 +226,58 @@ TEST(DOMJointAxis, ToElement) sdf::ElementPtr dynElem = elem->GetElement("dynamics", errors); ASSERT_TRUE(errors.empty()); - double damping = 0; - damping = dynElem->Get(errors, "damping", damping).first; + double damping; + damping = dynElem->Get(errors, "damping", 0.0).first; ASSERT_TRUE(errors.empty()); EXPECT_DOUBLE_EQ(0.2, damping); - double friction = 0; - friction = dynElem->Get(errors, "friction", friction).first; + double friction; + friction = dynElem->Get(errors, "friction", 0.0).first; ASSERT_TRUE(errors.empty()); EXPECT_DOUBLE_EQ(1.3, friction); - double springReference = 0; + double springReference; springReference = dynElem->Get( - errors, "spring_reference", springReference).first; + errors, "spring_reference", 0.0).first; ASSERT_TRUE(errors.empty()); EXPECT_DOUBLE_EQ(2.4, springReference); - double springStiffness = 0; + double springStiffness; springStiffness = dynElem->Get( - errors, "spring_stiffness", springStiffness).first; + errors, "spring_stiffness", 0.0).first; ASSERT_TRUE(errors.empty()); EXPECT_DOUBLE_EQ(-1.2, springStiffness); // Check //axis/limit sdf::ElementPtr limitElem = elem->GetElement("limit", errors); - double lower = 0; - lower = limitElem->Get(errors, "lower", lower).first; + double lower; + lower = limitElem->Get(errors, "lower", 0.0).first; ASSERT_TRUE(errors.empty()); EXPECT_DOUBLE_EQ(-10.8, lower); - double upper = 0; - upper = limitElem->Get(errors, "upper", upper).first; + double upper; + upper = limitElem->Get(errors, "upper", 0.0).first; ASSERT_TRUE(errors.empty()); EXPECT_DOUBLE_EQ(123.4, upper); - double effort = 0; - effort = limitElem->Get(errors, "effort", effort).first; + double effort; + effort = limitElem->Get(errors, "effort", 0.0).first; ASSERT_TRUE(errors.empty()); EXPECT_DOUBLE_EQ(3.2, effort); - double maxVel = 0; - maxVel = limitElem->Get(errors, "velocity", maxVel).first; + double maxVel; + maxVel = limitElem->Get(errors, "velocity", 0.0).first; ASSERT_TRUE(errors.empty()); EXPECT_DOUBLE_EQ(54.2, maxVel); - double stiffness = 0; - stiffness = limitElem->Get(errors, "stiffness", stiffness).first; + double stiffness; + stiffness = limitElem->Get(errors, "stiffness", 0.0).first; ASSERT_TRUE(errors.empty()); EXPECT_DOUBLE_EQ(1e2, stiffness); - double dissipation = 0; + double dissipation; dissipation = limitElem->Get( - errors, "dissipation", dissipation).first; + errors, "dissipation", 0.0).first; ASSERT_TRUE(errors.empty()); EXPECT_DOUBLE_EQ(1.5, dissipation); @@ -286,31 +286,31 @@ TEST(DOMJointAxis, ToElement) ASSERT_NE(nullptr, mimicElem); std::string mimicJointName; mimicJointName = mimicElem->Get( - errors, "joint", mimicJointName).first; + errors, "joint", "").first; ASSERT_TRUE(errors.empty()); EXPECT_EQ("test_joint", mimicJointName); std::string mimicAxisName; mimicAxisName = mimicElem->Get( - errors, "axis", mimicAxisName).first; + errors, "axis", "").first; ASSERT_TRUE(errors.empty()); EXPECT_EQ("axis2", mimicAxisName); double multiplier; multiplier = mimicElem->Get( - errors, "multiplier", multiplier).first; + errors, "multiplier", 0.0).first; ASSERT_TRUE(errors.empty()); EXPECT_DOUBLE_EQ(5.0, multiplier); double offset; offset = mimicElem->Get( - errors, "offset", offset).first; + errors, "offset", 0.0).first; ASSERT_TRUE(errors.empty()); EXPECT_DOUBLE_EQ(1.0, offset); double reference; reference = mimicElem->Get( - errors, "reference", reference).first; + errors, "reference", 0.0).first; ASSERT_TRUE(errors.empty()); EXPECT_DOUBLE_EQ(2.0, reference); diff --git a/src/cmd/CMakeLists.txt b/src/cmd/CMakeLists.txt index a1cf707c1..c1c91078b 100644 --- a/src/cmd/CMakeLists.txt +++ b/src/cmd/CMakeLists.txt @@ -31,7 +31,13 @@ set(cmd_script_configured "${CMAKE_CURRENT_BINARY_DIR}/cmd${PROJECT_NAME}.rb.con # Set the library_location variable to the relative path to the library file # within the install directory structure. -set(library_location "../../../${CMAKE_INSTALL_LIBDIR}/$") +if (MSVC) + set(library_location_prefix "${CMAKE_INSTALL_BINDIR}") +else() + set(library_location_prefix "${CMAKE_INSTALL_LIBDIR}") +endif() + +set(library_location "../../../${library_location_prefix}/$") configure_file( "cmd${PROJECT_NAME_NO_VERSION_LOWER}.rb.in" diff --git a/src/cmd/cmdsdformat.rb.in b/src/cmd/cmdsdformat.rb.in index 7c93d7680..c4bd35f4c 100644 --- a/src/cmd/cmdsdformat.rb.in +++ b/src/cmd/cmdsdformat.rb.in @@ -26,6 +26,8 @@ else end require 'optparse' +require 'pathname' + # Constants. LIBRARY_NAME = '@library_location@' @@ -174,9 +176,7 @@ class Cmd # puts options # Read the plugin that handles the command. - if LIBRARY_NAME[0] == '/' - # If the first character is a slash, we'll assume that we've been given an - # absolute path to the library. This is only used during test mode. + if Pathname.new(LIBRARY_NAME).absolute? plugin = LIBRARY_NAME else # We're assuming that the library path is relative to the current @@ -185,10 +185,18 @@ class Cmd end conf_version = LIBRARY_VERSION + if defined? RubyInstaller + # RubyInstaller does not search for dlls in PATH or the directory that tests are running from, + # so we'll add the parent directory of the plugin to the search path. + # https://github.com/oneclick/rubyinstaller2/wiki/For-gem-developers#-dll-loading + RubyInstaller::Runtime.add_dll_directory(File.dirname(plugin)) + end + begin Importer.dlload plugin - rescue DLError + rescue DLError => error puts "Library error: [#{plugin}] not found." + puts "DLError: #{error.message}" exit(-1) end diff --git a/src/gz_TEST.cc b/src/gz_TEST.cc index 816882f56..2e16d19db 100644 --- a/src/gz_TEST.cc +++ b/src/gz_TEST.cc @@ -73,7 +73,7 @@ std::string custom_exec_str(std::string _cmd) } ///////////////////////////////////////////////// -TEST(checkUnrecognizedElements, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) +TEST(checkUnrecognizedElements, SDF) { // Check an SDFormat file with unrecognized elements { @@ -120,7 +120,7 @@ TEST(checkUnrecognizedElements, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) } ///////////////////////////////////////////////// -TEST(check, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) +TEST(check, SDF) { // Check a good SDF file { @@ -1011,7 +1011,7 @@ TEST(check, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) } ///////////////////////////////////////////////// -TEST(check_shapes_sdf, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) +TEST(check_shapes_sdf, SDF) { { const auto path = @@ -1035,7 +1035,7 @@ TEST(check_shapes_sdf, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) } ///////////////////////////////////////////////// -TEST(check_model_sdf, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) +TEST(check_model_sdf, SDF) { // Check a good SDF file by passing the absolute path { @@ -1062,7 +1062,7 @@ TEST(check_model_sdf, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) } ///////////////////////////////////////////////// -TEST(describe, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) +TEST(describe, SDF) { // Get the description std::string output = @@ -1074,7 +1074,7 @@ TEST(describe, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) } ///////////////////////////////////////////////// -TEST(print, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) +TEST(print, SDF) { // Check a good SDF file { @@ -1103,7 +1103,7 @@ TEST(print, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) } ///////////////////////////////////////////////// -TEST(print_rotations_in_degrees, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) +TEST(print_rotations_in_degrees, SDF) { const std::string path = sdf::testing::TestFile("sdf", "rotations_in_degrees.sdf"); @@ -1171,7 +1171,7 @@ TEST(print_rotations_in_degrees, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) } ///////////////////////////////////////////////// -TEST(print_rotations_in_radians, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) +TEST(print_rotations_in_radians, SDF) { const std::string path = sdf::testing::TestFile("sdf", "rotations_in_radians.sdf"); @@ -1239,7 +1239,7 @@ TEST(print_rotations_in_radians, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) } ///////////////////////////////////////////////// -TEST(print_rotations_in_quaternions, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) +TEST(print_rotations_in_quaternions, SDF) { const auto path = sdf::testing::TestFile( "sdf", "rotations_in_quaternions.sdf"); @@ -1308,7 +1308,7 @@ TEST(print_rotations_in_quaternions, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) } ///////////////////////////////////////////////// -TEST(print_includes_rotations_in_degrees, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) +TEST(print_includes_rotations_in_degrees, SDF) { // Set SDF_PATH so that included models can be found gz::utils::setenv( @@ -1379,7 +1379,7 @@ TEST(print_includes_rotations_in_degrees, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) } ///////////////////////////////////////////////// -TEST(print_includes_rotations_in_radians, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) +TEST(print_includes_rotations_in_radians, SDF) { // Set SDF_PATH so that included models can be found gz::utils::setenv( @@ -1450,8 +1450,7 @@ TEST(print_includes_rotations_in_radians, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) } ///////////////////////////////////////////////// -TEST(print_includes_rotations_in_quaternions, - GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) +TEST(print_includes_rotations_in_quaternions, SDF) { // Set SDF_PATH so that included models can be found gz::utils::setenv( @@ -1523,8 +1522,7 @@ TEST(print_includes_rotations_in_quaternions, } ///////////////////////////////////////////////// -TEST(print_rotations_in_unnormalized_degrees, - GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) +TEST(print_rotations_in_unnormalized_degrees, SDF) { const std::string path = sdf::testing::TestFile("sdf", "rotations_in_unnormalized_degrees.sdf"); @@ -1595,8 +1593,7 @@ TEST(print_rotations_in_unnormalized_degrees, } ///////////////////////////////////////////////// -TEST(print_rotations_in_unnormalized_radians, - GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) +TEST(print_rotations_in_unnormalized_radians, SDF) { const std::string path = sdf::testing::TestFile("sdf", "rotations_in_unnormalized_radians.sdf"); @@ -1664,7 +1661,7 @@ TEST(print_rotations_in_unnormalized_radians, } ///////////////////////////////////////////////// -TEST(shuffled_cmd_flags, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) +TEST(shuffled_cmd_flags, SDF) { const std::string path = sdf::testing::TestFile("sdf", "rotations_in_unnormalized_radians.sdf"); @@ -1713,8 +1710,7 @@ TEST(shuffled_cmd_flags, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) } ///////////////////////////////////////////////// -TEST(print_snap_to_degrees_tolerance_too_high, - GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) +TEST(print_snap_to_degrees_tolerance_too_high, SDF) { const std::string path = sdf::testing::TestFile( "sdf", @@ -1731,7 +1727,7 @@ TEST(print_snap_to_degrees_tolerance_too_high, } ///////////////////////////////////////////////// -TEST(GraphCmd, GZ_UTILS_TEST_DISABLED_ON_WIN32(WorldPoseRelativeTo)) +TEST(GraphCmd, WorldPoseRelativeTo) { // world pose relative_to graph const std::string path = @@ -1780,7 +1776,7 @@ TEST(GraphCmd, GZ_UTILS_TEST_DISABLED_ON_WIN32(WorldPoseRelativeTo)) } ///////////////////////////////////////////////// -TEST(GraphCmd, GZ_UTILS_TEST_DISABLED_ON_WIN32(ModelPoseRelativeTo)) +TEST(GraphCmd, ModelPoseRelativeTo) { const auto path = sdf::testing::TestFile("sdf", "model_relative_to_nested_reference.sdf"); @@ -1857,7 +1853,7 @@ TEST(GraphCmd, GZ_UTILS_TEST_DISABLED_ON_WIN32(ModelPoseRelativeTo)) } ///////////////////////////////////////////////// -TEST(GraphCmd, GZ_UTILS_TEST_DISABLED_ON_WIN32(WorldFrameAttachedTo)) +TEST(GraphCmd, WorldFrameAttachedTo) { const auto path = sdf::testing::TestFile("sdf", "world_nested_frame_attached_to.sdf"); @@ -1903,7 +1899,7 @@ TEST(GraphCmd, GZ_UTILS_TEST_DISABLED_ON_WIN32(WorldFrameAttachedTo)) } ///////////////////////////////////////////////// -TEST(GraphCmd, GZ_UTILS_TEST_DISABLED_ON_WIN32(ModelFrameAttachedTo)) +TEST(GraphCmd, ModelFrameAttachedTo) { const auto path = sdf::testing::TestFile("sdf", "model_nested_frame_attached_to.sdf"); @@ -1955,7 +1951,7 @@ TEST(GraphCmd, GZ_UTILS_TEST_DISABLED_ON_WIN32(ModelFrameAttachedTo)) // Disable on arm #if !defined __ARM_ARCH ///////////////////////////////////////////////// -TEST(inertial_stats, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) +TEST(inertial_stats, SDF) { std::string expectedOutput = "Inertial statistics for model: test_model\n" @@ -2043,7 +2039,7 @@ TEST(inertial_stats, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) ////////////////////////////////////////////////// /// \brief Check help message and bash completion script for consistent flags -TEST(HelpVsCompletionFlags, SDF) +TEST(HelpVsCompletionFlags, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF)) { // Flags in help message std::string helpOutput = custom_exec_str(GzCommand() + " sdf --help"); @@ -2098,6 +2094,16 @@ int main(int argc, char **argv) gz::utils::setenv("LD_LIBRARY_PATH", testLibraryPath); #endif + // temporarily set HOME + std::string homeDir; + sdf::testing::TestTmpPath(homeDir); + +#ifdef _WIN32 + gz::utils::setenv("HOMEPATH", homeDir); +#else + gz::utils::setenv("HOME", homeDir); +#endif + ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }