この記事の他にも,ロボティクスの辞書 に様々なロボティクスに関する記事をまとめていますので、よろしければそちらもご覧ください!
お疲れ様です。秋並です。
ROSでは、odomという概念があります。
こちら、特に移動ロボット(AMR)のナビゲーションの際などに非常に重要になりますが、中々分かりにくいので今回は図解も交えてできる限り分かりやすく解説したいと思います。
目次
※ 一般的なodometryについての知識がある方は、「odomフレーム」からお読みいただいてもOKです。
【前提知識】odometryとは
まず、最初にodometryとはなんなのかを説明します。
odometryとは、
- AMRがセンサなどの情報をもとに、現在位置を推定する方法
であり、移動ロボットにとって重要な機能の一つになります。
ここでは、各手法の具体的なアルゴリズムについては触れませんが、最も一般的なものとして
- 「車輪のエンコーダ情報をもとにAMRの移動量を計算し、自己位置を推定」する Wheel Odometry
があります。
なお、Wheel Odometryを略してodometryと呼ぶことがありますが、
- ROSにおけるodomはwheel odometryに限らず、LiDARやIMUなど様々なセンサをもとに推定した最終的な自己位置
であることに注意してください(もちろん、使っているセンサが、車輪のエンコーダ1つのみの場合は、odom = wheel odometryになります)。
odomフレーム
ここからは、odomフレームについて解説していきます。
なお、odomフレームを説明するには
- mapフレーム
- base_footprintフレーム
についても、知っておく必要があるので3つのフレームについて順番に説明します。
まず、mapフレームは
- SLAMなどで作成した地図の原点位置
になります(「mapフレームの原点」は、任意の場所に設定できるので必ずしも地図の隅っこになるとは限らないことに注意してください)。
次に、odomフレームはodometryの時にも述べたように
- AMRの初期位置
になります。
また、odomフレームは、一般にbase_footprintフレームを子供に持ちます。
ここで、base_footprintフレームは、
- AMRが初期値位置から、どのくらい移動した位置にいるか(=「odomフレーム原点」からの移動量)。
を示します。
ROSにおいて、base_footprintフレームは、一般に「移動ロボットの中心座標の投影点の座標」、すなわち
- x,y座標はロボットの中心位置だが、zは地面に投影した位置
を原点とするフレームになります(移動ロボットでは一般に、「地面を基準として経路などを計算する」ため、z軸はロボットの中心ではなく、地面の表面位置とします)。
上記3つのフレームを一つにまとめると
- mapフレーム → odomフレーム → base_footprintフレーム
のような、ツリー構造で示すことができます。
なお、ROSでは「TF」と呼ばれるライブラリで、各フレームをツリー構造で管理しています。
「TFで管理されているツリー構造」そのものをTFと呼ぶことも多いので、この記事でも以降はTFと呼ぶこととします(厳密な定義からは外れるかもしれませんが)。
ここで、上記のTFでAMRを扱う場合、
- 電源ON時にAMR本体は、地図上のどこにいるか分からない
という問題が発生します。
地図上のどこにいるか分からないということは、すなわち
- mapフレームを原点とした時の、「odomフレームの(原点)位置」が分からない
ということになります。
そのため、「mapフレームをTFの根元のフレーム」とした場合は、
- AMRの初期位置が地図上のどこにあたるか
を気にする必要が出てきます。
そのため、rvizなどでは、「2D Pose Estimate」ボタンを使うことで、AMRの初期位置を設定することができます。
これは、要するに
- map → odomフレームへの変換を設定
しているということです。
正確には、
- 2D Pose Estimateで、推定位置を設定し、その情報をもとにAMCLというアルゴリズムにより、map → odom への変換が計算されています。
なお、AMRの初期位置は毎回同じとは限らないので、odomフレームの位置はその時々によって変わることもあり得ます。
ここで、「odomフレームの位置がその都度変わると座標の扱いなどが変わってしまい、不便なのではないか」と思う方もいるかと思いますが、それは問題ありません。
なぜなら
- ユーザー側が、navigationなどの際に指定する座標は「mapフレームにおける座標」
だからです。
odomフレームの位置が変わったとしても、「mapフレームから見たAMRの位置」は変わらないため、ユーザー側は内部的な事情を気にせずnavigationなどの指示を出すことができます。
ここまで話した内容をもとに
- AMRの初期位置の設定(=map → odomフレームの設定)
- ナビゲーション指示によるAMRの移動(ユーザーは、「mapフレームから見た」座標位置をゴール位置として指定)
を動画にすると以下のようなイメージになります。
/odomトピック
ここまで、odomフレームについて解説してきましたが、odomにはTFでのフレームの他に、/odomトピックが存在します。
odomトピックのメッセージは nav_msgs/msg/Odometry.msg という型で、
- odomフレームを原点とした時の位置、姿勢
- odomフレームの子フレームの現在速度、各速度(=ロボットの現在速度、各速度)
などが定義されています。
std_msgs/Header header
- stamp # タイムスタンプ
- frame_id # 基準フレーム(例: "odom")
string child_frame_id # ロボットのフレーム(例: "base_footprint")
geometry_msgs/PoseWithCovariance pose
- pose # 位置(x,y,z) + 姿勢(クォータニオン)
- covariance # 6x6共分散行列(不確かさ)
geometry_msgs/TwistWithCovariance twist
- twist # 線速度(vx,vy,vz) + 角速度(wx,wy,wz)
- covariance # 6x6共分散行列(不確かさ)
例えば、
- 各センサから算出したオドメトリをodomトピックとしてPublishし
- それらのトピックをSubscribeしたノードが、最終的なオドメトリを計算し、odom→base_footprintフレームへの変換を/tfトピックに配信する
のように使われます。
すなわち、odomトピックは
- 他ノードにodomtry情報を渡したい場合
に使います。
odomフレームと/odomトピックの違い
ここまでの内容をまとめると、odomフレームとodomトピックの違いは以下になります。
- odomフレーム
- TFにおけるフレーム
- 「全てのセンサ」からの情報を統合して算出した「最終的な」位置・姿勢
- 正確には、odomフレームを原点とした時の、base_footprintフレームの(原点)位置
- odomトピック:
- 他ノードに配信/購読されるトピック
- 「各センサ」によって算出した位置や姿勢
- 得られる情報はセンサによって異なる(GPSの場合、姿勢情報は取れないなど)
- 必ずしもodomトピックが最終的な位置、姿勢とは限らない
最後に
今回は、ROS におけるodomについて解説しました。
TFの存在、mapフレームとの関係、/odomトピックとの違い等、混乱しやすい部分が多い概念だと思うので、この記事をきっかけに少しでも理解の手助けになれば幸いです。















