32 #include <boost/algorithm/string.hpp>
33 #include <Eigen/Geometry>
42 Eigen::Isometry3d
parseOrigin(
const tinyxml2::XMLElement* xml_element)
44 Eigen::Isometry3d origin = Eigen::Isometry3d::Identity();
46 if (xml_element->Attribute(
"xyz") ==
nullptr && xml_element->Attribute(
"rpy") ==
nullptr &&
47 xml_element->Attribute(
"wxyz") ==
nullptr)
48 std::throw_with_nested(std::runtime_error(
"Origin: Error missing required attributes 'xyz' and 'rpy' and/or 'wxyz' "
49 "for origin element!"));
51 std::string xyz_string, rpy_string, wxyz_string;
53 if (status != tinyxml2::XML_NO_ATTRIBUTE && status != tinyxml2::XML_SUCCESS)
54 std::throw_with_nested(std::runtime_error(
"Origin: Failed to parse attribute 'xyz'!"));
56 if (status != tinyxml2::XML_NO_ATTRIBUTE)
58 std::vector<std::string> tokens;
59 boost::split(tokens, xyz_string, boost::is_any_of(
" "), boost::token_compress_on);
61 std::throw_with_nested(std::runtime_error(
"Origin: Failed to parse attribute 'xyz' string!"));
63 double x{ 0 }, y{ 0 }, z{ 0 };
69 origin.translation() = Eigen::Vector3d(x, y, z);
72 if (xml_element->Attribute(
"wxyz") ==
nullptr)
75 if (status != tinyxml2::XML_NO_ATTRIBUTE && status != tinyxml2::XML_SUCCESS)
76 std::throw_with_nested(std::runtime_error(
"Origin: Failed to parse attribute 'rpy'!"));
78 if (status != tinyxml2::XML_NO_ATTRIBUTE)
80 std::vector<std::string> tokens;
81 boost::split(tokens, rpy_string, boost::is_any_of(
" "), boost::token_compress_on);
83 std::throw_with_nested(std::runtime_error(
"Origin: Failed to parse attribute 'rpy' string!"));
85 double r{ 0 }, p{ 0 }, y{ 0 };
91 Eigen::AngleAxisd rollAngle(
r, Eigen::Vector3d::UnitX());
92 Eigen::AngleAxisd pitchAngle(p, Eigen::Vector3d::UnitY());
93 Eigen::AngleAxisd yawAngle(y, Eigen::Vector3d::UnitZ());
95 Eigen::Quaterniond rpy{ yawAngle * pitchAngle * rollAngle };
97 origin.linear() = rpy.toRotationMatrix();
103 if (status != tinyxml2::XML_NO_ATTRIBUTE && status != tinyxml2::XML_SUCCESS)
104 std::throw_with_nested(std::runtime_error(
"Origin: Failed to parse attribute 'wxyz'!"));
106 if (status != tinyxml2::XML_NO_ATTRIBUTE)
108 std::vector<std::string> tokens;
109 boost::split(tokens, wxyz_string, boost::is_any_of(
" "), boost::token_compress_on);
111 std::throw_with_nested(std::runtime_error(
"Origin: Failed to parse attribute 'wxyz' string!"));
113 double qw{ 0 }, qx{ 0 }, qy{ 0 }, qz{ 0 };
120 Eigen::Quaterniond q(qw, qx, qy, qz);
123 origin.linear() = q.toRotationMatrix();
129 tinyxml2::XMLElement*
writeOrigin(
const Eigen::Isometry3d& origin, tinyxml2::XMLDocument& doc)
132 Eigen::IOFormat eigen_format(Eigen::StreamPrecision, Eigen::DontAlignCols,
" ",
" ");
135 if (!origin.translation().isZero(std::numeric_limits<double>::epsilon()))
137 std::stringstream xyz_string;
138 xyz_string << origin.translation().format(eigen_format);
139 xml_element->SetAttribute(
"xyz", xyz_string.str().c_str());
143 if (!origin.linear().isIdentity(std::numeric_limits<double>::epsilon()))
145 Eigen::Vector3d ypr = origin.linear().eulerAngles(2, 1, 0);
146 Eigen::Vector3d rpy(ypr.z(), ypr.y(), ypr.x());
147 std::stringstream rpy_string;
148 rpy_string << rpy.format(eigen_format);
149 xml_element->SetAttribute(
"rpy", rpy_string.str().c_str());