論文サマリ「A Robust Layered Control System For a Mobile Robot」Rodney Brooks, MIT A.I. Memo, 864, 1985.

オリジナル論文へのリンク

1. Introduction

完全自律移動ロボットの制御システムを作りたい。環境の境界条件は次々変化するし、それを認識するためのセンサ信号はノイズにまみれている。リアルタイムな情報処理が必要である。従来型のシステムは、Figure 1のような「機能の水平分割」により構成される。筆者は、Figure 2のような「機能の垂直分割」による構成を提案する。これはシステムの設計や実装を革新的に変えるもので、頑健さ、構築の容易さ、テストの容易さの点で優れている。

画像1

画像2

設計上の要求事項を整理しよう。
・システムには大抵複数の目的が課され、それらはしばしば競合する(早く到達したい VS エネルギー消費を抑えたい、等)。文脈に基づいて優先すべき目的を選ばなければいけない。
・システムは複数のセンサを持ち、それら全てに誤差が乗る。意味的に重複するものもあるし、それらの間で矛盾も起こり得る。
・システムは頑健(ロバスト)でなければならない。センサが幾つか故障しても、環境が大きく変わっても、計算に多少誤りがあっても、停まったり迷走したりしてはならない。
・センサや機能を後から追加できる拡張性を持っていなければならない。

このようなシステムの設計指針として9つの原則を独自に立てる。
1) 複雑な(そして有益な)振舞は複雑な環境の反映であり、複雑なシステムの産物ではないと心得る。
2) システムは単純であるべき。システム構築で重要なのはインタフェースであり、インタフェースがコンポネントより複雑になるのは考え物である。また頑健性の観点からは、システムの安定性が特定のコンポネント(群)に依存しているのは好ましくない。
3) システムは人が介入しなくても動き続けるべき。役に立つロボットを安く作りたい。必然的に地図作成の機能が重要となる。
4) 人と共存するためには世界の3次元的モデル化が必要。
5) 絶対座標による表現は誤差累積の大元。リレーショナルマップを使うべき。そのためには知覚・認識の方法(表現)から再考しなくてはいけない。
6) 多面体モデルは便利だが、それで世界を正確にモデル化できると思ってはいけない。
7) ソナーは反射的回避等には役立つが、世界をリッチに記述するものではない。視覚を使うべき。
8) センサが一つや二つ故障しても動けないといけないし、迅速にリカバリできないといけない。必然的に常にセルフキャリブレーションし続けないといけない。特別なキャリブレーション手続きは行わない。
9) 「人口の存在(artificial being)」を作りたい。動的環境で人の介入なしに何日も何週間も何カ月も生き抜いて欲しい。そのためにはself-sustainableでなければいけない。

この研究で使うロボットの具体的仕様。
・直径約43cm、高さ約76cmの円筒型移動ロボット(下の写真参照)
・駆動系はReal World Interface of Sudbury製(※メーカー?)
 ・モータ2個を1個のマイコンでサーボ制御
 ・独立駆動車輪×3
 ・最小旋回半径0.5cm
・ポラロイドソナー×12、ToFレンジセンサ、ソニーCCDカメラ×2
 ・ソナーはボディ外縁に等間隔配置
 ・カメラは頭部ティルト台に搭載
 ・地面接触センサを採用検討中
・メインオンボードコンピュータIntel 8031
 ・モータサーボ用マイコンと通信
 ・ソナー、ティルト台、カメラ切り替えを制御
・オフボードコンピュータに複数台のLispマシン
 ・Chaosネットで相互通信
 ・オンボードコンピュータとは12Kbit/sで無線通信(半分はエラー補正)
 ・標準TV信号を単チャンネルビデオ伝送(復調器とフレーム取込器あり)

画像3

2. Levels and Layers

普通、工学の問題解決は「問題の分解」→「部分問題の解決」→「全体の解決」という手順で行われる。ここでは最初から違うアプローチをとる。

