热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

cartographer中的pose_extrapolator梳理

本文主要目的有二:弄清extrapolator的涉及到的运动学变量;弄清odom、imu、scanmatch对应的数据在poseextrapolato

本文主要目的有:

  1. 弄清extrapolator的涉及到的运动学变量;
  2. 弄清odom、imu、scan match对应的数据在pose extrapolator中的对应作用。

PoseExtrapolator::ExtrapolatePose

推算当前给定时间 time 对应的位姿(平移+旋转)。包括调用PoseExtrapolator::ExtrapolateTranslation来计算平移增量以及调用PoseExtrapolator::ExtrapolateRotation来计算旋转增量

transform::Rigid3d PoseExtrapolator::ExtrapolatePose(const common::Time time) {const TimedPose& newest_timed_pose = timed_pose_queue_.back();CHECK_GE(time, newest_timed_pose.time);if (cached_extrapolated_pose_.time != time) {const Eigen::Vector3d translation =//↓当前时刻到newest_timed_pose.time之间的位移。 ↓newest_timed_pose.time时刻的位置ExtrapolateTranslation(time) + newest_timed_pose.pose.translation();const Eigen::Quaterniond rotation = //旋转量使用四元数表示newest_timed_pose.pose.rotation() * //上一时刻的姿态四元数ExtrapolateRotation(time, extrapolation_imu_tracker_.get());//缓存的位姿:包括平移和旋转。 cached_extrapolated_pose_ =TimedPose{time, transform::Rigid3d{translation, rotation}};}return cached_extrapolated_pose_.pose;
}

PoseExtrapolator::ExtrapolateTranslation
主要就是odometry_data_队列的值足够的时候,使用odom推算的linear_velocity_线性速度;否则根据历史节点的位姿来推算linear_velocity_线性速度。然后根据当前时间和位姿队列中最新位姿的时间差,计算这段时间内的平移增量

Eigen::Vector3d PoseExtrapolator::ExtrapolateTranslation(common::Time time) {const TimedPose& newest_timed_pose &#61; timed_pose_queue_.back();const double extrapolation_delta &#61;common::ToSeconds(time - newest_timed_pose.time);if (odometry_data_.size() < 2) {return extrapolation_delta * linear_velocity_from_poses_;}return extrapolation_delta * linear_velocity_from_odometry_;
}

PoseExtrapolator::ExtrapolateRotation

Eigen::Quaterniond PoseExtrapolator::ExtrapolateRotation(const common::Time time, ImuTracker* const imu_tracker) const {CHECK_GE(time, imu_tracker->time());AdvanceImuTracker(time, imu_tracker);const Eigen::Quaterniond last_orientation &#61; imu_tracker_->orientation();return last_orientation.inverse() * imu_tracker->orientation();
}

姿态外推&#xff0c;需要调用函数AdvanceImuTracker&#xff08;更新imu跟踪器&#xff09;。

void PoseExtrapolator::AdvanceImuTracker(const common::Time time,ImuTracker* const imu_tracker) const {CHECK_GE(time, imu_tracker->time());if (imu_data_.empty() || time < imu_data_.front().time) {// There is no IMU data until &#39;time&#39;, so we advance the ImuTracker and use// the angular velocities from poses and fake gravity to help 2D stability.//在time时间之前都没有imu数据&#xff0c;这时候需要使用从历史位姿中估计的角速度和假的重力加速度来帮助构建一个稳定的imu跟踪器。imu_tracker->Advance(time);imu_tracker->AddImuLinearAccelerationObservation(Eigen::Vector3d::UnitZ());imu_tracker->AddImuAngularVelocityObservation(odometry_data_.size() < 2 ? angular_velocity_from_poses_: angular_velocity_from_odometry_);LOG(INFO) << "There is no IMU data until &#39;time&#39;: "<< time << " s" << "odometry_data_.size() is: "<<odometry_data_.size();return;}//当前的imu跟踪器的数据 早于 imu_data_队列中的起始时间if (imu_tracker->time() < imu_data_.front().time) {// Advance to the beginning of &#39;imu_data_&#39;.//将imu跟踪器更新到 imu_data_队列中的起始时间imu_tracker->Advance(imu_data_.front().time);}auto it &#61; std::lower_bound(imu_data_.begin(), imu_data_.end(), imu_tracker->time(),[](const sensor::ImuData& imu_data, const common::Time& time) {return imu_data.time < time;});while (it !&#61; imu_data_.end() && it->time < time) { //迭代递推到当前时间timeimu_tracker->Advance(it->time);imu_tracker->AddImuLinearAccelerationObservation(it->linear_acceleration);imu_tracker->AddImuAngularVelocityObservation(it->angular_velocity);&#43;&#43;it;}imu_tracker->Advance(time);
}


推荐阅读
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 合并列值-合并为一列问题需求:createtabletab(Aint,Bint,Cint)inserttabselect1,2,3unionallsel ... [详细]
  • 本文介绍了在Android开发中使用软引用和弱引用的应用。如果一个对象只具有软引用,那么只有在内存不够的情况下才会被回收,可以用来实现内存敏感的高速缓存;而如果一个对象只具有弱引用,不管内存是否足够,都会被垃圾回收器回收。软引用和弱引用还可以与引用队列联合使用,当被引用的对象被回收时,会将引用加入到关联的引用队列中。软引用和弱引用的根本区别在于生命周期的长短,弱引用的对象可能随时被回收,而软引用的对象只有在内存不够时才会被回收。 ... [详细]
  • DSP中cmd文件的命令文件组成及其作用
    本文介绍了DSP中cmd文件的命令文件的组成和作用,包括链接器配置文件的存放链接器配置信息、命令文件的组成、MEMORY和SECTIONS两个伪指令的使用、CMD分配ROM和RAM空间的目的以及MEMORY指定芯片的ROM和RAM大小和划分区间的方法。同时强调了根据不同芯片进行修改的必要性,以适应不同芯片的存储用户程序的需求。 ... [详细]
  • 本文介绍了一道经典的状态压缩题目——关灯问题2,并提供了解决该问题的算法思路。通过使用二进制表示灯的状态,并枚举所有可能的状态,可以求解出最少按按钮的次数,从而将所有灯关掉。本文还对状压和位运算进行了解释,并指出了该方法的适用性和局限性。 ... [详细]
  • Todayatworksomeonetriedtoconvincemethat:今天在工作中有人试图说服我:{$obj->getTableInfo()}isfine ... [详细]
  • STL迭代器的种类及其功能介绍
    本文介绍了标准模板库(STL)定义的五种迭代器的种类和功能。通过图表展示了这几种迭代器之间的关系,并详细描述了各个迭代器的功能和使用方法。其中,输入迭代器用于从容器中读取元素,输出迭代器用于向容器中写入元素,正向迭代器是输入迭代器和输出迭代器的组合。本文的目的是帮助读者更好地理解STL迭代器的使用方法和特点。 ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
  • 本文介绍了如何使用n3-charts绘制以日期为x轴的数据,并提供了相应的代码示例。通过设置x轴的类型为日期,可以实现对日期数据的正确显示和处理。同时,还介绍了如何设置y轴的类型和其他相关参数。通过本文的学习,读者可以掌握使用n3-charts绘制日期数据的方法。 ... [详细]
  • Spring框架《一》简介
    Spring框架《一》1.Spring概述1.1简介1.2Spring模板二、IOC容器和Bean1.IOC和DI简介2.三种通过类型获取bean3.给bean的属性赋值3.1依赖 ... [详细]
  • 深入理解Java虚拟机的并发编程与性能优化
    本文主要介绍了Java内存模型与线程的相关概念,探讨了并发编程在服务端应用中的重要性。同时,介绍了Java语言和虚拟机提供的工具,帮助开发人员处理并发方面的问题,提高程序的并发能力和性能优化。文章指出,充分利用计算机处理器的能力和协调线程之间的并发操作是提高服务端程序性能的关键。 ... [详细]
author-avatar
哀公家园_678
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有