直接把配置过程写在这里,适合正在搞机器人导航、却被传感器数据融合搞得头疼的人。如果你已经能让小车动起来、能出里程计和IMU的数据,但发现定位飘得离谱,或者转弯之后位置就歪掉了,那robot_pose_ekf就是你需要的那个东西。它是ROS里一个非常经典的位姿融合包,做的是多传感器扩展卡尔曼滤波的活,把轮式里程计、IMU的角速度和加速度、还有视觉里程计的数据拧在一起,输出一个比单一传感器稳定得多的位姿估计。写得特别直白,不需要你懂深层的滤波理论,配置好输入数据源和坐标系,它自己就能跑。
这篇文章不打算讲高深数学,我直接按实战流程来:先说明这包解决什么问题、里面的设计思路是怎么一回事,然后给出一份能直接抄的配置方案,再走一遍实际运行和排查的过程,最后把我踩过的坑、验证过的调试手段全部列出来。内容针对ROS Melodic和Noetic都适用,用的是ROS原生的标准接口。
1. 核心设计思路:为什么需要单独一个包来融合位姿
1.1 单一传感器到底哪里不够用
先说里程计。轮式里程计短距离内看着还靠谱,直线走个几米误差很小,但你让它原地转几圈再走,或者经过打滑的地面,积分会一路飘,而且这个误差会随时间累积下去,跑久了根本无法直视。IMU呢,短期角速度非常准,但积分的漂移又是个大麻烦,加速度计一抖,姿态里面全是噪声,纯靠它来定位也撑不了多久。
我见过不少刚接触导航的人,在小车上只装轮式里程计,结果做导航的时候误差越来越大,又感觉无从下手。实际上问题不在控制算法,是定位本身就不够稳。单靠轮子,轮胎打滑一次、地上有个小坎颠一下,位置瞬间就多了一个不小的跳变,而IMU不会受打滑影响,它能用角速度帮你修正转向过程中的偏差,两者是天然的互补关系。
robot_pose_ekf的核心思路就是用一个扩展卡尔曼滤波,把不同传感器的输出按协方差矩阵作为可信度权重,融合成一个更可靠的位姿。它不是简单取平均值,而是根据传感器的噪声特性动态调整信任程度,比如你在光滑地面上跑,里程计方差变大,滤波输出就会多参考IMU。
1.2 它的输入、输出和消息结构
这个包接收三类输入消息:
- odometry:轮式里程计,消息类型nav_msgs/Odometry,话题名默认odom,可通过remap改。
- imu_data:IMU数据,消息类型sensor_msgs/Imu,默认话题imu_data,同样可以remap。
- vo:视觉里程计,消息类型nav_msgs/Odometry,默认话题vo。
输出一个融合后的位姿,消息类型也是nav_msgs/Odometry,默认话题robot_pose_ekf/odom_combined,同时也会发布tf变换,把base_footprint(或者你配置的base_frame)关联到odom_combined这个坐标系。
用生活化类比解释,这个融合过程就像三个人同时告诉你车在哪:轮式里程计说“我估摸开了五米,但可能滑了一下”,IMU说“我感觉转了个90度的弯”,视觉里程计说“我看周围环境像是往前挪了三米”。三个人的信息都有噪声、都有各自盲区,扩展卡尔曼滤波做的,就是按每个人的靠谱程度,把三种说法综合成一个最好的估计。
1.3 什么时候必须用它,什么时候可以不用
如果你做的只是纯仿真环境,机器人在Gazebo里没有打滑问题,里程计噪声设置也很理想,那这个包确实不太用得上。但一旦上了实体车,哪怕只是一个几十块钱的MPU6050和普通编码器电机,融合和不融合的差别也极其明显。尤其是做导航时要用到move_base、AMCL这类模块,AMCL依赖的是激光匹配,但机器人空跑和转弯时,激光如果扫到空旷区域,匹配质量会直线下降,这时候多一个融合后的稳定位姿做参考,整个导航体验会完全不同。
有人会问,那直接上robot_localization不就行了,功能更强大。对,这个包胜在简单、轻量、容易配置,代码量也小,也足够稳定。如果你的传感器只有里程计和IMU,robot_pose_ekf完全够用,没必要上更重的方案。
2. 配置前的准备:安装、坐标系与消息检查
2.1 安装与版本选择
不同的ROS发行版里包名有点区别,Melodic和Noetic下一般直接装就好:
sudo apt install ros-noetic-robot-pose-ekf如果你用的是Melodic,就把后面的Noetic换成Melodic。老项目里也可能遇到自己维护的代码分支,建议优先用系统源里的标准版本,稳定省心。
装完之后可以先看它有没有装对位置:
rospack find robot_pose_ekf正常的输出会指向一个目录,比如/opt/ros/noetic/share/robot_pose_ekf,里面有launch、src、include这些目录。如果你用的平台包源里没有,那就得通过git方式拉取源码,自己catkin编译,这个下面会提到要注意的地方。
2.2 坐标系约定:base_footprint到底怎么配
robot_pose_ekf有一个很重要的概念:base_footprint_frame。这个参数告诉滤波器哪个坐标系代表机器人本体在地面的投影。
常见的机器人URDF模型里,底盘坐标系通常叫base_footprint或者base_link。如果机器人的传感器放在不同位置,比如IMU装在底盘上方10厘米处,那么严格来讲需要把IMU的坐标系单独声明,并在上游处理好传感器与机身的tf关系,滤波器本身默认直接以base_footprint作为本体系。对于大多数小车,都是直接把base_footprint作为机器人的基座坐标系,这样配置最省事。
至于output_frame,一般设置成odom_combined,相当于融合后的里程计坐标系。它发布的消息里,位姿的坐标值就是相对于这个output_frame的。换句话说,整个机器人定位的参考系就是这个odom_combined。
2.3 检查上游数据源:发布频率和消息质量
配置之前,先花几分钟确认消息到底来了没有、频率稳不稳定。比如你的里程计话题是/odom,IMU话题是/imu/data,那么用下面两条命令就能看得明明白白:
rostopic hz /odom rostopic hz /imu/data如果IMU的发布频率只有几赫兹,而里程计有几十赫兹,这个时候就要小心了。机器人快速转弯的时候,IMU数据太稀疏的话,滤波器在IMU两次更新之间几乎只能依赖里程计,融合效果会打折。但也不需要矫枉过正,IMU有30Hz以上就基本够用,关键是消息本身要是实时传感器读数,不能是反复发布的模拟数据。
同样要确认消息里的协方差矩阵是否有意义。很多人用rosbag回放数据或者手写模拟节点发消息,协方差矩阵全写0,这件事的影响非常大。EKF的所谓“信任程度”,全靠协方差矩阵体现,全填0等于告诉滤波器这个传感器的数据百分之百可信、完全没有噪声。多个传感器都填0的话,矩阵求解会出问题,融合形同虚设。
导航里有一个类似点:AMCL初始粒子出问题也很影响定位。但这类问题往往是配置上的小细节,和这一样,如果协方差配置不对,后面的功夫全白费,所以检查协方差这一步千万不能省。
3. 手把手配置robot_pose_ekf:launch文件与全部参数说明
3.1 最小可用的launch文件
下面这份launch文件是我平时用的模板,直接把话题重映射到机器人实际的话题名上,改完就能跑:
<launch> <node pkg="robot_pose_ekf" type="robot_pose_ekf" name="robot_pose_ekf"> <param name="output_frame" value="odom_combined"/> <param name="base_footprint_frame" value="base_footprint"/> <param name="freq" value="30.0"/> <param name="sensor_timeout" value="1.0"/> <param name="odom_used" value="true"/> <param name="imu_used" value="true"/> <param name="vo_used" value="false"/> <remap from="odom" to="/odom"/> <remap from="imu_data" to="/imu/data"/> </node> </launch>逐项解释一下关键参数:
- output_frame:融合结果所在的坐标系,也是消息头里的frame_id,一般设成odom_combined。
- base_footprint_frame:机器人本体系,通常base_footprint。
- freq:滤波器的运行频率。不是说发布频率,而是内部预测更新的频率,一般设25到50Hz。设太低会让机器人在数据更新间隔里全靠预测,设太高CPU开销大但精度也上不去,30Hz在一般ARM小车上比较合适。
- sensor_timeout:如果某个传感器超过这个时间没更新,滤波器会认为它失效,暂时把它摘掉,避免拿过期数据硬融。设1秒比较稳妥,太小的话消息偶尔延迟一下就会频繁切换状态。
odom_used、imu_used、vo_used这三个开关,决定哪些传感器参与融合。没有用到的传感器千万别打开,不然节点会一直等这个数据,等到超时后每次都在诊断里报错,还影响其他传感器融合。
3.2 协方差矩阵的准确配置
这个写进launch文件里看不见,体现在上游消息里,但它的重要性值得单独拎出来说。扩展卡尔曼滤波里面有一个核心矩阵R,表示测量噪声,每组传感器数据自带的协方差矩阵扮演的正是这个角色。
ROS里nav_msgs/Odometry消息中,pose部分的covariance是一个36位数组,按行优先存储6x6矩阵,对应x、y、z、roll、pitch、yaw。
对于轮式差速小车,一般做法是,x、y方向给个0.05到0.1的方差,yaw方向给个0.05到0.2的方差。IMU所发布的协方差矩阵,其中orientation部分的roll和pitch方差可以给得比较小,比如0.01,yaw方向则看IMU的性能,一般0.02到0.05。
我们来实际算一下到底填什么值。假如你用的是差速底盘,跑起来后每走1米大概累积2厘米的位置误差,换算成方差就是0.02^2 = 0.0004,但滤波里的方差通常给的比实测值再大一点,因为噪声往往不是高斯分布,再加上打滑之类的影响,我给0.0025(相当于0.05米的误差)。IMU的yaw如果要比较信任,就给0.0016,相当于约2.3度的标准差;不太信就给0.01以上。如果你直接抄别人的值,出来的融合结果也不一定是对的,因为每个机器人的传感器布置和底盘特性都不一样。
实践里最省事的做法是:先给一个比较均衡的初始值,然后跑直线和转弯,观察robot_pose_ekf输出的odom_combined和真实轨迹的偏差。如果融合结果跟着里程计一起飘,就调小里程计方差,或调大IMU的yaw方差权重;如果转向时角度过头,就反过来调。这是一个反复试错的过程。
3.3 用remap连接实际话题名
包默认监听的话题名是odom、imu_data、vo,但绝大多数机器人项目里,主题名都不是这样的,可能是/odom、/imu/data、/camera/odom,这时就必须在launch里做remap。
这里有两个细节值得注意:一是remap的from名字不要加斜杠,即写成odom,而不是/odom,虽然加上也不是完全不可用,但对部分版本不够稳妥。二是同一个launch里,如果别的节点也remap了名字,要小心全局名私有名的差异,确保map到同一个节点参数里。
比较好的验证方法是把launch跑起来之后,打开下面这个命令看rosnode的信息:
rosnode info /robot_pose_ekf输出里会明确显示这个节点订阅和发布的话题。如果看到订阅的是/odom、/imu/data,说明remap生效了。如果订阅的还是默认的odom、imu_data,就去launch文件里检查拼写。
3.4 什么时候打开vo_used
视觉里程计通常只在你的底盘有相机、并且有视觉里程计节点在输出nav_msgs/Odometry消息时才打开。那个视觉里程计节点的输出频率通常没有轮式里程计高,可能10到20Hz,而且它的噪声特性在不同光照、纹理环境下变化很大。展开vo_used之前,先确认视觉里程计的话题输出是否稳定,并且协方差是否有意义。大部分移动机器人场景里,只靠里程计加IMU就已经能获得明显改善,vo更多是锦上添花。
不过如果你的场景有视觉传感器,你倒是可以把vo_used打开,然后把视觉里程计的协方差当成可调参数,多比较几组数据,看看定位是否更稳。实际中这类配置的最大问题不在算法,而是视觉里程计偶尔跳变一下,滤波器如果权值给得太高,跳变也会跟着出来,这个时候适当调大vo的方差,让EKF更保守,反而更稳定。
4. 实际操作流程:从启动到读数据
4.1 启动融合节点并观察话题
假设你的机器人工控机上已经运行了底盘驱动节点和IMU驱动节点,此时启动融合节点:
roslaunch robot_pose_ekf robot_pose_ekf.launch紧接着用rostopic list确认输出话题在不在:
rostopic list | grep robot_pose_ekf正常情况下会看到这样几个话题:
- /robot_pose_ekf/odom_combined
- /robot_pose_ekf/odom(这个取决于版本,有的只输出odom_combined)
然后看它的更新频率是否和freq设置一致:
rostopic hz /robot_pose_ekf/odom_combined如果频率接近30Hz,说明节点本身工作正常。
真正重要的一步是看数据内容是否合理。找一个空地,把机器人前后推一推,把IMU的数据刷一下,再观察odom_combined里面的数值变化。你可以用命令行直接打印消息里位置的x、y和四元数:
rostopic echo /robot_pose_ekf/odom_combined/pose/pose推着机器人直线走半米,x应该在0.5米附近,y方向基本不动。原地转个90度,四元数对应的yaw应该在1.57附近。如果这些基础动作都不对,说明坐标系或者输入数据存在问题,不要急着调滤波器参数,先把消息源头查清楚。
4.2 在tf树里看坐标变换
robot_pose_ekf在融合过程中除了输出odom_combined消息,还会维护一个从output_frame到base_footprint_frame的坐标变换,这个变换很重要,因为AMCL等导航模块经常需要它。
查看方式:
rosrun tf tf_echo odom_combined base_footprint这里会每秒刷新出相对位置和姿态四元数。刚启动时,由于里程计和IMU还没有什么漂移,它应该接近于零,也就是odom_combined和base_footprint基本重合。随着机器人移动,变换值会越来越大。
如果tf树里根本没看到odom_combined到base_footprint这条边,多半是base_footprint_frame配置和URDF里的根坐标系名称不一致。这里有个最常见的失误:URDF里的坐标系叫base_link,但launch里填了base_footprint,节点自然找不到对应的tf原点到base_footprint的变换,于是融合结果就发布不出去消息里的frame_id倒是生成了,但tf关系对不上,下游模块一接收就报警。
解决方式根据项目来:要么把launch里的base_footprint_frame改成base_link,要么在URDF里加入base_footprint到base_link的固定变换。对于地面移动机器人,习惯上是保留base_footprint,在URDF里定义一个虚拟关节,一个fixed joint,把base_link放在它下面。
4.3 从diagnostics里读滤波器的“报表”
robot_pose_ekf有一个非常有用的功能:它会把每个传感器的融合状态通过/diagnostics话题发布出来。这个细节很少有人提,但在调试时价值极高。
rostopic echo /diagnostics你会看到类似这样的信息,以“Wheel Odom”为例,里面包含一个重要字段Update status,如果为OK,说明里程计正常参与融合;如果为Warning,说明传感器在超时边缘,要检查消息是否断流;如果为Error,那就完全没收到数据或数据类型不对,需要立刻排查。
按钮检查法:挨个把里程计节点、IMU节点停掉,再观察diagnostics里的对应状态。刚才还是OK,停掉之后马上就变成Error,说明滤波器与数据源是连通且能感知断流的。如果停掉某个数据源后状态仍然显示OK,说明这个传感器压根没有被有效接入,检查remap或者话题状态。
诊断报表里有几个关键字段:Update rate表示该传感器实际输入频率,hits表示成功融合的次数,misses表示因超时或异常被跳过的次数,这些都可以帮你定位数据质量。比如hits在涨但misses也在涨,说明传感器数据时断时续,要先解决发布端。
4.4 上游数据时间戳问题
多传感器融合最容易踩的坑是时间戳同步。EKF做数据融合前,会对不同传感器的观测做一个时间对齐,差太多就会被丢到misses里。遇到这个问题,先检查传感器驱动是否设置use_sim_time。比如你播放rosbag并用了use_sim_time,而传感器驱动还在用系统时钟,两边对不上,融合直接崩。
所以步骤是:
- 如果实际运行,各节点时间都由系统时钟提供,统一用rospy.Time.now或者机械臂驱动里给出的当前时间戳。
- 如果回放数据,所有节点都要加use_sim_time,并且rosbag本身要按时序格式录制。
另一类问题是IMU驱动复用同一个时间戳或者时间戳重复。比如某些便宜IMU驱动默认时间戳一帧不变,此时滤波器以为所有IMU数据都是一瞬间的数据,但对里程计来说时间是按顺序推进的,时间线就乱了。解决方法是重写IMU驱动里的时间戳,用当前系统时间计算,不要沿用设备里的寄存器时间。
5. 实际调试记录:从“能跑”到“跑得准”
5.1 调试场景:一台双轮差速小车
某开发者手里有台差速底盘小车,底盘驱动节点发布/odom给里程计,IMU驱动发布/imu/data,输出6轴数据。装好robot_pose_ekf并做基础配置后,小车开动,第一次测试就有明显感知:转弯后再直线跑,位置偏移比原来小了不少。
这个时候开发者并没有马上投入导航,而是做了一个简单标定测试:让小车上电后原地转一圈90度,不移动位置,只看odom_combined里yaw的变化。理论上转完应该精确落在1.57附近,实际上第一次测出来是1.79,明显偏大。查下来发现,IMU yaw方向的协方差设得太自信了,滤波器对IMU的yaw过度信任,连里程计在转弯时的合理积分都不太参考。把IMU yaw协方差调大之后,再测试就基本回落到1.6左右。
这个调参思路非常值得参考:先固定机器人不动,用IMU的yaw测试;再推着走直线用里程计测x;再原地转圈看yaw。每个自由度单独验证,不要一上来就开着车跑整个圆环,那样定位不准了都不知道是哪个环节出的问题。
5.2 调试记录:IMU话题正常但融合结果原地不动
之前遇到过一个情况,rostopic hz /imu/data显示IMU正常发布,diagnostics里IMU状态也正常,但机器人不管怎么动,odom_combined都不更新。查了半天,发现问题是车体驱动节点默认发布的是odom→base_link的tf,而没有发odom→base_footprint。robot_pose_ekf想要输出odom_combined到base_footprint的变换,结果它找不到base_footprint,只能在消息里输出,但tf树里没有这条边,底层导航模块拿不到变换自然对不齐。
解决办法是把机器人底盘驱动里的输出坐标系从base_link统一改成base_footprint,或者让launch里base_footprint_frame和底盘驱动里的frame_id保持一致。具体选哪个看项目整体设计,但核心是把“机器人的本体坐标系”这个概念从头到尾统一,不然后面AMCL和move_base也要踩同样的坑。
5.3 数据平滑度对比:融合前后到底差多少
这是很多人喜欢问的一句话:融合后到底好在哪?直接看传感器数据曲线就能发现差别。只开里程计的时候,一旦有个小坎,x方向会出现一个阶跃式的跳变,这是因为轮子打滑导致里程计认为走了更多距离。如果把里程计和IMU同时开,阶跃会被明显平滑,因为IMU的加速度和角速度信息在滤波里抵消了一部分虚假的移动。
从数据上看,单里程计的输出是零阶保持的阶梯增长,融合后则是一条更平滑的曲线,转弯过程中角速度的变化也更连续,对导航算法更友好。AMCL粒子滤波对这种跳变非常敏感,一旦有阶跃,粒子分布会瞬间发散,然后又要花时间收敛回来,直接的表现就是导航过程中机器人会突然抖一下、或者路径规划重新刷新。融合之后这类现象就少很多。
6. 常见问题速查:排错思路与解决方案
| 现象 | 可能原因 | 解决方法 |
|---|---|---|
| 启动节点后没有输出 | 订阅的输入话题接不上 | 用rosnode info看订阅话题名,检查remap |
| 输出频率比freq低很多 | 传感器消息发布频率太低或断流 | 调大sensor_timeout,检查消息发布端 |
| 融合结果跟着里程计飘 | 里程计协方差太小,过度置信 | 调大里程计协方差,或调大IMU融合权重 |
| 转弯时角度偏大 | IMU yaw协方差太小 | 调大IMU yaw协方差,控制在0.01以上 |
| 推车位置不变但odom_combined乱跳 | IMU静止时零漂严重 | 在IMU驱动里做静态校准,等温度稳定后再启 |
| 某个传感器没参与但没报错 | 未正确打开_used开关或话题没remap | 检查launch置位和诊断状态 |
| tf树里缺odom_combined到base_footprint | 包名坐标系与URDF不一致 | 统一base_footprint_frame名字 |
| rosbag回放数据时滤波器不更新 | 没开use_sim_time或者时间戳乱序 | 各节点统一开启use_sim_time,检查bag时间 |
| 滤波器输出正常但AMCL报警 | AMCL的odom_frame_id没设置成odom_combined | 改参数odom_frame_id为odom_combined |
| 包启动后CPU占用过高 | freq设太大 | 降到20至30Hz,对大多数小车够用 |
| 切换地图后定位不稳 | 应该是坐标系设置问题,与nav模块有关联 | 检查map、odom、base_footprint三者之间的tf |
表中最后一条其实牵涉到整个导航框架,不只是robot_pose_ekf的事,但出现坐标系相关的错误时,先从robot_pose_ekf这边的odom_combined出发去查,比直接怀疑AMCL里的参数要高效得多。
7. 一些进阶用法与实际项目的取舍
7.1 如何把robot_pose_ekf嵌入导航框架
在导航过程中,move_base通常需要订阅一个odom话题来获取机器人的里程信息,默认是/odom,同时AMCL需要的odom_frame_id参数默认是odom。如果你用了robot_pose_ekf,需要做两处改动:把move_base和AMCL订阅的odom话题改成/robot_pose_ekf/odom_combined(不同版本可以是/robot_pose_ekf/odom),把odom_frame_id改odom_combined。注意这样改动之后,map→odom_combined这条tf边由AMCL管理,而odom_combined→base_footprint由EKF维护,这正好组成完整链路。
同时需要注意,原来的轮式里程计话题就不应该再被AMCL订阅了,否则会出现两个里程信息来源,定位会乱套。一个项目里,里程计信息来源在任何时刻都只能有一个,EKF的输出在加快速度和稳定性方面有优势,但前提是必须关掉另一路odom的直连。
7.2 与robot_localization的对比:什么场景下换
robot_pose_ekf确实没怎么在维护了,后续更推荐的是robot_localization这个包,里面那个ekf_node功能类似,但更完整也更灵活,支持任意数量的传感器输入,还能直接配GPS、激光匹配信息。不过如果一个项目只需要两路输入,且不打算加GPS等外部绝对位置传感器,robot_pose_ekf依然是个不错的选择,配置简单、依赖少、代码逻辑容易读,排查起来也快。
两者在配置写法上的差别,主要就是robot_pose_ekf通过四个_used参数控制开关,robot_localization通过显式的sensors配置列表来控制,后者更灵活但配置量也更大。选型时看项目体量,一个单底盘小车,robot_pose_ekf完全能把活干漂亮,没必要为了未来的扩展性提前上个复杂度翻倍的框架。
7.3 一个小技巧:可以看到的诊断报表触发验证
如果你不确定配置整没整对,试着在运行时把某个话题停掉再重新发起来。比如不停里程计,只重启一下底盘驱动,观察diagnostics里Wheel Odom的状态从OK变Error再变OK,这过程非常直观。经历过这个验证后,你就知道滤波器确实在独立感知每个传感器的生命状态,而不是只闭上眼睛在那算。
以后再遇到“融合结果看起来不对,但明明所有传感器都正常”的问题,我建议先不要调包,不要动粒子数,先看一眼/diagnostics,再听一遍rostopic hz,把每个通道的频率和状态记下来。很多时候问题不是出在EKF上,而是某个传感器驱动在公开数据时时间戳不稳定,或者协方差矩阵写得根本不符合物理意义。与其瞎调参数,不如先按数据说话,这也是做机器人工程的人最需要培养的习惯。
8. 个人经验与总结
我在实际项目中用robot_pose_ekF配置过好几台车,从几十块钱零件攒的学习小车到更大三轮全向底盘,感受最深的不是算法本身多神奇,而是它对输入数据的要求非常朴素:你只要把规范的话题类型、完整的时间戳、合理的协方差矩阵交给它,它就能做一个比较可靠的融合。反过来,如果数据源头乱糟糟,融合效果只会更乱,还会把问题掩盖起来,让你以为是外部干扰引起的。
斗胆给一点个人建议:配置这类传感器融合包,不要照着网上的launch抄一遍就跑。第一步先自己看一下odom和imu消息内容,确认协方差不是0,确认frame_id和坐标系完全一致,再动手改参数。前面这些基础工作做到位了,后面调参的时间可以缩短一半以上。
如果你只是想把小车导航跑起来,包能正常输出和tf,其实就可以结束配置了。如果你想把定位精度进一步提高,那需要在前面提到的标定上下功夫:单独验证里程计、单独验证IMU、再融合验整体。这个顺序顺着来,比直接调参数要高效得多。
最后分享一个小技巧:大多数时候,IMU的静态零漂在开机后的前30秒是很明显的,如果你开机之后就马上开始融合,位置内容容易出现短时间的漂移。建议上车后等IMU数据稳定了再启动导航,或者在滤波前的数据链路上做一次静态校准。这个动作能让你后面跑线的准确率提升不少,花的时间也就30秒。