環境
本記事は以下の環境を想定して記述されている。
項目 | 値 |
---|---|
OS | Ubuntu 22.04 |
ROS | ROS 2 Humble |
概要
rosbag2
は、ROSトピックをファイルとして保存、再生するツールである。
データを保存して再生することで同じ入力を繰り返し与えられるようになる。
これにより、デバッグを容易にしたり、ソフトウェアの性能、品質の変化を繰り返し検証したりすることが可能になる。
この記事では、rosbag2
の基本的な使い方を解説する。
前提
この記事では、実行結果を示すためにURDFを記述する2で作成したファイルを利用する。
そのため、~/ros2_lecture_ws/
にROS 2のワークスペースがあり、その中にurdf2
パッケージがあることを前提とする。
インストール
rosbag2
は基本的にros2 bag
コマンドで使用する。
コマンドが認識されるように、必要なパッケージを以下のコマンドでインストールする。
このコマンドは、rosbag2
に関連するパッケージをまとめてインストールする。
sudo apt install ros-humble-rosbag2
ros-humble-ros-base
パッケージを含む方法でROS 2 Humbleをインストールしていれば、既にインストールされているはずである。(参考)
rosbag2のCLIツール
ros2 bag
コマンドの代表的なサブコマンドとして、以下の3つが挙げられる。
以下では、順番に例を示しながら説明する。
-
record
: トピックを記録しファイルに保存する -
info
: ファイルの情報を表示する -
play
: ファイルを再生する
データの記録
よく用いられる使い方を実行例とともに示す。
ros2 bag record -a
全てのトピックを保存する。
ここでは、simple_urdf5.urdf
のジョイント角度を変化させたときに流れるROSトピックを保存する例を示す。
1つ目のターミナルで、ROSトピックを保存するコマンドを実行する。
記録をやめるときは、ctrl+C
でプログラムを終了させればよい。ただし、実際に終了させるのは2つ目のターミナルでジョイントを操作した後にする。
# 1つ目のターミナルで実行
$ source /opt/ros/humble/setup.bash
$ ros2 bag record -a
[INFO] [1712829858.209008073] [rosbag2_recorder]: Press SPACE for pausing/resuming
[INFO] [1712829858.209803309] [rosbag2_storage]: Opened database 'rosbag2_2024_04_11-10_04_18/rosbag2_2024_04_11-10_04_18_0.db3' for READ_WRITE.
[INFO] [1712829858.210174977] [rosbag2_recorder]: Listening for topics...
[INFO] [1712829858.210181207] [rosbag2_recorder]: Event publisher thread: Starting
[INFO] [1712829858.211180195] [rosbag2_recorder]: Subscribed to topic '/tf'
[INFO] [1712829858.211784093] [rosbag2_recorder]: Subscribed to topic '/rosout'
[INFO] [1712829858.212109612] [rosbag2_recorder]: Subscribed to topic '/tf_static'
[INFO] [1712829858.212514715] [rosbag2_recorder]: Subscribed to topic '/robot_description'
[INFO] [1712829858.212934563] [rosbag2_recorder]: Subscribed to topic '/parameter_events'
[INFO] [1712829858.213463362] [rosbag2_recorder]: Subscribed to topic '/joint_states'
[INFO] [1712829858.213749679] [rosbag2_recorder]: Subscribed to topic '/events/write_split'
[INFO] [1712829858.213811301] [rosbag2_recorder]: Recording...
[INFO] [1712829861.828320826] [rosbag2_cpp]: Writing remaining messages from cache to the bag. It may take a while
[INFO] [1712829861.829472027] [rosbag2_recorder]: Event publisher thread: Exiting
[INFO] [1712829861.829592256] [rosbag2_recorder]: Recording stopped
[INFO] [1712829861.832200216] [rosbag2_recorder]: Recording stopped
ターミナルの出力からは、保存されるトピック名が確認できる。
2つ目のターミナルで以下のコマンドを実行し、表示されたウインドウのスライダーからジョイント角度を変化させる。
# 2つ目のターミナルで実行
# urdf2パッケージを実行するために必要な依存パッケージをインストールする。
$ cd ~/ros2_lecture_ws
$ rosdep install --from-paths src/urdf2 -y
$ source install/setup.bash
# simple_urdf5.urdfを表示する
$ ros2 launch urdf_launch display.launch.py urdf_package:=urdf2 urdf_package_path:=urdf/simple_urdf5.urdf
ジョイントをいくらか動かしたら、2つのターミナルのプログラムを終了させる。
実行を終了すると、新しくディレクトリが作成され、その中にいくつかのファイルが作成されていることが分かる。
拡張子.db3
で終わっているファイルにデータの中身が保存され、メタデータはmetadata.yaml
に保存される。(注:デフォルトのrosbag2のデータフォーマットについて)
$ ls rosbag2_2024_04_11-09_53_38
metadata.yaml rosbag2_2024_04_11-09_53_38_0.db3
ros2 bag record <トピック名...>
特定のトピックのみを保存できる。トピックは複数指定できる。
# /joint_states のみを保存する例
$ ros2 bag record /joint_states
[INFO] [1712829884.133863422] [rosbag2_recorder]: Press SPACE for pausing/resuming
[INFO] [1712829884.134576549] [rosbag2_storage]: Opened database 'rosbag2_2024_04_11-10_04_44/rosbag2_2024_04_11-10_04_44_0.db3' for READ_WRITE.
[INFO] [1712829884.134876560] [rosbag2_recorder]: Listening for topics...
[INFO] [1712829884.134890311] [rosbag2_recorder]: Event publisher thread: Starting
[INFO] [1712829884.135692144] [rosbag2_recorder]: Subscribed to topic '/joint_states'
[INFO] [1712829884.135725894] [rosbag2_recorder]: Recording...
[INFO] [1712829884.135854573] [rosbag2_recorder]: All requested topics are subscribed. Stopping discovery...
[INFO] [1712829887.053425270] [rosbag2_cpp]: Writing remaining messages from cache to the bag. It may take a while
[INFO] [1712829887.054379654] [rosbag2_recorder]: Event publisher thread: Exiting
[INFO] [1712829887.054488154] [rosbag2_recorder]: Recording stopped
[INFO] [1712829887.055596658] [rosbag2_recorder]: Recording stopped
ros2 bag record -o <ディレクトリ名>
出力ディレクトリ名を指定できる。
# rosbag_outputというディレクトリ名で保存する例
$ ros2 bag record -a -o rosbag_output
[INFO] [1712829921.680191718] [rosbag2_recorder]: Press SPACE for pausing/resuming
[INFO] [1712829921.681924127] [rosbag2_storage]: Opened database 'rosbag_output/rosbag_output_0.db3' for READ_WRITE.
[INFO] [1712829921.682711612] [rosbag2_recorder]: Listening for topics...
[INFO] [1712829921.682730551] [rosbag2_recorder]: Event publisher thread: Starting
[INFO] [1712829921.685310849] [rosbag2_recorder]: Subscribed to topic '/tf'
[INFO] [1712829921.686693247] [rosbag2_recorder]: Subscribed to topic '/rosout'
[INFO] [1712829921.687176454] [rosbag2_recorder]: Subscribed to topic '/tf_static'
[INFO] [1712829921.687789462] [rosbag2_recorder]: Subscribed to topic '/robot_description'
[INFO] [1712829921.688541636] [rosbag2_recorder]: Subscribed to topic '/parameter_events'
[INFO] [1712829921.689306413] [rosbag2_recorder]: Subscribed to topic '/joint_states'
[INFO] [1712829921.689700160] [rosbag2_recorder]: Subscribed to topic '/events/write_split'
[INFO] [1712829921.689764745] [rosbag2_recorder]: Recording...
[INFO] [1712829925.407919031] [rosbag2_cpp]: Writing remaining messages from cache to the bag. It may take a while
[INFO] [1712829925.409472084] [rosbag2_recorder]: Event publisher thread: Exiting
[INFO] [1712829925.409651664] [rosbag2_recorder]: Recording stopped
[INFO] [1712829925.411853042] [rosbag2_recorder]: Recording stopped
その他にも様々なオプションがある。使い方はros2 bag record --help
を実行すると確認できる。
データの情報表示
ros2 bag info <保存ディレクトリ名>
を実行すると、保存したデータの情報を確認できる。
$ ros2 bag info rosbag2_2024_04_11-10_04_18
Files: rosbag2_2024_04_11-10_04_18_0.db3
Bag size: 45.2 KiB
Storage id: sqlite3
Duration: 3.586s
Start: Apr 11 2024 10:04:18.213 (1712829858.213)
End: Apr 11 2024 10:04:21.800 (1712829861.800)
Messages: 84
Topic information: Topic: /events/write_split | Type: rosbag2_interfaces/msg/WriteSplitEvent | Count: 0 | Serialization Format: cdr
Topic: /joint_states | Type: sensor_msgs/msg/JointState | Count: 36 | Serialization Format: cdr
Topic: /parameter_events | Type: rcl_interfaces/msg/ParameterEvent | Count: 0 | Serialization Format: cdr
Topic: /robot_description | Type: std_msgs/msg/String | Count: 1 | Serialization Format: cdr
Topic: /tf_static | Type: tf2_msgs/msg/TFMessage | Count: 1 | Serialization Format: cdr
Topic: /rosout | Type: rcl_interfaces/msg/Log | Count: 10 | Serialization Format: cdr
Topic: /tf | Type: tf2_msgs/msg/TFMessage | Count: 36 | Serialization Format: cdr
データの再生
スライダーでジョイントを操作したときに記録したrosbagファイルを再生し、同じようにジョイントが動くことを確かめる。
1つ目のターミナルでRvizを実行する。
ros2 run rviz2 rviz2
RvizのGUIウインドウを操作して、Fixed Frameを「base_link」とし、TF、RobotModelを表示させるようにする。
また、左のパネルのRobotModelの項目を開き、以下の画像のように、「description_topic」を「robot_description」に指定する。
2つ目のターミナルで、先程記録したrosbagファイルのディレクトリを引数として、ros2 bag play
コマンドを実行する。
$ ros2 bag play rosbag2_2024_04_11-10_04_18/
[INFO] [1712830034.099801306] [rosbag2_storage]: Opened database 'rosbag2_2024_04_11-10_04_18/rosbag2_2024_04_11-10_04_18_0.db3' for READ_ONLY.
[INFO] [1712830034.099846307] [rosbag2_player]: Set rate to 1
[INFO] [1712830034.106853886] [rosbag2_player]: Adding keyboard callbacks.
[INFO] [1712830034.106884151] [rosbag2_player]: Press SPACE for Pause/Resume
[INFO] [1712830034.106888756] [rosbag2_player]: Press CURSOR_RIGHT for Play Next Message
[INFO] [1712830034.106892600] [rosbag2_player]: Press CURSOR_UP for Increase Rate 10%
[INFO] [1712830034.106896418] [rosbag2_player]: Press CURSOR_DOWN for Decrease Rate 10%
[INFO] [1712830034.107178461] [rosbag2_storage]: Opened database 'rosbag2_2024_04_11-10_04_18/rosbag2_2024_04_11-10_04_18_0.db3' for READ_ONLY.
すると、Rviz上にロボットモデルが現れ、GUIウインドウで操作したときと全く同じようにロボットが動く。
これは、データを記録したときと同じ情報がROSネットワークに流れ、Rvizがそれらを受け取って表示しているためである。
具体的には、ロボットモデル、TF、joint_states等のトピックがrosbagファイルから再生されている。
launchファイル内で使う
rosbag2リポジトリでは、launchファイル内でros2 bag
コマンドを使う例が紹介されている。
launchファイル内で他のプログラムと合わせて記録や再生できるようになると便利な場合がある。
以下に上記リンクで示されているlaunchファイルの実装(rosbag_record_all.launch.py)を示す。
なおros2 bag
コマンドに限らず、コマンド全般を以下のように実行することが可能である。
import launch
def generate_launch_description():
return launch.LaunchDescription([
launch.actions.ExecuteProcess(
cmd=['ros2', 'bag', 'record', '-a'],
output='screen'
)
])
QoSオーバーライド
ROS 2ではトピックごとにQoSが定められている(参考:実習ROS 2:QoSを設定する)ため、rosbagファイルにもQoSの設定が保存される。
rosbagファイルはデフォルトでは保存したときと同じQoSで再生されるが、QoSを上書きして再生することもできる。
上書きするQoS設定はyamlファイルで行い、再生時に以下のようにパスを指定して実行する。
ros2 bag play <rosbagディレクトリへのパス> --qos-profile-overrides-path <yamlファイルへのパス>
設定ファイルの例をqos_override.yamlに示す。以下の例では、joint_states
トピックのReliabilityポリシーとHistoryポリシーを設定している。
設定できる項目の一覧はROS 2公式ドキュメントに記載がある。
/joint_states:
reliability: best_effort
history: keep_all
その他のツール
rosbagファイルに記録されているトピックの値をグラフとして可視化し、デバッグを容易にするツールとして、rqt_bagと、plotjugglerがある。
2つのツールの具体的な説明は実習ROS 2:ROStoolsに記載されている。
デフォルトのrosbag2のデータフォーマットについて
ROS 2 Humbleでは、データはデータベースシステムの一種であるSQLiteのデータ構造で保存される。
これに対して、ROS 2 Iron以降のディストリビューションでは、デフォルトのデータフォーマットがMCAPが使われている。この場合、データファイルの拡張子は.mcap
となる。
mcapは、ロボット向けの利用を想定して設計されたデータコンテナフォーマットであり、以下のような特徴がある。
- マルチモーダルなセンサデータや、小さなデータ量で高頻度でPub/Subされるようなメッセージのロギングに適している
- 書き込み性能が優れており、SQLite形式よりも信頼性の高いデータ保存が可能
- Protocol Buffers, JSONなどといった、特定のシリアライゼーションフォーマットに依存しない
ROS 2 Iron以降のディストリビューションにおいても、SQLite形式でのrosbag2ツールの利用は可能である。
ROS 2 Humbleにおいても、ros-humble-rosbag2-storage-mcap
パッケージをインストールすることで、mcap形式でのデータの扱いが可能になる。
なお、MCAPのツールを用いて、SQLite形式のデータファイルとMCAP形式のデータファイルの相互変換ができる。