一大堆的问题啊,整死我了,搞了整天,差点想放弃了,想想自己毕设,再试试吧!
kinetic和pcl1.7版本,编译hdl_localization包,简直太难受了!一大堆的编译问题,主要是 两部分问题 以下问题:
1.相关依赖的包编译问题
2.本身由于pcl库接口的问题
3.ros参数加载问题
4.运行rviz没有地图问题
这个问题好解决,大部分都是因为C++_11标准的问题,找到CMakeLisk文件,增加一行代码解决:
project(hdl_global_localization)
set(CMAKE_CXX_FLAGS "-std=c++14")
这部分也有点坑,好像是因为kinetic系统apt-get install安装的pcl库是1.7版本,包中所依赖的接口好像在pcl 1.80 版本之后才有。编译报错是transformPointCloud没有匹配的接口:
no matching function for call to ‘transformPointCloud(std::__cxx11::string&, pcl::PointCloud<pcl::PointXYZI>&, pcl::PointCloud<pcl::PointXYZI>&, tf2_ros::Buffer&)’
if(!pcl_ros::transformPointCloud(odom_child_frame_id, *pcl_cloud, *cloud, this->tf_buffer))
看github上面有人说除了更新pcl1.8版本, 还可以自己修改,然后自己copy了pcl库中的函数,添加进来。
而且因为没有找到基于第四个参数tf2_ros::Buffer类型的接口,需要将this->tf_buffer参数转换成有适配接口的tf::TransformListener tf_listener类型:
/*这里注释掉
//transform pointcloud into odom_child_frame_id
pcl::PointCloud::Ptr cloud(new pcl::PointCloud());
if(!pcl_ros::transformPointCloud(odom_child_frame_id, *pcl_cloud, *cloud, this->tf_buffer)) {
NODELET_ERROR("point cloud cannot be transformed into target frame!!");
return;
} */
//像这样修改,调用函数
pcl::PointCloud<PointT>::Ptr cloud(new pcl::PointCloud<PointT>());
tf::TransformListener tf_listener;
if(!tf_listener.canTransform(odom_child_frame_id, pcl_cloud->header.frame_id, ros::Time(0))) {
std::cerr << "failed to find transform between " << odom_child_frame_id << " and " << pcl_cloud->header.frame_id << std::endl;
}
tf::StampedTransform transform;
tf_listener.waitForTransform(odom_child_frame_id, pcl_cloud->header.frame_id, ros::Time(0), ros::Duration(2.0));
tf_listener.lookupTransform(odom_child_frame_id, pcl_cloud->header.frame_id, ros::Time(0), transform);
if(!transformPointCloud(odom_child_frame_id,*pcl_cloud,*cloud, tf_listener)) {
NODELET_ERROR("point cloud cannot be transformed into target frame!!");
return;
}
error: no matching function for call to ‘ros::NodeHandle::param(const char [27], const char [8]) const’
std::string ndt_neighbor_search_method = private_nh.param<std::string>("ndt_neighbor_search_method", "DIRECT7");
hdl_ws/src/hdl_localization/apps/hdl_localization_nodelet.cpp:86:75: error: no matching function for call to ‘ros::NodeHandle::param(const char [15], double) const’
double ndt_resolution = private_nh.param<double>("ndt_resolution", 1.0);
像这样的问题,虽然不知道是为什么,可能是由于ros版本问题,没有合适的接口。没得办法,只有去适配现有环境的接口,修改也很简单:
//原代码
/*std::string ndt_neighbor_search_method = private_nh.param("ndt_neighbor_search_method", "DIRECT7");*/
//修改后
std::string ndt_neighbor_search_method;
private_nh.param<std::string>("ndt_neighbor_search_method",ndt_neighbor_search_method , "DIRECT7");
编译后基本不会报错了!! ! 望奔走相告!
这个问题你们大概不会遇到,我无中生有出来的问题。。。。。。
本来以为编译通过就万事大吉,结果老老实实跟着github教程去配置,还参考了一篇博客配置了一下。注释了一行代码,结果一运行,啥玩意都没有,既没有地图,也没有bag包播放的雷达数据!
原代码launch文件有一行是这样的:
<!-- in case you use velodyne_driver, comment out the following line -->
<node pkg="nodelet" type="nodelet" name="$(arg nodelet_manager)" args="manager" output="screen"/>
我一看就理解为运行velodyne雷达就把代码注释掉,结果人家意思是运行velodyne_driver雷达驱动时将代码注释,其实就是实际小车运行时应该注释。 仿真你就别注释!!!
其他参数根据测试和自己需求配置就行。