转载自:https://blog.csdn.net/qq_36170626/article/details/108498533

IMUGPS传感器ESKF融合定位

纷繁中淡定 2020-09-09 18:29:38

1800

收藏 40

分类专栏: 手写VIO 文章标签: slam

版权

IMUGPS传感器ESKF融合定位

文章目录

  • IMUGPS传感器ESKF融合定位
    • 1、代码整体框架说明
    • 2、主要函数介绍
      • 2.1 LocalizationWrapper构造函数
      • 2.2 滤波算法进行预测
      • 2.3 通过GPS位置测量数据更新系统的状态
    • 3. 结果评价
    • 参考文献:


分别在两个终端下运行命令:

rosbag play utbm_robocar_dataset_20180502_noimage1.bag
roslaunch imu_gps_localization imu_gps_localization.launch

1、代码整体框架说明

代码具体结构框架如下图所示:

cpp文件 文件具体实现作用 备注
localization_node.cpp 主函数文件,实现初始化ros,初始化LocalizationWrapper类
localization_wrapper.h LocalizationWrapper类定义,主要声明构造函数、析构函数以及imu回调函数、gps回调函数、打印状态、打印gps数据,把状态格式数据转换成ros话题机制
localization_wrapper.cpp 构造函数中主要是加载参数,保存数据到文件夹下,订阅imugps的话题然后发布融合后的轨迹;析构函数主要是释放空间;imu回调函数主要是读取imu数据,然后对数据进行处理,转变状态发布成ros话题,打印状态;gps回调函数主要是实现读取数据,然后进行处理,最后打印。
imu_gps_localizer.cpp ProcessImuData()函数初始化imu数据,对imu数据进行预测,从ENU坐标系转换到GPS坐标系,发布融合后的状态;ProcessGpsPositionData()函数主要实现初始化数据以及位置的更新。
imu_gps_localizer.h ImuGpsLocalizer类构造函数,声明ProcessImuData()函数,声明ProcessGpsPositionData()函数
initializer.h 初始化类,主要是构造函数,添加imu数据,添加gps数据,计算imu数据到gps数据的旋转矩阵这里参考的是openvins
imu_processor.cpp 滤波融合的预测部分Predict()函数具体实现
imu_processor.h ImuProcessor类主要是滤波融合的预测部分Predict()函数声明
gps_processor.h GpsProcessor类通过GPS位置更新系统的状态UpdateStateByGpsPosition()以及计算残差以及雅可比矩阵和把得到的误差更新状态
base_type.h 主要是imu数据、GPS数据以及系统状态的数据结构
utils.h 主要包括弧度和角度之间的相互转换、ENU坐标系与LLA坐标系的转换以及得到反对称矩阵

2、主要函数介绍

2.1 LocalizationWrapper构造函数

LocalizationWrapper构造函数主要实现加载参数、添加数据保存位置、订阅话题和发布话题

LocalizationWrapper::LocalizationWrapper(ros::NodeHandle& nh) {// Load configs.double acc_noise, gyro_noise, acc_bias_noise, gyro_bias_noise;nh.param("acc_noise",       acc_noise, 1e-2);nh.param("gyro_noise",      gyro_noise, 1e-4);nh.param("acc_bias_noise",  acc_bias_noise, 1e-6);nh.param("gyro_bias_noise", gyro_bias_noise, 1e-8);double x, y, z;nh.param("I_p_Gps_x", x, 0.);nh.param("I_p_Gps_y", y, 0.);nh.param("I_p_Gps_z", z, 0.);const Eigen::Vector3d I_p_Gps(x, y, z);std::string log_folder= "/home/sunshine/catkin_imu_gps_localization/src/imu_gps_localization";ros::param::get("log_folder", log_folder);// Log.file_state_.open(log_folder + "/state.csv");file_gps_.open(log_folder +"/gps.csv");// Initialization imu gps localizer.imu_gps_localizer_ptr_ = std::make_unique<ImuGpsLocalization::ImuGpsLocalizer>(acc_noise, gyro_noise,acc_bias_noise, gyro_bias_noise,I_p_Gps);// Subscribe topics.imu_sub_ = nh.subscribe("/imu/data", 10,  &LocalizationWrapper::ImuCallback, this);//TODO 运行数据集需要修改的地方: gps的话题为/fixgps_position_sub_ = nh.subscribe("/fix", 10,  &LocalizationWrapper::GpsPositionCallback, this);//发布融合后的轨迹state_pub_ = nh.advertise<nav_msgs::Path>("fused_path", 10);
}

