3D激光SLAM:ALOAM---后端lasermapping通过Ceres进行帧到地图的位姿优化

简介: 上一篇博客构建了线约束和面约束,添加到了残差模块。[ALOAM:后端 lasermapping构建角点约束与面点约束](https://www.guyuehome.com/38660)本片主要介绍通过ceres构建的约束的CostFuction,及后续的通过Ceres进行位姿优化

@TOC

前言

上一篇博客构建了线约束和面约束,添加到了残差模块。
ALOAM:后端 lasermapping构建角点约束与面点约束

本片主要介绍通过ceres构建的约束的CostFuction,及后续的通过Ceres进行位姿优化

角点的约束添加在这个地方
在这里插入图片描述
这里的CostFunction是通过LidarEdgeFactor自定义的结构体建立的
和前端里程计用的角点约束是一样的在这篇博客中做了分析
原理就是求当前点到a、b点构成的直线的距离作为残差

面点的约束添加在这个地方
在这里插入图片描述
输入参数有:

  • curr_point 当前点
  • norm 归一化得平面法向量
  • negative_OA_dot_norm 法向量模的倒数

代码分析

然后可以分析 这个 LidarPlaneNormFactor 自定义的结构体了

struct LidarPlaneNormFactor
{

    LidarPlaneNormFactor(Eigen::Vector3d curr_point_, Eigen::Vector3d plane_unit_norm_,
                         double negative_OA_dot_norm_) : curr_point(curr_point_), plane_unit_norm(plane_unit_norm_),
                                                         negative_OA_dot_norm(negative_OA_dot_norm_) {}

构造函数,通过生成结构体时的参数,初始化三个变量,和上面的三个是一样的

  • curr_point 当前点
  • plane_unit_norm 归一化得平面法向量
  • negative_OA_dot_norm 法向量模的倒数
    template <typename T>
    bool operator()(const T *q, const T *t, T *residual) const
    {

在前面说了分析Ceres的costfunction重点就是看这个重载()函数
参数模块在前,残差在后

Eigen::Quaternion<T> q_w_curr{q[3], q[0], q[1], q[2]};

把q转成 eigen的形式

Eigen::Matrix<T, 3, 1> t_w_curr{t[0], t[1], t[2]};

把t转成 eigen的形式

Eigen::Matrix<T, 3, 1> cp{T(curr_point.x()), T(curr_point.y()), T(curr_point.z())};

当前点 转成 eigen 的形式

        Eigen::Matrix<T, 3, 1> point_w;//当前点投影到局部地图坐标系下的点
        point_w = q_w_curr * cp + t_w_curr;//将当前点投影到局部地图坐标系下

q_w_curr和t_w_curr是当前帧到局部地图的位姿变换
上面的操作将当前点投影到局部地图上

        Eigen::Matrix<T, 3, 1> norm(T(plane_unit_norm.x()), T(plane_unit_norm.y()), T(plane_unit_norm.z()));
        residual[0] = norm.dot(point_w) + T(negative_OA_dot_norm);//求点到平面的距离

第一行就是把法向量转成eigen的形式
第二行就是求点到平面的距离
dot就是点乘,求解和前面说的一样
在这里插入图片描述
残差可以不取模,因为在ceres里面会平方的。

        return true;
    }

最后重载函数返回true即可

    static ceres::CostFunction *Create(const Eigen::Vector3d curr_point_, const Eigen::Vector3d plane_unit_norm_,
                                       const double negative_OA_dot_norm_)
    {
        return (new ceres::AutoDiffCostFunction<
                LidarPlaneNormFactor, 1, 4, 3>(
            new LidarPlaneNormFactor(curr_point_, plane_unit_norm_, negative_OA_dot_norm_)));
    }

定义一个Creat函数,在里面实现AutoDiffCostFunction的定义,最后返回一个CostFunction

之后可以回到后端处理cpp---lasermapping.cpp中,在前面的博客添加了角点和面点约束,在上面分析了CostFunction,下面就是调用Ceres求解了

                    // 调用Ceres求解
                    TicToc t_solver;
                    ceres::Solver::Options options;
                    options.linear_solver_type = ceres::DENSE_QR;//稠密的问题 用DENSE_QR的求解方式
                    options.max_num_iterations = 4;//最大迭代次数
                    options.minimizer_progress_to_stdout = false;
                    options.check_gradients = false;
                    options.gradient_check_relative_precision = 1e-4;
                    ceres::Solver::Summary summary;
                    ceres::Solve(options, &problem, &summary);//求解
                    printf("mapping solver time %f ms \n", t_solver.toc());//一次ceres求解的时间

就是Ceres的常规操作了, 由于涉及局部地图了,属于稠密问题,所以求解方式使用的DENSE_QR求解。最大迭代次数为4次。在终端打印一次ceres求解的时间。

Ceres优化时间测试

这优化过程中,在终端设置了这些的打印信息
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
分别是:

  • 构建角点和面点约束的时间
  • 一次ceres求解的时间
  • 两次迭代优化用的时间

在这篇ALOAM:gazebo仿真测试场景搭建中搭建了测试场景,下面来测试下Ceres的优化时间是多少

场景是这样的,角点和面点很丰富
在这里插入图片描述

这个是ALOAM出的地图(AGV没动)
在这里插入图片描述
终端打印的数据(一帧)
在这里插入图片描述
局部地图提取的时间是0.12ms
局部地图中的角点数为1061 面点数是682
建立kd-tree的时间为0.20ms
构建角点和面点约束的时间为 1.59ms
一次ceres求解的时间为 1.75ms
两次迭代优化用的时间 为 7.04ms

相关文章
|
2月前
|
缓存 负载均衡 算法
后端架构设计中的优化技巧
【2月更文挑战第9天】 后端架构设计是一个复杂而关键的工作,不仅需要考虑系统的可靠性和扩展性,还需要保证系统的高性能。本文将介绍一些后端架构设计中的优化技巧,包括数据库设计、缓存优化、负载均衡等方面的内容,帮助开发者在设计后端架构时更好地提升系统性能。
35 1
|
3月前
|
NoSQL 算法 Java
后端接口性能优化分析-程序结构优化(中)
后端接口性能优化分析-程序结构优化
38 0
|
3月前
|
缓存 NoSQL Java
后端接口性能优化分析-多线程优化(中)
后端接口性能优化分析-多线程优化
50 0
|
3月前
|
消息中间件 存储 监控
后端接口性能优化分析-多线程优化(上)
后端接口性能优化分析-多线程优化
61 0
|
3月前
|
缓存 数据库 索引
高效后端开发:数据库优化策略详解
数据库优化是后端开发中不可或缺的一部分。本文将从多个方面详细阐述数据库优化策略,包括数据表设计、索引优化、查询性能优化等。通过本文的学习,读者可以了解如何优化数据库,提升后端应用性能和稳定性。
76 1
|
3月前
|
SQL 关系型数据库 MySQL
后端接口性能优化分析-数据库优化(上)
后端接口性能优化分析-数据库优化
115 0
|
3月前
|
NoSQL Java Redis
后端接口性能优化分析-程序结构优化(上)
后端接口性能优化分析-程序结构优化
165 0
|
3月前
|
SQL 关系型数据库 MySQL
后端接口性能优化分析-数据库优化(下)
后端接口性能优化分析-数据库优化
70 1
|
8天前
|
缓存 负载均衡 数据库
优化后端性能:提升Web应用响应速度的关键策略
在当今数字化时代,Web应用的性能对于用户体验至关重要。本文探讨了如何通过优化后端架构和技术手段,提升Web应用的响应速度。从数据库优化、缓存机制到异步处理等多个方面进行了深入分析,并提出了一系列实用的优化策略,以帮助开发者更好地应对日益增长的用户访问量和复杂的业务需求。
12 1
|
10天前
|
SQL 关系型数据库 数据库
【后端面经】【数据库与MySQL】SQL优化:如何发现SQL中的问题?
【4月更文挑战第12天】数据库优化涉及硬件升级、操作系统调整、服务器/引擎优化和SQL优化。SQL优化目标是减少磁盘IO和内存/CPU消耗。`EXPLAIN`命令用于检查SQL执行计划,关注`type`、`possible_keys`、`key`、`rows`和`filtered`字段。设计索引时考虑外键、频繁出现在`where`、`order by`和关联查询中的列,以及区分度高的列。大数据表改结构需谨慎,可能需要停机、低峰期变更或新建表。面试中应准备SQL优化案例,如覆盖索引、优化`order by`、`count`和索引提示。优化分页查询时避免大偏移量,可利用上一批的最大ID进行限制。
36 3