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

ROS Subscriber not updating values with callback data [closed]

asked 2022-06-23 14:39:51 -0600


I am trying to write a subscriber which subscribes to the /cf<id>/pose topic (of the Crazyswarm ROS package) to retrieve the pose of my Crazyflie quadcopter, where <id> is the index of the Crazyflie, which is 1 in my case since I am testing it with only one quadcopter for now. However, only the variable initialization (np.ones(3); np.ones(4)) gets returned and not the updated value from the callback function. I have tried checking the contents of the topic's message with rostopic echo /cf<id>/pose, and seem to be getting the correct real-time position of the robot. I have also tried using the global keyword within the callback function with no luck. Plus, initializing p and theta with None returns the error:

TypeError: 'NoneType' object is not subscriptable.

What could I be doing wrong? I have pored over robotics.stackexchange and ROS Answers and tried every solution I could find, and am still getting the same results, so there is definitely something wrong with my code.

Here's my code:

import numpy as np
import math
import rospy
from geometry_msgs.msg import Pose
import tf

p = np.ones(3)
theta = np.ones(4)

def allPoseCallback(data):
    global p
    global theta

    p = np.array(data.position)
    theta = np.array(data.orientation)

def cfPoseSubscriber():
    rospy.Subscriber('/cf1/pose', Pose, allPoseCallback)

allcfpose = {} #Initialize empty dictionary
allcfrpy = np.zeros((1,3)) #Array to hold roll pitch yaw values of one CF

if __name__ == '__main__':
        rospy.init_node('cflistener', anonymous=True)  

        k = 0

        while not rospy.is_shutdown():
            allcfrpy[k,:] = np.array(tf.transformations.euler_from_quaternion(theta)) #Populate allcfrpy using rpy angles
            allcfpose[f'cf{k+1}'] = np.array(p) #Populate dictionary using pose data

                # k+=1


Any help will be appreciated. Many thanks.

edit retag flag offensive reopen merge delete

Closed for the following reason question is not relevant or outdated by cenwerem
close date 2022-06-25 12:18:40.660881


Since you have a main function it makes sense that all your global variables be defined under main, dont define anything outside it or it will be a confusion.

Ammar Albakri gravatar image Ammar Albakri  ( 2022-06-24 03:19:17 -0600 )edit

Thanks, I've shifted the variables around, but usually run into a scoping problem outside the main environment. I've had to use a built-in method from the Crazyswarm package for my needs temporarily. See my comment below. Thank you for the help.

cenwerem gravatar image cenwerem  ( 2022-06-24 10:55:42 -0600 )edit

1 Answer

Sort by ยป oldest newest most voted

answered 2022-06-23 19:15:36 -0600

Mike Scheutzow gravatar image

Your while loop has problems:

  • Do not keep re-subscribing every time through the loop. Do it once before you enter the loop.
  • You must sleep() inside the while loop. Use rospy.sleep(n), or use a rospy.Rate object.

To get started, try n = 0.250

edit flag offensive delete link more


Thank you for your response. I have effected the changes you highlighted, but I am still getting the same behavior; higher or lower values of the sleep period also do not change the result. I have also tried using empty arrays and can confirm that the callback isn't being called, because I get the empty arrays back exactly. I should also add that defining the variables, subscriber, and callback within a class yields similar results. Perhaps, there is some other way of initializing the p and theta variables other than None or empty arrays that just might work. Thanks for your time and help.

cenwerem gravatar image cenwerem  ( 2022-06-23 22:15:55 -0600 )edit

I could not get this to work, but in the meantime, I've had to use the position() method of the Crazyflie class, which returns the real-time position of the Crazyflie. There isn't one for the attitude, but I only need the position currently and can just assume that all the robots are in a hover state for now.

cenwerem gravatar image cenwerem  ( 2022-06-24 10:47:30 -0600 )edit

If you add a try/except around the code in your subscribe callback, and print any exception that is thrown, you will likely discover what is wrong. I'm skeptical that np.array(data.position) is valid code.

Mike Scheutzow gravatar image Mike Scheutzow  ( 2022-06-24 10:59:43 -0600 )edit

Yeah, I did take out the np.array part in a later version of the code and left it just as data.position, but still got empty values. Thanks, I didn't think of the try/except part. I'll add a try/except block in my callback to see if I can catch the error. Thank you.

cenwerem gravatar image cenwerem  ( 2022-06-24 18:38:32 -0600 )edit

I have this in the callback now, but the except block doesn't print anything. Is this implementation right? Thanks.

p = []
theta = []
def allPoseCallback(data):
        global p
        global theta

        p = data.position
        theta = data.orientation
    except len(p) == 0:
        print("Callback didn't run!")
cenwerem gravatar image cenwerem  ( 2022-06-24 18:44:02 -0600 )edit

No, not right: position is not an array. data is a geometry_msgs/Pose object, so position is a geometry_msgs/Position object. You can use rosmsg terminal command to quickly see the structure:

rosmsg info geometry_msgs/Pose

Also, the except keyword has to be followed by an Exception class type. Do an internet search for this.

Mike Scheutzow gravatar image Mike Scheutzow  ( 2022-06-25 08:32:06 -0600 )edit

Got it. Thanks.

cenwerem gravatar image cenwerem  ( 2022-06-25 10:17:34 -0600 )edit

I just wanted to add that the problem was because I was listening for the wrong message type in my subscriber function. The message type should have been PoseStamped and not Pose. Thanks to everyone for the help!

cenwerem gravatar image cenwerem  ( 2022-07-10 18:36:54 -0600 )edit

Question Tools

1 follower


Asked: 2022-06-23 14:39:51 -0600

Seen: 270 times

Last updated: Jun 23 '22