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

How do I Calculate Distance Using 2 GPS Topics

asked 2017-04-26 19:44:10 -0600

SupermanPrime01 gravatar image

Hello,

So currently I have two GPS modules and they each have their own nodes. The 2 nodes publish their GPS information onto their own topics. So 2 nodes and 2 topics. I'm able to subscribe to both nodes but I'm having trouble using the variables in the callback function to calculate distance.

I would get this error: NameError: global name 'gps_lat' is not defined

Here's my code below

#!/usr/bin/env python
import rospy
from std_msgs.msg import String
from nmea_msgs.msg import Sentence
from sensor_msgs.msg import NavSatFix
import math

def callback(data):
    gps_lat = round(data.latitude, 6)
    gps_lon = round(data.longitude, 6)

def callback1(data):
    gps1_lat = round(data.latitude, 6)
    gps1_lon = round(data.longitude, 6)

def listener():

    rospy.init_node('gps_monitor', anonymous=True)
    rospy.Subscriber("/fix", NavSatFix, callback)
    rospy.Subscriber("/fix1", NavSatFix, callback1)
    rospy.spin()

    delta_lat = (gps_lat*(108000) - gps1_lat*(108000))
    delta_lon = (gps_lon*(108000) - gps1_lon*(108000))
    hyp_m = (delta_lat**2 + delta_lon**2)**0.5
    hyp_ft = (hyp_m*3.2800839)
    rospy.loginfo("Distance is %s in ft.", hyp_ft)



if __name__ == '__main__':
    listener()
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
2

answered 2017-04-26 21:10:45 -0600

Geoff gravatar image

You can't use variables local to one function (your callback functions, in this case) in another function (the listener() function).

For working with data from multiple topics, there are several ways you can structure your program.

The first is to use global variables. Make gps_lat, gps_lon, gps1_lat and gps1_lon global variables that are updated in the callbacks and used in listener(). However this approach does not synchronise the data so you might get inaccurate values for the calculated distance if it uses a mix of new and old data.

The second is to make your node a class, with the gps data stored in member variables and the callbacks methods of the class. This would essentially be the same as the above, but without the use of global variables.

The third is to use message filters to synchronise the data received from the two sensors and calculate the distance when data is received from both. With a message filter, you provide it a set of inputs (your two topics, /fix and /fix1), and register a callback. The callback is called when the message filter has data meeting its condition, such as a message on each topic with similar timestamps. If your GPS sensors are not producing data in sync, then you might need to use the approximate time policy filter. You can use it like this:

#!/usr/bin/env python

import rospy
import message_filters
from sensor_msgs.msg import NavSatFix


def calc_distance(gps1, gps2):
    gps1_lat = round(gps1.latitude, 6)
    gps1_lon = round(gps1.longitude, 6)
    gps2_lat = round(gps2.latitude, 6)
    gps2_lon = round(gps2.longitude, 6)
    delta_lat = (gps1_lat*(108000) - gps2_lat*(108000))
    delta_lon = (gps1_lon*(108000) - gps2_lon*(108000))
    hyp_m = (delta_lat**2 + delta_lon**2)**0.5
    hyp_ft = (hyp_m*3.2800839)
    rospy.loginfo("Distance is %s in ft.", hyp_ft)


def listener():
    rospy.init_node('gps_monitor', anonymous=True)
    gps1 = message_filters.Subscriber('/fix', NavSatFix)
    gps2 = message_filters.Subscriber('/fix1', NavSatFix)
    ts = message_filters.ApproximateTimeSynchronizer([gps1, gps2], 10, 5)
    ts.registerCallback(calc_distance)
    rospy.spin()


if __name__ == '__main__':
    listener()

This will print a new distance calculation every time it gets a message on each topic that are within 5 seconds of each other.

edit flag offensive delete link more

Comments

Thank you so much Geoff. This was exactly what I needed. When I tried the global variables method the distances would continuously increase so you're right about that too.

SupermanPrime01 gravatar image SupermanPrime01  ( 2017-04-26 22:19:01 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2017-04-26 19:44:10 -0600

Seen: 1,120 times

Last updated: Apr 26 '17