43 namespace kinematics {
45 __inline__
double sinc(
double x) {
49 static const double c_2 = 1.0 / 6.0;
50 static const double c_4 = 1.0 / 120.0;
51 static const double c_6 = 1.0 / 5040.0;
52 const double x_2 = x * x;
53 const double x_4 = x_2 * x_2;
54 const double x_6 = x_2 * x_2 * x_2;
55 return 1.0 - c_2 * x_2 + c_4 * x_4 - c_6 * x_6;
59 __inline__ Eigen::Quaterniond
deltaQ(
const Eigen::Vector3d& dAlpha)
62 double halfnorm = 0.5 * dAlpha.template tail<3>().norm();
63 dq.template head<3>() =
sinc(halfnorm) * 0.5 * dAlpha.template tail<3>();
64 dq[3] = cos(halfnorm);
65 return Eigen::Quaterniond(dq);
69 __inline__ Eigen::Matrix3d
rightJacobian(
const Eigen::Vector3d & PhiVec) {
70 const double Phi = PhiVec.norm();
71 Eigen::Matrix3d retMat = Eigen::Matrix3d::Identity();
73 const Eigen::Matrix3d Phi_x2 = Phi_x*Phi_x;
75 retMat += -0.5*Phi_x + 1.0/6.0*Phi_x2;
77 const double Phi2 = Phi*Phi;
78 const double Phi3 = Phi2*Phi;
79 retMat += -(1.0-cos(Phi))/(Phi2)*Phi_x + (Phi-sin(Phi))/Phi3*Phi_x2;
85 : parameters_(other.parameters_),
93 : parameters_(std::move(other.parameters_)),
96 C_(std::move(other.C_)) {
101 : r_(¶meters_[0]),
103 C_(Eigen::Matrix3d::Identity()) {
104 r_ = Eigen::Vector3d(0.0, 0.0, 0.0);
105 q_ = Eigen::Quaterniond(1.0, 0.0, 0.0, 0.0);
109 const Eigen::Quaterniond& q_AB)
110 : r_(¶meters_[0]),
111 q_(¶meters_[3]) {
113 q_ = q_AB.normalized();
117 : r_(¶meters_[0]),
119 C_(T_AB.topLeftCorner<3, 3>()) {
120 r_ = (T_AB.topRightCorner<3, 1>());
121 q_ = (T_AB.topLeftCorner<3, 3>());
122 assert(fabs(T_AB(3, 0)) < 1.0e-12);
123 assert(fabs(T_AB(3, 1)) < 1.0e-12);
124 assert(fabs(T_AB(3, 2)) < 1.0e-12);
125 assert(fabs(T_AB(3, 3) - 1.0) < 1.0e-12);
131 template<
typename Derived_coeffs>
133 const Eigen::MatrixBase<Derived_coeffs> & coeffs) {
134 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Derived_coeffs, 7);
142 Eigen::Matrix4d T_ret;
143 T_ret.topLeftCorner<3, 3>() =
C_;
144 T_ret.topRightCorner<3, 1>() =
r_;
145 T_ret.bottomLeftCorner<1, 3>().setZero();
165 Eigen::Matrix<double, 3, 4> T3x4_ret;
166 T3x4_ret.topLeftCorner<3, 3>() =
C_;
167 T3x4_ret.topRightCorner<3, 1>() =
r_;
181 double rotationMaxRadians) {
183 Eigen::Vector3d axis = rotationMaxRadians * Eigen::Vector3d::Random();
185 Eigen::Vector3d
r = translationMaxMeters * Eigen::Vector3d::Random();
187 q_ = Eigen::AngleAxisd(axis.norm(), axis.normalized());
193 r_ = (T_AB.topRightCorner<3, 1>());
194 q_ = (T_AB.topLeftCorner<3, 3>());
198 const Eigen::Quaternion<double> & q_AB) {
200 q_ = q_AB.normalized();
220 const Eigen::Vector3d & rhs)
const {
224 const Eigen::Vector4d & rhs)
const {
225 const double s = rhs[3];
226 Eigen::Vector4d retVec;
227 retVec.head<3>() =
C_ * rhs.head<3>() +
r_ * s;
241 C_ =
q_.toRotationMatrix();
245 template<
typename Derived_delta>
247 const Eigen::MatrixBase<Derived_delta> & delta) {
248 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Derived_delta, 6);
249 r_ += delta.template head<3>();
251 double halfnorm = 0.5 * delta.template tail<3>().norm();
252 dq.template head<3>() =
sinc(halfnorm) * 0.5 * delta.template tail<3>();
253 dq[3] = cos(halfnorm);
254 q_ = (Eigen::Quaterniond(dq) *
q_);
260 template<
typename Derived_delta,
typename Derived_jacobian>
262 const Eigen::MatrixBase<Derived_delta> & delta,
263 const Eigen::MatrixBase<Derived_jacobian> & jacobian) {
264 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Derived_delta, 6);
265 EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived_jacobian, 7, 6);
272 template<
typename Derived_jacobian>
274 const Eigen::MatrixBase<Derived_jacobian> & jacobian)
const {
275 EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived_jacobian, 7, 6);
276 Eigen::Matrix<double, 4, 3>
S = Eigen::Matrix<double, 4, 3>::Zero();
277 const_cast<Eigen::MatrixBase<Derived_jacobian>&
>(jacobian).setZero();
278 const_cast<Eigen::MatrixBase<Derived_jacobian>&
>(jacobian)
279 .
template topLeftCorner<3, 3>().setIdentity();
283 const_cast<Eigen::MatrixBase<Derived_jacobian>&
>(jacobian)
288 template <
typename Derived_jacobian>
291 EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived_jacobian, 6, 7);
292 const_cast<Eigen::MatrixBase<Derived_jacobian>&
>(jacobian).setZero();
293 const_cast<Eigen::MatrixBase<Derived_jacobian>&
>(jacobian).
template topLeftCorner<3,3>()
294 = Eigen::Matrix3d::Identity();
295 const_cast<Eigen::MatrixBase<Derived_jacobian>&
>(jacobian).
template bottomRightCorner<3,4>()
Eigen::Matrix< Scalar_T, 3, 3 > crossMx(Scalar_T x, Scalar_T y, Scalar_T z)
Cross matrix of a vector [x,y,z]. Adopted from Schweizer-Messer by Paul Furgale.
Definition: operators.hpp:62
Eigen::Matrix4d oplus(const Eigen::Quaterniond &q_BC)
Oplus matrix of a quaternion, i.e. q_AB*q_BC = oplus(q_BC)*q_AB.coeffs().
Definition: operators.hpp:104
__inline__ double sinc(double x)
Implements sin(x)/x for all x in R.
Definition: Transformation.hpp:45
__inline__ Eigen::Matrix3d rightJacobian(const Eigen::Vector3d &PhiVec)
Right Jacobian, see Forster et al. RSS 2015 eqn. (8)
Definition: Transformation.hpp:69
__inline__ Eigen::Quaterniond deltaQ(const Eigen::Vector3d &dAlpha)
Implements the exponential map for quaternions.
Definition: Transformation.hpp:59