utils.h
Go to the documentation of this file.
1 
26 #ifndef TESSERACT_KINEMATICS_UTILS_H
27 #define TESSERACT_KINEMATICS_UTILS_H
28 
31 #include <Eigen/Core>
32 #include <Eigen/Geometry>
33 #include <console_bridge/console.h>
35 
36 #include <tesseract_common/utils.h>
38 
39 namespace tesseract_kinematics
40 {
41 template <typename FloatType>
42 using VectorX = Eigen::Matrix<FloatType, Eigen::Dynamic, 1>;
43 
44 class JointGroup;
45 class ForwardKinematics;
46 
55 void numericalJacobian(Eigen::Ref<Eigen::MatrixXd> jacobian,
56  const Eigen::Isometry3d& change_base,
58  const Eigen::Ref<const Eigen::VectorXd>& joint_values,
59  const std::string& link_name,
60  const Eigen::Ref<const Eigen::Vector3d>& link_point);
61 
70 void numericalJacobian(Eigen::Ref<Eigen::MatrixXd> jacobian,
71  const Eigen::Isometry3d& change_base,
72  const JointGroup& joint_group,
73  const Eigen::Ref<const Eigen::VectorXd>& joint_values,
74  const std::string& link_name,
75  const Eigen::Ref<const Eigen::Vector3d>& link_point);
76 
85 bool solvePInv(const Eigen::Ref<const Eigen::MatrixXd>& A,
86  const Eigen::Ref<const Eigen::VectorXd>& b,
87  Eigen::Ref<Eigen::VectorXd> x);
88 
98 bool dampedPInv(const Eigen::Ref<const Eigen::MatrixXd>& A,
99  Eigen::Ref<Eigen::MatrixXd> P,
100  double eps = 0.011,
101  double lambda = 0.01);
102 
111 bool isNearSingularity(const Eigen::Ref<const Eigen::MatrixXd>& jacobian, double threshold = 0.01);
112 
115 {
116  // LCOV_EXCL_START
117  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
118  // LCOV_EXCL_STOP
119 
121  Eigen::VectorXd eigen_values;
122 
130  double measure{ 0 };
131 
137  double condition{ 0 };
138 
140  double volume{ 0 };
141 };
142 
145 {
146  // LCOV_EXCL_START
147  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
148  // LCOV_EXCL_STOP
149 
152 
155 
158 
161 
164 
167 };
168 
174 Manipulability calcManipulability(const Eigen::Ref<const Eigen::MatrixXd>& jacobian);
175 
180 template <typename FloatType>
181 inline void getRedundantSolutionsHelper(std::vector<VectorX<FloatType>>& redundant_sols,
182  const Eigen::Ref<const Eigen::VectorXd>& sol,
183  const Eigen::MatrixX2d& limits,
184  std::vector<Eigen::Index>::const_iterator current_index,
185  std::vector<Eigen::Index>::const_iterator end_index)
186 {
187  double val{ 0 };
188  for (; current_index != end_index; ++current_index)
189  {
190  if (std::isinf(limits(*current_index, 0)))
191  {
192  std::stringstream ss;
193  ss << "Lower limit of joint " << *current_index << " is infinite; no redundant solutions will be generated\n";
194  CONSOLE_BRIDGE_logWarn(ss.str().c_str());
195  }
196  else
197  {
198  val = sol[*current_index];
199  while ((val -= (2.0 * M_PI)) > limits(*current_index, 0) ||
200  tesseract_common::almostEqualRelativeAndAbs(val, limits(*current_index, 0)))
201  {
202  // It not guaranteed that the provided solution is within limits so this check is needed
203  if (val < limits(*current_index, 1) ||
204  tesseract_common::almostEqualRelativeAndAbs(val, limits(*current_index, 1)))
205  {
206  Eigen::VectorXd new_sol = sol;
207  new_sol[*current_index] = val;
208 
209  if (tesseract_common::satisfiesLimits<double>(new_sol, limits))
210  {
212  redundant_sols.push_back(new_sol.template cast<FloatType>());
213  }
214 
215  getRedundantSolutionsHelper<FloatType>(redundant_sols, new_sol, limits, current_index + 1, end_index);
216  }
217  }
218  }
219 
220  if (std::isinf(limits(*current_index, 1)))
221  {
222  std::stringstream ss;
223  ss << "Upper limit of joint " << *current_index << " is infinite; no redundant solutions will be generated\n";
224  CONSOLE_BRIDGE_logWarn(ss.str().c_str());
225  }
226  else
227  {
228  val = sol[*current_index];
229  while ((val += (2.0 * M_PI)) < limits(*current_index, 1) ||
230  tesseract_common::almostEqualRelativeAndAbs(val, limits(*current_index, 1)))
231  {
232  // It not guaranteed that the provided solution is within limits so this check is needed
233  if (val > limits(*current_index, 0) ||
234  tesseract_common::almostEqualRelativeAndAbs(val, limits(*current_index, 0)))
235  {
236  Eigen::VectorXd new_sol = sol;
237  new_sol[*current_index] = val;
238 
239  if (tesseract_common::satisfiesLimits<double>(new_sol, limits))
240  {
242  redundant_sols.push_back(new_sol.template cast<FloatType>());
243  }
244 
245  getRedundantSolutionsHelper<FloatType>(redundant_sols, new_sol, limits, current_index + 1, end_index);
246  }
247  }
248  }
249  }
250 }
251 
259 template <typename FloatType>
260 inline std::vector<VectorX<FloatType>> getRedundantSolutions(const Eigen::Ref<const VectorX<FloatType>>& sol,
261  const Eigen::MatrixX2d& limits,
262  const std::vector<Eigen::Index>& redundancy_capable_joints)
263 {
264  if (redundancy_capable_joints.empty())
265  return {};
266 
267  for (const Eigen::Index& idx : redundancy_capable_joints)
268  {
269  if (idx >= sol.size())
270  {
271  std::stringstream ss;
272  ss << "Redundant joint index " << idx << " is greater than or equal to the joint state size (" << sol.size()
273  << ")";
274  throw std::runtime_error(ss.str());
275  }
276  }
277 
278  std::vector<VectorX<FloatType>> redundant_sols;
279  getRedundantSolutionsHelper<FloatType>(redundant_sols,
280  sol.template cast<double>(),
281  limits,
282  redundancy_capable_joints.begin(),
283  redundancy_capable_joints.end());
284  return redundant_sols;
285 }
286 
296 template <typename FloatType>
297 inline bool isValid(const std::array<FloatType, 6>& qs)
298 {
299  for (const auto& q : qs)
300  if (!std::isfinite(q))
301  return false;
302 
303  return true;
304 }
305 
311 template <typename FloatType>
312 inline void harmonizeTowardZero(Eigen::Ref<VectorX<FloatType>> qs,
313  const std::vector<Eigen::Index>& redundancy_capable_joints)
314 {
315  const static auto pi = FloatType(M_PI);
316  const static auto two_pi = FloatType(2.0 * M_PI);
317 
318  for (const auto& i : redundancy_capable_joints)
319  {
320  const auto diff = std::fmod(qs[i] + pi, two_pi);
321  qs[i] = (diff < 0) ? (diff + pi) : (diff - pi);
322  }
323 }
324 
330 template <typename FloatType>
331 inline void harmonizeTowardMedian(Eigen::Ref<VectorX<FloatType>> qs,
332  const std::vector<Eigen::Index>& redundancy_capable_joints,
333  const Eigen::Ref<const Eigen::Matrix<FloatType, Eigen::Dynamic, 2>>& position_limits)
334 {
335  const static auto pi = FloatType(M_PI);
336  const static auto two_pi = FloatType(2.0 * M_PI);
337 
338  for (const auto& i : redundancy_capable_joints)
339  {
340  const auto mean = (position_limits(i, 0) + position_limits(i, 1)) / 2.0;
341  const auto diff = std::fmod((qs[i] - mean) + pi, two_pi);
342  const auto vv = (diff < 0) ? (diff + pi) : (diff - pi);
343  qs[i] = (vv + mean);
344  }
345 }
346 
347 } // namespace tesseract_kinematics
348 #endif // TESSERACT_KINEMATICS_UTILS_H
tesseract_kinematics::harmonizeTowardZero
void harmonizeTowardZero(Eigen::Ref< VectorX< FloatType >> qs, const std::vector< Eigen::Index > &redundancy_capable_joints)
This takes an array of floats and modifies them in place to be between [-PI, PI].
Definition: utils.h:312
tesseract_kinematics::ForwardKinematics
Forward kinematics functions.
Definition: forward_kinematics.h:43
tesseract_kinematics::harmonizeTowardMedian
void harmonizeTowardMedian(Eigen::Ref< VectorX< FloatType >> qs, const std::vector< Eigen::Index > &redundancy_capable_joints, const Eigen::Ref< const Eigen::Matrix< FloatType, Eigen::Dynamic, 2 >> &position_limits)
This takes the array of floats and modifies them in place to be between [-PI, PI] relative to limits ...
Definition: utils.h:331
tesseract_kinematics::isNearSingularity
bool isNearSingularity(const Eigen::Ref< const Eigen::MatrixXd > &jacobian, double threshold=0.01)
Check if the provided jacobian is near a singularity.
Definition: utils.cpp:181
tesseract_kinematics::numericalJacobian
void numericalJacobian(Eigen::Ref< Eigen::MatrixXd > jacobian, const Eigen::Isometry3d &change_base, const tesseract_kinematics::ForwardKinematics &kin, const Eigen::Ref< const Eigen::VectorXd > &joint_values, const std::string &link_name, const Eigen::Ref< const Eigen::Vector3d > &link_point)
Numerically calculate a jacobian. This is mainly used for testing.
Definition: utils.cpp:38
tesseract_kinematics::Manipulability::m_linear
ManipulabilityEllipsoid m_linear
Linear velocity manipulability ellipsoid.
Definition: utils.h:154
utils.h
tesseract_kinematics::calcManipulability
Manipulability calcManipulability(const Eigen::Ref< const Eigen::MatrixXd > &jacobian)
Calculate manipulability data about the provided jacobian.
Definition: utils.cpp:188
tesseract_kinematics::Manipulability::f_linear
ManipulabilityEllipsoid f_linear
Linear force manipulability ellipsoid.
Definition: utils.h:163
tesseract_common::almostEqualRelativeAndAbs
bool almostEqualRelativeAndAbs(const Eigen::Ref< const Eigen::VectorXd > &v1, const Eigen::Ref< const Eigen::VectorXd > &v2, const Eigen::Ref< const Eigen::VectorXd > &max_diff, const Eigen::Ref< const Eigen::VectorXd > &max_rel_diff)
tesseract_kinematics::JointGroup
A Joint Group is defined by a list of joint_names.
Definition: joint_group.h:44
kinematic_limits.h
tesseract_kinematics::getRedundantSolutions
std::vector< VectorX< FloatType > > getRedundantSolutions(const Eigen::Ref< const VectorX< FloatType >> &sol, const Eigen::MatrixX2d &limits, const std::vector< Eigen::Index > &redundancy_capable_joints)
Kinematics only return solution between PI and -PI. Provided the limits it will append redundant solu...
Definition: utils.h:260
TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
#define TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
tesseract_kinematics::getRedundantSolutionsHelper
void getRedundantSolutionsHelper(std::vector< VectorX< FloatType >> &redundant_sols, const Eigen::Ref< const Eigen::VectorXd > &sol, const Eigen::MatrixX2d &limits, std::vector< Eigen::Index >::const_iterator current_index, std::vector< Eigen::Index >::const_iterator end_index)
This a recursive function for calculating all permutations of the redundant solutions.
Definition: utils.h:181
tesseract_kinematics::ManipulabilityEllipsoid::measure
double measure
The ratio of longest and shortes axes of the manipulability ellipsoid.
Definition: utils.h:130
tesseract_kinematics::VectorX
Eigen::Matrix< FloatType, Eigen::Dynamic, 1 > VectorX
Definition: utils.h:42
tesseract_kinematics::ManipulabilityEllipsoid::volume
double volume
This is propotial to the volume.
Definition: utils.h:140
tesseract_kinematics::ManipulabilityEllipsoid::condition
double condition
The condition number of A.
Definition: utils.h:137
tesseract_kinematics::Manipulability::m_angular
ManipulabilityEllipsoid m_angular
Angular velocity manipulability ellipsoid.
Definition: utils.h:157
tesseract_kinematics::Manipulability
Contains both manipulability ellipsoid and force ellipsoid data.
Definition: utils.h:144
tesseract_kinematics::ManipulabilityEllipsoid::eigen_values
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Eigen::VectorXd eigen_values
The manipulability ellipsoid eigen values.
Definition: utils.h:121
tesseract_kinematics::Manipulability::m
EIGEN_MAKE_ALIGNED_OPERATOR_NEW ManipulabilityEllipsoid m
Full Manipulability Ellipsoid.
Definition: utils.h:151
tesseract_common::enforceLimits< double >
template void enforceLimits< double >(Eigen::Ref< Eigen::Matrix< double, Eigen::Dynamic, 1 >> values, const Eigen::Ref< const Eigen::Matrix< double, Eigen::Dynamic, 2 >> &limits)
tesseract_kinematics::dampedPInv
bool dampedPInv(const Eigen::Ref< const Eigen::MatrixXd > &A, Eigen::Ref< Eigen::MatrixXd > P, double eps=0.011, double lambda=0.01)
Calculate Damped Pseudoinverse Use this SVD to compute A+ (pseudoinverse of A). Weighting still TBD.
Definition: utils.cpp:148
TESSERACT_COMMON_IGNORE_WARNINGS_POP
#define TESSERACT_COMMON_IGNORE_WARNINGS_POP
tesseract_kinematics::Manipulability::f_angular
ManipulabilityEllipsoid f_angular
Angular momentum manipulability ellipsoid.
Definition: utils.h:166
tesseract_kinematics::ManipulabilityEllipsoid
Used to store Manipulability and Force Ellipsoid data.
Definition: utils.h:114
tesseract_kinematics
Definition: forward_kinematics.h:40
tesseract_common::satisfiesLimits< double >
template bool satisfiesLimits< double >(const Eigen::Ref< const Eigen::Matrix< double, Eigen::Dynamic, 1 >> &values, const Eigen::Ref< const Eigen::Matrix< double, Eigen::Dynamic, 2 >> &limits, const Eigen::Ref< const Eigen::Matrix< double, Eigen::Dynamic, 1 >> &max_diff, const Eigen::Ref< const Eigen::Matrix< double, Eigen::Dynamic, 1 >> &max_rel_diff)
macros.h
tesseract_kinematics::Manipulability::f
ManipulabilityEllipsoid f
Full Force Ellipsoid.
Definition: utils.h:160
tesseract_kinematics::isValid
bool isValid(const std::array< FloatType, 6 > &qs)
Given a vector of floats, this check if they are finite.
Definition: utils.h:297
tesseract_kinematics::solvePInv
bool solvePInv(const Eigen::Ref< const Eigen::MatrixXd > &A, const Eigen::Ref< const Eigen::VectorXd > &b, Eigen::Ref< Eigen::VectorXd > x)
Solve equation Ax=b for x Use this SVD to compute A+ (pseudoinverse of A). Weighting still TBD.
Definition: utils.cpp:106


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