g2o
Functions
test_slam3d_jacobian.cpp File Reference
#include <iostream>
#include <cstdio>
#include "g2o/core/jacobian_workspace.h"
#include "g2o/stuff/macros.h"
#include "edge_se3.h"
#include "edge_se3_prior.h"
Include dependency graph for test_slam3d_jacobian.cpp:

Go to the source code of this file.

Functions

Isometry3D randomIsometry3d ()
 
int main (int, char **)
 

Function Documentation

int main ( int  ,
char **   
)

Definition at line 49 of file test_slam3d_jacobian.cpp.

References g2o::OptimizableGraph::addEdge(), g2o::OptimizableGraph::addParameter(), g2o::OptimizableGraph::addVertex(), g2o::JacobianWorkspace::allocate(), g2o::BaseEdge< D, E >::chi2(), g2o::EdgeSE3Prior::computeError(), g2o::BaseVertex< D, T >::estimate(), graph, g2o::EdgeSE3Prior::initialEstimate(), g2o::BaseEdge< D, E >::measurement(), randomIsometry3d(), g2o::BaseVertex< D, T >::setEstimate(), g2o::Parameter::setId(), g2o::OptimizableGraph::Vertex::setId(), g2o::BaseEdge< D, E >::setInformation(), g2o::EdgeSE3::setMeasurement(), g2o::EdgeSE3Prior::setMeasurement(), g2o::OptimizableGraph::Edge::setParameterId(), g2o::HyperGraph::Edge::setVertex(), g2o::JacobianWorkspace::updateSize(), and g2o::JacobianWorkspace::workspaceForVertex().

