The first nodeHandle fully initalizes your node, any other nodeHandles constructed along the way (e.g. for another topic, scoping etc) increases the global refrence count. The first nodeHandle sets the count to 1 and starts the node with ros::start()
. More info check this link text
I stumbled into the following message, when my last nodehandle ran out of scope and I checked for ros::ok()
returning false and chrasing the node having multiple boost threads.
* Error in `/home/user/Downloads/catkin_ws/devel/lib/foo/foo': free(): invalid pointer: 0x00007ffe036a1280 *
In my case I constructed publisher objects having nodehandles and the ros::publisher . This is handy: once the topic is not needed anymore I did let the object run out of scope (or erase it from the object container like vector < pub_obj >) and the destructor of pub_obj got called.
As a solution. Have one nodeHandle right after ros::init
and dont let it go out of scope till the main function finishes. So if one of the pub_obj gets destroyed the refrence count decreases only down to 1 not causing the error.
Check this example with scoping: If you compile it with the nodeHandle after the bracket the second ros::ok
returns false thus the node being not connected to the ros system. The way it is below returns ok:
//ros headers (most functions of ROS)
#include "ros/ros.h"
#include "std_msgs/String.h"
//c++ headers
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <sstream>
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
ros::init(argc, argv, "foo");
std::cout << "published roso1?" <<ros::ok()<< std::endl;
ros::NodeHandle nh_;
{
ros::Publisher chatter_pub;
chatter_pub = nh_.advertise <std_msgs::String>("chatter", 100);
ROS_INFO("advertised chatter");
std_msgs::String msg;
std::stringstream ss;
ss << "hello world ";
msg.data = ss.str();
ROS_INFO("%s", msg.data.c_str());
chatter_pub.publish(msg);
usleep(50000000);//5s
}
std::cout << "published rosok2?" <<ros::ok()<< std::endl;
}
now lets check it with $ rosrun foo foo
published roso1?1
[ INFO] [1467717888.162157852]: advertised chatter
[ INFO] [1467717888.162239147]: hello world
published rosok2?1
The nodehandle declared in the constructor should end its life cycle (destroyed) after the constructor function has been successfully executed, which according to the http://wiki.ros.org/roscpp/Overview/Initialization%20and%20Shutdown, the destroy of last nodehandle instance will kill all open subscriptions, publications, service calls, and service servers. Please correct me if I am wrong.