22 #pragma GCC diagnostic push 23 #pragma GCC diagnostic ignored "-Wunused-variable" 26 #include <boost/graph/breadth_first_search.hpp> 28 #pragma GCC diagnostic pop 30 #include <boost/graph/prim_minimum_spanning_tree.hpp> 52 const auto [
g, root, key2vertex] = gtsam::predecessorMap2Graph<SGraph<KEY>, SVertex,
KEY>(p_map);
57 boost::breadth_first_search(
g, root, boost::visitor(vis));
62 template<
class G,
class F,
class KEY>
66 typedef typename boost::graph_traits<SDGraph<KEY> >::vertex_descriptor BoostVertex;
67 std::map<KEY, BoostVertex> key2vertex;
68 typename G::const_iterator itFactor;
71 for(itFactor=graph.begin(); itFactor!=graph.end(); itFactor++) {
74 if ((*itFactor)->keys().size() != 2)
78 std::shared_ptr<F> factor = std::dynamic_pointer_cast<
F>(*itFactor);
80 if (!factor)
continue;
89 if (key2vertex.find(key1) == key2vertex.end()) {
90 v1 = add_vertex(key1, g);
91 key2vertex.insert(std::pair<KEY,KEY>(key1, v1));
93 v1 = key2vertex[
key1];
96 if (key2vertex.find(key2) == key2vertex.end()) {
97 v2 = add_vertex(key2, g);
98 key2vertex.insert(std::pair<KEY,KEY>(key2, v2));
100 v2 = key2vertex[
key2];
103 boost::property<boost::edge_weight_t, double> edge_property(1.0);
104 boost::add_edge(v1, v2, edge_property, g);
111 template<
class G,
class V,
class KEY>
112 std::tuple<G, V, std::map<KEY,V> >
116 std::map<KEY, V> key2vertex;
118 bool foundRoot =
false;
119 for(
const auto& [child, parent]: p_map) {
120 if (key2vertex.find(child) == key2vertex.end()) {
121 v1 = add_vertex(child, g);
122 key2vertex.emplace(child, v1);
124 v1 = key2vertex[child];
126 if (key2vertex.find(parent) == key2vertex.end()) {
127 v2 = add_vertex(parent, g);
128 key2vertex.emplace(parent, v2);
130 v2 = key2vertex[parent];
136 boost::add_edge(v2, v1, g);
140 throw std::invalid_argument(
"predecessorMap2Graph: invalid predecessor map!");
142 return std::tuple<G, V, std::map<KEY, V> >(
g, root, key2vertex);
146 template <
class V,
class POSE,
class KEY>
156 template <
typename Edge,
typename Graph>
void tree_edge(Edge edge,
const Graph&
g)
const {
157 KEY key_from =
boost::get(boost::vertex_name, g, boost::source(edge, g));
158 KEY key_to =
boost::get(boost::vertex_name, g, boost::target(edge, g));
159 POSE relativePose =
boost::get(boost::edge_weight, g, edge);
160 config_->insert(key_to, config_->at<POSE>(key_from).compose(relativePose));
166 template<
class G,
class Factor,
class POSE,
class KEY>
168 const POSE& rootPose) {
171 typedef typename boost::adjacency_list<
172 boost::vecS, boost::vecS, boost::directedS,
173 boost::property<boost::vertex_name_t, KEY>,
174 boost::property<boost::edge_weight_t, POSE> > PoseGraph;
175 typedef typename boost::graph_traits<PoseGraph>::vertex_descriptor PoseVertex;
179 std::map<KEY, PoseVertex> key2vertex;
180 std::tie(g, root, key2vertex) =
181 predecessorMap2Graph<PoseGraph, PoseVertex, KEY>(tree);
184 for(
typename G::sharedFactor nl_factor: graph) {
186 if (nl_factor->keys().size() > 2)
187 throw std::invalid_argument(
"composePoses: only support factors with at most two keys");
190 std::shared_ptr<Factor> factor = std::dynamic_pointer_cast<
Factor>(nl_factor);
191 if (!factor)
continue;
196 PoseVertex
v1 = key2vertex.find(key1)->second;
197 PoseVertex
v2 = key2vertex.find(key2)->second;
199 POSE l1Xl2 = factor->measured();
200 const auto [edge12, found1] = boost::edge(v1, v2, g);
201 const auto [edge21, found2] = boost::edge(v2, v1, g);
202 if (found1 && found2)
throw std::invalid_argument (
"composePoses: invalid spanning tree");
203 if (!found1 && !found2)
continue;
205 boost::put(boost::edge_weight, g, edge12, l1Xl2);
207 boost::put(boost::edge_weight, g, edge21, l1Xl2.inverse());
211 std::shared_ptr<Values> config(
new Values);
213 config->insert(rootKey, rootPose);
215 boost::breadth_first_search(g, root, boost::visitor(vis));
221 template<
class G,
class KEY,
class FACTOR2>
228 std::vector<typename SDGraph<KEY>::Vertex> p_map(boost::num_vertices(g));
229 prim_minimum_spanning_tree(g, &p_map[0]);
244 template<
class G,
class KEY,
class FACTOR2>
247 typedef typename G::sharedFactor
F ;
249 for(
const F& factor: g)
251 if (factor->keys().size() > 2)
252 throw(std::invalid_argument(
"split: only support factors with at most two keys"));
254 if (factor->keys().size() == 1) {
255 Ab1.push_back(factor);
259 std::shared_ptr<FACTOR2>
factor2 = std::dynamic_pointer_cast<
261 if (!factor2)
continue;
266 if ((tree.find(key1) != tree.end() &&
267 tree.find(key1)->second.compare(key2) == 0) ||
268 (tree.find(key2) != tree.end() &&
269 tree.find(key2)->second.compare(key1)== 0) )
270 Ab1.push_back(factor2);
272 Ab2.push_back(factor2);
const gtsam::Symbol key('X', 0)
std::shared_ptr< Values > composePoses(const G &graph, const PredecessorMap< KEY > &tree, const POSE &rootPose)
void insert(const KEY &key, const KEY &parent)
PredecessorMap< KEY > findMinimumSpanningTree(const G &fg)
ordering_key_visitor(std::list< KEY > &ordering_in)
std::shared_ptr< Values > config_
JacobiRotation< float > G
void tree_edge(Edge edge, const Graph &g) const
NonlinearFactorGraph graph
void discover_vertex(Vertex v, const Graph &g) const
void g(const string &key, int i)
void split(const G &g, const PredecessorMap< KEY > &tree, G &Ab1, G &Ab2)
SDGraph< KEY > toBoostGraph(const G &graph)
const Symbol key1('v', 1)
std::tuple< G, V, std::map< KEY, V > > predecessorMap2Graph(const PredecessorMap< KEY > &p_map)
boost::graph_traits< SDGraph< KEY > >::vertex_descriptor Vertex
Array< int, Dynamic, 1 > v
compose_key_visitor(std::shared_ptr< Values > config_in)
Graph algorithm using boost library.
std::list< KEY > & ordering_
boost::graph_traits< SGraph< KEY > >::vertex_descriptor Vertex
Container::iterator get(Container &c, Position position)
std::list< KEY > predecessorMap2Keys(const PredecessorMap< KEY > &p_map)
const Symbol key2('v', 2)