spanning_tree.cpp
Go to the documentation of this file.
1 #include "lib/spanning_tree.h"
2 
4 {
5 }
6 
8 {
9  return mst_edges;
10 }
11 
12 geometry_msgs::PoseArray spanning_tree::get_tree ()
13 {
14  geometry_msgs::PoseArray path;
15  vector<geometry_msgs::Pose> poses;
16  geometry_msgs::Pose pose;
17 
18  for (auto e : mst_edges) {
19  // from
20  pose.position.x = e.from % map.info.width * map.info.resolution + map.info.origin.position.x;
21  pose.position.y = e.from / map.info.width * map.info.resolution + map.info.origin.position.y;
22 
23  // orientation
24  double dx = e.to % map.info.width * map.info.resolution + map.info.origin.position.x - pose.position.x;
25  double dy = e.to / map.info.width * map.info.resolution + map.info.origin.position.y - pose.position.y;
26  tf2::Quaternion direction;
27  direction.setRPY(0, 0, atan2(dy, dx));
28  pose.orientation = tf2::toMsg(direction);
29 
30  poses.push_back(pose);
31  }
32 
33  path.poses = poses;
34  path.header.stamp = Time::now();
35  path.header.frame_id = "local_origin_ned";
36  return path;
37 }
38 
39 void spanning_tree::initialize_graph (nav_msgs::OccupancyGrid gridmap, bool vertical, bool connect4)
40 {
41  // orientation of tree edges
42  this->vertical = vertical;
43 
44  // initialize map
45  map = gridmap;
46  int rows = gridmap.info.height;
47  int cols = gridmap.info.width;
48 
49  // empty containers
50  nodes.clear();
51  nodes.resize(rows*cols);
52  edges = priority_queue<edge, vector<edge>, compare_edge>();
53 
54  // iterate all rows and columns
55  for (int i=0; i<rows; i++) {
56  for (int j=0; j<cols; j++) {
57  // found a vertex
58  if (map.data[i*cols+j] == 0) {
59  // check von neumann neighborhood for connected vertices
60  if (i>0 && map.data[(i-1)*cols+j] == 0) {
61  add_edge(i*cols+j, (i-1)*cols+j, 1);
62  }
63  if (i<rows-1 && map.data[(i+1)*cols+j] == 0) {
64  add_edge(i*cols+j, (i+1)*cols+j, 1);
65  }
66  if (j>0 && map.data[i*cols+j-1] == 0) {
67  add_edge(i*cols+j, i*cols+j-1, 1);
68  }
69  if (j<cols-1 && map.data[i*cols+j+1] == 0) {
70  add_edge(i*cols+j, i*cols+j+1, 1);
71  }
72 
73  // check moore neighborhood for connected vertices
74  if (!connect4) {
75  if (i>0 && j>0 && map.data[(i-1)*cols+j-1] == 0) {
76  add_edge(i*cols+j, (i-1)*cols+j-1, 1);
77  }
78  if (i<rows-1 && j<cols-1 && map.data[(i+1)*cols+j+1] == 0) {
79  add_edge(i*cols+j, (i+1)*cols+j+1, 1);
80  }
81  if (i<rows-1 && j>0 && map.data[(i+1)*cols+j-1] == 0) {
82  add_edge(i*cols+j, (i+1)*cols+j-1, 1);
83  }
84  if (i>0 && j<cols-1 && map.data[(i-1)*cols+j+1] == 0) {
85  add_edge(i*cols+j, (i-1)*cols+j+1, 1);
86  }
87  }
88  }
89  }
90  }
91 }
92 
94 {
95  mst_edges.clear();
96 
97  while (!edges.empty()) {
98  // select shortest edge
99  edge edge = edges.top();
100 
101  // edge connects different sets
102  if (nodes[edge.from] != nodes[edge.to]) {
103  // combine the two sets
104  unordered_set<int> s(nodes[edge.from].begin(), nodes[edge.from].end());
105  for (auto v : nodes[edge.to])
106  s.insert(v);
107  for (auto v : s)
108  nodes[v] = s;
109 
110  // add edge to mst
111  mst_edges.push_back(edge);
112  }
113 
114  // remove edge from source tree
115  edges.pop();
116  }
117 }
118 
119 void spanning_tree::add_edge (int from, int to, int cost)
120 {
121  // add edge to priority queue
122  edges.push(edge(from, to, cost, vertical));
123 
124  // create singleton set for both vertices
125  if (nodes[from].size() == 0) {
126  nodes[from].insert(from);
127  }
128  if (nodes[to].size() == 0) {
129  nodes[to].insert(to);
130  }
131 }
132 
133 bool spanning_tree::different_sets (int a, int b)
134 {
135  return nodes[a] != nodes[b];
136 }
nav_msgs::OccupancyGrid map
The grid map that needs to be covered by the MST.
Definition: spanning_tree.h:87
void setRPY(const tf2Scalar &roll, const tf2Scalar &pitch, const tf2Scalar &yaw)
vector< edge > mst_edges
Edges in Minimal-Spanning Tree.
Definition: spanning_tree.h:82
void add_edge(int from, int to, int cost)
Add an edge to the tree.
void construct()
Generate the MST using Kruskal&#39;s algorithm.
XmlRpcServer s
A struct that provides the comparison of edge objects. It allows sorting of edges for priority queues...
Definition: edge.h:52
vector< edge > get_mst_edges()
Get the edges of the MST.
int to
The ending vertex of the edge.
Definition: edge.h:36
A class for representing edges.
Definition: edge.h:9
int from
The starting vertex of the edge.
Definition: edge.h:31
spanning_tree()
Constructor.
void initialize_graph(nav_msgs::OccupancyGrid gridmap, bool vertical=false, bool connect4=true)
Initialize the internal tree structure from a given grid map.
mst_path path
The coverage path.
Definition: coverage_path.h:70
B toMsg(const A &a)
geometry_msgs::PoseArray get_tree()
Get the generated MST for visualization.
vector< unordered_set< int > > nodes
The sets of connected vertices.
Definition: spanning_tree.h:72
bool vertical
Whether the sweeping pattern is vertical or horizontal.
priority_queue< edge, vector< edge >, compare_edge > edges
Priority queue of edge objects sorted by cost.
Definition: spanning_tree.h:77
bool different_sets(int a, int b)
Check whether two vertices are in different sets.


coverage_path
Author(s): Micha Sende
autogenerated on Tue Jan 19 2021 03:30:03