42 #include <boost/chrono.hpp> 43 #include <boost/shared_ptr.hpp> 47 #include <sensor_msgs/PointCloud2.h> 49 #include <nav_msgs/Odometry.h> 50 #include <sensor_msgs/Imu.h> 51 #include <geometry_msgs/PoseArray.h> 52 #include <geometry_msgs/PoseWithCovarianceStamped.h> 53 #include <geometry_msgs/TransformStamped.h> 54 #include <visualization_msgs/MarkerArray.h> 55 #include <mcl_3dl_msgs/ResizeParticle.h> 56 #include <mcl_3dl_msgs/Status.h> 57 #include <std_srvs/Trigger.h> 66 #include <pcl/point_types.h> 69 #include <pcl/conversions.h> 70 #include <pcl/filters/voxel_grid.h> 71 #include <pcl/kdtree/kdtree.h> 72 #include <pcl/kdtree/kdtree_flann.h> 108 std::shared_ptr<pf::ParticleFilter<State6DOF, float, ParticleWeightedMeanQuat, std::default_random_engine>>
pf_;
112 using pcl::PointRepresentation<PointType>::nr_dimensions_;
127 void cbMapcloud(
const sensor_msgs::PointCloud2::ConstPtr& msg)
130 pcl::PointCloud<PointType>::Ptr pc_tmp(
new pcl::PointCloud<PointType>);
139 pc_map_.reset(
new pcl::PointCloud<PointType>);
143 ds.setInputCloud(pc_tmp);
152 ROS_INFO(
"map original: %d points", (
int)pc_tmp->points.size());
160 pcl::PointCloud<PointType>::Ptr pc_tmp(
new pcl::PointCloud<PointType>);
164 pc_update_.reset(
new pcl::PointCloud<PointType>);
166 ds.setInputCloud(pc_tmp);
171 void cbPosition(
const geometry_msgs::PoseWithCovarianceStamped::ConstPtr& msg)
174 msg->pose.pose.orientation.x * msg->pose.pose.orientation.x +
175 msg->pose.pose.orientation.y * msg->pose.pose.orientation.y +
176 msg->pose.pose.orientation.z * msg->pose.pose.orientation.z +
177 msg->pose.pose.orientation.w * msg->pose.pose.orientation.w;
178 if (std::abs(len2 - 1.0) > 0.1)
180 ROS_ERROR(
"Discarded invalid initialpose. The orientation must be unit quaternion.");
184 geometry_msgs::PoseStamped pose_in, pose;
185 pose_in.header = msg->header;
186 pose_in.pose = msg->pose.pose;
197 const State6DOF mean(
Vec3(pose.pose.position.x, pose.pose.position.y, pose.pose.position.z),
198 Quat(pose.pose.orientation.x,
199 pose.pose.orientation.y,
200 pose.pose.orientation.z,
201 pose.pose.orientation.w));
203 pf_->initUsingNoiseGenerator(noise_gen);
208 s.odom_err_integ_lin_ =
Vec3();
209 s.odom_err_integ_ang_ =
Vec3();
211 pf_->predict(integ_reset_func);
216 void cbOdom(
const nav_msgs::Odometry::ConstPtr& msg)
220 Vec3(msg->pose.pose.position.x,
221 msg->pose.pose.position.y,
222 msg->pose.pose.position.z),
223 Quat(msg->pose.pose.orientation.x,
224 msg->pose.pose.orientation.y,
225 msg->pose.pose.orientation.z,
226 msg->pose.pose.orientation.w));
234 const float dt = (msg->header.stamp -
odom_last_).toSec();
235 if (dt < 0.0 || dt > 5.0)
237 ROS_WARN(
"Detected time jump in odometry. Resetting.");
248 pf_->predict(prediction_func);
255 sensor_msgs::Imu::Ptr imu(
new sensor_msgs::Imu);
256 imu->header = msg->header;
257 imu->linear_acceleration.x = accel.
x_;
258 imu->linear_acceleration.y = accel.
y_;
259 imu->linear_acceleration.z = accel.
z_;
260 imu->orientation = msg->pose.pose.orientation;
264 void cbCloud(
const sensor_msgs::PointCloud2::ConstPtr& msg)
266 status_ = mcl_3dl_msgs::Status();
268 status_.status = mcl_3dl_msgs::Status::NORMAL;
269 status_.error = mcl_3dl_msgs::Status::ERROR_NORMAL;
270 status_.convergence_status = mcl_3dl_msgs::Status::CONVERGENCE_STATUS_NORMAL;
276 msg->header.frame_id,
290 bool accumCloud(
const sensor_msgs::PointCloud2::ConstPtr& msg)
292 sensor_msgs::PointCloud2 pc_bl;
301 ROS_INFO(
"Failed to transform pointcloud: %s", e.what());
304 pcl::PointCloud<PointType>::Ptr pc_tmp(
new pcl::PointCloud<PointType>);
307 ROS_INFO(
"Failed to convert pointcloud");
311 for (
auto& p : pc_tmp->points)
330 ROS_ERROR(
"MCL measure function is called without available pointcloud");
342 const Eigen::Affine3f trans_eigen =
343 Eigen::Translation3f(
344 trans.transform.translation.x,
345 trans.transform.translation.y,
346 trans.transform.translation.z) *
348 trans.transform.rotation.w,
349 trans.transform.rotation.x,
350 trans.transform.rotation.y,
351 trans.transform.rotation.z);
356 ROS_INFO(
"Failed to transform pointcloud: %s", e.what());
359 std::vector<Vec3> origins;
366 origins.push_back(
Vec3(trans.transform.translation.x,
367 trans.transform.translation.y,
368 trans.transform.translation.z));
372 ROS_INFO(
"Failed to transform pointcloud: %s", e.what());
377 const auto ts = boost::chrono::high_resolution_clock::now();
379 pcl::PointCloud<PointType>::Ptr pc_local_full(
new pcl::PointCloud<PointType>);
383 ds.
filter(*pc_local_full);
385 std::map<std::string, pcl::PointCloud<PointType>::Ptr> pc_locals;
388 lm.second->setGlobalLocalizationStatus(
393 const State6DOF prev_mean = pf_->expectation();
394 const float cov_ratio = std::max(0.1
f, static_cast<float>(
params_.
num_particles_) / pf_->getParticleSize());
395 const std::vector<State6DOF> prev_cov = pf_->covariance(1.0, cov_ratio);
399 pc_locals[lm.first] = lm.second->filter(pc_local_full);
402 if (pc_locals[
"likelihood"]->size() == 0)
404 ROS_ERROR(
"All points are filtered out. Failed to localize.");
405 status_.error = mcl_3dl_msgs::Status::ERROR_POINTS_NOT_FOUND;
410 if (pc_locals[
"beam"] && pc_locals[
"beam"]->size() == 0)
412 ROS_DEBUG(
"All beam points are filtered out. Skipping beam model.");
415 float match_ratio_min = 1.0;
416 float match_ratio_max = 0.0;
419 auto measure_func = [
this, &pc_locals,
422 &match_ratio_min, &match_ratio_max](
const State6DOF&
s) ->
float 424 float likelihood = 1;
425 std::map<std::string, float> qualities;
426 for (
auto& lm : lidar_measurements_)
429 kdtree_, pc_locals[lm.first], origins,
s);
431 qualities[lm.first] = result.
quality;
433 if (match_ratio_min > qualities[
"likelihood"])
434 match_ratio_min = qualities[
"likelihood"];
435 if (match_ratio_max < qualities[
"likelihood"])
436 match_ratio_max = qualities[
"likelihood"];
439 const float odom_error =
440 odom_error_lin_nd(
s.odom_err_integ_lin_.norm());
441 return likelihood * odom_error;
443 pf_->measure(measure_func);
447 auto bias_func = [](
const State6DOF&
s,
float& p_bias) ->
void 451 pf_->bias(bias_func);
457 auto bias_func = [
this, &nl_lin, &nl_ang](
const State6DOF&
s,
float& p_bias) ->
void 463 p_bias = nl_lin(lin_diff) * nl_ang(ang_diff) + 1e-6;
464 assert(std::isfinite(p_bias));
466 pf_->bias(bias_func);
468 auto e = pf_->expectationBiased();
469 const auto e_max = pf_->max();
471 assert(std::isfinite(e.pos_.x_));
472 assert(std::isfinite(e.pos_.y_));
473 assert(std::isfinite(e.pos_.z_));
474 assert(std::isfinite(e.rot_.x_));
475 assert(std::isfinite(e.rot_.y_));
476 assert(std::isfinite(e.rot_.z_));
477 assert(std::isfinite(e.rot_.w_));
481 if (lidar_measurements_[
"beam"])
483 visualization_msgs::MarkerArray markers;
485 pcl::PointCloud<PointType>::Ptr pc_particle_beam(
new pcl::PointCloud<PointType>);
486 *pc_particle_beam = *pc_locals[
"beam"];
487 e.transform(*pc_particle_beam);
489 for (
auto& p : pc_particle_beam->points)
491 const int beam_header_id = p.label;
492 const Vec3 pos = e.pos_ + e.rot_ * origins[beam_header_id];
493 const Vec3 end(p.x, p.y, p.z);
499 visualization_msgs::Marker marker;
501 marker.header.stamp = header.stamp;
502 marker.ns =
"Ray collisions";
503 marker.id = markers.markers.size();
504 marker.type = visualization_msgs::Marker::CUBE;
506 marker.pose.position.x = point.
pos_.
x_;
507 marker.pose.position.y = point.
pos_.
y_;
508 marker.pose.position.z = point.
pos_.
z_;
509 marker.pose.orientation.x = 0.0;
510 marker.pose.orientation.y = 0.0;
511 marker.pose.orientation.z = 0.0;
512 marker.pose.orientation.w = 1.0;
513 marker.scale.x = marker.scale.y = marker.scale.z = 0.2;
515 marker.frame_locked =
true;
519 marker.color.a = 0.8;
520 marker.color.r = 0.0;
521 marker.color.g = 1.0;
522 marker.color.b = 0.0;
525 marker.color.a = 0.8;
526 marker.color.r = 1.0;
527 marker.color.g = 0.0;
528 marker.color.b = 0.0;
531 marker.color.a = 0.2;
532 marker.color.r = 0.0;
533 marker.color.g = 1.0;
534 marker.color.b = 0.0;
539 markers.markers.push_back(marker);
542 visualization_msgs::Marker marker;
544 marker.header.stamp = header.stamp;
546 marker.id = markers.markers.size();
547 marker.type = visualization_msgs::Marker::LINE_STRIP;
549 marker.pose.position.x = 0.0;
550 marker.pose.position.y = 0.0;
551 marker.pose.position.z = 0.0;
552 marker.pose.orientation.x = 0.0;
553 marker.pose.orientation.y = 0.0;
554 marker.pose.orientation.z = 0.0;
555 marker.pose.orientation.w = 1.0;
556 marker.scale.x = marker.scale.y = marker.scale.z = 0.04;
558 marker.frame_locked =
true;
559 marker.points.resize(2);
560 marker.points[0].x = pos.
x_;
561 marker.points[0].y = pos.
y_;
562 marker.points[0].z = pos.
z_;
563 marker.points[1].x = end.
x_;
564 marker.points[1].y = end.
y_;
565 marker.points[1].z = end.
z_;
566 marker.colors.resize(2);
571 marker.colors[0].a = 0.5;
572 marker.colors[0].r = 0.0;
573 marker.colors[0].g = 1.0;
574 marker.colors[0].b = 0.0;
575 marker.colors[1].a = 0.8;
576 marker.colors[1].r = 0.0;
577 marker.colors[1].g = 1.0;
578 marker.colors[1].b = 0.0;
581 marker.colors[0].a = 0.5;
582 marker.colors[0].r = 1.0;
583 marker.colors[0].g = 0.0;
584 marker.colors[0].b = 0.0;
585 marker.colors[1].a = 0.8;
586 marker.colors[1].r = 1.0;
587 marker.colors[1].g = 0.0;
588 marker.colors[1].b = 0.0;
591 marker.colors[0].a = 0.5;
592 marker.colors[0].r = 0.0;
593 marker.colors[0].g = 0.0;
594 marker.colors[0].b = 1.0;
595 marker.colors[1].a = 0.8;
596 marker.colors[1].r = 0.0;
597 marker.colors[1].g = 0.0;
598 marker.colors[1].b = 1.0;
601 marker.colors[0].a = 0.2;
602 marker.colors[0].r = 0.0;
603 marker.colors[0].g = 1.0;
604 marker.colors[0].b = 0.0;
605 marker.colors[1].a = 0.2;
606 marker.colors[1].r = 0.0;
607 marker.colors[1].g = 1.0;
608 marker.colors[1].b = 0.0;
611 markers.markers.push_back(marker);
614 pcl::PointCloud<PointType>::Ptr pc_particle(
new pcl::PointCloud<PointType>);
615 *pc_particle = *pc_locals[
"likelihood"];
616 e.transform(*pc_particle);
617 for (
auto& p : pc_particle->points)
619 visualization_msgs::Marker marker;
621 marker.header.stamp = header.stamp;
622 marker.ns =
"Sample points";
623 marker.id = markers.markers.size();
624 marker.type = visualization_msgs::Marker::SPHERE;
626 marker.pose.position.x = p.x;
627 marker.pose.position.y = p.y;
628 marker.pose.position.z = p.z;
629 marker.pose.orientation.x = 0.0;
630 marker.pose.orientation.y = 0.0;
631 marker.pose.orientation.z = 0.0;
632 marker.pose.orientation.w = 1.0;
633 marker.scale.x = marker.scale.y = marker.scale.z = 0.2;
635 marker.frame_locked =
true;
636 marker.color.a = 1.0;
637 marker.color.r = 1.0;
638 marker.color.g = 0.0;
639 marker.color.b = 1.0;
641 markers.markers.push_back(marker);
667 ROS_INFO(
"Pose jumped pos:%0.3f, ang:%0.3f", jump_dist, jump_ang);
672 s.odom_err_integ_lin_ =
Vec3();
673 s.odom_err_integ_ang_ =
Vec3();
675 pf_->predict(integ_reset_func);
679 geometry_msgs::TransformStamped trans;
686 const auto rpy = map_rot.
getRPY();
693 map_pos =
f_pos_->in(map_pos);
694 trans.transform.translation =
tf2::toMsg(tf2::Vector3(map_pos.
x_, map_pos.
y_, map_pos.
z_));
697 std::vector<geometry_msgs::TransformStamped> transforms;
698 transforms.push_back(trans);
703 assert(std::isfinite(e.pos_.x_));
704 assert(std::isfinite(e.pos_.y_));
705 assert(std::isfinite(e.pos_.z_));
706 assert(std::isfinite(e.rot_.x_));
707 assert(std::isfinite(e.rot_.y_));
708 assert(std::isfinite(e.rot_.z_));
709 assert(std::isfinite(e.rot_.w_));
713 trans.transform.translation =
tf2::toMsg(tf2::Vector3(0.0, 0.0, e.pos_.z_));
716 transforms.push_back(trans);
723 auto cov = pf_->covariance(
728 geometry_msgs::PoseWithCovarianceStamped pose;
729 pose.header.stamp = header.stamp;
730 pose.header.frame_id = trans.header.frame_id;
731 pose.pose.pose.position.x = e.pos_.x_;
732 pose.pose.pose.position.y = e.pos_.y_;
733 pose.pose.pose.position.z = e.pos_.z_;
734 pose.pose.pose.orientation.x = e.rot_.x_;
735 pose.pose.pose.orientation.y = e.rot_.y_;
736 pose.pose.pose.orientation.z = e.rot_.z_;
737 pose.pose.pose.orientation.w = e.rot_.w_;
738 for (
size_t i = 0; i < 36; i++)
740 pose.pose.covariance[i] = cov[i / 6][i % 6];
750 status_.convergence_status = mcl_3dl_msgs::Status::CONVERGENCE_STATUS_LARGE_STD_VALUE;
754 if (
status_.convergence_status != mcl_3dl_msgs::Status::CONVERGENCE_STATUS_LARGE_STD_VALUE)
757 const float fix_ang = std::sqrt(cov[3][3] + cov[4][4] + cov[5][5]);
758 const float fix_dist = std::sqrt(cov[0][0] + cov[1][1] + cov[2][2]);
759 ROS_DEBUG(
"cov: lin %0.3f ang %0.3f", fix_dist, fix_ang);
764 status_.convergence_status = mcl_3dl_msgs::Status::CONVERGENCE_STATUS_CONVERGED;
770 pcl::PointCloud<PointType>::Ptr pc_particle(
new pcl::PointCloud<PointType>);
771 *pc_particle = *pc_locals[
"likelihood"];
772 e.transform(*pc_particle);
782 pcl::PointCloud<pcl::PointXYZ>::Ptr pc_match(
new pcl::PointCloud<pcl::PointXYZ>);
783 pcl::PointCloud<pcl::PointXYZ>::Ptr pc_unmatch(
new pcl::PointCloud<pcl::PointXYZ>);
785 pcl::PointCloud<PointType>::Ptr pc_local(
new pcl::PointCloud<PointType>);
786 *pc_local = *pc_local_full;
788 e.transform(*pc_local);
790 std::vector<int> id(1);
791 std::vector<float> sqdist(1);
793 for (
auto& p : pc_local->points)
797 pc_unmatch->points.emplace_back(p.x, p.y, p.z);
799 else if (sqdist[0] < match_dist_sq)
801 pc_match->points.emplace_back(p.x, p.y, p.z);
806 sensor_msgs::PointCloud2 pc2;
808 pc2.header.stamp = header.stamp;
814 sensor_msgs::PointCloud2 pc2;
816 pc2.header.stamp = header.stamp;
832 std::normal_distribution<float> noise(0.0, 1.0);
833 auto update_noise_func = [
this, &noise](
State6DOF&
s)
840 pf_->predict(update_noise_func);
842 const auto tnow = boost::chrono::high_resolution_clock::now();
844 boost::chrono::duration<float>(tnow - ts).count());
845 const auto err_integ_map = e_max.rot_ * e_max.odom_err_integ_lin_;
846 ROS_DEBUG(
"odom error integral lin: %0.3f, %0.3f, %0.3f, " 847 "ang: %0.3f, %0.3f, %0.3f, " 848 "pos: %0.3f, %0.3f, %0.3f, " 849 "err on map: %0.3f, %0.3f, %0.3f",
850 e_max.odom_err_integ_lin_.x_,
851 e_max.odom_err_integ_lin_.y_,
852 e_max.odom_err_integ_lin_.z_,
853 e_max.odom_err_integ_ang_.x_,
854 e_max.odom_err_integ_ang_.y_,
855 e_max.odom_err_integ_ang_.z_,
862 ROS_DEBUG(
"match ratio min: %0.3f, max: %0.3f, pos: %0.3f, %0.3f, %0.3f",
878 status_.status = mcl_3dl_msgs::Status::EXPANSION_RESETTING;
892 const int reduced = pf_->getParticleSize() * 0.75;
895 pf_->resizeParticle(reduced);
907 status_.status = mcl_3dl_msgs::Status::GLOBAL_LOCALIZATION;
910 status_.match_ratio = match_ratio_max;
911 status_.particle_size = pf_->getParticleSize();
914 void cbLandmark(
const geometry_msgs::PoseWithCovarianceStamped::ConstPtr& msg)
917 Eigen::Matrix<double, 6, 6>(
918 msg->pose.covariance.data())
921 Vec3(msg->pose.pose.position.x,
922 msg->pose.pose.position.y,
923 msg->pose.pose.position.z),
924 Quat(msg->pose.pose.orientation.x,
925 msg->pose.pose.orientation.y,
926 msg->pose.pose.orientation.z,
927 msg->pose.pose.orientation.w));
928 auto measure_func = [
this, &measured, &nd](
const State6DOF&
s) ->
float 932 const Eigen::Matrix<float, 6, 1> diff_vec =
933 (Eigen::MatrixXf(6, 1) << diff.
pos_.
x_,
941 const auto n = nd(diff_vec);
944 pf_->measure(measure_func);
956 void cbImu(
const sensor_msgs::Imu::ConstPtr& msg)
959 msg->linear_acceleration.x,
960 msg->linear_acceleration.y,
961 msg->linear_acceleration.z));
971 float dt = (msg->header.stamp -
imu_last_).toSec();
972 if (dt < 0.0 || dt > 5.0)
974 ROS_WARN(
"Detected time jump in imu. Resetting.");
983 geometry_msgs::Vector3 in, out;
984 in.x = acc_measure.
x_;
985 in.y = acc_measure.
y_;
986 in.z = acc_measure.
z_;
991 acc_measure =
Vec3(out.x, out.y, out.z);
1000 axis =
Quat(trans.transform.rotation.x,
1001 trans.transform.rotation.y,
1002 trans.transform.rotation.z,
1003 trans.transform.rotation.w) *
1013 auto imu_measure_func = [
this](
const State6DOF&
s) ->
float 1017 pf_->measure(imu_measure_func);
1023 nav_msgs::Odometry::Ptr odom(
new nav_msgs::Odometry);
1025 odom->header.stamp = msg->header.stamp;
1035 mcl_3dl_msgs::ResizeParticleResponse& response)
1037 pf_->resizeParticle(request.size);
1042 std_srvs::TriggerResponse& response)
1055 std_srvs::TriggerResponse& response)
1059 response.success =
false;
1060 response.message =
"No map received.";
1063 pcl::PointCloud<PointType>::Ptr points(
new pcl::PointCloud<PointType>);
1073 pcl::KdTreeFLANN<PointType>::Ptr kdtree(
new pcl::KdTreeFLANN<PointType>);
1074 kdtree->setPointRepresentation(
1075 boost::dynamic_pointer_cast<
1076 pcl::PointRepresentation<PointType>,
1078 kdtree->setInputCloud(points);
1080 auto pc_filter = [
this, kdtree](
const PointType& p)
1082 std::vector<int> id(1);
1083 std::vector<float> sqdist(1);
1087 return kdtree->radiusSearch(
1091 std::remove_if(points->begin(), points->end(), pc_filter),
1095 pf_->resizeParticle(points->size() * dir);
1096 auto pit = points->begin();
1098 const float prob = 1.0 /
static_cast<float>(points->size());
1100 for (
auto& particle : *pf_)
1102 assert(pit != points->end());
1103 particle.probability_ = prob;
1104 particle.probability_bias_ = 1.0;
1106 Vec3(pit->x, pit->y, pit->z),
1114 response.success =
true;
1115 response.message = std::to_string(pf_->getParticleSize()) +
" particles";
1121 geometry_msgs::PoseArray pa;
1127 for (
size_t i = 0; i < pf_->getParticleSize(); i++)
1129 geometry_msgs::Pose pm;
1130 auto p = pf_->getParticle(i);
1132 pm.position.x = p.pos_.x_;
1133 pm.position.y = p.pos_.y_;
1134 pm.position.z = p.pos_.z_;
1135 pm.orientation.x = p.rot_.x_;
1136 pm.orientation.y = p.rot_.y_;
1137 pm.orientation.z = p.rot_.z_;
1138 pm.orientation.w = p.rot_.w_;
1139 pa.poses.push_back(pm);
1147 for (
auto& particle : *pf_)
1149 sum += particle.probability_;
1152 float entropy = 0.0f;
1153 for (
auto& particle : *pf_)
1155 if (particle.probability_ / sum > 0.0)
1156 entropy += particle.probability_ / sum * std::log(particle.probability_ / sum);
1164 if (
status_.error == mcl_3dl_msgs::Status::ERROR_POINTS_NOT_FOUND)
1166 stat.
summary(diagnostic_msgs::DiagnosticStatus::ERROR,
"Valid points does not found.");
1168 else if (
status_.convergence_status == mcl_3dl_msgs::Status::CONVERGENCE_STATUS_LARGE_STD_VALUE)
1170 stat.
summary(diagnostic_msgs::DiagnosticStatus::ERROR,
"Too Large Standard Deviation.");
1174 stat.
summary(diagnostic_msgs::DiagnosticStatus::OK,
"OK");
1177 stat.
add(
"Map Availability",
has_map_ ?
"true" :
"false");
1178 stat.
add(
"Odometry Availability",
has_odom_ ?
"true" :
"false");
1179 stat.
add(
"IMU Availability",
has_imu_ ?
"true" :
"false");
1206 int odom_queue_size;
1207 pnh_.
param(
"odom_queue_size", odom_queue_size, 200);
1215 pnh_.
param(
"imu_queue_size", imu_queue_size, 200);
1221 int cloud_queue_size;
1222 pnh_.
param(
"cloud_queue_size", cloud_queue_size, 100);
1230 nh_,
"mapcloud_update",
1236 nh_,
"mcl_measurement",
1248 nh_,
"resize_mcl_particle",
1251 nh_,
"global_localization",
1254 nh_,
"expansion_resetting",
1301 float max_search_radius = 0;
1304 lm.second->loadConfig(
pnh_, lm.first);
1305 max_search_radius = std::max(max_search_radius, lm.second->getMaxSearchRange());
1309 auto sampler = std::make_shared<PointCloudSamplerWithNormal<PointType>>();
1310 sampler->loadConfig(
pnh_);
1311 lm.second->setRandomSampler(sampler);
1315 auto sampler = std::make_shared<PointCloudUniformSampler<PointType>>();
1316 lm.second->setRandomSampler(sampler);
1320 ROS_DEBUG(
"max_search_radius: %0.3f", max_search_radius);
1323 kdtree_->setPointRepresentation(
1324 boost::dynamic_pointer_cast<
1325 pcl::PointRepresentation<PointType>,
1341 std::cerr <<
"mcl_3dl: saving pcd file.";
1342 std::cerr <<
" (" <<
pc_all_accum_->points.size() <<
" points)" << std::endl;
1351 const auto ts = boost::chrono::high_resolution_clock::now();
1355 pc_map2_.reset(
new pcl::PointCloud<PointType>);
1368 sensor_msgs::PointCloud2 out;
1371 const auto tnow = boost::chrono::high_resolution_clock::now();
1373 boost::chrono::duration<float>(tnow - ts).count());
virtual void filter(const PointCloud2::ConstPtr &input, const IndicesPtr &indices, PointCloud2 &output)
std::default_random_engine engine_
ros::Time match_output_last_
void setAxisAng(const Vec3 &axis, const float &ang)
std::shared_ptr< pf::ParticleFilter< State6DOF, float, ParticleWeightedMeanQuat, std::default_random_engine > > pf_
bool load(ros::NodeHandle &nh)
double update_downsample_x_
void cbOdom(const nav_msgs::Odometry::ConstPtr &msg)
#define ROS_WARN_THROTTLE(rate,...)
double resample_var_roll_
void publish(const boost::shared_ptr< M > &message) const
void summary(unsigned char lvl, const std::string s)
ros::Publisher pub_debug_marker_
double unmatch_output_dist_
void setHardwareID(const std::string &hwid)
ros::Subscriber sub_mapcloud_
std::shared_ptr< ChunkedKdtree > Ptr
virtual geometry_msgs::TransformStamped lookupTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, const ros::Duration timeout) const
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
IMETHOD Vector diff(const Vector &p_w_a, const Vector &p_w_b, double dt=1)
double match_output_dist_
void add(const std::string &name, TaskFunction f)
std::random_device seed_gen_
double update_downsample_z_
tf2_ros::TransformBroadcaster tfb_
double expansion_var_roll_
ros::ServiceServer srv_global_localization_
ros::Subscriber sub_cloud_
void doTransform(const T &data_in, T &data_out, const geometry_msgs::TransformStamped &transform)
ros::Subscriber sub_odom_
ros::Publisher pub_status_
pcl::PointCloud< PointType >::Ptr pc_update_
TFSIMD_FORCE_INLINE tfScalar angle(const Quaternion &q1, const Quaternion &q2)
ROSCPP_DECL void spin(Spinner &spinner)
std::shared_ptr< FilterVec3 > f_ang_
std::map< std::string, LidarMeasurementModelBase::Ptr > lidar_measurements_
ChunkedKdtree< PointType >::Ptr kdtree_
pcl::PointCloud< PointType >::Ptr pc_map2_
std::shared_ptr< ros::Duration > map_update_interval_
TFSIMD_FORCE_INLINE Vector3 normalized() const
ros::ServiceServer advertiseService(ros::NodeHandle &nh_new, const std::string &service_new, ros::NodeHandle &nh_old, const std::string &service_old, bool(T::*srv_func)(MReq &, MRes &), T *obj)
ros::Publisher pub_particle_
ros::Subscriber sub_mapcloud_update_
int total_accum_cloud_max_
std::shared_ptr< Filter > localize_rate_
double global_localization_grid_
void cbMapUpdateTimer(const ros::TimerEvent &event)
constexpr Vec3 getRPY() const
bool accumCloud(const sensor_msgs::PointCloud2::ConstPtr &msg)
void diagnoseStatus(diagnostic_updater::DiagnosticStatusWrapper &stat)
bool fromROSMsg(const sensor_msgs::PointCloud2 &msg, pcl::PointCloud< PointT > &pc)
ros::ServiceServer srv_expansion_reset_
ros::Time localized_last_
void cbLandmark(const geometry_msgs::PoseWithCovarianceStamped::ConstPtr &msg)
State6DOF initial_pose_std_
CloudAccumulationLogicBase::Ptr accum_
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
constexpr Quat inv() const
ros::Publisher pub_unmatched_
void getAxisAng(Vec3 &axis, float &ang) const
ros::Subscriber sub_landmark_
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
MotionPredictionModelBase::Ptr motion_prediction_model_
ros::Publisher pub_matched_
std::shared_ptr< LidarMeasurementModelBase > Ptr
std::array< float, 3 > std_warn_thresh_
pcl::PointCloud< PointType >::Ptr pc_local_accum_
bool cbExpansionReset(std_srvs::TriggerRequest &request, std_srvs::TriggerResponse &response)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
double odom_err_integ_lin_tc_
tf2_ros::TransformListener tfl_
virtual void copyToFloatArray(const PointType &p, float *out) const
double expansion_var_yaw_
mcl_3dl_msgs::Status status_
std::shared_ptr< FilterVec3 > f_acc_
std::shared_ptr< FilterVec3 > f_pos_
void cbMapcloud(const sensor_msgs::PointCloud2::ConstPtr &msg)
ImuMeasurementModelBase::Ptr imu_measurement_model_
std::shared_ptr< ImuMeasurementModelBase > Ptr
int main(int argc, char *argv[])
ros::Subscriber subscribe(ros::NodeHandle &nh_new, const std::string &topic_new, ros::NodeHandle &nh_old, const std::string &topic_old, uint32_t queue_size, void(T::*fp)(M) const, T *obj, const ros::TransportHints &transport_hints=ros::TransportHints())
uint32_t getNumSubscribers() const
std::map< std::string, std::string > frame_ids_
void setRPY(const Vec3 &rpy)
void setParticleStatistics(const State6DOF &mean, const std::vector< State6DOF > &covariances)
std::vector< std_msgs::Header > pc_accum_header_
MyPointRepresentation point_rep_
void toROSMsg(const sensor_msgs::PointCloud2 &cloud, sensor_msgs::Image &image)
double expansion_var_pitch_
double odom_err_integ_ang_tc_
ros::Publisher pub_mapcloud_
double match_ratio_thresh_
ros::Timer map_update_timer_
void cbPosition(const geometry_msgs::PoseWithCovarianceStamped::ConstPtr &msg)
ros::Duration tf_tolerance_base_
void cbImu(const sensor_msgs::Imu::ConstPtr &msg)
void add(const std::string &key, const T &val)
diagnostic_updater::Updater diag_updater_
bool use_random_sampler_with_normal_
pcl::PointCloud< PointType >::Ptr pc_map_
std::shared_ptr< ros::Duration > match_output_interval_
bool cbResizeParticle(mcl_3dl_msgs::ResizeParticleRequest &request, mcl_3dl_msgs::ResizeParticleResponse &response)
std::shared_ptr< ros::Duration > tf_tolerance_
double odom_err_integ_lin_sigma_
void cbMapcloudUpdate(const sensor_msgs::PointCloud2::ConstPtr &msg)
double update_downsample_y_
int global_localization_div_yaw_
ros::ServiceServer srv_particle_size_
std::shared_ptr< CloudAccumulationLogicBase > Ptr
size_t global_localization_fix_cnt_
double odom_err_integ_ang_sigma_
ros::Subscriber sub_position_
void toPCL(const ros::Time &stamp, pcl::uint64_t &pcl_stamp)
pcl::PointCloud< PointType >::Ptr pc_all_accum_
bool cbGlobalLocalization(std_srvs::TriggerRequest &request, std_srvs::TriggerResponse &response)
double resample_var_pitch_
std::shared_ptr< MotionPredictionModelBase > Ptr
void cbCloud(const sensor_msgs::PointCloud2::ConstPtr &msg)
std::array< float, 4 > dist_weight_