Multiple subscribers and single publisher in one python script?
I'm having issues with getting this to work. What I need to do is pull magnetometer data from the imu topic, pull gps data from gps topic, do calculations, and publish to cmd_vel topic. It seems like it would be simple, but I can't seem to get it to work. I can get both subscribers and the publisher to work simoultenously, but I cannot get the data to play together, and I'm pretty sure i'm getting stuck in a callback function.
My code is currently printing my bearing and heading, but it isn't moving, and I'm not sure what else I can try.
My most recent code:
#!/usr/bin/env python
import rospy
from geometry_msgs.msg import Twist
from geometry_msgs.msg import Vector3Stamped
from geometry_msgs.msg import Vector3
from math import radians
from sensor_msgs.msg import NavSatFix
import time
import numpy
global lat1
global long1
def call_head(um6):
global heading
global bearing
r = rospy.Rate(5);
# rospy.loginfo("Bearing: %s", um6.vector) #Print mag reading for bearing
z = um6.vector.z
y = um6.vector.y
angles = Vector3()
heading = numpy.rad2deg(numpy.arctan2(z, y)) + 90
angles.x = heading
angles.z = bearing
call_bear_pub = rospy.Publisher("navStuff", Vector3, queue_size=10)
call_bear_pub.publish(angles)
r.sleep()
return "done heading"
def call_nav(navsat):
global heading
global bearing
global lat1
global long1
r = rospy.Rate(5);
# rospy.loginfo("Latitude: %s", navsat.latitude) #Print GPS co-or to terminal
# rospy.loginfo("Longitude: %s", navsat.longitude)
angles = Vector3()
lat1 = navsat.latitude
long1 = navsat.longitude
###########################################################
lat2 = 30.210406
# Destination
long2 = -92.022914
############################################################
dLon = long2 - long1
y = numpy.sin(dLon) * numpy.cos(lat2)
x = numpy.cos(lat1)*numpy.sin(lat2) - numpy.sin(lat1)*numpy.cos(lat2)*numpy.cos(dLon)
bearing = (numpy.rad2deg(numpy.arctan2(y, x)) + 360) % 360
angles.z = bearing
call_nav_pub = rospy.Publisher("navStuff", Vector3, queue_size=10)
# if (heading != 0):
# call_nav_pub.publish(angles)
# else:
# pass
r.sleep()
return "done bearing"
def call_move(data):
r = rospy.Rate(5);
pub = rospy.Publisher('/husky_velocity_controller/cmd_vel', Twist, queue_size=10)
move_cmd = Twist()
turn_cmd = Twist()
###########################################################
lat2 = 30.210406
# Destination
long2 = -92.022914
############################################################
move_cmd.linear.x = 2
turn_cmd.angular.z = radians(45)
heading = data.z
bearing = data.x
turn_angle = heading - bearing
rospy.loginfo("bearing: %s", bearing)
rospy.loginfo("heading: %s", heading)
if (turn_angle > 180):
turn_angle -= 360
elif (turn_angle < -180):
turn_angle += 360
else:
turn_angle = turn_angle
if (abs(lat1-lat2)<.0005 and abs(long1-long2)<.0005):
pub.publish(Twist())
r.sleep()
else:
if (abs(turn_angle) < 8):
pub.publish(move_cmd)
rospy.spin()
else:
pub.publish(turn_cmd)
r.sleep()
return "done move"
def run():
rospy.init_node('navigate_that_husky')
rospy.Subscriber("/imu_um6/mag", Vector3Stamped, call_head)
rospy.Subscriber("/gps/fix", NavSatFix, call_nav)
rospy.Subscriber("navStuff", Vector3, call_move)
rospy.spin()
if __name__ == '__main__':
run()
That's actually what I tried first, bit I couldn't get it to work. I switched to this method because of this
I'm sure I just don't understand how to use global variables enough. I'll post a simple version my attempt at using global variables.
#!/usr/bin/env python
import rospy
from ...