A message is basically any predefined datatype that can be used for communication. Images, simple numbers, primitive messages like float, integer, String, even a collection of other messages. You can get a list of messages available by:
rosmsg list
rosmsg info std_msgs/ColorRGBA
rosmsg info std_msgs/Header
rosmsg info sensor_msgs/PointCloud
rosmsg packages
command.Here's the output of the commands. As you can see, a message is basically data that can be moved from one place to another. We'll later see how to create our own messages.
Every node in C++ has a particular structure to follow. Let's discuss this in brief while making a simple node that prints out all the arguments passed. We'll discuss more complicated nodes later. Here are the things that you must follow while making a node using C++. These are made using roscpp (API here).
I'll be writing all this code in a file named "ArgumentParser.cpp" inside the src folder of the package intro_pkg1. We created this folder in the previous tutorial.
Open the "CMakeLists.txt" file of the package intro_pkg1 and do the following amendments
catkin_make
catkin_make -pkg intro_pkg1
. This would invoke catkin_make only on intro_pkg1.roscore
on a terminal. Make sure that roscore is running before running any ROS nodesrosrun intro_pkg1 ArgumentParser
rosrun intro_pkg1 ArgumentParser -a Arg1 -b Arg2
Output of the two commands suggested while running the node. Note that the name of the executable is what we specified in the add_executable function.
Just like C++ nodes, even nodes made using Python have a structure to follow and a few things that must be taken care of. One thing to remember is that python is interpreted, not compiled. Thus no need to build the workspace to run Python nodes, they only need to be made executable. These are made using rospy (API here)
roscd intro_pkg1/scripts/
ls -la
chmod +x *.py
man chmod
and check the output (or click here).ls -la
roscore
on a terminal if it's not already running. Make sure that roscore is running before running any ROS nodes.rosrun intro_pkg1 ArgsParser.py
rosrun intro_pkg1 ArgsParser.py -a ABC --help -b --clear
CPP code for argument Parser
Python code for argument parser
ROS has various options to debug and get insights into what your code is actually doing. It's generally a good idea to put out messages so that you get information about what's happening during the execution of your program, irrespective of it being written in C++ or python.
You can check out the outputs of the C++ code and Python code written for this. The ultimate "CMakeLists.txt" file must look like this. Do not forget to do the essentials for building and executing the C++ or python node as we discussed earlier.
Note that when you run either of the codes, you'll not be able to see the messages of DEBUG level priority on the command line. This is the default setting. To enable the DEBUG messages as well, do the following:
rosnode list
. This will give you the name of the python script assigned by the master server. It's assigned at random by the ros server during runtime. It's "/Debugger_Python_14141_1544275364681" for me.rosconsole set /Debugger_Python_14141_1544275364681 rosout debug
rosconsole set /DebuggerCheck ros.intro_pkg1 debug
rqt_logger_level
command.Python code
C++ Code
There are several ways in which you can set the debugger level (other than the use of rosconsole
as shown above). Let's explore a few of them
We use the rosconsole C++ API for this. The function set_logger_level is used. Here's an example
Setting the logger level to DEBUG
ROS logger is made on top of log4cxx and log4j libraries. These use configuration files. The default configuration file used by ROS (for C++) is present in $ROS_ROOT/config/rosconsole.config (basically, /opt/ros/melodic/share/ros/config/rosconsole.config). You can create a folder named "config" in your package and redeclare the variables. More on this for C++ here and for Python here. Here's a short summary of what to do:
An example is given below
Launch file above
You'll learn more about launch files later on, for now you can skip this section and come back later if you don't completely get this.
Note that the override is on the file location hence the complete list of contents must be available in the ".conf" file that you make. In C++ there are just two and there exist internal definitions, so you can omit the first one (log4j.logger.ros) can be omitted, but for Python, you have to declare the entire thing. It's best that you come here every time you want to change the logger levels for C++ and Python and read this text block.
For more on C++ config file, check out this page (Scroll to section named "2. Configuration")
You can set the environment variables however you want, through launch files is just one method. You can come back here after learning about launch files later. This same section is attached in the end of that page as well (check the Additional > Configuring the Debugger levels of launched nodes on this page).