timeIncremental.cpp
Go to the documentation of this file.
1 /* ----------------------------------------------------------------------------
2 
3  * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4  * Atlanta, Georgia 30332-0415
5  * All Rights Reserved
6  * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7 
8  * See LICENSE for the license information
9  * -------------------------------------------------------------------------- */
10 
17 #include <gtsam/slam/dataset.h>
20 #include <gtsam/geometry/Pose2.h>
21 #include <gtsam/inference/Symbol.h>
22 #include <gtsam/nonlinear/ISAM2.h>
24 #include <gtsam/base/timing.h>
25 
26 #include <fstream>
27 #include <boost/archive/binary_oarchive.hpp>
28 #include <boost/archive/binary_iarchive.hpp>
29 #include <boost/serialization/export.hpp>
30 #include <boost/range/adaptor/reversed.hpp>
31 
32 using namespace std;
33 using namespace gtsam;
34 using namespace gtsam::symbol_shorthand;
35 
36 typedef Pose2 Pose;
37 
41 
42 //GTSAM_VALUE_EXPORT(Value);
43 //GTSAM_VALUE_EXPORT(Pose);
44 //GTSAM_VALUE_EXPORT(NonlinearFactor);
45 //GTSAM_VALUE_EXPORT(NoiseModelFactor);
46 //GTSAM_VALUE_EXPORT(NM1);
47 //GTSAM_VALUE_EXPORT(NM2);
48 //GTSAM_VALUE_EXPORT(BetweenFactor<Pose>);
49 //GTSAM_VALUE_EXPORT(PriorFactor<Pose>);
50 //GTSAM_VALUE_EXPORT(BR);
51 //GTSAM_VALUE_EXPORT(noiseModel::Base);
52 //GTSAM_VALUE_EXPORT(noiseModel::Isotropic);
53 //GTSAM_VALUE_EXPORT(noiseModel::Gaussian);
54 //GTSAM_VALUE_EXPORT(noiseModel::Diagonal);
55 //GTSAM_VALUE_EXPORT(noiseModel::Unit);
56 
58  // Compute degrees of freedom (observations - variables)
59  // In ocaml, +1 was added to the observations to account for the prior, but
60  // the factor graph already includes a factor for the prior/equality constraint.
61  // double dof = graph.size() - config.size();
62  int graph_dim = 0;
63  for(const boost::shared_ptr<gtsam::NonlinearFactor>& nlf: graph) {
64  graph_dim += nlf->dim();
65  }
66  double dof = graph_dim - config.dim(); // kaess: changed to dim
67  return 2. * graph.error(config) / dof; // kaess: added factor 2, graph.error returns half of actual error
68 }
69 
70 int main(int argc, char *argv[]) {
71 
72  cout << "Loading data..." << endl;
73 
74  gttic_(Find_datafile);
75  //string datasetFile = findExampleDataFile("w10000-odom");
76  string datasetFile = findExampleDataFile("victoria_park");
77  std::pair<NonlinearFactorGraph::shared_ptr, Values::shared_ptr> data =
78  load2D(datasetFile);
79  gttoc_(Find_datafile);
80 
81  NonlinearFactorGraph measurements = *data.first;
82  Values initial = *data.second;
83 
84  cout << "Playing forward time steps..." << endl;
85 
86  ISAM2 isam2;
87 
88  size_t nextMeasurement = 0;
89  for(size_t step=1; nextMeasurement < measurements.size(); ++step) {
90 
91  Values newVariables;
92  NonlinearFactorGraph newFactors;
93 
94  // Collect measurements and new variables for the current step
95  gttic_(Collect_measurements);
96  if(step == 1) {
97  // cout << "Initializing " << 0 << endl;
98  newVariables.insert(0, Pose());
99  // Add prior
100  newFactors.addPrior(0, Pose(), noiseModel::Unit::Create(3));
101  }
102  while(nextMeasurement < measurements.size()) {
103 
104  NonlinearFactor::shared_ptr measurementf = measurements[nextMeasurement];
105 
107  boost::dynamic_pointer_cast<BetweenFactor<Pose> >(measurementf))
108  {
109  // Stop collecting measurements that are for future steps
110  if(measurement->key1() > step || measurement->key2() > step)
111  break;
112 
113  // Require that one of the nodes is the current one
114  if(measurement->key1() != step && measurement->key2() != step)
115  throw runtime_error("Problem in data file, out-of-sequence measurements");
116 
117  // Add a new factor
118  newFactors.push_back(measurement);
119 
120  // Initialize the new variable
121  if(measurement->key1() == step && measurement->key2() == step-1) {
122  if(step == 1)
123  newVariables.insert(step, measurement->measured().inverse());
124  else {
125  Pose prevPose = isam2.calculateEstimate<Pose>(step-1);
126  newVariables.insert(step, prevPose * measurement->measured().inverse());
127  }
128  // cout << "Initializing " << step << endl;
129  } else if(measurement->key2() == step && measurement->key1() == step-1) {
130  if(step == 1)
131  newVariables.insert(step, measurement->measured());
132  else {
133  Pose prevPose = isam2.calculateEstimate<Pose>(step-1);
134  newVariables.insert(step, prevPose * measurement->measured());
135  }
136  // cout << "Initializing " << step << endl;
137  }
138  }
140  boost::dynamic_pointer_cast<BearingRangeFactor<Pose, Point2> >(measurementf))
141  {
142  Key poseKey = measurement->keys()[0], lmKey = measurement->keys()[1];
143 
144  // Stop collecting measurements that are for future steps
145  if(poseKey > step)
146  throw runtime_error("Problem in data file, out-of-sequence measurements");
147 
148  // Add new factor
149  newFactors.push_back(measurement);
150 
151  // Initialize new landmark
152  if(!isam2.getLinearizationPoint().exists(lmKey))
153  {
155  Rot2 measuredBearing = measurement->measured().bearing();
156  double measuredRange = measurement->measured().range();
157  newVariables.insert(lmKey,
158  pose.transformFrom(measuredBearing.rotate(Point2(measuredRange, 0.0))));
159  }
160  }
161  else
162  {
163  throw std::runtime_error("Unknown factor type read from data file");
164  }
165  ++ nextMeasurement;
166  }
167  gttoc_(Collect_measurements);
168 
169  // Update iSAM2
170  gttic_(Update_ISAM2);
171  isam2.update(newFactors, newVariables);
172  gttoc_(Update_ISAM2);
173 
174  if(step % 100 == 0) {
175  gttic_(chi2);
176  Values estimate(isam2.calculateEstimate());
177  double chi2 = chi2_red(isam2.getFactorsUnsafe(), estimate);
178  cout << "chi2 = " << chi2 << endl;
179  gttoc_(chi2);
180  }
181 
183 
184  if(step % 1000 == 0) {
185  cout << "Step " << step << endl;
186  tictoc_print_();
187  }
188  }
189 
190  //try {
191  // {
192  // std::ofstream writerStream("incremental_init", ios::binary);
193  // boost::archive::binary_oarchive writer(writerStream);
194  // writer << isam2.calculateEstimate();
195  // writerStream.close();
196  // }
197  // {
198  // std::ofstream writerStream("incremental_graph", ios::binary);
199  // boost::archive::binary_oarchive writer(writerStream);
200  // writer << isam2.getFactorsUnsafe();
201  // writerStream.close();
202  // }
203  //} catch(std::exception& e) {
204  // cout << e.what() << endl;
205  //}
206 
208  Values values;
209 
210  //{
211  // std::ifstream readerStream("incremental_init", ios::binary);
212  // boost::archive::binary_iarchive reader(readerStream);
213  // reader >> values;
214  //}
215  //{
216  // std::ifstream readerStream("incremental_graph", ios::binary);
217  // boost::archive::binary_iarchive reader(readerStream);
218  // reader >> graph;
219  //}
220 
221  graph = isam2.getFactorsUnsafe();
222  values = isam2.calculateEstimate();
223 
224  // Compute marginals
225  try {
226  Marginals marginals(graph, values);
227  int i=0;
228  for (Key key1: boost::adaptors::reverse(values.keys())) {
229  int j=0;
230  for (Key key2: boost::adaptors::reverse(values.keys())) {
231  if(i != j) {
232  gttic_(jointMarginalInformation);
233  KeyVector keys(2);
234  keys[0] = key1;
235  keys[1] = key2;
236  JointMarginal info = marginals.jointMarginalInformation(keys);
237  gttoc_(jointMarginalInformation);
239  }
240  ++j;
241  if(j >= 50)
242  break;
243  }
244  ++i;
245  if(i >= 50)
246  break;
247  }
248  tictoc_print_();
249  for(Key key: values.keys()) {
250  gttic_(marginalInformation);
251  Matrix info = marginals.marginalInformation(key);
252  gttoc_(marginalInformation);
254  ++i;
255  }
256  } catch(std::exception& e) {
257  cout << e.what() << endl;
258  }
259  tictoc_print_();
260 
261  return 0;
262 }
size_t dim() const
Definition: Values.cpp:207
const gtsam::Key poseKey
def step(data, isam, result, truth, currPoseIndex)
Definition: visual_isam.py:82
size_t size() const
Definition: FactorGraph.h:306
bool exists(Key j) const
Definition: Values.cpp:104
#define gttic_(label)
Definition: timing.h:230
boost::shared_ptr< This > shared_ptr
void insert(Key j, const Value &val)
Definition: Values.cpp:140
GraphAndValues load2D(const string &filename, SharedNoiseModel model, size_t maxIndex, bool addNoise, bool smart, NoiseFormat noiseFormat, KernelFunctionType kernelFunctionType)
Definition: dataset.cpp:500
Vector2 Point2
Definition: Point2.h:27
Eigen::MatrixXd Matrix
Definition: base/Matrix.h:43
leaf::MyValues values
double measurement(10.0)
Definition: Half.h:150
IsDerived< DERIVEDFACTOR > push_back(boost::shared_ptr< DERIVEDFACTOR > factor)
Add a factor directly using a shared_ptr.
Definition: FactorGraph.h:166
NonlinearFactorGraph graph
KeyVector keys() const
Definition: Values.cpp:191
NoiseModelFactor2< Pose, Pose > NM2
void addPrior(Key key, const T &prior, const SharedNoiseModel &model=nullptr)
string findExampleDataFile(const string &name)
Definition: dataset.cpp:65
const Symbol key1('v', 1)
else if n * info
Values calculateEstimate() const
Definition: ISAM2.cpp:763
boost::shared_ptr< BetweenFactor > shared_ptr
Definition: BetweenFactor.h:60
int main(int argc, char *argv[])
FastVector< Key > KeyVector
Define collection type once and for all - also used in wrappers.
Definition: Key.h:86
static const Pose3 pose(Rot3(Vector3(1,-1,-1).asDiagonal()), Point3(0, 0, 0.5))
Incremental update functionality (ISAM2) for BayesTree, with fluid relinearization.
NoiseModelFactor1< Pose > NM1
boost::shared_ptr< This > shared_ptr
int data[]
JointMarginal jointMarginalInformation(const KeyVector &variables) const
Definition: Marginals.cpp:141
void tictoc_print_()
Definition: timing.h:253
Array< double, 1, 3 > e(1./3., 0.5, 2.)
double chi2_red(const gtsam::NonlinearFactorGraph &graph, const gtsam::Values &config)
traits
Definition: chartTesting.h:28
Pose2 Pose
GTSAM_EXPORT Point2 transformFrom(const Point2 &point, OptionalJacobian< 2, 3 > Dpose=boost::none, OptionalJacobian< 2, 2 > Dpoint=boost::none) const
Definition: Pose2.cpp:218
void reverse(const MatrixType &m)
const Symbol key2('v', 2)
virtual ISAM2Result update(const NonlinearFactorGraph &newFactors=NonlinearFactorGraph(), const Values &newTheta=Values(), const FactorIndices &removeFactorIndices=FactorIndices(), const boost::optional< FastMap< Key, int > > &constrainedKeys=boost::none, const boost::optional< FastList< Key > > &noRelinKeys=boost::none, const boost::optional< FastList< Key > > &extraReelimKeys=boost::none, bool force_relinearize=false)
Definition: ISAM2.cpp:396
A class for computing marginals in a NonlinearFactorGraph.
void tictoc_finishedIteration_()
Definition: timing.h:249
const KeyVector keys
const NonlinearFactorGraph & getFactorsUnsafe() const
Definition: ISAM2.h:257
2D Pose
#define gttoc_(label)
Definition: timing.h:235
utility functions for loading datasets
BearingRangeFactor< Pose, Point2 > BR
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:61
Marginals marginals(graph, result)
std::ptrdiff_t j
Timing utilities.
const Values & getLinearizationPoint() const
Access the current linearization point.
Definition: ISAM2.h:205
Matrix marginalInformation(Key variable) const
Definition: Marginals.cpp:121


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:50:33