0
$\begingroup$

Rosanswers logo

Hi,

I can't wrap my head around this problem I'm facing, where I've made a very bare-bones node that should for the moment being only subscribe to a topic and republish it under a new name. I know that the subscribed topic is indeed published by another node, but the callback function is never called when it receives messages from this topic.

Both the "pubbing" and "subbing" messages are displayed in the terminal window, however never the message in the callback function TestBlock::gnssCB. When I use "rosnode info /test_node" it says it has no subscribers.

I'd be very grateful if someone could point out where I'm wrong! :)

testnode.h:

#include "ros/ros.h"
#include "std_msgs/String.h"
#include <std_msgs/Float64.h>
#include "custom_msgs/gnssGGA.h"
#include <sstream>


class TestBlock
{
public:
    explicit TestBlock(ros::NodeHandle nh);
private:
    ros::NodeHandle nh;
    ros::Subscriber gnssGGA_sub;
    ros::Publisher signal_pub;

    void gnssPublish(custom_msgs::gnssGGA& msg);
    void gnssCB(const custom_msgs::gnssGGA& msg);
    void initPublishers();
    void initSubscribers();

    // Constructing gnssGGA msg
    double latitude;
    //string lat_direction
    double longitude;
    //string lon_direction
    double altitude;
    //gnssGGA_status status
};

Test_ros.cpp:

#include "testnode.h"


void TestBlock::initPublishers(){
    ros::Publisher signal_pub = nh.advertise<custom_msgs::gnssGGA>("/GPS/fix_AFTER", 10);
    ROS_WARN("Pubbing");
}

void TestBlock::initSubscribers(){
    ros::Subscriber gnssGGA_sub = nh.subscribe("/GPS/fix_PRE",10,&SigBlock::gnssCB,this);
    ROS_WARN("Subbing");
}

void TestBlock::gnssCB(const custom_msgs::gnssGGA& msg){
   ROS_WARN("Callback");
   latitude = msg.latitude;
   longitude = msg.longitude;
   altitude = msg.altitude;
}

void TestBlock::gnssPublish(custom_msgs::gnssGGA& msg){
    custom_msgs::gnssGGA received_GGA;
    received_GGA.latitude = msg.latitude;
    received_GGA.longitude = msg.longitude;
    received_GGA.altitude = msg.altitude;
    ROS_WARN("Published! %f",msg.longitude);
    signal_pub.publish(received_GGA);
}


TestBlock::TestBlock(ros::NodeHandle nh) : nh(nh)
{
    ROS_WARN("Initing Sig");
    initPublishers();
    initSubscribers();
}

test_node.cpp:

#include "testnode.h"    
int main(int argc, char **argv)
    {
      ros::init(argc, argv, "TestBlock");
      ros::NodeHandle n_sig;
      TestBlock sig_node(n_sig);
      ros::spin();
      return 0;
    }

Originally posted by RosNewbie92 on ROS Answers with karma: 3 on 2019-01-29

Post score: 0

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

This is a C++ problem.

Even though you have a ros::Subscriber gnssGGA_sub and a ros::Publisher signal_pub member in your class, you initialise your subscriber here:

ros::Publisher signal_pub = nh.advertise<..>(..);

and publisher like so:

ros::Subscriber gnssGGA_sub = nh.subscribe(..);

That makes signal_pub and gnssGGA_sub variables local to initPublishers(..) and initSubscribers(..). The specific terminology here is variable shadowing.

As those variables go out of scope at "the end" of those methods, the subscription and the publication will be destroyed, and your callback is "never called".

You'll want to do something like this:

signal_pub = nh.advertise<..>(..);

Note the absence of ros::Publisher.

Note also that there are code styles where member variables are suffixed with an underscore (_). That way, signal_pub and signal_pub_ are two different things (well .. names .. but it's more obvious to a human reading the code what the intent is).


Originally posted by gvdhoorn with karma: 86574 on 2019-01-29

This answer was ACCEPTED on the original site

Post score: 1


Original comments

Comment by RosNewbie92 on 2019-01-29:
Thank you.

What would be a solution for this scoping problem? I'd want to avoid having them in the main function, is that possible?

Comment by gvdhoorn on 2019-01-29:
Please read my answer. Especially the last bit.

Comment by RosNewbie92 on 2019-01-29:
That fixed it, thanks a lot!

$\endgroup$

Your Answer

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