rosbagの便利オプション

実験時のセンサデータとかをすべて記録しておけるrosbagはROSの便利機能の中でもかなり有用な機能です。センサが手元に無くても記録したデータを再生することで、システムがちゃんと動作するか確認することが出来ます。
一方でrosbagには独自の使い方があったりするので、ここで一度出来ること&出来ないことを確認してみたいと思います。

事前に今流れているトピックを確認する

rostopic list

#例
rostopic list | grep cmd #「cmd」を含むものだけ表示

まず最初に記録すべきトピック、記録しなくてもいいトピックを見極めましょう。grepによる検索と合わせて使うことも多いです

record関連

特定のトピックだけrecord

rosbag record (トピック名) (トピック名) ...

#例
rosbag record /joy /cmd_vel
rosbag record -O input_data /joy #「input_data.bag」ファイルに「/joy」トピックを記録

特定のトピックだけを狙って記録する方法です。すべてのデータを記録するとファイルサイズがGB単位になって大変な時はこのやり方もありです。
しかし、あとになってこのデータ取っておけば良かった、となること多しなので慎重に決めましょう。

すべてのトピックをrecord

rosbag record -a

すべてのトピックを記録する方法です。後で完全にシミュレート出来ますが、ファイルサイズが膨大になります。小さなシステムならむしろおすすめです。再生したときにTFが上手く表示されない時は、下のplay –clockを使いましょう。

正規表現にマッチするトピックだけrecord

rosbag record -e "(正規表現)"

#例

rosbag record -e "/MyRobot/.*" #「/MyRobot/」で始まるトピックのみ記録する
rosbag record -e ".*(joy|lidar|imu).*"  #「joy」「lidar」「imu」のいずれかを含むトピックのみ記録する

〇〇で始まるトピック等、一部のトピックだけ記録したいときや、センサからのメッセージだけ記録したいときによく使います。

正規表現にマッチするトピックだけ除外する

rosbag record -x "(正規表現)"

#例
rosbag record -a -x ".*robot.*" #「robot」を含むトピックを除外する
rosbag record -a -x ".*(image|velodyne).*" #「image」または「velodyne」を含むトピックを除外する

正規表現にマッチしたトピックだけを除外することができます。必ず-aオプションか-eオプションと共に使う必要があります。データが大きすぎてrecordするとbagファイルの容量が大きくなってしまうときに有効です。

play関連

ループ再生

rosbag play test.bag -l
# または
rosbag play test.bag --loop

bagファイルをリピート再生します。センサデータを使ってシステムのチェックを行いたい時等、何回も再生しなおすのが面倒な時に便利です。

ちなみに通常の方法でも同様ですが、再生中にスペースキーを押すとポーズが出来ます。さらに、ポーズ中に「s」キーを押すと0.1秒ずつ再生をすすめることができます。

bagファイルのクロックを使用

rosparam set /use_sim_time true #roscoreから出力されるクロックを停止
rosbag play test.bag --clock #bagファイルのクロックを出力

通常bagファイルを再生するときはroscoreのクロック(現在の時間)を使用しますが、時間が重要な場合(TFなど)はbagファイル記録時の時間を使うほうが良いです。一行目でroscoreのクロックを無効にし、二行目でバグファイルの時間を基準の時間として再生します。

倍速・スロー再生

rosbag play -r 0.5 test.bag

データを0.5倍速で再生します。データをゆっくり見たいときに。

途中から再生

rosbag play -s 45 -u 10 test.bag

45秒からスタートして10秒間再生します。一部だけ集中して見たい時や途中から見たいときに使います。-rや-lと合わせて使うことも多いです。

トピック名をリネームして再生

rosbag play test.bag tf:=tf_old

tfという名前のトピックをtf_oldにリネームして再生します。同じ名前のトピックがあってエラーが起きるときに使います。

検証関連

bagファイルの情報を表示

rosbag info test.bag

バグファイルにどんなトピックが記録されているか等の情報を見ることが出来ます。

ROS初心者の方はまずはこちらの本がオススメです。

catkin_make時の便利なコンパイルオプション

はじめに

ROSプログラムをコンパイルする時はcatkin_makeを使っているけれど、仕組みはいまいち分かっていない。(そもそもmakeって何かも良くわかっていない)

そんなあなたも取り敢えず試せる便利なコンパイルオプションがこちら。

msg.hが無いと言われる他

ちゃんとCMakelist.txtに書いてるのに作られてない…

これはおそらくメッセージを作るより前にコンパイルエラーで止まってるのが原因。次のオプションで、エラーが起きたプログラムはとりあえず無視して最後までコンパイルできる。

catkin_make -i

もう一度コンパイルするとエラー出ない。

warningめっちゃ出るんだけど…

前はコンパイル出来たやつがあるときからめっちゃwarning出ることがある。またはerror[warning]みたいになって止まる。

そんなとき、エラーを全無視するオプションがこちら。

catkin_make --cmake-args -DCMAKE_CXX_FLAGS="-w"

エラーを放置することになるのであんまりよくないかも。

パッケージを除外する

他の人が作ったパッケージは動かないことが往々にしてある。その人が帰ってくるまで待つとして、その間そのパッケージは無視してコンパイルしたい時は

catkin_make -DCATKIN_BLACKLIST_PACKAGES="package1;package2"

ROSのTFとは?簡単に説明(サンプルコード付き)

