LOAM系列——ALOAM配置、安装、问题解决及VLP16测试效果以及关键记录

本文主要是介绍LOAM系列——ALOAM配置、安装、问题解决及VLP16测试效果以及关键记录,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

LOAM系列——ALOAM配置、安装、问题解决及VLP16测试效果以及关键记录

  • 安装依赖
  • 安装
  • bag包测试
  • 问题解决
    • 问题1
    • 解决1
  • 关键记录
    • A-LOAM主要特点
    • 残差
    • 关键代码

安装依赖

ros
Ceres Solver
PCL

安装

cd ~/catkin_ws/src
git clone https://github.com/HKUST-Aerial-Robotics/A-LOAM.git
cd ../
catkin_make
source ~/catkin_ws/devel/setup.bash

如果你只想编译ALoam功能包,可以在catkin_make后面添加-DCATKIN_WHITELIST_PACKAGES="aloam_velodyne"命令,如下:

catkin_make -DCATKIN_WHITELIST_PACKAGES="aloam_velodyne"

bag包测试

roslaunch aloam_velodyne aloam_velodyne_VLP_16.launch
rosbag play YOUR_DATASET_FOLDER/nsh_indoor_outdoor.bag
测试截图如下:

请添加图片描述

请添加图片描述

请添加图片描述

问题解决

问题1

如果运行
roslaunch aloam_velodyne aloam_velodyne_VLP_16.launch
出现如下错误:
[alaserOdometry-3] process has died [pid 23572, exit code 127, cmd xxxxxxx_ws/devel/lib/aloam_velodyne/alaserOdometry __name:=alaserOdometry __log:=xxxxxxx/.ros/log/76115896-bef6-11eb-962f-94e6f7e52acc/alaserOdometry-3.log].
log file:xxxxxxx/.ros/log/76115896-bef6-11eb-962f-94e6f7e52acc/alaserOdometry-3*.log
[alaserMapping-4] process has died [pid 23574, exit code 127, cmd xxxxxxx_ws/devel/lib/aloam_velodyne/alaserMapping __name:=alaserMapping __log:=xxxxxxx/.ros/log/76115896-bef6-11eb-962f-94e6f7e52acc/alaserMapping-4.log].
log file:xxxxxxx/.ros/log/76115896-bef6-11eb-962f-94e6f7e52acc/alaserMapping-4*.log

解决1

卸载glog后,重新运行launch文件,问题解决!

关键记录

A-LOAM主要特点

1) 去掉了和IMU相关的部分
2) 使用Eigen(四元数)做位姿转换,简化了代码
3) 使用ceres做迭代优化,简化了代码,但降低了效率
代码:https://github.com/HKUST-Aerial-Robotics/A-LOAM

残差

请添加图片描述

关键代码

