30#ifndef CPPSRC_CORE_INCLUDE_COVERAGECONTROL_COVERAGE_SYSTEM_H_
31#define CPPSRC_CORE_INCLUDE_COVERAGECONTROL_COVERAGE_SYSTEM_H_
68 std::shared_ptr <WorldIDF> world_idf_ptr_;
69 size_t num_robots_ = 0;
70 std::vector<RobotModel> robots_;
71 double normalization_factor_ = 0;
73 std::vector<VoronoiCell> voronoi_cells_;
74 mutable std::random_device
76 mutable std::mt19937 gen_;
77 mutable std::mutex mutex_;
78 std::uniform_real_distribution<>
87 std::vector<std::list<Point2>>
88 robot_positions_history_;
89 double exploration_ratio_ = 0;
90 double weighted_exploration_ratio_ =
92 double total_idf_weight_ = 0;
93 std::vector<PlotterData> plotter_data_;
94 std::vector<std::vector<Point2>>
95 relative_positions_neighbors_;
97 std::vector<std::vector<int>>
104 void UpdateSystemMap() {
106 for (
size_t i = 0; i < num_robots_; ++i) {
111 explored_idf_map_.block(index.
left + offset.
left,
116 exploration_map_.block(
120 system_map_ = explored_idf_map_ - exploration_map_;
134 void PostStepCommands(
size_t robot_id);
139 void PostStepCommands();
142 void ComputeAdjacencyMatrix();
145 void UpdateRobotPositions() {
146 for (
size_t iRobot = 0; iRobot < num_robots_; ++iRobot) {
147 robot_global_positions_[iRobot] =
148 robots_[iRobot].GetGlobalCurrentPosition();
153 void UpdateNeighbors();
177 int const num_robots);
180 int const num_polygons,
int const num_robots);
190 std::string
const &pos_file_name);
199 std::vector<Point2>
const &robot_positions);
208 std::vector<BivariateNormalDistribution>
const &dists,
209 std::vector<Point2>
const &robot_positions);
224 Point2 const &relative_pos) {
225 robots_[robot_id].SetRobotPosition(relative_pos);
226 PostStepCommands(robot_id);
231 robots_[robot_id].SetGlobalRobotPosition(global_pos);
232 PostStepCommands(robot_id);
237 if (global_positions.size() != num_robots_) {
238 throw std::length_error{
239 "The size of the positions don't match with the number of robots"};
241 for (
size_t i = 0; i < num_robots_; ++i) {
242 robots_[i].SetGlobalRobotPosition(global_positions[i]);
250 if (positions.size() != num_robots_) {
251 throw std::length_error{
252 "The size of the positions don't match with the number of robots"};
254 for (
size_t i = 0; i < num_robots_; ++i) {
255 robots_[i].SetRobotPosition(positions[i]);
262 world_idf_ptr_.reset(
new WorldIDF{world_idf});
263 normalization_factor_ = world_idf_ptr_->GetNormalizationFactor();
280 for (
size_t iRobot = 0; iRobot < num_robots_; ++iRobot) {
281 Point2 action = actions[iRobot];
282 double speed = action.norm();
283 Point2 direction = action.normalized();
284 if (robots_[iRobot].
StepControl(direction, speed)) {
285 std::cerr <<
"Control incorrect\n";
304 double speed = action.norm();
305 Point2 direction = action.normalized();
306 if (robots_[robot_id].
StepControl(direction, speed)) {
307 std::cerr <<
"Control incorrect\n";
326 double const speed) {
327 if (robots_[robot_id].
StepControl(direction, speed)) {
328 std::cerr <<
"Control incorrect\n";
345 if (robot_positions_history_[robot_id].size() < 3) {
348 auto const &history = robot_positions_history_[robot_id];
349 Point2 const last_pos = history.back();
350 auto it_end = std::next(history.crbegin(), std::min(6,
static_cast<int>(history.size()) - 1));
353 std::for_each(history.crbegin(), it_end,
354 [last_pos, &count](
Point2 const &pt) {
355 if ((pt - last_pos).norm() < kLargeEps) {
366 if (
id >= num_robots_) {
367 throw std::out_of_range{
"Robot index more than the number of robots"};
372 UpdateRobotPositions();
373 voronoi_ =
Voronoi(robot_global_positions_, GetWorldMap(),
387 bool StepRobotToGoal(
int const robot_id,
Point2 const &goal,
388 double const speed_factor = 1);
400 for (
size_t i = 0; i < num_robots_; ++i) {
401 robots_[i].ClearRobotMap();
414 int WriteRobotPositions(std::string
const &file_name)
const;
415 int WriteRobotPositions(std::string
const &file_name,
417 int WriteEnvironment(std::string
const &pos_filename,
418 std::string
const &env_filename)
const;
423 void PlotFrontiers(std::string
const &,
int const &,
426 std::vector<int> robot_status(num_robots_, 0);
427 PlotSystemMap(dir_name, step, robot_status);
429 void PlotSystemMap(std::string
const &)
const;
430 void PlotSystemMap(std::string
const &,
int const &,
431 std::vector<int>
const &)
const;
432 void PlotMapVoronoi(std::string
const &,
int const &);
433 void PlotMapVoronoi(std::string
const &,
int const &,
Voronoi const &,
435 void PlotWorldMap(std::string
const &, std::string
const &)
const;
436 void PlotWorldMapRobots(std::string
const &, std::string
const &)
const;
438 PlotInitMap(
"./", filename);
440 void PlotInitMap(std::string
const &, std::string
const &)
const;
441 void PlotRobotLocalMap(std::string
const &,
int const &,
int const &);
442 void PlotRobotSystemMap(std::string
const &,
int const &,
int const &);
443 void PlotRobotExplorationMap(std::string
const &,
int const &,
int const &);
444 void PlotRobotSensorView(std::string
const &,
int const &,
int const &);
445 void PlotRobotObstacleMap(std::string
const &,
int const &,
int const &);
446 void PlotRobotCommunicationMaps(std::string
const &,
int const &,
int const &,
449 void RenderRecordedMap(std::string
const &, std::string
const &)
const;
450 void RecordPlotData(std::vector<int>
const &, std::string
const &);
452 RecordPlotData(robot_status,
"system");
455 std::vector<int> robot_status(num_robots_, 0);
456 RecordPlotData(robot_status, map_name);
459 std::vector<int> robot_status(num_robots_, 0);
460 RecordPlotData(robot_status,
"system");
468 return world_idf_ptr_;
482 return robots_[id].GetRobotMapMutable();
489 double exploration_ratio =
490 1.0 -
static_cast<double>(exploration_map_.sum()) /
492 return exploration_ratio;
497 double weighted_exploration_ratio =
498 static_cast<double>(explored_idf_map_.sum()) / (total_idf_weight_);
499 return weighted_exploration_ratio;
502 PointVector GetRelativePositonsNeighbors(
size_t const robot_id);
504 return neighbor_ids_[robot_id];
515 UpdateRobotPositions();
518 for (
Point2 pt : robot_global_positions_) {
519 noisy_robot_global_positions.push_back(AddNoise(pt));
521 return noisy_robot_global_positions;
523 return robot_global_positions_;
527 bool force_no_noise =
false)
const {
529 robot_pos[0] = robots_[robot_id].GetGlobalCurrentPosition()[0];
530 robot_pos[1] = robots_[robot_id].GetGlobalCurrentPosition()[1];
532 return AddNoise(robot_pos);
539 return robots_[id].GetRobotLocalMap();
544 return robots_[id].GetRobotMap();
549 return robots_[id].GetExplorationMap();
554 return robots_[id].GetRobotSystemMap();
558 return robots_[id].GetObstacleMap();
563 return robots_[id].GetSensorView();
569 for (
size_t i = 0; i < num_robots_; ++i) {
574 robot_global_positions_[i] - robot_global_positions_[id];
576 robot_neighbors_pos.push_back(relative_pos);
580 robot_neighbors_pos.begin(), robot_neighbors_pos.end(),
581 [](
Point2 const &a,
Point2 const &b) { return a.norm() < b.norm(); });
582 return robot_neighbors_pos;
585 std::pair<MapType, MapType> GetRobotCommunicationMaps(
size_t const,
size_t);
588 std::vector<MapType> communication_maps(2 * num_robots_);
590 for (
size_t i = 0; i < num_robots_; ++i) {
591 auto comm_map = GetRobotCommunicationMaps(i, map_size);
592 communication_maps[2 * i] = comm_map.first;
593 communication_maps[2 * i + 1] = comm_map.second;
595 return communication_maps;
599 ComputeVoronoiCells();
604 std::vector<std::vector<double>> features(num_robots_);
605#pragma omp parallel for num_threads(num_robots_)
606 for (
size_t iRobot = 0; iRobot < num_robots_; ++iRobot) {
607 features[iRobot] = robots_[iRobot].GetExplorationFeatures();
613 std::vector<std::vector<double>> features(num_robots_);
614#pragma omp parallel for num_threads(num_robots_)
615 for (
size_t iRobot = 0; iRobot < num_robots_; ++iRobot) {
616 features[iRobot] = robots_[iRobot].GetVoronoiFeatures();
624 std::vector<double> GetLocalVoronoiFeatures(
int const robot_id);
627 std::vector<std::vector<double>> features(num_robots_);
628#pragma omp parallel for num_threads(num_robots_)
629 for (
size_t iRobot = 0; iRobot < num_robots_; ++iRobot) {
630 features[iRobot] = GetLocalVoronoiFeatures(iRobot);
641 normalization_factor_ = world_idf_ptr_->GetNormalizationFactor();
642 return normalization_factor_;
Class for Bivariate Normal Distribution.
The CoverageSystem class is the main class for the coverage control library.
PointVector GetRobotPositions(bool force_no_noise=false)
Get the global positions of all robots.
const MapType & GetSystemExploredIDFMap() const
MapType & GetWorldMapMutable()
Get the world map (mutable)
double GetExplorationRatio() const
void SetLocalRobotPositions(std::vector< Point2 > const &relative_pos)
double GetWeightedExplorationRatio() const
Get the weighted (by IDF) exploration ratio.
auto GetVoronoiCell(int const robot_id)
bool StepControl(size_t robot_id, Point2 const &direction, double const speed)
Execute velocity control for robot_id.
MapType & GetSystemExploredIDFMapMutable()
std::vector< MapType > GetCommunicationMaps(size_t map_size)
const MapType & GetRobotExplorationMap(size_t const id)
const MapType & GetRobotSensorView(size_t const id) const
void RecordPlotData(std::string const &map_name)
const MapType & GetSystemExplorationMap() const
auto GetRobotExplorationFeatures()
const MapType & GetSystemMap() const
auto GetNumFeatures() const
void RecordPlotData(std::vector< int > const &robot_status)
double GetNormalizationFactor()
std::vector< int > GetNeighborIDs(size_t const robot_id) const
const MapType & GetRobotObstacleMap(size_t const id)
void CheckRobotID(size_t const id) const
std::shared_ptr< const WorldIDF > GetWorldIDFPtr() const
bool CheckOscillation(size_t const robot_id) const
void ComputeVoronoiCells()
bool StepActions(PointVector const &actions)
Execute given actions for all robots.
void PlotInitMap(std::string const &filename) const
Point2 GetRobotPosition(int const robot_id, bool force_no_noise=false) const
const MapType & GetWorldMap() const
Get the world map.
MapType & GetRobotMapMutable(size_t const id)
void SetRobotPositions(std::vector< Point2 > const &positions)
void PlotSystemMap(std::string const &dir_name, int const &step) const
auto GetRobotVoronoiFeatures()
std::vector< std::vector< double > > GetLocalVoronoiFeatures()
auto GetRobotsInCommunication(size_t const id) const
auto GetNumRobots() const
const MapType & GetRobotMap(size_t const id) const
const MapType & GetRobotSystemMap(size_t const id)
void SetGlobalRobotPosition(size_t const robot_id, Point2 const &global_pos)
Set the global position of robot_id.
void SetLocalRobotPosition(size_t const robot_id, Point2 const &relative_pos)
Set the position of robot_id with respect to its current position.
bool StepAction(size_t const robot_id, Point2 const action)
Execute given action for robot_id.
const WorldIDF & GetWorldIDFObject() const
const MapType & GetRobotLocalMap(size_t const id)
Point2 AddNoise(Point2 const pt) const
Add noise to the given point and ensure within bounds.
void SetGlobalRobotPositions(PointVector const &global_positions)
Set the global positions of all robots.
void SetWorldIDF(WorldIDF const &world_idf)
Set the world IDF and recompute the world map.
Class to store parameters.
double pCommunicationRange
Radius of communication (in meters)
Class for computing Voronoi cells.
auto GetVoronoiCells() const
double GetSumIDFSiteDistSqr()
Class for Importance Density Function (IDF) for the world.
Constants for the CoverageControl library.
Eigen::Matrix< float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > MapType
std::vector< Point2 > PointVector
Utility functions for transforming maps.
void ComputeOffsets(double const resolution, Point2 const &pos, int const submap_size, int const map_size, MapBounds &index, MapBounds &offset)
Namespace for the CoverageControl library.
Class for handling the robot model.
Contains typedefs for the library.
Class for computing Voronoi cells.
Contains the class for Importance Density Function (IDF) for the world.