Ubuntu 20.04上从零复现A-Loam:我踩过的那些坑和最终解决方案
Ubuntu 20.04上从零复现A-Loam:我踩过的那些坑和最终解决方案
在激光SLAM领域,A-Loam作为Loam算法的优化版本,因其代码简洁、易读性强而备受初学者青睐。然而,当我在Ubuntu 20.04系统上尝试复现这个框架时,却遭遇了一系列意想不到的挑战。这篇文章将详细记录我的完整复现过程,特别是那些在Ubuntu 16.04/18.04教程中不会遇到的特殊问题,以及最终验证可行的解决方案。
1. 系统准备与环境配置
Ubuntu 20.04作为长期支持版本,带来了许多新特性,但也引入了一些兼容性问题。在开始之前,建议先完成以下基础准备:
系统更新:确保系统是最新状态
sudo apt update && sudo apt upgrade -y开发者工具安装:
sudo apt install build-essential cmake git -y
我在初始配置时犯了一个常见错误——直接按照Ubuntu 18.04的教程进行操作,这导致后续出现了大量依赖冲突。特别需要注意的是,Ubuntu 20.04默认的软件包版本与早期系统有很大不同。
提示:建议在开始前创建一个独立的工作目录,所有操作都在此目录下进行,便于管理和清理。
2. ROS安装的曲折之路
ROS作为A-Loam的基础依赖,其安装过程在Ubuntu 20.04上尤为棘手。官方推荐使用ROS Noetic,这是首个专为20.04设计的ROS版本。
2.1 正确的ROS Noetic安装步骤
经过多次尝试,以下是我验证可用的安装流程:
设置sources.list:
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'设置密钥:
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654安装完整桌面版ROS:
sudo apt update sudo apt install ros-noetic-desktop-full环境设置:
echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc source ~/.bashrc
2.2 常见问题及解决方案
在ROS安装过程中,我遇到了几个典型问题:
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 安装速度极慢 | 默认源连接不稳定 | 更换国内镜像源 |
| 依赖关系错误 | 系统残留旧版本 | 彻底清理后重试 |
| rosdep初始化失败 | 网络连接问题 | 手动配置rosdep |
最耗时的环节是rosdep init和rosdep update,这两个命令经常因网络问题失败。经过多次尝试,我发现以下方法最为可靠:
sudo mkdir -p /etc/ros/rosdep/sources.list.d/ sudo curl -o /etc/ros/rosdep/sources.list.d/20-default.list https://mirrors.tuna.tsinghua.edu.cn/git/rosdistro/raw/master/rosdep/sources.list.d/20-default.list sudo rosdep init rosdep update3. 关键依赖库的版本选择
A-Loam依赖于几个关键库,包括PCL和Ceres Solver。这些库的版本选择直接影响复现成功率。
3.1 PCL库的最佳实践
PCL(Point Cloud Library)是处理点云数据的核心库。在Ubuntu 20.04上,默认仓库提供的PCL版本是1.10,但经过测试,1.9版本更为稳定。
手动编译PCL 1.9的步骤:
安装依赖:
sudo apt install libboost-all-dev libeigen3-dev libflann-dev libvtk7-dev libqhull-dev下载源码:
git clone https://github.com/PointCloudLibrary/pcl.git cd pcl git checkout pcl-1.9.1编译安装:
mkdir build && cd build cmake -DCMAKE_BUILD_TYPE=Release .. make -j$(nproc) sudo make install
注意:编译过程可能耗时较长,建议使用
-j参数并行编译以加快速度。
3.2 Ceres Solver的安装技巧
Ceres Solver是一个广泛使用的非线性优化库。在Ubuntu 20.04上,我推荐安装1.14.x版本。
安装步骤:
安装依赖:
sudo apt install libgoogle-glog-dev libgflags-dev libatlas-base-dev libsuitesparse-dev下载并编译:
git clone https://ceres-solver.googlesource.com/ceres-solver cd ceres-solver git checkout 1.14.0 mkdir build && cd build cmake .. make -j$(nproc) sudo make install
4. A-Loam的编译与调试
当所有依赖就绪后,就可以开始A-Loam的编译工作了。这里有几个关键点需要注意。
4.1 获取源码与准备工作
mkdir -p ~/aloam_ws/src cd ~/aloam_ws/src git clone https://github.com/HKUST-Aerial-Robotics/A-LOAM.git cd ..在编译前,需要修改几处关键配置:
修改
CMakeLists.txt中的PCL版本检测:find_package(PCL 1.9 REQUIRED)确保Eigen3路径正确:
include_directories( ${catkin_INCLUDE_DIRS} /usr/include/eigen3 )
4.2 常见编译错误及修复
在编译过程中,我遇到了以下典型错误:
Eigen相关错误:
error: 'ScalarBinaryOpTraits' is not a member of 'Eigen'解决方案:在相关头文件中添加:
#include <Eigen/Core>PCL版本不匹配:
undefined reference to `pcl::KdTreeFLANN<pcl::PointXYZI>::~KdTreeFLANN()'解决方案:确保系统中只有一个版本的PCL,并彻底清理后重新编译。
Ceres链接错误:
undefined reference to `ceres::Problem::Problem()'解决方案:在
CMakeLists.txt中正确链接Ceres库:target_link_libraries(alaserOdometry ${CERES_LIBRARIES})
4.3 运行与测试
成功编译后,可以使用KITTI数据集进行测试:
roslaunch aloam_velodyne aloam_velodyne_VLP_16.launch rosbag play kitti_2011_09_30_drive_0027_synced.bag在测试过程中,我发现以下几个性能优化技巧:
调整
laserOdometry.cpp中的参数可以显著提高实时性:// 减少每帧处理的特征点数 const int edgeFeatureNum = 2000; const int surfFeatureNum = 2000;对于低配置机器,可以降低点云分辨率:
pcl::VoxelGrid<pcl::PointXYZI> downSizeFilter; downSizeFilter.setLeafSize(0.2, 0.2, 0.2); // 原始值为0.1
5. 实战经验与高级技巧
经过多次尝试和优化,我总结出以下提升A-Loam性能的实用技巧:
5.1 参数调优指南
A-Loam的性能很大程度上取决于参数设置。以下是一些关键参数及其影响:
| 参数 | 位置 | 推荐值 | 作用 |
|---|---|---|---|
| edgeThreshold | scanRegistration.cpp | 0.1 | 边缘特征点阈值 |
| surfThreshold | scanRegistration.cpp | 0.1 | 平面特征点阈值 |
| nearestFeatureSearchNum | laserOdometry.cpp | 5 | 最近邻搜索数量 |
| optimizationCount | laserOdometry.cpp | 2 | 优化迭代次数 |
5.2 实时性能监控
为了实时监控算法性能,可以添加以下ROS节点:
#!/usr/bin/env python import rospy from std_msgs.msg import Float32 def callback(data): rospy.loginfo("Processing time: %f ms", data.data*1000) def monitor(): rospy.init_node('performance_monitor') rospy.Subscriber("/processing_time", Float32, callback) rospy.spin() if __name__ == '__main__': monitor()5.3 点云可视化优化
使用RViz进行可视化时,可以通过以下配置提升体验:
创建自定义rviz配置:
rosrun rviz rviz -d $(rospack find aloam_velodyne)/rviz_cfg/aloam_velodyne.rviz优化显示参数:
- 点云大小:0.05
- 颜色方案:Intensity
- 衰减时间:0.1秒
6. 典型问题深度解析
在复现过程中,有几个问题特别值得深入分析,它们反映了Ubuntu 20.04环境下特有的挑战。
6.1 线程安全与Eigen冲突
Ubuntu 20.04默认的Eigen版本(3.3.7)与某些PCL操作存在线程安全问题。典型表现是随机崩溃,错误信息涉及Eigen内部结构。
解决方案:
升级Eigen到最新版本:
git clone https://gitlab.com/libeigen/eigen.git cd eigen mkdir build && cd build cmake .. sudo make install或者在代码中添加线程保护:
#include <mutex> std::mutex mtx; // 在关键Eigen操作前后加锁 mtx.lock(); // Eigen操作 mtx.unlock();
6.2 点云对齐精度问题
在高版本系统中,由于浮点运算优化的差异,点云对齐可能出现细微偏差。这会导致建图时出现"重影"现象。
优化方法:
修改
laserMapping.cpp中的残差计算:// 原始代码 double residual = point_sel.x * norm_x + point_sel.y * norm_y + point_sel.z * norm_z + negative_OA_dot_norm; // 优化后 double residual = (point_sel.x * norm_x + point_sel.y * norm_y + point_sel.z * norm_z + negative_OA_dot_norm) * 1e6; residual = round(residual) / 1e6;调整Ceres求解器参数:
ceres::Solver::Options options; options.linear_solver_type = ceres::DENSE_QR; options.minimizer_progress_to_stdout = false; options.num_threads = 4; options.max_num_iterations = 4;
6.3 内存泄漏排查
长时间运行时,A-Loam可能出现内存缓慢增长的问题。使用Valgrind工具可以准确诊断:
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes rosrun aloam_velodyne alaserOdometry常见的内存问题来源:
- PCL点云对象未正确释放
- Ceres问题实例未销毁
- ROS消息未及时清理
7. 性能优化与扩展思路
当基础功能实现后,可以考虑进一步优化和扩展A-Loam的功能。
7.1 多传感器融合扩展
A-Loam可以相对容易地扩展为多传感器融合系统。以下是添加IMU支持的基本步骤:
创建新的ROS节点订阅IMU话题:
ros::Subscriber subImu = nh.subscribe<sensor_msgs::Imu>("/imu/data", 100, imuHandler);在odometry中融合IMU数据:
void imuHandler(const sensor_msgs::Imu::ConstPtr& imuMsg) { // 转换IMU数据到Eigen格式 Eigen::Quaterniond q(imuMsg->orientation.w, imuMsg->orientation.x, imuMsg->orientation.y, imuMsg->orientation.z); // 更新当前姿态估计 }
7.2 并行计算优化
利用现代CPU的多核特性,可以显著提升处理速度:
特征提取并行化:
#pragma omp parallel for for (size_t i = 0; i < cloudSize; ++i) { // 特征计算代码 }KD-tree构建优化:
pcl::search::KdTree<pcl::PointXYZI>::Ptr kdtree(new pcl::search::KdTree<pcl::PointXYZI>()); kdtree->setNumberOfThreads(4);
7.3 点云预处理流水线
为提高后续处理效率,可以添加预处理步骤:
pcl::PointCloud<pcl::PointXYZI>::Ptr preprocessCloud(const pcl::PointCloud<pcl::PointXYZI>::Ptr& input) { pcl::PointCloud<pcl::PointXYZI>::Ptr output(new pcl::PointCloud<pcl::PointXYZI>); // 1. 去除NaN点 std::vector<int> indices; pcl::removeNaNFromPointCloud(*input, *output, indices); // 2. 统计滤波去除离群点 pcl::StatisticalOutlierRemoval<pcl::PointXYZI> sor; sor.setInputCloud(output); sor.setMeanK(50); sor.setStddevMulThresh(1.0); sor.filter(*output); // 3. 体素滤波降采样 pcl::VoxelGrid<pcl::PointXYZI> vg; vg.setInputCloud(output); vg.setLeafSize(0.1f, 0.1f, 0.1f); vg.filter(*output); return output; }8. 实际项目中的应用建议
将A-Loam应用到实际机器人项目中时,还需要考虑以下几个工程化问题:
8.1 系统集成方案
A-Loam可以很好地集成到ROS导航栈中。典型的集成架构如下:
A-Loam (位姿估计) ↓ robot_localization (传感器融合) ↓ move_base (路径规划) ↓ 底盘控制器8.2 实时性保障措施
为确保实时性能,建议:
- 使用RT内核:
sudo apt install linux-rt - 调整进程优先级:
chrt -f 99 rosrun aloam_velodyne alaserOdometry - 禁用CPU频率调节:
sudo cpupower frequency-set --governor performance
8.3 长期运行稳定性
对于需要长时间运行的场景:
- 添加看门狗机制,监控节点状态
- 实现自动恢复功能
- 定期保存地图和状态
一个简单的看门狗实现:
#!/usr/bin/env python import rospy import subprocess def watchdog(): rospy.init_node('aloam_watchdog') rate = rospy.Rate(1) # 1Hz while not rospy.is_shutdown(): try: # 检查节点是否运行 output = subprocess.check_output(["pgrep", "-f", "alaserOdometry"]) if not output: rospy.logerr("A-Loam crashed, restarting...") subprocess.Popen(["rosrun", "aloam_velodyne", "alaserOdometry"]) except subprocess.CalledProcessError: rospy.logerr("A-Loam not running, starting...") subprocess.Popen(["rosrun", "aloam_velodyne", "alaserOdometry"]) rate.sleep() if __name__ == '__main__': watchdog()经过两个月的反复试验和优化,我的A-Loam系统现在可以在Ubuntu 20.04上稳定运行,处理速度达到实时要求(10Hz),并且内存使用保持平稳。最大的收获是认识到版本兼容性在机器人开发中的重要性——有时候最前沿的工具链并不总是最好的选择,稳定性和可靠性才是工程实践中的首要考虑因素。
