Ask Your Question
-1

Subscribing to a topic and storing the message

asked 2011-06-05 01:58:05 -0500

ASMIK2011ROS gravatar image

updated 2011-06-06 05:24:04 -0500

Wim gravatar image

Drear ROS users,
I have a model of a robot arm (KUKA youBot) running in Gazebo. In my cpp program, which generates messages for the Joints of the model, I also need to somehow read and store into a variable the current positions of the Joints.

As far as I know, the corresponding messages are published under the topic named "joint_states". So, when I type in a separate Terminal Window "rostopic echo joint_states", I get all the names of the joints together with corresponding positions, velocities, etc.,constantly published with some high freq. (+ from the youbot Documentation (Locomotec) it is known, that "the arm periodically publish JointState messages for position and velocities of the arm joints").

So, how can I subscribe for this topic "joint_states", read out and store the positions of the arm joints?

Hope for your help!

2 dornhege: Please, if possible, explain in some more detail, what do you mean by "just use sensor_msgs::JointState"? Please give a short example on how to, e.g., add 0.03 to all current positions of the Joints, which have currently been read out by "just using sensor_msgs::JointState".. You will help me so much!.. - ASMIK2011ROS (13 mins ago)

edit retag flag offensive close merge delete

3 Answers

Sort by ยป oldest newest most voted
0

answered 2011-06-10 14:10:51 -0500

ASMIK2011ROS gravatar image

updated 2011-06-10 14:13:31 -0500

OK, I've solved the problem. So, once again ('cause seemingly the original description was not clear enough or too long to read(?) ;), my problem was: I HAD TO BE ABLE TO READ OUT AND STORE THE POSITIONS FROM THE MODEL IN GAZEBO "FROM TIME TO TIME, WHEN NEEDED" INSIDE A "GLOBAL" PROGRAM, WHICH HAS PLENTY OF OTHER DIFFERENT TASKS (So, creating a separate node for subscribing for messages of joint_state topic was of course not the solution I needed). HERE'S THE CODE I USED inside my "global program":

using namespace std;
float joint_pos_global;
void callback(const sensor_msgs::JointState & msg)
{
joint_pos_global = msg.position[3];
}
int main(int argc, char** argv) {
//--------//
ros::init(argc, argv, "listener");
ros::NodeHandle nh;
ros::Subscriber sub; sub = nh.subscribe ("joint_states", 10, callback);
//--------//

smth....smth...smth...smth...

//--Here I suddenly need to know the current position of joint Numb. 3--//
ros::spinOnce();
cout << "Position of joint 3 is" << joint_pos_global << "\n";
//--------------------------------------------------------------------------------------------------//

                           }
edit flag offensive delete link more

Comments

That may not work as you expect - I believe that Messages are queued up for delivery by ROS until the spin occurs at which point all callbacks occur. When the queue overflows messages are dropped, so the joint states you are seeing may be the ones from immediately after your last spin.
JonW gravatar imageJonW ( 2011-06-10 15:52:17 -0500 )edit

Hi, I am facing the same problem. Could you tell me the header files you are including in the beginning. I am getting errors by simply including

#include "ros/ros.h"
#include "std_msgs/String.h"

Thank you so much.

Dr Abdul Mannan gravatar imageDr Abdul Mannan ( 2016-11-25 05:11:49 -0500 )edit
4

answered 2011-06-05 03:39:16 -0500

dornhege gravatar image

updated 2011-06-05 07:16:06 -0500

You subscribe to joint_states like you subscribe for any other topic: Tutorial

Example for accessing joint state:

for(unsigned int i = 0; i < msg.position.size(); i++) { msg.position[i] += 0.03; }

You can lookup the message definitions in the ROS wiki.

edit flag offensive delete link more

Comments