2.2 滤波算法进行预测

void ImuProcessor::Predict(const ImuDataPtr last_imu, const ImuDataPtr cur_imu, State* state) {// Time.const double delta_t = cur_imu->timestamp - last_imu->timestamp;const double delta_t2 = delta_t * delta_t;// Set last state.State last_state = *state;// mid_point integration methods// Acc and gyro.const Eigen::Vector3d acc_unbias = 0.5 * (last_imu->acc + cur_imu->acc) - last_state.acc_bias;const Eigen::Vector3d gyro_unbias = 0.5 * (last_imu->gyro + cur_imu->gyro) - last_state.gyro_bias;// Normal state. // Using P58. of "Quaternion kinematics for the error-state Kalman Filter".state->G_p_I = last_state.G_p_I + last_state.G_v_I * delta_t + 0.5 * (last_state.G_R_I * acc_unbias + gravity_) * delta_t2;state->G_v_I = last_state.G_v_I + (last_state.G_R_I * acc_unbias + gravity_) * delta_t;const Eigen::Vector3d delta_angle_axis = gyro_unbias * delta_t;if (delta_angle_axis.norm() > 1e-12) {// std::cout << "norm" << delta_angle_axis.norm() << "normlized"//           << delta_angle_axis.normalized() << std::endl;state->G_R_I = last_state.G_R_I* Eigen::AngleAxisd(delta_angle_axis.norm(),delta_angle_axis.normalized()).toRotationMatrix();}// Error-state. Not needed.// Covariance of the error-state.   Eigen::Matrix<double, 15, 15> Fx = Eigen::Matrix<double, 15, 15>::Identity();Fx.block<3, 3>(0, 3)   = Eigen::Matrix3d::Identity() * delta_t;Fx.block<3, 3>(3, 6)   = - state->G_R_I * GetSkewMatrix(acc_unbias) * delta_t;Fx.block<3, 3>(3, 9)   = - state->G_R_I * delta_t;if (delta_angle_axis.norm() > 1e-12) {Fx.block<3, 3>(6, 6) = Eigen::AngleAxisd(delta_angle_axis.norm(), delta_angle_axis.normalized()).toRotationMatrix().transpose();} else {Fx.block<3, 3>(6, 6).setIdentity();}Fx.block<3, 3>(6, 12)  = - Eigen::Matrix3d::Identity() * delta_t;Eigen::Matrix<double, 15, 12> Fi = Eigen::Matrix<double, 15, 12>::Zero();Fi.block<12, 12>(3, 0) = Eigen::Matrix<double, 12, 12>::Identity();Eigen::Matrix<double, 12, 12> Qi = Eigen::Matrix<double, 12, 12>::Zero();Qi.block<3, 3>(0, 0) = delta_t2 * acc_noise_ * Eigen::Matrix3d::Identity();Qi.block<3, 3>(3, 3) = delta_t2 * gyro_noise_ * Eigen::Matrix3d::Identity();Qi.block<3, 3>(6, 6) = delta_t * acc_bias_noise_ * Eigen::Matrix3d::Identity();Qi.block<3, 3>(9, 9) = delta_t * gyro_bias_noise_ * Eigen::Matrix3d::Identity();//协方差预测state->cov = Fx * last_state.cov * Fx.transpose() + Fi * Qi * Fi.transpose();// Time and imu.state->timestamp = cur_imu->timestamp;state->imu_data_ptr = cur_imu;
}

2.3 通过GPS位置测量数据更新系统的状态

