26 #ifndef TESSERACT_COMMON_KINEMATIC_LIMITS_H
27 #define TESSERACT_COMMON_KINEMATIC_LIMITS_H
31 #include <Eigen/Geometry>
32 #include <boost/serialization/export.hpp>
33 #include <boost/serialization/base_object.hpp>
44 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
59 void resize(Eigen::Index size);
67 template <
class Archive>
68 void serialize(Archive& ar,
const unsigned int version);
77 template <
typename FloatType>
78 bool isWithinLimits(
const Eigen::Ref<
const Eigen::Matrix<FloatType, Eigen::Dynamic, 1>>& values,
79 const Eigen::Ref<
const Eigen::Matrix<FloatType, Eigen::Dynamic, 2>>& limits)
81 auto p = values.array();
82 auto l0 = limits.col(0).array();
83 auto l1 = limits.col(1).array();
84 return (!(p > l1).any() && !(p < l0).any());
97 template <
typename FloatType>
98 bool satisfiesLimits(
const Eigen::Ref<
const Eigen::Matrix<FloatType, Eigen::Dynamic, 1>>& values,
99 const Eigen::Ref<
const Eigen::Matrix<FloatType, Eigen::Dynamic, 2>>& limits,
100 const Eigen::Ref<
const Eigen::Matrix<FloatType, Eigen::Dynamic, 1>>& max_diff,
101 const Eigen::Ref<
const Eigen::Matrix<FloatType, Eigen::Dynamic, 1>>& max_rel_diff)
103 auto p = values.array();
104 auto l0 = limits.col(0).array();
105 auto l1 = limits.col(1).array();
106 auto md = max_diff.array();
107 auto mrd = max_rel_diff.array();
109 auto lower_diff_abs = (p - l0).abs();
110 auto lower_diff = (lower_diff_abs <= md);
111 auto lower_relative_diff = (lower_diff_abs <= mrd * (p.abs().max)(l0.abs()));
112 auto lower_check = p > l0 || lower_diff || lower_relative_diff;
114 auto upper_diff_abs = (p - l1).abs();
115 auto upper_diff = (upper_diff_abs <= md);
116 auto upper_relative_diff = (upper_diff_abs <= mrd * (p.abs().max)(l1.abs()));
117 auto upper_check = p < l1 || upper_diff || upper_relative_diff;
119 return (lower_check.all() && upper_check.all());
132 template <
typename FloatType>
133 bool satisfiesLimits(
const Eigen::Ref<
const Eigen::Matrix<FloatType, Eigen::Dynamic, 1>>& values,
134 const Eigen::Ref<
const Eigen::Matrix<FloatType, Eigen::Dynamic, 2>>& limits,
135 FloatType max_diff =
static_cast<FloatType
>(1e-6),
136 FloatType max_rel_diff = std::numeric_limits<FloatType>::epsilon())
138 const auto eigen_max_diff = Eigen::Matrix<FloatType, Eigen::Dynamic, 1>::Constant(values.size(), max_diff);
139 const auto eigen_max_rel_diff = Eigen::Matrix<FloatType, Eigen::Dynamic, 1>::Constant(values.size(), max_rel_diff);
141 return satisfiesLimits<FloatType>(values, limits, eigen_max_diff, eigen_max_rel_diff);
149 template <
typename FloatType>
150 void enforceLimits(Eigen::Ref<Eigen::Matrix<FloatType, Eigen::Dynamic, 1>> values,
151 const Eigen::Ref<
const Eigen::Matrix<FloatType, Eigen::Dynamic, 2>>& limits)
153 values = ((values.array().min)(limits.col(1).array()).max)(limits.col(0).array());
159 #endif // TESSERACT_COMMON_KINEMATIC_LIMITS_H