0
$\begingroup$

Rosanswers logo

Hello there,

I'm having trouble with the robot_localization package. At first I had odometry, IMU and GPS, but the IMU data got disturbed by a magnetic field of our robot. So I have to use only odometry and GPS for this approach since I can not make any new measurements and have to evaluate what I can from this data. So, I want to fuse odometry and GPS. I am using the Dual-EKF-Node example. I will give all information needed here: As there is no usable IMU-Data, I have to use the wait-for-datum-mode and give a datum in the config-file.

Launch-File:

<launch>
  <rosparam command="load" file="$(find bike_localization)/config/odom_gps.yaml" />

  <node pkg="robot_localization" type="ekf_localization_node" name="ekf_state_estimate_odom" clear_params="true"/>

  <node pkg="robot_localization" type="ekf_localization_node" name="ekf_state_estimate_map" clear_params="true">
    <remap from="odometry/filtered" to="odometry/filtered_map"/>
  </node>

  <node pkg="robot_localization" type="navsat_transform_node" name="navsat_transform" clear_params="true">
    <remap from="odometry/filtered" to="odometry/filtered_map"/>
    <remap from="gps/fix" to="gps_rep"/>
  </node>

</launch>

Config: odom_gps.yaml

ekf_state_estimate_odom:
  frequency: 30
  sensor_timeout: 0.1
  two_d_mode: true
  transform_time_offset: 0.0
  transform_timeout: 0.0
  print_diagnostics: true
  debug: false

  map_frame: map
  odom_frame: odom
  base_link_frame: base_link
  world_frame: odom

  odom0: /odom_can
  odom0_config: [false, false, false,
                 false, false, false,
                 true,  true,  false,
                 false, false, false,
                 false, false, false]
  odom0_queue_size: 10
  odom0_nodelay: true
  odom0_differential: false
  odom0_relative: false
  
ekf_state_estimate_map:
  frequency: 30
  sensor_timeout: 0.1
  two_d_mode: true
  transform_time_offset: 0.0
  transform_timeout: 0.0
  print_diagnostics: true
  debug: true

  map_frame: map
  odom_frame: odom
  base_link_frame: base_link
  world_frame: map

  odom0: /odom_can
  odom0_config: [false, false, false,
                 false, false, false,
                 true,  true,  false,
                 false, false, false,
                 false, false, false]
  odom0_queue_size: 10
  odom0_nodelay: true
  odom0_differential: false
  odom0_relative: true

  odom1: odometry/gps
  odom1_config: [true,  true,  false,
                 false, false, false,
                 false , false, false,
                 false, false, false,
                 false, false, false]
  odom1_queue_size: 10
  odom1_nodelay: false
  odom1_differential: false
  odom1_relative: false

  use_control: false

navsat_transform:
  frequency: 30
  delay: 2.0
  magnetic_declination_radians: 3.55641
  #yaw_offset: 1.570796327
  zero_altitude: true
  broadcast_utm_transform: false
  publish_filtered_gps: true
  use_odometry_yaw: false       # I tried true, too
  wait_for_datum: true
  datum: [XXXXX, YYYYY, -1.5707, map, base_link]    # we start facing south, 0 is facing east, so -pi/2 is facing south, tried other values, get the same output 
# For the actual run, real gps data is used

Now, this ist, what one of my odometry-messages look like. The odometry is facing X:

header: 
  seq: 113
  stamp: 
    secs: 1559130292
    nsecs:  62068063
  frame_id: "odom"
child_frame_id: "base_link"
pose: 
  pose: 
    position: 
      x: 0.281387492407
      y: 0.0023472056171
      z: 0.0
    orientation: 
      x: 0.0
      y: 0.0
      z: 0.0118238048699
      w: 0.999930096376
  covariance: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
twist: 
  twist: 
    linear: 
      x: 0.440455263089
      y: 0.00978800793434
      z: 0.0
    angular: 
      x: 0.0
      y: 0.0
      z: -0.0706352548189
  covariance: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

I do not publish a transform between base_link and odom or between odom and map and this is what my tf-tree looks like:

