2#include "GraphOptimization/Headers/base_vertex.h"
3#include "GraphOptimization/Headers/base_binary_edge.h"
4#include "GraphOptimization/Headers/types_sba.h"
5#include "GraphOptimization/Headers/base_multi_edge.h"
6#include "GraphOptimization/Headers/base_unary_edge.h"
8#include <opencv2/core/core.hpp>
11#include <Eigen/Geometry>
14#include "OrbSLAM/Headers/Frame.h"
15#include "OrbSLAM/Headers/KeyFrame.h"
38 Eigen::Matrix3<g_type>
ExpSO3(
const g_type x,
const g_type y,
const g_type z);
43 Eigen::Matrix3<g_type>
ExpSO3(
const Eigen::Vector3<g_type>& w);
49 Eigen::Vector3<g_type>
LogSO3(
const Eigen::Matrix3<g_type>& R);
73 Eigen::Matrix3<g_type>
Skew(
const Eigen::Vector3<g_type>& w);
86 template<
typename T = g_type>
88 Eigen::JacobiSVD<Eigen::Matrix<T, 3, 3>> svd(R, Eigen::ComputeFullU | Eigen::ComputeFullV);
89 return svd.matrixU() * svd.matrixV().transpose();
121 void SetParam(
const Buffer<Eigen::Matrix3<g_type>>& _Rcw,
const Buffer<Eigen::Vector3<g_type>>& _tcw,
const Buffer<Eigen::Matrix3<g_type>>& _Rbc,
122 const Buffer<Eigen::Vector3<g_type>>& _tbc,
const g_type& _bf);
137 Eigen::Vector2<g_type>
Project(
const Eigen::Vector3<g_type>& Xw,
int cam_idx = 0)
const;
143 Eigen::Vector3<g_type>
ProjectStereo(
const Eigen::Vector3<g_type>& Xw,
int cam_idx = 0)
const;
152 Eigen::Matrix3<g_type>
Rwb;
153 Eigen::Vector3<g_type>
twb;
163 Eigen::Matrix3<g_type>
DR;
189 g_type fx, fy, cx, cy,
bf;
198 VertexPose(
Frame& pF) {
201 virtual void oplusImpl(
const g_type* update_)
final override
212 VertexPose4DoF(
Frame& pF) {
215 VertexPose4DoF(Eigen::Matrix3<g_type>& _Rwc, Eigen::Vector3<g_type>& _twc,
KeyFrame* pKF) {
219 virtual void oplusImpl(
const g_type* update_)
override {
220 g_type update6DoF[6];
223 update6DoF[2] = update_[0];
224 update6DoF[3] = update_[1];
225 update6DoF[4] = update_[2];
226 update6DoF[5] = update_[3];
232 class VertexVelocity :
public BaseVertex<3, Eigen::Vector3<g_type>>
235 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
237 VertexVelocity(
Frame& pF);
239 virtual void oplusImpl(
const g_type* update_)
final override
241 Eigen::Vector3<g_type> uv;
242 uv << update_[0], update_[1], update_[2];
251 class VertexGyroBias :
public BaseVertex<3, Eigen::Vector3<g_type>>
254 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
256 VertexGyroBias(
Frame& pF);
258 virtual void oplusImpl(
const g_type* update_)
final override
260 Eigen::Vector3<g_type> ubg;
261 ubg << update_[0], update_[1], update_[2];
268 class VertexAccBias :
public BaseVertex<3, Eigen::Vector3<g_type>>
271 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
273 VertexAccBias(
Frame& pF);
275 virtual void oplusImpl(
const g_type* update_)
final override
277 Eigen::Vector3<g_type> uba;
278 uba << update_[0], update_[1], update_[2];
288 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
290 GDirection(Eigen::Matrix3<g_type> pRwg) : Rwg(pRwg) {}
292 void Update(
const g_type* pu)
294 Rwg = Rwg *
ExpSO3(pu[0], pu[1], 0.0);
297 Eigen::Matrix3<g_type> Rwg,
Rgw;
307 VertexGDir(Eigen::Matrix3<g_type> pRwg) {
310 virtual void oplusImpl(
const g_type* update_)
final override {
319 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
323 VertexScale(g_type ps) {
327 virtual void oplusImpl(
const g_type* update_)
final override {
337 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
339 VertexInvDepth(g_type invDepth, g_type u, g_type v,
KeyFrame* pHostKF) {
342 virtual void oplusImpl(
const g_type* update_)
final override {
348 class EdgeMono :
public BaseBinaryEdge<2, Eigen::Vector2<g_type>, VertexSBAPointXYZ, VertexPose>
351 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
353 EdgeMono(
int cam_idx_ = 0)
365 bool isDepthPositive()
370 Eigen::Matrix<g_type, 2, 9> GetJacobian() {
372 Eigen::Matrix<g_type, 2, 9> J;
378 Eigen::Matrix<g_type, 9, 9> GetHessian()
381 Eigen::Matrix<g_type, 2, 9> J;
393 class EdgeMonoOnlyPose :
public BaseUnaryEdge<2, Eigen::Vector2<g_type>, VertexPose>
396 EdgeMonoOnlyPose(
const Eigen::Vector3<g_type>& Xw_,
int cam_idx_ = 0)
409 bool isDepthPositive()
414 Eigen::Matrix<g_type, 6, 6> GetHessian() {
420 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
421 const Eigen::Vector3<g_type> Xw;
426 class EdgeStereo :
public BaseBinaryEdge<3, Eigen::Vector3<g_type>, VertexSBAPointXYZ, VertexPose>
429 EdgeStereo(
int cam_idx_ = 0)
432 bool isDepthPositive()
446 Eigen::Matrix<g_type, 3, 9> GetJacobian()
449 Eigen::Matrix<g_type, 3, 9> J;
455 Eigen::Matrix<g_type, 9, 9> GetHessian()
458 Eigen::Matrix<g_type, 3, 9> J;
464 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
470 class EdgeStereoOnlyPose :
public BaseUnaryEdge<3, Eigen::Vector3<g_type>, VertexPose>
473 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
475 EdgeStereoOnlyPose(
const Eigen::Vector3f& Xw_,
int cam_idx_ = 0) :
476 Xw(Xw_.cast<g_type>()), cam_idx(cam_idx_) {}
485 Eigen::Matrix<g_type, 6, 6> GetHessian() {
491 const Eigen::Vector3<g_type> Xw;
499 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
501 EdgeInertial(IMU::Preintegrated* pInt);
503 virtual void linearizeOplus();
505 Eigen::Matrix<g_type, 24, 24> GetHessian() {
507 Eigen::Matrix<g_type, 9, 24> J;
517 Eigen::Matrix<g_type, 18, 18> GetHessianNoPose1() {
519 Eigen::Matrix<g_type, 9, 18> J;
528 Eigen::Matrix<g_type, 9, 9> GetHessian2() {
530 Eigen::Matrix<g_type, 9, 9> J;
536 const Eigen::Matrix3<g_type> JRg, JVg, JPg;
537 const Eigen::Matrix3<g_type> JVa, JPa;
538 IMU::Preintegrated* mpInt;
540 Eigen::Vector3<g_type> g;
548 EdgeInertialGS(IMU::Preintegrated* pInt);
550 virtual
void linearizeOplus() final override;
552 const Eigen::Matrix3<g_type> JRg, JVg, JPg;
553 const Eigen::Matrix3<g_type> JVa, JPa;
554 IMU::Preintegrated* mpInt;
556 Eigen::Vector3<g_type> g, gI;
557 Eigen::
Matrix<g_type, 27, 27> GetHessian()
560 Eigen::Matrix<g_type, 9, 27> J;
572 Eigen::Matrix<g_type, 27, 27> GetHessian2() {
574 Eigen::Matrix<g_type, 9, 27> J;
586 Eigen::Matrix<g_type, 9, 9> GetHessian3() {
588 Eigen::Matrix<g_type, 9, 9> J;
598 Eigen::Matrix<g_type, 1, 1> GetHessianScale() {
604 Eigen::Matrix<g_type, 3, 3> GetHessianBiasGyro() {
610 Eigen::Matrix<g_type, 3, 3> GetHessianBiasAcc() {
616 Eigen::Matrix<g_type, 2, 2> GetHessianGDir() {
626 class EdgeGyroRW :
public BaseBinaryEdge<3, Eigen::Vector3<g_type>, VertexGyroBias, VertexGyroBias>
629 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
644 Eigen::Matrix<g_type, 6, 6> GetHessian() {
646 Eigen::Matrix<g_type, 3, 6> J;
652 Eigen::Matrix3<g_type> GetHessian2() {
660 class EdgeAccRW :
public BaseBinaryEdge<3, Eigen::Vector3<g_type>, VertexAccBias, VertexAccBias>
663 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
679 Eigen::Matrix<g_type, 6, 6> GetHessian() {
681 Eigen::Matrix<g_type, 3, 6> J;
687 Eigen::Matrix3<g_type> GetHessian2() {
694 class ConstraintPoseImu
697 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
698 ConstraintPoseImu(
const Eigen::Matrix3<g_type>& Rwb_
699 ,
const Eigen::Vector3<g_type>& twb_
700 ,
const Eigen::Vector3<g_type>& vwb_
701 ,
const Eigen::Vector3<g_type>& bg_
702 ,
const Eigen::Vector3<g_type>& ba_
712 Eigen::SelfAdjointEigenSolver<Eigen::Matrix<g_type, 15, 15> > es(
H);
713 Eigen::Matrix<g_type, 15, 1> eigs = es.eigenvalues();
714 for (
int i = 0; i < 15; i++)
717 H = es.eigenvectors() * eigs.asDiagonal() * es.eigenvectors().transpose();
720 Eigen::Matrix3<g_type>
Rwb;
721 Eigen::Vector3<g_type>
twb;
722 Eigen::Vector3<g_type>
vwb;
723 Eigen::Vector3<g_type>
bg;
724 Eigen::Vector3<g_type>
ba;
732 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
735 virtual void linearizeOplus()
override;
737 Eigen::Matrix<g_type, 15, 15> GetHessian()
740 Eigen::Matrix<g_type, 15, 15> J;
748 Eigen::Matrix<g_type, 9, 9> GetHessianNoPose()
751 Eigen::Matrix<g_type, 15, 9> J;
757 Eigen::Matrix3<g_type> Rwb;
758 Eigen::Vector3<g_type> twb, vwb;
759 Eigen::Vector3<g_type> bg, ba;
763 class EdgePriorAcc :
public BaseUnaryEdge<3, Eigen::Vector3<g_type>, VertexAccBias>
766 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
768 EdgePriorAcc(
const Eigen::Vector3f& bprior_)
769 : bprior(bprior_.cast<g_type>())
780 Eigen::
Matrix<g_type, 3, 3> GetHessian()
786 const Eigen::Vector3<g_type> bprior;
790 class EdgePriorGyro :
public BaseUnaryEdge<3, Eigen::Vector3<g_type>, VertexGyroBias>
793 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
795 EdgePriorGyro(
const Eigen::Vector3f& bprior_) :bprior(bprior_.cast<g_type>()) {}
805 Eigen::
Matrix<g_type, 3, 3> GetHessian()
811 const Eigen::Vector3<g_type> bprior;
816 class Edge4DoF :
public BaseBinaryEdge<6, vector6d, VertexPose4DoF, VertexPose4DoF>
819 Edge4DoF(
const Eigen::Matrix4<g_type>& deltaT) {
821 dRij = deltaT.block<3, 3>(0, 0);
822 dtij = deltaT.block<3, 1>(0, 3);
827 _error <<
LogSO3(
m_a->estimate().Rcw[0] *
m_a->estimate().Rcw[0].transpose() * dRij.transpose()),
828 m_a->estimate().Rcw[0] * (-
m_a->estimate().Rcw[0].transpose() *
m_a->estimate().tcw[0])
829 +
m_a->estimate().tcw[0] - dtij;
836 Eigen::Matrix4<g_type> dTij;
837 Eigen::Matrix3<g_type> dRij;
838 Eigen::Vector3<g_type> dtij;
virtual void linearizeOplus()
JacobianXiOplusType _jacobianOplusXi
JacobianXjOplusType _jacobianOplusXj
const InformationType & information() const
Buffer< JacobianType > _jacobianOplus
virtual void linearizeOplus()
JacobianXiOplusType _jacobianOplusXi
const EstimateType & estimate() const
void setEstimate(const EstimateType &et)
The equivelent of std::vector but with a bit more control.
Stores a prior constraint on an IMU pose with its information matrix.
Eigen::Matrix3< g_type > Rwb
Body-to-world rotation.
Eigen::Vector3< g_type > ba
Accelerometer bias.
Matrix15d H
15x15 information matrix.
Eigen::Vector3< g_type > twb
Body-to-world translation.
Eigen::Vector3< g_type > bg
Gyroscope bias.
Eigen::Vector3< g_type > vwb
Body velocity in world frame.
void computeError()
Computes the error of the edge and stores it internally.
void computeError() final override
Computes the error of the edge and stores it internally.
void computeError() final override
Computes the error of the edge and stores it internally.
void computeError() final override
Computes the error of the edge and stores it internally.
void computeError()
Computes the error of the edge and stores it internally.
void computeError()
Computes the error of the edge and stores it internally.
void computeError()
Computes the error of the edge and stores it internally.
void computeError() final override
Computes the error of the edge and stores it internally.
void computeError() final override
Computes the error of the edge and stores it internally.
void computeError() override
Computes the error of the edge and stores it internally.
void computeError()
Computes the error of the edge and stores it internally.
void computeError()
Computes the error of the edge and stores it internally.
Represents a single image frame with extracted features and pose information.
Represents the gravity direction as a rotation for optimization.
Eigen::Matrix3< g_type > Rgw
World-to-gravity and gravity-to-world rotations.
int its
Iteration counter.
Abstract interface for geometric camera models (pinhole, fisheye, etc.).
Represents a combined IMU and camera pose for graph optimization.
Eigen::Vector3< g_type > twb
IMU body-to-world translation.
int its
Iteration counter.
Buffer< Eigen::Vector3< g_type > > tbc
Camera-body and body-camera translations.
void UpdateW(const g_type *pu)
Updates the pose in the world reference frame.
ImuCamPose()
Default constructor.
Eigen::Matrix3< g_type > Rwb0
Initial body-to-world rotation for 4DoF pose graph.
ImuCamPose(Frame &pF)
Constructs from a Frame.
void Update(const g_type *pu)
Updates the pose in the IMU body reference frame.
Eigen::Vector3< g_type > ProjectStereo(const Eigen::Vector3< g_type > &Xw, int cam_idx=0) const
Projects a 3D world point to stereo coordinates.
bool isDepthPositive(const Eigen::Vector3< g_type > &Xw, int cam_idx=0) const
Checks whether a 3D point has positive depth in the given camera.
Eigen::Vector2< g_type > Project(const Eigen::Vector3< g_type > &Xw, int cam_idx=0) const
Projects a 3D world point to 2D (monocular).
void SetParam(const Buffer< Eigen::Matrix3< g_type > > &_Rcw, const Buffer< Eigen::Vector3< g_type > > &_tcw, const Buffer< Eigen::Matrix3< g_type > > &_Rbc, const Buffer< Eigen::Vector3< g_type > > &_tbc, const g_type &_bf)
Sets camera and IMU extrinsic parameters.
Eigen::Matrix3< g_type > DR
Delta rotation for 4DoF optimization.
Buffer< Eigen::Matrix3< g_type > > Rcw
Camera-to-world rotations per camera.
Buffer< Eigen::Matrix3< g_type > > Rbc
Camera-body and body-camera rotations.
g_type bf
Stereo baseline times focal length.
ImuCamPose(Eigen::Matrix3< g_type > &_Rwc, Eigen::Vector3< g_type > &_twc, KeyFrame *pKF)
Constructs from a rotation, translation, and keyframe.
Eigen::Matrix3< g_type > Rwb
IMU body-to-world rotation.
Buffer< GeometricCamera * > pCamera
Camera models.
Buffer< Eigen::Vector3< g_type > > tcw
Camera-to-world translations per camera.
Represents a 3D point parameterized by inverse depth in the host frame.
int its
Iteration counter.
InvDepthPoint(g_type _rho, g_type _u, g_type _v, KeyFrame *pHostKF)
Constructs from inverse depth and pixel coordinates.
g_type bf
Intrinsic parameters from the host frame.
void Update(const g_type *pu)
Updates the inverse depth from the optimization delta.
g_type v
Pixel observation coordinates in the host frame.
g_type rho
Inverse depth value.
InvDepthPoint()
Default constructor.
A keyframe in the SLAM map, derived from Frame.
Templated logic for doing matrix multiplication.
virtual void oplusImpl(const g_type *update_) final override
update the position of the node from the parameters in v.
virtual void oplusImpl(const g_type *update_) final override
update the position of the node from the parameters in v.
virtual void oplusImpl(const g_type *update_) final override
update the position of the node from the parameters in v.
virtual void oplusImpl(const g_type *update_) final override
update the position of the node from the parameters in v.
virtual void oplusImpl(const g_type *update_) override
update the position of the node from the parameters in v.
virtual void oplusImpl(const g_type *update_) final override
update the position of the node from the parameters in v.
virtual void oplusImpl(const g_type *update_) final override
update the position of the node from the parameters in v.
virtual void oplusImpl(const g_type *update_) final override
update the position of the node from the parameters in v.
The primary namespace for the NDEVR SDK.
Eigen::Matrix3< g_type > ExpSO3(const g_type x, const g_type y, const g_type z)
Computes the SO3 exponential map from axis components.
Eigen::Matrix< g_type, 15, 15 > Matrix15d
15x15 matrix type.
Eigen::Matrix< g_type, 12, 12 > Matrix12d
12x12 matrix type.
Eigen::Matrix< T, 3, 3 > NormalizeRotation(const Eigen::Matrix< T, 3, 3 > &R)
Normalizes a rotation matrix using SVD decomposition.
Eigen::Matrix< g_type, 12, 1 > vector12d
12-element vector type.
constexpr Angle< t_angle_type > abs(const Angle< t_angle_type > &value)
Changes an input with a negative sign, to a positive sign.
Eigen::Vector3< g_type > LogSO3(const Eigen::Matrix3< g_type > &R)
Computes the SO3 logarithm map.
Eigen::Matrix3< g_type > InverseRightJacobianSO3(const Eigen::Vector3< g_type > &v)
Computes the inverse right Jacobian of SO3.
Eigen::Matrix3< g_type > RightJacobianSO3(const Eigen::Vector3< g_type > &v)
Computes the right Jacobian of SO3.
Eigen::Matrix< g_type, 15, 1 > vector15d
15-element vector type.
Eigen::Matrix< g_type, 9, 9 > Matrix9d
9x9 matrix type.
Eigen::Matrix< g_type, 9, 1 > vector9d
9-element vector type.
Eigen::Matrix3< g_type > Skew(const Eigen::Vector3< g_type > &w)
Computes the skew-symmetric matrix of a 3D vector.
Eigen::Matrix< g_type, 6, 1 > vector6d
6-element vector type.