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;
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()) {
91 key2vertex.insert(std::pair<KEY,KEY>(
key1,
v1));
96 if (key2vertex.find(
key2) == key2vertex.end()) {
98 key2vertex.insert(std::pair<KEY,KEY>(
key2,
v2));
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<