Robotics StackExchange | Archived questions

Robot_localization configuration (GPS, IMU, Odometry)

Hello,

I try to use the robot_localization package for a project where we have the following sensors:

After I have read the robot_localization documentation and seen the ROSCON presentation of Tom Moore I have the following setup:

My frame configuration is the following:

I have read in the "ekftemplate.yaml" of the robotlocalization package that I should set the worldframe to map when fusing a global absolute position and get the odom->baselink transform from somewhere else (another estimation node for example but I shouldn't fuse global data there).

In my configuration I am using the global position in both nodes (input for navsattransformnode and the output of the node into ekflocalizationnode)

Do I need to create a second ekflocalizationnode with just continous data input and use the data output of this node as input into the first ekflocalizationnode which just fuses two odometry sources (from navsattransformnode and second ekflocalizationnode) then?

Is the output of the first ekflocalizationnode or the navsattransformnode the most reliable then to use the pose for distance measuring or calculation of circle radius for example?

Thank you guys in advance!

EDIT:

We have the following configuration for ekf_localization_node (at the moment):

frequency: 30

sensor_timeout: 0.1

two_d_mode: false

transform_time_offset: 0.0

transform_timeout: 0.0

print_diagnostics: true

debug: false

debug_out_file: robot_localization_debug.txt

publish_tf: true

publish_acceleration: false

odom_frame: odom            # Defaults to "odom" if unspecified
base_link_frame: base_link  # Defaults to "base_link" if unspecified
world_frame: odom           # Defaults to the value of odom_frame if unspecified

odom0: /odom

odom0_config: [false,  false,  false,
               false, false, false,
               true, true, false,
               false, false, true,
               false, false, false]

odom0_queue_size: 2

odom0_nodelay: false

odom0_differential: false

odom0_relative: false

odom0_pose_rejection_threshold: 5
odom0_twist_rejection_threshold: 1

odom1: /odometry/gps
odom1_config: [true, true, true,
               false, false, false,
               false, false, false,
               false, false, false,
               false, false, false]

odom1_differential: false

odom1_relative: true

odom1_queue_size: 2

odom1_pose_rejection_threshold: 2

odom1_twist_rejection_threshold: 0.2

odom1_nodelay: false


imu0: /imu/data
imu0_config: [false, false, false,
              false,  false, true,
              false, false, false,
              false, false, true,
              true, false, false]
imu0_nodelay: false

imu0_differential: false

imu0_relative: true

imu0_queue_size: 5

imu0_pose_rejection_threshold: 0.8               

imu0_twist_rejection_threshold: 0.8

imu0_linear_acceleration_rejection_threshold: 0.8  

imu0_remove_gravitational_acceleration: true

use_control: false

stamped_control: false

control_timeout: 0.2

control_config: [true, false, false, false, false, true]

acceleration_limits: [1.3, 0.0, 0.0, 0.0, 0.0, 3.4]

deceleration_limits: [1.3, 0.0, 0.0, 0.0, 0.0, 4.5]

acceleration_gains: [0.8, 0.0, 0.0, 0.0, 0.0, 0.9]

deceleration_gains: [1.0, 0.0, 0.0, 0.0, 0.0, 1.0]

process_noise_covariance: [0.05, 0,    0,    0,    0,    0,    0,     0,     0,    0,    0,    0,    0,    0,    0,
                           0,    0.05, 0,    0,    0,    0,    0,     0,     0,    0,    0,    0,    0,    0,    0,
                           0,    0,    0.06, 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.06, 0,     0,     0,    0,    0,    0,    0,    0,    0,
                           0,    0,    0,    0,    0,    0,    0.025, 0,     0,    0,    0,    0,    0,    0,    0,
                           0,    0,    0,    0,    0,    0,    0,     0.025, 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.02, 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]


initial_estimate_covariance: [1e-9, 0,    0,    0,    0,    0,    0,    0,    0,    0,     0,     0,     0,    0,    0,
                              0,    1e-9, 0,    0,    0,    0,    0,    0,    0,    0,     0,     0,     0,    0,    0,
                              0,    0,    1e-9, 0,    0,    0,    0,    0,    0,    0,     0,     0,     0,    0,    0,
                              0,    0,    0,    1e-9, 0,    0,    0,    0,    0,    0,     0,     0,     0,    0,    0,
                              0,    0,    0,    0,    1e-9, 0,    0,    0,    0,    0,     0,     0,     0,    0,    0,
                              0,    0,    0,    0,    0,    1e-9, 0,    0,    0,    0,     0,     0,     0,    0,    0,
                              0,    0,    0,    0,    0,    0,    1e-9, 0,    0,    0,     0,     0,     0,    0,    0,
                              0,    0,    0,    0,    0,    0,    0,    1e-9, 0,    0,     0,     0,     0,    0,    0,
                              0,    0,    0,    0,    0,    0,    0,    0,    1e-9, 0,     0,     0,     0,    0,    0,
                              0,    0,    0,    0,    0,    0,    0,    0,    0,    1e-9,  0,     0,     0,    0,    0,
                              0,    0,    0,    0,    0,    0,    0,    0,    0,    0,     1e-9,  0,     0,    0,    0,
                              0,    0,    0,    0,    0,    0,    0,    0,    0,    0,     0,     1e-9,  0,    0,    0,
                              0,    0,    0,    0,    0,    0,    0,    0,    0,    0,     0,     0,     1e-9, 0,    0,
                              0,    0,    0,    0,    0,    0,    0,    0,    0,    0,     0,     0,     0,    1e-9, 0,
                              0,    0,    0,    0,    0,    0,    0,    0,    0,    0,     0,     0,     0,    0,    1e-9]

We have the following configuration for navsat_transform_node:

frequency: 30

delay: 3.0

magnetic_declination_radians: 0

yaw_offset: 1.5707963

zero_altitude: false

broadcast_utm_transform: false

broadcast_utm_transform_as_parent_frame: false

publish_filtered_gps: false

use_odometry_yaw: false

wait_for_datum: false

datum: [55.944904, -3.186693, 0.0]

Our launch file:

<launch>

  <node pkg="robot_localization" type="ekf_localization_node" name="ekf_se" clear_params="true">
    <rosparam command="load" file="$(find robot_localization_specfic)/params/ekf_template.yaml" />
  </node>


  <node pkg="robot_localization" type="navsat_transform_node" name="navsat_transform_node" clear_params="true">
    <rosparam command="load" file="$(find robot_localization_specfic)/params/navsat_transform_template.yaml" />
  </node>

</launch>

This our configuration at the moment:

Our configuration at the moment

Would you suggest a solution like this now (from what I have understood from your answer)? image description

Or is the configuration different?

I have found the dual_ekf_navsat_example in robot_localization, is that the one I should stick to?

If we would have a second odometry source do we have to fuse the odometry in ekf_localization_node 2 too with the first one?

We want to drive outdoors in terrain without many features (like a meadow) and use the most accurate odometry (from robot localization) for 3D mapping.

Thank you very much in advance!

Asked by ce_guy on 2018-06-18 07:26:58 UTC

Comments

Answers

Please post your configuration and launch files. It makes answering such questions easier.

I can say that this is a typical setup for GPS data:

EKF1: world frame is odom, fuse IMU and wheel encoders.

EKF2: world frame is map, fuse GPS, IMU, and wheel encoders

navsat_transform_node should listen to the output of EKF2.

As to which output to use, it doesn't really make sense to use the output of navsat_transform_node, unless you want to plot it in Google Earth or something. The output of EKF2 will be the most accurate pose, but is obviously subject to discontinuities from the GPS.

EDIT: your second solution is more in line with what I was thinking, yes. The example in the package isn't prescriptive; that is, I don't encourage you to stick to it necessarily, but it gives an idea of what's required to work with GPS data.

What is your second odometry source? The odom_gps data? Or another one?

I'll give you the same advice I give everyone: get your filters working with just IMU and wheel encoders. When that's done, add the GPS data.

I'm not sure how well this will work in a mapping context, but I know nothing about your setup.

Asked by Tom Moore on 2018-06-19 05:40:39 UTC

Comments

Thank you very much for your answer! I have updated the question now with the configuration and launch files.

Asked by ce_guy on 2018-06-25 05:00:40 UTC