bool GpsProcessor::UpdateStateByGpsPosition(const Eigen::Vector3d& init_lla, const GpsPositionDataPtr gps_data_ptr, State* state) {Eigen::Matrix<double, 3, 15> H;Eigen::Vector3d residual;ComputeJacobianAndResidual(init_lla, gps_data_ptr, *state, &H, &residual);const Eigen::Matrix3d& V = gps_data_ptr->cov;// EKF.const Eigen::MatrixXd& P = state->cov;//P:状态的协方差矩阵;V:gps数据的协方差矩阵;H:误差状态的雅可比矩阵const Eigen::MatrixXd K = P * H.transpose() * (H * P * H.transpose() + V).inverse();const Eigen::VectorXd delta_x = K * residual;// Add delta_x to state.AddDeltaToState(delta_x, state);// Covarance.const Eigen::MatrixXd I_KH = Eigen::Matrix<double, 15, 15>::Identity() - K * H;state->cov = I_KH * P * I_KH.transpose() + K * V * K.transpose();
}
//计算雅克比矩阵以及残差项 P61 Quaternion kinematics for the error-state Kalman filter
void GpsProcessor::ComputeJacobianAndResidual(const Eigen::Vector3d& init_lla,  const GpsPositionDataPtr gps_data, const State& state,Eigen::Matrix<double, 3, 15>* jacobian,Eigen::Vector3d* residual) {const Eigen::Vector3d& G_p_I   = state.G_p_I;const Eigen::Matrix3d& G_R_I   = state.G_R_I;// Convert wgs84 to ENU frame.Eigen::Vector3d G_p_Gps;ConvertLLAToENU(init_lla, gps_data->lla, &G_p_Gps);// Compute residual.*residual = G_p_Gps - (G_p_I + G_R_I * I_p_Gps_);// Compute jacobian.???对哪一项求导?jacobian->setZero();jacobian->block<3, 3>(0, 0)  = Eigen::Matrix3d::Identity();jacobian->block<3, 3>(0, 6)  = - G_R_I * GetSkewMatrix(I_p_Gps_);
}
//添加误差项到状态
void AddDeltaToState(const Eigen::Matrix<double, 15, 1>& delta_x, State* state) {state->G_p_I     += delta_x.block<3, 1>(0, 0);state->G_v_I     += delta_x.block<3, 1>(3, 0);state->acc_bias  += delta_x.block<3, 1>(9, 0);state->gyro_bias += delta_x.block<3, 1>(12, 0);if (delta_x.block<3, 1>(6, 0).norm() > 1e-12) {state->G_R_I *= Eigen::AngleAxisd(delta_x.block<3, 1>(6, 0).norm(), delta_x.block<3, 1>(6, 0).normalized()).toRotationMatrix();}
}

3. 结果评价

参考文献:

IMU & GPS定位 Quaternion kinematics for ESKF[part 3]

EU Long-term Dataset with Multiple Sensors for Autonomous Driving

Quaternion kinematics for the error-state Kalman filter

Woosik Lee, Intermittent GPS-aided VIO: Online Initialization and Calibration.

A General Optimization-based Framework for Global Pose Estimation with Multiple Sensors

A General Optimization-based Framework for Local Odometry Estimation with Multiple Sensors

