当前位置: 首页 > news >正文

镭神C32测试LEGO-LOAM

原文链接

目录

跑通LEGO-LOAM

安装gtsam(Georgia Tech Smoothing and Mapping library, 4.0.0-alpha2)

安装编译LEGO-LOAM

运行

测试

修改utility.h

修改imageProjection.cpp

转换话题文件

修改LEGO-LOAM配置

测试效果


跑通LEGO-LOAM

安装gtsam(Georgia Tech Smoothing and Mapping library, 4.0.0-alpha2)

  
  
  1. wget -O ~/Downloads/gtsam.zip https://github.com/borglab/gtsam/archive/4.0.0-alpha2.zip
  2. cd ~/Downloads/ && unzip gtsam.zip -d ~/Downloads/
  3. cd ~/Downloads/gtsam-4.0.0-alpha2/
  4. mkdir build && cd build
  5. cmake -DGTSAM_BUILD_WITH_MARCH_NATIVE=OFF -DGTSAM_USE_SYSTEM_EIGEN=ON ..
  6. sudo make install

        由于系统是ubuntu20.04中文版,所以把上面的【Downloads】换为【下载】即可,中间会有好多warning,不知道是否影响使用。

安装编译LEGO-LOAM

  
  
  1. cd ~/catkin_ws/src
  2. git clone https://github.com/RobustFieldAutonomyLab/LeGO-LOAM.git
  3. cd ..
  4. catkin_make -j1

第一次编译代码时,需要在“catkin_make”后面加上“-j1”来生成一些消息类型。以后的编译不需要“-j1”

编译时报错:

  • In file included from /home/lpf/catkin_ws/src/LeGO-LOAM/LeGO-LOAM/src/imageProjection.cpp:35:/home/lpf/catkin_ws/src/LeGO-LOAM/LeGO-LOAM/include/utility.h:13:10: fatal error: opencv/cv.h: 没有那个文件或目录

   13 | #include <opencv/cv.h>

我记得以前是装过opencv的,应该是版本不同,就去搜了一下,原因是在opencv4中opencv2的cv.h融合进了imgproc.hpp里,所以把utility.h中的#include <opencv/cv.h>改成#include <opencv2/imgproc.hpp>即可。

  • /home/lpf/catkin_ws/src/LeGO-LOAM/LeGO-LOAM/include/utility.h:182:1: error: ‘mulscalar’ is not a member of ‘pcl::traits’

将cmakelists.txt中的c++编译版本改为14

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -O3")

  • /usr/include/pcl-1.10/pcl/filters/voxel_grid.h:340:21: error: ‘Index’ is not a member of ‘Eigen’

这个错误是因为 Lego LOAM 中原作者建议使用的 gtsam 版本为 4.0.0-alpha2,gtsam 是自带了一个 eigen 库的,而这个版本的 gtsam 中使用的是较低版本的 Eigen,还没有 Eigen::Index 这个定义。比较简单的做法是将 PCL 中用到的 Eigen::Index 改为 int 即可。不过使用 gtsam 中低版本的 Eigen 可能也会在别的库造成问题,所以建议的做法是不适用 gtsam 带的第三方库,具体方法为按照作者的方法编译 gtsam 时在 cmake 阶段设置使用系统自带的 Eigen,此外 gtsam 编译时会默认进行 SSE 加速,而如 PCL 等其他库大多数情况不会打开,因此如果一起使用的话会造成节点崩溃,因此一般将其关闭,如下所示:


  
  
  1. mkdir build && cd build
  2. cmake -DGTSAM_BUILD_WITH_MARCH_NATIVE=OFF -DGTSAM_USE_SYSTEM_EIGEN=ON ..
  3. sudo make install

又报错:


  
  
  1. /usr/bin/ld: 找不到 -lBoost::serialization
  2. /usr/bin/ld: 找不到 -lBoost::thread
  3. /usr/bin/ld: 找不到 -lBoost::timer
  4. /usr/bin/ld: 找不到 -lBoost::chrono

