Ask Your Question

ros::init() must be called before creating a node handle

asked 2012-04-24 13:33:43 -0600

gavinmachine gravatar image

updated 2012-04-24 14:37:06 -0600


I have defined a library (i.e. another ROS package) that node "X" depends upon. In the header file of the library I have a class that declares a node handle. When "X" is being preprocessed, the library's header file is pulled into "X".

When I run the system (via roslaunch), I immediately get this: "ros::init() must be called before creating a node handle" and the node crashes b/c it finds the node handle before it finds main(), which is where ros::init is called.

The question: How do I allow a node handle to exist in the library header file (so the library class can use it) without causing such an error?

Here is an example:


class Z
     public: ...
     private: ros::NodeHandle nh;

Node "X" source (.cpp):

#include <Lib/Lib.h>
     Z z;

When I launch "X", which depends upon Lib (and by extension "Z"), the node handle is found before ros::init() is executed, even though the node handle is not used until afterwards...

Again, the runtime error is: "ros::init() must be called before creating a node handle"

Thanks a lot!

edit retag flag offensive close merge delete

4 Answers

Sort by ยป oldest newest most voted

answered 2012-04-24 14:47:49 -0600

Patrick Mihelich gravatar image

There is nothing wrong with your example as described; in fact it's a typical usage. The NodeHandle is not created until you create the instance of Z, which happens after the call to ros::init(), so there should be no problem.

Most likely you are declaring a global instance of Z (or some other class containing a NodeHandle) either in your main.cpp or in the library. Since globals are created before main(), ros::init() has not yet been called and you get the error.

Get a stack trace from the failed assertion to see where the NodeHandle is being created.

edit flag offensive delete link more



That makes sense. Would is work to create a node handle/publisher in a member function of Z, and then call the member function to publish something? The reason I'm not just creating Z after init() is because I need Z to be global so that anything (classes included) in node "X" can access it...

gavinmachine gravatar image gavinmachine  ( 2012-04-24 15:31:54 -0600 )edit

I have the same problem you mentioned ^

Could you tell me how you fixed it?

2ROS0 gravatar image 2ROS0  ( 2014-11-25 14:13:53 -0600 )edit

answered 2012-04-24 16:53:08 -0600

joq gravatar image

If you want to control when the constructor for Z runs, you can make it a boost::shared_ptr (even a global one) and then wait until after the ros::init() before allocating it.

boost::shared_ptr<Z> z;
  z.reset(new Z());
edit flag offensive delete link more


Using this approaches seems to forbid me from using member functions of Z... for example, using the above syntax, and then calling from within a class in node "X" gives the error that "boost::shared_ptr<Z> does not contain function foo"

gavinmachine gravatar image gavinmachine  ( 2012-04-24 19:48:49 -0600 )edit

It's now a pointer, so the call looks like z->foo().

joq gravatar image joq  ( 2012-04-24 21:52:01 -0600 )edit

answered 2014-02-24 00:14:38 -0600

Kamiccolo gravatar image

updated 2014-02-24 01:59:43 -0600

Personally, using kind a fixed Major's version:

class ROSCommonNode
    ROSCommonNode(int argc, char **argv, const char *node_name)
        ros::init(argc, argv, node_name);

class ROSCommonWorker : ROSCommonNode
    ROSCommonWorker(int argc, char **argv, const char *node_name) : ROSBaseNode(argc, argv, node_name)
        //register some common publishers/subscribers or deal with global param service, whatever

    ros::NodeHandle node_handle;

Motivation: couple of duplicated lines of code saved, also centralized way of changing how all of my common nodes/services/workers/etc. works with logging/dealing with parameters/etc.

edit flag offensive delete link more


This seems like a really complicated way to wrap calling ros::init as the first line in main(). Is the Base/Common node a singleton?

dornhege gravatar image dornhege  ( 2014-02-24 01:33:56 -0600 )edit

In the context of single ROS node - it's a singleton. Not sure if You were asking that and I understood the question right. The main idea is - why the hell I need to initiate each Node by hand in `main()` if I can wrap it like that and forget? EDIT: fixed a few typos in the code.

Kamiccolo gravatar image Kamiccolo  ( 2014-02-24 02:03:58 -0600 )edit

class ROSCommonNode should have a constructer named ROSCommonNode() instead of ROSBaseNode() but it i like this solution to inherate from this basenode.

major gravatar image major  ( 2014-02-24 02:06:49 -0600 )edit

I think dornehege question about the singleton is becaus of using more nodes so everytime ros::init is called. maybe a static variable (static int is_inited = 0;) or a static mutex could solve this and an IF -Statement in constructer could solve this to get a singleton behavior ...

major gravatar image major  ( 2014-02-24 02:11:02 -0600 )edit

You can't also forget about this one as you still need to initialize your RosCommonWorker node.

dornhege gravatar image dornhege  ( 2014-02-24 03:24:21 -0600 )edit

answered 2014-02-22 04:40:01 -0600

major gravatar image

updated 2014-02-24 01:58:43 -0600

I have done it in this way

class Rosinit
    static int is_inited = 0;
    Rosinit(int argc, char **argv, const char *node_name)


class Rosnode_parent

    Rosinit init;
    ros::NodeHandle n;

    Rosnode_parent(int argc, char **argv, const char *node_name):init(argc, argv, node_name)

the class Rosnode_parent has a memer Rosinit init, in the constructer this member is initializied with with an argumentlist,this is done bevor a NodeHandle Construkter is called.

in class Rosinit the static member "static int is_inited" enusres that there is only on call of ros::init

I use Rosnode_parent as a super calls and inherite , important is that in the childclass in there own constructer the super constructer is called

edit flag offensive delete link more


This is a bad idea because you're not passing the program arguments to ros::init(). This means that you will not be able to use any of the command-line remapping arguments with your node.

ahendrix gravatar image ahendrix  ( 2014-02-22 08:34:02 -0600 )edit

The canonical way to do this is to simply call ros::init() once at the very beginning of your main() function.

ahendrix gravatar image ahendrix  ( 2014-02-22 08:34:27 -0600 )edit

@ahendrix ok I edit the post and now the argc.argv are past. In previous it was just a scheme and yes your are right normally it have to be in the main, but if you use a library you didn't have any main and if you want it global like in the question the ros::init would do nothing because the global node is created befor the call

major gravatar image major  ( 2014-02-24 02:02:01 -0600 )edit

You should not call ros::init from a library. That should have been done in a node. The library can't and should not know or set a node name.

dornhege gravatar image dornhege  ( 2014-02-24 03:25:07 -0600 )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


Asked: 2012-04-24 13:33:43 -0600

Seen: 22,223 times

Last updated: Feb 24 '14