Unfortunately this tutorial is not clear for me. E.g. with ROS_INFO we can publish the positions - where should I see them? And I should write the callback function, when using not std_msgs, but sensor_msgs, as follows, right?:
ASMIK2011ROS gravatar imageASMIK2011ROS ( 2011-06-05 04:15:44 -0500 )edit
void callback(const sensor_msgs::JointState::ConstPtr& msg) { ROS_INFO("Received: ", msg->position); cout<<Subscriber works!" };
ASMIK2011ROS gravatar imageASMIK2011ROS ( 2011-06-05 04:17:26 -0500 )edit
And this tutorial also doesn't answer the question "how to save the Joint positions into a variable". How to correctly set the type of such a variable? Do I definitely need to use the callback function for this? (As well as previous question, this one is also asked not without reading all the possible tutorials. So, I will be grateful for some EXAMPLE OF YOURS.)
ASMIK2011ROS gravatar imageASMIK2011ROS ( 2011-06-05 04:42:30 -0500 )edit
yes, the signature is correct. ROS_INFO will print out, so you see results on the screen (it also sends it to /rosout for logging).
dornhege gravatar imagedornhege ( 2011-06-05 04:58:20 -0500 )edit
You don't really need to put something in variable - just use the sensor_msgs::JointState.
dornhege gravatar imagedornhege ( 2011-06-05 04:59:23 -0500 )edit
1
.. Please, if possible, explain in some more detail, what do you mean by "just use sensor_msgs::JointState"? Please give a short example on how to, e.g., add 0.03 to all current positions of the Joints, which have currently been read out by "just using sensor_msgs::JointState".. You will help me so much!..
ASMIK2011ROS gravatar imageASMIK2011ROS ( 2011-06-05 05:37:18 -0500 )edit
0

answered 2011-06-05 04:26:44 -0500

ASMIK2011ROS gravatar image

So, the code which I use is as follows:
...
using namespace std;
void callback(const sensor_msgs::JointState::ConstPtr& msg)
{ ROS_INFO("Received: ", msg->position);
cout << "Subscriber works!";
}

int main(int argc, char** argv) {
ros::init(argc, argv, "youbot_arm_test");
ros::Rate rate(20); //Hz

ros::NodeHandle nh; ros::Subscriber sub;
sub = nh.subscribe ("JointState", 1000, callback);

ros::Rate rate(20); //Hz
//So, from now on in my program I can get the positions of the Joints by writing
//sub = nh.subscribe("joint_states", 1000, callback);
//RIGHT??

edit flag offensive delete link more

Comments

1
But this code doesn't work! (I've also tried various small modifications, of course). The callback function seem not to execute!
ASMIK2011ROS gravatar imageASMIK2011ROS ( 2011-06-05 04:29:04 -0500 )edit
just add a call to ros::spin(); Then your callback should be called.
dornhege gravatar imagedornhege ( 2011-06-05 04:57:27 -0500 )edit
1
You can edit your original post to add information to the question.
dornhege gravatar imagedornhege ( 2011-06-05 05:09:29 -0500 )edit
1
So, you mean, that each time I need to get the positions of my joints, i need to write sub = nh.subscribe ("JointState", 1000, callback); and then ros::spin();.. Well, this doesn't work. This doesn't work also with ros::spinpnce(); after sub = nh.subscribe ("JointState", 1000, callback);. Something should be wrong in the callback function....
ASMIK2011ROS gravatar imageASMIK2011ROS ( 2011-06-05 06:36:47 -0500 )edit
No, you just write it once. The callback will be called by ROS. You probably want "joint_states" instead of "JointState" as the topic name. Perhaps it's a good idea to reread the ROS introduction to get a grasp on how everything basically works.
dornhege gravatar imagedornhege ( 2011-06-05 07:07:36 -0500 )edit

Yes, this code is not working.

Dr Abdul Mannan gravatar imageDr Abdul Mannan ( 2016-11-25 06:57:36 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2011-06-05 01:58:05 -0500

Seen: 5,882 times

Last updated: Jun 10 '11