問題の水平分解に基づけば、典型的な移動ロボットシステムの構成部品は
・センシング
・センサデータからの地図作成(世界の表象)
・(経路)計画
・タスク実行
・モータ制御
となろう。これらが連鎖しフィードバックループを作る(各々も内部フィードバックループを持つ)。後からある部分を修正・機能追加しようと思ったら、隣接モジュールとのインタフェースを変えないようにするか、影響の及ぶ全てのモジュールも修正するか、という二択に迫られる。
そうではなく問題を垂直分解、つまり「内部でどう処理するか」ではなく「外部にどう働きかけるか」に基づいて問題分解する。このために、能力レベル(levels of competence)を次のように定義する。
 0. 外部物体との接触回避
 1. (無目的な)徘徊
 2. 探索(視野内の物体観察)
 3. 地図作成と経路計画
 4. 環境変化への注意
 5. 物体認識と状況判断
 6. 外界操作を伴う行動計画と実行
 7. 物体の振舞の判断とそれに基づく行動計画の修正
上位レベルの能力は下位レベルの能力を包含していることに注意。

実際のシステムの作り方は次のようである。まず能力レベル0のロボットを作り、徹底的にデバッグして、以降はこれを変更しない。次に能力レベル1の機能を作る。内部的にはレベル0の機能を利用する(通常のデータフローは抑制する)。レベル0自体は、通常のデータフローに乗っているか上位レベルからのフローを受けているかは気にせず稼働する。以下同様に、上位レベルを積み重ねていく(Figure 3参照)。これを包摂アーキテクチャ(Subsumption architecture)と呼ぼう。

画像4

上記提案は、イントロで提起した4つの要求事項に次の意味で答える。
複数の目的:各レイヤーは各々の目的に沿って同時に働き、抑制メカニズムが行動を調停する。どの目的を優先すべきか、入口の段階で決める必要は無く、それぞれの行動パターンが揃ってから最後の最後に決めれば良い。
複数のセンサ:レイヤーが個別に必要なセンサから必要な情報をもらう。全てのセンサを使って総合的表象を作る、というやり方は基本的にとらない。
頑健性:下位レイヤーが十分デバッグされていれば、上位レイヤーがなにがしかの理由でタイムリーに出力を上書きできなかったとしても、下位の出力がそのまま働くだけである。
拡張性:レイヤー間の通信は頻繁には発生しないので、レイヤーごとに異なるプロセッサ上で動かせる。レイヤーを追加したければプロセッサを追加すれば良い。あるレイヤーの機能を複数プロセッサに分散させることも可能。

ここまで読んで、個々のレイヤーは結局従来と同じ方法で機能分割、実装しなければいけないんじゃないか?という疑問を持たれるかも知れない。これはある程度正しい。が、与えられたセンサ群とタスク群に対しどのように機能分割するかは自由なので、全ての知覚と処理を以て単一の分割で行動を生成する、というやり方とは異なる。

筆者の実装では、レイヤーは相互にメッセージを送り合うプロセッサ群を使って組み立てる。それぞれのプロセッサ(モジュール)は有限状態機械で、非同期にメッセージを送り合う。レイヤー内にスーパーバイザは作らず、メッセージを少々ロストしても気にしない。モジュールが別のモジュールの入出力を抑制できるようにすることで下位レイヤーを包摂する。

3. A Robot Control System Specification Language

それぞれのモジュールは内部変数を持つ有限状態機械であり、入出力を複数とる。入力ラインは短要素バッファであり、常に最新のデータが参照される(読みそこなった古いデータは無視される)。またresetという特別な入力を受け付ける。全てのモジュールは動作開始時にNIL状態をとり、reset信号を受け取ったらNIL状態に戻る。NIL状態以外には次の4種類の状態をとる。
出力:入力と内部変数に基づいて出力値を決め、指定の状態に移る。
副作用:入力に基づいて内部変数を設定し、指定の状態に移る。
条件付き呼び出し:入力と内部変数の真理値に基づいて、選択的に指定の2状態のいずれかに移る。
イベント呼び出し:条件と状態の組のシーケンスを一つ一つ確かめていき、合致したものを採用する。
下記はavoidモジュール(レベル1)のLispによる実装例。

(defmodule avoid
  :inputs (force heading)
  :outputs (command)
  :instance-vars (resultforce)
  :states
    ((nil (event-dispatch (and force heading) plan))
     (plan (setf resultforce (select-direction force heading)) go)
     (go (conditional-dispatch (significant-force-p resultforce 1.0) start nil))
     (start (output command (follow-force resultforce)) nil)))

force(入力):ソナーで検出した各点からの距離の5乗に反比例する反発力
select-direction:forceともう一つの入力headingを組み合わせて進行方向を決める関数(Khatibの局所ポテンシャル法)
significant-force-p:select-directionが決めた合力が閾値を超えているかチェックする関数(超えていた場合はその動作を1秒未満継続)
follow-force:合力をモータ速度指令に変換する関数

