chichengcn / gici-open

GNSS/INS/Camera Integrated Navigation Library
GNU General Public License v3.0
399 stars 112 forks source link

能否模拟EKF #40

Closed AnthonyCR68 closed 3 days ago

AnthonyCR68 commented 2 months ago

池博好,我认为EKF是因子图滑动窗口长度为1时的特例,当我尝试使用RTK_TC进行解算,将estimator中RTK_TC和RTK的option下的max_window_length改为1,如下图所示: image 但是解算开始不久后就会出错,想问一下您我这样修改滑动窗口长度模拟EKF是否正确?如果不正确的话我应该怎么做?另外想问您一下滑动窗口的长度应该如何选择,根据什么样的环境因素可以对其进行修改?

chichengcn commented 1 month ago

虽然理论上讲,两者在一定程度上具有等效性,但是在代码实现上并不等效,GICI-LIB图优化的滑窗长度至少为2,因为代码中默认构建历元间的状态传递残差项,而理论上,滑窗为1的模型,状态传递误差项不存在,而是被涵盖在边缘化因子当中,这将使得实现方式发生很大的变化。

AnthonyCR68 commented 1 month ago

虽然理论上讲,两者在一定程度上具有等效性,但是在代码实现上并不等效,GICI-LIB图优化的滑窗长度至少为2,因为代码中默认构建历元间的状态传递残差项,而理论上,滑窗为1的模型,状态传递误差项不存在,而是被涵盖在边缘化因子当中,这将使得实现方式发生很大的变化。

感谢您的回复,那在代码层面上来说,滑窗为2可以被视为EKF吗?

chichengcn commented 1 month ago

也不可以,这种情况下,图优化维护了两个时刻状态k和k-1,两个时刻的状态通过状态更新因子(如INS预积分因子)相连接,其先验是连接在k-1时刻上的,在优化过程中,k和k-1时刻的状态均会变化。而一般的KF算法只维护一个时刻的状态k,其先验是由k-1时刻predict预测而来的,在优化中,k-1时刻的变量并不会发生改变。

此外,图优化和KF对于先验的维护方式也并不相同,前者是基于边缘化因子,一般是通过舒尔补获得的,并且该先验是以信息矩阵方式存在的;后者是基于先验状态和先验协方差矩阵,而非信息矩阵,且通过卡尔曼估计构造的先验矩阵,与舒尔补构造的先验信息矩阵,也并非完全等价。

当然,如果你说,想要将图优化等效为MSCKF那种多状态卡尔曼约束的形式,那么两者的差异就基本上只在先验构造方式不同上了。但如果讨论如此广义的等效性的话,两者总能通过某种变化达成完全的等价,因为它们都可以从最优估计理论推导而来,只是表达形式不同罢了。

从性能上讲,如果你把滑窗长度设为2、取消掉所有的loss function、将迭代次数设为1,其性能可以尽可能的接近EKF的性能,虽然理论不等价,但性能不会差太多。

AnthonyCR68 commented 1 month ago

也不可以,这种情况下,图优化维护了两个时刻状态k和k-1,两个时刻的状态通过状态更新因子(如INS预积分因子)相连接,其先验是连接在k-1时刻上的,在优化过程中,k和k-1时刻的状态均会变化。而一般的KF算法只维护一个时刻的状态k,其先验是由k-1时刻predict预测而来的,在优化中,k-1时刻的变量并不会发生改变。

此外,图优化和KF对于先验的维护方式也并不相同,前者是基于边缘化因子,一般是通过舒尔补获得的,并且该先验是以信息矩阵方式存在的;后者是基于先验状态和先验协方差矩阵,而非信息矩阵,且通过卡尔曼估计构造的先验矩阵,与舒尔补构造的先验信息矩阵,也并非完全等价。

当然,如果你说,想要将图优化等效为MSCKF那种多状态卡尔曼约束的形式,那么两者的差异就基本上只在先验构造方式不同上了。但如果讨论如此广义的等效性的话,两者总能通过某种变化达成完全的等价,因为它们都可以从最优估计理论推导而来,只是表达形式不同罢了。

从性能上讲,如果你把滑窗长度设为2、取消掉所有的loss function、将迭代次数设为1,其性能可以尽可能的接近EKF的性能,虽然理论不等价,但性能不会差太多。

您的回答太棒了,真的是受益匪浅,感谢!

AnthonyCR68 commented 1 month ago

