20.9.24 msckf_vio学习——源码试用问题

本文介绍了在运行msckf_vio时遇到的两个常见问题及解决方案。首先,针对编译时缺少random_numbers的问题,通过重新编译并设置释放模式解决。其次,测试阶段的报错可以通过返回上一级目录并重新尝试解决。最后,提供了使用rosbagplay播放Euroc数据集的步骤。

msckf_vio学习参考文见:
https://zhuanlan.zhihu.com/p/76347723

本文主要解决在运行时的一些报错问题:
1、编译时出现没有random_numbers的问题
博文

2、测试时,
第一个问题:
在这里插入图片描述

解决办法:
见博文
先重新编译,
catkin_make --pkg msckf_vio --cmake-args -DCMAKE_BUILD_TYPE=Release
再配置环境,
source ./devel/setup.bash
就OK了。
roslaunch msckf_vio msckf_vio_euroc.launch

第二个问题:
在这里插入图片描述
解决办法:
返回上一目录 cd
在这里插入图片描述
这里很奇怪,第一次不行,再试一次就OK了。(影响不大)

最后,带数据:
rosbag play ~/data/euroc/MH_04_difficult.bag

<think>好的,我现在需要帮助用户解决Eigen库中的Block函数断言失败问题,以及未声明变量old_rows和old_cols的编译错误。首先,我得仔细分析用户提供的错误信息,然后结合之前的回答和相关引用,给出具体的排查步骤。 首先,用户提到的是Eigen的Block函数断言失败,具体错误信息是startRow >= 0 && blockRows >= 0等条件不满足。根据之前的回答,这类问题通常是由于矩阵操作时的索引或维度不匹配导致的。此外,用户还提到了未声明的变量old_rows和old_cols,这可能是代码中存在拼写错误或者变量作用域问题。 接下来,我需要参考用户提供的站内引用,其中提到在使用g2o时,BlockSolverTraits的维度设置错误可能导致类似的断言失败。这可能提示用户需要检查代码中的维度设置是否正确,特别是在使用类似g2o的块求解器时,或者在使用Eigen的Block操作时是否传入了正确的参数。 用户还特别指出需要针对msckf_vio代码库中的stateAugmentation和errorStateUKF函数进行排查。因此,我需要考虑这两个函数中可能涉及到的矩阵操作,尤其是Block函数的调用是否正确,以及是否存在变量未声明的问题。 首先处理Block断言失败的问题。可能的原因包括: 1. 在调用Block函数时,startRow或startCol为负数,或者blockRows/blockCols为负数。 2. Block操作的范围超出了原矩阵的尺寸,比如startRow + blockRows超过了原矩阵的行数。 3. 动态矩阵在调整大小时未正确指定维度,导致后续操作越界。 针对这些可能的原因,需要用户检查所有使用Block的地方,特别是在stateAugmentation和errorStateUKF函数中的相关代码。例如,是否有地方错误地计算了起始位置或块的大小,或者在调整矩阵大小时未正确设置新的维度。 然后是未声明的变量old_rows和old_cols。这看起来像是用户代码中使用了这两个变量,但未定义它们。需要检查这两个变量是否在函数内部声明,或者是否有拼写错误,比如old_row和old_rows的区别。此外,可能是在某些条件编译或宏定义中遗漏了变量的声明。 接下来,结合之前的回答,用户可能需要使用GDB调试来捕捉断言失败的具体位置,并通过打印变量值来确认参数是否正确。同时,对于编译错误,需要检查代码中的变量声明部分,确保所有使用的变量都已正确声明。 现在,我需要将这些思考整理成结构化的步骤,包括错误分析、调试方法、具体代码检查点以及解决方案。同时,要确保步骤详细,覆盖用户提到的特定函数和可能的问题点。此外,要引用之前提到的GDB调试步骤和维度检查方法,确保用户能够逐步排查问题。 最后,生成相关问题,帮助用户进一步排查可能遇到的类似问题,比如内存对齐、矩阵初始化等。确保回答符合用户要求的格式,正确使用LaTeX,并添加引用标识。</think>--- ### 针对Eigen Block断言失败及未声明变量的排查指南 --- #### 一、Block断言失败问题分析(`startRow >= 0`等条件不满足) ##### 1. **错误根源定位** - **核心原因**:调用`Eigen::Block`时参数越界,例如: - `startRow`或`startCol`为负数 - `blockRows`或`blockCols`超过原矩阵剩余空间 - 动态矩阵未正确初始化导致尺寸计算错误 - **典型场景**:在`msckf_vio`的`stateAugmentation`或`errorStateUKF`中可能涉及以下操作: ```cpp // 错误示例:假设原矩阵行数为5,尝试取第3行开始的3行块 Eigen::MatrixXd matrix(5,5); auto block = matrix.block(3,0,3,5); // 3+3=6 > 5,触发断言失败 ``` ##### 2. **具体排查步骤** **步骤1:定位触发断言的Block调用** - **GDB断点调试**: ```bash # 编译时开启调试符号 catkin_make -DCMAKE_BUILD_TYPE=Debug # 启动GDB调试节点 gdb --args /opt/ros/melodic/lib/nodelet/nodelet standalone msckf_vio/MsckfVioNodelet ``` ```gdb (gdb) break Eigen::Block<XprType, BlockRows, BlockCols, InnerPanel>::Block (gdb) run # 复现错误后查看堆栈 (gdb) backtrace full # 定位用户代码中具体调用位置 ``` **步骤2:验证Block参数合法性** 在代码中添加维度检查逻辑: ```cpp // 示例:检查stateAugmentation中的矩阵操作 Eigen::MatrixXd& state = ...; // 假设为状态矩阵 int startRow = ...; // 从代码逻辑中获取具体值 int blockRows = ...; // 添加断言或日志输出 assert(startRow >= 0 && "startRow must be non-negative"); assert(blockRows <= (state.rows() - startRow) && "Block rows exceed matrix bounds"); ROS_INFO("Block params: start=%d, rows=%d, matrix_size=%ldx%ld", startRow, blockRows, state.rows(), state.cols()); ``` **步骤3:检查动态矩阵初始化** 在`errorStateUKF`中,若涉及协方差矩阵操作: ```cpp // 错误示例:未初始化矩阵直接操作 Eigen::MatrixXd P; // 未指定大小 P.block(0,0,3,3) = ...; // 触发断言 // 修正:显式初始化维度 P.resize(n_states, n_states); // 确保与UKF状态维度一致 ``` --- #### 二、`old_rows`/`old_cols`未声明编译错误处理 ##### 1. **错误原因分析** - **直接原因**:代码中使用了未定义的变量`old_rows`或`old_cols` - **常见场景**: - 在矩阵resize操作中记录原始尺寸: ```cpp matrix.conservativeResize(new_rows, new_cols); // 错误:尝试使用未定义的old_rows if (old_rows > new_rows) { ... } ``` - 变量名拼写错误(如`old_row` vs `old_rows`) ##### 2. **排查与修复** **步骤1:全局搜索变量定义** ```bash # 在代码库中搜索变量声明 grep -rn "old_rows" src/msckf_vio/ grep -rn "old_cols" src/msckf_vio/ ``` **步骤2:检查作用域生命周期** - **情况1**:变量在条件分支中声明: ```cpp if (resize_needed) { int old_rows = matrix.rows(); // 作用域仅限于if块 } // 此处无法访问old_rows ``` **修复**:扩大作用域: ```cpp int old_rows = matrix.rows(); if (resize_needed) { matrix.conservativeResize(...); } ``` **步骤3:补充变量声明** 在需要记录旧尺寸的位置显式声明: ```cpp // 示例:在stateAugmentation中调整协方差矩阵 int old_rows = P.rows(); int old_cols = P.cols(); P.conservativeResize(new_rows, new_cols); // 使用old_rows/old_cols填充新增区域 P.block(old_rows, 0, new_rows-old_rows, old_cols).setZero(); ``` --- #### 三、针对`msckf_vio`的具体代码检查点 ##### 1. **`stateAugmentation`函数** - **关键操作**:状态向量和协方差矩阵扩展 ```cpp // 检查协方差矩阵P的Block操作 P.block<new_state_size, new_state_size>(old_state_size, old_state_size) = ...; // 确保old_state_size + new_state_size <= P.rows() ``` ##### 2. **`errorStateUKF`函数** - **关键操作**:误差状态预测与更新 ```cpp // 检查Jacobian矩阵J的Block赋值 J.block(start_row, start_col, block_rows, block_cols) = ...; // 验证start_row + block_rows <= J.rows() ``` ##### 3. **动态尺寸管理** - **建议**:在关键位置添加尺寸日志: ```cpp ROS_DEBUG_STREAM("Covariance matrix size: " << P.rows() << "x" << P.cols()); ``` --- ### 相关问题 1. 如何在Eigen中安全地操作动态矩阵的子块(避免越界)? 2. 使用`conservativeResize`时如何保留原有数据并初始化新增区域? 3. 如何通过ROS参数服务器动态调整MSKF-VIO的状态维度? 4. 在C++中如何通过编译选项捕获未声明变量? --- [^1]: Eigen的Block操作要求参数严格满足矩阵边界条件,动态尺寸需显式管理。 [^2]: 未声明变量错误通常由作用域限制或拼写错误导致,需结合编译输出定位。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值