93 num_robots_{num_robots},
95 exploration_map_{env.GetSystemExplorationMap()},
96 explored_idf_map_{env.GetSystemExploredIDFMap()} {
97 num_exploring_robots_ = num_robots_;
98 voronoi_cells_.resize(num_robots_);
101 actions_.resize(num_robots_);
102 goals_ = robot_global_positions_;
105 exploit_threshold_ = 0.2 * local_win_ * local_win_;
107 robot_status_.resize(num_robots_, 0);
108 frontiers_.resize(num_robots_);
116 rand_dist_ = std::uniform_real_distribution<>(0, 2 * M_PI);
131 for (
size_t iRobot = 0; iRobot < num_robots_; ++iRobot) {
132 robot_status_[iRobot] = 0;
136 robot_global_positions_[iRobot], local_win_,
149 if (unexplored < exploit_threshold_ and idf_value > exploit_threshold_) {
150 robot_status_[iRobot] = 1;
151 for (
size_t jRobot = 0; jRobot < iRobot; ++jRobot) {
152 double goal_dist = (goals_[iRobot] - goals_[jRobot]).norm();
153 if (goal_dist < too_close_factor_ * params_.
pSensorSize *
156 robot_status_[jRobot] = 0;
166 double best_bcr = 0, best_benefit = 0;
167 double pos_x_lim = std::min(pos[0] + 2 * time_step_dist_,
169 double pos_y_lim = std::min(pos[1] + 2 * time_step_dist_,
171 for (
double pos_x = std::max(pos[0] - 2 * time_step_dist_, eps);
172 pos_x < pos_x_lim; pos_x += 1 * params_.
pResolution) {
173 for (
double pos_y = std::max(pos[1] - 2 * time_step_dist_, eps);
174 pos_y < pos_y_lim; pos_y += 1 * params_.
pResolution) {
175 Point2 qpos{pos_x, pos_y};
176 double dist = (qpos - pos).norm();
178 dist = std::max(dist, time_step_dist_);
187 double benefit = unexplored;
188 if (unexplored > 0.1 * sensor_area_) {
194 benefit += 2 * idf_value;
196 double bcr = benefit / dist;
198 if (frontiers.size() < num_frontiers_) {
199 frontiers.push(
Frontier(qpos, bcr));
201 auto worst_frontier = frontiers.top();
202 if (worst_frontier.value < bcr) {
204 frontiers.push(
Frontier(qpos, bcr));
208 double bcr_diff = bcr - best_bcr;
210 if (bcr_diff < -
kEps) {
213 if (std::abs(bcr_diff) <
kEps) {
214 Point2 unit_best_goal = best_goal.normalized();
215 Point2 unit_qpos = qpos.normalized();
216 Point2 unit_curr_pos = pos.normalized();
217 if (unit_best_goal.dot(unit_curr_pos) >
218 unit_qpos.dot(unit_curr_pos)) {
223 if (bcr_diff >
kEps or update ==
true) {
226 best_benefit = benefit;
239#pragma omp parallel for num_threads(num_robots_)
240 for (
size_t iRobot = 0; iRobot < num_robots_; ++iRobot) {
241 frontiers_[iRobot] =
queue_t();
242 if (robot_status_[iRobot] == 0) {
243 double best_benefit =
246 if (best_benefit < better_threshold_) {
247 robot_status_[iRobot] = 1;
256 for (
size_t iRobot = 0; iRobot < num_robots_; ++iRobot) {
257 if (robot_status_[iRobot] != 0) {
258 exploit_robots_.push_back(iRobot);
261#pragma omp parallel for num_threads(num_robots_)
262 for (
size_t iRobot = 0; iRobot < num_robots_; ++iRobot) {
263 if (robot_status_[iRobot] != 0) {
264 Point2 const &pos = robot_global_positions_[iRobot];
270 MapType robot_local_map = explored_idf_map_.block(
284 for (
size_t jRobot = 0; jRobot < num_robots_; ++jRobot) {
285 if (iRobot == jRobot or robot_status_[jRobot] == 0) {
289 robot_global_positions_[jRobot] - robot_global_positions_[iRobot];
291 robot_neighbors_pos.push_back(robot_global_positions_[jRobot]);
294 PointVector robot_positions(robot_neighbors_pos.size() + 1);
296 robot_positions[0] = robot_global_positions_[iRobot] - map_translation;
300 for (
Point2 const &pos : robot_neighbors_pos) {
301 robot_positions[count] = pos - map_translation;
305 Voronoi voronoi(robot_positions, robot_local_map, map_size,
309 vcell.centroid() + robot_positions[0] + map_translation;
310 if (goals_[iRobot][0] < 0 or
312 goals_[iRobot][1] < 0 or
314 std::cout <<
"Goal out of bounds: " << goals_[iRobot][0] <<
" "
315 << goals_[iRobot][1] << std::endl;
316 std::cout << robot_global_positions_[iRobot][0] <<
" "
317 << robot_global_positions_[iRobot][1] << std::endl;
318 std::cout << vcell.centroid()[0] <<
" " << vcell.centroid()[1]
320 std::cout << map_translation[0] <<
" " << map_translation[1]
322 std::cout << robot_local_map.sum() << std::endl;
323 throw std::runtime_error(
324 "Goal out of bounds: this should not have happened for convex "
339 goals_ = robot_global_positions_;
340 if (first_step_ ==
true) {
342 for (
size_t iRobot = 0; iRobot < num_robots_; ++iRobot) {
343 double ang = rand_dist_(gen_);
344 goals_[iRobot] = robot_global_positions_[iRobot] +
345 time_step_dist_ *
Point2{cos(ang), sin(ang)};
351 is_converged_ =
true;
352 num_exploring_robots_ = 0;
353 for (
size_t iRobot = 0; iRobot < num_robots_; ++iRobot) {
354 if (robot_status_[iRobot] == 0) {
355 ++num_exploring_robots_;
359 for (
size_t iRobot = 0; iRobot < num_robots_; ++iRobot) {
360 actions_[iRobot] =
Point2(0, 0);
361 Point2 diff = goals_[iRobot] - robot_global_positions_[iRobot];
362 double dist = diff.norm();
366 direction.normalize();
367 actions_[iRobot] = speed * direction;
374 if (num_exploring_robots_ == 0) {
379 is_converged_ =
false;