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

Return a value from a callback function

asked 2014-06-22 15:53:26 -0600

jashanvir gravatar image

updated 2014-06-22 15:57:58 -0600

Hello !

I want to have a value to be returned when I call a callback function while subscribing to a topic. I am using ROS-Hydro I have wrote a demo code that what I want. Please also suggest some new way to achieve this if callback function can't return anything !

def bridge_opencv():
    image_pub = rospy.Publisher("quadrotor/videocamera1/camera_info",Image)
    cv2.namedWindow("Image window", 1)
    image_sub = rospy.Subscriber("quadrotor/videocamera1/image",Image, callback)
    get value of y from callback function when it is returning 
    y = z
    return z            
def callback(data):
    bridge = CvBridge()
    try:
        cv_image = bridge.imgmsg_to_cv2(data, "bgr8")
    except CvBridgeError, e:
        print e
    (rows,cols,channels) = cv_image.shape
    if cols > 60 and rows > 60 :
                     cv2.circle(cv_image, (50,50), 10, 255)
           cv2.imshow("Image window", cv_image)
           return y
def my_function()
           x=cv_bridge()
           if x = 1: 
               return "true"
           else:
                perform the task

def pilot():
rospy.init_node("pilot")
    my_value = my_function()
    if my_value = true:
               stop everything...
    else: do the above process again
     rospy.spin()
if __name__ == '__main__':
    pilot()

Thanks a lot ! Looking forward for answers !

edit retag flag offensive close merge delete

Comments

Hello. I have the same issue. Do you have solutions? Please help.

Tvlad gravatar image Tvlad  ( 2016-10-24 01:21:44 -0600 )edit

3 Answers

Sort by ยป oldest newest most voted
8

answered 2014-06-22 20:51:51 -0600

al-dev gravatar image

updated 2014-06-24 09:03:04 -0600

Hi jashanvir, one common way to do this is to use define a class and make the callback function a class member : http://wiki.ros.org/roscpp_tutorials/... . In the body of the callback function, you can modify a class attribute, and then get the value in your main() using a get method.

Edit : I don't think the tutorial is available in Python, but you can have a look at how the callback function is implemented here : http://wiki.ros.org/rospy_tutorials/T...

edit flag offensive delete link more

Comments

Thanks a lot for your time al-dev ! I want to ask if that tutorial is available in python ?

jashanvir gravatar image jashanvir  ( 2014-06-23 03:47:57 -0600 )edit
1
beluga gravatar image beluga  ( 2019-01-09 23:58:22 -0600 )edit
5

answered 2014-06-22 20:55:40 -0600

Mehdi. gravatar image

If I understood you well, you want your callback to process some data and then deliver some result that will be used by other functions. What I do in that case is that instead of return y I publish y to a topic making it accessible to other functions: callback_pub.publish(y) where callback_pub is declared as

callback_pub = rospy.Publisher("callback_y",std_msgs/int32)

As a concrete example you can imagine an image_callback detecting faces and publishing faces positions.

Another easy way to do that is to just set y as a global variable and make the callback function change its value whenever it is called. I don't know how python internally works but you should maybe consider using mutex to avoid Write/Read on y on the same time.

Finally and as al-dev suggested, using a class but you should bind it as a callback using boost. I don't know if there is some tutorial for that in python.

edit flag offensive delete link more

Comments

Thanks for this ! works for me

hpurohit gravatar image hpurohit  ( 2017-05-18 10:34:36 -0600 )edit

I am getting error that stds_msgs not defined.

Mikku gravatar image Mikku  ( 2017-11-23 09:03:03 -0600 )edit

try adding: import sensor_msgs.msg

Ibrahim101 gravatar image Ibrahim101  ( 2017-11-28 12:23:24 -0600 )edit
0

answered 2018-01-24 04:25:22 -0600

updated 2018-01-24 04:27:44 -0600

#!/usr/bin/env python Hey guys , i am also facing just a problem like that . Callback is the function that i get the cmd_vel .

I need the callback to somehow return the captured values OR callback being able to inherit the 'ser' (Serial)

from time import sleep
import serial
import rospy
import tf
from nav_msgs.msg import Odometry
from geometry_msgs.msg import Point, Pose, Quaternion, Twist, Vector3
import serial.tools.list_ports as port

ser = None

speed = 0
angle = 0
Drive = 0
Turn = 0


class Kangaroo:
     def __init__(self, debug=False ,ser= None):
          self.debug = debug
          self.source = None
          self.status = True
          self.ser = ser
          self.Drive = None
          self.Turn = None

     def callback(self,data):
          print data
          # speed = translate(data.linear.x,-1,1,-100,100)
          speed = data.linear.x * 100 + speed
          self.Drive = "D,p" + str(int(speed)) +"\r\n"
          # angle = translate(-data.angular.z,-1,1,100,-100)
          angle = -data.angular.z * 100 + angle
          self.Turn = "T,p" + str(int(angle))+"\r\n"



     def listener( self ):
          rospy.init_node('listener', )
          rospy.Subscriber("/cmd_vel", Twist, self.callback)

          print "\nSpeed =", self.Drive
          ser.write("D,home")
          ser.write(self.Drive)

          print "\nAngle =", self.Turn
          ser.write("T,home")
          ser.write(self.Turn)

          # sleep(.1) # Delay for one tenth of a second
          # print ser.readline()


          # sleep(.1) # Delay for one tenth of a second
          # print ser.readline()
          # print ser.readline()
          # ser.write("D,getp")
          #print ser.readline()

          rospy.spin()


 if __name__ == '__main__':
     print "\nInit kangaroo x2....\n"

     print "\nDetecting kangaroo x2....\n"
     portlist = list(port.comports())
     print portlist
     address = ''
     for p in portlist:
          print p
          if ' USB2.0-Serial' in str(p):
               address = str(p).split(" ")
       print "\nAddress found @"
       print address[0]

       ser = serial.Serial(address[0], 9600)  # Establish the connection on a specific port
       print ser.readline()
       ser.write("D,home")
       ser.write("T,home")
       sleep(.1)  # Delay for one tenth of a second
       ser.write("D,p0")
       sleep(.1)  # Delay for one tenth of a second
       ser.write("T,p0")
       sleep(.1)  # Delay for one tenth of a second

       speed = 0
       angle = 0
       kangaroo = Kangaroo(debug=True , ser=ser)
       kangaroo.listener()
edit flag offensive delete link more

Comments

3

Please don't use an answer to ask a question. This isn't a forum. You can ask a new question and reference this one.

jayess gravatar image jayess  ( 2018-01-24 04:29:12 -0600 )edit

Question Tools

3 followers

Stats

Asked: 2014-06-22 15:53:26 -0600

Seen: 28,404 times

Last updated: Jan 24 '18