011 gtsam/examples/IMUKittiExampleGPS.cpp

news/2024/4/27 10:47:01/文章来源:https://blog.csdn.net/weixin_43848456/article/details/127621673

IMUKittiExampleGPS.cpp

  • 一、预先定义
    • 1.1 symbol
    • 1.2 kitti参数
    • 1.3 imu和gps测量
    • 1.4 加载数据集
  • 二、main函数
    • 2.1 读入数据
    • 2.2 初始变量设置
    • 2.3 噪声和imu预积分参数设置
    • 2.4 iSAM求解器、因子图、Values定义设置
    • 2.5 main loop
      • 2.5.1 添加因子
      • 2.5.2 保存文件
  • 三、mention
    • 3.1 update
      • 3.1.1 gtsam中iSAM求解器的update成员函数

说明:
Example of application of ISAM2 for GPS-aided navigation on the KITTI

一、预先定义

1.1 symbol

using symbol_shorthand::B;  // Bias  (ax,ay,az,gx,gy,gz)
using symbol_shorthand::V;  // Vel   (xdot,ydot,zdot)
using symbol_shorthand::X;  // Pose3 (x,y,z,r,p,y)

1.2 kitti参数

外参数、噪声

struct KittiCalibration {double body_ptx;double body_pty;double body_ptz;double body_prx;double body_pry;double body_prz;double accelerometer_sigma;double gyroscope_sigma;double integration_sigma;double accelerometer_bias_sigma;double gyroscope_bias_sigma;double average_delta_t;
};

1.3 imu和gps测量

struct ImuMeasurement {double time;double dt;Vector3 accelerometer;Vector3 gyroscope;  // omega
};struct GpsMeasurement {double time;Vector3 position;  // x,y,z
};

1.4 加载数据集

void loadKittiData(KittiCalibration& kitti_calibration,vector<ImuMeasurement>& imu_measurements,vector<GpsMeasurement>& gps_measurements) {}

二、main函数

2.1 读入数据

  KittiCalibration kitti_calibration;vector<ImuMeasurement> imu_measurements;vector<GpsMeasurement> gps_measurements;loadKittiData(kitti_calibration, imu_measurements, gps_measurements);

body系 imu系的位姿变换

  Vector6 BodyP =(Vector6() << kitti_calibration.body_ptx, kitti_calibration.body_pty,kitti_calibration.body_ptz, kitti_calibration.body_prx,kitti_calibration.body_pry, kitti_calibration.body_prz).finished();auto body_T_imu = Pose3::Expmap(BodyP);if (!body_T_imu.equals(Pose3(), 1e-5)) {printf("Currently only support IMUinBody is identity, i.e. IMU and body frame ""are the same");exit(-1);}

2.2 初始变量设置

  // Configure different variables// double t_offset = gps_measurements[0].time;size_t first_gps_pose = 1;size_t gps_skip = 10;  // Skip this many GPS measurements each timedouble g = 9.8;auto w_coriolis = Vector3::Zero();  // zero vector

coriolisforcecoriolis\ forcecoriolis force

2.3 噪声和imu预积分参数设置

  // Configure noise modelsauto noise_model_gps = noiseModel::Diagonal::Precisions((Vector6() << Vector3::Constant(0), Vector3::Constant(1.0 / 0.07)).finished());// Set initial conditions for the estimated trajectory// initial pose is the reference frame (navigation frame)auto current_pose_global =Pose3(Rot3(), gps_measurements[first_gps_pose].position);// the vehicle is stationary at the beginning at position 0,0,0Vector3 current_velocity_global = Vector3::Zero();auto current_bias = imuBias::ConstantBias();  // init with zero biasauto sigma_init_x = noiseModel::Diagonal::Precisions((Vector6() << Vector3::Constant(0), Vector3::Constant(1.0)).finished());auto sigma_init_v = noiseModel::Diagonal::Sigmas(Vector3::Constant(1000.0));auto sigma_init_b = noiseModel::Diagonal::Sigmas((Vector6() << Vector3::Constant(0.100), Vector3::Constant(5.00e-05)).finished());// Set IMU preintegration parametersMatrix33 measured_acc_cov =I_3x3 * pow(kitti_calibration.accelerometer_sigma, 2);Matrix33 measured_omega_cov =I_3x3 * pow(kitti_calibration.gyroscope_sigma, 2);// error committed in integrating position from velocitiesMatrix33 integration_error_cov =I_3x3 * pow(kitti_calibration.integration_sigma, 2);auto imu_params = PreintegratedImuMeasurements::Params::MakeSharedU(g);imu_params->accelerometerCovariance =measured_acc_cov;  // acc white noise in continuousimu_params->integrationCovariance =integration_error_cov;  // integration uncertainty continuousimu_params->gyroscopeCovariance =measured_omega_cov;  // gyro white noise in continuousimu_params->omegaCoriolis = w_coriolis;

