ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

I ran into similar issues. The ROS logging macros are numerous and defined 5 or more levels deep, so whenever you pass the wrong one of the plethora of stringy types in C++, you get several screenfulls of preprocessor error.

If you're developing in C++11, you can use closures to bring back a measure of explicitly typed sanity:

    auto log_info =  [] (const std::string & str) {ROS_INFO_STREAM(str);};
    auto log_warning =  [] (const std::string & str) {ROS_WARNING_STREAM(str);};
    auto log_error =  [] (const std::string & str) {ROS_ERROR_STREAM(str);};

There are probably many ways of defining the above closures; there may be a better one for your code. At doing it this way decomposes the task of fixing the types in the call sites in your code from the much harder problem of figuring out which types will actually work in ROS's macros.

I'm sure there are reasonable historical reasons for why ROS is code generating header files full of macros nested 5 levels deep, but IMHO it has resulted in an unreasonable level of complexity for something as simple as logging a string. Perhaps someone can post an example of what all the macros actually boil down to in the end.

I ran into similar issues. The ROS logging macros are numerous and defined 5 or more levels deep, so whenever you pass the wrong one of the plethora of stringy types in C++, you get several screenfulls of preprocessor error.

If you're developing in C++11, you can use closures to bring back a measure of explicitly typed sanity:

    auto log_info =  [] (const std::string & str) {ROS_INFO_STREAM(str);};
    auto log_warning =  [] (const std::string & str) {ROS_WARNING_STREAM(str);};
    auto log_error =  [] (const std::string & str) {ROS_ERROR_STREAM(str);};

There are probably many ways of defining the above closures; there may be a better one for your code. At doing Doing it this way decomposes the task of fixing the types in the call sites in your code from the much harder problem of figuring out which types will actually work in ROS's macros.

I'm sure there are reasonable historical reasons for why ROS is code generating header files full of macros nested 5 levels deep, but IMHO it has resulted in an unreasonable level of complexity for something as simple as logging a string. Perhaps someone can post an example of what all the macros actually boil down to in the end.