C++
ROS
ロボット

ROS講義06 ROS Logger

環境

この記事は以下の環境で動いています。

項目
CPU Core i5-8250U
Ubuntu 16.04
ROS Kinetic

インストールについてはROS講座02 インストールを参照してください。
またこの記事のプログラムはgithubにアップロードされています。ROS講座11 gitリポジトリを参照してください。

概要

printfデバッグはお手軽で有用な方法です。ROSでもprintfを使うことができますが、多数のROSノードが実行される状況では多数のノードのprintfが混ざってしまうために少々使いにくなります。
その代わりにROSではROS loggerという仕組みが用意されています。ターミナルで表示できるだけでなく、rqt_consoleというデバッグ情報を統合的に表示するツールもあります。このようなツールがあるために大規模なシステムではソフトウェア的なエラーメッセージはROS loggerを使います。
後々書きますが、ハードウェアの接続エラーには「diagnostics」という別の仕組みを使います。

Roslogerをpublishするソースコード

ソースコード

basic_lecture/src/basic_logger.cpp
#include "ros/ros.h"
#include <string.h>

int main(int argc, char **argv)
{
    ros::init(argc, argv, "logger");
    ros::NodeHandle n;
    ros::Rate loop_rate(1);
    /*if( ros::console::set_logger_level(ROSCONSOLE_DEFAULT_NAME, ros::console::levels::Debug) ) {
        ros::console::notifyLoggerLevelsChanged();
    }*/

    int count=0;
    while (ros::ok()){
        ROS_DEBUG("log:%i", count);
        ROS_INFO( "log:%i", count);
        ROS_WARN( "log:%i", count);
        ROS_ERROR("log:%i", count);
        ROS_FATAL("log:%i", count);

        ros::spinOnce();
        loop_rate.sleep();
    }
    return 0;
}

ROS_BEBUG()などはprintf()と同等に使うことができます。1つ違う点は最後尾に\nが自動で追加されるので入れる必要はありません。

launchファイル

basic_lecture/launch/logger.launch
<launch>
  <node name="logger1" pkg="basic_lecture" type="basic_logger" />
  <node name="logger2" pkg="basic_lecture" type="basic_logger" />
</launch>

CmakeListの設定

basic_lecture/CMakeLists.txtへの追加
add_executable(basic_logger src/basic_logger.cpp)

target_link_libraries(basic_logger
  ${catkin_LIBRARIES}
)

ビルド

cd ~catkin_ws
catkin_make

実行

ノード単体での実行

1つ目のターミナル
roscore
2つ目のターミナル
rosrun basic_lecture basic_logger 

表示例

以下のように表示されます。

[ INFO] [1525732240.098944582]: log:0
[ WARN] [1525732240.098974515]: log:0
[ERROR] [1525732240.098999224]: log:0
[FATAL] [1525732240.099023751]: log:0

Debugの表示方法

初期設定ではDEBUGレベルのメッセージは表示されません。これを表示するようにするには以下をターミナルに打ち込むか、

rosservice call /(node_name)/set_logger_level ros.(package_name) (logger_level)

もしくはソースコード中に以下のように追記します(コメントアウトされている部分でです)。

#include <ros/console.h>
if( ros::console::set_logger_level(ROSCONSOLE_DEFAULT_NAME, ros::console::levels::Debug) ) {
   ros::console::notifyLoggerLevelsChanged();
}

launch時でのROS logger

実行
roslaunch basic_lecture logger.launch

表示

[ERROR] [1525732240.098999224]: log:0
[ERROR] [1525732240.098999224]: log:0
[FATAL] [1525732240.099023751]: log:0
[FATAL] [1525732240.099023751]: log:0

この場合はError、Fatalのレベルしか表示されません。

rqt_console

上記のlaunchを動かしたまま以下のコマンドを実行します。

rosrun rqt_console rqt_console

rqt_console.png

このようなGUI画面が表示されます。真ん中の「Exlude Messages」で表示するloggerを選択できます。

コメント

大規模でエラーの管理が難しくなるとprintfよりかは便利に使えるツールです。基本的に使うのはInfoとErrorの2つで、ノードを単体で動かしている時に見たいログをInfoで書きます。そのノードの機能に影響が起きるような状況が起きたらErrorでログを出力します。

参考

ROS wiki: http://wiki.ros.org/roscpp/Overview/Logging

目次ページへのリンク

ROS講座の目次へのリンク