Reza
Reza

Reputation: 31

Unable to publish a subscribed topic in rospy

I am using ROS and python and I have written this code. This code is supposed to subscribe to a ROS topic called "map" (coming from hector_slam using LIDAR) and save it into a variable called 'mapdata' which will be used later. I just want to make sure it is importing it correctly by publishing it as another ROS topic called 'mapprob'. The code compiles and runs fine, but nothing is published in 'mapprob'. I have made sure that "map" is publishing 'OccupancyGrid' messages and we want to extract the OccupancyGrid.data to use as 'mapdata'.

Any help will be appreciated.

Thanks,

CDS

#!/usr/bin/env python

import rospy
import sys
import time
import os
from nav_msgs.msg import OccupancyGrid
from nav_msgs.msg import MapMetaData
from std_msgs.msg import String
from std_msgs.msg import Float64
from std_msgs.msg import Int8MultiArray

def callback(OccupancyGrid):
#   mapdata = Int8MultiArray()
    mapdata.data = OccupancyGrid.data

def talker():
    global mapdata
    mapdata = Int8MultiArray()
    pub = rospy.Publisher('mapprob', Int8MultiArray, queue_size=10)
    rospy.init_node('talker', anonymous=True)
    rospy.Subscriber("map", OccupancyGrid, callback)
#   mapdata.data = OccupancyGrid.data
    rospy.loginfo(mapdata)
    pub.publish(mapdata)
    rospy.spin()


if __name__ == '__main__':
    try:
        talker()
    except rospy.ROSInterruptException:
        pass

Upvotes: 3

Views: 3236

Answers (3)

José Sánchez
José Sánchez

Reputation: 1136

The problem is you are declaring mapdata as a global variable, so every time you are about to publish it gets reset to its default value initialization (i.e. mapdata = Int8MultiArray()).

You can define your node as a class and have mapdata as an instance variable, see this answer for an example.

Hope it helps.

Upvotes: 1

user3778085
user3778085

Reputation: 1

the code below seems to

#!/usr/bin/env python

import rospy
import sys
import time
import os
from nav_msgs.msg import OccupancyGrid
from nav_msgs.msg import MapMetaData
from std_msgs.msg import String
from std_msgs.msg import Float64
from std_msgs.msg import Int8MultiArray

def callback(OccupancyGrid):
    mapdata.data = OccupancyGrid.data
    pub = rospy.Publisher('mapprob', Int8MultiArray, queue_size=10)
    pub.publish(mapdata)



def somethingCool():
    global mapdata
    mapdata = Int8MultiArray()
    rospy.init_node('test_name', anonymous=False)
    rospy.Subscriber("map", OccupancyGrid, callback)
    rospy.loginfo(mapdata)
    rospy.spin()


if __name__ == '__main__':
    try:
        somethingCool()
     except rospy.ROSInterruptException:
        pass

Upvotes: 0

Vtik
Vtik

Reputation: 3140

rospy.spin() will not return until the node has been shutdown, either through a call to ros::shutdown() or a Ctrl-C. this means that your pub.publish(mapdata) command will never be executed once you spin() is reached.

there's a C++ solution for that, making use of ros::spinonce() usually in a while(ros::ok()) loop, and do whatever you want after acquiring the message. Unfortunately for python users, the equivalent of spinonce() in python dosen't exist. so, either

  • use threads for spinning
  • convert your code to C++ (best alternative because the code is not that heavy).

Upvotes: 0

Related Questions