Navigation Stack

    コンテンツ

    • はじめに
    • Navigation Stack概要
      • Navigation Stackとは
      • Navigation Stackの入出力
        • Transform Tree
        • 測域センサ情報(レーザースキャン)
        • 測域センサ情報(ポイントクラウド)
        • オドメトリ情報
        • 地図
        • 駆動(速度)命令
        • その他のメッセージ型
        • サービス型
        • アクション型
    • 各パッケージ仕様
      • move_baseメイン
        • move_base
        • nav_core
      • 自己位置推定関連
        • amcl
        • fake_localization
      • 地図配信
        • map_server
      • コストマップ関連
        • costmap_2d
        • voxel_grid
      • グローバルプランナー関連
        • nav_fn
        • global_planner
        • carrot_planner
      • ローカルプランナー関連
        • base_local_planner
        • dwa_local_planner
      • リカバリー動作関連
        • clear_costmap_recovery
        • rotate_recovery
        • move_slow_and_clear

nav_fn¶

目次

 1. 概要
 2. アルゴリズム
  2.1. ポテンシャルマップの生成
  2.2. ポテンシャルマップ上での経路生成
 3. NavfnROS
  3.1. APIの安定性
  3.2. ROS API
   2.2.1. パブリッシュトピック
   2.2.2. パラメータ
  3.3. C++ API
 4. NavFN
  4.1. APIの安定性
  4.2. C++ API
 5. 内部処理手順
  5.1. メソッドコールシーケンス

1. 概要¶

navfnは、移動体の経路生成に使用可能な、高速で、補間されたナビゲーションを行う機能を、navfn::NavFnクラスで提供しています。 このプランナーは、移動体として円形のロボットを想定しており、コストマップ上で、グリッド内の開始点から終了点を結ぶ最も低コストな経路を探索するための処理を行います。 このナビゲーション機能は、ダイクストラ法を使用して経路計算を行っていますが、将来的にA*ヒューリスティクスが追加されるかもしれません。 また、navfn::NavFnクラスのROSラッパーであるnavfn::NavfnROSオブジェクトも提供しています。navfn::NavfnROSオブジェクトは、 nav_core パッケージで定義されるnav_core :: BaseGlobalPlannerインターフェイスに準拠しており、move_baseノードからグローバルプランナープラグインとしても使用されています。


  • 管理状態: 管理済み
  • 管理者: David V. Lu!! <davidvlu AT gmail DOT com>, Michael Ferguson <mfergs7 AT gmail DOT com>, Aaron Hoy <ahoy AT fetchrobotics DOT com>
  • 著者: Kurt Konolige, Eitan Marder-Eppstein, contradict@gmail.com
  • ライセンス: BSD
  • ソース: git https://github.com/ros-planning/navigation.git (branch: melodic-devel)

2. アルゴリズム¶

navfnは、グローバルコストマップおよびグローバルコストマップ上のスタート座標、ゴール座標を入力値として、経路を出力します。経路を出力するまでの過程は、以下のようになっています。

  1. ポテンシャル計算のために、グローバルコストマップのコストニュートラル値(何もないセルのコスト値)を底上げします。具体的には、-1~254のコスト値を、50~254に変換します。(底上げ後の254が進入不可のセル)

    • 「致命的(Lethal)」コスト → COST_OBS(254)
    • 「内接半径(Inscribed)」コスト → COST_OBS(254)
    • 「未知(Unknown)」コスト → COST_OBS-1(253) ※allow_unknown パラメーターがfalseの場合はCOST_OBS(254)
    • その他のコスト → (コスト値 * 0.8) + 50
  2. コスト値の底上げを行ったコストマップから、ポテンシャルマップを生成します。

  3. ポテンシャルマップ上で、default_tolerance パラメーターに従ったゴール座標の補正を行います。ゴール座標が進入不可のセル内にある場合は、default_tolerance パラメーターの範囲内で、進入可能なセル内の最も近い座標に補正されます。

  4. ゴール座標が到達可能である場合は、ポテンシャルマップ上のスタート座標からゴール座標まで、経路を生成します。


2.1. ポテンシャルマップの生成¶

