diff --git a/include/sdf/Param.hh b/include/sdf/Param.hh index 827ba3f06..e9404022b 100644 --- a/include/sdf/Param.hh +++ b/include/sdf/Param.hh @@ -75,28 +75,37 @@ namespace sdf struct ParamStreamer { const T &val; + const int precision; // Used to set std::ostream's std::setprecision + explicit ParamStreamer(const T &_val, int _precision = 0) + : val(_val), precision(_precision) {} }; - template ParamStreamer(T) -> ParamStreamer; - template std::ostream& operator<<(std::ostream &os, ParamStreamer s) { - os << s.val; - return os; - } - - template<> - inline std::ostream& operator<<(std::ostream &os, ParamStreamer s) - { - os << std::setprecision(std::numeric_limits::max_digits10) << s.val; - return os; - } + if (s.precision == std::numeric_limits::max()) + { + if constexpr (std::is_same_v + || std::is_same_v + || std::is_same_v + || std::is_same_v + || std::is_same_v + || std::is_same_v) + { + os << std::setprecision(std::numeric_limits::max_digits10); + } + else if constexpr (std::is_same_v + || std::is_same_v) + { + os << std::setprecision(std::numeric_limits::max_digits10); + } + } + else + { + os << std::setprecision(s.precision); + } - template<> - inline std::ostream& operator<<(std::ostream &os, ParamStreamer s) - { - os << std::setprecision(std::numeric_limits::max_digits10) << s.val; + os << s.val; return os; } @@ -104,9 +113,9 @@ namespace sdf std::ostream& operator<<(std::ostream& os, ParamStreamer> sv) { - std::visit([&os](auto const &v) + std::visit([&os, &sv](auto const &v) { - os << ParamStreamer{v}; + os << ParamStreamer{v, sv.precision}; }, sv.val); return os; } @@ -357,7 +366,8 @@ namespace sdf /// \def ParamVariant /// \brief Variant type def. /// Note: When a new variant is added, add variant to functions - /// ParamPrivate::TypeToString and ParamPrivate::ValueFromStringImpl + /// ParamPrivate::TypeToString, ParamPrivate::ValueFromStringImpl, + /// and template std::ostream operator if new variant is floating point public: typedef std::variant &_originalStr, - std::string &_valueStr) const; - /// \brief Data type to string mapping /// \return The type as a string, empty string if unknown type public: template diff --git a/include/sdf/PrintConfig.hh b/include/sdf/PrintConfig.hh index 8696339c3..c74bfa590 100644 --- a/include/sdf/PrintConfig.hh +++ b/include/sdf/PrintConfig.hh @@ -75,6 +75,16 @@ namespace sdf /// False if they are to be expanded. public: bool PreserveIncludes() const; + /// \brief Set precision of output stream for float / double types. + /// By default, the output stream uses maximum precision. + /// \param[in] _precision The new precision value. To set back to maximum + /// precision, use std::numeric_limits::max(). + public: void SetOutPrecision(int _precision); + + /// \brief Retrieve the output stream's set precision value. + /// \return The output stream's precision. + public: int OutPrecision() const; + /// \brief Return true if both PrintConfig objects contain the same values. /// \param[in] _config PrintConfig to compare. /// \return True if 'this' == _config. diff --git a/src/Param.cc b/src/Param.cc index fcf1633f2..15b2ee3f1 100644 --- a/src/Param.cc +++ b/src/Param.cc @@ -313,7 +313,6 @@ std::string Param::GetAsString(const PrintConfig &_config) const this->dataPtr->StringFromValueImpl(_config, this->dataPtr->typeName, this->dataPtr->value, - this->dataPtr->strValue, valueStr)) { return valueStr; @@ -330,7 +329,6 @@ std::string Param::GetDefaultAsString(const PrintConfig &_config) const _config, this->dataPtr->typeName, this->dataPtr->defaultValue, - this->dataPtr->defaultStrValue, defaultStr)) { return defaultStr; @@ -339,7 +337,7 @@ std::string Param::GetDefaultAsString(const PrintConfig &_config) const sdferr << "Unable to get string from default value, " << "using ParamStreamer instead.\n"; StringStreamClassicLocale ss; - ss << ParamStreamer{ this->dataPtr->defaultValue }; + ss << ParamStreamer{ this->dataPtr->defaultValue, _config.OutPrecision() }; return ss.str(); } @@ -797,7 +795,6 @@ bool ParamPrivate::ValueFromStringImpl(const std::string &_typeName, /// \param[in] _config Printing configuration for the output string. /// \param[in] _parentAttributes Parent Element Attributes. /// \param[in] _value The variant value of this pose. -/// \param[in] _originalStr The original string used to set this pose value. /// \param[out] _valueStr The pose as a string. /// \return True if the string was successfully retrieved from the pose, false /// otherwise. @@ -805,11 +802,15 @@ bool ParamPrivate::ValueFromStringImpl(const std::string &_typeName, bool PoseStringFromValue(const PrintConfig &_config, const Param_V &_parentAttributes, const ParamPrivate::ParamVariant &_value, - const std::optional &_originalStr, std::string &_valueStr) { StringStreamClassicLocale ss; + if (_config.OutPrecision() == std::numeric_limits::max()) + ss << std::setprecision(std::numeric_limits::max_digits10); + else + ss << std::setprecision(_config.OutPrecision()); + const ignition::math::Pose3d *pose = std::get_if(&_value); if (!pose) @@ -878,7 +879,7 @@ bool PoseStringFromValue(const PrintConfig &_config, } // Helper function that sanitizes zero values like '-0' - auto sanitizeZero = [](double _number) + auto sanitizeZero = [&_config](double _number) { StringStreamClassicLocale stream; if (std::fpclassify(_number) == FP_ZERO) @@ -887,6 +888,11 @@ bool PoseStringFromValue(const PrintConfig &_config, } else { + if (_config.OutPrecision() == std::numeric_limits::max()) + stream << std::setprecision(std::numeric_limits::max_digits10); + else + stream << std::setprecision(_config.OutPrecision()); + stream << _number; } return stream.str(); @@ -949,17 +955,6 @@ bool PoseStringFromValue(const PrintConfig &_config, return true; } - // If no modification to the value is needed, the original string is returned. - if (!_config.RotationInDegrees() && - !_config.RotationSnapToDegrees().has_value() && - !_config.RotationSnapTolerance().has_value() && - _originalStr.has_value() && - !_originalStr->empty()) - { - _valueStr = _originalStr.value(); - return true; - } - ss << pose->Pos() << posRotDelimiter << sanitizeZero(pose->Rot().Roll()) << " " << sanitizeZero(pose->Rot().Pitch()) << " " @@ -974,22 +969,6 @@ bool ParamPrivate::StringFromValueImpl( const std::string &_typeName, const ParamVariant &_value, std::string &_valueStr) const -{ - return this->StringFromValueImpl( - _config, - _typeName, - _value, - std::nullopt, - _valueStr); -} - -///////////////////////////////////////////////// -bool ParamPrivate::StringFromValueImpl( - const PrintConfig &_config, - const std::string &_typeName, - const ParamVariant &_value, - const std::optional &_originalStr, - std::string &_valueStr) const { // This will be handled in a type specific manner if (_typeName == "bool") @@ -1012,13 +991,13 @@ bool ParamPrivate::StringFromValueImpl( if (!this->ignoreParentAttributes && p) { return PoseStringFromValue( - _config, p->GetAttributes(), _value, _originalStr, _valueStr); + _config, p->GetAttributes(), _value, _valueStr); } - return PoseStringFromValue(_config, {}, _value, _originalStr, _valueStr); + return PoseStringFromValue(_config, {}, _value, _valueStr); } StringStreamClassicLocale ss; - ss << ParamStreamer{ _value }; + ss << ParamStreamer{ _value, _config.OutPrecision() }; _valueStr = ss.str(); return true; } diff --git a/src/PrintConfig.cc b/src/PrintConfig.cc index a36c441b5..311c02141 100644 --- a/src/PrintConfig.cc +++ b/src/PrintConfig.cc @@ -14,6 +14,7 @@ * limitations under the License. * */ +#include #include "sdf/PrintConfig.hh" #include "sdf/Console.hh" @@ -36,6 +37,9 @@ class PrintConfig::Implementation /// \brief True to preserve tags, false to expand. public: bool preserveIncludes = false; + + /// \brief The output stream's precision. By default, uses maximum precision. + public: int outPrecision = std::numeric_limits::max(); }; ///////////////////////////////////////////////// @@ -104,13 +108,26 @@ std::optional PrintConfig::RotationSnapTolerance() const return this->dataPtr->rotationSnapTolerance; } +///////////////////////////////////////////////// +void PrintConfig::SetOutPrecision(int _precision) +{ + this->dataPtr->outPrecision = _precision; +} + +///////////////////////////////////////////////// +int PrintConfig::OutPrecision() const +{ + return this->dataPtr->outPrecision; +} + ///////////////////////////////////////////////// bool PrintConfig::operator==(const PrintConfig &_config) const { if (this->RotationInDegrees() == _config.RotationInDegrees() && this->RotationSnapToDegrees() == _config.RotationSnapToDegrees() && this->RotationSnapTolerance() == _config.RotationSnapTolerance() && - this->PreserveIncludes() == _config.PreserveIncludes()) + this->PreserveIncludes() == _config.PreserveIncludes() && + this->OutPrecision() == _config.OutPrecision()) { return true; } diff --git a/src/PrintConfig_TEST.cc b/src/PrintConfig_TEST.cc index 9ac523c9e..dea1e2db3 100644 --- a/src/PrintConfig_TEST.cc +++ b/src/PrintConfig_TEST.cc @@ -105,3 +105,16 @@ TEST(PrintConfig, PreserveIncludes) config.SetPreserveIncludes(false); EXPECT_FALSE(config.PreserveIncludes()); } + +///////////////////////////////////////////////// +TEST(PrintConfig, OutPrecision) +{ + sdf::PrintConfig config; + EXPECT_EQ(std::numeric_limits::max(), config.OutPrecision()); + config.SetOutPrecision(2); + EXPECT_EQ(2, config.OutPrecision()); + config.SetOutPrecision(8); + EXPECT_EQ(8, config.OutPrecision()); + config.SetOutPrecision(std::numeric_limits::max()); + EXPECT_EQ(std::numeric_limits::max(), config.OutPrecision()); +} diff --git a/src/cmd/cmdsdformat.rb.in b/src/cmd/cmdsdformat.rb.in index 04562f03f..c9dbcf450 100644 --- a/src/cmd/cmdsdformat.rb.in +++ b/src/cmd/cmdsdformat.rb.in @@ -42,7 +42,8 @@ COMMANDS = { 'sdf' => " -d [ --describe ] [SPEC VERSION] Print the aggregated SDFormat spec description. Default version (@SDF_PROTOCOL_VERSION@).\n" + " -g [ --graph ] arg Print the PoseRelativeTo or FrameAttachedTo graph. (WARNING: This is for advanced\n" + " use only and the output may change without any promise of stability)\n" + - " -p [ --print ] arg Print converted arg.\n" + + " -p [ --print ] arg Print converted arg. Note the quaternion representation of the\n" + + " rotational part of poses and unit vectors will be normalized.\n" + " -i [ --preserve-includes ] Preserve included tags when printing converted arg (does not preserve merge-includes).\n" + " --degrees Pose rotation angles are printed in degrees.\n" + " --snap-to-degrees arg Snap pose rotation angles to this specified interval in degrees. This value must be\n" + @@ -50,6 +51,8 @@ COMMANDS = { 'sdf' => " --snap-tolerance arg Used in conjunction with --snap-to-degrees, specifies the tolerance at which snapping\n" + " occurs. This value must be larger than 0, less than 360, and less than the defined\n" + " degrees value to snap to. If unspecified, its default value is 0.01.\n" + + " --precision arg Set the output stream precision for floating point numbers. The arg must be a positive integer.\n" + + COMMON_OPTIONS } @@ -65,6 +68,7 @@ class Cmd options = {} options['degrees'] = 0 options['snap_tolerance'] = 0.01 + options['preserve_includes'] = 0 usage = COMMANDS[args[0]] @@ -109,6 +113,10 @@ class Cmd end options['snap_tolerance'] = arg end + opts.on('--precision arg', Integer, + 'Set the output stream precision for floating point numbers.') do |arg| + options['precision'] = arg + end opts.on('-g arg', '--graph type', String, 'Print PoseRelativeTo or FrameAttachedTo graph') do |graph_type| options['graph'] = {:type => graph_type} @@ -131,7 +139,8 @@ class Cmd options['command'] = ARGV[0] - if options['preserve_includes'] and not options['print'] + if (options['preserve_includes'] != 0 and not options['print']) || + (options['precision'] and not options['print']) puts usage exit(-1) end @@ -206,21 +215,25 @@ class Cmd exit(Importer.cmdDescribe(options['describe'])) elsif options.key?('print') snap_to_degrees = 0 - if options['preserve_includes'] - Importer.extern 'int cmdPrintPreserveIncludes(const char *)' - exit(Importer.cmdPrintPreserveIncludes(File.expand_path(options['print']))) - elsif options.key?('snap_to_degrees') + precision = 0 + + if options.key?('snap_to_degrees') if options['snap_to_degrees'] < options['snap_tolerance'] puts "Rotation snapping tolerance must be larger than the snapping tolerance." exit(-1) end snap_to_degrees = options['snap_to_degrees'] end - Importer.extern 'int cmdPrint(const char *, int in_degrees, int snap_to_degrees, float snap_tolerance)' + if options.key?('precision') + precision = options['precision'] + end + Importer.extern 'int cmdPrint(const char *, int in_degrees, int snap_to_degrees, float snap_tolerance, int, int)' exit(Importer.cmdPrint(File.expand_path(options['print']), options['degrees'], snap_to_degrees, - options['snap_tolerance'])) + options['snap_tolerance'], + options['preserve_includes'], + precision)) elsif options.key?('graph') Importer.extern 'int cmdGraph(const char *, const char *)' exit(Importer.cmdGraph(options['graph'][:type], File.expand_path(ARGV[1]))) diff --git a/src/ign.cc b/src/ign.cc index 23f9625e8..b68efc950 100644 --- a/src/ign.cc +++ b/src/ign.cc @@ -134,7 +134,8 @@ extern "C" SDFORMAT_VISIBLE int cmdDescribe(const char *_version) ////////////////////////////////////////////////// extern "C" SDFORMAT_VISIBLE int cmdPrint(const char *_path, - int inDegrees, int snapToDegrees, float snapTolerance) + int _inDegrees, int _snapToDegrees, float _snapTolerance, + int _preserveIncludes, int _outPrecision) { if (!sdf::filesystem::exists(_path)) { @@ -157,47 +158,24 @@ extern "C" SDFORMAT_VISIBLE int cmdPrint(const char *_path, } sdf::PrintConfig config; - if (inDegrees!= 0) + if (_inDegrees != 0) { config.SetRotationInDegrees(true); } - if (snapToDegrees > 0) - { - config.SetRotationSnapToDegrees(static_cast(snapToDegrees), - static_cast(snapTolerance)); - } - sdf->PrintValues(config); - return 0; -} - -////////////////////////////////////////////////// -extern "C" SDFORMAT_VISIBLE int cmdPrintPreserveIncludes(const char *_path) -{ - if (!sdf::filesystem::exists(_path)) + if (_snapToDegrees > 0) { - std::cerr << "Error: File [" << _path << "] does not exist.\n"; - return -1; + config.SetRotationSnapToDegrees(static_cast(_snapToDegrees), + static_cast(_snapTolerance)); } - sdf::SDFPtr sdf(new sdf::SDF()); + if (_preserveIncludes != 0) + config.SetPreserveIncludes(true); - if (!sdf::init(sdf)) - { - std::cerr << "Error: SDF schema initialization failed.\n"; - return -1; - } - - if (!sdf::readFile(_path, sdf)) - { - std::cerr << "Error: SDF parsing the xml failed.\n"; - return -1; - } + if (_outPrecision > 0) + config.SetOutPrecision(_outPrecision); - sdf::PrintConfig config; - config.SetPreserveIncludes(true); sdf->PrintValues(config); - return 0; } diff --git a/src/ign_TEST.cc b/src/ign_TEST.cc index a60c9c525..1e649e7f5 100644 --- a/src/ign_TEST.cc +++ b/src/ign_TEST.cc @@ -962,14 +962,15 @@ TEST(print_rotations_in_degrees, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // Default printing std::string output = custom_exec_str( - IgnCommand() + " sdf -p " + path + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "1 2 3 30.009 44.991 -60.009"); // Printing with in_degrees output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --degrees " + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --degrees " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -977,8 +978,8 @@ TEST(print_rotations_in_degrees, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // Printing with snap_to_degrees 5 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 5 " + - SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 5 " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -986,8 +987,8 @@ TEST(print_rotations_in_degrees, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // Printing with snap_to_degrees 2 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 2 " + - SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 2 " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -995,8 +996,8 @@ TEST(print_rotations_in_degrees, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // Printing with snap_to_degrees 20 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 20 " + - SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 20 " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1004,8 +1005,8 @@ TEST(print_rotations_in_degrees, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // Printing with snap_to_degrees 5, snap_tolerance 0.008 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 5 " + - "--snap-tolerance 0.008 " + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 5 " + + "--snap-tolerance 0.008 " + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1029,14 +1030,15 @@ TEST(print_rotations_in_radians, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // Default printing std::string output = custom_exec_str( - IgnCommand() + " sdf -p " + path + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "1 2 3 0.523756 0.785241 -1.04735"); // Printing with in_degrees output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --degrees " + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --degrees " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1044,8 +1046,8 @@ TEST(print_rotations_in_radians, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // Printing with snap_to_degrees 5 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 5 " + - SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 5 " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1053,8 +1055,8 @@ TEST(print_rotations_in_radians, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // Printing with snap_to_degrees 2 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 2 " + - SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 2 " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1062,8 +1064,8 @@ TEST(print_rotations_in_radians, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // Printing with snap_to_degrees 20 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 20 " + - SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 20 " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1071,8 +1073,8 @@ TEST(print_rotations_in_radians, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // Printing with snap_to_degrees 5, snap_tolerance 0.008 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 5 " + - "--snap-tolerance 0.008 " + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 5 " + + "--snap-tolerance 0.008 " + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1096,7 +1098,7 @@ TEST(print_rotations_in_quaternions, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // Default printing std::string output = custom_exec_str( - IgnCommand() + " sdf -p " + path + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1104,7 +1106,8 @@ TEST(print_rotations_in_quaternions, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // Printing with in_degrees output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --degrees " + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --degrees " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1121,8 +1124,8 @@ TEST(print_rotations_in_quaternions, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // Printing with snap_to_degrees 2 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 2 " + - SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 2 " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1130,8 +1133,8 @@ TEST(print_rotations_in_quaternions, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // Printing with snap_to_degrees 20 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 20 " + - SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 20 " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1139,8 +1142,8 @@ TEST(print_rotations_in_quaternions, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // Printing with snap_to_degrees 5, snap_tolerance 0.008 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 5 " + - "--snap-tolerance 0.008 " + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 5 " + + "--snap-tolerance 0.008 " + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1167,14 +1170,15 @@ TEST(print_includes_rotations_in_degrees, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // Default printing std::string output = custom_exec_str( - IgnCommand() + " sdf -p " + path + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "1 2 3 30.009 44.991 -60.009"); // Printing with in_degrees output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --degrees " + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --degrees " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1191,8 +1195,8 @@ TEST(print_includes_rotations_in_degrees, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // Printing with snap_to_degrees 2 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 2 " + - SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 2 " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1200,8 +1204,8 @@ TEST(print_includes_rotations_in_degrees, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // Printing with snap_to_degrees 20 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 20 " + - SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 20 " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1209,8 +1213,8 @@ TEST(print_includes_rotations_in_degrees, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // Printing with snap_to_degrees 5, snap_tolerance 0.008 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 5 " + - "--snap-tolerance 0.008 " + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 5 " + + "--snap-tolerance 0.008 " + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1237,14 +1241,15 @@ TEST(print_includes_rotations_in_radians, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // Default printing std::string output = custom_exec_str( - IgnCommand() + " sdf -p " + path + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "1 2 3 0.523756 0.785241 -1.04735"); // Printing with in_degrees output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --degrees " + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --degrees " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1261,8 +1266,8 @@ TEST(print_includes_rotations_in_radians, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // Printing with snap_to_degrees 2 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 2 " + - SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 2 " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1270,8 +1275,8 @@ TEST(print_includes_rotations_in_radians, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // Printing with snap_to_degrees 20 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 20 " + - SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 20 " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1279,8 +1284,8 @@ TEST(print_includes_rotations_in_radians, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // Printing with snap_to_degrees 5, snap_tolerance 0.008 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 5 " + - "--snap-tolerance 0.008 " + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 5 " + + "--snap-tolerance 0.008 " + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1308,7 +1313,7 @@ TEST(print_includes_rotations_in_quaternions, // Default printing std::string output = custom_exec_str( - IgnCommand() + " sdf -p " + path + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1316,7 +1321,8 @@ TEST(print_includes_rotations_in_quaternions, // Printing with in_degrees output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --degrees " + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --degrees " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1333,8 +1339,8 @@ TEST(print_includes_rotations_in_quaternions, // Printing with snap_to_degrees 2 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 2 " + - SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 2 " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1342,8 +1348,8 @@ TEST(print_includes_rotations_in_quaternions, // Printing with snap_to_degrees 20 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 20 " + - SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 20 " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1351,8 +1357,8 @@ TEST(print_includes_rotations_in_quaternions, // Printing with snap_to_degrees 5, snap_tolerance 0.008 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 5 " + - "--snap-tolerance 0.008 " + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 5 " + + "--snap-tolerance 0.008 " + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1380,14 +1386,15 @@ TEST(print_rotations_in_unnormalized_degrees, // returned by parsing the pose value, whenever a parent Element Attribute, // or PrintConfig is used. std::string output = custom_exec_str( - IgnCommand() + " sdf -p " + path + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "1 2 3 30.009 44.991 -60.009"); // Printing with in_degrees output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --degrees " + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --degrees " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1404,8 +1411,8 @@ TEST(print_rotations_in_unnormalized_degrees, // Printing with snap_to_degrees 2 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 2 " + - SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 2 " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1413,8 +1420,8 @@ TEST(print_rotations_in_unnormalized_degrees, // Printing with snap_to_degrees 20 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 20 " + - SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 20 " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1422,8 +1429,8 @@ TEST(print_rotations_in_unnormalized_degrees, // Printing with snap_to_degrees 5, snap_tolerance 0.008 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 5 " + - "--snap-tolerance 0.008 " + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 5 " + + "--snap-tolerance 0.008 " + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1448,14 +1455,15 @@ TEST(print_rotations_in_unnormalized_radians, // Default printing std::string output = custom_exec_str( - IgnCommand() + " sdf -p " + path + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, - "1 2 3 -5.75943 -11.78112 5.23583"); + "1 2 3 0.523755 0.785251 -1.04736"); // Printing with in_degrees output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --degrees " + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --degrees " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1472,8 +1480,8 @@ TEST(print_rotations_in_unnormalized_radians, // Printing with snap_to_degrees 2 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 2 " + - SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 2 " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1481,8 +1489,8 @@ TEST(print_rotations_in_unnormalized_radians, // Printing with snap_to_degrees 20 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 20 " + - SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 20 " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1490,8 +1498,8 @@ TEST(print_rotations_in_unnormalized_radians, // Printing with snap_to_degrees 5, snap_tolerance 0.008 output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --snap-to-degrees 5 " + - "--snap-tolerance 0.008 " + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --snap-to-degrees 5 " + + "--snap-tolerance 0.008 " + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1515,7 +1523,8 @@ TEST(shuffled_cmd_flags, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // -p PATH --degrees std::string output = custom_exec_str( - IgnCommand() + " sdf -p " + path + " --degrees " + SdfVersion()); + IgnCommand() + " sdf -p --precision 6 " + path + " --degrees " + + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" @@ -1523,7 +1532,7 @@ TEST(shuffled_cmd_flags, IGN_UTILS_TEST_DISABLED_ON_WIN32(SDF)) // --degrees -p PATH output = custom_exec_str( - IgnCommand() + " sdf --degrees -p " + path + SdfVersion()); + IgnCommand() + " sdf --degrees -p --precision 6 " + path + SdfVersion()); ASSERT_FALSE(output.empty()); EXPECT_PRED2(contains, output, "" diff --git a/test/integration/default_elements.cc b/test/integration/default_elements.cc index 7785d5490..b93821ac0 100644 --- a/test/integration/default_elements.cc +++ b/test/integration/default_elements.cc @@ -214,8 +214,10 @@ TEST(ExplicitlySetInFile, ToString) << " \n" << "\n"; - EXPECT_EQ(root.Element()->ToString(""), stream.str()); - EXPECT_EQ(root.Element()->ToString("", true, false), stream.str()); + sdf::PrintConfig config; + config.SetOutPrecision(6); + EXPECT_EQ(root.Element()->ToString("", config), stream.str()); + EXPECT_EQ(root.Element()->ToString("", true, false, config), stream.str()); stream.str(std::string()); stream @@ -249,5 +251,5 @@ TEST(ExplicitlySetInFile, ToString) << " \n" << "\n"; - EXPECT_EQ(root.Element()->ToString("", true, true), stream.str()); + EXPECT_EQ(root.Element()->ToString("", true, true, config), stream.str()); } diff --git a/test/integration/model/test_model_with_frames_no_rotations/model.config b/test/integration/model/test_model_with_frames_no_rotations/model.config new file mode 100644 index 000000000..33e622b95 --- /dev/null +++ b/test/integration/model/test_model_with_frames_no_rotations/model.config @@ -0,0 +1,6 @@ + + + + test_model_with_frames + model.sdf + diff --git a/test/integration/model/test_model_with_frames_no_rotations/model.sdf b/test/integration/model/test_model_with_frames_no_rotations/model.sdf new file mode 100644 index 000000000..769175115 --- /dev/null +++ b/test/integration/model/test_model_with_frames_no_rotations/model.sdf @@ -0,0 +1,69 @@ + + + + + 0.12345 0 0 0 0 0 + + + 0 1.2345 0 0 0 0 + + + + + + + + 1.5707963267948966 + + + + + + + + 0.78539816339744828 + + + + + + 1 0 0 0 0 0 + + + 0 1 0 0 0 0 + + + 0 0 1 0 0 0 + + + + L1 + L2 + + 0 0 1 + + + 1 0 0 + + + + 0 0 1 0 0 0 + L2 + L3 + + 0 0 1 + + + + 1 0 1 0 0 0 + L3 + L4 + + + 1 0 0 0 0 0 + + 1 0 0 0 0 0 + + + + diff --git a/test/integration/model/test_nested_model_with_frames/model.sdf b/test/integration/model/test_nested_model_with_frames/model.sdf index b28a42b4f..7716ebeea 100644 --- a/test/integration/model/test_nested_model_with_frames/model.sdf +++ b/test/integration/model/test_nested_model_with_frames/model.sdf @@ -3,8 +3,8 @@ - test_model_with_frames - 0 10 0 1.570796326794895 0 0 + test_model_with_frames_no_rotations + 0 10 0 0 0 0 diff --git a/test/integration/nested_model.cc b/test/integration/nested_model.cc index d6056274d..935345fc4 100644 --- a/test/integration/nested_model.cc +++ b/test/integration/nested_model.cc @@ -574,15 +574,15 @@ void prepareForDirectComparison(sdf::ElementPtr _worldElem) } ////////////////////////////////////////////////// -// Test parsing models with child models containg frames nested via +// Test parsing models with child models containing frames nested via // Compare parsed SDF with expected string TEST(NestedModel, NestedModelWithFramesDirectComparison) { - const std::string name = "test_model_with_frames"; + const std::string name = "test_model_with_frames_no_rotations"; const std::string modelPath = sdf::testing::TestFile("integration", "model", name); - const ignition::math::Pose3d model1Pose(10, 0, 0, 0, 0, IGN_PI/2); + const ignition::math::Pose3d model1Pose(10, 0, 0, 0, 0, 0); std::ostringstream stream; std::string version = "1.7"; @@ -731,7 +731,7 @@ TEST(NestedModel, TwoLevelNestedModelWithFramesDirectComparison) const std::string modelPath = sdf::testing::TestFile( "integration", "model", name); - const ignition::math::Pose3d model1Pose(10, 0, 0, 0, 0, IGN_PI/2); + const ignition::math::Pose3d model1Pose(10, 0, 0, 0, 0, 0); std::ostringstream stream; std::string version = "1.7"; diff --git a/test/integration/nested_model_with_frames_expected.sdf b/test/integration/nested_model_with_frames_expected.sdf index 04cf0cf89..078f6f7db 100644 --- a/test/integration/nested_model_with_frames_expected.sdf +++ b/test/integration/nested_model_with_frames_expected.sdf @@ -4,10 +4,10 @@ - 0 0 0 1.570796 0 0 + 0.12345 0 0 0 0 0 - 0 0 0 0 0.785398 0 + 0 1.2344999999999999 0 0 0 0 0 0 0 0 0 0 @@ -67,7 +67,7 @@ 1 0 0 0 0 0 - 10 0 0 0 0 1.5708 + 10 0 0 0 0 0 diff --git a/test/integration/pose_1_9_sdf.cc b/test/integration/pose_1_9_sdf.cc index d806401d7..c0c16f104 100644 --- a/test/integration/pose_1_9_sdf.cc +++ b/test/integration/pose_1_9_sdf.cc @@ -764,7 +764,9 @@ TEST(Pose1_9, ToStringWithoutAttrib) ASSERT_NE(nullptr, poseValueParam); EXPECT_TRUE(poseValueParam->SetFromString("1 2 3 0.4 0.5 0.6")); - std::string elemStr = poseElem->ToString(""); + sdf::PrintConfig config; + config.SetOutPrecision(6); + std::string elemStr = poseElem->ToString("", config); EXPECT_PRED2(contains, elemStr, "0.4 0.5 0.6"); } @@ -786,7 +788,9 @@ TEST(Pose1_9, ToStringWithDegreesFalse) ASSERT_NE(nullptr, poseValueParam); EXPECT_TRUE(poseValueParam->SetFromString("1 2 3 0.4 0.5 0.6")); - std::string elemStr = poseElem->ToString(""); + sdf::PrintConfig config; + config.SetOutPrecision(6); + std::string elemStr = poseElem->ToString("", config); EXPECT_PRED2(contains, elemStr, "degrees='false'"); EXPECT_PRED2(contains, elemStr, "0.4 0.5 0.6"); } @@ -809,7 +813,9 @@ TEST(Pose1_9, ToStringWithDegreesTrue) ASSERT_NE(nullptr, poseValueParam); EXPECT_TRUE(poseValueParam->SetFromString("1 2 3 0.4 0.5 0.6")); - std::string elemStr = poseElem->ToString(""); + sdf::PrintConfig config; + config.SetOutPrecision(6); + std::string elemStr = poseElem->ToString("", config); EXPECT_PRED2(contains, elemStr, "degrees='true'"); EXPECT_PRED2(contains, elemStr, "0.4 0.5 0.6"); } @@ -833,7 +839,9 @@ TEST(Pose1_9, ToStringWithEulerRPY) ASSERT_NE(nullptr, poseValueParam); EXPECT_TRUE(poseValueParam->SetFromString("1 2 3 0.4 0.5 0.6")); - std::string elemStr = poseElem->ToString(""); + sdf::PrintConfig config; + config.SetOutPrecision(6); + std::string elemStr = poseElem->ToString("", config); EXPECT_PRED2(contains, elemStr, "rotation_format='euler_rpy'"); EXPECT_PRED2(contains, elemStr, "0.4 0.5 0.6"); } @@ -861,7 +869,9 @@ TEST(Pose1_9, ToStringWithEulerRPYDegreesTrue) ASSERT_NE(nullptr, poseValueParam); EXPECT_TRUE(poseValueParam->SetFromString("1 2 3 0.4 0.5 0.6")); - std::string elemStr = poseElem->ToString(""); + sdf::PrintConfig config; + config.SetOutPrecision(6); + std::string elemStr = poseElem->ToString("", config); EXPECT_PRED2(contains, elemStr, "degrees='true'"); EXPECT_PRED2(contains, elemStr, "rotation_format='euler_rpy'"); EXPECT_PRED2(contains, elemStr, "0.4 0.5 0.6"); @@ -886,9 +896,11 @@ TEST(Pose1_9, ToStringWithQuatXYZ) ASSERT_NE(nullptr, poseValueParam); EXPECT_TRUE(poseValueParam->SetFromString("1 2 3 0.7071068 0 0 0.7071068")); + sdf::PrintConfig config; + config.SetOutPrecision(6); // The string output has changed as it was parsed from the value, instead of // the original string. - std::string elemStr = poseElem->ToString(""); + std::string elemStr = poseElem->ToString("", config); EXPECT_PRED2(contains, elemStr, "rotation_format='quat_xyzw'"); EXPECT_PRED2(contains, elemStr, "0.707107 0 0 0.707107"); } @@ -916,9 +928,11 @@ TEST(Pose1_9, ToStringWithQuatXYZWDegreesFalse) ASSERT_NE(nullptr, poseValueParam); EXPECT_TRUE(poseValueParam->SetFromString("1 2 3 0.7071068 0 0 0.7071068")); + sdf::PrintConfig config; + config.SetOutPrecision(6); // The string output has changed as it was parsed from the value, instead of // the original string. - std::string elemStr = poseElem->ToString(""); + std::string elemStr = poseElem->ToString("", config); EXPECT_PRED2(contains, elemStr, "degrees='false'"); EXPECT_PRED2(contains, elemStr, "rotation_format='quat_xyzw'"); EXPECT_PRED2(contains, elemStr, "0.707107 0 0 0.707107"); @@ -939,7 +953,9 @@ TEST(Pose1_9, ToStringAfterChangingDegreeAttribute) ASSERT_NE(nullptr, valParam); ASSERT_TRUE(valParam->SetFromString("1 2 3 0.4 0.5 0.6")); - std::string elemStr = poseElem->ToString(""); + sdf::PrintConfig config; + config.SetOutPrecision(6); + std::string elemStr = poseElem->ToString("", config); EXPECT_PRED2(contains, elemStr, "0.4 0.5 0.6"); // Changing to attribute to degrees, however this does not modify the @@ -950,13 +966,14 @@ TEST(Pose1_9, ToStringAfterChangingDegreeAttribute) ASSERT_TRUE(degreesAttrib->Set(true)); EXPECT_TRUE(valParam->Reparse()); - elemStr = poseElem->ToString(""); + elemStr = poseElem->ToString("", config); EXPECT_PRED2(contains, elemStr, "degrees='true'"); EXPECT_PRED2(contains, elemStr, "0.4 0.5 0.6"); // Changing back to radians ASSERT_TRUE(degreesAttrib->Set(false)); - elemStr = poseElem->ToString(""); + EXPECT_TRUE(valParam->Reparse()); + elemStr = poseElem->ToString("", config); EXPECT_PRED2(contains, elemStr, "degrees='false'"); EXPECT_PRED2(contains, elemStr, "0.4 0.5 0.6"); } diff --git a/test/integration/print_config.cc b/test/integration/print_config.cc index 511b6b69e..12c6b8753 100644 --- a/test/integration/print_config.cc +++ b/test/integration/print_config.cc @@ -17,6 +17,8 @@ #include +#include +#include #include #include @@ -136,6 +138,7 @@ R"( )"; sdf::PrintConfig config; + config.SetOutPrecision(6); // by default, included model should be expanded EXPECT_EQ(includedModel->Element()->ToString("", config), expandedIncludeStr); EXPECT_EQ(modelWithInclude->Element()->ToString("", config), @@ -224,3 +227,190 @@ R"( EXPECT_EQ(includeMergedModel->Element()->ToString("", config), expectedIncludeMerge); } + +void PrecisionTest(const sdf::ElementPtr _elem, + const std::map &_expected) +{ + ASSERT_NE(_elem, nullptr); + + EXPECT_EQ(_elem->GetValue()->GetAsString(), _expected.at("default")); + + sdf::PrintConfig config; + config.SetOutPrecision(6); + EXPECT_EQ(_elem->GetValue()->GetAsString(config), _expected.at("6")); + + config.SetOutPrecision(2); + EXPECT_EQ(_elem->GetValue()->GetAsString(config), _expected.at("2")); + + config.SetOutPrecision(std::numeric_limits::max()); + EXPECT_EQ(_elem->GetValue()->GetAsString(config), _expected.at("default")); +} + +///////////////////////////////////////////////// +TEST(PrintConfig, OutPrecision) +{ + const std::string sdfStr = +R"( + + + + + + + 1 1.0 -1.5707963267948966 + 0.707106781 0 0 0.707106781 + + + + 1.23456789123456789 + + + + 0.15 0.6 0.87525741223854215 1 + 0.16 + + 0.15 + + + + 1.4 + + 0.15 + + +
0.1512345678912345678 1.4
+
+
+
+ + + world + L1 + + 1.5707963267948966 0.34 0.56 + + +
+
+
+)"; + + sdf::Root root; + sdf::Errors errors = root.LoadSdfString(sdfStr); + EXPECT_TRUE(errors.empty()) << errors; + + auto *world = root.WorldByIndex(0); + ASSERT_NE(world, nullptr); + auto *model = world->ModelByIndex(0); + ASSERT_NE(model, nullptr); + auto *link = model->LinkByIndex(0); + ASSERT_NE(link, nullptr); + auto *visual = link->VisualByIndex(0); + ASSERT_NE(visual, nullptr); + + + // Below we are comparing default (maximum) then setting the precision + // to 6 (std::ostream's default), 2, and then back to max. + // Used this IEEE 754 floating point converter to determine expected strings: + // https://baseconvert.com/ieee-754-floating-point + // double (64 bit) has max of 17 digits + // float (32 bit) has max of 9 digits + + // key: precision, value: expected string + std::map expected = { + {"default", ""}, + {"6", ""}, + {"2", ""} + }; + sdf::ElementPtr elem; + + // //pose -> type: ignition::math::Pose3d + { + SCOPED_TRACE("PrecisionTest: Pose3d"); + elem = visual->Element()->FindElement("pose"); + expected["default"] = + "1 1 -1.5707963267948966 " + "0.70710678100000002 0 0 0.70710678100000002"; + expected["6"] = "1 1 -1.5708 0.707107 0 0 0.707107"; + expected["2"] = "1 1 -1.6 0.71 0 0 0.71"; + + PrecisionTest(elem, expected); + } + + // //radius -> type: double + { + auto *geom = visual->Geom(); + ASSERT_NE(geom, nullptr); + auto *sphere = geom->SphereShape(); + ASSERT_NE(sphere, nullptr); + + SCOPED_TRACE("PrecisionTest: double"); + elem = sphere->Element()->FindElement("radius"); + expected["default"] = "1.2345678912345679"; + expected["6"] = "1.23457"; + expected["2"] = "1.2"; + + PrecisionTest(elem, expected); + } + + auto *material = visual->Material(); + ASSERT_NE(material, nullptr); + + // //material/diffuse -> type: ignition::math::Color (float values) + { + SCOPED_TRACE("PrecisionTest: Color"); + elem = material->Element()->FindElement("diffuse"); + expected["default"] = + "0.150000006 0.600000024 0.875257432 1"; + expected["6"] = "0.15 0.6 0.875257 1"; + expected["2"] = "0.15 0.6 0.88 1"; + + PrecisionTest(elem, expected); + } + + // //material/render_order -> type: float + { + SCOPED_TRACE("PrecisionTest: float"); + elem = material->Element()->FindElement("render_order"); + expected["default"] = "0.159999996"; + expected["6"] = "0.16"; + expected["2"] = "0.16"; + + PrecisionTest(elem, expected); + } + + // //camera/distortion/center -> type: ignition::math::Vector2d + { + auto *sensor = link->SensorByIndex(0); + ASSERT_NE(sensor, nullptr); + auto *camera = sensor->CameraSensor(); + ASSERT_NE(camera, nullptr); + elem = camera->Element()->FindElement("distortion"); + ASSERT_NE(elem, nullptr); + + SCOPED_TRACE("PrecisionTest: Vector2d"); + elem = elem->FindElement("center"); + expected["default"] = "0.15123456789123457 1.3999999999999999"; + expected["6"] = "0.151235 1.4"; + expected["2"] = "0.15 1.4"; + + PrecisionTest(elem, expected); + } + + // //joint/axis/xyz -> type: ignition::math::Vector3d + { + auto *joint = model->JointByIndex(0); + ASSERT_NE(joint, nullptr); + auto *axis = joint->Axis(0); + ASSERT_NE(axis, nullptr); + + SCOPED_TRACE("PrecisionTest: Vector3d"); + elem = axis->Element()->FindElement("xyz"); + expected["default"] = + "1.5707963267948966 0.34000000000000002 0.56000000000000005"; + expected["6"] = "1.5708 0.34 0.56"; + expected["2"] = "1.6 0.34 0.56"; + + PrecisionTest(elem, expected); + } +} diff --git a/test/integration/two_level_nested_model_with_frames_expected.sdf b/test/integration/two_level_nested_model_with_frames_expected.sdf index 34bc32674..a0b97a805 100644 --- a/test/integration/two_level_nested_model_with_frames_expected.sdf +++ b/test/integration/two_level_nested_model_with_frames_expected.sdf @@ -5,10 +5,10 @@ - 0 0 0 1.570796 0 0 + 0.12345 0 0 0 0 0 - 0 0 0 0 0.785398 0 + 0 1.2344999999999999 0 0 0 0 0 0 0 0 0 0 @@ -68,9 +68,9 @@ 1 0 0 0 0 0 - 0 10 0 1.570796326794895 0 0 + 0 10 0 0 0 0 - 10 0 0 0 0 1.5708 + 10 0 0 0 0 0