diff --git a/include/sdf/AirPressure.hh b/include/sdf/AirPressure.hh index 5117a6e1a..798474dd5 100644 --- a/include/sdf/AirPressure.hh +++ b/include/sdf/AirPressure.hh @@ -91,6 +91,14 @@ namespace sdf /// \return SDF element pointer with updated sensor values. public: sdf::ElementPtr ToElement() const; + /// \brief Create and return an SDF element filled with data from this + /// air pressure sensor. + /// Note that parameter passing functionality is not captured with this + /// function. + /// \param[out] _errors Vector of errors. + /// \return SDF element pointer with updated sensor values. + public: sdf::ElementPtr ToElement(sdf::Errors &_errors) const; + /// \brief Private data pointer. GZ_UTILS_IMPL_PTR(dataPtr) }; diff --git a/src/AirPressure.cc b/src/AirPressure.cc index 26c4b7c8e..9cc58a8a0 100644 --- a/src/AirPressure.cc +++ b/src/AirPressure.cc @@ -18,6 +18,7 @@ #include #include "sdf/AirPressure.hh" #include "sdf/parser.hh" +#include "Utils.hh" using namespace sdf; @@ -60,13 +61,13 @@ Errors AirPressure::Load(ElementPtr _sdf) // Load the noise values. if (_sdf->HasElement("pressure")) { - sdf::ElementPtr elem = _sdf->GetElement("pressure"); + sdf::ElementPtr elem = _sdf->GetElement("pressure", errors); if (elem->HasElement("noise")) - this->dataPtr->noise.Load(elem->GetElement("noise")); + this->dataPtr->noise.Load(elem->GetElement("noise", errors)); } - this->dataPtr->referenceAltitude = _sdf->Get("reference_altitude", - this->dataPtr->referenceAltitude).first; + this->dataPtr->referenceAltitude = _sdf->Get( + errors, "reference_altitude", this->dataPtr->referenceAltitude).first; return errors; } @@ -117,15 +118,24 @@ void AirPressure::SetPressureNoise(const Noise &_noise) ///////////////////////////////////////////////// sdf::ElementPtr AirPressure::ToElement() const +{ + sdf::Errors errors; + auto result = this->ToElement(errors); + sdf::throwOrPrintErrors(errors); + return result; +} + +///////////////////////////////////////////////// +sdf::ElementPtr AirPressure::ToElement(sdf::Errors &_errors) const { sdf::ElementPtr elem(new sdf::Element); sdf::initFile("air_pressure.sdf", elem); - elem->GetElement("reference_altitude")->Set( - this->ReferenceAltitude()); - sdf::ElementPtr pressureElem = elem->GetElement("pressure"); - sdf::ElementPtr noiseElem = pressureElem->GetElement("noise"); - noiseElem->Copy(this->dataPtr->noise.ToElement()); + elem->GetElement("reference_altitude", _errors)->Set( + _errors, this->ReferenceAltitude()); + sdf::ElementPtr pressureElem = elem->GetElement("pressure", _errors); + sdf::ElementPtr noiseElem = pressureElem->GetElement("noise", _errors); + noiseElem->Copy(this->dataPtr->noise.ToElement(_errors), _errors); return elem; } diff --git a/src/AirPressure_TEST.cc b/src/AirPressure_TEST.cc index fff895faf..076d6c7fc 100644 --- a/src/AirPressure_TEST.cc +++ b/src/AirPressure_TEST.cc @@ -17,6 +17,7 @@ #include #include "sdf/AirPressure.hh" +#include "test_utils.hh" ///////////////////////////////////////////////// TEST(DOMAirPressure, Construction) @@ -131,3 +132,61 @@ TEST(DOMAirPressure, ToElement) air3.Load(air2Elem); EXPECT_DOUBLE_EQ(111.0, air3.ReferenceAltitude()); } + +///////////////////////////////////////////////// +TEST(DOMAirPressure, ToElementErrorOutput) +{ + std::stringstream buffer; + sdf::testing::RedirectConsoleStream redir( + sdf::Console::Instance()->GetMsgStream(), &buffer); + + #ifdef _WIN32 + sdf::Console::Instance()->SetQuiet(false); + sdf::testing::ScopeExit revertSetQuiet( + [] + { + sdf::Console::Instance()->SetQuiet(true); + }); + #endif + + // test calling ToElement on a DOM object constructed without calling Load + sdf::AirPressure air; + sdf::Noise noise; + sdf::Errors errors; + air.SetReferenceAltitude(10.2); + noise.SetType(sdf::NoiseType::GAUSSIAN); + noise.SetMean(1.2); + noise.SetStdDev(2.3); + noise.SetBiasMean(4.5); + noise.SetBiasStdDev(6.7); + noise.SetPrecision(8.9); + air.SetPressureNoise(noise); + + sdf::ElementPtr airElem = air.ToElement(errors); + EXPECT_TRUE(errors.empty()); + EXPECT_NE(nullptr, airElem); + EXPECT_EQ(nullptr, air.Element()); + + // verify values after loading the element back + sdf::AirPressure air2; + errors = air2.Load(airElem); + EXPECT_TRUE(errors.empty()); + + EXPECT_DOUBLE_EQ(noise.Mean(), air2.PressureNoise().Mean()); + EXPECT_DOUBLE_EQ(noise.StdDev(), air2.PressureNoise().StdDev()); + EXPECT_DOUBLE_EQ(noise.BiasMean(), air2.PressureNoise().BiasMean()); + EXPECT_DOUBLE_EQ(noise.BiasStdDev(), air2.PressureNoise().BiasStdDev()); + EXPECT_DOUBLE_EQ(noise.Precision(), air2.PressureNoise().Precision()); + EXPECT_DOUBLE_EQ(10.2, air2.ReferenceAltitude()); + + // make changes to DOM and verify ToElement produces updated values + air2.SetReferenceAltitude(111); + sdf::ElementPtr air2Elem = air2.ToElement(); + EXPECT_NE(nullptr, air2Elem); + sdf::AirPressure air3; + air3.Load(air2Elem); + EXPECT_DOUBLE_EQ(111.0, air3.ReferenceAltitude()); + + // Check nothing has been printed + EXPECT_TRUE(buffer.str().empty()) << buffer.str(); +}