0
$\begingroup$

Rosanswers logo

BLUF (Bottom line up front): Using ackermann style odometry only, Robot_localization isn't providing an /odometry/filtered output.

Machine: Ubuntu 16 & ROS Kinetic

Details: I have an ackermann style vehicle with simulated sensors running in Unity and broadcasting to ROS.

For odometry, I wrote a bicycle model script to estimate position, orientation, and velocity. I publish this to /odometry/bicycle and its a child of /map. That looks like:

odom_quat = tf.transformations.quaternion_from_euler(0, 0, veh.yaw)
# first, we'll publish the transform over tf
odom_broadcaster.sendTransform(
            (veh.x, veh.y, 0.),
            odom_quat,
            current_time,
            "bicycle",
            "map"
            )
# next, we'll publish the odometry message over ROS
odom = Odometry()
odom.header.stamp = current_time
odom.header.frame_id = "map"

# set the position
odom.pose.pose = Pose(Point(veh.x, veh.y, 0.), Quaternion(*odom_quat))
odom.pose.covariance = [0.01,  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.01,  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.1,  0.0,
                        0.0,   0.0,  0.0,  0.0,  0.0,  0.1]
# set the velocity
odom.child_frame_id = "bicycle"
odom.twist.twist = Twist(Vector3(veh.xdot, veh.ydot, 0), Vector3(0, 0, veh.yawdot))
odom.twist.covariance = [0.01,  0.00,  0.00,  0.00,  0.00,  0.00,
                         0.00,  0.01,  0.00,  0.00,  0.00,  0.00,
                         0.00,  0.00,  0.01,  0.00,  0.00,  0.00,
                         0.00,  0.00,  0.00,  0.10,  0.00,  0.00,
                         0.00,  0.00,  0.00,  0.00,  0.10,  0.00,
                         0.00,  0.00,  0.00,  0.00,  0.00,  0.10]
# publish the message
odom_pub.publish(odom)

Some common errors I've read about include having a forward slash (/) before the tf. I don't think I have that issue.

I also have a simulated IMU broadcasting to /imu_data, and gps broadcasted to /gps/fix. I will probably have questions on them later, but right now I want to focus on filtering just the odometry message. Ideally I want to recreate the dual EKF setup described on the robot localization page.

When setting up the EKF for just odometry, I'm not getting an odometry filtered message. Diagnostics does give me an error about erroneous settings.

Odometry message:

header: 
  seq: 66
  stamp: 
    secs: 1554917950
    nsecs:  73329925
  frame_id: "map"
child_frame_id: "bicycle"
pose: 
  pose: 
    position: 
      x: 0.0
      y: 0.0
      z: 0.0
    orientation: 
      x: 0.0
      y: 0.0
      z: 0.0
      w: 1.0
  covariance: [0.01, 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.01, 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.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1]
twist: 
  twist: 
    linear: 
      x: 0.0
      y: 0.0
      z: 0.0
    angular: 
      x: 0.0
      y: 0.0
      z: 0.0
  covariance: [0.01, 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.01, 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.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1]

ROS Out Diagnostics

header: 
  seq: 136
  stamp: 
    secs: 1554918082
    nsecs: 586047931
  frame_id: ''
status: 
  - 
    level: 2
    name: "ekf_odom: Filter diagnostic updater"
    message: "Erroneous data or settings detected for a robot_localization state estimation node."
    hardware_id: "none"
    values: 
      - 
        key: "PITCH_configuration"
        value: "Neither PITCH nor its velocity is being measured. This will result in unbounded error\
  \ growth and erratic filter behavior."
      - 
        key: "ROLL_configuration"
        value: "Neither ROLL nor its velocity is being measured. This will result in unbounded error\
  \ growth and erratic filter behavior."
      - 
        key: "X_configuration"
        value: "Neither X nor its velocity is being measured. This will result in unbounded error\
  \ growth and erratic filter behavior."
      - 
        key: "YAW_configuration"
        value: "Neither YAW nor its velocity is being measured. This will result in unbounded error\
  \ growth and erratic filter behavior."
      - 
        key: "Y_configuration"
        value: "Neither Y nor its velocity is being measured. This will result in unbounded error\
  \ growth and erratic filter behavior."
      - 
        key: "Z_configuration"
        value: "Neither Z nor its velocity is being measured. This will result in unbounded error\
  \ growth and erratic filter behavior."
  - 
    level: 2
    name: "ekf_odom: odometry/filtered topic status"
    message: "No events recorded."
    hardware_id: "none"
    values: 
      - 
        key: "Events in window"
        value: "0"
      - 
        key: "Events since startup"
        value: "0"
      - 
        key: "Duration of window (s)"
        value: "10.157473"
      - 
        key: "Actual frequency (Hz)"
        value: "0.000000"
      - 
        key: "Minimum acceptable frequency (Hz)"
        value: "25.200000"
      - 
        key: "Maximum acceptable frequency (Hz)"
        value: "35.200000"