モジュールの通信形態を模式図(Figure 4)に示す。他モジュール出力により入力・出力はそれぞれsuppress・inhibitされ得る(※suppressもinhibitも日本語だと「抑制」と訳されるのだが、前者は抑制をかけた他モジュール出力がそれを乗っ取る、後者は単に阻害されるだけ、という違いが含められている)。円内の数字は「抑制時間」を表している。Lispコードでは例えば

(defwire (feelforce force) (runaway force) (avoid force))
(defwire (avoid command) ((suppress (motor command) 1.5)))

のようにする。この例では、feelforceモジュールの出力forceがrunawayとavoidの二つのモジュールに入力されている。またavoidの出力commandがmotorへの入力commandを1.5秒間suppressする。

画像5

4. A Robot Control System Instance

論文執筆時点ではレベル0~1までできており、レベル2の実装に取り組んでいる。コードをAppendixに載せている。

レベル0
最下層ではロボットが外界物体との衝突を避ける。横から物体が迫ったら離れるし、進路上に物体があれば停まる。これで静的障害/動的障害の両方に対応できる。もちろん完全に衝突しないことを保証するものではない。物体が高速移動していたり、多数の障害物が入り組んだりしている場合にはぶつかる。
Figure 5に全体像を示す。各モジュールの働きは次の通り。
motorモジュール:回転角度・回転速度・前進量・前進速度指令を一定時間ロボットに発行(haltが入力されたら即座に停止指令を発行)
sonarモジュール:ソナー信号からロボット中心マップを作成
collideモジュール:マップ上でロボットの目の前に物体があればhaltを発行
feelforceモジュール:外界からの仮想反発力の合力を計算
runawayモジュール:合力に従って移動方向を決定

画像6

レベル1
次のレベルでは、ロボットは衝突を避けながら徘徊する。レベル0とは逆に物体にぶつかりに行く性質を作る。ただし、物体よりも少し先に向かうようにする、というヒューリスティックを入れてレベル0との競合を避ける。全体像をFigure 6に示す。
wanderモジュール:10秒ごとにロボットの進行方向指令を発行
avoidモジュール:レベル0のfeelforceが作った合力にheadingの情報を足して、所望の方向に動く機能を作る。runawayを包摂する(runawayの出力をsuppressする)。

画像7

レベル2
探索機能を加え、興味を引く方向にロボットを向かわせる。全体像をFigure 7に示す(Figure 6のシステムに幾つかモジュールと結線を加えただけ)。
grabberモジュール:motorモジュールにhaltを送って主導権を握り、下位モジュールをinhibitしまくって2秒間機能停止させ、その間にgoalをpathplanモジュールに送信
monitorモジュール:motorモジュールの状態を監視し、ディアクティベートされている間にシャフトエンコーダの値を読んで移動量を算出
integrateモジュール:monitorの出力を積算(デッドレコニング)
pathplanモジュール:goalの方向と距離、最終目標姿勢に基づいてheadingを決定しavoidに送信(avoidへの入力をsuppressする)。目的地が近づいたらstraightenモジュールにgoalをスルー
straightenモジュール:最後の姿勢調整指令を発行
本稿執筆時点でレベル2は完成していないが、視覚に基づく高度な経路計画機能等も追加する予定。

画像8

誤解を避けるためにここで注記しておきたい。Figure 7の随所にあるinhibit・suppress信号はあくまでもレベル2のモジュールに送られるのであって、レベル1、レベル0にある同名のモジュール達は、この間もそれぞれ動作する

5. Performance

まずシミュレーションでロボットシステムの動作を検証した。その際、移動量には±5%の誤差を付加し、12本のソナービームのうち幾つかはロストさせることでリアルさを模擬した(Figure 8)。シミュレータとロボットシステムは同じプロセッサ上で走らせた。レベル0~1ではロボットが衝突を避けながら徘徊する様(Figure 9)、レベル2ではパスに沿って移動する(ゴール到達後は徘徊行動に戻る)振舞(Figure 10)が再現された。

画像9

画像10

画像11

6. Implementation Issues

提案のモチベーションの一つに拡張性がある。レイヤーを足したいと思ったらプロセッサを足せば良く、プロセッサ間の同期は不要で通信バンド幅が低くて済む(共有メモリも不要)、という考えはうまくいっている。ただしLispプログラムにアクセスする際のオーバーヘッドが無視できず、これは誤算であった。

