1.はじめに
前回記事に引き続き、 ROS2のPlanSys2の試行に関連する気づきをまとめました。
回数 | シリーズ「ROS2・PlanSys2 チュートリアルチャレンジ」・概要 |
---|---|
1 | PlanSys2のインストールと基本操作 |
2 | プランニング |
2.1 | プランの調製 |
3 | rvizで視覚化 |
4 | Behavior Trees |
番外編 | (今回)PDDL入門 |
今回は、Planning Domain Definition Language(PDDL言語)そのものについて、知見を深めていきます。
2.PDDL入門
NOTE
本記事は、ROS2のPlanSys2に含まれるPDDLの読み解きを進める為の、副読本的な位置づけです。
PDDL言語そのものに興味がある方は、下記の資料を参考にしてください。
- Getting Started with PDDL | LearnPDDL
- CSC2542: Topics in KR&R: Automated Reasoning
- Assignment 1ページのなかにある「PDDL tutorial by Malte Helmert.」
(1)自動計画とプランナー
ここにはロボットが配置されており、それに様々な作業をさせることを想像します。
通常は、作業内容を一つ一つ棚卸しし、作業手順に落とし込み、それをロボットでこなせるように最適化し、さらに必要があれば治具や工具を作成し、PLCやロボットの記述言語を使用してシーケンスとして組み上げ、自動的に作業を進められるようなシステムを構築します。
作業対象が少しでも変われば、当然、上記の内容を修正、または一から作り直す必要があります。
構成要素である各装置の増減や動作条件、その動作条件を考慮したシステム全体を抽象化し、手順そのものを自動的に作成する仕組みが、自動計画と呼ばれる概念です。
ある状態(初期状態)を、目的の状態(終了状態)にするまでに必要な動作と、その順序(動作手順・アクション)を求める問題をプランニング問題と呼びます。
このプランニング問題をコンピューターなどで演算する仕組みが、プランナー(自動計画器)です。
プランナーは一般的に、外界の初期状態、目標とされるゴール、取ることができるアクションの集合という3つの入力を必要とします。プランナーはこれらの集合を基に演算し、初期状態からゴール状態へと変化させる一連のアクションの計画を生成します。
これらの集合情報をプランナーに読み込ませるためには、記述言語を使用します。そのひとつが、Planning Domain Definition Language(PDDL言語)です。
(2)PDDLとは
PDDLとは、自動計画を定義するための標準的な言語です。この言語は、計画問題のモデルを人間が理解しやすい形式で記述することを目的としています。
例えば、ロボットが物を運ぶ計画問題を定義する場合、PDDLを使ってロボットの動作範囲、物の初期位置、持って行きたい目標位置などを記述します。これを元に、プランナーが最適な行動順序を演算します。
(3)PDDLによるモデル化の考え方
こちらを教科書に(意訳も含め)読み解いていきます。
以降では、外界の初期状態、目標とされるゴール、とりうるアクションの集合の3つの入力のことを「ワールド」と表現します。
PDDL で「ワールド」をモデル化する方法を理解します。
- 「ワールド」は一連の
states
(状態)によって記述され、それぞれのstates
にはfacts
(事実)やobjects
オブジェクトのリストが含まれます。 - 「ワールド」は
initial state
(初期状態)から始まり、各状態で実行できるactions
(アクション)を制限する一連のルールと制約によって管理され、各アクションは通常、異なる状態への遷移を表します。
PDDLの主なポイント:
ドメイン定義 | 計画問題の全体的な構造や可能な状態、行動のセットを定義します |
問題定義 | 特定の計画問題に関する初期状態と目標を記述します |
行動の記述 | 各行動の前提条件とその結果を定義します |
時間、数 | 前述の内容に時間と数の概念を与えて、実態に近い複雑な計画問題を表現(PDDL 2.1以降) |
(4)主要なキーワード
「ワールド」を記述するうえで必要なキーワードは以下になります。
記述キーワード | 訳 | 補足説明 |
---|---|---|
Objects | オブジェクト | 世界のなかで、私たちが興味を持っているもの |
Predicates | 述語 | 関心のある事実 (オブジェクトのプロパティなど)。真または偽の可能性があります |
Initial state | 初期状態 | 私たちが開始する世界の状態、つまり、開始時に真であるもの |
Goal specification | 目標の仕様 | 私たちが終了したい世界の状態、つまり、最終的に真実であってほしいもの |
Actions/Operators | アクション/オペレーター | 世界の状態を変える方法、つまり、事実を変える出来事 |
?hoge | 「?」で始まる文字は、 predicates やactions のパラメータで、時間、数を与えます |
(5)PDDLの構文
PDDLを記述するファイルには通常、拡張子.pddl
が付いています。
PDDL ファイルは 2種類あります。
Domainファイル | ワールドのコンテキストを確立します。状態にどのような種類の詳細を含めることができるか (述語:predicates )、および世界の状態間を移動するために何ができるか (アクション:action ) を決定します |
|
Problemファイル | ドメイン内に確立したワールドのインスタンスを表します。これは、計画の開始時に何が真実であるか (初期状態:init )、計画の終了時に何が真実であるか (目標状態:goal ) を決定します |
次は「Getting Started with PDDL - Simple Example: Let’s Eat!」の内容に移りますが、ここからは一旦、「Getting Started with PDDL」の読み解きから離れて、PlanSys2のチュートリアルを読み解いていきます。
3.チュートリアルPDDLの読み解き
チュートリアルチャレンジ(2)~(2.1)を進めるにあたって、PDDLファイルの存在や役割は冒頭に軽く説明している程度でした。
ここでは、先ほどの記事のターミナル1で立ち上げる plansys2_simple_example_launch.py にて読み込まれる/pddl/simple_example.pddl
を読み解いていきます。
simple_example.pddl
この内容を順番に読み解きます。
types
以降で情報を記述する際の”型”を定義します。
:types | この型に入る情報 |
---|---|
robot | ロボット本体 |
room | 場所(ロボットが向かう行き先、場所) |
predicates
Predicates には、関心のある事実、例えばオブジェクトのプロパティなどを記述します。
ここでは具体的に、ロボットの状態や行き先となる部屋の繋がり、充電場所を記述しています。
?_
は引数、ハイフンのあとはpredicateの型typesを指定します。
:predicates | ここに入る情報 | argument1 | argument2 | argument3 |
---|---|---|---|---|
robot_at | ロボットの種類(?r)と、そのロボットの居る場所(?ro) | ?r - robot | ?ro - room | - |
connected | 行き先となる部屋(?ro1)と部屋(?ro2)の繋がり | ?ro1 - room | ?ro2 - room | - |
battery_full | ロボットの種類(?r)とそのバッテリーの充電が必要でない状態を示す | ?r - robot | - | - |
battery_low | ロボットの種類(?r)とそのバッテリーの充電が必要な状態を示す | ?r - robot | - | - |
charging_point_at | バッテリーを充電できる部屋(?ro) | ?ro - room | - | - |
functions
functionsは、actionの実行に伴って時間の経過とともに変化する可能性がある数値を表すために使用されます。
functions
では、単純な述語 (true / false
) だけでは不十分な、より複雑な計画問題に役立ちます。
プランナーはfunctions
を使用して、リソース、距離、コストなどの数量を処理できます。
例として、温度、速度、エネルギーなどの変数を計算するのに活用します。
ただし、PlanSys2 のサンプルコードにはfunctionsは含まれていません
durative-action
PlanSys2のチュートリアルのPDDLでは、action
ではなくdurative-action
(=持続的なアクション)で記述されています。
実際の行動・アクションを考えたときに、アクションが一瞬(時間ゼロ)で完了することはなく、ある程度の時間の範囲を持ってアクションが実行されます。 そのため、アクションの時間方向に対しても条件の評価を与えることができます。
構文 | 挙動 | |
---|---|---|
(at start ([condition/effect])) | アクションの開始時に引数が評価され、condition=Trueならばこのアクションが始まり、始まったことでeffectに指定の内容を書き換えます | |
(at end ([condition/effect])) | アクションの最後に評価され、condition=Trueならばこのアクションが終わり、終わったことでeffectに指定の内容を書き換えます | |
(over all ([condition])) | アクションの継続時間全体にわたって、condition=Trueである限り継続します |
move
- ロボットが部屋から部屋に移動するというアクションを記述します。行き先や、ロボットのバッテリーの消耗なども加味されます
:durative-action | argument1 | argument2 | argument3 | |||
---|---|---|---|---|---|---|
move | :parameters | ?r - robot | ?r1 - room | ?r2 - room | ||
〃 | :duration 継続期間 | = ?duration 5 | ||||
〃 | :condition 開始条件 | and | ||||
〃 | 〃 | at start | connected | ?r1 | ?r2 | |
〃 | 〃 | at start | robot_at | ?r | ?r1 | |
〃 | 〃 | over all | battery_full | ?r | ||
〃 | :effect | and | ||||
〃 | 〃 | at start | not robot_at | ?r | ?r1 | |
〃 | 〃 | at end | robot_at | ?r | ?r2 | |
askcharge
- ロボットのバッテリーの残量を確認します。充電の必要があれば、充電器のある部屋に移動するための判断に使います
:durative-action | argument1 | argument2 | argument3 | |||
---|---|---|---|---|---|---|
askcharge | :parameters | ?r - robot | ?r1 - room | ?r2 - room | ||
〃 | :duration | = ?duration 5 | ||||
〃 | :condition | and | ||||
〃 | 〃 | at start | robot_at | ?r | ?r1 | |
〃 | 〃 | at start | charging_point_at | ?r2 | ||
〃 | :effect | and | ||||
〃 | 〃 | at start | not robot_at | ?r | ?r1 | |
〃 | 〃 | at end | robot_at | ?r | ?r2 | |
charge
- ロボットのバッテリーを充電します
:durative-action | argument1 | argument2 | argument3 | |||
---|---|---|---|---|---|---|
charge | :parameters | ?r - robot | ?r1 - room | ?r2 - room | ||
〃 | :duration | = ?duration 5 | ||||
〃 | :condition | and | ||||
〃 | 〃 | at start | robot_at | ?r | ?r1 | |
〃 | 〃 | at start | charging_point_at | ?r2 | ||
〃 | :effect | and | ||||
〃 | 〃 | at end | not battery_low | ?r | ||
〃 | 〃 | at end | battery_full | ?r | ||
commands:problemの記述ファイル
先ほどのPDDLが定義された状態で、上記のcommandsファイルに含まれるproblemを与えると、下記の図の様な関係が構築されます。
(この図は、チュートリアルチャレンジ(2)の こちらに記載している内容です)
graph LR A === B B === C C === D B === E E === F A(entrance</br>(初めにロボットがいるところ)) B(dining) C(kitchen) D(chargingroom</br>(充電場所)) E(bedroom) F(bathroom</br>(ロボットに向かわせる先))
4.PlanSys2 designの読み解き
こちらを教科書に(意訳も含め)読み解いていきます。
PlanSys2は以下の4つのノードで構成されています。
ノード | 役割 |
---|---|
Domain Expert | PDDLモデル情報(型、述語、関数、アクション)を保持します |
Problem Expert | モデルを構成する現在のインスタンス、述語、関数、ゴールを含む |
Planner | ドメイン・エキスパートとプロブレム・エキスパートに含まれる情報を使用して、プラン(アクションのシーケンス)を生成します |
Executor | プランを受け取り、アクション実行者(各アクションを実装するROS2ノード)をアクティブにして実行する |
これらの各ノードは、PlanSys2としてどのようなアプリケーションでも使用できるようにクライアントライブラリとして作成されており、ROS2サービスを容易に活用できます。
(PlanSys2 designからの引用画像)
(途中)
参考資料
- 自動計画のあり方
- PDDL
- behavior-tree