IMU与GPS传感器ESKF融合定位(转载)相关推荐

  1. GPS定位平台软件,GPS/UWB/WIFI融合定位,提供开发接口

    GPS定位平台软件,GPS定位系统软件,GPS/UWB/WIFI融合定位,提供HTTP/MQTT开发接口. GPS与UWB融合定位 由于GPS只能在室外定位,通过引进UWB技术,可实现室内室外无死角高 ...

  2. IMU与GPS的数据融合

    1.IMU简介 惯性测量单元(Inertial Measurement Unit)通常由3个加速度计和3个陀螺仪组合而成,加速度计和陀螺仪安装在互相垂直的测量轴上,这里可以将其输出看作为三个方向的加速 ...

  3. 动手学无人驾驶(6):基于IMU和GPS数据融合的自车定位

    在上一篇博文<动手学无人驾驶(5):多传感器数据融合>介绍了如何使用Radar和LiDAR数据对自行车进行追踪,这是对汽车外界运动物体进行定位. 对于自动驾驶的汽车来说,有时也需要对自身进 ...

  4. 动手学无人驾驶(5):多传感器数据融合

    本系列的前4篇文章主要介绍了深度学习技术在无人驾驶环境感知中的应用,包括交通标志识别,图像与点云3D目标检测.关于环境感知部分的介绍本系列暂且告一段落,后续如有需要再进行补充. 现在我们开启新的篇章, ...

  5. 无人车传感器 IMU与GPS数据融合进行定位机制

    前言 上一次的分享里,我介绍了GPS的原理(三角定位)及特性(精度.频率),同时也从无人车控制的角度,讨论了为什么仅有GPS无法满足无人车的定位要求. 为了能让无人驾驶系统更高频率地获取定位信息,就必 ...

  6. 多传感器融合定位(4-基于滤波的2融合方法)2-使用仿真数据进行imu-gnss eskf和时变系统下的可观测性分析

    多传感器融合定位(4-基于滤波的2融合方法)2-使用仿真数据进行imu-gnss eskf和时变系统下的可观测性分析 本次作业摘自 张松鹏大哥的优秀作业 代码下载 https://github.com ...

  7. 多传感器融合定位(GPS+Wheel+camera)(1)-读取传感器数据

    多传感器融合定位(GPS+Wheel+camera)(1)-读取传感器数据 文章目录 1.读取Kaist数据集到融合系统中 1.读取Kaist数据集到融合系统中 int main(int argc, ...

  8. 【多传感器融合定位SLAM专栏】前端里程计、IMU预积分、滤波、图优化推导与应用(3)

    本专栏基于深蓝学院<多传感器融合定位>课程基础上进行拓展,对多传感器融合SLAM的学习过程进行记录 文章目录 第三章 惯性导航原理及误差分析 惯性器件 1. 机械陀螺 2. 激光陀螺 ME ...

  9. 《多传感器融合定位》惯性导航基础(二)

    续: <多传感器融合定位>惯性导航基础(一). 惯性导航基础习题二 四.一组对自定义数据进行惯性导航解算验证 1.使用gnss-ins-sim仿真imu运动数据 2.对自定义运动惯性导航解 ...

  10. 多传感器融合定位 第八章 基于滤波的融合方法进阶

    多传感器融合定位 第八章 基于滤波的融合方法进阶 参考博客:深蓝学院-多传感器融合定位-第8章作业 代码下载:https://github.com/kahowang/sensor-fusion-for ...

最新文章

  1. python pip升级 指向不同python版本
  2. JAVASE——File类
  3. JavaScript练习笔记
  4. 自然哲学的数学原理_物理起源点,牛顿《自然哲学的数学原理》
  5. golang开发环境配置及Beego框架安装
  6. [转] @JoinColumn 详解 (javax.persistence.JoinColumn)
  7. C#制作单机版桌面软件(带数据库)
  8. 吴恩达—机器学习的六个核心算法
  9. Linux中执行shell脚本的方法,在Linux中执行Shell脚本的4种方法的总结
  10. 51单片机体系结构初步分析
  11. selenium driver关闭
  12. 理县“有福童享”“牵手圆梦 陪伴成长”关爱折翼天使志愿服务活动
  13. 裁员潮?忍不住偷出阿里P8大舅哥整理的2022年春招内部面试题
  14. CAD -2012软件安装的讲解
  15. 8c SQL手册 六
  16. 【智能优化算法-闪电算法】基于闪电算法求解多目标优化问题附matlab代码
  17. 百度优化客服电话搜索
  18. 【C/C++】C++代码质量检核工具-cppcheck
  19. JavaWeb在线考试系统(简单版)
  20. 仿照写的sina微博的简单爬虫

热门文章

  1. QQ聊天记录生成词云--WordCloud
  2. mysql复制表 复制表结构和数据 改变字段
  3. android mpandroidchart渐变曲线,MPAndroidChart 线条颜色渐变
  4. 在eclipse中编写HDFS的Java程序
  5. Win11更新补丁导致应用程序崩溃错误代码0xc0000135怎么解决?
  6. Windows 2016 出現 0xc0000135 ServerManager.exe 无法启用
  7. 开发一个 app 有多难?
  8. windows资源保护无法启动修复服务器,Windows资源保护无法启动修复服务 | MOS86
  9. JavaWeb如何判断账户密码
  10. 温度传感器—LM75