发布日期:2024-04-29 04:08 浏览次数:次
背景:在SLAM中,很多问题都是在求解Translation(包含旋转和平移量),因此这里以其为代表,来分析使用ceres如何对其近求导。
1. ceres::Solver::Summary summary
优化中的产生的各种信息。
2. ceres::Solver::Options options;
对优化器进行配置。例如使用多少个核来进行计算,最大迭代次数等。
3. ceres::Solve(options, &problem, &summary)
4. ceres::Problem
最后则是如何构建整个优化问题。这里需要详细分析。
4.1 首先是cost function的构建
那么,cost function的详细定义如下:
这里面需要注意的主要有三点:
? 这个地方比较重要的地方有两个;
? ①自动求导的构造函数输入,就是自定义的cost function的实例的指针。这个具体在下一点讲。
? ②模板参数<Edge2EdgeError, 1,4,3>:
? 第一个是cost function。
? 第二个是残差的维度
? 第三个是待优化参数的维度。这里是4,表示旋转的四元数表示。
? 第四个也是待优化参数的维度。这里是3,表示平移量的xyz。
? 也可以有56789个,ceres内部根据传入参数的数量进行了重载。
? 但是,不管有多少个待优化的参数,这里的4,3的顺序是和后面的AddResidualBlock()的输入对应的!
? 在实例化这一个cost function的时候,把就按残差所需要的数据进行了传入。
第二点:实现对operator()的重载构造仿函数。
在对符号进行重载的函数里,实现了对残差的计算。
4.2 对整个问题也就是problem添加AddResidualBlock();也即如下:
注意,这里的AddResidualBlock(T1,T2,T3,T4)一共输入了四个参数。
其中,T1是cost的
? T2是损失函数,也即是核函数。
? T3是前面所强调的四元数
? T4是平移量。
需要注意的是,这里的待优化参数的传入是变量的地址!
上面所举的例子的分析是使用的自动求导。实际上ceres还有其他的求导方式。他们分别是:
1.自动求导(Automatic Differentiation)
2.解析求导(Analytic Differentiation)
3.数值求导(numeric Differentiation)
下面我们分别对这三种求导方式进行对比分析
2.1 自动求导(Automatic Differentiation)
2.2 数值求导(numeric Differentiation)
注意,和自动求导相比,唯一的区别在于模板参数里多了一个
所以,在ceres的官方文档里对这两种求导方法进行了对比:
简单来说,就是自动求导又快又好。数值求导又慢又不稳定。
2.3 解析求导(Analytic Differentiation)
但是不是什么情况下都是可以使用自动求导的。在某些情况下,使用闭式求解会更快更有效率,而不是拘泥于自动求导的链式求导规则。
注意,解析求导和之前两个不一样的地方有两点:
1.最后CostFunction* 指向的直接就是自己定义的残差函数
2.自己定义的残差函数需要继承ceres自己定义的:
这里面的模板参数定义了残差和待优化变量的维度。
同时没有了之前的仿函数,转而对进行了继承和重载。
输入的参数有
:雅克比矩阵,二维矩阵
这里的输入的参数的维度该如何理解呢?为什么直接就是二维矩阵了呢?
留待下文分析!