2.4 iSAM求解器、因子图、Values定义设置

  // Set ISAM2 parameters and create ISAM2 solver objectISAM2Params isam_params;isam_params.factorization = ISAM2Params::CHOLESKY;isam_params.relinearizeSkip = 10;ISAM2 isam(isam_params);// Create the factor graph and values object that will store new factors and// values to add to the incremental graphNonlinearFactorGraph new_factors;Values new_values;  // values storing the initial estimates of new nodes in// the factor graph

2.5 main loop

2.5.1 添加因子

  size_t j = 0;size_t included_imu_measurement_count = 0;for (size_t i = first_gps_pose; i < gps_measurements.size() - 1; i++) {// At each non=IMU measurement we initialize a new node in the graphauto current_pose_key = X(i);auto current_vel_key = V(i);auto current_bias_key = B(i);double t = gps_measurements[i].time;if (i == first_gps_pose) {// Create initial estimate and prior on initial pose, velocity, and biases// 添加关于位姿、速度、bias的初始估计和prior factornew_values.insert(current_pose_key, current_pose_global);new_values.insert(current_vel_key, current_velocity_global);new_values.insert(current_bias_key, current_bias);new_factors.emplace_shared<PriorFactor<Pose3>>(current_pose_key, current_pose_global, sigma_init_x);new_factors.emplace_shared<PriorFactor<Vector3>>(current_vel_key, current_velocity_global, sigma_init_v);new_factors.emplace_shared<PriorFactor<imuBias::ConstantBias>>(current_bias_key, current_bias, sigma_init_b);} else {double t_previous = gps_measurements[i - 1].time;// Summarize IMU data between the previous GPS measurement and now// 两个GPS帧之间进行IMU预积分current_summarized_measurement =std::make_shared<PreintegratedImuMeasurements>(imu_params,current_bias);while (j < imu_measurements.size() && imu_measurements[j].time <= t) {if (imu_measurements[j].time >= t_previous) {current_summarized_measurement->integrateMeasurement(imu_measurements[j].accelerometer, imu_measurements[j].gyroscope,imu_measurements[j].dt);included_imu_measurement_count++;}j++;}// Create IMU factor// 创建IMU Factorauto previous_pose_key = X(i - 1);auto previous_vel_key = V(i - 1);auto previous_bias_key = B(i - 1);new_factors.emplace_shared<ImuFactor>(previous_pose_key, previous_vel_key, current_pose_key,current_vel_key, previous_bias_key, *current_summarized_measurement);// Bias evolution as given in the IMU metadata// 从元数据中获取bias的噪声模型auto sigma_between_b = noiseModel::Diagonal::Sigmas((Vector6() << Vector3::Constant(sqrt(included_imu_measurement_count) *kitti_calibration.accelerometer_bias_sigma),Vector3::Constant(sqrt(included_imu_measurement_count) *kitti_calibration.gyroscope_bias_sigma)).finished());// 利用bias添加BetweenFactornew_factors.emplace_shared<BetweenFactor<imuBias::ConstantBias>>(previous_bias_key, current_bias_key, imuBias::ConstantBias(),sigma_between_b);// Create GPS factor// 构建并向因子图中添加GPS factorauto gps_pose =Pose3(current_pose_global.rotation(), gps_measurements[i].position);if ((i % gps_skip) == 0) {//到达添加GPS因子的周期new_factors.emplace_shared<PriorFactor<Pose3>>(current_pose_key, gps_pose, noise_model_gps);new_values.insert(current_pose_key, gps_pose);printf("############ POSE INCLUDED AT TIME %.6lf ############\n",t);cout << gps_pose.translation();printf("\n\n");} else {new_values.insert(current_pose_key, current_pose_global);//否则只进行变量的添加}// Add initial values for velocity and bias based on the previous estimates// 添加速度和bias变量new_values.insert(current_vel_key, current_velocity_global);new_values.insert(current_bias_key, current_bias);// Update solver// =======================================================================// We accumulate 2*GPSskip GPS measurements before updating the solver a first so that the heading becomes observable.// 在第一次解算之前累积一定时间以便于可观测if (i > (first_gps_pose + 2 * gps_skip)) {printf("############ NEW FACTORS AT TIME %.6lf ############\n",t);new_factors.print();isam.update(new_factors, new_values);//更新解算// Reset the newFactors and newValues list// 重置graphs和Valuesnew_factors.resize(0);new_values.clear();// Extract the result/current estimatesValues result = isam.calculateEstimate();//从isam2求解器中读取值current_pose_global = result.at<Pose3>(current_pose_key);current_velocity_global = result.at<Vector3>(current_vel_key);current_bias = result.at<imuBias::ConstantBias>(current_bias_key);printf("\n############ POSE AT TIME %lf ############\n", t);current_pose_global.print();printf("\n\n");}}}

2.5.2 保存文件

  // Save results to fileprintf("\nWriting results to file...\n");FILE* fp_out = fopen(output_filename.c_str(), "w+");fprintf(fp_out,"#time(s),x(m),y(m),z(m),qx,qy,qz,qw,gt_x(m),gt_y(m),gt_z(m)\n");Values result = isam.calculateEstimate();for (size_t i = first_gps_pose; i < gps_measurements.size() - 1; i++) {auto pose_key = X(i);auto vel_key = V(i);auto bias_key = B(i);auto pose = result.at<Pose3>(pose_key);auto velocity = result.at<Vector3>(vel_key);auto bias = result.at<imuBias::ConstantBias>(bias_key);auto pose_quat = pose.rotation().toQuaternion();auto gps = gps_measurements[i].position;cout << "State at #" << i << endl;cout << "Pose:" << endl << pose << endl;cout << "Velocity:" << endl << velocity << endl;cout << "Bias:" << endl << bias << endl;fprintf(fp_out, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",gps_measurements[i].time, pose.x(), pose.y(), pose.z(),pose_quat.x(), pose_quat.y(), pose_quat.z(), pose_quat.w(), gps(0),gps(1), gps(2));}fclose(fp_out);

三、mention

        isam.update(new_factors, new_values);//更新解算// Reset the newFactors and newValues list// 重置graphs和Valuesnew_factors.resize(0);new_values.clear();// Extract the result/current estimatesValues result = isam.calculateEstimate();//从isam2求解器中读取值

3.1 update

graphs和Values都是const &传递
所以iSAM求解器和

        new_factors.resize(0);new_values.clear();

上述代码不会影响iSAM求解器中的值
isam优化器的重置见lio-sam有例子

    /*** 重置ISAM2优化器*/void resetOptimization(){gtsam::ISAM2Params optParameters;optParameters.relinearizeThreshold = 0.1;optParameters.relinearizeSkip = 1;optimizer = gtsam::ISAM2(optParameters);gtsam::NonlinearFactorGraph newGraphFactors;graphFactors = newGraphFactors;gtsam::Values NewGraphValues;graphValues = NewGraphValues;}

相当于重新定义

3.1.1 gtsam中iSAM求解器的update成员函数

  /*** Add new factors, updating the solution and relinearizing as needed.** Optionally, this function remove existing factors from the system to enable* behaviors such as swapping existing factors with new ones.** Add new measurements, and optionally new variables, to the current system.* This runs a full step of the ISAM2 algorithm, relinearizing and updating* the solution as needed, according to the wildfire and relinearize* thresholds.** @param newFactors The new factors to be added to the system* @param newTheta Initialization points for new variables to be added to the* system. You must include here all new variables occuring in newFactors* (which were not already in the system).  There must not be any variables* here that do not occur in newFactors, and additionally, variables that were* already in the system must not be included here.* @param removeFactorIndices Indices of factors to remove from system* @param force_relinearize Relinearize any variables whose delta magnitude is* sufficiently large (Params::relinearizeThreshold), regardless of the* relinearization interval (Params::relinearizeSkip).* @param constrainedKeys is an optional map of keys to group labels, such* that a variable can be constrained to a particular grouping in the* BayesTree* @param noRelinKeys is an optional set of nonlinear keys that iSAM2 will* hold at a constant linearization point, regardless of the size of the* linear delta* @param extraReelimKeys is an optional set of nonlinear keys that iSAM2 will* re-eliminate, regardless of the size of the linear delta. This allows the* provided keys to be reordered.* @return An ISAM2Result struct containing information about the update*/virtual ISAM2Result update(const NonlinearFactorGraph& newFactors = NonlinearFactorGraph(),const Values& newTheta = Values(),const FactorIndices& removeFactorIndices = FactorIndices(),const boost::optional<FastMap<Key, int> >& constrainedKeys = boost::none,const boost::optional<FastList<Key> >& noRelinKeys = boost::none,const boost::optional<FastList<Key> >& extraReelimKeys = boost::none,bool force_relinearize = false);/*** Add new factors, updating the solution and relinearizing as needed.** Alternative signature of update() (see its documentation above), with all* additional parameters in one structure. This form makes easier to keep* future API/ABI compatibility if parameters change.** @param newFactors The new factors to be added to the system* @param newTheta Initialization points for new variables to be added to the* system. You must include here all new variables occuring in newFactors* (which were not already in the system).  There must not be any variables* here that do not occur in newFactors, and additionally, variables that were* already in the system must not be included here.* @param updateParams Additional parameters to control relinearization,* constrained keys, etc.* @return An ISAM2Result struct containing information about the update* @note No default parameters to avoid ambiguous call errors.*/virtual ISAM2Result update(const NonlinearFactorGraph& newFactors,const Values& newTheta,const ISAM2UpdateParams& updateParams);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_410091.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

推荐一个.Net Core轻量级插件架构

今天给大家推荐一个开源插件架构。在介绍项目之前&#xff0c;我们了解下什么是插件架构&#xff0c;它的用处。 现有的软件开发中&#xff0c;业务越来越复杂&#xff0c;一些大型的项目版本一直在迭代&#xff0c;代码规模越来越大&#xff0c;涉及的人员也越来越多&#xf…

电子江湖里,女攻城狮到底是一种怎样的存在?

关于电子工程师这一角色&#xff0c;女生真的不能胜任么&#xff1f;我觉得不然&#xff01; 虽然说出身电子信息类的女生并不算多&#xff0c;去到职场中就职且能坚持下去的更是少之又少&#xff0c;毕竟理工科嘛&#xff0c;加上真实存在的行业歧视&#xff0c;想要靠近的女生…

学长教你学C-day5-C语言变量与数据类型

小韩是一个学习比较刻苦认真的学生&#xff0c;虽然老师上课进度刚讲到输入输出&#xff0c;但是小韩已经自学到C语言指针部分的内容了。但是进度太快的弊端就是有些东西很难消化吸收&#xff0c;这不就遇到了问题&#xff0c;来请教小刘&#xff1a;“学长&#xff0c;你说这个…

机器学习——聚类分析

文章目录聚类分析K-means算法K-中心算法DBSCAN算法聚类分析 K-means算法 算法简要步骤 随机选取K个样本点&#xff08;不一定来自样本数据&#xff09;作为初始的质心第一次迭代&#xff0c;将所有样本分配到这K个类中 对每个样本计算其到两个聚类中心的欧式距离&#xff08;…

2022年12个最佳WordPress备份插件比较

您是否正在寻找可靠的WordPress备份插件来定期备份您的网站&#xff1f; 备份就像您网站的安全网。每当您的网站因任何原因崩溃时&#xff0c;您都可以快速恢复您的网站。但是您需要确保您的备份具有最新的更改&#xff0c;否则您可能会丢失重要数据。一个好的备份插件将确保您…

艾美捷藻红蛋白RPE化学性质文献参考

艾美捷藻红蛋白RPE背景&#xff1a; R-藻红蛋白是从海藻&#xff08;甘紫菜或高氏肠枝藻&#xff09;分离的藻胆蛋白家族成员。从红藻中分离得到 R- 藻红蛋白(PE)。其主吸收峰位于565nm&#xff0c;次吸收峰位于496nm 和545nm。次级峰的相对显著性在不同种的 R-PE 中差异显著。…

前端开发学习之【Vue】-下

文章目录Vuex1.概述2.使用3.四个 map 方法4.模块化命名空间Vue Router1.SPA2.路由3.基本使用4.多级路由5.路由传参query参数6.命名路由7.路由传参params参数8.路由的props配置9.路由跳转方式10.缓存路由11. activated deactivated生命周期钩子12.路由守卫13.路由器的两种工作模…

极限多标签算法: FastXML 的解析

文章目录前言1.关于极限多标签 (XML: eXtreme multi-label Classification)1.1 流派1.2 评价指标2.FastXML2.1 FastXML的特点2.2 FastXML的局部性2.3 FastXML的拟合目标2.4 通过代码分析FastXML的拟合细节2.4.1 r\mathbf{r}^{}r的优化与拟合2.4.2 δ\deltaδ的优化与拟合 ---- …

知识图谱-命名实体-关系-免费标注工具-快速打标签-Python3

知识图谱-命名实体-关系-免费标注工具-快速打标签-Python3一、功能介绍1、代码文件夹结构2、运行环境3、自定义命名实体、关系模板4、导入文件5、选择自定义实体和关系文件6、文本标注7、撤销和取消标注8、导出和导出并退出系统9、导出文件后解析10、标注规范和KG规范11、系统提…

SQL学习二十、SQL高级特性

约束&#xff08;constraint&#xff09; 管理如何插入或处理数据库数据的规则。 DBMS 通过在数据库表上施加约束来实施引用完整性。 大多数约束是在 表定义中定义的&#xff0c;用 CREATE TABLE 或 ALTER TABLE 语句。 1、主键 &#xff08;PRIMARY KEY&#xff09; 主键是…

AMCL代码详解(六)amcl中的重采样

1.重采样判断 上一章讲述了amcl中如何根据激光观测更新粒子权重&#xff0c;当粒子更新完后amcl会需要根据程序判断是否需要进行重采样。这个判断在粒子观测更新权重后进行判断&#xff0c;代码在amcl_node.cpp中&#xff1a; if(!(resample_count_ % resample_interval_)){ p…

[GYCTF2020]Easyphp

尝试了一下万能密码不行&#xff0c;又到处翻了一下&#xff0c;扫目录结果又有www.zip 审计代码好久&#xff0c;序列化和sql结合的题还是第一次见&#xff0c;太菜了呀&#xff0c;花了很久时间才理解这个题 首先看到update.php&#xff0c;这个文件是最亮眼的&#xff0c;…

javascript 原生类 DOMParser 把 字符串格式的HTML文档源码 转换成 document DOM对象

文章目录IntroQADOMParser 在 console 的使用cheerio 在 node 项目中的使用Reference测试sumIntro 有一天我在写爬虫。 其实也说不上是爬虫&#xff0c;就是打开浏览器上网&#xff0c;觉得页面有些数据挺有意思&#xff0c;就打开开发者工具&#xff0c;在 Network/Console 中…

01.初识C语言1

一、前期准备 1.gitee网址&#xff08;代码托管网站&#xff09;&#xff1a;工作台 - Gitee.com Git教程 - 廖雪峰的官方网站 (liaoxuefeng.com) 用法&#xff1a; 1&#xff09;新建仓库 2&#xff09;随意勾选 3&#xff09;网络仓库构建完成 2.所学知识&#xff1a;计算…

【期末大作业】基于HTML+CSS+JavaScript网上订餐系统(23个页面)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

Jetson Orin 平台单进程采集四路独立video调试记录

1. 概述 现在有4个摄像头, 如何捕获4个摄像头(/dev/video0 - video3)在一个进程像这样: 现在只能捕捉一个相机使用gst-launch如下: gst-launch-1.0 v4l2src device=/dev/video0 ! video/x-raw,width=1280,height=720 ! videoconvert ! video/x-raw,format=I420 ! xvimagesi…

《设计模式:可复用面向对象软件的基础》——行为模式(2)(笔记)

文章目录五、行为模式5.5 MEDIATOR(中介者)1.意图补充部分2.动机3.适用性4.结构5.参与者6.协作7.效果8.实现9.代码示例10.相关模式5.6 MEMENTO ( 备忘录)1.意图2.别名3.动机4.适用性5.结构6.参与者7.协作8.效果9.实现10.代码示例11.相关模式5.7 OBSERVER (观察者)1.意图2.别名3…

21.C++11

C11的官网&#xff1a;C11 - cppreference.com 1.C11简介 在2003年C标准委员会曾经提交了一份技术勘误表(简称TC1)&#xff0c;使得C03这个名字已经取代了C98称为C11之前的最新C标准名称。不过由于TC1主要是对C98标准中的漏洞进行修复&#xff0c;语言的核心部分则没有改动&am…

Java语言实现猜数字小游戏

之前笔者在学习C语言的初级阶段&#xff0c;就已经实现了用C语言简单实现猜数字小游戏&#xff0c;既然笔者最近在学习Java的初级阶段&#xff0c;那么&#xff0c;也应该写一个Java语言实现的猜数字小游戏&#xff01;&#xff01; C语言实现猜数字小游戏&#xff1a;原文链接…

浏览器播放rtsp视频流:4、jsmpeg+go实现局域网下的rtsp视频流web端播放

文章目录1.前言2.资料准备3.兼容性及适用性说明4.jsmpeg架构5.基于以上架构的go方案可行性分析6.编译和结果展示&#xff08;编译坑点&#xff09;7.最后1.前言 之前的rtsp转webrtc的方案存在如下缺陷&#xff1a;1.只支持h264&#xff1b;2.受限于webrtc的理解难度以及搭建tu…