使用robot_localization融合IMU数据和GPS数据

前言

现在我们要将 GPS 数据添加到车轮里程计和 IMU 数据中。这三个测量将通过使用 robots_localization 包进行融合。GPS 提供机器人相对于地球框架的位置。这是一个优点。然而,它也有一些缺点,包括:

  • 误差较大。然而,特殊类型的 GPS(例如 DGPS 和 RTK)误差要小得多,但价格昂贵。
  • 仅提供位置。GPS 本身不提供任何有关方向的信息。

当与车轮里程计和IMU数据融合时,可以克服GPS的大误差。

这篇博客将简单介绍下如何将 GPS 数据与车轮里程计和 IMU 数据融合。

数据下载

链接: https://pan.baidu.com/s/1zSXyNhMNQdaFlDFziDse1Q 密码: 6j6u

创建 robots_localization 包

cd ~/catkin_ws/src
catkin_create_pkg gps2odom
cd gps2odom
mkdir launch
mkdir yaml

这将创建具有以下结构的新包:

my_gps_localization:
  |--launch
  |--yaml
  |--package.xml
  |--CMakeLists.txt

创建gps2odom.launch

<launch>

    <rosparam file="$(find gps2odom)/yaml/gps2odom.yaml" command="load" />

    <node pkg="tf" type="static_transform_publisher" name="static_transform_publisher" 
	  args="0 0 0 0 0 0 1  /base_link /imu_link 10" />

    <!-- EKF GPS-->
    <node pkg="robot_localization" type="ekf_localization_node" name="ekf_gps" respawn="true">
        <remap from="odometry/filtered" to="odom" />
    </node>

    <!-- Navsat -->
    <node pkg="robot_localization" type="navsat_transform_node" name="navsat" respawn="true">
        <remap from="imu/data" to="imu_correct" />
        <remap from="gps/fix" to="gps/fix" />
        <remap from="odometry/filtered" to="odom" />
    </node>

</launch>

创建配置文件gps2odom.yaml

# Navsat (convert GPS coordinates to Cartesian)
navsat:
  frequency: 50
  wait_for_datum: false
  delay: 0.0
  magnetic_declination_radians: 0
  yaw_offset: 0
  zero_altitude: true
  broadcast_utm_transform: false
  broadcast_utm_transform_as_parent_frame: false
  publish_filtered_gps: false

# EKF for Navsat
ekf_gps:
  publish_tf: true
  map_frame: map
  odom_frame: odom
  base_link_frame: base_link
  world_frame: odom

  frequency: 50
  two_d_mode: false
  sensor_timeout: 0.01
  # -------------------------------------
  # External IMU:
  # -------------------------------------
  imu0: imu_correct
  # make sure the input is aligned with ROS REP105. "imu_correct" is manually transformed by myself. EKF can also transform the data using tf between your imu and base_link
  imu0_config: [false, false, false,
                true,  true,  true,
                false, false, false,
                false, false, true,
                true,  true,  true]
  imu0_differential: false
  imu0_queue_size: 50 
  imu0_remove_gravitational_acceleration: true
  # -------------------------------------
  # Odometry (From Navsat):
  # -------------------------------------
  odom0: odometry/gps
  odom0_config: [true,  true,  true,
                 false, false, false,
                 false, false, false,
                 false, false, false,
                 false, false, false]
  odom0_differential: false
  odom0_queue_size: 10

  #                            x     y     z     r     p     y   x_dot  y_dot  z_dot  r_dot p_dot y_dot x_ddot y_ddot z_ddot
  process_noise_covariance: [  1.0,  0,    0,    0,    0,    0,    0,     0,     0,     0,    0,    0,    0,    0,      0,
                               0,    1.0,  0,    0,    0,    0,    0,     0,     0,     0,    0,    0,    0,    0,      0,
                               0,    0,    10.0, 0,    0,    0,    0,     0,     0,     0,    0,    0,    0,    0,      0,
                               0,    0,    0,    0.03, 0,    0,    0,     0,     0,     0,    0,    0,    0,    0,      0,
                               0,    0,    0,    0,    0.03, 0,    0,     0,     0,     0,    0,    0,    0,    0,      0,
                               0,    0,    0,    0,    0,    0.1,  0,     0,     0,     0,    0,    0,    0,    0,      0,
                               0,    0,    0,    0,    0,    0,    0.25,  0,     0,     0,    0,    0,    0,    0,      0,
                               0,    0,    0,    0,    0,    0,    0,     0.25,  0,     0,    0,    0,    0,    0,      0,
                               0,    0,    0,    0,    0,    0,    0,     0,     0.04,  0,    0,    0,    0,    0,      0,
                               0,    0,    0,    0,    0,    0,    0,     0,     0,     0.01, 0,    0,    0,    0,      0,
                               0,    0,    0,    0,    0,    0,    0,     0,     0,     0,    0.01, 0,    0,    0,      0,
                               0,    0,    0,    0,    0,    0,    0,     0,     0,     0,    0,    0.5,  0,    0,      0,
                               0,    0,    0,    0,    0,    0,    0,     0,     0,     0,    0,    0,    0.01, 0,      0,
                               0,    0,    0,    0,    0,    0,    0,     0,     0,     0,    0,    0,    0,    0.01,   0,
                               0,    0,    0,    0,    0,    0,    0,     0,     0,     0,    0,    0,    0,    0,      0.015]


