27 template <
int D,
typename E,
typename VertexXiType,
typename VertexXjType>
28 OptimizableGraph::Vertex* BaseBinaryEdge<D, E, VertexXiType, VertexXjType>::createFrom(){
29 return createVertex(0);
32 template <
int D,
typename E,
typename VertexXiType,
typename VertexXjType>
33 OptimizableGraph::Vertex* BaseBinaryEdge<D, E, VertexXiType, VertexXjType>::createTo(){
34 return createVertex(1);
37 template <
int D,
typename E,
typename VertexXiType,
typename VertexXjType>
38 OptimizableGraph::Vertex* BaseBinaryEdge<D, E, VertexXiType, VertexXjType>::createVertex(
int i){
40 case 0:
return new VertexXiType();
41 case 1:
return new VertexXjType();
47 template <
int D,
typename E,
typename VertexXiType,
typename VertexXjType>
48 void BaseBinaryEdge<D, E, VertexXiType, VertexXjType>::resize(
size_t size)
51 std::cerr <<
"WARNING, attempting to resize binary edge " << BaseEdge<D, E>::id() <<
" to " << size << std::endl;
53 BaseEdge<D, E>::resize(size);
56 template <
int D,
typename E,
typename VertexXiType,
typename VertexXjType>
57 bool BaseBinaryEdge<D, E, VertexXiType, VertexXjType>::allVerticesFixed()
const 59 return (static_cast<const VertexXiType*> (_vertices[0])->fixed() &&
60 static_cast<const VertexXjType*> (_vertices[1])->fixed());
63 template <
int D,
typename E,
typename VertexXiType,
typename VertexXjType>
64 void BaseBinaryEdge<D, E, VertexXiType, VertexXjType>::constructQuadraticForm()
66 VertexXiType* from =
static_cast<VertexXiType*
>(_vertices[0]);
67 VertexXjType* to =
static_cast<VertexXjType*
>(_vertices[1]);
70 const JacobianXiOplusType& A = jacobianOplusXi();
71 const JacobianXjOplusType& B = jacobianOplusXj();
74 bool fromNotFixed = !(from->fixed());
75 bool toNotFixed = !(to->fixed());
77 if (fromNotFixed || toNotFixed) {
79 from->lockQuadraticForm();
80 to->lockQuadraticForm();
82 const InformationType& omega = _information;
83 Eigen::Matrix<double, D, 1, Eigen::ColMajor> omega_r = - omega * _error;
84 if (this->robustKernel() == 0) {
86 Eigen::Matrix<double, VertexXiType::Dimension, D, Eigen::ColMajor> AtO = A.transpose() * omega;
87 from->b().noalias() += A.transpose() * omega_r;
88 from->A().noalias() += AtO*A;
91 _hessianTransposed.noalias() += B.transpose() * AtO.transpose();
93 _hessian.noalias() += AtO * B;
97 to->b().noalias() += B.transpose() * omega_r;
98 to->A().noalias() += B.transpose() * omega * B;
101 double error = this->chi2();
103 this->robustKernel()->robustify(error, rho);
104 InformationType weightedOmega = this->robustInformation(rho);
110 from->b().noalias() += A.transpose() * omega_r;
111 from->A().noalias() += A.transpose() * weightedOmega * A;
113 if (_hessianRowMajor)
114 _hessianTransposed.noalias() += B.transpose() * weightedOmega * A;
116 _hessian.noalias() += A.transpose() * weightedOmega * B;
120 to->b().noalias() += B.transpose() * omega_r;
121 to->A().noalias() += B.transpose() * weightedOmega * B;
125 to->unlockQuadraticForm();
126 from->unlockQuadraticForm();
131 template <
int D,
typename E,
typename VertexXiType,
typename VertexXjType>
132 void BaseBinaryEdge<D, E, VertexXiType, VertexXjType>::linearizeOplus(JacobianWorkspace& jacobianWorkspace)
134 new (&_jacobianOplusXi) JacobianXiOplusType(jacobianWorkspace.workspaceForVertex(0), D, Di);
135 new (&_jacobianOplusXj) JacobianXjOplusType(jacobianWorkspace.workspaceForVertex(1), D, Dj);
139 template <
int D,
typename E,
typename VertexXiType,
typename VertexXjType>
140 void BaseBinaryEdge<D, E, VertexXiType, VertexXjType>::linearizeOplus()
142 VertexXiType* vi =
static_cast<VertexXiType*
>(_vertices[0]);
143 VertexXjType* vj =
static_cast<VertexXjType*
>(_vertices[1]);
145 bool iNotFixed = !(vi->fixed());
146 bool jNotFixed = !(vj->fixed());
148 if (!iNotFixed && !jNotFixed)
152 vi->lockQuadraticForm();
153 vj->lockQuadraticForm();
156 const double delta = 1e-9;
157 const double scalar = 1.0 / (2*delta);
158 ErrorVector errorBak;
159 ErrorVector errorBeforeNumeric = _error;
163 double add_vi[VertexXiType::Dimension];
164 std::fill(add_vi, add_vi + VertexXiType::Dimension, 0.0);
166 for (
int d = 0; d < VertexXiType::Dimension; ++d) {
181 _jacobianOplusXi.col(d) = scalar * errorBak;
187 double add_vj[VertexXjType::Dimension];
188 std::fill(add_vj, add_vj + VertexXjType::Dimension, 0.0);
190 for (
int d = 0; d < VertexXjType::Dimension; ++d) {
205 _jacobianOplusXj.col(d) = scalar * errorBak;
209 _error = errorBeforeNumeric;
211 vj->unlockQuadraticForm();
212 vi->unlockQuadraticForm();
216 template <
int D,
typename E,
typename VertexXiType,
typename VertexXjType>
217 void BaseBinaryEdge<D, E, VertexXiType, VertexXjType>::mapHessianMemory(
double* d,
int i,
int j,
bool rowMajor)
222 new (&_hessianTransposed) HessianBlockTransposedType(d, VertexXjType::Dimension, VertexXiType::Dimension);
224 new (&_hessian) HessianBlockType(d, VertexXiType::Dimension, VertexXjType::Dimension);
226 _hessianRowMajor = rowMajor;
Eigen::Matrix< double, 3, 1, Eigen::ColMajor > Vector3D