How it works…

Setting the logging level at compile time requires code modification, which is not recommended for most cases; however, it removes the overhead of all the logging functions below a given level. Also, ROS provides ROSCONSOLE_MIN_SEVERITY as a macro variable, which must be set to the minimum desired severity level. These macros are as follows:

  • ROSCONSOLE_SEVERITY_DEBUG
  • ROSCONSOLE_SEVERITY_INFO
  • ROSCONSOLE_SEVERITY_WARN
  • ROSCONSOLE_SEVERITY_ERROR
  • ROSCONSOLE_SEVERITY_FATAL
  • ROSCONSOLE_SEVERITY_NONE

For example, if the desired logging level is an ERROR or higher message, we should define this in the source code as follows:

#define ROSCONSOLE_MIN_SEVERITY ROSCONSOLE_SEVERITY_ERROR

On the other hand, ROSCONSOLE_MIN_SEVERITY could be defined for all nodes in a package by setting this macro in CMakeLists.txt as follows:

add_definitions(-DROSCONSOLE_MIN_SEVERITY =ROSCONSOLE_SEVERITY_ERROR)

Alternatively, ROS provides more flexible methods of setting the minimum logging level in a configuration file at runtime. We will create a config folder and a file named chapter4_tutorials.config there, with the following content:

log4j.logger.ros.chapter4_tutorials=ERROR

We can also refer to the implementation at chapter4_tutorials/config/chapter4_tutorials.config at GitHub.

Then, we must set the ROSCONSOLE_CONFIG_FILE environment variable to assign the config file, which we created previously. This can be easily done in the launch file as follows (refer to chapter4_tutorials/launch/program1.launch for more information):

<launch> 
<!-- Logger config --> <env name=""ROSCONSOLE_CONFIG_FILE"" value=""$(find chapter4_tutorials)/config/chapter4_tutorials.config""/> <!-- Program 1 --> <node pkg=""chapter4_tutorials"" type=""program1"" name=""program1"" output=""screen""/>
</launch>

Here, the environment variable takes the configuration file defined previously, which contains the logging level specification for each named logger. By default, ROS assigns names after the node's name to the messages. However, in complex nodes, we could provide a name to those messages based upon a given module or its functionality. This can be done with the ROS_<LEVEL>[_STREAM]_NAMED functions (refer to chapter4_tutorials/src/program2.cpp for more information):

ROS_INFO_STREAM_NAMED( ""named_msg"", ""ROS INFO named message."" );

Moreover, with the named message, we can define different initial logging levels for each named message using the configuration file:

log4j.logger.ros.chapter4_tutorials.named_msg=ERROR

Furthermore, ROS provides conditional messages that are only printed when a given condition is satisfied. These can be used using the ROS_<LEVEL>[_STREAM]_COND[_NAMED] functions (refer to chapter4_tutorials/src/program2.cpp for more examples and combinations):

/* Conditional messages: */ ROS_INFO_STREAM_COND(val < 0., ""ROS conditional INFO stream message; val ("" << val << "") < 0"");

There are filtered messages that are inherently similar to conditional messages. However they are enabled to specify a user-defined filter that extends ros::console::FilterBase. The following example can be found in program2.cpp:

/* Filtered messages: */ struct ROSLowerFilter : public ros::console::FilterBase { ROSLowerFilter( const double& val ) : value( val ) {} inline virtual bool isEnabled() { return value < 0.; } double value; }; ROSLowerFilter filter_lower(val); ROS_INFO_STREAM_FILTER( &filter_lower, ""ROS filter INFO stream message; val ("" << val << "") < 0"" );

We can also control how many times a given message should be shown using ROS_<LEVEL>[_STREAM]_ONCE[_NAMED]:

/* Once messages: */ for( int i = 0; i < 10; ++i ) { ROS_INFO_STREAM_ONCE( ""ROS once INFO stream message; i = "" << i ); }

However, it is usually better to show the message with a certain frequency. This is possible by ROS_<LEVEL>[_STREAM]_THROTTLE[_NAMED] throttle messages. Additionally, they have a first argument, which is a period in seconds, which defines the frequency of printing:

/* Throttle messages: */ for( int i = 0; i < 10; ++i ) { ROS_INFO_STREAM_THROTTLE( 2, ""ROS throttle INFO stream message; i = "" << i ); ros::Duration(1).sleep(); }

Finally, the named, conditional, and once or throttle messages can be used together with all the available levels. nodelet also have support in terms of logging messages, where all the macros are discussed until they are valid, but instead using OS_*, we have to use NODELET_*. Basically, these macros will only compile inside nodelets.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.219.95.244