はじめに

ROSの便利機能にして基本機能TF(Transform、トランスフォーム)について、出来るだけ難しい言葉を使わずに説明していきたいと思います。

static transformの書き方

TFとは?

TF(transform)とは「ある座標系」と「他の座標系」の位置関係を表すものです。

座標系とは基準点のことで、例えば部屋の基準点なら部屋の隅、ロボットの基準点なら重心、センサの基準点ならセンサ底面などです。

例として次のような車輪ロボットを考えてみます。

車輪ロボットとセンサ

このとき、ロボットの重心位置においたbase_link座標系からセンサのlaser座標系に行くには「x方向に20cm、z方向に10cm」と表現できます。これが「TF」です。

※ 正確には、2つの座標系の関係を3次元で表すには、位置(x,y,z)と姿勢(ロール、ピッチ、ヨー)の6つのパラメータが必要です。また、姿勢を4つのパラメータで表す方法(4元数、クォータニオン)もあります。

TFの特徴

複数のTFをつなげることが出来る

TFは2つの座標系の位置関係を表すものですが、普通ロボットや自動車は沢山の部品で出来ています。それらを1つの基準点(たとえば上の図のロボット座標系)からすべて表すのは大変です。
したがってTFは数珠つなぎに記述することが一般的です。例えば先程のロボットの例で、車体の上面の中心にtop_center座標系を作るとレーザセンサやカメラまでの位置を計測しやすくなるため便利になります。base_link座標系→top_center座標系→laser、camera座標系と数珠つなぎになっているのが分かります。

ロボットの座標系

ROSでは座標系のことを「frame(フレーム)」と呼びます。rvizに表示される黄色の線は「あるフレーム」から「他のフレーム」へのTF、つまり一方のフレームから見たもう一方のフレームの位置と姿勢がROSに登録されている事を示しています。元になるフレームを「parent frame(親フレーム)」または単に「frame」、目的のフレームを「child frame(子フレーム)」と呼びます。

2フレーム間のTFをROSに登録する

ROSで利用するすべてのTFはROSシステムに登録されます。親フレーム名、子フレーム名、位置関係、タイムスタンプ等の情報をメッセージにまとめてROSに送信します。またTFには有効期限があるため、1度登録したら終わりではなく10ms毎など定期的に登録し直す必要があります。(例外として、有効期限が無いstatic_transformというものもあります)

つながっているTF同士の位置関係は自動計算される

すべてのフレーム間の位置関係をROSに登録しておくことで、任意の2フレーム間のTFをROSが自動計算してくれます。例えば上の例でbase_linkフレームとcameraフレームは直接繋がっていませんが、これを自動計算できる仕組みがROSに備わっています。

逆に、TFが途中で切れていると、2フレーム間のTFが取得できず、エラーになります。

ROSに登録されてから一定時間経つと無効になる

TFは一度誰かが発信してROSシステムに登録された後、一定時間経つと無効になります。ずっと表示させたければすべてのTFを定期的に再発信する必要があります。

静的TFと動的TF

TFには例えばロボットのセンサのように位置関係が永久に変わらないものと、部屋からみたロボットの位置のように変わり続けるものがあります。前者を静的TF、後者を単にTFと言います。

TFを発信する

静的TFを発信するコードを書いてみます。最も簡単なのは次のようなlaunchファイルを作ることです。

<launch>

  <node pkg="tf" type="static_transform_publisher" name="robot_to_sensor" args="0.2 0 0.1 0 0 0 robot sensor 10" />

</launch>

「<node」 から 「/>」までがTFを発信するプログラムを実行する部分です。それぞれの引数の意味は次のとおりです。

引数値の例備考
pkg“tf” (固定)パッケージの名前
type“static_transform_publisher” (固定)プログラムの名前
name“(任意の名前)”実行時の名前。同名のプログラムがあると実行できないので適宜変更。
args(例)”0.2 0 0.1 0 0 0 robot sensor 10″
“[x] [y] [z] [yaw] [pitch] [roll] [parent_frame] [child_frame] [Hz]”
x方向、y方向、z方向、ヨー、ピッチ、ロール、親フレーム、子フレーム、発信の間隔[Hz]

nameが同じプログラムを同時に作るとエラーになります。これを自分のパッケージ→lanchフォルダの中に入れて実行すると、argsで指定したTFが発信されます。

roslaunch my_package static_tf.launch

発信されているTFをrvizで見てみましょう。rvizを起動して、左下部あたりにある「Add」をクリック、「By display type」から「TF」を追加して下さい。

静的TFが表示された!

2つの座標軸が表示されていれば成功です!
rvizの左側の「Fixed Frame」を「robot」や「sensor」に切り替えることで、どのフレームを中心に据えるか選ぶ事が出来ます。lanchファイルで複数のプログラムを起動すれば、TFの数珠つなぎも簡単に実現できます。

<launch>

  <node pkg="tf" type="static_transform_publisher" name="robot_to_sensor" args="0.2 0 0.1 0 0 0 robot sensor 10" />
 <node pkg="tf" type="static_transform_publisher" name="map_to_robot" args="1.0 0.5 0 0 0 0 map robot 10" />

</launch>

しかし、これだと常に同じTFしか発信できません。
次回は常に変化する位置関係の発信方法をご紹介したいと思います。

ROS初心者の方はまずはこちらの本がオススメです。

動的TFの書き方>>