百度查了一下,说是该类问题有通用的解决方法,先用locate定位未找到的共享库,然后建立软链接,试了一下不行,然后继续搜,找到了这篇,是通过修改CmakeList.txt文件,调用这些包。


  
  
  1. find_package(Boost REQUIRED COMPONENTS
  2. serialization timer thread chrono)
  3. # include directories
  4. include_directories(
  5. include
  6. ${catkin_INCLUDE_DIRS}
  7. ${PCL_INCLUDE_DIRS}
  8. ${OpenCV_INCLUDE_DIRS}
  9. ${GTSAM_INCLUDE_DIR}
  10. ${Boost_INCLUDE_DIRS}
  11. )
  12. # link directories
  13. link_directories(
  14. include
  15. ${PCL_LIBRARY_DIRS}
  16. ${OpenCV_LIBRARY_DIRS}
  17. ${GTSAM_LIBRARY_DIRS}
  18. ${Boost_INCLUDE_DIRS}
  19. )

到此就编译完成了,如下图

运行

因为 tf2 开始已经不会在 frame_id 前面加 /,所以需要将代码中所有涉及 frame_id 的部分将 / 去掉

roslaunch lego_loam run.launch
  
  

Notes: launch文件中 The parameter "/use_sim_time" is set to "true" for simulation, "false" to real robot usage.

rosbag play *.bag --clock --topic /velodyne_points /imu/data
  
  

--clock指播放时顺带显示录制文件的时间戳,后面表示播放录制文件中指定话题的消息,参考

但是,我一开始没有加参数,rviz没有显示点云,不知道为什么?这个有影响吗?

根据github提供的代码地址下载数据集,播放same_position.bag文件

测试

换用自己的传感器主要需要修改utility.h以及imageProjection.cpp,并转换topic

修改utility.h

源文件作者的备注:

New Lidar:The key thing to adapt the code to a new sensor is making sure the point cloud can be properly projected to an range image and ground can be correctly detected. For example, VLP-16 has a angular resolution of 0.2° and 2° along two directions. It has 16 beams. The angle of the bottom beam is -15°. Thus, the parameters in “utility.h” are listed as below. When you implement new sensor, make sure that the ground_cloud has enough points for matching. Before you post any issues, please read this.


  
  
  1. extern const int N_SCAN = 16;
  2. extern const int Horizon_SCAN = 1800;
  3. extern const float ang_res_x = 0.2;
  4. extern const float ang_res_y = 2.0;
  5. extern const float ang_bottom = 15.0;
  6. extern const int groundScanInd = 7;

Another example for Velodyne HDL-32e range image projection:


  
  
  1. extern const int N_SCAN = 32; //线数
  2. extern const int Horizon_SCAN = 1800; //旋转一周的采样数
  3. extern const float ang_res_x = 360.0/Horizon_SCAN; //水平分辨率
  4. extern const float ang_res_y = 41.333/ float(N_Scan -1); //垂直分辨率
  5. extern const float ang_bottom = 30.666666; //lidar底部线束的角度偏移
  6. extern const int groundScanInd = 20; //lidar判定为地面的线束

针对镭神C32,参考,在utility.h中添加镭神C32的配置


  
  
  1. // LeiShen-32C-5Hz
  2. // extern const int N_SCAN = 32;
  3. // extern const int Horizon_SCAN = 4000;
  4. // extern const float ang_res_x = 360.0 / float(Horizon_SCAN);
  5. // extern const float ang_res_y = 26 / float(N_SCAN-1);
  6. // extern const float ang_bottom = 16.5;
  7. // extern const int groundScanInd = 10; //地面的线扫条数
  8. // LeiShen-32C-10Hz
  9. extern const int N_SCAN = 32;
  10. extern const int Horizon_SCAN = 2000;
  11. extern const float ang_res_x = 360.0 / float(Horizon_SCAN);
  12. extern const float ang_res_y = 31.0 / float(N_SCAN -1);
  13. extern const float ang_bottom = 16.5; //雷达底部线束的偏移角度
  14. extern const int groundScanInd = 10; //地面的线扫条数

