Coverage Control Library
Loading...
Searching...
No Matches
plotter.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the CoverageControl library
3 *
4 * Author: Saurav Agarwal
5 * Contact: sauravag@seas.upenn.edu, agr.saurav1@gmail.com
6 * Repository: https://github.com/KumarRobotics/CoverageControl
7 *
8 * Copyright (c) 2024, Saurav Agarwal
9 *
10 * The CoverageControl library is free software: you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or (at your
13 * option) any later version.
14 *
15 * The CoverageControl library is distributed in the hope that it will be
16 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
18 * Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License along with
21 * CoverageControl library. If not, see <https://www.gnu.org/licenses/>.
22 */
23
29#include <filesystem>
30#include <iostream>
31
32#include "CoverageControl/extern/gnuplot/gnuplot-iostream.h"
34
35namespace CoverageControl {
36
37[[nodiscard]] bool Plotter::GnuplotCommands(Gnuplot &gp) {
38 std::filesystem::path map_filename{
39 std::filesystem::weakly_canonical(dir + "/" + plot_name)};
40 std::filesystem::path dir_path{map_filename.parent_path()};
41 if (!std::filesystem::exists(dir_path)) {
42 std::cerr << "Directory does not exist: " << dir_path << std::endl;
43 return 1;
44 }
45 gp << "set o '" << map_filename.string() << "'\n";
46 gp << "set terminal pngcairo enhanced font 'Times," << font_sz << "' size "
47 << image_sz << "," << image_sz << "\n";
48 gp << "set palette defined (-5 'black', -1 '" << color_unknown
49 << "', 0 'white', 1 '" << color_idf << "')\n";
50 gp << "set cbrange [-5:1]\n";
51 gp << "set size ratio -1\n";
52 gp << "set xrange [0:" << range_max << "]\n";
53 gp << "set yrange [0:" << range_max << "]\n";
54 gp << "set border linewidth 1.5\n";
55 if (unset_colorbox) gp << "unset colorbox\n";
56 return 0;
57}
58
59void Plotter::StreamMap(Gnuplot &gp, MapType const &map) {
60 for (int i = 0; i < map.rows(); ++i) {
61 for (int j = 0; j < map.cols(); ++j) {
62 gp << map(i, j) << " ";
63 }
64 gp << "\n";
65 }
66 gp << "e" << std::endl;
67}
68
69void Plotter::PlotMap(Gnuplot &gp, bool begin) {
70 if (begin == true)
71 gp << "plot ";
72 else
73 gp << ", ";
74 gp << "'-' matrix using ($2*" << resolution << "):($1*" << resolution
75 << "):3 with image notitle ";
76}
77
78void Plotter::PlotLine(Gnuplot &gp, int marker_size, std::string color,
79 bool begin) {
80 if (begin == true)
81 gp << "plot ";
82 else
83 gp << ", ";
84 gp << "'-' with line lw " << marker_size << " lc rgb '" << color
85 << "' notitle";
86}
87
88void Plotter::PlotPoints(Gnuplot &gp, int point_type, int marker_size,
89 std::string color, bool begin) {
90 if (begin == true)
91 gp << "plot ";
92 else
93 gp << ", ";
94 gp << "'-' with points pt " << point_type << " ps " << marker_size
95 << " lc rgb '" << color << "' notitle";
96}
97
98void Plotter::PlotMap(MapType const &map) {
99 Gnuplot gp;
100 if (GnuplotCommands(gp)) {
101 std::cerr << "Error in GnuplotCommands" << std::endl;
102 return;
103 }
104 PlotMap(gp);
105 gp << "\n";
106 StreamMap(gp, map);
107}
108
109void Plotter::PlotMap(MapType const &map, PointVector const &positions) {
110 Gnuplot gp;
111 if (GnuplotCommands(gp)) {
112 std::cerr << "Error in GnuplotCommands" << std::endl;
113 return;
114 }
115 PlotMap(gp);
116 PlotPoints(gp, 7, marker_sz, color_robot);
117 gp << "\n";
118
119 StreamMap(gp, map);
120
121 for (auto const &pos : positions) {
122 gp << pos[0] << " " << pos[1] << std::endl;
123 }
124 gp << "e" << std::endl;
125}
126
127void Plotter::PlotMap(MapType const &map, PointVector const &positions,
128 std::vector<std::list<Point2>> const &trajectories,
129 std::vector<int> const &robot_status) {
130 Gnuplot gp;
131 if (GnuplotCommands(gp)) {
132 std::cerr << "Error in GnuplotCommands" << std::endl;
133 return;
134 }
135 PlotMap(gp);
136
137 for (size_t i = 0; i < positions.size(); ++i) {
138 if (robot_status[i] == 0) {
139 PlotLine(gp, marker_sz, color_robot, false);
140 } else {
141 PlotLine(gp, marker_sz, color_robot_alt, false);
142 }
143 }
144 for (size_t i = 0; i < positions.size(); ++i) {
145 if (robot_status[i] == 0) {
146 PlotPoints(gp, 7, marker_sz, color_robot, false);
147 } else {
148 PlotPoints(gp, 7, marker_sz, color_robot_alt, false);
149 }
150 }
151 gp << "\n";
152
153 StreamMap(gp, map);
154 for (auto const &trajectory : trajectories) {
155 for (auto const &pos : trajectory) {
156 gp << pos[0] << " " << pos[1] << std::endl;
157 }
158 gp << "e" << std::endl;
159 }
160
161 for (auto const &pos : positions) {
162 gp << pos[0] << " " << pos[1] << std::endl;
163 gp << "e" << std::endl;
164 }
165}
166
167void Plotter::PlotMap(MapType const &map, PointVector const &positions,
168 std::vector<std::list<Point2>> const &trajectories,
169 std::vector<int> const &robot_status,
170 double const &communication_range) {
171 Gnuplot gp;
172 if (GnuplotCommands(gp)) {
173 std::cerr << "Error in GnuplotCommands" << std::endl;
174 return;
175 }
176 PlotMap(gp);
177
178 for (size_t i = 0; i < positions.size(); ++i) {
179 if (robot_status[i] == 0) {
180 PlotLine(gp, marker_sz, color_robot, false);
181 } else {
182 PlotLine(gp, marker_sz, color_robot_alt, false);
183 }
184 }
185 PlotLine(gp, half_marker_sz, color_communication_links, false);
186 for (size_t i = 0; i < positions.size(); ++i) {
187 if (robot_status[i] == 0) {
188 PlotPoints(gp, 7, marker_sz, color_robot, false);
189 } else {
190 PlotPoints(gp, 7, marker_sz, color_robot_alt, false);
191 }
192 }
193 gp << "\n";
194
195 StreamMap(gp, map);
196 for (auto const &trajectory : trajectories) {
197 for (auto const &pos : trajectory) {
198 gp << pos[0] << " " << pos[1] << std::endl;
199 }
200 gp << "e" << std::endl;
201 }
202
203 for (size_t i = 0; i < positions.size(); ++i) {
204 for (size_t j = i + 1; j < positions.size(); ++j) {
205 if ((positions[i] - positions[j]).norm() < communication_range) {
206 gp << positions[i][0] << " " << positions[i][1] << "\n";
207 gp << positions[j][0] << " " << positions[j][1] << "\n";
208 gp << "\n";
209 }
210 }
211 }
212 gp << "e" << std::endl;
213 for (auto const &pos : positions) {
214 gp << pos[0] << " " << pos[1] << std::endl;
215 gp << "e" << std::endl;
216 }
217}
218
219void Plotter::PlotMap(MapType const &map, PointVector const &positions,
220 std::vector<std::list<Point2>> const &voronoi,
221 std::vector<std::list<Point2>> const &trajectories) {
222 Gnuplot gp;
223 if (GnuplotCommands(gp)) {
224 std::cerr << "Error in GnuplotCommands" << std::endl;
225 return;
226 }
227 PlotMap(gp);
228
229 PlotLine(gp, marker_sz, color_robot, false);
230 PlotLine(gp, half_marker_sz, color_voronoi, false); // voronoi
231 PlotPoints(gp, 7, marker_sz, color_robot, false); // robots
232 gp << "\n";
233
234 StreamMap(gp, map);
235
236 for (auto const &trajectory : trajectories) {
237 for (auto const &pos : trajectory) {
238 gp << pos[0] << " " << pos[1] << "\n";
239 }
240 gp << "\n";
241 }
242 gp << "e" << std::endl;
243
244 for (auto const &vcell : voronoi) {
245 for (auto const &pos : vcell) {
246 gp << pos[0] << " " << pos[1] << "\n";
247 }
248 gp << "\n";
249 }
250 gp << "e" << std::endl;
251
252 for (auto const &pos : positions) {
253 gp << pos[0] << " " << pos[1] << "\n";
254 }
255 gp << "e" << std::endl;
256}
257
258void Plotter::PlotMap(MapType const &map, PointVector const &positions,
259 Voronoi const &voronoi,
260 std::vector<std::list<Point2>> const &trajectories) {
261 Gnuplot gp;
262 if (GnuplotCommands(gp)) {
263 std::cerr << "Error in GnuplotCommands" << std::endl;
264 return;
265 }
266 PlotMap(gp);
267
268 PlotLine(gp, marker_sz, color_robot, false);
269 PlotLine(gp, half_marker_sz, color_voronoi, false); // voronoi
270 PlotPoints(gp, 7, marker_sz, color_robot, false); // robots
271 gp << "\n";
272
273 StreamMap(gp, map);
274
275 for (auto const &trajectory : trajectories) {
276 for (auto const &pos : trajectory) {
277 gp << pos[0] << " " << pos[1] << "\n";
278 }
279 gp << "\n";
280 }
281 gp << "e" << std::endl;
282
283 auto voronoi_cells = voronoi.GetVoronoiCells();
284 for (auto const &vcell : voronoi_cells) {
285 for (auto const &pos : vcell.cell) {
286 gp << pos[0] << " " << pos[1] << "\n";
287 }
288 auto const &pos = vcell.cell.front();
289 gp << pos[0] << " " << pos[1] << "\n";
290 gp << "\n";
291 }
292 gp << "e" << std::endl;
293
294 for (auto const &pos : positions) {
295 gp << pos[0] << " " << pos[1] << "\n";
296 }
297 gp << "e" << std::endl;
298}
299
300void Plotter::PlotMap(MapType const &map, PointVector const &positions,
301 PointVector const &goals, Voronoi const &voronoi) {
302 Gnuplot gp;
303 if (GnuplotCommands(gp)) {
304 std::cerr << "Error in GnuplotCommands" << std::endl;
305 return;
306 }
307 PlotMap(gp);
308
309 PlotLine(gp, half_marker_sz, color_voronoi, false); // voronoi
310 PlotLine(gp, half_marker_sz, color_robot, false); // goals path
311 PlotPoints(gp, 28, marker_sz, color_robot, false); // goals
312 PlotPoints(gp, 7, marker_sz, color_robot, false); // robots
313 gp << "\n";
314
315 StreamMap(gp, map);
316
317 auto voronoi_cells = voronoi.GetVoronoiCells();
318 for (auto const &vcell : voronoi_cells) {
319 for (auto const &pos : vcell.cell) {
320 gp << pos[0] << " " << pos[1] << std::endl;
321 }
322 auto const &pos = vcell.cell.front();
323 gp << pos[0] << " " << pos[1] << std::endl;
324 gp << "\n";
325 }
326 gp << "e" << std::endl;
327
328 for (size_t i = 0; i < positions.size(); ++i) {
329 auto const &pos = positions[i];
330 auto const &goal = goals[i];
331 gp << pos[0] << " " << pos[1] << std::endl;
332 gp << goal[0] << " " << goal[1] << std::endl;
333 gp << "\n";
334 }
335 gp << "e" << std::endl;
336
337 for (auto const &pos : goals) {
338 gp << pos[0] << " " << pos[1] << std::endl;
339 }
340 gp << "e" << std::endl;
341
342 for (auto const &pos : positions) {
343 gp << pos[0] << " " << pos[1] << std::endl;
344 }
345 gp << "e" << std::endl;
346}
347
348void Plotter::PlotMap(MapType const &map, PointVector const &positions,
349 std::vector<std::list<Point2>> const &trajectories,
350 PointVector const &frontiers) {
351 Gnuplot gp;
352 if (GnuplotCommands(gp)) {
353 std::cerr << "Error in GnuplotCommands" << std::endl;
354 return;
355 }
356
357 PlotMap(gp);
358 PlotLine(gp, marker_sz, color_robot);
359 PlotPoints(gp, 7, marker_sz, color_robot);
360 PlotPoints(gp, 1, half_marker_sz, color_robot);
361
362 gp << "\n";
363
364 StreamMap(gp, map);
365 for (auto const &trajectory : trajectories) {
366 for (auto const &pos : trajectory) {
367 gp << pos[0] << " " << pos[1] << std::endl;
368 }
369 gp << "\n";
370 }
371 gp << "e" << std::endl;
372
373 for (auto const &pos : positions) {
374 gp << pos[0] << " " << pos[1] << std::endl;
375 }
376 gp << "e" << std::endl;
377
378 for (auto const &pos : frontiers) {
379 gp << pos[0] << " " << pos[1] << std::endl;
380 }
381 gp << "e" << std::endl;
382}
383
384} // namespace CoverageControl
Class for computing Voronoi cells.
Definition voronoi.h:116
auto GetVoronoiCells() const
Definition voronoi.h:185
Eigen::Matrix< float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > MapType
Definition typedefs.h:48
std::vector< Point2 > PointVector
Definition typedefs.h:51
Namespace for the CoverageControl library.
Class to plot the map.