ポテンシャルマップとは、ゴール位置のセルが最も低く、スタート位置のセルが最も高い(進入不可のセルを除く)地形図のようなものを表現したグリッド地図で、スタート位置にボールを置いて、地形の傾斜に沿ってボールが転がり、最後にゴール位置に到達するというようなイメージで、ポテンシャルマップ上に経路が生成されます。

下の図で、赤いセルがポテンシャル値が大きい(高度が高い)セル、青に近づくほどポテンシャル値が小さく(高度が低く)なり、黒いセルが、ポテンシャル値ゼロ(ゴール地点)のセルになります。

_images/OldNavFn.png

出典:http://wiki.ros.org/global_planner


ポテンシャルマップの生成は、以下のように行われます。

  1. グローバルコストマップと同じサイズのグリッド地図を生成し、最初に、全てのセルをPOT_HIGH(ポテンシャル値未設定)で埋めます。

  2. ゴール位置のセルにポテンシャル値0を設定し、その上下左右の4つのセルを、ポテンシャル値の計算の対象セルに加えます。

  3. 対象セルの位置のコスト値がCOST_OBS(254)である場合は、ポテンシャル値の計算を行わずPOT_HIGHのままとし、次の対象セルの計算に進みます。

  4. 対象セルのポテンシャル値(P(x)とします)の計算は、対象セルに対して、上下のセルの小さいほうのポテンシャル値(P(v)とします)、左右のセルの小さいほうのポテンシャル値(P(h)とします)および自セルのコスト値(cとします)を使って計算します。

    • P(v)がPOT_HIGHである場合は、P(h)にcを足し合わせて、P(x)とします。P(h)がPOT_HIGHである場合は、その逆です。

    • P(v)、P(h)ともに有効なポテンシャル値である場合は、下記の数式を満足するようなP(x)を求めます。ただし、P(v)とP(h)の差がc以上の場合は、下記を満足する解がないため、P(v)とP(h)の小さいほうにcを足し合わせてP(x)とします。

      math_quadratic

  5. 対象セルのポテンシャル値を計算したら、その上下左右のセルのうち、まだPOT_HIGHとなっているセルを、次の計算対象に加えます。この時、追加元のセルのポテンシャル値がより低いものを、次に優先的に計算します。

  6. このように、ゴール位置のセルからポテンシャル値計算を広げていき、スタート位置のセルに到達したら、ポテンシャルマップ生成完了とします。

なお、上述の2次方程式は、実際には下記のような近似計算を行っています。:

1 float d = fabs(P(v) - P(h)) / c;
2 float v = -0.2301*d*d + 0.5307*d + 0.7040;
3 P(x) = min(P(v), P(h)) + (c * v);

このような2次方程式を使わずに、単純に、P(v)とP(h)の小さい方をcに足していけばよいようにも見えますが、単純な足し算だと、あるセルに対して、直線で2つ向こう側にあるセルと斜めにあるセルとで、ポテンシャル値が同等になってしまいます。(実際には、斜めにあるセルの方が近いにも関わらず。)

斜めにあるセルのポテンシャル値を、より適切な値にするために、上述の2次方程式が使用されています。


2.2. ポテンシャルマップ上での経路生成¶

ポテンシャルマップ上で、スタート位置にボールを置いて、地形の傾斜に沿ってボールが転がり、最後にゴール位置に到達するというようなイメージで、ポテンシャルマップ上に経路を生成します。

経路の生成は、以下のように行われます。

  1. スタート座標を最初の現在位置として、経路に追加します。

  2. ポテンシャルマップ上で、スタート座標が含まれるセルと、その右隣り、下、右下の4枚のセルを取り出します。

    CalcPath

  3. それぞれのセルについて、x軸方向の傾きとy軸方向の傾きを求めます。セルの傾きは、対象セルの左右のセルとのポテンシャル値の差からx軸方向の傾きを求め、対象セルの上下のセルとのポテンシャル値の差からy軸方向の傾きを求めます。(ポテンシャル値がより小さいほうに傾けます。)

  4. 4枚のセルの傾きから、x軸方向、y軸方向それぞれの加重平均を求めます。加重平均の重みは、現在座標がセル上のどの位置にいるかで決まります。

    セル上で、現在位置がより右側にある場合は、右隣りおよび右下のセルの重みが大きくなります。また、現在位置がより下側にある場合は、下および右下のセルの重みが大きくなります

  5. 求めた傾きの加重平均の分、現在位置をポテンシャルマップ上で移動させ、この座標を経路に追加します。

  6. 移動後の現在位置に対して、同じ傾き計算および座標移動、経路への追加を繰り返します。現在座標がゴール位置のセルに入るかまたは近接したら、最後にゴール座標を経路に追加します。


