validate.cpp
Go to the documentation of this file.
1 
29 #include <Eigen/Geometry>
30 #include <console_bridge/console.h>
31 #include <sstream>
33 
35 #include <tesseract_common/utils.h>
37 
38 namespace tesseract_kinematics
39 {
40 bool checkKinematics(const KinematicGroup& manip, double tol)
41 {
42  Eigen::Isometry3d test1;
43  Eigen::Isometry3d test2;
44  Eigen::VectorXd seed_angles(manip.numJoints());
45  Eigen::VectorXd joint_angles2(manip.numJoints());
46  std::vector<std::string> tip_links = manip.getAllPossibleTipLinkNames();
47  std::vector<std::string> working_frames = manip.getAllValidWorkingFrames();
48  const int nj = static_cast<int>(manip.numJoints());
49 
50  std::vector<std::vector<double>> passed_data;
51  std::vector<std::vector<double>> failed_data;
52  int translation_failures{ 0 };
53  int angular_failures{ 0 };
54  double translation_max{ 0 };
55  double angular_max{ 0 };
56 
57  std::vector<std::pair<std::string, std::string>> checks;
58  checks.reserve(tip_links.size() + working_frames.size());
59 
60  for (const auto& tip_link : tip_links)
61  checks.emplace_back(working_frames[0], tip_link);
62 
63  for (const auto& working_frame : working_frames)
64  checks.emplace_back(working_frame, tip_links[0]);
65 
66  for (const auto& check : checks)
67  {
68  seed_angles.setZero();
69  joint_angles2.setZero();
70 
71  for (int t = 0; t < nj; ++t)
72  {
73  joint_angles2[t] = M_PI_4;
74 
75  auto poses1 = manip.calcFwdKin(joint_angles2);
76  test1 = poses1.at(check.first).inverse() * poses1.at(check.second);
77  KinGroupIKInput ik_input(test1, check.first, check.second);
78  IKSolutions sols = manip.calcInvKin({ ik_input }, seed_angles);
79  for (const auto& sol : sols)
80  {
81  auto poses2 = manip.calcFwdKin(sol);
82  test2 = poses2.at(check.first).inverse() * poses2.at(check.second);
83 
84  double translation_distance = (test1.translation() - test2.translation()).norm();
85  double angular_distance =
86  Eigen::Quaterniond(test1.linear()).angularDistance(Eigen::Quaterniond(test2.linear()));
87  if (translation_distance > tol || angular_distance > tol)
88  {
89  if (translation_distance > tol)
90  ++translation_failures;
91 
92  if (angular_distance > tol)
93  ++angular_failures;
94 
95  if (angular_distance > angular_max)
96  angular_max = angular_distance;
97 
98  if (translation_distance > translation_max)
99  translation_max = translation_distance;
100 
101  std::vector<double> data{ translation_distance, tol, angular_distance, tol };
102  for (Eigen::Index i = 0; i < sol.rows(); ++i)
103  data.push_back(sol(i));
104 
105  failed_data.push_back(data);
106  }
107  else
108  {
109  std::vector<double> data{ translation_distance, tol, angular_distance, tol };
110  for (Eigen::Index i = 0; i < sol.rows(); ++i)
111  data.push_back(sol(i));
112 
113  passed_data.push_back(data);
114  }
115  }
116 
117  joint_angles2[t] = 0;
118  }
119  }
120 
121  // LCOV_EXCL_START
122  if (!failed_data.empty())
123  {
124  CONSOLE_BRIDGE_logError("checkKinematics failed %d out of %d\n Translation failures %d out of %d (max: "
125  "%f)\n Angular failures %d out of %d (max: %f)",
126  failed_data.size(),
127  (failed_data.size() + passed_data.size()),
128  translation_failures,
129  failed_data.size(),
130  translation_max,
131  angular_failures,
132  failed_data.size(),
133  angular_max);
134  std::stringstream msg;
135  msg << "\n";
136  msg << "*****************************\n";
137  msg << "******** Failed Data ********\n";
138  msg << "*****************************\n";
139 
140  std::string header = "Trans. Dist. (m), tol, Angle Dist. (rad), tol";
141  for (const auto& jn : manip.getJointNames())
142  header += ", " + jn;
143 
144  msg << header << "\n";
145  for (const auto& d : failed_data)
146  {
147  for (const auto& val : d)
148  msg << val << ", ";
149  msg << "\n";
150  }
151 
152  msg << "*****************************\n";
153  msg << "******** Passed Data ********\n";
154  msg << "*****************************\n";
155  if (passed_data.empty())
156  {
157  msg << "No Data!"
158  << "\n";
159  }
160  else
161  {
162  for (const auto& d : passed_data)
163  {
164  for (const auto& val : d)
165  msg << val << ", ";
166  msg << "\n";
167  }
168  }
169 
170  CONSOLE_BRIDGE_logError("%s", msg.str().c_str());
171  return false;
172  }
173  // LCOV_EXCL_STOP
174 
175  return true;
176 }
177 } // namespace tesseract_kinematics
tesseract_kinematics::KinGroupIKInput
Structure containing the data required to solve inverse kinematics.
Definition: kinematic_group.h:48
tesseract_kinematics::JointGroup::numJoints
Eigen::Index numJoints() const
Number of joints in robot.
Definition: joint_group.cpp:299
utils.h
tesseract_kinematics::checkKinematics
bool checkKinematics(const KinematicGroup &manip, double tol=1e-3)
This compares calcFwdKin to calcInvKin for a KinematicGroup.
Definition: validate.cpp:40
TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
#define TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
tesseract_kinematics::KinematicGroup::getAllPossibleTipLinkNames
std::vector< std::string > getAllPossibleTipLinkNames() const
Get the tip link name.
Definition: kinematic_group.cpp:309
tesseract_kinematics::JointGroup::getJointNames
std::vector< std::string > getJointNames() const
Get list of joint names for kinematic object.
Definition: joint_group.cpp:267
tesseract_kinematics::KinematicGroup::calcInvKin
IKSolutions calcInvKin(const KinGroupIKInputs &tip_link_poses, const Eigen::Ref< const Eigen::VectorXd > &seed) const
Calculates joint solutions given a pose.
Definition: kinematic_group.cpp:210
tesseract_kinematics::KinematicGroup::getAllValidWorkingFrames
std::vector< std::string > getAllValidWorkingFrames() const
Returns all possible working frames in which goal poses can be defined.
Definition: kinematic_group.cpp:307
kinematic_group.h
A kinematic group with forward and inverse kinematics methods.
TESSERACT_COMMON_IGNORE_WARNINGS_POP
#define TESSERACT_COMMON_IGNORE_WARNINGS_POP
validate.h
This contains utility function validate things like forward kinematics match inverse kinematics.
tesseract_kinematics
Definition: forward_kinematics.h:40
tesseract_kinematics::JointGroup::calcFwdKin
tesseract_common::TransformMap calcFwdKin(const Eigen::Ref< const Eigen::VectorXd > &joint_angles) const
Calculates tool pose of robot chain.
Definition: joint_group.cpp:126
tesseract_kinematics::IKSolutions
std::vector< Eigen::VectorXd > IKSolutions
The inverse kinematics solutions container.
Definition: types.h:38
macros.h
tesseract_kinematics::KinematicGroup
Definition: kinematic_group.h:75


tesseract_kinematics
Author(s): Levi Armstrong
autogenerated on Sun May 18 2025 03:02:14