GTSAM自定义一元因子编译正常运行触发Eigen断言失败问题排查
问题分析与解决方案
错误原因
报错来自Eigen的断言检查,说明代码中尝试创建编译时固定大小的矩阵(此处为1x1),但传入的维度参数与编译时预设大小不匹配,结合你的自定义因子代码,核心问题大概率出在类型不匹配或函数返回值错误上。
修复步骤
1. 确认funct函数返回值类型
必须保证funct(p, xi)返回double类型,如果它返回的是Vector或其他复合类型,xi * xi * val这类表达式会生成向量,赋值给雅可比矩阵的单个元素时会触发Eigen内部错误。正确实现示例:
double funct(const gtsam::Vector3& p, double x) { // 假设拟合模型为 y = a*x² + b*x + c,p对应[a,b,c] return p(0) * x * x + p(1) * x + p(2); }
2. 修改残差返回的向量类型
将固定大小的gtsam::Vector1替换为动态大小的gtsam::Vector,避免固定/动态向量的类型冲突:
// 替换原返回语句 return (gtsam::Vector(1) << val - yi).finished();
3. 优化雅可比矩阵赋值方式
虽然原逗号初始化写法逻辑正确,但显式指定元素位置可避免潜在的歧义:
if (H) { gtsam::Matrix Jac = gtsam::Matrix::Zero(1, 3); Jac(0, 0) = xi * xi * val; Jac(0, 1) = xi * val; Jac(0, 2) = val; (*H) = Jac; }
4. 简化clone函数实现
原clone函数的类型转换冗余,简化为:
gtsam::NonlinearFactor::shared_ptr clone() const override { return std::make_shared<curvfitFactor>(*this); }
额外检查
- 修正初始值变量名拼写:你代码中写的
intial应为initial,确保它是正确初始化的gtsam::Vector3,例如:gtsam::Vector3 initial(0.0, 0.0, 0.0); - 确认噪声模型的维度与残差维度一致(均为1),例如:
auto noise_model = gtsam::noiseModel::Isotropic::Sigma(1, 0.1);
内容的提问来源于stack exchange,提问作者zhibo zhao
相关产品推荐
相关产品推荐

