13 #include "mf_sensors_simulator/MultiPoses.h" 14 #include "mf_mapping/UpdateGP.h" 15 #include <visualization_msgs/Marker.h> 16 #include <nav_msgs/Path.h> 17 #include <geometry_msgs/Quaternion.h> 18 #include <geometry_msgs/Pose.h> 19 #include <geometry_msgs/PoseStamped.h> 20 #include <tf2/LinearMath/Scalar.h> 21 #include <tf2_geometry_msgs/tf2_geometry_msgs.h> 22 #include <eigen3/Eigen/Dense> 28 using Eigen::Vector3f;
33 vector<mf_common::Float32Array> PlanningNodelet::vector2D_to_array(
34 const vector<vector<float>> &vector2D)
36 int n = vector2D.size();
37 vector<mf_common::Float32Array> out(n);
39 for (
int k = 0; k <
n; k++) {
40 out[k].data = vector2D[k];
47 vector<vector<float>> PlanningNodelet::array_to_vector2D(
48 const vector<mf_common::Float32Array> &array)
51 vector<vector<float>> out(n);
53 for (
int k = 0; k <
n; k++) {
54 out[k] = array[k].data;
61 vector<vector<float>> PlanningNodelet::array_to_vector2D(
62 const mf_common::Array2D &array)
64 int n = array.data.size();
65 vector<vector<float>> out(n);
67 for (
int k = 0; k <
n; k++) {
68 out[k] = array.data[k].data;
75 Eigen::Vector3f PlanningNodelet::get_wall_orientation(
float &yaw_wall)
77 double roll, pitch, yaw;
78 to_euler(ocean_robot_tf_.transform.rotation, roll, pitch, yaw);
80 yaw_wall = wall_orientation_;
82 while (fabs(yaw_wall - yaw) > M_PI_2) {
83 if (yaw_wall - yaw > M_PI_2)
89 return Eigen::Vector3f(cos(yaw_wall), sin(yaw_wall), 0.0);
93 Eigen::Vector3f PlanningNodelet::get_wall_orientation()
96 return get_wall_orientation(foo);
100 void PlanningNodelet::generate_cart_lattice(
float max_lat_angle,
float max_elev_angle,
101 float horizon,
float resolution,
Lattice &lattice)
103 int n_x = horizon / resolution;
104 int n_y = horizon * sin(max_lat_angle) / resolution;
105 int n_z = horizon * sin(max_elev_angle) / resolution;
106 unsigned int n_lattice = n_x * (2*n_y + 1) * (2*n_z + 1);
108 lattice.
nodes.clear();
109 lattice.
nodes.reserve(n_lattice);
112 for (
int i = 0; i < n_x; i++) {
114 float y = -n_y * resolution;
116 for (
int j = -n_y; j <= n_y; j++) {
117 float z = -n_z * resolution;
119 for (
int k = -n_z; k <= n_z; k++) {
121 float lat_angle = atan2(y, x);
122 float elev_angle = atan2(z, x);
124 if (abs(lat_angle) <= max_lat_angle && abs(elev_angle) <= max_elev_angle) {
125 geometry_msgs::Pose pose;
131 tf2::Quaternion q_orig, q_rot, q_new;
132 q_orig.setRPY(0, 0, 0);
133 q_rot.setRPY(0.0, -elev_angle, lat_angle);
135 q_new = q_rot * q_orig;
137 tf2::convert(q_new, pose.orientation);
140 lattice.
nodes.back()->pose = pose;
152 void PlanningNodelet::generate_lattice(
Lattice &lattice)
154 float duration = plan_horizon_/plan_speed_;
155 int n_horiz = 2*lattice_size_horiz_ + 1;
156 int n_vert = 2*lattice_size_vert_ + 1;
157 lattice.
nodes.clear();
158 lattice.
nodes.resize(n_horiz*n_vert);
161 for (
int k = -lattice_size_horiz_; k <= lattice_size_horiz_; k++) {
162 for (
int l = -lattice_size_vert_; l <= lattice_size_vert_; l++) {
164 float prop_speed = robot_model_.steady_propeller_speed(plan_speed_);
165 float vert_angle = max_elev_rudder_ * l / max(lattice_size_vert_, 1);
166 float ref_horiz_angle = max_lat_rudder_ * k / max(lattice_size_horiz_, 1);
170 for (
int cnt = 0; cnt < N; cnt++) {
171 float t = float(cnt) / N;
172 float current_horiz_angle = ref_horiz_angle*(-2*pow(t, 3) + 4*pow(t,2) - 1);
175 robot_model_.integrate(state, input, 0.0, duration/N, duration/N/10);
179 geometry_msgs::Pose pose, lattice_pose;
180 pose.position.x = state[0];
181 pose.position.y = state[1];
182 pose.position.z = state[2];
184 float wall_orientation = wall_orientation_;
186 while (fabs(wall_orientation - state[5]) > M_PI_2) {
187 if (wall_orientation - state[5] > M_PI_2)
188 wall_orientation -= M_PI;
190 wall_orientation += M_PI;
193 to_quaternion(state[3], state[4], wall_orientation, pose.orientation);
195 tf2::doTransform(pose, lattice_pose, robot_ocean_tf_);
198 lattice.
nodes[counter]->pose = lattice_pose;
205 void PlanningNodelet::generate_lattices(
207 std::vector<Lattice> &lattices)
211 Eigen::Vector3f orientation_wall = get_wall_orientation(yaw_wall);
212 geometry_msgs::Quaternion quati;
215 geometry_msgs::Quaternion orientation_vp;
216 tf2::doTransform(quati, orientation_vp, wall_ocean_tf_);
219 geometry_msgs::Point p_ocean, p_wall;
220 p_ocean.x = init_state[0];
221 p_ocean.y = init_state[1];
222 p_ocean.z = init_state[2];
223 tf2::doTransform(p_ocean, p_wall, wall_ocean_tf_);
225 bool backwards = (p_wall.z < 0);
228 int nbr_lattices = lattices.size();
229 int nbr_nodes = lattice_size_vert_*lattice_size_horiz_;
231 float dy = plan_horizon_;
234 float dx = fabs(bnd_depth_[1] - bnd_depth_[0] - 2*margin) / (lattice_size_vert_-1);
235 float dz = fabs(bnd_wall_dist_[1] - bnd_wall_dist_[0] - 2*margin) / (lattice_size_horiz_-1);
242 for (
int k = 0; k < nbr_lattices; k++) {
243 lattices[k].nodes.clear();
244 lattices[k].nodes.reserve(nbr_nodes);
246 float x = bnd_depth_[0] + margin/(lattice_size_vert_-1);
248 for (
int l = 0; l < lattice_size_vert_; l++) {
249 float z = bnd_wall_dist_[0] + margin/(lattice_size_horiz_-1);
254 for (
int m = 0; m < lattice_size_horiz_; m++) {
256 shared_ptr<LatticeNode> new_node (
new LatticeNode());
257 new_node->pose.position.x = x;
258 new_node->pose.position.y = y;
259 new_node->pose.position.z = z;
260 new_node->pose.orientation = orientation_vp;
262 lattices[k].nodes.emplace_back(std::move(new_node));
272 for (
int k = 0; k < nbr_lattices; k++) {
273 for (
int l = 0; l < nbr_nodes; l++) {
274 geometry_msgs::Pose pose_tmp;
275 tf2::doTransform(lattices[k].nodes[l]->pose, pose_tmp, robot_wall_tf_);
276 lattices[k].nodes[l]->pose = pose_tmp;
284 lattice_out.
nodes.reserve(lattice_in.
nodes.size());
286 for (
int k = 0; k < lattice_in.
nodes.size(); k++) {
287 bool position_ok =
false;
288 bool pitch_ok =
false;
289 bool orientation_ok =
false;
292 geometry_msgs::Pose vp1;
293 geometry_msgs::Pose vp2;
294 tf2::doTransform(lattice_in.
nodes[k]->pose, vp1, wall_robot_tf_);
295 tf2::doTransform(lattice_in.
nodes[k]->pose, vp2, ocean_robot_tf_);
298 if (fabs(vp1.position.z) >= bnd_wall_dist_[0] && fabs(vp1.position.z) <= bnd_wall_dist_[1]
299 && vp1.position.x >= bnd_depth_[0] && vp1.position.x <= bnd_depth_[1]) {
303 if (vp1.position.z * wall_robot_tf_.transform.translation.z < 0.0)
307 double roll, pitch, yaw;
308 to_euler(vp2.orientation, roll, pitch, yaw);
310 if (abs(pitch) <= bnd_pitch_)
314 Eigen::Vector3f orientation_vp;
316 Eigen::Vector3f orientation_wall = get_wall_orientation();
318 if (orientation_vp.dot(orientation_wall) >= 0.0)
319 orientation_ok =
true;
322 if (position_ok && pitch_ok && orientation_ok) {
323 lattice_out.
nodes.emplace_back(std::move(lattice_in.
nodes[k]));
329 void PlanningNodelet::transform_lattices(
330 std::vector<Lattice> &lattices,
331 const geometry_msgs::TransformStamped &transform)
333 for (
int k = 0; k < lattices.size(); k++) {
334 for (
int l = 0; l < lattices[k].nodes.size(); l++) {
335 geometry_msgs::Pose tmp;
336 tf2::doTransform(lattices[k].nodes[l]->pose, tmp, transform);
337 lattices[k].nodes[l]->pose = tmp;
343 void PlanningNodelet::add_node(
345 const geometry_msgs::TransformStamped &frame_ocean_tf,
348 geometry_msgs::Pose p_ocean, p_frame;
349 p_ocean.position.x = state[0];
350 p_ocean.position.y = state[1];
351 p_ocean.position.z = state[2];
352 to_quaternion(state[3], state[4], state[5], p_ocean.orientation);
353 tf2::doTransform(p_ocean, p_frame, frame_ocean_tf);
355 shared_ptr<LatticeNode> new_node (
new LatticeNode());
356 new_node->pose = p_frame;
357 new_node->speed = state[6];
358 lattice.
nodes.emplace_back(std::move(new_node));
362 void PlanningNodelet::connect_lattices(
364 std::vector<Lattice> &lattices_in,
365 std::vector<Lattice> &lattices_out)
368 int nbr_lattices = lattices_in.size();
369 transform_lattices(lattices_in, wall_robot_tf_);
373 add_node(init_state, wall_ocean_tf_, initial_lattice);
376 for (
int k = 0; k < nbr_lattices; k++)
378 Lattice* next_lattice = &(lattices_in[k]);
381 prev_lattice = &initial_lattice;
383 prev_lattice = &(lattices_out[k-1]);
385 vector<bool> reached(next_lattice->
nodes.size(),
false);
389 Eigen::Vector3f wall_orientation = get_wall_orientation(wall_yaw);
390 vector<int> lat_mult = {-1, -1, 1, 1};
391 vector<int> elev_mult = {-1, 1, -1, 1};
392 float prop_speed = robot_model_.steady_propeller_speed(plan_speed_);
394 for (
int l = 0; l < prev_lattice->
nodes.size(); l++ )
397 geometry_msgs::Pose pose_ocean;
398 tf2::doTransform(prev_lattice->
nodes[l]->pose, pose_ocean, ocean_wall_tf_);
402 init_state[6] = prev_lattice->
nodes[l]->speed;
405 vector<geometry_msgs::Pose> propag_poses(4);
406 float propag_speed = 1000;
408 for (
int m = 0; m < 4; m++) {
410 Eigen::Vector3f origin; origin << state[0], state[1], state[2];
411 Eigen::Vector3f current_pos;
413 float elev_angle = max_elev_rudder_ * elev_mult[m];
414 float lat_angle = max_lat_rudder_ * lat_mult[m];
416 float duration = (plan_horizon_ / plan_speed_) / 5;
420 float max_distance = 0.0;
425 robot_model_.integrate(state, input, 0.0, duration, duration/5);
426 current_pos << state[0], state[1], state[2];
427 distance = wall_orientation.dot(current_pos - origin);
429 if (distance > max_distance ) {
430 best_pos = current_pos;
433 }
while (distance < plan_horizon_ && safe_cnt++ < 20);
436 pose_ocean.position.x = best_pos(0);
437 pose_ocean.position.y = best_pos(1);
438 pose_ocean.position.z = best_pos(2);
441 tf2::doTransform(pose_ocean, propag_poses[m], wall_ocean_tf_);
443 if (state[6] < propag_speed)
444 propag_speed = state[6];
448 vector<float> x_values(4), z_values(4);
449 for (
int m = 0; m < 4; m++) {
450 x_values[m] = propag_poses[m].position.x;
451 z_values[m] = propag_poses[m].position.z;
454 float min_x = *(std::min_element(x_values.begin(), x_values.end()));
455 float max_x = *(std::max_element(x_values.begin(), x_values.end()));
456 float min_z = *(std::min_element(z_values.begin(), z_values.end()));
457 float max_z = *(std::max_element(z_values.begin(), z_values.end()));
460 for (
int m = 0; m < next_lattice->
nodes.size(); m++) {
461 geometry_msgs::Point node_pos = next_lattice->
nodes[m]->pose.position;
463 if (node_pos.x >= min_x && node_pos.x <= max_x && node_pos.z >= min_z && node_pos.z <= max_z) {
464 prev_lattice->
nodes[l]->next.emplace_back(next_lattice->
nodes[m]);
466 next_lattice->
nodes[m]->speed = propag_speed;
472 for (
int l = 0; l < next_lattice->
nodes.size(); l++) {
474 lattices_out[k].nodes.emplace_back(lattices_in[k].nodes[l]);
480 transform_lattices(lattices_out, robot_wall_tf_);
487 bool PlanningNodelet::compute_lattice_gp(
Lattice &lattice, ros::Time stamp)
490 int size_lattice = lattice.
nodes.size();
491 vector<geometry_msgs::Pose> poses(size_lattice);
493 for (
int k = 0; k < size_lattice; k++) {
494 tf2::Quaternion q_orig, q_rot, q_new;
495 tf2::convert(lattice.
nodes[k]->pose.orientation, q_orig);
496 q_rot.setRPY(M_PI_2, 0.0, 0.0);
498 q_new = q_orig * q_rot;
500 tf2::convert(q_new, poses[k].orientation);
502 poses[k].position = lattice.
nodes[k]->pose.position;
506 geometry_msgs::TransformStamped camera_robot_tf;
509 camera_robot_tf = tf_buffer_.lookupTransform(camera_frame_, robot_frame_, stamp);
511 catch (tf2::TransformException &ex) {
512 NODELET_WARN(
"[planning_nodelet] %s", ex.what());
516 for (
int k = 0; k < size_lattice; k++) {
517 geometry_msgs::Pose transf_pose;
518 tf2::doTransform(poses[k], transf_pose, camera_robot_tf);
520 poses[k] = transf_pose;
524 mf_sensors_simulator::MultiPoses camera_srv;
525 camera_srv.request.stamp = stamp;
526 camera_srv.request.pose_array.header.frame_id = robot_frame_;
527 camera_srv.request.pose_array.poses = poses;
528 camera_srv.request.n_pxl_height = camera_height_;
529 camera_srv.request.n_pxl_width = camera_width_;
531 if (ray_multi_client_.call(camera_srv)) {
532 if (!camera_srv.response.is_success) {
533 NODELET_WARN(
"[planning_nodelet] Call to raycast_multi service didn't give output ");
537 NODELET_WARN(
"[planning_nodelet] Failed to call raycast_multi service");
542 for (
int k = 0; k < size_lattice; k++) {
543 lattice.
nodes[k]->camera_pts_x = camera_srv.response.results[k].x;
544 lattice.
nodes[k]->camera_pts_y = camera_srv.response.results[k].y;
545 lattice.
nodes[k]->camera_pts_z = camera_srv.response.results[k].z;
549 mf_mapping::UpdateGP gp_srv;
550 gp_srv.request.stamp = stamp;
551 gp_srv.request.use_internal_mean =
true;
552 gp_srv.request.use_internal_cov =
true;
553 gp_srv.request.update_mean =
false;
554 gp_srv.request.return_cov_diag =
true;
555 gp_srv.request.eval_gp =
false;
557 gp_srv.request.meas.resize(size_lattice);
558 for (
int k = 0; k < size_lattice; k++) {
559 gp_srv.request.meas[k] = camera_srv.response.results[k];
562 if (update_gp_client_.call(gp_srv)) {
563 for (
int k = 0; k < size_lattice; k++) {
564 lattice.
nodes[k]->gp_cov = gp_srv.response.new_cov_diag[k].data;
567 NODELET_WARN(
"[planning_nodelet] Failed to call update_gp service");
575 void PlanningNodelet::compute_info_gain(
Lattice &lattice)
577 int size_gp = last_gp_mean_.size();
579 for (
int k = 0; k < lattice.
nodes.size(); k++) {
580 lattice.
nodes[k]->info_gain = 0.0;
582 for (
int l = 0; l < size_gp; l++) {
583 float cov_diff = last_gp_cov_[l][l] - lattice.
nodes[k]->gp_cov[l];
586 if (last_gp_mean_[l] > gp_threshold_)
589 lattice.
nodes[k]->info_gain += weight * cov_diff;
595 std::vector<LatticeNode*> PlanningNodelet::select_viewpoints(
const std::vector<Lattice> &lattices)
597 float best_info_gain = 0.0;
598 vector<LatticeNode*> selected_vp;
600 for (
int k = 0; k < lattices[0].nodes.size(); k++) {
602 vector<LatticeNode*> vp;
604 select_viewpoints(lattices[0].nodes[k].
get(), info_gain, vp);
606 if (info_gain > best_info_gain) {
608 best_info_gain = info_gain;
616 void PlanningNodelet::select_viewpoints(
619 std::vector<LatticeNode*> &selected_vp)
622 if (node->
next.size() == 0) {
624 selected_vp.resize(1);
625 selected_vp[0] = node;
631 float best_info_gain = 0.0;
633 for (
int k = 0; k < node->
next.size(); k++) {
635 vector<LatticeNode*> vp;
637 select_viewpoints(node->
next[k].get(), info_gain, vp);
639 if (info_gain > best_info_gain) {
641 best_info_gain = info_gain;
646 info_gain = best_info_gain + node->
info_gain;
647 selected_vp.insert(selected_vp.begin(), node);
651 void PlanningNodelet::fill_display_obj(
652 const std::vector<Lattice> &lattices,
653 const std::vector<LatticeNode*> &selected_vp)
656 selected_vp_.resize(nbr_lattices_);
657 x_hit_pt_sel_.resize(0);
658 y_hit_pt_sel_.resize(0);
659 z_hit_pt_sel_.resize(0);
661 for (
int k = 0; k < nbr_lattices_; k++) {
663 geometry_msgs::Pose pose;
664 tf2::doTransform(selected_vp[k]->pose, pose, ocean_robot_tf_);
665 selected_vp_[k] = pose;
668 x_hit_pt_sel_.insert(x_hit_pt_sel_.end(), selected_vp[k]->camera_pts_x.begin(), selected_vp[k]->camera_pts_x.end());
669 y_hit_pt_sel_.insert(y_hit_pt_sel_.end(), selected_vp[k]->camera_pts_y.begin(), selected_vp[k]->camera_pts_y.end());
670 z_hit_pt_sel_.insert(z_hit_pt_sel_.end(), selected_vp[k]->camera_pts_z.begin(), selected_vp[k]->camera_pts_z.end());
673 for (
int k = 0; k < x_hit_pt_sel_.size(); k++) {
675 geometry_msgs::Point pose, tmp;
676 pose.x = x_hit_pt_sel_[k];
677 pose.y = y_hit_pt_sel_[k];
678 pose.z = z_hit_pt_sel_[k];
680 tf2::doTransform(pose, tmp, ocean_camera_tf_);
682 x_hit_pt_sel_[k] = tmp.x;
683 y_hit_pt_sel_[k] = tmp.y;
684 z_hit_pt_sel_[k] = tmp.z;
690 for (
int k = 0; k < nbr_lattices_; k++) {
691 for (
int l = 0; l < lattices[k].nodes.size(); l++) {
692 if (lattices[k].nodes[l].
get() != selected_vp[k]) {
693 geometry_msgs::Pose pose;
694 tf2::doTransform(lattices[k].nodes[l]->pose, pose, ocean_robot_tf_);
695 lattice_.emplace_back(pose);
702 void PlanningNodelet::generate_path(
703 const std::vector<geometry_msgs::Pose> &selected_vp,
704 nav_msgs::Path &path,
705 std::vector<geometry_msgs::Pose> &waypoints)
707 path.poses.resize(0);
710 if (waypoints_.size() == 0 | replan_)
711 waypoints[0] = tf_to_pose(ocean_robot_tf_);
713 waypoints[0] = waypoints_.back();
715 waypoints.insert(waypoints.end(), selected_vp_.begin(), selected_vp_.end());
718 for (
int k = 0; k < nbr_lattices_; k++) {
719 nav_msgs::Path intermed_path = straight_line_path(waypoints[k], waypoints[k+1], path_res_);
722 path.poses = intermed_path.poses;
724 path.poses.insert(path.poses.end(), intermed_path.poses.begin()+1, intermed_path.poses.end());
727 path = spline_path(waypoints, path_res_, plan_speed_);
732 nav_msgs::Path PlanningNodelet::straight_line_path(
const geometry_msgs::Pose &start,
733 const geometry_msgs::Pose &end,
float resolution)
737 tf2::convert(start.position, p1);
738 tf2::convert(end.position, p2);
740 tf2::Quaternion q1, q2;
741 tf2::convert(start.orientation, q1);
742 tf2::convert(end.orientation, q2);
746 float d = tf2::tf2Distance(p1, p2);
747 int n = d/resolution;
749 path.header.frame_id = ocean_frame_;
750 path.header.stamp = ros::Time::now();
751 path.poses.resize(n + 1);
754 for (
int k = 0; k <=
n; k++) {
755 geometry_msgs::PoseStamped new_pose;
756 tf2::toMsg( p1 + (p2-p1) * (
float(k)/n), new_pose.pose.position);
757 tf2::convert((q1 + (q2-q1) * (
float(k)/n)).normalize(), new_pose.pose.orientation);
759 path.poses[k] = new_pose;
766 nav_msgs::Path PlanningNodelet::spline_path(
767 const std::vector<geometry_msgs::Pose> &waypoints,
771 int n = waypoints.size();
772 vector<Eigen::Vector3f> p(n);
773 vector<Eigen::Vector3f> o(n);
775 for (
int k = 0; k <
n; k++) {
776 p[k] << waypoints[k].position.x, waypoints[k].position.y, waypoints[k].position.z;
778 double roll, pitch, yaw;
779 to_euler(waypoints[k].orientation, roll, pitch, yaw);
780 o[k] << cos(yaw), sin(yaw), sin(pitch);
783 Spline spline(p, o, speed);
786 path.poses.resize(0);
787 path.header.frame_id = ocean_frame_;
788 bool last_reached =
false;
791 while (!last_reached) {
795 spline.
evaluate(t, p, o, last_reached);
798 geometry_msgs::PoseStamped pose;
799 pose.pose.position.x = p(0);
800 pose.pose.position.y = p(1);
801 pose.pose.position.z = p(2);
802 to_quaternion(0.0, -asin(o(2)), atan2(o(1), o(0)), pose.pose.orientation);
804 path.poses.emplace_back(pose);
805 t += resolution /
speed;
812 bool PlanningNodelet::plan_trajectory()
815 int size_gp = last_gp_cov_.size();
817 if (last_gp_cov_.size() == 0 || last_gp_mean_.size() == 0)
821 vector<Lattice> lattices_tmp(nbr_lattices_);
827 if (waypoints_.size() == 0 || replan_) {
830 state =
to_state(waypoints_.back(), state_.size());
833 generate_lattices(state, lattices_tmp);
835 else if (cart_lattice_)
837 float lat_turn_radius = robot_model_.lat_turn_radius(plan_speed_, max_lat_rudder_);
838 float elev_turn_radius = robot_model_.elev_turn_radius(plan_speed_, max_lat_rudder_);
840 float max_lat_angle = plan_horizon_ / (2 * lat_turn_radius);
841 float max_elev_angle = plan_horizon_ / (2 * elev_turn_radius);
843 if (!horiz_motion_) max_lat_angle = 0;
844 if (!vert_motion_) max_elev_angle = 0;
846 generate_cart_lattice(max_lat_angle, max_elev_angle, plan_horizon_, lattice_res_, lattices_tmp[0]);
850 generate_lattice(lattices_tmp[0]);
854 vector<Lattice> lattices_tmp2(nbr_lattices_);
856 for (
int k = 0; k < nbr_lattices_; k++) {
857 filter_lattice(lattices_tmp[k], lattices_tmp2[k]);
861 vector<Lattice> lattices(nbr_lattices_);
862 connect_lattices(state_, lattices_tmp2, lattices);
864 for (
int k = 0; k < nbr_lattices_; k++) {
865 if (lattices[k].nodes.size() == 0) {
866 NODELET_WARN(
"[planning_nodelet] Lattice %d is empty", k);
872 ros::Time stamp = ocean_robot_tf_.header.stamp;
874 for (
int k = 0; k < nbr_lattices_; k++) {
875 bool ret = compute_lattice_gp(lattices[k], stamp);
878 NODELET_WARN(
"[planning_nodelet] Error when computing GP covariance ");
884 for (
int k = 0; k < nbr_lattices_; k++) {
885 compute_info_gain(lattices[k]);
888 vector<LatticeNode*> selected_vp = select_viewpoints(lattices);
890 if (selected_vp.size() != nbr_lattices_) {
891 NODELET_WARN(
"[planning_nodelet] Not the right number of selected viewpoints (%d against %d)",
892 (
int)selected_vp.size(), (int)nbr_lattices_
898 fill_display_obj(lattices, selected_vp);
901 nav_msgs::Path new_path;
902 vector<geometry_msgs::Pose> waypoints;
903 generate_path(selected_vp_, new_path, waypoints);
905 if (new_path.poses.size() <= 1) {
906 NODELET_WARN(
"[planning_nodelet] Computed path to small (size: %d)", (
int)new_path.poses.size());
911 path_.header.stamp = ros::Time::now();
914 path_.poses = new_path.poses;
915 waypoints_ = waypoints;
918 if (path_.poses.size() == 0) {
919 path_.poses.emplace_back(new_path.poses[0]);
920 waypoints_.emplace_back(waypoints[0]);
923 path_.poses.insert(path_.poses.end(), new_path.poses.begin()+1, new_path.poses.end());
924 waypoints_.insert(waypoints_.end(), waypoints.begin()+1, waypoints.end());
float info_gain
Information gain fo this viewpoint.
std::vector< std::shared_ptr< LatticeNode > > nodes
Nodes of the lattice.
Class to represent a lattice.
void evaluate(float t, Eigen::Vector3f &position, Eigen::Vector3f &orientation, bool &last_reached)
Evaluates the spline at a specific time instant (assuming constant speed)
void to_quaternion(double roll, double pitch, double yaw, tf2::Quaternion &quat)
Converts Roll-Pitch-Yaw Euler angles to a quaternion.
std::vector< double > state_type
Data type of the state.
Declaration of common functions.
Declaration of a class for 3D spline interpolation.
std::vector< std::shared_ptr< LatticeNode > > next
Nodes in the next lattice that can be reached from this node.
float distance(const geometry_msgs::Point &p1, const geometry_msgs::Point &p2)
Computes the the euclidean distance between two positions.
std::vector< double > input_type
Data type of the input.
RobotModel::state_type to_state(const geometry_msgs::Pose &pose, int state_size)
Converts a pose into a state message.
Declaration of a nodelet for path plannning of an underwater robot surveying a marine farm...
Declaration of useful classes for planning with lattices.
void get_orientation(float roll, float pitch, float yaw, VectorT &orientation)
Get orientation vector (x vector of the frame) given by Roll-Pitch-Yaw.
Class to represent a node (viewpoint) of a lattice.
Class for spline interpolation.
void to_euler(const tf2::Quaternion &quat, double &roll, double &pitch, double &yaw)
Converts a quaternion to Roll-Pitch-Yaw Euler angles.