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

Revision history [back]

click to hide/show revision 1
initial version

The simplest way is to calculate a moving average. Here is some rather ugly code that calculates the average of the 60 most recent numbers received on a topic:

import rospy
from std_msgs.msg import Int32

history = []

def callback(msg):
    global history
    history.append(msg.data)
    if len(history) > 60:
        history = history[-60:]
    average = sum(history) / float(len(history))
    rospy.loginfo('Average of most recent {} samples: {}'.format(len(history), average))


n = rospy.init_node('moving_average')
s = rospy.Subscriber('/numbers', Int32, callback)
rospy.spin()

It's averaging integers but modifying it to average GPS values would be simple. Also note that it will immediately start producing an answer even before it gets 60 values. If you don't want that, then you should change it to not calculate an average unless the history length is 60.

This code uses pure Python so it's not that fast. You can do it faster using numpy, for which Stack Overflow is full of answers.

If you explicitly want to take only the last 60 samples, average them, and then wait for 60 more samples before producing another average, then you should only calculate an average if the history length is 60, and clear the history after calculating the average.

A better way to estimate robot pose than a simple moving average is to use a filter such as an Extended Kalman Filter. These are much more involved to write and use, but fortunately you're using ROS and ROS has packages to do this sort of thing for you! The robot_pose_ekf package is one of the most commonly used. It's intended to work with data from sensors such as odometry and IMUs, but it can be convinced to use GPS data. If you have other input data such as odometry then so much the better, because you will get a better position estimate.