21 #include <boost/foreach.hpp>
23 #pragma GCC diagnostic push
24 #pragma GCC diagnostic ignored "-Wunused-variable"
27 #include <boost/graph/breadth_first_search.hpp>
29 #pragma GCC diagnostic pop
31 #include <boost/graph/prim_minimum_spanning_tree.hpp>
35 #define FOREACH_PAIR( KEY, VAL, COL) BOOST_FOREACH (boost::tie(KEY,VAL),COL)
44 template <
typename Vertex,
typename Graph>
void discover_vertex(Vertex v,
const Graph& g)
const {
45 KEY key = boost::get(boost::vertex_name, g, v);
46 ordering_.push_front(key);
48 std::list<KEY>& ordering_;
55 typedef typename SGraph<KEY>::Vertex SVertex;
59 std::map<KEY, SVertex> key2vertex;
60 boost::tie(g, root, key2vertex) = gtsam::predecessorMap2Graph<SGraph<KEY>, SVertex, KEY>(p_map);
65 boost::breadth_first_search(g, root, boost::visitor(vis));
70 template<
class G,
class F,
class KEY>
74 typedef typename boost::graph_traits<SDGraph<KEY> >::vertex_descriptor BoostVertex;
75 std::map<KEY, BoostVertex> key2vertex;
76 typename G::const_iterator itFactor;
79 for(itFactor=graph.begin(); itFactor!=graph.end(); itFactor++) {
82 if ((*itFactor)->keys().size() != 2)
86 boost::shared_ptr<F> factor = boost::dynamic_pointer_cast<F>(*itFactor);
88 if (!factor)
continue;
91 KEY key1 = factor->keys()[0];
92 KEY key2 = factor->keys()[1];
97 if (key2vertex.find(key1) == key2vertex.end()) {
98 v1 = add_vertex(key1, g);
99 key2vertex.insert(std::pair<KEY,KEY>(key1, v1));
101 v1 = key2vertex[key1];
104 if (key2vertex.find(key2) == key2vertex.end()) {
105 v2 = add_vertex(key2, g);
106 key2vertex.insert(std::pair<KEY,KEY>(key2, v2));
108 v2 = key2vertex[key2];
111 boost::property<boost::edge_weight_t, double> edge_property(1.0);
112 boost::add_edge(v1, v2, edge_property, g);
119 template<
class G,
class V,
class KEY>
120 boost::tuple<G, V, std::map<KEY,V> >
124 std::map<KEY, V> key2vertex;
127 bool foundRoot =
false;
128 FOREACH_PAIR(child, parent, p_map) {
129 if (key2vertex.find(child) == key2vertex.end()) {
130 v1 = add_vertex(child, g);
131 key2vertex.insert(std::make_pair(child, v1));
133 v1 = key2vertex[child];
135 if (key2vertex.find(parent) == key2vertex.end()) {
136 v2 = add_vertex(parent, g);
137 key2vertex.insert(std::make_pair(parent, v2));
139 v2 = key2vertex[parent];
145 boost::add_edge(v2, v1, g);
149 throw std::invalid_argument(
"predecessorMap2Graph: invalid predecessor map!");
151 return boost::tuple<G, V, std::map<KEY, V> >(g, root, key2vertex);
155 template <
class V,
class POSE,
class KEY>
159 boost::shared_ptr<Values> config_;
165 template <
typename Edge,
typename Graph>
void tree_edge(Edge edge,
const Graph& g)
const {
166 KEY key_from = boost::get(boost::vertex_name, g, boost::source(edge, g));
167 KEY key_to = boost::get(boost::vertex_name, g, boost::target(edge, g));
168 POSE relativePose = boost::get(boost::edge_weight, g, edge);
169 config_->insert(key_to, config_->at<POSE>(key_from).compose(relativePose));
175 template<
class G,
class Factor,
class POSE,
class KEY>
177 const POSE& rootPose) {
180 typedef typename boost::adjacency_list<
181 boost::vecS, boost::vecS, boost::directedS,
182 boost::property<boost::vertex_name_t, KEY>,
183 boost::property<boost::edge_weight_t, POSE> > PoseGraph;
184 typedef typename boost::graph_traits<PoseGraph>::vertex_descriptor PoseVertex;
185 typedef typename boost::graph_traits<PoseGraph>::edge_descriptor PoseEdge;
189 std::map<KEY, PoseVertex> key2vertex;
190 boost::tie(g, root, key2vertex) =
191 predecessorMap2Graph<PoseGraph, PoseVertex, KEY>(tree);
194 PoseEdge edge12, edge21;
196 BOOST_FOREACH(
typename G::sharedFactor nl_factor, graph) {
198 if (nl_factor->keys().size() > 2)
199 throw std::invalid_argument(
"composePoses: only support factors with at most two keys");
202 boost::shared_ptr<Factor> factor = boost::dynamic_pointer_cast<
Factor>(nl_factor);
203 if (!factor)
continue;
205 KEY key1 = factor->key1();
206 KEY key2 = factor->key2();
208 PoseVertex v1 = key2vertex.find(key1)->second;
209 PoseVertex v2 = key2vertex.find(key2)->second;
211 POSE l1Xl2 = factor->measured();
212 boost::tie(edge12, found1) = boost::edge(v1, v2, g);
213 boost::tie(edge21, found2) = boost::edge(v2, v1, g);
214 if (found1 && found2)
throw std::invalid_argument (
"composePoses: invalid spanning tree");
215 if (!found1 && !found2)
continue;
217 boost::put(boost::edge_weight, g, edge12, l1Xl2);
219 boost::put(boost::edge_weight, g, edge21, l1Xl2.inverse());
223 boost::shared_ptr<Values> config(
new Values);
224 KEY rootKey = boost::get(boost::vertex_name, g, root);
225 config->insert(rootKey, rootPose);
227 boost::breadth_first_search(g, root, boost::visitor(vis));
233 template<
class G,
class KEY,
class FACTOR2>
237 SDGraph<KEY> g = gtsam::toBoostGraph<G, FACTOR2, KEY>(fg);
240 std::vector<typename SDGraph<KEY>::Vertex> p_map(boost::num_vertices(g));
241 prim_minimum_spanning_tree(g, &p_map[0]);
246 BOOST_FOREACH(
const typename SDGraph<KEY>::Vertex& vi, p_map){
247 KEY key = boost::get(boost::vertex_name, g, *itVertex);
248 KEY parent = boost::get(boost::vertex_name, g, vi);
256 template<
class G,
class KEY,
class FACTOR2>
259 typedef typename G::sharedFactor F ;
261 BOOST_FOREACH(
const F& factor, g)
263 if (factor->keys().size() > 2)
264 throw(std::invalid_argument(
"split: only support factors with at most two keys"));
266 if (factor->keys().size() == 1) {
267 Ab1.push_back(factor);
271 boost::shared_ptr<FACTOR2> factor2 = boost::dynamic_pointer_cast<
273 if (!factor2)
continue;
275 KEY key1 = factor2->key1();
276 KEY key2 = factor2->key2();
278 if ((tree.find(key1) != tree.end() &&
279 tree.find(key1)->second.compare(key2) == 0) ||
280 (tree.find(key2) != tree.end() &&
281 tree.find(key2)->second.compare(key1)== 0) )
282 Ab1.push_back(factor2);
284 Ab2.push_back(factor2);
boost::tuple< G, V, std::map< KEY, V > > predecessorMap2Graph(const PredecessorMap< KEY > &p_map)
Build takes a predecessor map, and builds a directed graph corresponding to the tree.
Definition: graph-inl.h:121
SDGraph is undirected graph with variable keys and double edge weights.
Definition: graph.h:38
PredecessorMap< KEY > findMinimumSpanningTree(const G &fg)
find the minimum spanning tree using boost graph library
Definition: graph-inl.h:234
Map from variable key to parent key.
Definition: graph.h:58
boost::shared_ptr< Values > composePoses(const G &graph, const PredecessorMap< KEY > &tree, const POSE &rootPose)
Compose the poses by following the chain specified by the spanning tree.
Definition: graph-inl.h:176
This is the base class for all factor types.
Definition: Factor.h:51
Graph algorithm using boost library.
Definition: graph-inl.h:41
A non-templated config holding any types of Manifold-group elements.
Definition: Values.h:75
std::list< KEY > predecessorMap2Keys(const PredecessorMap< KEY > &p_map)
Generate a list of keys from a spanning tree represented by its predecessor map.
Definition: graph-inl.h:53
Definition: graph-inl.h:156
void insert(const KEY &key, const KEY &parent)
convenience insert so we can pass ints for TypedSymbol keys
Definition: graph.h:61
SDGraph< KEY > toBoostGraph(const G &graph)
Convert the factor graph to an SDGraph G = Graph type F = Factor type Key = Key type.
Definition: graph-inl.h:71
void split(const G &g, const PredecessorMap< KEY > &tree, G &Ab1, G &Ab2)
Split the graph into two parts: one corresponds to the given spanning tree, and the other corresponds...
Definition: graph-inl.h:257