也不可以,这种情况下,图优化维护了两个时刻状态k和k-1,两个时刻的状态通过状态更新因子(如INS预积分因子)相连接,其先验是连接在k-1时刻上的,在优化过程中,k和k-1时刻的状态均会变化。而一般的KF算法只维护一个时刻的状态k,其先验是由k-1时刻predict预测而来的,在优化中,k-1时刻的变量并不会发生改变。

此外,图优化和KF对于先验的维护方式也并不相同,前者是基于边缘化因子,一般是通过舒尔补获得的,并且该先验是以信息矩阵方式存在的;后者是基于先验状态和先验协方差矩阵,而非信息矩阵,且通过卡尔曼估计构造的先验矩阵,与舒尔补构造的先验信息矩阵,也并非完全等价。

当然,如果你说,想要将图优化等效为MSCKF那种多状态卡尔曼约束的形式,那么两者的差异就基本上只在先验构造方式不同上了。但如果讨论如此广义的等效性的话,两者总能通过某种变化达成完全的等价,因为它们都可以从最优估计理论推导而来,只是表达形式不同罢了。

从性能上讲,如果你把滑窗长度设为2、取消掉所有的loss function、将迭代次数设为1,其性能可以尽可能的接近EKF的性能,虽然理论不等价,但性能不会差太多。

您好,我还有几个问题: 1.请问您我应该如何取消掉loss function呢?是注释掉配置文件中的例如“solver_type:dense_schur”吗?但是cpp文件中构造函数里面也有默认选项,我是不是需要应该在代码中注释这部分内容呢? 2.迭代次数指的是estimator_base_options中的max_iteration吗,还是gnss_imu_initializer_options中的max_iteration?

chichengcn commented 1 month ago
  1. 我们确实没有写取消loss function的选项,不过修改也很容易,把estimator_base.cpp构造函数中的cauchy_loss_function_和huber_loss_function_设为nullptr即可取消所有factor的loss function。
  2. 是estimator_base_options的max_iteration,gnss_imu_initializer_options那个是初始对准用的,设小了优化不出来。
AnthonyCR68 commented 1 month ago
  1. 我们确实没有写取消loss function的选项,不过修改也很容易,把estimator_base.cpp构造函数中的cauchy_loss_function_和huber_loss_function_设为nullptr即可取消所有factor的loss function。
  2. 是estimator_base_options的max_iteration,gnss_imu_initializer_options那个是初始对准用的,设小了优化不出来。

再次感谢,您说的方法很有用!

AnthonyCR68 commented 1 month ago
  1. 我们确实没有写取消loss function的选项,不过修改也很容易,把estimator_base.cpp构造函数中的cauchy_loss_function_和huber_loss_function_设为nullptr即可取消所有factor的loss function。
  2. 是estimator_base_options的max_iteration,gnss_imu_initializer_options那个是初始对准用的,设小了优化不出来。

池博好,上次按照您说的方法改变滑窗大小模拟出EKF来,并对PPP/INS TC和RTK/INS TC的不同滑窗大小下做了性能分析,发现一些问题: 1.按照滑动窗口的理论来说,滑动窗口的长度越大,利用的历史数据信息越多,迭代优化的效果越好,最后的定位精度也越好。但如图所示,PPP/INS TC和RTK/INS TC的定位精度都大概在滑动窗口大小3~5的时候性能达到最优,窗口越大反而定位性能越差 image 想请问您一下如何解释这样的现象? 2.当RTK/INS TC的滑动窗口设置为20、30、50时,定位误差漂到数千甚至数万米,我是将配置文件中的rtk_imu_tc_options和rtk_options中的max_window_length分别都设置为20、30、50。如图: image 想请问您如何解释RTK/INS TC 中的这样一个现象?是不是我的实验分析设置失误导致这样的结果? 3.想问您一下,默认的配置文件中,rtk_imu_tc_options、rtk_options、ppp_imu_tc_options、ppp_options中的默认max_window_length分别设置为10、3、10、10。这样的窗口长度设置是有什么依据吗?如何根据数据集的类型设置窗口长度?在实测中要如何设置窗口长度?窗口的长度选择和哪些因素有关? 最后感谢池博的工作,希望您在工作之余能够抽一点时间解答一下我的疑问,感谢您!

chichengcn commented 2 weeks ago

电脑跑不过来了,注意一下log里“pending”相关字段,如果出现,则性能肯定会降级。跑较长窗口时,应当减小回放速度。 窗口长度就是运算效率和性能之间的权衡,根据实际需求选择。