查手册,10 Hz时,Horizon_SCAN = 360/0.18 = 2000

 New: a new useCloudRing flag has been added to help with point cloud projection. Velodyne point cloud has “ring” channel that directly gives the point row id in a range image. Other lidars may have a same type of channel, i.e., “r” in Ouster. If you are using a non-Velodyne lidar but it has a similar “ring” channel, you can change the PointXYZIR definition in utility.h and the corresponding code in imageProjection.cpp.

useCloudRing标志帮助点云进行投影,Velodyne点云包含"环"频道,在大范围图像内直接给出点的行id。其他雷达可能也有这个通道。如果您使用的是非velodyne激光雷达,但是它有一个类似的“环形”通道,您可以在utility.h中更改PointXYZIR定义,并在imageproject .cpp中更改相应的代码。

镭神好像是没有Velodyne雷达的ring channel功能,所以useCloudRing设置为false了,设置false后,应该是会通过分辨率和角度来计算属于哪条线束


  
  
  1. // Using velodyne cloud "ring" channel for image projection (other lidar may have different name for this channel, change "PointXYZIR" below)
  2. extern const bool useCloudRing = false; // if true, ang_res_y and ang_bottom are not used
修改imageProjection.cpp

找到copyPointCloud,将cloudHeader.stamp = ros::Time::now()的注释去掉


  
  
  1. void copyPointCloud(const sensor_msgs::PointCloud2ConstPtr& laserCloudMsg){
  2. cloudHeader = laserCloudMsg->header;
  3. cloudHeader.stamp = ros::Time:: now(); // Ouster lidar users may need to uncomment this line
  4. pcl:: fromROSMsg(*laserCloudMsg, *laserCloudIn);
  5. // Remove Nan points
  6. std::vector< int> indices;
  7. pcl:: removeNaNFromPointCloud(*laserCloudIn, *laserCloudIn, indices);
  8. // have "ring" channel in the cloud
  9. if (useCloudRing == true){
  10. pcl:: fromROSMsg(*laserCloudMsg, *laserCloudInRing);
  11. if (laserCloudInRing->is_dense == false) {
  12. ROS_ERROR( "Point cloud is not in dense format, please remove NaN points first!");
  13. ros:: shutdown();
  14. }
  15. }
  16. }
转换话题

LeGO-LOAM默认的接受的topic name是velodyne_points,点云的frame_id是velodyne,镭神驱动发布的topic name为lslidar_point_cloud,frame_id为laser_link。所以,要想LEGO-LOAM可以使用镭神C32,有以下两种方法:

  1. 修改lslidar_c32.launch文件
  2. 写中间文件,将话题消息作下转换

考虑普适性与便利性,应该写中间文件进行话题转换

