0
$\begingroup$

Rosanswers logo

Hi, I am relatively new to ROS and have a question regarding Publisher and Subscriber.

To make this easy I use the Code from the ROS Tutorial "Writing a Simple Publisher and Subscriber (C++)". I can get everything to run and I can see the published messages through the "listener" node.

My question now is, how can I get the messages from the "chatterCallback" function back into my main function because I want to use it with Data from the main. I looked into the documentation of "subscribe" but I cant get it to work.

Maybe I cant see the obvious solution because I didn't programmed for a while now.

Used Code: http://wiki.ros.org/ROS/Tutorials/WritingPublisherSubscriber%28c%2B%2B%29

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

void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
  ROS_INFO("I heard: [%s]", msg->data.c_str());
}

int main(int argc, char **argv)
{
  ros::init(argc, argv, "listener");

  ros::NodeHandle n;

  ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);

  //here I want access to the message from chatterCallback

  ros::spin();

  return 0;
}

Thank you for the answers.


Originally posted by Slevin Kelevra on ROS Answers with karma: 1 on 2018-01-18

Post score: 0


Original comments

Comment by jayess on 2018-01-18:
Welcome! What does

I cant get it to work

mean? What have you tried (post your code please)?

Comment by Slevin Kelevra on 2018-01-18:
I edited the post.

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

What you can do is create a global variable to store the data in. For example

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

std_msgs::String str_var; // global variable

void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
  str_var.data = msg->data; // save the data in the callback
  ROS_INFO("I heard: [%s]", msg->data.c_str());
}

int main(int argc, char **argv)
{
  ros::init(argc, argv, "listener");

  ros::NodeHandle n;

  ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);

  //here I want access to the message from chatterCallback

  ros::spin();

  return 0;
}

Ideally, you'd create a class for this and save the data to a class variable instead of a global one.

Note that I haven't compiled the code so there may be some errors, but the main idea is there.


Originally posted by jayess with karma: 6155 on 2018-01-18

This answer was ACCEPTED on the original site

Post score: 0


Original comments

Comment by gvdhoorn on 2018-01-18:
Note btw that this (as all examples given on questions about 'using msgs in main') diverges from the purely event-based style of control-flow that asynchronous systems such as ROS pub-sub make possible/are proponents of.

Attempting to treat it as a synchronous, sampling, periodic while-loop is ..

Comment by gvdhoorn on 2018-01-18:
.. obviously possible, but may lead to unexpected behaviour and even subtle bugs.

See this ROSCon17 presentation about something similar.

Comment by Slevin Kelevra on 2018-01-18:
I knew that I could use a global variable but I learned that global variables should be avoided if possible.

I try your idea with the class tomorrow but it sounds promissing.

To the problem with the asynchronous system: would it be a solution when I build a queue in the class to accumulate all ...

Comment by Slevin Kelevra on 2018-01-18:
...messages till I get them from the main function?

Comment by thejose on 2020-08-14:
I understand that there could be errors if no message is received and the code in main calls the message. However, I don't see how this problem is solved using a class variable instead of a global variable.

Also, what is the most ideal way to solve this problem? I am sure it is quite common for people to want to access messages from a topic, manipulate them and publish the output to another topic. There must be a standard way to do this.

Comment by gvdhoorn on 2020-08-14:\

I am sure it is quite common for people to want to access messages from a topic, manipulate them and publish the output to another topic. There must be a standard way to do this.

Yes:

  1. store them in a work-queue or a message_filters/Cache and have a separate thread process the queue, or
  2. do the work in the callback and publish as soon as you have processed the message
$\endgroup$

Your Answer

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