ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Filtered odometry drifts when no measurements received

asked 2015-10-19 07:02:41 -0500

updated 2015-11-16 07:11:06 -0500

I'm trying to fuse wheel odometry with visual poses computed from observed visual markers. Whenever the robot is standing still (no odometry received) and there's no visual marker in sight (no visual pose as well), the filtered estimation starts drifting with increasing velocity.

First I thought this is caused by nonzero velocity remaining in the "twist" part of the odometry message. But it also occurs if I use absolute x, y and yaw measurements, like in the following launch file:


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

      <param name="frequency" value="10"/>
      <param name="sensor_timeout" value="0.1"/>
      <param name="two_d_mode" value="true"/>

      <param name="world_frame" value="odom"/>

      <param name="odom0" value="odometryPose"/>
      <rosparam param="odom0_config">[true, true, false,
                                      false, false, true,
                                      false, false, false,
                                      false, false, false,
                                      false, false, false]</rosparam>

      <param name="pose0" value="visualPose"/>
      <rosparam param="pose0_config">[true, true, false,
                                      false, false, true,
                                      false, false, false,
                                      false, false, false,
                                      false, false, false]</rosparam>



Sure, when there's no measurement (not even an "I'm not moving!"), the uncertainty grows. Thus, I shouldn't believe in the computed expected pose too much.

But, is there any configuration I'm missing? Like don't filter without any new measurement? I'd like to avoid introducing another dummy node publishing pseudo zero measurements in case of stillstand.

Update 1

I noticed that the filtered pose jumps back to where it should be, as soon as a new measurement arrives. So the drift only seems to affect the prediction and vanishes with the next correction step. But how can a node - receiving the /odometry/filtered message - distinguish between a vague prediction and a corrected pose based on measurements?

Update 2

After apparently having fixed the issue, there's a drift again. This time I boiled it down to the following minimum example:


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

      <param name="two_d_mode" value="true"/>                                             
      <param name="world_frame" value="odom"/>                                            

      <param name="odom0" value="wheelOdometry"/>                                         
      <rosparam param="odom0_config">[false, false, false,                                
                                      false, false, false,                                
                                      true, true, false,                                  
                                      false, false, true,                                 
                                      false, false, false]</rosparam>                     


    <node pkg="unit_tests" type="" name="publishers" />                      


The launch script runs robot_localization and the following message publisher:

wheelPub = rospy.Publisher("/wheelOdometry", Odometry, queue_size=1)
while not rospy.is_shutdown():
    wheelPub.publish(Odometry(header=Header(, frame_id="odom"), child_frame_id="base_link"))

In this example, there is no drift. But the covariance of /odometry/filtered is growing unboundedly which indirectly causes a drift when adding a second data source like visual pose estimations.

So how can the uncertainty increase if the only information given is "My velocity is zero. I'm 100 % sure."?

edit retag flag offensive close merge delete


Can you post some sample messages? Also, are you saying that when your robot stands still, your odometryPose message stops being published?

Tom Moore gravatar image Tom Moore  ( 2015-10-22 07:40:21 -0500 )edit

@tom-moore: Sorry to bother you again. But after isolating the issue in a unit test I'm struggling with understanding the resulting odometry. See Update 2 for a complete launch file and rospy node.

Falko gravatar image Falko  ( 2015-11-16 07:13:27 -0500 )edit

2 Answers

Sort by ยป oldest newest most voted

answered 2015-11-10 11:36:49 -0500

Tom Moore gravatar image

updated 2015-11-19 07:17:46 -0500

The EKF follows a predict/update cycle. If no measurement is received within the sensor_timeout period, the filter will carry out a prediction step. If no sensor is available to correct it, the error will grow rapidly, and I wouldn't be surprised to see your pose drift. Is there a reason why your wheel odometry can't publish messages when standing still? I would make it publish messages with decreased covariance values, as you can be certain the robot isn't moving. Also, I'd switch your odometry source so that it is fusing velocity and not pose data.

Response to Update 2

If you just fuse velocities, there will always be unbounded error growth in your pose. You have nothing correcting the covariance for your pose variables. At every time step, we do a prediction, which causes the errors to grow for every variable. Then we immediately correct with a measurement, and any variable that is measured sees its covariance (usually) decrease in the state estimate. If your variable is never measured, it will never be corrected. If you watch the covariance on your twist data, you'll see that it's bounded.

I'm not sure I understand why adding pose input would result in drift. If anything, it should stick very close to your pose estimate, with some slight corrections as you move around.

edit flag offensive delete link more


Thanks, Tom! After reviewing/refactoring the whole setup the drift vanished and I couldn't reproduce the drift. (That's why I struggled with providing samples.) Basically, I followed your suggestions: Continue to send odometry with small variance when standing still + fuse velocity rather than pose

Falko gravatar image Falko  ( 2015-11-12 00:52:01 -0500 )edit

Ok. I thought pose (position) and twist (velocities) are somehow coupled. If I have an old pose and new zero-twist measurements with zero uncertainty - how should the pose uncertainty grow. But maybe this is a technical detail of your model and/or implementation. I'll try to find a workaraound.

Falko gravatar image Falko  ( 2015-11-25 09:37:17 -0500 )edit

They are coupled in the sense that position = velocity * time, but that relationship is only exercised during prediction. Also, you can't have zero values in your covariance matrix diagonal. That matrix needs to be invertible.

Tom Moore gravatar image Tom Moore  ( 2015-11-28 07:42:17 -0500 )edit

answered 2015-10-21 11:45:05 -0500

nyquist09 gravatar image

Based on your experience in your updated answer I would intuitively say that the noise parameter of your odometry is off. So you would need to tune your Kalman filter. The tuning parameters of a Kalman filter are process and observation noise levels (assuming your model is correct and can be simplified well enough as having gaussian noise).

Could you try and increase the process noise level of the odometry? Because you don't want the filter to drift between measurement updates (of your visual pose), it should always yield the best possible estimate. I don't know the package, so I can't tell you exactly where to change the parameters.

Remember: tuning a kalman filter can be tedious..

edit flag offensive delete link more

Question Tools

1 follower


Asked: 2015-10-19 07:02:41 -0500

Seen: 1,373 times

Last updated: Nov 19 '15