# How do I average 60 values published values from a node

Hello,

Is there a way I can take 60 values from a topic and calculate the average after every 60 values. I'm working with GPS and the accuracy is about 3 meters. So I'll get readings that are ~3 meters of where I'm actually at. Taking the average helps pin point my approximate location but I don't know a way to do it without copying and pasting my data into an excel sheet.

edit retag close merge delete

Sort by » oldest newest most voted 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.

more

Extending this: there is also the robot_localization package which is intended to use GPS data...