31#include <Eigen/Geometry>
65 template <
typename Derived>
66 explicit SE3Quat(
const Eigen::MatrixBase<Derived>& v) {
67 assert((v.size() == 6 || v.size() == 7) &&
68 "Vector dimension does not match");
70 for (
int i = 0; i < 3; i++) {
72 _r.coeffs()(i) = v[i + 3];
78 double w2 =
cst(1.) - _r.squaredNorm();
79 _r.w() = (w2 <
cst(0.)) ?
cst(0.) : std::sqrt(w2);
81 }
else if (v.size() == 7) {
83 for (
int i = 0; i < 3; ++i, ++idx) _t(i) = v(idx);
84 for (
int i = 0; i < 4; ++i, ++idx) _r.coeffs()(i) = v(idx);
99 result.
_t += _r * tr2.
_t;
116 ret.
_r = _r.conjugate();
117 ret.
_t = ret.
_r * (_t * -
cst(1.));
123 if (i < 3)
return _t[i];
124 return _r.coeffs()[i - 3];
141 _t =
Vector3(v[0], v[1], v[2]);
156 double w =
cst(1.) - v[3] * v[3] - v[4] * v[4] - v[5] * v[5];
158 _r =
Quaternion(std::sqrt(w), v[3], v[4], v[5]);
162 _t =
Vector3(v[0], v[1], v[2]);
167 Matrix3 _R = _r.toRotationMatrix();
168 double d =
cst(0.5) * (_R(0, 0) + _R(1, 1) + _R(2, 2) - 1);
175 if (std::abs(d) >
cst(0.99999)) {
178 V_inv = Matrix3::Identity() -
cst(0.5) * Omega +
179 (
cst(1.) /
cst(12.)) * (Omega * Omega);
181 double theta = std::acos(d);
182 omega = theta / (2 * std::sqrt(1 - d * d)) * dR;
184 V_inv = (Matrix3::Identity() -
cst(0.5) * Omega +
185 (1 - theta / (2 * std::tan(theta / 2))) / (theta * theta) *
189 upsilon = V_inv * _t;
190 for (
int i = 0; i < 3; i++) {
193 for (
int i = 0; i < 3; i++) {
194 res[i + 3] = upsilon[i];
204 for (
int i = 0; i < 3; i++) omega[i] = update[i];
206 for (
int i = 0; i < 3; i++) upsilon[i] = update[i + 3];
208 double theta = omega.norm();
213 if (theta <
cst(0.00001)) {
214 Matrix3 Omega2 = Omega * Omega;
216 R = (Matrix3::Identity() + Omega +
cst(0.5) * Omega2);
218 V = (Matrix3::Identity() +
cst(0.5) * Omega +
cst(1.) /
cst(6.) * Omega2);
220 Matrix3 Omega2 = Omega * Omega;
222 R = (Matrix3::Identity() + std::sin(theta) / theta * Omega +
223 (1 - std::cos(theta)) / (theta * theta) * Omega2);
225 V = (Matrix3::Identity() +
226 (1 - std::cos(theta)) / (theta * theta) * Omega +
227 (theta - std::sin(theta)) / (std::pow(theta, 3)) * Omega2);
232 Eigen::Matrix<double, 6, 6, Eigen::ColMajor>
adj()
const {
233 Matrix3 R = _r.toRotationMatrix();
234 Eigen::Matrix<double, 6, 6, Eigen::ColMajor> res;
235 res.block(0, 0, 3, 3) = R;
236 res.block(3, 3, 3, 3) = R;
237 res.block(3, 0, 3, 3) =
skew(_t) * R;
238 res.block(0, 3, 3, 3) = Matrix3::Zero(3, 3);
243 Eigen::Matrix<double, 4, 4, Eigen::ColMajor> homogeneous_matrix;
244 homogeneous_matrix.setIdentity();
245 homogeneous_matrix.block(0, 0, 3, 3) = _r.toRotationMatrix();
246 homogeneous_matrix.col(3).head(3) = translation();
248 return homogeneous_matrix;
263 result.translation() = translation();
SE3Quat operator*(const SE3Quat &tr2) const
Vector6 toMinimalVector() const
static SE3Quat exp(const Vector6 &update)
SE3Quat(const Quaternion &q, const Vector3 &t)
Eigen::Matrix< double, 4, 4, Eigen::ColMajor > to_homogeneous_matrix() const
SE3Quat & operator*=(const SE3Quat &tr2)
const Quaternion & rotation() const
Vector3 operator*(const Vector3 &v) const
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
void fromVector(const Vector7 &v)
void fromMinimalVector(const Vector6 &v)
const Vector3 & translation() const
void setRotation(const Quaternion &r_)
SE3Quat(const Matrix3 &R, const Vector3 &t)
SE3Quat(const Eigen::MatrixBase< Derived > &v)
void setTranslation(const Vector3 &t_)
double operator[](int i) const
Vector3 map(const Vector3 &xyz) const
Eigen::Matrix< double, 6, 6, Eigen::ColMajor > adj() const
#define G2O_TYPES_SLAM3D_API
some general case utility functions
constexpr double cst(long double v)
Eigen::Transform< double, 3, Eigen::Isometry, Eigen::ColMajor > Isometry3
std::ostream & operator<<(std::ostream &os, const G2OBatchStatistics &st)
Eigen::Quaternion< double > Quaternion
Vector3 deltaR(const Matrix3 &R)
Matrix3 skew(const Vector3 &v)