配置文件中参数说明

**frequency**:滤波器产生状态估计的实值频率(以 Hz 为单位)。

**two_d_mode**:如果您的机器人在平面环境中运行,并且您愿意忽略地面的细微变化(由 IMU 报告),则将其设置为 true。它将融合所有 3D 变量(Z、横滚、俯仰以及它们各自的速度和加速度)的 0 值。这可以防止这些值的协方差爆炸,同时确保机器人的状态估计保持固定在 XY 平面上。

**publish_tf**:如果为 true,状态估计节点会将 world_frame 参数指定的帧的变换发布到其子节点。如果world_frame与map_frame相同,它将发布从map_frame到odom_frame的变换,如果world_frame与odom_frame相同,它将发布从odom_frame到base_link_frame的变换。默认为 true。

**Coordinate frame specification**:

- “map_frame”、“odom_frame”和“base_link_frame”的默认值分别是“map”、“odom”和“base_link”。“world_frame”参数默认为“odom_frame”的值。
- 如果您的系统没有map_frame,只需删除或注释它,并确保“world_frame”设置为“odom_frame”的值。
- 如果您仅融合连续位置数据,例如车轮编码器里程计、视觉里程计或 IMU 数据,请将“world_frame”设置为“odom_frame”的值。这是 robots_localization 中状态估计节点的默认行为,也是它最常见的用途。这不是我们的情况,因为我们还使用不连续的 GPS 数据。
- 如果您正在融合受离散跳跃影响的全球绝对位置数据(例如,GPS 或来自地标观测的位置更新),则将“world_frame”设置为“map_frame”的值。还要确保其他东西正在生成 odom->base_link 变换。这甚至可以是 robots_localization 状态估计节点的另一个实例。但是,该实例不应融合全局数据。这是我们的案例,因为我们使用 GPS 数据。

[sensor]:对于每个传感器,您需要根据传感器发布的主题定义此参数。

[sensor]_config:由布尔 5×3 矩阵定义如下:

```bash
[  X,         Y,        Z,
  Roll,     Pitch,     Yaw,
  dX/dt,    dY/dt,    dZ/dt,
 dRoll/dt, dPitch/dt, dYaw/dt,
 d2X/dt2,   d2Y/dt2,  d2Z/dt2]

[sensor]_ Differential:使用此参数,您可以指定是否应对位姿变量进行差分积分。如果给定值设置为 true,则对于相关传感器在时间 t 的测量值,我们首先减去时间 t−1 的测量值,并将结果值转换为速度。如果您的机器人有两个绝对位姿信息源(例如,来自里程计和 IMU 的偏航测量),则此设置特别有用。在这种情况下,如果输入源的方差配置不正确,这些测量结果可能会彼此不同步并导致滤波器振荡,但通过对其中一个或两者进行差分积分,我们可以避免这种情况。

如果将“navsat_transform”节点的输出与 中的任何状态估计节点融合 robot_localization,则应确保 该输入odomN_differential 的设置(其中 N 是从 0 开始的数字)为 false 。

process_noise_covariance:通常表示为 Q,用于对滤波算法的预测阶段的不确定性进行建模。对角线上的值是状态向量的方差,其中包括姿态,然后是速度,然后是线性加速度。它可能很难调整,并且已作为参数公开以便于定制。该参数可以单独保留,但通过调整它您将获得更好的结果。一般来说,Q 值相对于输入消息中给定变量的方差越大,滤波器收敛到测量值的速度就越快。

initial_estimate_covariance:此参数允许设置状态估计协方差矩阵的初始值,这将影响滤波器收敛的速度。您应该遵循以下规则:如果您正在测量变量,请使initial_estimate_covariance 中的对角线值大于该测量的协方差。因此,例如,如果相关变量的测量协方差值为 1e-6,则将initial_estimate_covariance 对角线值设为 1e-3 或类似值。

猜你喜欢

转载自blog.csdn.net/weixin_42990464/article/details/132489617