// Edgepoints 计算点到直线的距离作为误差函数
struct LidarEdgeFactor
{LidarEdgeFactor(Eigen::Vector3d curr_point_, Eigen::Vector3d last_point_a_,Eigen::Vector3d last_point_b_, double s_): curr_point(curr_point_), last_point_a(last_point_a_), last_point_b(last_point_b_), s(s_) {}template <typename T>bool operator()(const T *q, const T *t, T *residual) const // 构建误差函数,点到直线距离,跟论文中一样{Eigen::Matrix<T, 3, 1> cp{T(curr_point.x()), T(curr_point.y()), T(curr_point.z())};Eigen::Matrix<T, 3, 1> lpa{T(last_point_a.x()), T(last_point_a.y()), T(last_point_a.z())};Eigen::Matrix<T, 3, 1> lpb{T(last_point_b.x()), T(last_point_b.y()), T(last_point_b.z())};//Eigen::Quaternion<T> q_last_curr{q[3], T(s) * q[0], T(s) * q[1], T(s) * q[2]};Eigen::Quaternion<T> q_last_curr{q[3], q[0], q[1], q[2]};Eigen::Quaternion<T> q_identity{T(1), T(0), T(0), T(0)};q_last_curr = q_identity.slerp(T(s), q_last_curr); // 根据s进行插值Eigen::Matrix<T, 3, 1> t_last_curr{T(s) * t[0], T(s) * t[1], T(s) * t[2]};Eigen::Matrix<T, 3, 1> lp;lp = q_last_curr * cp + t_last_curr; Eigen::Matrix<T, 3, 1> nu = (lp - lpa).cross(lp - lpb);Eigen::Matrix<T, 3, 1> de = lpa - lpb;residual[0] = nu.x() / de.norm(); residual[1] = nu.y() / de.norm();residual[2] = nu.z() / de.norm();return true;}static ceres::CostFunction *Create(const Eigen::Vector3d curr_point_, const Eigen::Vector3d last_point_a_,const Eigen::Vector3d last_point_b_, const double s_){// 使用ceres的自动求导return (new ceres::AutoDiffCostFunction<LidarEdgeFactor, 3, 4, 3>( //残差维度  第一个参数块维度 第二个参数块维度new LidarEdgeFactor(curr_point_, last_point_a_, last_point_b_, s_)));}Eigen::Vector3d curr_point, last_point_a, last_point_b;double s;
};// Planar Points 计算点到平面的距离作为误差函数
struct LidarPlaneFactor
{LidarPlaneFactor(Eigen::Vector3d curr_point_, Eigen::Vector3d last_point_j_,Eigen::Vector3d last_point_l_, Eigen::Vector3d last_point_m_, double s_): curr_point(curr_point_), last_point_j(last_point_j_), last_point_l(last_point_l_),last_point_m(last_point_m_), s(s_){ljm_norm = (last_point_j - last_point_l).cross(last_point_j - last_point_m); // 得到平面的单位法向量ljm_norm.normalize();}template <typename T>bool operator()(const T *q, const T *t, T *residual) const{Eigen::Matrix<T, 3, 1> cp{T(curr_point.x()), T(curr_point.y()), T(curr_point.z())};Eigen::Matrix<T, 3, 1> lpj{T(last_point_j.x()), T(last_point_j.y()), T(last_point_j.z())};//Eigen::Matrix<T, 3, 1> lpl{T(last_point_l.x()), T(last_point_l.y()), T(last_point_l.z())};//Eigen::Matrix<T, 3, 1> lpm{T(last_point_m.x()), T(last_point_m.y()), T(last_point_m.z())};Eigen::Matrix<T, 3, 1> ljm{T(ljm_norm.x()), T(ljm_norm.y()), T(ljm_norm.z())};//Eigen::Quaternion<T> q_last_curr{q[3], T(s) * q[0], T(s) * q[1], T(s) * q[2]};Eigen::Quaternion<T> q_last_curr{q[3], q[0], q[1], q[2]};Eigen::Quaternion<T> q_identity{T(1), T(0), T(0), T(0)};q_last_curr = q_identity.slerp(T(s), q_last_curr);Eigen::Matrix<T, 3, 1> t_last_curr{T(s) * t[0], T(s) * t[1], T(s) * t[2]};Eigen::Matrix<T, 3, 1> lp;lp = q_last_curr * cp + t_last_curr; residual[0] = (lp - lpj).dot(ljm); return true;}static ceres::CostFunction *Create(const Eigen::Vector3d curr_point_, const Eigen::Vector3d last_point_j_,const Eigen::Vector3d last_point_l_, const Eigen::Vector3d last_point_m_,const double s_){return (new ceres::AutoDiffCostFunction<LidarPlaneFactor, 1, 4, 3>(  //残差维度  第一个参数块维度 第二个参数块维度new LidarPlaneFactor(curr_point_, last_point_j_, last_point_l_, last_point_m_, s_)));}Eigen::Vector3d curr_point, last_point_j, last_point_l, last_point_m;Eigen::Vector3d ljm_norm;double s;
};
......double para_q[4] = {0, 0, 0, 1}; // ceres用来优化时的数组,四元数
double para_t[3] = {0, 0, 0}; // 平移ceres::LossFunction *loss_function = new ceres::HuberLoss(0.1); // 定义一个0.1阈值的huber核函数,优化时抑制离群点用ceres::LocalParameterization *q_parameterization = new ceres::EigenQuaternionParameterization(); 
ceres::Problem::Options problem_options;
ceres::Problem problem(problem_options);
problem.AddParameterBlock(para_q, 4, q_parameterization); 
problem.AddParameterBlock(para_t, 3);......
ceres::CostFunction *cost_function = LidarEdgeFactor::Create(curr_point, last_point_a, last_point_b, s);
problem.AddResidualBlock(cost_function, loss_function, para_q, para_t);......
ceres::CostFunction *cost_function = LidarPlaneFactor::Create(curr_point, last_point_a, last_point_b, last_point_c, s);
problem.AddResidualBlock(cost_function, loss_function, para_q, para_t);......
ceres::Solver::Options options;
options.linear_solver_type = ceres::DENSE_QR;
options.max_num_iterations = 4; // 在非线性优化求解中最多进行几次迭代
options.minimizer_progress_to_stdout = false;
ceres::Solver::Summary summary;
ceres::Solve(options, &problem, &summary);

注:该处的四元数存储顺序是(x,y,z,w)
关于 problem.AddParameterBlock(para_q, 4, q_parameterization); 的理解见其他博客

这篇关于LOAM系列——ALOAM配置、安装、问题解决及VLP16测试效果以及关键记录的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:https://blog.csdn.net/jppdss/article/details/128002986
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/722258

相关文章

windows系统上如何进行maven安装和配置方式

《windows系统上如何进行maven安装和配置方式》:本文主要介绍windows系统上如何进行maven安装和配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不... 目录1. Maven 简介2. maven的下载与安装2.1 下载 Maven2.2 Maven安装2.

Redis指南及6.2.x版本安装过程

《Redis指南及6.2.x版本安装过程》Redis是完全开源免费的,遵守BSD协议,是一个高性能(NOSQL)的key-value数据库,Redis是一个开源的使用ANSIC语言编写、支持网络、... 目录概述Redis特点Redis应用场景缓存缓存分布式会话分布式锁社交网络最新列表Redis各版本介绍旧

解决mysql插入数据锁等待超时报错:Lock wait timeout exceeded;try restarting transaction

《解决mysql插入数据锁等待超时报错:Lockwaittimeoutexceeded;tryrestartingtransaction》:本文主要介绍解决mysql插入数据锁等待超时报... 目录报错信息解决办法1、数据库中执行如下sql2、再到 INNODB_TRX 事务表中查看总结报错信息Lock

Apache 高级配置实战之从连接保持到日志分析的完整指南

《Apache高级配置实战之从连接保持到日志分析的完整指南》本文带你从连接保持优化开始,一路走到访问控制和日志管理,最后用AWStats来分析网站数据,对Apache配置日志分析相关知识感兴趣的朋友... 目录Apache 高级配置实战:从连接保持到日志分析的完整指南前言 一、Apache 连接保持 - 性

MySQL启动报错:InnoDB表空间丢失问题及解决方法

《MySQL启动报错:InnoDB表空间丢失问题及解决方法》在启动MySQL时,遇到了InnoDB:Tablespace5975wasnotfound,该错误表明MySQL在启动过程中无法找到指定的s... 目录mysql 启动报错:InnoDB 表空间丢失问题及解决方法错误分析解决方案1. 启用 inno

apache的commons-pool2原理与使用实践记录

《apache的commons-pool2原理与使用实践记录》ApacheCommonsPool2是一个高效的对象池化框架,通过复用昂贵资源(如数据库连接、线程、网络连接)优化系统性能,这篇文章主... 目录一、核心原理与组件二、使用步骤详解(以数据库连接池为例)三、高级配置与优化四、典型应用场景五、注意事

Linux下安装Anaconda3全过程

《Linux下安装Anaconda3全过程》:本文主要介绍Linux下安装Anaconda3全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录简介环境下载安装一、找到下载好的文件名为Anaconda3-2018.12-linux-x86_64的安装包二、或者通

MySQL 安装配置超完整教程

《MySQL安装配置超完整教程》MySQL是一款广泛使用的开源关系型数据库管理系统(RDBMS),由瑞典MySQLAB公司开发,目前属于Oracle公司旗下产品,:本文主要介绍MySQL安装配置... 目录一、mysql 简介二、下载 MySQL三、安装 MySQL四、配置环境变量五、配置 MySQL5.1

Mybatis Plus JSqlParser解析sql语句及JSqlParser安装步骤

《MybatisPlusJSqlParser解析sql语句及JSqlParser安装步骤》JSqlParser是一个用于解析SQL语句的Java库,它可以将SQL语句解析为一个Java对象树,允许... 目录【一】jsqlParser 是什么【二】JSqlParser 的安装步骤【三】使用场景【1】sql语

Java使用MethodHandle来替代反射,提高性能问题

《Java使用MethodHandle来替代反射,提高性能问题》:本文主要介绍Java使用MethodHandle来替代反射,提高性能问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录一、认识MethodHandle1、简介2、使用方式3、与反射的区别二、示例1、基本使用2、(重要)