BlackBoxはROS2用のロギングライブラリです。このライブラリを使用すると、プロセス内でrosbagファイル(Mcap形式)を作成できるため、rosbagファイル作成用の専用ノードを起動する必要がなく、Pub/Sub操作も不要になります。 このライブラリを活用することで、実行時のコンソールログ、独自メッセージ、Pub/Subメッセージを1つのrosbagファイルにまとめて保存することが可能です。作成されたrosbagファイルはrosbag2やFoxgloveでそのまま解析やシミュレーションを行うことができます。
Foxgloveは、Foxglove Studio(GUIツール)とFoxglove Bridge(ROS2の通信をWebSocketに変換するツール)から構成されています。Foxglove Studioはmcapファイルを直接解析でき、Windows、Mac、スマホ(ブラウザ)で動作します。ROS2が起動しているLinux上でFoxglove Bridgeを起動し、Foxglove StudioでそのIPとポート番号を指定することで接続できます。
Foxglove Studioのインストール
Foxglove Bridgeのインストール
Foxglove Studioは日本語に対応しており、設定から言語変更が可能です。また、フレームレートの調整も設定画面から行えます。
sudo apt install -y ansibleros2ワークスペースのsrc内
git clone https://github.com/Ayrton2718/blackbox.git
cd blackbox
ansible-playbook --ask-become-pass ansible/dev.ymlこのライブラリを使用するには、BlackBoxNodeを継承する必要があります。rclcpp::Nodeの継承は避けてください。
class TestNode : public blackbox::BlackBoxNode {
public:
TestNode(const std::string &name_space = "")
: blackbox::BlackBoxNode(blackbox::debug_mode_t::DEBUG, "test_node", name_space) {}
};blackbox::debug_mode_t::DEBUGで、このノードのデバッグモードを指定できます(詳しくはLogger)。
実行中のデバッグメッセージをレコードすることができます。ログごとにログの重要度とタグ名を設定することができます。Foxglove StudioのLogパネルを用いることで、ログの出力を確認することができます。ログは、/tagger/namespace/node_nameに格納されています。
blackbox::Logger _log_info;
_log_info.init(this, blackbox::INFO, "log1"); // ログのレベル、ログのタグ
TAGGER(_log_info, "status : OK");BlackBoxNodeでDebugモードを指定することで、そのノードのすべてのLoggerのログがコンソール上に出力されるようになります。
// Debugモード
blackbox::BlackBoxNode(blackbox::debug_mode_t::DEBUG, "test_node", name_space)
// Releaseモード
blackbox::BlackBoxNode(blackbox::debug_mode_t::RELEASE, "test_node", name_space)/// @brief ログの重要度を指定する
enum log_type_t{
ERR = rcl_interfaces::msg::Log::ERROR, // 常にレコード、DebugモードではSTDOUT
WARN = rcl_interfaces::msg::Log::WARN, // 常にレコード、DebugモードではSTDOUT
INFO = rcl_interfaces::msg::Log::INFO, // 常にレコード、DebugモードではSTDOUT
DEBUG = rcl_interfaces::msg::Log::DEBUG, // Debugモードのときだけレコード + STDOUT
};パッケージ内の内部変数等をレコードするライブラリです。数値型を持つメッセージであれば、Foxglove StudioのPlotパネルと連携させることで、グラフを表示することができ、実行中はFoxglove Bridge経由で波形を監視し、実行後は生成されるmcapファイルから解析することができます。レコードしたデータは、/record/namespace/node_nameに格納されています。
Foxglove Plot Panel
Foxglove Plotを使う際は、Rangeを設定すると見やすくなります。
blackbox::Record<std_msgs::msg::Float32MultiArray, true, true> _rec1; // メッセージの型, Publishするか、レコードするか
_rec1.init(this, "rec1", 0); // トピック名, ドロップ数(何回に一回レコードしないか)
std_msgs::msg::Float32MultiArray msg;
msg.data.push_back((float)(param % 100) / 100);
_rec1.record(msg);Publishするデータをレコードすることができます。PubRecordは通常のPublisherをレコードすることが目的で、Recordはノードの内部変数を監視することが目的で作られています(Recordと機能的に違う部分としては、トピック名をユーザが設定できる点のみです)。
blackbox::Topic<std_msgs::msg::String, true> _pub1; // メッセージの型, レコードするか
_pub1.init(this, "pub1", 10, 0); // トピック名、QoS、ドロップ数(何回に一回レコードしないか)
std_msgs::msg::String str;
str.data = "example";
_pub1.publish(str);Subscriptionするデータをレコードすることができます。
blackbox::SubRecord<std_msgs::msg::String, true> _sub1; // メッセージの型, レコードするか
_sub1.init(this, "pub1", 10, [this](std_msgs::msg::String::SharedPtr msg){
TAGGER(_log1_debug, msg->data);
}, 0); // トピック名、QoS、コールバック、ドロップ数(何回に一回レコードしないか)直近のログファイルは/tmp/blackbox_logに保存されます。
過去のログは/var/tmp/blackbox_archiveに保存されます。
/tmp/blackbox_log内には、ノードごとに分かれてMcapファイルが保存されます。
ログファイルの保存場所/tmp/blackbox_logを作成します。
プログラムの実行前に必ずこのコマンドを実行する必要があります。
launchファイルにこのような行を追加すれば、自動的にログファイルの保存場所を作成することができます。
import subprocess
subprocess.run(["blackbox_create"])直近のログファイル/tmp/blackbox_logを/var/tmp/blackbox_archiveに移動させます。
BLACKBOXという名前の外部ディスクがあると、そちらに保存されるようになります。
こちらもlaunchファイルに追加することで、自動的にログファイルがアーカイブされるようになります。
注意点としては、ログファイルの大きさによっては、launchの起動が遅くなる可能性があります。
対策として、ros2をsystemdで起動するようにし、サービス終了時にアーカイブするようにすることを推奨します。
import subprocess
subprocess.run(["blackbox_archive"])
subprocess.run(["blackbox_create"])/tmp/blackbox_logにある、ノードごとに分かれているMcapを一つにまとめることができます。
一つになったmcapファイルは、merged.mcapとして出力されます。
# 最後に実行したものに対して行う
blackbox_merge '/tmp/blackbox_log'
# 過去のBlackBoxに対して
blackbox_merge '/var/tmp/blackbox_archive/blackbox_2024-03-24_21-24-14'
# 現在のディレクトリに対して
blackbox_merge .