Rosanswers logo

hello everyone
I created a class stage_listener; then, in an externally defined main() function, an object of class stage_listener is created and its function listen is invoked.
The purpose of this function is forcing the object of class stage_listener to become a listener of certain kinds of messages. Here is the code of function:

void stage_listener::listen(int c, char **v){
    while_flag = 1;
    ROS_INFO("Listening activity begun");
    ros::init(c,v, "listener");
    ros::NodeHandle n_odom, n_scan, n_end;
/*  std_msgs::String s;

    //ros::Subscriber sub_odom = n_odom.subscribe("/odom", 1000, &stage_listener::end_loop,this);
    ros::Subscriber sub_odom = n_odom.subscribe("/odom", 1000, &stage_listener::addOdomNode,this);
    ros::Subscriber sub_scan = n_scan.subscribe("/base_scan", 1000, &stage_listener::addScanNode,this);
    ros::Subscriber sub_end = n_end.subscribe("/end", 1000, &stage_listener::end_loop,this);
        //ros::Subscriber sub_odom = n_odom.subscribe("/odom", 1000, &stage_listener::end_loop,this);
    ROS_INFO("Exit from while");

The function receives, as parameters, the argc and argv of the main() where object has been created, since such parameters are requested by ros::init.
These are the functions used for listening:

void stage_listener::end_loop(const std_msgs::String mes){
    ROS_INFO("Setting flag");
    while_flag = 0;

void stage_listener::addOdomNode (const nav_msgs::Odometry mes){
    geometry_msgs::Pose robot_pose = mes.pose.pose;
    geometry_msgs::Point robot_point = robot_pose.position;

    odom_node *on = new odom_node();
    (*on).xCoord = robot_point.x;
    (*on).yCoord = robot_point.y;
    (*on).frame_id = mes.header.frame_id;
    double orientation = tf::getYaw(robot_pose.orientation);
    (*on).angle = (float)orientation;

void stage_listener::addScanNode (const sensor_msgs::LaserScan mes){
    scan_node *sn = new scan_node();
    (*sn).scan = mes.ranges;
    (*sn).frame_id = mes.header.frame_id;
    (*sn).cartesian = polar2cart(mes.ranges, mes.angle_min, mes.angle_increment, mes.range_min, mes.range_max);

After invocation of function listen, the object created begins to wait for messages. An external node, in another package, prepares and sends an std_msgs::String message:

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

int main(int argc, char **argv){
    ros::init(argc, argv,"end_bag");
    ros::NodeHandle n;
    ros::Publisher chatter_pub = n.advertise("/end",1000);
    ros::Rate loop_rate(10);
    std_msgs::String msg;
    msg.data = "end of loop";
    ROS_INFO("Message sent: %s",msg.data.c_str());

The problem is that the message created is never received by the waiting object, since it remains iterating on spinOnce() instruction, never exiting the loop, a result that should be granted by reception of message.

Can you individuate any error in my code causing receiver node not to get any message? thanks for support.

Originally posted by ubisum on ROS Answers with karma: 23 on 2012-12-18

Post score: 0


1 Answer 1


Rosanswers logo

Your sender does NOT remain iterating in the spinOnce() instruction. As the name says: It only spins once. Thus, your sender will exit before anyone has connected. Use ros::spin() or put the spinOnce in a while loop to keep the program running.

Alternatively, you can wait until chatter_pub.getNumSubscribers() > 0 to make sure someone has connected before the program quits.

In general, when testing publish/subscribe: Use rostopic echo and rostopic pub in place of a subscriber/publisher to isolate where the error comes from.

Originally posted by dornhege with karma: 31395 on 2012-12-18

This answer was ACCEPTED on the original site

Post score: 1

Original comments

Comment by ubisum on 2012-12-18:
thanks for answer. let's suppose that message sent by node has to be stored into a bag file. the process (started from a shell) waiting for messages to store in bag file, is considered a subscriber? will it increment the number of subscribers of topic?

Comment by dornhege on 2012-12-18:
Yes and yes.


Your Answer

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