Lispを使ったのは空間認識に都合が良いからである。1ビットALUを持つ約60個のプロセッサで円環ネットワークを作り、Lispのハードコードを実行した。円環ネットワークはちょうどロボットを囲む環境をモデル化する。これはシングルチップコンピュータにちょうど良い。
有限状態機械を表現するプロセッサは状態を16個もとれれば十分である(実際、上記の実装例では8状態でも足りる。その後の拡張で必要な状態数は増えている)。

視覚認識まで載せようと思ったら今のLispマシン1台では限界が来るのは目に見えており(包摂アーキテクチャに則った視覚認識アルゴリズムを検討中)、カスタムチップを作るのは長期的課題。短期的には、Lispマシンとプロセッサの通信にはNEWSネットワークを使い、モジュール間通信にはクロスオメガネットワークを使うのが良さそうである。

7. Conclusion

本稿の主張のキーポイントをまとめる。
1. 移動ロボットの制御システムは、機能でなく振舞で分解できる。
2. この考え方は複雑なシステムの段階的構築・テストの方法につながる。
3. 非同期プロセッサの低速・緩結合により有益な並列計算が行える。ネットワークのトポロジーは相対的に決められる。
4. 移動ロボットにはスーパバイザリモジュールは必要ない。制御システムは唯我的な世界に生きるエージェントのなすシステムと見なせる。
これは従来と異なるシステム実装戦略につながり、またシステムの能力にも影響する。システムの最下層で動的障害物にも対応していること―伝統的な移動ロボットでは扱っていなかった―は特筆に値する。

一方、本稿で記している内容には次のことが欠けている。
1. 実ロボットでのデモンストレーション
2. レベル2の完全な実装
3. 制御アルゴリズムと実装メディアとの明確な分離
4. レベル0がレベル2でしか使われない出力を持っていること
しかし、この方法論はきっと実ロボット上で結実するであろう。

References

省略。

読後所感

ロボット制御アーキテクチャに関するエポックメイキングな文献。雑誌論文ではなくあくまでメモ。イントロに記されている「9個の原則」は何か事実に裏付けされているわけではないし、その後の議論の布石となっているわけでもない。が、いずれも個人的に賛同するものではある。

機能ではなく振舞を軸とする「問題の垂直分割」が包摂アーキテクチャの考え方の肝である。示唆に富む指摘と思う一方で、幾つか疑問もある。
第一に、上位レイヤーを開発する段階では下位レイヤーは既に徹底的なデバッグが済んでいる、という仮定は現実的には置き難い。ただしこれは、レイヤーのオブジェクト化により改善できる余地はありそうである。
第二に、レイヤーの実装方法が明確でない。紹介されているレベル2の実装は、モジュール同士の接続方法は複雑に入り組んでおり、抑制のかけ方は発見的である。Brooks自身が文中で、個々のレイヤーは結局従来と同じ方法で機能分割、実装しなければいけないのではないか?という指摘をしており、それに対するエクスキューズは弱い。
第三に、そして最も深刻なことに、最終的にどのレイヤーの出力をロボットに与えるか、という問いへの答えが明確でない。2章には「抑制メカニズムが行動を調停」し、「上位レイヤーがなにがしかの理由でタイムリーに出力できなかった」場合に下位レイヤーの出力がスルーされる、とある。上位レイヤーほど処理が重くなるという点が払拭されないならば、各レイヤーの出力は頻繁に乖離する。システムが健全に動作している(上位出力が採用されている)間はロボットの振舞はやはり即応性に欠け、逆に下位出力が採用されるべき緊急事態にひとたび陥ったら、上位レイヤーによる高次の振舞に復帰するのが難しくなる。いずれにしても問題である。

Brooksは結局レベル幾つまで作れたのだろうか。

非同期モジュールの並列的緩結合、という発想までは理解が行く。モジュール≠機能であるところが、つまり機能でなく振舞で分割するという大元の考え方が上記のような綻びを作っているように思えてならない。振舞は機能が作る。両者は分けてはならないのである。

機能の非同期な並列的緩結合で高次の振舞を作るのは容易ではない。が、実世界ロボット開発はそれに取り組まなければならない。

この記事が気に入ったらサポートをしてみませんか?