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

Revision history [back]

The structure of this python node needs a bit of work.

You're creating a new instance of the gonnaGetDown object in every iteration of your main loop for starters so you creating and destroying the publisher and subscriber objects every time as well so your timing will be all over the place.

This is very important! The design ethos of ROS is that your publishers and subscribers are created once when your node starts up, they then run for the lifetime of the node, 99% of ROS nodes will work in this way.

To get this working you'll need do a few modification:

1) Move the creation of the gonnaGetDown object and the rospy.Rate object to before your while loop. They only need creating once, in fact rate won't work properly if you create a new once each time.

2) The while loop should be changed to while not rospy.is_shutdown(): instead of while(1):

3) The line velocity_publisher = rospy.Publisher('/quadrotor/cmd_vel', Twist, queue_size=10) needs to be in __init__ and should create a property so should be: self.velocity_publisher = rospy.Publisher('/quadrotor/cmd_vel', Twist, queue_size=10). They you can refer to it directly as self.velocity_publisher from then on instead of taking a copy of it each time.

4) Get rid of the cmdvel_publisher method, I don't what this is meant to be doing but it's a callback to a topic which is publishing on the same topic. This means that as soon as it receives a message it's stuck in an infinite loop of receiving and publishing on the same topic. The only reason this doesn't go on for ever in your code is that the object is destroyed at the end of each iteration of your main while loop.

5) You need to describe all of the behaviour of the cmd_vel topic within the detect_marker callback. Setting it to zero if no marker is detected and setting the z linear velocity to -0.01 if it is. You can also print out your debugging information here but note it will be printed once for each ar_pose_marker message received.

This should get your system behaving something like what you want.

The structure of this python node needs a bit of work.

You're creating a new instance of the gonnaGetDown object in every iteration of your main loop for starters so you creating and destroying the publisher and subscriber objects every time as well so your timing will be all over the place.

This is very important! The design ethos of ROS is that your publishers and subscribers are created once when your node starts up, they then run for the lifetime of the node, 99% of ROS nodes will work in this way.

To get this working you'll need do a few modification:

1) Move the creation of the gonnaGetDown object and the rospy.Rate object to before your while loop. They only need creating once, in fact rate won't work properly if you create a new once each time.

2) The while loop should be changed to while not rospy.is_shutdown(): instead of while(1):

3) The line velocity_publisher = rospy.Publisher('/quadrotor/cmd_vel', Twist, queue_size=10) needs to be in __init__ and should create a property so should be: self.velocity_publisher = rospy.Publisher('/quadrotor/cmd_vel', Twist, queue_size=10). They you can refer to it directly as self.velocity_publisher from then on instead of taking a copy of it each time.

4) Get rid of the cmdvel_publisher method, I don't what this is meant to be doing but it's a callback to a topic which is publishing on the same topic. This means that as soon as it receives a message it's stuck in an infinite loop of receiving and publishing on the same topic. The only reason this doesn't go on for ever in your code is that the object is destroyed at the end of each iteration of your main while loop.

5) You need to describe all of the behaviour of the cmd_vel topic within the detect_marker callback. Setting it to zero if no marker is detected and setting the z linear velocity to -0.01 if it is. You can also print out your debugging information here but note it will be printed once for each ar_pose_marker message received.

This should get your system behaving something like what you want.

UPDATE:

To answer your additional questions:

You don't call objects you create them, this is a very important distinction. When the gonnaGetDown is created it's initializer creates a subscriber, from this point on when a messages is received on this topic it will automatically invoke code within the object. You do not need to do anything from this point for the object to do it's job.

Regarding the knowing the values of cmd_vel. Your own code is creating and publishing the values of cmd_vel, if you need to know what's it's values were in the past you can record them in a local variable within the object.

Can I recommend that you read up on event-driven programming here, this is the paradigm that ROS is based upon and you have to use it in this way. You appear to be trying to use it in a purely imperative way which will not work.