0
$\begingroup$

Rosanswers logo

Hi folks, This is a follow-up to a question about callbacks found at http://answers.ros.org/question/39123/can-someone-explain-callbacks/?comment=39701#comment-39701

I'm using Python to implement a navigation interface between the ROS nav stack and my own motor controllers. I have created a Driver object that subscribes to the 'cmd_vel' topic and receives Twist messages from this topic. My callback function from the subscriber determines motor commands based on the info in each Twist message it receives.

A confusing problem I've found is that I need to hand both the Twist message and the 'self' object to my callback function , so that the callback has access to some global parameters associated with the Driver object. I cannot find a way to pass both pieces of information to the callback function when it's called within the Subscriber command.

Code:

class Driver:
    def __init__(self):
         # node initialized and constants described here

    def subscribe_cmd_vel(self):
          rospy.Subscriber("cmd_vel", Twist, self.callback(self))
          rospy.spin()
    def callback(self, msg):
            print "Linear x of Twist message: " + str(msg.linear.x)
            # do some calculations with contents of msg

if __name__ == "__main__"
    dr = Driver()
    dr.subscribe_cmd_vel()

I am consistently only passing the self object to my callback, not the Twist message. When this code hits the print line in the callback function, I get an error saying something like "The Driver object has no 'linear' field.". This means that my msg pointer is being pointed to the self object and my actual Twist message is being lost. Please tell me if you know what mistakes I've made here.

EDIT - SOLUTION =================

By removing the self parameter and parentheses from the callback invoked in the subscriber, both the message and the self object were correctly passed to the callback. I was overthinking the process of passing parameters and the significance of parentheses. Thanks to those who answered me below.

=================================

Many thanks,

Khiya


Originally posted by Khiya on ROS Answers with karma: 49 on 2012-07-25

Post score: 2

$\endgroup$

2 Answers 2

0
$\begingroup$

Rosanswers logo

Just leave out the (self):

rospy.Subscriber("cmd_vel", Twist, self.callback)

What happens is that instead of passing a reference to the callback method to the subscribe method, you call it actually with self as parameter. That's why the print fails. The backtrace you get should show that the error happens in the subscribe_cmd_vel method.

Btw. please always copy-paste the exact error message you get, including the backtrace.


Originally posted by Lorenz with karma: 22731 on 2012-07-25

This answer was ACCEPTED on the original site

Post score: 4

$\endgroup$
0
$\begingroup$

Rosanswers logo

Lorenz's answer is correct; whenever you use brackets, it tries to call the function immediately, which isn't what you are trying to do.

In terms of arguments to the function, you don't need to bother passing in the 'self' argument, it is automatically done for you. self.callback is a bound method - it already contains a reference to the scope that it is bound to (saved in the self variable). So you never need to provide the self argument, regardless of where you call the method.

As an aside,

If you do want to do partial functions, you can do so using functools.partial. Here's an example:

from functools import partial

def jon(a, b):
    print "a is", a
    print "b is", b

partialjon = partial(jon, "part of the partial function...")

partialjon("not.")

>> a is part of the partial function...
>> b is not.

http://docs.python.org/library/functools.html#functools.partial


Originally posted by Jon Mace with karma: 431 on 2012-07-25

This answer was NOT ACCEPTED on the original site

Post score: 3


Original comments

Comment by Benjamin Blumer on 2013-12-03:
Great solution to this problem. I came across this question while looking to do exactly that. I got it to work, but I think it would be valuable to add an example of how this ties in to rospy. If you make your answer editable, I'll be happy to do so.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.