NASA Astrobee Robot Software  0.19.1
Flight software for the Astrobee robots operating inside the International Space Station.
graph_optimizer.h
Go to the documentation of this file.
1 /* Copyright (c) 2017, United States Government, as represented by the
2  * Administrator of the National Aeronautics and Space Administration.
3  *
4  * All rights reserved.
5  *
6  * The Astrobee platform is licensed under the Apache License, Version 2.0
7  * (the "License"); you may not use this file except in compliance with the
8  * License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15  * License for the specific language governing permissions and limitations
16  * under the License.
17  */
18 
19 #ifndef GRAPH_OPTIMIZER_GRAPH_OPTIMIZER_H_
20 #define GRAPH_OPTIMIZER_GRAPH_OPTIMIZER_H_
21 
24 #include <optimizers/optimizer.h>
25 #include <node_adders/node_adder.h>
26 #include <nodes/values.h>
29 
30 #include <gtsam/nonlinear/NonlinearFactorGraph.h>
31 
32 #include <boost/serialization/serialization.hpp>
33 
34 #include <memory>
35 #include <string>
36 #include <utility>
37 #include <vector>
38 
39 namespace graph_optimizer {
40 // Time-based factor graph optimizer that uses FactorAdders to generate and add factors for a given time range to the
41 // graph and NodeAdders to provide corresponding nodes for these factors at required timestamps. Generally FactorAdders
42 // are measurement-based and generate factors for a certain type of measurement at given timestamps. NodeAdders are also
43 // typically measurement-based and create linked nodes using relative factors that span the graph. As an example, a
44 // Visual-Inertial Odometry (VIO) graph may contain an image-based FactorAdder that generates visual-odometry factors
45 // using image measurements. A VIO graph will solve for Pose/Velocity/IMU Bias (PVB) values at different timestamps, so
46 // it will also contain a PVB NodeAdder that creates timestamped PVB nodes for the visual-odometry factors and links
47 // these nodes using IMU measurements. See the FactorAdder and NodeAdder packages for more information and different
48 // types of FactorAdders and NodeAdders. Maintains a set of values used for optimization. All NodeAdders added to the
49 // GraphOptimizer should be constructed using the GraphOptimizer's values (accessable with the values() member
50 // function). Acts as a base class for the SlidingWindowGraphOptimizer.
52  public:
53  // Construct GraphOptimizer with provided optimizer.
54  GraphOptimizer(const GraphOptimizerParams& params, std::unique_ptr<optimizers::Optimizer> optimizer);
55 
56  // Default constructor for serialization only
58 
59  virtual ~GraphOptimizer() = default;
60 
61  // Adds node adder used for graph optimization.
62  // Initializes the nodes and priors for the node adder.
63  void AddNodeAdder(std::shared_ptr<node_adders::NodeAdder> node_adder);
64 
65  // Adds factor adder used for graph optimization.
66  void AddFactorAdder(std::shared_ptr<factor_adders::FactorAdder> factor_adder);
67 
68  // Adds factors for each factor in valid time range to the graph.
69  // Since factor adders are linked to the node adder they use, this also adds required
70  // nodes for these factors.
71  // Return the number of factors added by the factor adders, not including the relative factors added by the node
72  // adders.
73  // TODO(rsoussan): Return both?
74  int AddFactors(const localization_common::Time start_time, const localization_common::Time end_time);
75 
76  // Wrapper for AddFactors passing a pair of timestamps.
77  int AddFactors(const std::pair<localization_common::Time, localization_common::Time>& start_and_end_time);
78 
79  // Performs optimization on the factor graph.
80  bool Optimize();
81 
82  // Calculates the covariance matrix for the provided node's key.
83  // Requires a successful round of optimization to have been performed.
84  boost::optional<gtsam::Matrix> Covariance(const gtsam::Key& key) const;
85 
86  // Calculates the covariance matrix wrt two nodes for the provided keys.
87  // Requires a successful round of optimization to have been performed.
88  boost::optional<gtsam::Matrix> Covariance(const gtsam::Key& key_a, const gtsam::Key& key_b) const;
89 
90  // Returns set of factors currently in the graph.
91  const gtsam::NonlinearFactorGraph& factors() const;
92 
93  // Returns set of factors currently in the graph.
94  gtsam::NonlinearFactorGraph& factors();
95 
96  // Returns set of factors of FactorType currently in the graph.
97  template <typename FactorType>
98  std::vector<boost::shared_ptr<const FactorType>> Factors() const;
99 
100  // Returns number of factors currently in the graph.
101  int num_factors() const;
102 
103  // Returns number of factors of provided FactorType currently in the graph.
104  template <typename FactorType>
105  int NumFactors() const;
106 
107  // Returns number of values currently in the graph.
108  int num_values() const;
109 
110  // Graph optimizer params.
111  const GraphOptimizerParams& params() const;
112 
113  // Returns a shared pointer to the values used by the graph optimizer.
114  // All node adders added to the graph optimizer should be constructed
115  // with these values.
116  std::shared_ptr<nodes::Values> values();
117 
118  // Returns a const reference to the gtsam Values used within the Values object.
119  const gtsam::Values& gtsam_values() const;
120 
121  // Returns a reference to the stats logger
123 
124  // Returns a const reference to the optimization timer
126 
127  // Returns a const reference to the optimization_iterations averager
129 
130  // Sum of factor errors for each factor in the graph
131  double TotalGraphError() const;
132 
133  // Optional validity check for graph before optimizing.
134  // If this fails, no optimization is performed.
135  // Default behavior always returns true.
136  virtual bool ValidGraph() const;
137 
138  // Prints factor graph information and logs stats.
139  virtual void Print() const;
140 
141  // Saves the graph to a dot file, can be used to generate visual representation
142  // of the graph.
143  void SaveGraphDotFile(const std::string& output_path = "graph.dot") const;
144 
145  // Returns marginals if they have been calculated.
146  boost::optional<const gtsam::Marginals&> marginals() const;
147 
148  private:
149  // Add averagers and timers for logging.
150  void AddAveragersAndTimers();
151 
152  // Returns a reference to the gtsam Values used within the Values object.
153  gtsam::Values& gtsam_values();
154 
155  // Serialization function
157  template <class Archive>
158  void serialize(Archive& ar, const unsigned int file_version) {
159  ar& BOOST_SERIALIZATION_NVP(params_);
160  ar& BOOST_SERIALIZATION_NVP(optimizer_);
161  ar& BOOST_SERIALIZATION_NVP(factors_);
162  ar& BOOST_SERIALIZATION_NVP(values_);
163  ar& BOOST_SERIALIZATION_NVP(factor_adders_);
164  ar& BOOST_SERIALIZATION_NVP(node_adders_);
165  ar& BOOST_SERIALIZATION_NVP(stats_logger_);
166  ar& BOOST_SERIALIZATION_NVP(optimization_timer_);
167  ar& BOOST_SERIALIZATION_NVP(optimization_timer_);
168  ar& BOOST_SERIALIZATION_NVP(optimization_iterations_averager_);
169  ar& BOOST_SERIALIZATION_NVP(total_error_averager_);
170  }
171 
172  GraphOptimizerParams params_;
173  std::unique_ptr<optimizers::Optimizer> optimizer_;
174  gtsam::NonlinearFactorGraph factors_;
175  std::shared_ptr<nodes::Values> values_;
176  std::vector<std::shared_ptr<factor_adders::FactorAdder>> factor_adders_;
177  std::vector<std::shared_ptr<node_adders::NodeAdder>> node_adders_;
178  localization_common::StatsLogger stats_logger_;
179 
180  // Logging
181  localization_common::Timer optimization_timer_ = localization_common::Timer("Optimization");
182  localization_common::Averager optimization_iterations_averager_ =
183  localization_common::Averager("Optimization Iterations");
184  localization_common::Averager total_error_averager_ = localization_common::Averager("Total Factor Error");
185 };
186 
187 // Implementation
188 template <typename FactorType>
189 std::vector<boost::shared_ptr<const FactorType>> GraphOptimizer::Factors() const {
190  std::vector<boost::shared_ptr<const FactorType>> factors_vector;
191  for (const auto& factor : factors()) {
192  const auto casted_factor = boost::dynamic_pointer_cast<const FactorType>(factor);
193  if (casted_factor) factors_vector.emplace_back(casted_factor);
194  }
195  return factors_vector;
196 }
197 
198 template <typename FactorType>
200  int num_factors = 0;
201  for (const auto& factor : factors()) {
202  const auto casted_factor = boost::dynamic_pointer_cast<const FactorType>(factor);
203  if (casted_factor) ++num_factors;
204  }
205  return num_factors;
206 }
207 } // namespace graph_optimizer
208 
209 #endif // GRAPH_OPTIMIZER_GRAPH_OPTIMIZER_H_
localization_common::Timer
Definition: timer.h:30
factor_adder.h
graph_optimizer::GraphOptimizer::stats_logger
localization_common::StatsLogger & stats_logger()
Definition: graph_optimizer.cc:104
values.h
graph_optimizer::GraphOptimizer::NumFactors
int NumFactors() const
Definition: graph_optimizer.h:199
localization_common::Averager
Definition: averager.h:34
graph_optimizer::GraphOptimizer::TotalGraphError
double TotalGraphError() const
Definition: graph_optimizer.cc:112
graph_optimizer::GraphOptimizer::Factors
std::vector< boost::shared_ptr< const FactorType > > Factors() const
Definition: graph_optimizer.h:189
graph_optimizer::GraphOptimizer::GraphOptimizer
GraphOptimizer()
Definition: graph_optimizer.h:57
graph_optimizer_params.h
localization_common::StatsLogger
Definition: stats_logger.h:30
graph_optimizer::GraphOptimizer
Definition: graph_optimizer.h:51
graph_optimizer::GraphOptimizer::AddNodeAdder
void AddNodeAdder(std::shared_ptr< node_adders::NodeAdder > node_adder)
Definition: graph_optimizer.cc:40
stats_logger.h
graph_optimizer::GraphOptimizer::num_factors
int num_factors() const
Definition: graph_optimizer.cc:92
node_adder.h
graph_optimizer::GraphOptimizer::AddFactors
int AddFactors(const localization_common::Time start_time, const localization_common::Time end_time)
Definition: graph_optimizer.cc:49
graph_optimizer::GraphOptimizer::Print
virtual void Print() const
Definition: graph_optimizer.cc:123
time.h
graph_optimizer::GraphOptimizer::~GraphOptimizer
virtual ~GraphOptimizer()=default
graph_optimizer::GraphOptimizer::ValidGraph
virtual bool ValidGraph() const
Definition: graph_optimizer.cc:121
graph_optimizer::GraphOptimizer::values
std::shared_ptr< nodes::Values > values()
Definition: graph_optimizer.cc:98
graph_optimizer
Definition: graph_optimizer.h:39
graph_optimizer::GraphOptimizer::gtsam_values
const gtsam::Values & gtsam_values() const
Definition: graph_optimizer.cc:100
graph_optimizer::GraphOptimizer::Covariance
boost::optional< gtsam::Matrix > Covariance(const gtsam::Key &key) const
Definition: graph_optimizer.cc:80
graph_optimizer::GraphOptimizer::optimization_timer
const localization_common::Timer & optimization_timer() const
Definition: graph_optimizer.cc:106
graph_optimizer::GraphOptimizer::AddFactorAdder
void AddFactorAdder(std::shared_ptr< factor_adders::FactorAdder > factor_adder)
Definition: graph_optimizer.cc:45
graph_optimizer::GraphOptimizer::num_values
int num_values() const
Definition: graph_optimizer.cc:94
graph_optimizer::GraphOptimizer::Optimize
bool Optimize()
Definition: graph_optimizer.cc:61
graph_optimizer::GraphOptimizer::factors
const gtsam::NonlinearFactorGraph & factors() const
Definition: graph_optimizer.cc:88
optimizer.h
graph_optimizer::GraphOptimizer::params
const GraphOptimizerParams & params() const
Definition: graph_optimizer.cc:96
graph_optimizer::GraphOptimizerParams
Definition: graph_optimizer_params.h:22
localization_common::Time
double Time
Definition: time.h:23
graph_optimizer::GraphOptimizer::SaveGraphDotFile
void SaveGraphDotFile(const std::string &output_path="graph.dot") const
Definition: graph_optimizer.cc:128
graph_optimizer::GraphOptimizer::marginals
boost::optional< const gtsam::Marginals & > marginals() const
Definition: graph_optimizer.cc:133
graph_optimizer::GraphOptimizer::optimization_iterations_averager
const localization_common::Averager & optimization_iterations_averager() const
Definition: graph_optimizer.cc:108
graph_optimizer::GraphOptimizer::access
friend class boost::serialization::access
Definition: graph_optimizer.h:156