41 #include <mbf_msgs/GetPathResult.h>
62 double tolerance, std::vector<geometry_msgs::PoseStamped>& plan,
double& cost,
66 std::list<std::pair<mesh_map::Vector, lvr2::FaceHandle>> path;
70 ROS_INFO(
"start wave front propagation.");
91 const auto& face_normals =
mesh_map->faceNormals();
92 for (
auto& next : path)
94 geometry_msgs::PoseStamped pose;
100 plan.push_back(pose);
103 geometry_msgs::PoseStamped pose;
107 plan.push_back(pose);
110 nav_msgs::Path path_msg;
111 path_msg.poses = plan;
150 new dynamic_reconfigure::Server<wave_front_planner::WaveFrontPlannerConfig>(
private_nh));
160 ROS_INFO_STREAM(
"New height diff layer config through dynamic reconfigure.");
173 const auto& face_normals =
mesh_map->faceNormals();
174 const auto& vertex_normals =
mesh_map->vertexNormals();
176 for (
auto v3 :
mesh.vertices())
195 const auto& vec3 =
mesh.getVertexPosition(v3);
196 const auto& vec1 =
mesh.getVertexPosition(v1);
200 const auto dirVec = (vec1 - vec3).rotated(vertex_normals[v3],
direction[v3]);
208 std::list<std::pair<mesh_map::Vector, lvr2::FaceHandle>>& path)
221 const double u1 = distances[v1];
222 const double u2 = distances[v2];
223 const double u3 = distances[v3];
226 const double c = edge_weights[e12h.
unwrap()];
227 const double c_sq = c * c;
230 const double b = edge_weights[e13h.
unwrap()];
231 const double b_sq = b * b;
234 const double a = edge_weights[e23h.
unwrap()];
235 const double a_sq = a * a;
237 const double u1_sq = u1 * u1;
238 const double u2_sq = u2 * u2;
240 const double A = sqrt(std::max<double>((-u1 + u2 + c) * (u1 - u2 + c) * (u1 + u2 - c) * (u1 + u2 + c), 0));
241 const double B = sqrt(std::max<double>((-a + b + c) * (a - b + c) * (a + b - c) * (a + b + c), 0));
242 const double sx = (c_sq + u1_sq - u2_sq) / (2 * c);
243 const double sy = -A / (2 * c);
244 const double p = (-a_sq + b_sq + c_sq) / (2 * c);
245 const double hc = B / (2 * c);
246 const double dy = hc - sy;
249 const double dx =
p - sx;
251 const double u3tmp_sq = dx * dx + dy * dy;
252 double u3tmp = sqrt(u3tmp_sq);
256 if (distances[v1] < distances[v2])
258 const double S = sy *
p - sx * hc;
259 const double t1cos = (u3tmp_sq + b_sq - u1_sq) / (2 * u3tmp * b);
260 if (S <= 0 && std::fabs(t1cos) <= 1)
262 const double theta = acos(t1cos);
264 direction[v3] =
static_cast<float>(theta);
265 distances[v3] =
static_cast<float>(u3tmp);
270 "dir_vec" + std::to_string(v3.
idx()));
281 distances[v3] = u3tmp;
286 "dir_vec" + std::to_string(v3.
idx()));
295 const double S = sx * hc - hc * c + sy * c - sy *
p;
296 const double t2cos = (a_sq + u3tmp_sq - u2_sq) / (2 * a * u3tmp);
297 if (S <= 0 && std::fabs(t2cos) <= 1)
300 const double theta = -acos(t2cos);
301 direction[v3] =
static_cast<float>(theta);
302 distances[v3] =
static_cast<float>(u3tmp);
307 "dir_vec" + std::to_string(v3.
idx()));
317 distances[v3] = u3tmp;
323 "dir_vec" + std::to_string(v3.
idx()));
341 const double u1 = distances[v1];
342 const double u2 = distances[v2];
343 const double u3 = distances[v3];
346 const double c = edge_weights[e12h.
unwrap()];
347 const double c_sq = c * c;
350 const double b = edge_weights[e13h.
unwrap()];
351 const double b_sq = b * b;
354 const double a = edge_weights[e23h.
unwrap()];
355 const double a_sq = a * a;
357 const double u1_sq = u1 * u1;
358 const double u2_sq = u2 * u2;
360 const double sx = (c_sq + u1_sq - u2_sq) / (2 * c);
361 const double sy = -sqrt(std::max(u1_sq - sx*sx, 0.0));
363 const double p = (b_sq + c_sq -a_sq) / (2 * c);
364 const double hc = sqrt(std::max(b_sq -
p*
p, 0.0));
366 const double dy = hc - sy;
367 const double dx =
p - sx;
369 const double u3tmp_sq = dx * dx + dy * dy;
370 double u3tmp = sqrt(u3tmp_sq);
372 if (!std::isfinite(u3tmp))
378 const double t0a = (a_sq + b_sq - c_sq) / (2 * a * b);
379 const double t1a = (u3tmp_sq + b_sq - u1_sq) / (2 * u3tmp * b);
380 const double t2a = (a_sq + u3tmp_sq - u2_sq) / (2 * a * u3tmp);
383 if (std::fabs(t1a) > 1)
388 auto fH =
mesh.getFaceBetween(v1, v2, v3).unwrap();
393 "dir_vec" + std::to_string(v3.
idx()));
395 distances[v3] =
static_cast<float>(u3tmp);
402 else if (std::fabs(t2a) > 1)
407 auto fH =
mesh.getFaceBetween(v1, v2, v3).unwrap();
412 "dir_vec" + std::to_string(v3.
idx()));
414 distances[v3] =
static_cast<float>(u3tmp);
421 const double theta0 = acos(t0a);
422 const double theta1 = acos(t1a);
423 const double theta2 = acos(t2a);
426 if (!std::isfinite(theta0 + theta1 + theta2))
429 if (std::isnan(theta0))
431 if (std::isnan(theta1))
433 if (std::isnan(theta2))
435 if (std::isinf(theta2))
437 if (std::isinf(theta2))
439 if (std::isinf(theta2))
445 if (std::fabs(t2a) > 1)
448 ROS_INFO_STREAM(
"a: " << a <<
", u3: " << u3tmp <<
", u2: " << u2 <<
", a+u2: " << a + u2);
450 if (std::fabs(t1a) > 1)
453 ROS_INFO_STREAM(
"b: " << b <<
", u3: " << u3tmp <<
", u1: " << u1 <<
", b+u1: " << b + u1);
458 if (theta1 < theta0 && theta2 < theta0)
460 auto fH =
mesh.getFaceBetween(v1, v2, v3).unwrap();
462 distances[v3] =
static_cast<float>(u3tmp);
469 "dir_vec" + std::to_string(v3.
idx()));
478 "dir_vec" + std::to_string(v3.
idx()));
483 else if (theta1 < theta2)
488 auto fH =
mesh.getFaceBetween(v1, v2, v3).unwrap();
491 distances[v3] =
static_cast<float>(u3tmp);
494 "dir_vec" + std::to_string(v3.
idx()));
506 auto fH =
mesh.getFaceBetween(v1, v2, v3).unwrap();
509 distances[v3] =
static_cast<float>(u3tmp);
512 "dir_vec" + std::to_string(v3.
idx()));
527 std::list<std::pair<mesh_map::Vector, lvr2::FaceHandle>>& path,
534 const auto& vertex_costs =
mesh_map->vertexCosts();
544 const auto& start_opt =
mesh_map->getContainingFace(
start, 0.4);
545 const auto& goal_opt =
mesh_map->getContainingFace(goal, 0.4);
553 return mbf_msgs::GetPathResult::INVALID_START;
555 return mbf_msgs::GetPathResult::INVALID_GOAL;
557 const auto& start_face = start_opt.unwrap();
558 const auto& goal_face = goal_opt.unwrap();
567 if (goal_face == start_face)
569 return mbf_msgs::GetPathResult::SUCCESS;
579 for (
auto const& vH :
mesh.vertices())
581 distances.
insert(vH, std::numeric_limits<float>::infinity());
588 for (
auto vH :
mesh.getVerticesOfFace(start_face))
591 const float dist = diff.
length();
592 distances[vH] = dist;
599 std::array<lvr2::VertexHandle, 3> goal_vertices =
mesh.getVerticesOfFace(goal_face);
600 ROS_DEBUG_STREAM(
"The goal is at (" << goal.
x <<
", " << goal.
y <<
", " << goal.
z <<
") at the face ("
601 << goal_vertices[0] <<
", " << goal_vertices[1] <<
", " << goal_vertices[2]
607 float goal_dist = std::numeric_limits<float>::infinity();
611 size_t fixed_cnt = 0;
612 size_t fixed_set_cnt = 0;
614 double initialization_duration = (t_wavefront_start - t_initialization_start).toNSec() * 1e-6;
620 fixed[current_vh] =
true;
623 if (distances[current_vh] > goal_dist)
626 if (vertex_costs[current_vh] >
config.cost_limit)
629 if (invalid[current_vh])
632 if (current_vh == goal_vertices[0] || current_vh == goal_vertices[1] || current_vh == goal_vertices[2])
634 if (goal_dist == std::numeric_limits<float>::infinity() && fixed[goal_vertices[0]] && fixed[goal_vertices[1]] &&
635 fixed[goal_vertices[2]])
644 std::vector<lvr2::FaceHandle> faces;
645 mesh.getFacesOfVertex(current_vh, faces);
647 for (
auto fh : faces)
649 const auto vertices =
mesh.getVerticesOfFace(fh);
654 if (invalid[a] || invalid[b] || invalid[c])
659 if (fixed[a] && fixed[b] && fixed[c])
668 else if (fixed[a] && fixed[b] && !fixed[c])
671 #ifdef USE_UPDATE_WITH_S
677 pq.
insert(c, distances[c]);
684 else if (fixed[a] && !fixed[b] && fixed[c])
687 #ifdef USE_UPDATE_WITH_S
693 pq.
insert(b, distances[b]);
700 else if (!fixed[a] && fixed[b] && fixed[c])
703 #ifdef USE_UPDATE_WITH_S
709 pq.
insert(a, distances[a]);
725 invalid.insert(current_vh,
true);
731 invalid.insert(current_vh,
true);
740 return mbf_msgs::GetPathResult::CANCELED;
743 double wavefront_propagation_duration = (t_wavefront_end - t_wavefront_start).toNSec() * 1e-6;
749 double vector_field_duration = (t_vector_field_end - t_wavefront_end).toNSec() * 1e-6;
751 bool path_exists =
false;
752 for (
auto goal_vertex : goal_vertices)
763 ROS_WARN(
"Predecessor of the goal is not set! No path found!");
764 return mbf_msgs::GetPathResult::NO_PATH_FOUND;
771 path.push_front(std::pair<mesh_map::Vector, lvr2::FaceHandle>(current_pos, current_face));
780 if (
mesh_map->meshAhead(current_pos, current_face,
config.step_width))
782 path.push_front(std::pair<mesh_map::Vector, lvr2::FaceHandle>(current_pos, current_face));
786 ROS_WARN_STREAM(
"Could not find a valid path, while back-tracking from the goal");
787 return mbf_msgs::GetPathResult::NO_PATH_FOUND;
792 ROS_ERROR_STREAM(
"Could not find a valid path, while back-tracking from the goal: HalfEdgeMesh panicked!");
793 return mbf_msgs::GetPathResult::NO_PATH_FOUND;
796 path.push_front(std::pair<mesh_map::Vector, lvr2::FaceHandle>(
start, start_face));
799 double path_backtracking_duration = (t_path_backtracking - t_vector_field_end).toNSec() * 1e-6;
801 ROS_INFO_STREAM(
"Processed " << fixed_set_cnt <<
" vertices in the fixed set.");
802 ROS_INFO_STREAM(
"Initialization duration (ms): " << initialization_duration);
803 ROS_INFO_STREAM(
"Execution time wavefront propagation (ms): "<< wavefront_propagation_duration);
804 ROS_INFO_STREAM(
"Vector field post computation (ms): " << vector_field_duration);
805 ROS_INFO_STREAM(
"Path backtracking duration (ms): " << path_backtracking_duration);
810 return mbf_msgs::GetPathResult::CANCELED;
814 return mbf_msgs::GetPathResult::SUCCESS;