ros2 foxy robot-localization 里程计 imu多传感器融合踩坑指南

前言

Robot_localization是一个基于卡尔曼滤波 ROS的包,可以对里程计 imu gps多种传感器进行数据融合,进而完成机器人的定位的算法。对于不懂卡尔曼滤波的小伙伴,通过修改配置文件就能顺利的使用大佬们造好的轮子,极大的降低了使用多传感器定位的难度。

使用环境:

ubuntu 20.04  ros2  foxy

在线安装robot-localization

sudo apt install ros-foxy-robot-localization

robot_localization中有两个用于融合传感器数据的两种不同的算法节点ekf_localization_nodeukf_localization_node,它们的主要区别在于使用的滤波器算法不同。

运行测试

运行扩展卡尔曼滤波器(EKF):ros2 launch robot_localization ekf.launch.py

报错 退出
[INFO] [launch]: All log files can be found below /home/m/.ros/log/2023-07-14-12-26-37-916195-ubun-10497
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [ekf_node-1]: process started with pid [10499]
[ERROR] [ekf_node-1]: process has died [pid 10499, exit code -11, cmd '/opt/ros/foxy/lib/robot_localization/ekf_node --ros-args -r __node:=ekf_filter_node --params-file /opt/ros/foxy/share/robot_localization/params/ekf.yaml'].
运行无迹卡尔曼滤波器(UKF):ros2 launch robot_localization ukf.launch.py  

报错 退出
[INFO] [launch]: All log files can be found below /home/m/.ros/log/2023-07-14-13-06-00-945589-ubun-11298
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [ukf_node-1]: process started with pid [11300]
[ERROR] [ukf_node-1]: process has died [pid 11300, exit code -11, cmd '/opt/ros/foxy/lib/robot_localization/ukf_node --ros-args -r __node:=ukf_filter_node --params-file /opt/ros/foxy/share/robot_localization/params/ukf.yaml'].

不知道什么原因,我的在线安装的robot-localization工作不正常,一运行就报错退出,有知道原因的小伙伴评论区留言,没办法,只能卸载了用源码安装了。

卸载

sudo apt remove ros-foxy-robot-localization
 

源码安装robot-localization

源文件下载地址:

文件 · foxy-devel · mirrors / cra-ros-pkg / robot_localization · GitCode

根据使用的ros版本选择适合的程序下载(一定要注意下载的版本和本机的ros版本是否配套,不配套编译会过不了的),解压后放在ros工作空间src目录下。

编译

colcon build --packages-select robot_localization 

文件结构

测试运行

m@ubun:~/ros2_ws$ source install/setup.bash
ros2 launch robot_localization ekf.launch.py

能看到这个说明你安装成功了,下面该做的就是修改配置文件,把别人造好的轮子转起来。 

文件目录

先看一下我们关心的2个文件夹 launch params

ekf.launch.py    //扩展卡尔曼滤波器(EKF) 启动程序

ekf.yaml            //扩展卡尔曼滤波器配置文件        

为了不破坏源文件,我们复制一份ekf.launch.py原文件改名

odom_ekf.launch.py  并修改引用的配置文件的名字

# Copyright 2018 Open Source Robotics Foundation, Inc.
# Copyright 2019 Samsung Research America
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from launch import LaunchDescription
from ament_index_python.packages import get_package_share_directory
import launch_ros.actions
import os
import yaml
from launch.substitutions import EnvironmentVariable
import pathlib
import launch.actions
from launch.actions import DeclareLaunchArgument

def generate_launch_description():
    return LaunchDescription([
        launch_ros.actions.Node(
            package='robot_localization',
            executable='ekf_node',
            name='ekf_filter_node',
            output='screen',
            parameters=[os.path.join(get_package_share_directory("robot_localization"), 'params', 'odom_ekf.yaml')], 
#只是这里把ekf.yaml修改成了odom_ekf.yaml 
           ),
])

复制一份ekf.yaml原文件改名

odom_ekf.yaml  翻译备注并修改文件内容

### ekf config file ###
###ekf配置文件###
ekf_filter_node:
    ros__parameters:
# The frequency, in Hz, at which the filter will output a position estimate. Note that the filter will not begin
# computation until it receives at least one message from one of the inputs. It will then run continuously at the
# frequency specified here, regardless of whether it receives more measurements. Defaults to 30 if unspecified.

# 滤波器输出位置估计的频率,单位为Hz。请注意,过滤器在从其中一个输入接收到至少一条消息之前不会开始计算。
# 然后,无论是否接收到更多的测量值,它都将以此处指定的频率连续运行。如果未指定,则默认为30。        
        frequency: 30.0

# The period, in seconds, after which we consider a sensor to have timed out. In this event, we carry out a predict
# cycle on the EKF without correcting it. This parameter can be thought of as the minimum frequency with which the
# filter will generate new output. Defaults to 1 / frequency if not specified.

# 我们认为传感器超时的时间段(以秒为单位)。在这种情况下,我们在EKF上执行一个预测周期,而不进行校正。
# 这个参数可以被认为是滤波器产生新输出的最小频率。如果未指定,则默认为1/频率。
        sensor_timeout: 0.1