50 {
51  if (0) {
53  ParameterSE3Offset* offsetParam = new ParameterSE3Offset;
54  offsetParam->setId(0);
55  graph.addParameter(offsetParam);
56 
57  Isometry3D zeroPose = Isometry3D::Identity();
58  VertexSE3* v1 = new VertexSE3;
59  v1->setId(0);
60  graph.addVertex(v1);
61  OptimizableGraph::VertexSet auxSet;
62  EdgeSE3Prior* priorEdge = new EdgeSE3Prior;
63  priorEdge->setVertex(0, v1);
64  priorEdge->setMeasurement(randomIsometry3d());
65  priorEdge->setParameterId(0, 0);
66  cout << PVAR(priorEdge->measurement().matrix()) << endl;
67  graph.addEdge(priorEdge);
68 
69  Eigen::Matrix<double,6,6,Eigen::ColMajor> information = Eigen::Matrix<double,6,6,Eigen::ColMajor>::Identity();
70 
71  cout << "Full information" << endl;
72  v1->setEstimate(zeroPose);
73  priorEdge->setInformation(information);
74  priorEdge->initialEstimate(auxSet, 0);
75  cout << PVAR(priorEdge->chi2()) << endl;
76  cout << v1->estimate().matrix() << endl << endl;
77  priorEdge->computeError();
78 
79  cout << "Only translation" << endl;
80  v1->setEstimate(zeroPose);
81  information.block<3,3>(0,0) = Matrix3D::Identity();
82  information.block<3,3>(3,3) = Matrix3D::Zero();
83  priorEdge->setInformation(information);
84  priorEdge->initialEstimate(auxSet, 0);
85  cout << PVAR(priorEdge->chi2()) << endl;
86  cout << v1->estimate().matrix() << endl << endl;
87  priorEdge->computeError();
88 
89  cout << "Only rotation" << endl;
90  v1->setEstimate(zeroPose);
91  information.block<3,3>(0,0) = Matrix3D::Zero();
92  information.block<3,3>(3,3) = Matrix3D::Identity();
93  priorEdge->setInformation(information);
94  priorEdge->initialEstimate(auxSet, 0);
95  cout << PVAR(priorEdge->chi2()) << endl;
96  cout << v1->estimate().matrix() << endl << endl;
97  priorEdge->computeError();
98  return 0;
99  }
100 
101  VertexSE3 v1;
102  v1.setId(0);
103 
104  VertexSE3 v2;
105  v2.setId(1);
106 
107  EdgeSE3 e;
108  e.setVertex(0, &v1);
109  e.setVertex(1, &v2);
110  e.setInformation(Eigen::Matrix<double,6,6,Eigen::ColMajor>::Identity());
111 
112  JacobianWorkspace jacobianWorkspace;
113  JacobianWorkspace numericJacobianWorkspace;
114  numericJacobianWorkspace.updateSize(&e);
115  numericJacobianWorkspace.allocate();
116 
117  for (int k = 0; k < 100000; ++k) {
118 
122 
123  // calling the analytic Jacobian but writing to the numeric workspace
124  e.BaseBinaryEdge<6, Isometry3D, VertexSE3, VertexSE3>::linearizeOplus(numericJacobianWorkspace);
125  // copy result into analytic workspace
126  jacobianWorkspace = numericJacobianWorkspace;
127 
128  // compute the numeric Jacobian into the numericJacobianWorkspace workspace as setup by the previous call
129  e.BaseBinaryEdge<6, Isometry3D, VertexSE3, VertexSE3>::linearizeOplus();
130 
131  // compare the two Jacobians
132  const double allowedDifference = 1e-6;
133  for (int i = 0; i < 2; ++i) {
134  double* n = numericJacobianWorkspace.workspaceForVertex(i);
135  double* a = jacobianWorkspace.workspaceForVertex(i);
136  for (int j = 0; j < 6*6; ++j) {
137  double d = fabs(n[j] - a[j]);
138  if (d > allowedDifference) {
139  cerr << "\ndetected difference in the Jacobians " << d << endl;
140  cerr << PVAR(v1.estimate().matrix()) << endl << endl;
141  cerr << PVAR(v2.estimate().matrix()) << endl << endl;
142  cerr << PVAR(e.measurement().matrix()) << endl << endl;
143  return 1;
144  }
145  }
146  }
147  cerr << "+";
148 
149  }
150  return 0;
151 }
Isometry3D randomIsometry3d()
double * workspaceForVertex(int vertexIndex)
virtual double chi2() const
computes the chi2 based on the cached error value, only valid after computeError has been called...
Definition: base_edge.h:56
void setVertex(size_t i, Vertex *v)
Definition: hyper_graph.h:194
void setId(int id_)
Definition: parameter.cpp:35
Edge between two 3D pose vertices.
Definition: edge_se3.h:18
virtual void setId(int id)
sets the id of the node in the graph be sure that the graph keeps consistent after changing the id ...
bool setParameterId(int argNum, int paramId)
virtual void setMeasurement(const Isometry3D &m)
Definition: edge_se3.h:27
void updateSize(const HyperGraph::Edge *e)
EIGEN_STRONG_INLINE void setInformation(const InformationType &information)
Definition: base_edge.h:69
Eigen::Transform< double, 3, Eigen::Isometry, Eigen::ColMajor > Isometry3D
Definition: eigen_types.h:66
bool addParameter(Parameter *p)
void setEstimate(const EstimateType &et)
set the estimate for the vertex also calls updateCache()
Definition: base_vertex.h:101
const EstimateType & estimate() const
return the current estimate of the vertex
Definition: base_vertex.h:99
3D pose Vertex, represented as an Isometry3D
Definition: vertex_se3.h:50
virtual void setMeasurement(const Isometry3D &m)
provide memory workspace for computing the Jacobians
virtual bool addEdge(HyperGraph::Edge *e)
virtual bool addVertex(HyperGraph::Vertex *v, Data *userData)
prior for an SE3 element
Protocol The SLAM executable accepts such as solving the and retrieving or vertices in the graph
Definition: protocol.txt:7
EIGEN_STRONG_INLINE const Measurement & measurement() const
accessor functions for the measurement represented by the edge
Definition: base_edge.h:75
virtual void initialEstimate(const OptimizableGraph::VertexSet &from, OptimizableGraph::Vertex *to)
Isometry3D randomIsometry3d ( )

Definition at line 39 of file test_slam3d_jacobian.cpp.

Referenced by main().

40 {
41  Vector3D rotAxisAngle = Vector3D::Random();
42  rotAxisAngle += Vector3D::Random();
43  Eigen::AngleAxisd rotation(rotAxisAngle.norm(), rotAxisAngle.normalized());
44  Isometry3D result = (Isometry3D)rotation.toRotationMatrix();
45  result.translation() = Vector3D::Random();
46  return result;
47 }
Eigen::Matrix< double, 3, 1, Eigen::ColMajor > Vector3D
Definition: eigen_types.h:46
Eigen::Transform< double, 3, Eigen::Isometry, Eigen::ColMajor > Isometry3D
Definition: eigen_types.h:66