group_tool_center_points.cpp
Go to the documentation of this file.
1 
29 #include <tinyxml2.h>
30 #include <boost/algorithm/string/classification.hpp>
31 #include <boost/algorithm/string/split.hpp>
33 
34 #include <tesseract_common/utils.h>
37 
38 namespace tesseract_srdf
39 {
48  const tinyxml2::XMLElement* srdf_xml,
49  const std::array<int, 3>& /*version*/)
50 {
52 
53  GroupTCPs group_tcps;
54  for (const tinyxml2::XMLElement* xml_group_element = srdf_xml->FirstChildElement("group_tcps");
55  xml_group_element != nullptr;
56  xml_group_element = xml_group_element->NextSiblingElement("group_tcps"))
57  {
58  std::string group_name_string;
59  int status = tesseract_common::QueryStringAttributeRequired(xml_group_element, "group", group_name_string);
60  if (status != tinyxml2::XML_SUCCESS)
61  std::throw_with_nested(std::runtime_error("GroupTCPs: Missing or failed to parse attribute 'group'!"));
62 
63  for (const tinyxml2::XMLElement* xml_element = xml_group_element->FirstChildElement("tcp"); xml_element != nullptr;
64  xml_element = xml_element->NextSiblingElement("tcp"))
65  {
66  Eigen::Isometry3d tcp = Eigen::Isometry3d::Identity();
67 
68  if (xml_element->Attribute("name") == nullptr || xml_element->Attribute("xyz") == nullptr ||
69  (xml_element->Attribute("rpy") == nullptr && xml_element->Attribute("wxyz") == nullptr))
70  std::throw_with_nested(std::runtime_error(
71  strFormat("GroupTCPs: Invalid tcp definition for group '%s'!", group_name_string.c_str())));
72 
73  std::string tcp_name_string;
74  int status = tesseract_common::QueryStringAttributeRequired(xml_element, "name", tcp_name_string);
75  // LCOV_EXCL_START
76  if (status != tinyxml2::XML_SUCCESS)
77  std::throw_with_nested(
78  std::runtime_error("GroupTCPS: Failed to parse attribute 'name' for group '" + group_name_string + "'!"));
79  // LCOV_EXCL_STOP
80 
81  std::string xyz_string, rpy_string, wxyz_string;
82  status = tesseract_common::QueryStringAttribute(xml_element, "xyz", xyz_string);
83  // LCOV_EXCL_START
84  if (status != tinyxml2::XML_NO_ATTRIBUTE && status != tinyxml2::XML_SUCCESS)
85  std::throw_with_nested(std::runtime_error(strFormat("GroupTCPS: TCP '%s' for group '%s' failed to parse "
86  "attribute 'xyz'!",
87  tcp_name_string.c_str(),
88  group_name_string.c_str())));
89  // LCOV_EXCL_STOP
90 
91  if (status != tinyxml2::XML_NO_ATTRIBUTE)
92  {
93  std::vector<std::string> tokens;
94  boost::split(tokens, xyz_string, boost::is_any_of(" "), boost::token_compress_on);
95  if (tokens.size() != 3 || !tesseract_common::isNumeric(tokens))
96  std::throw_with_nested(std::runtime_error(strFormat("GroupTCPS: TCP '%s' for group '%s' failed to parse "
97  "attribute 'xyz'!",
98  tcp_name_string.c_str(),
99  group_name_string.c_str())));
100 
101  double x{ 0 }, y{ 0 }, z{ 0 };
102  // No need to check return values because the tokens are verified above
106 
107  tcp.translation() = Eigen::Vector3d(x, y, z);
108  }
109 
110  if (xml_element->Attribute("wxyz") == nullptr)
111  {
112  status = tesseract_common::QueryStringAttribute(xml_element, "rpy", rpy_string);
113  // LCOV_EXCL_START
114  if (status != tinyxml2::XML_NO_ATTRIBUTE && status != tinyxml2::XML_SUCCESS)
115  std::throw_with_nested(std::runtime_error(strFormat("GroupTCPS: TCP '%s' for group '%s' failed to parse "
116  "attribute 'rpy'!",
117  tcp_name_string.c_str(),
118  group_name_string.c_str())));
119  // LCOV_EXCL_STOP
120 
121  if (status != tinyxml2::XML_NO_ATTRIBUTE)
122  {
123  std::vector<std::string> tokens;
124  boost::split(tokens, rpy_string, boost::is_any_of(" "), boost::token_compress_on);
125  if (tokens.size() != 3 || !tesseract_common::isNumeric(tokens))
126  std::throw_with_nested(std::runtime_error(strFormat("GroupTCPS: TCP '%s' for group '%s' failed to parse "
127  "attribute 'rpy'!",
128  tcp_name_string.c_str(),
129  group_name_string.c_str())));
130 
131  double r{ 0 }, p{ 0 }, y{ 0 };
132  // No need to check return values because the tokens are verified above
136 
137  Eigen::AngleAxisd rollAngle(r, Eigen::Vector3d::UnitX());
138  Eigen::AngleAxisd pitchAngle(p, Eigen::Vector3d::UnitY());
139  Eigen::AngleAxisd yawAngle(y, Eigen::Vector3d::UnitZ());
140 
141  Eigen::Quaterniond rpy{ yawAngle * pitchAngle * rollAngle };
142 
143  tcp.linear() = rpy.toRotationMatrix();
144  }
145  }
146  else
147  {
148  status = tesseract_common::QueryStringAttribute(xml_element, "wxyz", wxyz_string);
149  // LCOV_EXCL_START
150  if (status != tinyxml2::XML_NO_ATTRIBUTE && status != tinyxml2::XML_SUCCESS)
151  std::throw_with_nested(std::runtime_error(strFormat("GroupTCPS: TCP '%s' for group '%s' failed to parse "
152  "attribute 'wxyz'!",
153  tcp_name_string.c_str(),
154  group_name_string.c_str())));
155  // LCOV_EXCL_STOP
156 
157  if (status != tinyxml2::XML_NO_ATTRIBUTE)
158  {
159  std::vector<std::string> tokens;
160  boost::split(tokens, wxyz_string, boost::is_any_of(" "), boost::token_compress_on);
161  if (tokens.size() != 4 || !tesseract_common::isNumeric(tokens))
162  std::throw_with_nested(std::runtime_error(strFormat("GroupTCPS: TCP '%s' for group '%s' failed to parse "
163  "attribute 'wxyz'!",
164  tcp_name_string.c_str(),
165  group_name_string.c_str())));
166 
167  double qw{ 0 }, qx{ 0 }, qy{ 0 }, qz{ 0 };
168  // No need to check return values because the tokens are verified above
173 
174  Eigen::Quaterniond q(qw, qx, qy, qz);
175  q.normalize();
176 
177  tcp.linear() = q.toRotationMatrix();
178  }
179  }
180 
181  auto group_tcp = group_tcps.find(group_name_string);
182  if (group_tcp == group_tcps.end())
183  {
184  group_tcps[group_name_string] = GroupsTCPs();
185  group_tcp = group_tcps.find(group_name_string);
186  }
187 
188  group_tcp->second[tcp_name_string] = tcp;
189  }
190 
191  if (group_tcps.count(group_name_string) == 0)
192  std::throw_with_nested(
193  std::runtime_error("GroupTCPS: No tool centers points were found for group '" + group_name_string + "'!"));
194  }
195 
196  return group_tcps;
197 }
198 
199 } // namespace tesseract_srdf
graph.h
tesseract_srdf::parseGroupTCPs
GroupTCPs parseGroupTCPs(const tesseract_scene_graph::SceneGraph &scene_graph, const tinyxml2::XMLElement *srdf_xml, const std::array< int, 3 > &version)
Parse groups tool center points from srdf xml element.
Definition: group_tool_center_points.cpp:47
tesseract_srdf
Main namespace.
Definition: collision_margins.h:43
tesseract_common::QueryStringAttributeRequired
int QueryStringAttributeRequired(const tinyxml2::XMLElement *xml_element, const char *name, std::string &value)
utils.h
TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
#define TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
tesseract_scene_graph::SceneGraph
tesseract_common::strFormat
std::string strFormat(const std::string &format, Args... args)
tesseract_srdf::GroupTCPs
tesseract_common::AlignedMap< std::string, GroupsTCPs > GroupTCPs
Definition: kinematics_information.h:53
tesseract_common::QueryStringAttribute
int QueryStringAttribute(const tinyxml2::XMLElement *xml_element, const char *name, std::string &value)
TESSERACT_COMMON_IGNORE_WARNINGS_POP
#define TESSERACT_COMMON_IGNORE_WARNINGS_POP
tesseract_common::isNumeric
bool isNumeric(const std::string &s)
tesseract_common::toNumeric< double >
template bool toNumeric< double >(const std::string &, double &)
macros.h
tesseract_srdf::GroupsTCPs
tesseract_common::AlignedMap< std::string, Eigen::Isometry3d > GroupsTCPs
Definition: kinematics_information.h:52
group_tool_center_points.h
Parse group tool center points data from srdf file.


tesseract_srdf
Author(s): Levi Armstrong
autogenerated on Sun May 18 2025 03:02:04