# ekf_localization_node and ukf_localization_node both use a 3D omnidirectional motion model. If this parameter is
# set to true, no 3D information will be used in your state estimate. Use this if you are operating in a planar
# environment and want to ignore the effect of small variations in the ground plane that might otherwise be detected
# by, for example, an IMU. Defaults to false if unspecified.

# ekf_localization_node and ukf_localization_node都使用3D全向运动模型。
# 如果此参数设置为true,则不会在状态估计中使用任何三维信息。
# 如果您在平面环境中操作,并且希望忽略地平面中可能检测到的微小变化的影响,请使用此选项
# 例如通过IMU。如果未指定,则默认为false。 
        two_d_mode: true

# Use this parameter to provide an offset to the transform generated by ekf_localization_node. This can be used for
# future dating the transform, which is required for interaction with some other packages. Defaults
<think>好的,我需要回答用户关于里程计误差原因及校正方法的问题。首先,用户引用了多个资料,我需要仔细分析这些引用内容,整理出主要的原因和解决方法。 根据引用[3],里程计的系统误差主要来自三个因素:左右轮直径偏差、轮间距偏差和平均直径偏差。这些会导致直线距离误差和旋转方向误差。引用[4]提到里程计的实际运动与计算存在偏差积累,而引用[5]则提到了通过调整轮子大小和轮距来校准的方法。引用[1]和[2]讨论了使用点云配准来修正误差的方法,说明除了校准,还可以通过外部传感器辅助修正。 接下来,我需要将这些信息结构化。首先列举误差的原因,每个原因下给出对应的解决方法。需要分点说明,保持逻辑清晰。同时,要确保数学公式使用正确的LaTeX格式,比如轮间距偏差的公式用$$...$$,行内变量用$...$。例如,直线误差可以用$\Delta L$,旋转角度误差用$\Delta \theta$。ROS校准步骤中的命令可能需要用代码块展示。 另外,用户要求生成相关问题,我需要根据内容提出三个相关问题,比如误差来源、校准步骤比较、点云配准的作用等。需要确保问题相关且有针对性。 最后,检查引用标识是否正确添加,每个引用对应的来源是否准确。比如,点云配准的方法在引用[1]和[4]都有提及,需要正确标注。同时,确保回答符合中文要求,不使用Markdown,保持口语化但专业。</think>### 里程计误差原因及校正方法 #### 一、误差原因分析 1. **轮径偏差** - **问题**:左右轮实际直径与标称直径存在偏差(例如制造误差或磨损),导致直线运动距离误差[^3]。 - **数学表达**:若左轮实际直径为$d_L$,标称直径为$d_0$,则直线位移误差为$\Delta L = \frac{d_L - d_R}{2} \cdot \theta$($\theta$为轮子转动角度)。 2. **轮间距偏差** - **问题**:左右轮实际间距与标称间距不符,导致旋转运动角度误差。 - **数学表达**:实际轮间距为$b_{\text{real}}$,标称值为$b$,则旋转角度误差为$\Delta \theta = \frac{b_{\text{real}} - b}{b} \cdot \theta_{\text{cmd}}$($\theta_{\text{cmd}}$为指令旋转角度)。 3. **平均直径偏差** - **问题**:两轮平均直径与标称值不符(如轮胎气压不均),同时影响直线和旋转运动精度。 4. **误差累积** - **问题**:里程计通过积分计算位姿,微小误差随时间累积,导致定位漂移[^4]。 --- #### 二、校正方法 1. **参数标定法** - **步骤**: - **直线标定**:控制机器人移动固定距离(如1米),观察里程计输出的$x$值偏差,调整轮径参数直至误差消除[^5]。 - **旋转标定**:控制机器人旋转一周,调整轮间距参数使角度输出接近$2\pi$弧度(约6.28)[^5]。 - **公式**: $$ d_{\text{new}} = d_{\text{old}} \cdot \frac{L_{\text{实际}}}{L_{\text{理论}}} $$ 其中$d_{\text{new}}$为修正后的轮径,$L_{\text{实际}}$为实测位移。 2. **传感器融合法** - **原理**:利用激光雷达、IMU或视觉传感器获取外部参考位姿,通过点云配准算法(如ICP)计算里程计误差并补偿[^1]。 - **示例**: ```python # 伪代码:基于点云配准的误差修正 actual_pose = point_cloud_registration(current_scan, previous_scan) odom_pose = get_odometry() error = calculate_error(actual_pose, odom_pose) apply_correction(error) ``` 3. **系统级补偿模型** - **方法**:建立误差模型(如线性回归或非线性滤波),根据历史误差数据动态修正输出[^3]。 - **模型示例**: $$ \Delta x = k_1 \cdot v + k_2 \cdot \omega $$ 其中$v$为线速度,$\omega$为角速度,$k_1, k_2$为标定系数。 --- #### 三、实际应用案例 - **AGV校准实验**:通过调整轮径和轮间距参数,某AGV目标点位置误差从10cm降至2cm[^2]。 - **ROS机器人校准**:使用`rosrun`命令动态修改轮径和轮距参数,实现实时标定。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值