Launch Script -- Note: Vehicle URDF is loaded in a separate launch file.

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

EKF Settings:

ekf_odom:
    frequency: 10
    sensor_timeout: 0.1
    two_d_mode: true
    transform_time_offset: 0.0
    transform_timeout: 0.0
    print_diagnostics: true
    debug: false
    publish_tf: true
    publish_acceleration: false
    map_frame: map              # Defaults to "map" if unspecified
    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: odometry/bicycle
    odom0_config: [true,  true,  true,
                   false, false, false,
                   false, false, false,
                   false, false, true,
                   false, false, false]
    odom0_queue_size: 5
    odom0_nodelay: false
    odom0_differential: false
    odom0_relative: false
    odom0_pose_rejection_threshold: 5
    odom0_twist_rejection_threshold: 1
#    imu0: imu_data
#    imu0_config: [false, false, false,
#                  false, false, false,
#                  false, false, false,
#                  true,  true,  true,
#                  true,  true,  true]
#    imu0_nodelay: false
#    imu0_differential: false
#    imu0_relative: true
#    imu0_queue_size: 5
#    imu0_pose_rejection_threshold: 0.8                 # Note the difference in parameter names
#    imu0_twist_rejection_threshold: 0.8                #
#    imu0_linear_acceleration_rejection_threshold: 0.8  #
#    imu0_remove_gravitational_acceleration: true
    use_control: false #true
    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]

image description image description


Originally posted by rukie on ROS Answers with karma: 71 on 2019-04-10

Post score: 0


Original comments

Comment by rukie on 2019-04-11:
I think part of what I should be doing, is broadcasting the bicycle publisher on frame id "odom" to child "bicycle". I should create a static relationship between map and odom (until earth/etc is set up).

And in odom I should track vx, vy, and vyaw instead of positions.

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

However, I still don't have a functioning robot localization.

Comment by rukie on 2019-04-11:
from here: https://answers.ros.org/question/314169/setting-frame-ids-for-ekf-localization/ I've confirmed my wheel odometry child frame should be "base link" and my frame id should be "odom" (I have map above)..

Still No improvement.

Comment by rukie on 2019-04-11:
I've also gone ahead and simplified my ekf yaml file:

ekf_odom:
    frequency: 20
    sensor_timeout: 2.0
    two_d_mode: true
    transform_time_offset: 0.0
    transform_timeout: 1.0
    print_diagnostics: true
    debug: false
    publish_tf: true
    publish_acceleration: false
    map_frame: map              
    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: odometry/bicycle
    odom0_config: [false,  false,  false,
                   false, false, true,
                   true, true, false,
                   false, false, true,
                   false, false, false]
    odom0_queue_size: 5
    odom0_nodelay: false
    odom0_differential: false
    odom0_relative: false

Comment by rukie on 2019-04-11:
And if anyone else is reading this: Many of the parameters added such as pose and twist thresholds, accel/decel limits, can cause the localization package to ignore the info...

However I still have the same error...

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

A bunch of things.

  1. First, do a rostopic info and make sure that the EKF is subscribed to the topic.
  2. You have your EKF world_frame set to odom. That means the EKF is going to try to transform all pose data into the odom frame before using it. If there's no transform available from map->odom, the EKF can't use your map frame data. So it ignores your odometry.
  3. You have your EKF base_link frame set to base_link, but your odometry data has a child_frame_id of bicycle. Again, the EKF will need to transform from bicyle->base_link if you want it to use that data.

Originally posted by Tom Moore with karma: 13689 on 2019-05-15

This answer was ACCEPTED on the original site

Post score: 1

$\endgroup$

Your Answer

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