image description

This is the actual pathway using a very good DGPS as reference (only as reference, not usable in later stages). The Beginning is marked with the yellow array. After the start it drives a big 8:

image description

This is the actual gps of the robot:

image description

The steering of the robot was a bit broken and therefore has a lot of inaccuracies. Nonetheless the odometry:

image description

And now my configuration of robot_localization produces this estimate in the odmoetry/filtered_map, start is at (0,0) facing X:

image description

I know, that my data are not the best, but this should nonetheless not be the estimate from these data. I have exhausted all my nerves for multiple weeks now. I am trying my best to find out, where my error might be. If you can help me, please do so.

EDIT1


As adviced I set the covariances. As I do not know the exact values, I tried some. The overall plot varies a little but the problem still remains. I used rather large and small covariances. Here are just two of the many tries: Example picture for velocity covariances x->0.3 y->0.9 image description

And covariances for velocities x->0.7, y->0.7 image description

Minor changes are visible but the overall plot stays really bad, especially the many circles around the beginning, which don't match the overall gps.

EDIT2


As asked, the GPS data has covariance, too which is of course changing over time.

header: 
  seq: 243
  stamp: 
    secs: 1559316888
    nsecs: 496287087
  frame_id: "gps_rep"
status: 
  status: 0
  service: 1
latitude: XXXXXXXX
longitude: YYYYYYYYY
altitude: 49.455
position_covariance: [3.078, 0.0, 0.0, 0.0, 3.078, 0.0, 0.0, 0.0, 3.605]
position_covariance_type: 2

Originally posted by Bob112358 on ROS Answers with karma: 1 on 2019-05-29

Post score: 0

$\endgroup$

2 Answers 2

0
$\begingroup$

Rosanswers logo

It looks like your covariance matrices are all zeros. Robot localization requires that all the data you feed into it has reasonable covariance values.

From the robot localization docs common errors section:

Missing covariances. If you have configured a given sensor to fuse a given variable into the state estimation node, then the variance for that value (i.e., the covariance matrix value at position (i,i) ( i , i ) , where i i is the index of that variable) should not be 0 0 . If a 0 0 variance value is encountered for a variable that is being fused, the state estimation nodes will add a small epsilon value (1e−6 1 e − 6 ) to that value. A better solution is for users to set covariances appropriately.

I would recommend you estimate your covariances and tack them on when you generate your message (or make a republisher that does it).

Hope that helps!


Originally posted by kkrasnosky with karma: 78 on 2019-05-30

This answer was NOT ACCEPTED on the original site

Post score: 2


Original comments

Comment by Bob112358 on 2019-05-31:
Thanks for your advice. I changed some values in the covariance matrix, just to see, if it has any influence. As I only fuse x and y velocities, I changed them to various values. See my edit 1 in the question. But that does not seem to change the overall picture

Comment by kkrasnosky on 2019-05-31:
Does your GPS have covariance too?

Comment by Bob112358 on 2019-05-31:
Indeed, it has. I added an example message in EDIT2

$\endgroup$
0
$\begingroup$

Rosanswers logo

Offhand, I note three things:

  1. You aren't fusing yaw or yaw velocity from your wheel odometry data. That's going to cause a covariance explosion in the output, which will have all kinds of ugly side effects. In general, every single pose or velocity variable needs at least one reference (measurement source). In the case of two_d_mode, you need a reference for X or X velocity, Y or Y velocity, and yaw or yaw velocity. You are missing the yaw data.
  2. I'm not sure why you're even using an EKF for the odom frame. You only have one input. If your IMU has gyros, I'd bring that back in. Only magnetometers are sensitive to magnetic fields. If you are sticking with just wheel odometry, then I suggest making your wheel odometry node publish the odom->base_link transform, and getting rid of your odom frame EKF.
  3. Even with sensitivity to magnetic distortion in general, if you at least start your robot in a location that doesn't have magnetic fields, you ought to be fine with using your IMU.

Originally posted by Tom Moore with karma: 13689 on 2019-06-03

This answer was NOT ACCEPTED on the original site

Post score: 2

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.