Skip to content

Commit faf534c

Browse files
author
Saurav Agarwal
committed
Add random polygonal features
1 parent ff3514f commit faf534c

File tree

18 files changed

+643
-248
lines changed

18 files changed

+643
-248
lines changed

cppsrc/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ set(sources_list
118118
polygon_utils.cpp
119119
parameters.cpp
120120
voronoi.cpp
121+
world_idf.cpp
121122
coverage_system.cpp
122123
plotter.cpp
123124
cuda_utils.cpp

cppsrc/core/include/CoverageControl/cgal/config.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,12 @@
3636
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
3737
#include <CGAL/Partition_traits_2.h>
3838
#include <CGAL/Polygon_with_holes_2.h>
39+
#include <CGAL/Random.h>
40+
#include <CGAL/algorithm.h>
3941
#include <CGAL/centroid.h>
4042
#include <CGAL/partition_2.h>
43+
#include <CGAL/point_generators_2.h>
44+
#include <CGAL/random_polygon_2.h>
4145

4246
#include <iterator>
4347

@@ -58,4 +62,7 @@ typedef CGAL::Arr_walk_along_line_point_location<Arrangement_2> CGAL_pl;
5862

5963
typedef CGAL::Partition_traits_2<K> Partition_traits_2;
6064

65+
typedef CGAL::Creator_uniform_2<double, CGAL_Point2> Creator;
66+
typedef CGAL::Random_points_in_square_2<CGAL_Point2, Creator> Point_generator;
67+
6168
#endif // CPPSRC_CORE_INCLUDE_COVERAGECONTROL_CGAL_CONFIG_H_

cppsrc/core/include/CoverageControl/cgal/polygon_utils.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,20 @@ namespace CoverageControl {
4343
void PolygonYMonotonePartition(PointVector const &polygon,
4444
std::vector<PointVector> &y_monotone_polygons);
4545

46+
/*! \brief Generate random polygons
47+
*
48+
* @param[in] num_polygons The number of polygons to generate
49+
* @param[in] max_vertices The maximum number of vertices in each polygon
50+
* @param[bounding_box_lower] The lower left corner of the bounding box
51+
* @param[bounding_box_upper] The upper right corner of the bounding box
52+
* @param[radius] The radius of the circle in which the polygons are generated
53+
* @param[out] polygons The output polygons
54+
*/
55+
56+
void GenerateRandomPolygons(int const num_polygons, int const max_vertices,
57+
double const half_width, double const world_size,
58+
std::vector<PointVector> &polygons);
59+
4660
} /* namespace CoverageControl */
4761

4862
#endif // CPPSRC_CORE_INCLUDE_COVERAGECONTROL_CGAL_POLYGON_UTILS_H_

cppsrc/core/include/CoverageControl/coverage_system.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,9 @@ class CoverageSystem {
180180
CoverageSystem(Parameters const &params, int const num_gaussians,
181181
int const num_robots);
182182

183+
CoverageSystem(Parameters const &params, int const num_gaussians,
184+
int const num_polygons, int const num_robots);
185+
183186
/*! \brief Create with given world IDF and robot positions from file
184187
*
185188
*
@@ -441,10 +444,13 @@ class CoverageSystem {
441444
//
442445
//! @{
443446
const auto &GetWorldIDFObject() const { return world_idf_; }
444-
const MapType &GetWorldMap() const { return world_idf_.GetWorldMap(); }
445447
const MapType &GetSystemMap() const { return system_map_; }
446448
const MapType &GetSystemExplorationMap() const { return exploration_map_; }
447449
const MapType &GetSystemExploredIDFMap() const { return explored_idf_map_; }
450+
//! Get the world map
451+
const MapType &GetWorldMap() const { return world_idf_.GetWorldMap(); }
452+
//! Get the world map (mutable)
453+
MapType &GetWorldMapMutable() { return world_idf_.GetWorldMapMutable(); }
448454

449455
inline auto GetNumRobots() const { return num_robots_; }
450456
inline auto GetNumFeatures() const { return num_robots_; }

cppsrc/core/include/CoverageControl/cuda/geometry_utils.cuh

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ namespace CoverageControl {
4141
* left of the vector \return -1 if point r is in clockwise direction, i.e.,
4242
* right of the vector \return 0 otherwise
4343
*/
44-
__device__ int Orientation(float2 const &p, float2 const &q, float2 const &r) {
44+
__host__ __device__ int Orientation(float2 const &p, float2 const &q,
45+
float2 const &r) {
4546
float2 qp{q.x - p.x, q.y - p.y};
4647
float2 rp{r.x - p.x, r.y - p.y};
4748
float cross_prod1 = qp.x * rp.y;
@@ -55,8 +56,8 @@ __device__ int Orientation(float2 const &p, float2 const &q, float2 const &r) {
5556
* Check if the point r is inside the monotone polygon defined by the vertices x
5657
* and y \return true if the point is inside the polygon \return false otherwise
5758
*/
58-
__device__ bool IsPointInMonotonePolygon(float *x, float *y, int sz,
59-
float2 const &r) {
59+
__host__ __device__ bool IsPointInMonotonePolygon(float *x, float *y, int sz,
60+
float2 const &r) {
6061
bool left = false;
6162
bool right = false;
6263
for (int ct = 0; ct < sz; ++ct) {

cppsrc/core/include/CoverageControl/parameters.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ class Parameters {
5757
*/
5858
int pNumRobots = 32; //!< Number of robots
5959
int pNumFeatures = 32; //!< Number of features
60+
int pNumPolygons = 0; //!< Number of polygonal features
61+
int pMaxVertices = 10; //!< Maximum number of vertices in a polygon
62+
double pPolygonRadius = 64;
6063

6164
/*! \name Map Parameters
6265
* @{

cppsrc/core/include/CoverageControl/world_idf.h

Lines changed: 21 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,20 @@ class WorldIDF {
176176
params_ = params;
177177
}
178178

179+
WorldIDF(Parameters const &params, MapType const &world_map)
180+
: WorldIDF(params.pWorldMapSize) {
181+
params_ = params;
182+
if (world_map.rows() != params.pWorldMapSize ||
183+
world_map.cols() != params.pWorldMapSize) {
184+
std::cout << "Error: World map size does not match the specified size"
185+
<< std::endl;
186+
throw std::invalid_argument(
187+
"World map size does not match the specified size");
188+
exit(1);
189+
}
190+
world_map_ = world_map;
191+
}
192+
179193
WorldIDF(Parameters const &params, std::string const &file_name)
180194
: WorldIDF(params.pWorldMapSize) {
181195
params_ = params;
@@ -201,14 +215,15 @@ class WorldIDF {
201215
} else if (type == "Uniform") {
202216
int num_vertices;
203217
file >> num_vertices;
218+
double importance;
219+
file >>
220+
importance; // importance moved here. Be careful with semantic file
204221
std::vector<Point2> vertices;
205222
for (int i = 0; i < num_vertices; ++i) {
206223
double x, y;
207224
file >> x >> y;
208225
vertices.push_back(Point2(x, y));
209226
}
210-
double importance;
211-
file >> importance;
212227
AddUniformDistributionPolygon(PolygonFeature(vertices, importance));
213228
} else {
214229
std::cout << "Error: Unknown feature type " << type << std::endl;
@@ -305,74 +320,15 @@ class WorldIDF {
305320

306321
const MapType &GetWorldMap() const { return world_map_; }
307322

308-
inline int WriteDistributions(std::string const &file_name) const {
309-
std::ofstream file(file_name);
310-
if (!file.is_open()) {
311-
std::cerr << "Could not open file: " << file_name << std::endl;
312-
return -1;
313-
}
314-
file << std::setprecision(kMaxPrecision);
315-
for (auto const &dist : normal_distributions_) {
316-
Point2 sigma = dist.GetSigma();
317-
if (sigma.x() == sigma.y()) {
318-
file << "CircularBND" << std::endl;
319-
file << dist.GetMean().x() << " " << dist.GetMean().y() << " "
320-
<< sigma.x() << " " << dist.GetScale() << std::endl;
321-
} else {
322-
file << "BND" << std::endl;
323-
file << dist.GetMean().x() << " " << dist.GetMean().y() << " "
324-
<< dist.GetSigma().x() << " " << dist.GetSigma().y() << " "
325-
<< dist.GetRho() << " " << dist.GetScale() << std::endl;
326-
}
327-
}
328-
file.close();
329-
return 0;
330-
}
323+
MapType &GetWorldMapMutable() { return world_map_; }
324+
325+
int WriteDistributions(std::string const &file_name) const;
331326

332327
auto GetNumFeatures() const {
333328
return normal_distributions_.size() + polygon_features_.size();
334329
}
335330

336-
/*! Fills in values of the world_map_ with the total importance for each cell
337-
*/
338-
void GenerateMapCPU() {
339-
/* std::cout << "Generating map using CPU" << std::endl; */
340-
float max_importance = 0;
341-
float res = static_cast<float>(params_.pResolution);
342-
for (int i = 0; i < params_.pWorldMapSize; ++i) { // Row (x index)
343-
float x1 = res * i; // Left x-coordinate of pixel
344-
float x2 = x1 + res; // Right x-coordinate of pixel
345-
for (int j = 0; j < params_.pWorldMapSize; ++j) { // Column (y index)
346-
float y1 = res * j; // Lower y-coordinate of pixel
347-
float y2 = y1 + res; // Upper y-coordinate of pixel
348-
float importance = ComputeImportanceBND<Point2f, float>(
349-
Point2f(x1, y1), Point2f(x2, y2));
350-
/* auto importance = ComputeImportanceBND(pt1, pt2); */
351-
/* if (std::abs(importance) < kEps) { */
352-
/* importance = 0; */
353-
/* } */
354-
world_map_(i, j) = importance;
355-
if (importance > max_importance) {
356-
max_importance = importance;
357-
}
358-
}
359-
}
360-
361-
if (max_importance < kEps) {
362-
normalization_factor_ = static_cast<float>(params_.pNorm);
363-
} else {
364-
normalization_factor_ =
365-
static_cast<float>(params_.pNorm) / max_importance;
366-
}
367-
368-
// Normalize the world map
369-
#pragma omp parallel for
370-
for (int i = 0; i < params_.pWorldMapSize; ++i) {
371-
for (int j = 0; j < params_.pWorldMapSize; ++j) {
372-
world_map_(i, j) *= normalization_factor_;
373-
}
374-
}
375-
}
331+
void GenerateMapCPU();
376332

377333
#ifdef COVERAGECONTROL_WITH_CUDA
378334
void GenerateMapCuda() {

cppsrc/core/src/coverage_system.cpp

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,15 @@
3232
namespace CoverageControl {
3333

3434
CoverageSystem::CoverageSystem(Parameters const &params)
35-
: CoverageSystem(params, params.pNumFeatures, params.pNumRobots) {}
35+
: CoverageSystem(params, params.pNumFeatures, params.pNumPolygons,
36+
params.pNumRobots) {}
3637

37-
CoverageSystem::CoverageSystem(Parameters const &params, int const num_features,
38+
CoverageSystem::CoverageSystem(Parameters const &params,
39+
int const num_gaussians, int const num_robots)
40+
: CoverageSystem(params, num_gaussians, 0, num_robots) {}
41+
42+
CoverageSystem::CoverageSystem(Parameters const &params,
43+
int const num_gaussians, int const num_polygons,
3844
int const num_robots)
3945
: params_{params}, world_idf_{WorldIDF(params_)} {
4046
// Generate Bivariate Normal Distribution from random numbers
@@ -48,22 +54,34 @@ CoverageSystem::CoverageSystem(Parameters const &params, int const num_features,
4854
params_.pMaxSigma);
4955
std::uniform_real_distribution<> distrib_peak(params_.pMinPeak,
5056
params_.pMaxPeak);
51-
for (int i = 0; i < num_features; ++i) {
57+
for (int i = 0; i < num_gaussians; ++i) {
5258
Point2 mean(distrib_pts_(gen_), distrib_pts_(gen_));
5359
double sigma(distrib_var(gen_));
5460
double scale(distrib_peak(gen_));
61+
scale = 2 * M_PI * sigma * sigma * scale;
5562
BivariateNormalDistribution dist(mean, sigma, scale);
5663
world_idf_.AddNormalDistribution(dist);
5764
}
5865

66+
std::vector<PointVector> polygons;
67+
GenerateRandomPolygons(num_polygons, params_.pMaxVertices,
68+
params_.pPolygonRadius,
69+
params_.pWorldMapSize * params_.pResolution, polygons);
70+
71+
for (auto &poly : polygons) {
72+
double importance = distrib_peak(gen_) * 0.5;
73+
PolygonFeature poly_feature(poly, importance);
74+
world_idf_.AddUniformDistributionPolygon(poly_feature);
75+
}
76+
5977
world_idf_.GenerateMap();
6078
normalization_factor_ = world_idf_.GetNormalizationFactor();
6179

62-
std::uniform_real_distribution<> robot_pos_dist(
80+
std::uniform_real_distribution<> env_point_dist(
6381
kLargeEps, params_.pRobotInitDist - kLargeEps);
6482
robots_.reserve(num_robots);
6583
for (int i = 0; i < num_robots; ++i) {
66-
Point2 start_pos(robot_pos_dist(gen_), robot_pos_dist(gen_));
84+
Point2 start_pos(env_point_dist(gen_), env_point_dist(gen_));
6785
robots_.push_back(RobotModel(params_, start_pos, world_idf_));
6886
}
6987
InitSetup();

0 commit comments

Comments
 (0)