3. NavfnROS¶

navfn::NavfnROSオブジェクトは、その機能を C ++ ROSラッパー として公開します。 これは、初期化時に指定されたROS名前空間(以降、nameとする)内で動作します。 nav_core パッケージにあるnav_core :: BaseGlobalPlannerインターフェイスに準拠しています。

navfn::NavfnROSオブジェクトの作成例:

 1 #include <tf/transform_listener.h>
 2 #include <costmap_2d/costmap_2d_ros.h>
 3 #include <navfn/navfn_ros.h>
 4
 5 ...
 6
 7 tf::TransformListener tf(ros::Duration(10));
 8 costmap_2d::Costmap2DROS costmap("my_costmap", tf);
 9
10 navfn::NavfnROS navfn;
11 navfn.initialize("my_navfn_planner", &costmap);

3.1. APIの安定性¶

  • ROS APIは安定しています。
  • C++ APIは安定しています。

3.2. ROS API¶

3.2.1. パブリッシュトピック¶

トピック名 型 内容
~<name>/plan nav_msgs/Path 最後に計算された計画。プランナーが経路を計算するたびにパブリッシュされ、主に視覚化の目的で使用されます。

3.2.2. パラメータ¶

パラメータ名 内容 型 単位 デフォルト
~<name>/allow_unknown プランナが不明スペースを横断する計画を作成できるようにするかどうかを指定します。注: 障害物マップレイヤー を使用している場合、そのレイヤーのtrack_unknown_spaceパラメーターもtrueに設定する必要があります。そうしないと、コストマップ上で、不明スペースがすべて空きスペースに変換されますので、本パラメータが意味をなさなくなります。 bool - true
~<name>/planner_window_x プランナーの探索範囲を限定するためのパラメータとして定義されていますが、現状は参照されていません。。 double - 0.0
~<name>/planner_window_y プランナーの探索範囲を限定するためのパラメータとして定義されていますが、現状は参照されていません。。 double - 0.0
~<name>/default_tolerance プランナーの目標位置の許容値。プランナーは、指定された目標にできるだけ近いがdefault_toleranceを超えない計画を作成しようとします。 double - 0.0
~<name>/visualize_potential 計算されたポテンシャルマップを視覚化するかどうかを指定します。trueに設定された場合は、PointCloud2形式のデータでポテンシャルマップをパブリッシュします。 bool - false

3.3. C++ API¶

navfn::NavfnROSは、nav_core パッケージにあるnav_core :: BaseGlobalPlannerインターフェイスに準拠しています。 詳細については、NavfnROS C++のドキュメント をご覧ください。


4. NavFN¶

navfn::NavFnオブジェクトは、上述のナビゲーション機能の実装を提供します。自由に利用して構いませんが、APIの安定性が保証されないことに留意してください。


4.1. APIの安定性¶

  • C++ APIは安定していません。いつでも変更の可能性があります。

4.2. C++ API¶

詳細については、navfn::NavFnクラスの C++ APIドキュメント をご覧ください。


5. 内部処理手順¶

5.1 メソッドコールシーケンス¶

NavfnROS→NavFnへは、スタート/ゴールを逆に設定して、NavFnが生成した経路を、最後に逆順に入れ替えるという処理になっています。


_images/navfn_sequence.png

  • This document is licensed under the Creative Commons Attribution 3.0
  • Copyright © National Institute of Advanced Industrial Science and Technology (AIST)
    (Japan Corporate Number 7010005005425). All rights reserved.