topic_change_node.cpp


  
  
  1. #include "ros/ros.h"
  2. #include "std_msgs/String.h"
  3. #include "sensor_msgs/PointCloud2.h"
  4. #include <string>
  5. #include <sstream>
  6. /**
  7. * This tutorial demonstrates simple sending of messages over the ROS system.
  8. */
  9. static ros::Publisher target_pub;
  10. std::string target_frame_id;
  11. static void source_topic_callback(const sensor_msgs::PointCloud2::ConstPtr& input)
  12. {
  13. sensor_msgs::PointCloud2 msg = *input;
  14. msg.header.frame_id = target_frame_id;
  15. target_pub. publish(msg);
  16. }
  17. int main(int argc, char *argv[])
  18. {
  19. ros:: init(argc, argv, "leishen_to_velodye");
  20. ros::NodeHandle private_nh("~");
  21. ros::NodeHandle n;
  22. std::string source_topic;
  23. std::string target_topic;
  24. if (!private_nh. getParam( "source_topic", source_topic))
  25. {
  26. ROS_ERROR( "can not get source_topic!");
  27. exit( 0);
  28. }
  29. if (!private_nh. getParam( "target_topic", target_topic))
  30. {
  31. ROS_ERROR( "can not get target_topic!");
  32. exit( 0);
  33. }
  34. if (!private_nh. getParam( "target_frame_id", target_frame_id))
  35. {
  36. ROS_ERROR( "can not get target_frame_id!");
  37. exit( 0);
  38. }
  39. target_pub = n. advertise<sensor_msgs::PointCloud2>(target_topic, 10);
  40. ros::Subscriber main_topic_sub = n. subscribe<sensor_msgs::PointCloud2>(source_topic, 10000, source_topic_callback);
  41. /**
  42. * A count of how many messages we have sent. This is used to create
  43. * a unique string for each message.
  44. */
  45. ros:: spin();
  46. return 0;
  47. }

 topic_change.launch


  
  
  1. <launch>
  2. <arg name= "target_topic_name" default= "velodyne_points" />
  3. <arg name= "target_frame_id_name" default= "velodyne" />
  4. <arg name= "source_topic_name" default= "lslidar_point_cloud" />
  5. <node pkg= "topic_change" name= "topic_change_node" type= "topic_change_node" output= "screen">
  6. <param name= "target_topic" value= "$(arg target_topic_name)" />
  7. <param name= "source_topic" value= "$(arg source_topic_name)" />
  8. <param name= "target_frame_id" value= "$(arg target_frame_id_name)" />
  9. </node>
  10. </launch>

单独编译:catkin_make -DCATKIN_WHITELIST_PACKAGES="topic_change"

恢复编译所有包:catkin_make -DCATKIN_WHITELIST_PACKAGES=""

修改LEGO-LOAM配置

由于布置的分布式通信系统,需要把镭神lslidar_c32.launch文件中的启动rviz注释掉

对于实时建图,需要修改LEGO-LOAM中的run.launch


  
  
  1. <!--- Sim Time -->
  2. <param name= "/use_sim_time" value= "false" />

将true改为false,表示不使用仿真时间

测试效果

测试效果如下(雷达放在原位置没有动)

相关文章:

  • IntelliJ IDEA 2021版创建springboot项目的五种方式
  • 深度解析前端页面性能优化
  • Python与SQL深度融合实战案例:打造你的数据处理秘籍
  • C++后端服务器开发技术栈有哪些?有哪些资源或开源库拿来用?
  • 嵌入式八股C语言---指针与函数篇
  • ESP8266 入门(第 2 部分):使用 AT 命令
  • c#面试题整理7
  • JavaScript系列07-事件委托:深入剖析与实践技术
  • LeetCode 1876长度为三且各字符不同的子字符串
  • 【数据结构】-- LinkedList与链表(1)
  • Docker 实践与应用举例
  • CCF-CSP第27次认证第1题 --《如此编码》
  • 大模型量化技术原理总结 [吃果冻不吐果冻皮]
  • 自然语言处理:最大期望值算法
  • 从案例分析看微型工业计算机在智能社区中的卓越表现
  • Springboot redis bitMap实现用户签到以及统计,保姆级教程
  • SpringBoot全栈开发:从数据库到Markdown文件导出的终极实践指南
  • TCP协议与包头格式
  • 计算机视觉中的前向卷绕算法全解析
  • 从0到1入门RabbitMQ
  • 有没有教做帽子的网站/网络推广营销方案免费
  • 做网站的公司哪些靠谱/国内做seo最好的公司
  • 天元建设集团有限公司标志源文件/网站搜索优化技巧
  • 南昌哪里有网站建设/暴疯团队seo课程
  • 鄂州手机网站设计/网站推广怎么弄
  • 用dedecms 做门户网站/经典软文案例100例