RoboCup Soccerにおける単純認識・判断に基づく
エージェントの作成と評価

00kc105 新島宇裕
指導教官 坂本直志助教授

1.はじめに

 現代において、ロボットは産業用に用いられる反復作業用の非人間型のものから、人間型で二足歩行するものやペットを模して作られた愛玩用のものまで幅広い種類・用途のものがある。これらのロボットは一部の一定作業を反復して行うだけのものを除けば、何らかの状況判断のためのパラメータを持ち、自分の行動を制御する必要がある。
しかし、非常に多くのパラメータを持つ環境においてはそれら全てを正確に把握して判断するために複雑な判断・認知のアルゴリズムが必要となるため、それらの環境をただ単純に受け取るだけではなく、判断に必要なデータを取捨選択したり、データを量子化するなどの判断基準に関わるデータの削減を行い、一定以上の正確な反応をよりスムーズに導き出す必要がある。本研究では、RoboCup Soccerのシミュレーションリーグを題材とした。RoboCup Soccerシミュレーションリーグでは、サッカープレイヤーとして環境データを受け取り、ソレに基づいた自律判断行動を行うエージェントと呼ばれるプログラムを利用する。本研究では、このエージェントが受け取る環境情報のうち、視覚情報を量子化して少数の状況に分類することで単純な状況判断を行わせるエージェントを作成した。そして、このような試みが適切であるかを評価した。
これらの情報の単純化は、単に扱う状況の分類を減らすだけではなく、状況の数に依存するルーチンやデータ量の削減をもたらし、処理速度を要しないプログラムの軽量化・単純化を可能とする。

2.RoboCup Soccerについて

2.1 RoboCup Soccer シミュレーションリーグとは

 RoboCupはランドマーク型と呼ばれる一つのプロジェクトである。ランドマーク型のプロジェクトとは、一つの標準問題を提示し、その解決に必要な環境を得るための手段や、問題に対する研究発表の場を提供することで標準問題解決を広く促進するタイプのプロジェクトであり、一般に標準問題として多くの技術の統合を必要とするものが与えられる。RoboCupで与えられる標準問題は自律行動するロボットに関する問題であり、ロボット工学を始めとして人工知能工学などの多くの工学分野にまたがる研究を必要とする問題である。
RoboCupは標準問題の違ういくつかのプロジェクトの集合体である。その1つであるRoboCup Soccerにおいてはサッカーを題材に「2050年までに、ヒューノマイド型ロボットを用いてサッカーワールドカップ優勝チームに公式ルール下において勝利する」という標準問題がある。この問題に関する研究の成果は、毎年行われる世界大会をはじめ、わが国でも国内代表決定戦を始めとした試合などを通して発表され、大学などの教育機関を中心として多くのチームで活発な研究が行われている。
RoboCup Soccerは、さらにシミュレーション・四足歩行(SONY AIBOを使用)・小型ロボット・中型ロボット・二足歩行の独立したリーグに分かれている。これらの各リーグでは求められるプレイヤーの性能やレギュレーションなどの環境が異なり、研究・開発において多くの方向性を与えている。
本研究で取り扱うシミュレーションリーグは、実機を使わずに仮想空間上で行うサッカーリーグで、プレイヤーに必要な戦略の獲得・協調行動を行うプレイヤーの研究・開発が行われているリーグである。このリーグは特に実機開発の必要が無く、プログラム開発の環境さえあれば容易に研究・開発が可能という利点があり、特にソフトウェア開発に向いているリーグであると言える。
シミュレーションリーグでは、1人のプレイヤーは1つのプログラムに対応し、それらを総称してエージェントと呼ぶ。各エージェントはクライアントとしてフィールドの状況を再現するサーバに接続し、サーバ・クライアント間でUDP/IPによる通信を行うことでデータのやり取りを行っていく(図1)。

図1
図1 RoboCup Soccerにおけるエージェントの接続

サーバ・クライアント間でやり取りされるデータは、全てS式と呼ばれる形式の文字列である。S式については参考文献[1]にも詳しくあるが、以下のような形式で示されるリストとして考えることができる。
(label {value}+ {(label {value}+)}*)
{...}*は要素が0個以上、{...}+は1個以上繰り返し存在することを示す。
コマンドや環境情報もS式によって与えられ、このため、RoboCup Soccerのシミュレーションリーグのクライアントプログラムは、UDP/IPによってサーバと通信ができ、サーバから与えられるS式を解釈し、S式の形でサーバにコマンドを送ることができる能力を最低限必要とする。
上述の条件さえ満たされれば、エージェントを作成する際に使用する言語は問われない。一般的にはC++またはJavaがプログラム言語として用いられている。
なお、プラットフォームは主にUNIXが使われているが、多少更新スピードが遅いもののWindows用のサーバプログラムも用意されており、Windowsマシン単独での開発も可能である。
図2
図2 S式の構造とトークンへの分解

2.2 RoboCup Soccer シミュレーションリーグのルール

 RoboCup Soccerのシミュレーションリーグにおけるルールは、人間のサッカーと共通なルールと、接続方式やプログラムの規定などの独自のものに大別できる。サッカー部分のルールは人間のものとほぼ同じルールを使う。但し、フィールドの大きさは105m×68mの大きさで、現在は高さに関する概念を持たない点や5分ハーフで試合を行うなどの相違点がある。
サッカーのプレイヤーや監督にあたるエージェントについては、前述のように各々が1つのプログラムに対応する。つまり、通常のプレイヤーにあたる11個のプレイヤー・エージェント(ゴールキーパーを最大1人まで含む)に加え、実際のサッカーの監督に相当するコーチ・エージェントが最大1個接続できる。このコーチエージェントは、通常のプレイヤーとは異なり、フィールドの全体にわたる視野を持ち、プレイヤーに対して戦略に対する指示を与えたりすることができる。
ゲームの状態やオフサイドなどのサッカーのルール上の反則の判定はサーバ上のレフリールーチンによって行われる。レフリーはフィールドの状況を把握し、フリーキックやキックイン(通常のサッカーのスローインにあたる)の指示や、キックオフの指示を行うためにプレイモードを変更する権限を持つ。変更されたプレイモードは直ちに全てのプレイヤーに通知され、プレイヤーはゲームの状況に応じた行動を要求される。
ゲームの状態の種類を、以下表1に示す。これらの情報は全てレフリーから発せられた聴覚情報として扱われる。




ゲーム状況
(Sideにはrかlのいずれかのプレイヤーサイドが入る)
意味
before_kick_offゲーム開始(キックオフ)前
エージェントの行動が制限される
kick_off_Sideキックオフ
play_onゲームプレイ中
この状態の間は時間が進行する
goal_Sideゴールによって得点した状態
kick_in_Sideキックイン(スローインにあたる)
corner_kick_Sideコーナーキック
goal_kick_Sideゴールキック
free_kick_Sideフリーキック
time_overゲーム終了

表1 ゲームの状態

2.3 プレイヤー・エージェントに与えられる情報

 サーバからプレイヤー・エージェントに与えられる情報は、システム情報・視覚情報・聴覚情報・感覚情報の4つに分けられる。これらの情報は全てS式の形で与えられ、その解釈ルーチンは各エージェントが持つ必要がある

2.3.1 システム情報

 システム情報とは、サーバと接続したときに与えられる初期情報(自分のコートサイドや、与えられた背番号など)を指す。これらの情報は以下の形のS式で与えられる。
(init Side UniformNumber PlayMode)
Sideはlまたはrで与えられ、自分が左右どちらのサイドのプレイヤーであるかを表す。この情報は主にレフリーによるチームの指示の場合に使われる。
UniformNumberは自分に与えられたチーム内背番号である。主に他のプレイヤーが得る視覚情報の一部として使われるが、同一プログラムによってチームを作る場合は、ポジションの決定や行動の内部処理の分岐に背番号を用いることがある。
Playmodeは接続した際のゲームの状態で、通常はbefore_kick_off(ゲーム開始前)の状態が与えられる。ただし、練習時などでゲーム中に追加のエージェントが配置される場合もあり、その場合には現在のゲームの状態が通知する必要があるため、初期情報としてサーバから与えられる。

2.3.2 視覚情報

 視覚情報とは、プレイヤー・エージェントの視界内にあるオブジェクトの一覧をS式の形で表したものである。オブジェクトにはプレイヤーやボールのような実体を持つオブジェクトと、自分の位置を計算するために使われるラインやフラッグなどの仮想オブジェクトがあるが、視覚情報ではこれらをひとまとめにして単にオブジェクトとして扱っている。

プレイヤー・エージェントの持つ視界には広角・通常・狭角の3つのモードがあり、任意に切り替えて使うことができる。広角視界を持つエージェントは左右に広い視野の範囲を持つが、遠くの物体の認識力に劣る。逆に狭角視界を持つエージェントは左右の視野の範囲が狭いが、より遠くの物体まで認識することができる。通常視界を持つエージェントはその中間の視野範囲と認識力を持つ(図3)。また、視界のパラメータとしてはその他にも情報の質と視覚情報の与えられる頻度により、良質な視覚情報を得られるが情報を得る頻度の低いhighモードと、その逆に情報の質が劣るものの情報を頻繁に得ることのできるlowモードの区別がある。

図3
図3 視野範囲のモード(通常視界以外の視界にある灰線は通常視界の範囲)


視覚情報は以下の形のS式で与えられる。
(see Time ObjInfo ObjInfo ...)
Timeはゲーム内での時間で、ゲーム開始時を0とした正の整数で与えられる。ObjInfoは視野に入った各オブジェクトの情報であり、さらに以下のいずれかのS式によって与えられる。
(ObjName Distance Direction DistChange DirChange BodyFacingDir HeadFacingDir)
(ObjName Distance Direction DistChange DirChange)
(ObjName Distance Direction)
(ObjName Direction)
ObjNameはオブジェクトの名称で、オブジェクトの種類により異なるS式で与えられる(参考文献[1]参照)。Distanceはプレイヤーからオブジェクトまでの直線距離で、距離が遠ければ遠いほど正確な値からの誤差が大きくなる量子化が施された実数値になる。
Directionはプレイヤーの視野の中心(プレイヤーの向きと、首の向きによって決まる)から見たオブジェクトの相対角で、視野の中心を0[°]として時計回りが正方向となる±180[°]の範囲で与えられる角度である。距離と異なり角度データには誤差が存在しないのが特徴である。
DistChangeおよびDirChangeは、プレイヤーから見た相対速度・相対角速度であり、プレイヤーのような動体オブジェクトがどう動こうとしているかのパラメータになる。
BodyFacingDirは、自分の視野の中心から見た対象の体の向きの相対角度を、HeadFasingDirは対象の体の向きから見た対象の顔の向きの相対角度を表す。これらのパラメータはプレイヤーオブジェクトに固有の情報で、プレイヤーの移動方向や視野を推測するためなどの利用法がある。
これらのデータは常に完全な形で与えられるわけではなく、例えばプレイヤーオブジェクトの場合なら対象との距離が遠くなれば背番号やチーム名の情報が失われていき、対象の状況が徐々に分からなくなっていく。
また、視野の外であっても一定のごく近距離にある一部のオブジェクトは、その存在を感知することができ、それぞれオブジェクト名で区別できるようにして存在のみが知らされる。

2.3.3 聴覚情報

 聴覚情報とは、プレイヤー・エージェントに流れ込んでくる音の情報をS式の形で表したものである。ここで音とは、他プレイヤーの発言や、レフリーからの情報を指す。
他プレイヤーの発言は全ての情報が聞き取れるわけではなく、一度に一定数を越える数の発言がされた場合はそのうちのいくつかが無作為に選ばれてプレイヤーに通知される。ただし、レフリーからの情報は重要であるため、この枠とは別に常に聞き取ることができる。また、自身が発した情報もこの枠とは別で、常に聞き取ることができる。発言を聞き取ることができるのは50[m]の距離内のプレイヤーであり、その範囲内にいれば違うチームのプレイヤーの発言であっても受け取ることができる。ただし、これを悪用して常に発言を続け、それによって相手プレイヤーが聴覚情報を受け取ることを妨害するようなプレイヤー・エージェントは、いわゆる紳士協定違反として公式の試合からは排除される。
聴覚情報は以下のS式によって与えられる。
(hear Time Direction Message)
Timeは視覚情報と同様にゲーム内での時間を示し、0以上の整数が与えられている。
Directionは発言元の方向で、通常は±180[°]の角度で与えられるが、特に発言元が自分自身であった場合は文字列"self"が、レフリーまたはコーチからの発言である場合は文字列"referee"が与えられる。
Messageは発言の本文で、数字・アルファベット・一部の記号からなるアスキー文字列である必要がある。メッセージ長は256バイト以内という制限が当初かけられていたが、エージェントの得た環境情報を圧縮して256バイト以内の文字列に収め、会話コマンドを通してエージェント間で情報を共有することで完全に近い状況を複数エージェント間で共有できるエージェントが作成されたことから、現在では10バイト以内の短いものに制限されている。

2.3.4 感覚情報

 感覚情報とは、プレイヤー自身に関する情報であり、常に正確な情報がサーバから与えられる。
感覚情報は以下のS式で与えられる。
(sense_body Time (view_mode ViewQuality ViewWidth) (stamina Stamina Effort) (speed AmountOfSpeed) (head_angle HeadDirection) (kick KickCount) (dash DashCount) (turn TurnCount) (say SayCount) (turn_neck TurnNeckCount))
ViewQuality は high と lowのうちの 1 つであり、 ViewWidth は narrow と normal、 wide のうちの 1 つである。これらは2.2.2で述べた視覚情報の品質と情報を得る頻度に関するパラメータである。Staminaはプレイヤーの持つスタミナの値、Effortはスタミナによって決定されるダッシュの実効値を決める係数である。AmountOfSpeed はプレイヤーの速度の大まかな近似であるが、もし速度の方向が必要ならそれは何か他の方法で推測する必要がある。 HeadDirection はプレイヤーの頭の相対的な方向である。 また、〜Countという名称を持つパラメータはサーバによって実行されたコマンドの合計数であり、例えば、DashCountの値が134であるということはプレイヤーがこれまでのところ134回dashコマンドを発行したということを意味する。

2.4 プレイヤーエージェントのコマンド

 プレイヤーエージェントがサーバに送るコマンドは、システムコマンド・行動コマンドの2種類に分類される。システムコマンドとはサーバに自身の初期情報(想定しているサーバのバージョン情報や、自身がゴールキーパーか否かなど)を与え、サーバとの接続を確立するコマンドや、サーバからの切断コマンドを指す。一方、行動コマンドは、プレイヤーエージェントの行動に関するコマンドのことを指し、サーバ接続後から切断までの間はこれらのコマンドを使ってプレイヤーエージェントを動作させる。

2.4.1 システムコマンド

 システムコマンドはinit,reconneect,byeの3のコマンドからなる。書式は以下の通りである。
(init Team_Name [(version VerNum)] [(goalie)])
(recoonect Team_Name UniformNumber)
(bye)
 initコマンド、reconnectコマンドは、サーバとの接続を確率するためのコマンドである。クライアントであるプレイヤーエージェントからは、パラメータとしてチーム名を送り、必要であれば自分の想定しているサッカーサーバ・プログラムのバージョンや、自身がゴールキーパーであることを示すS式(goalie)を含めて送る。
recoonectコマンドは、公式試合においてハーフタイム後にエージェントを一度切断/再接続することが認められているために設けられているコマンドで、そのエージェントが復帰するために必要な個人情報であるチーム名と背番号を送って接続を回復させるためのコマンドである。
byeコマンドは単にサーバとの切断を通知するためのコマンドである。異状切断との区別のため、プレイヤーエージェントは通常このコマンドを送ってからプログラムを終了させることが望ましいだろう。

2.4.2 行動コマンド

 行動コマンドはmove,dash,kick,turn,turn_neck,say,catch,change_viewの8つのコマンドからなる。これらのコマンドについては原則として、ゲーム内の1単位時間あたりに1つまでしかコマンドが発行できないという制限がある。もし、複数のコマンドを1単位時間内にサーバが受け取った場合は、それらのうちからランダムに1つ選ばれて実行されることになる。
ただし、change_viewはこの制限とは無関係にコマンドを発行することができ、turn_neckコマンドについてはdash,turn,kickコマンドど同時に処理される。ただし1単位時間に処理されるturn_neckコマンドはやはり1つである。
各コマンドの書式は以下の通りである。
(move X Y)
(dash Power)
(kick Power Direction)
(turn Morment)
(turn_neck Angle)
(say Message)
(catch Direction)
 moveコマンドはXY座標を指定することで、直接その座標に移動することが可能なコマンドである。このコマンドはゲーム開始前やゴール後の再スタート時、ハーフタイム中など特定の位置に戻る必要がある場合や、ゴールキックなどのペナルティエリア内の好きな位置に移動できる状況など、特別な場合に限り受け付けられるコマンドである。
dashコマンドは、プレイヤーエージェントの体の正面の方向に指定したPowerで移動するコマンドである。移動の際にはスタミナを消費する。また、プレイヤーが疲労している場合は、同じPowerのdashコマンドを発行しても、実効移動速度が異なるため、プレイヤーのスタミナモデルを考慮たコマンドの発行が必要になる。
kickコマンドは、指定したPowerで、Direction[°]で指定した体との相対角度の方向にボールを蹴るコマンドである。ボールを蹴るためには、プレイヤーとボールの距離がkickable_areaと呼ばれる範囲内にある必要があり、このデフォルト値は0.6[m]となっている。このコマンドもdashと共通のスタミナモデルが採用されるため、むやみにPowerを高くすることが良いとは言えない。また、ドリブル・シュートの区別も単にPowerの大小の差として区別される。
turnコマンドは、体の向きをパラメータMormentに従って回転させるコマンドである。プレイヤーが全く動いておらず、スタミナが十分にあるのならば、Morment[°]の回転が望めるが、プレイヤーが走っていたりスタミナが十分でない場合は、それより小さい回転角しか得ることができない。
turn_neckコマンドは、体の向きに対する相対的な首の角度をAngle[°]だけ変化させる。これはturnコマンドのようにプレイヤーの状態に依存せず、指定した角度だけ首の角度を回すことができる。
sayコマンドは、Messageで指定したメッセージを周囲に伝達することができる。メッセージの到達範囲は50[m]の範囲内の全プレイヤーあるが、範囲内のプレイヤーが全てsayで発信したMessageを受信できるとは限らない。
catchコマンドはゴールキーパーのみが使えるコマンドで、Direction[°]の方向で、幅1[m]長さ2[m]の範囲の長方形のエリアにボールがある場合に、ボールのキャッチを試みるコマンドである。キャッチが成功した場合、ゴールキーパーによるフリーキックモードに移行する。このとき、ゴールキーパーはボールと一緒にmoveコマンドによる移動をすることができる。

2.5 コーチエージェントに与えられる情報

 コーチエージェントは、プレイヤーエージェントと異なり実体となるプレイヤーはフィールド上に存在しないため、視覚情報の形式が異なるなどの相違点がある。
コーチエージェントは、以下のS式によって情報を与えられる。
(see Time ObjInfo ObjInfo....)
(hear Time Sender Message)
文字列"see"で始まるS式は視覚情報で、プレイヤーエージェントのものと形式が似ているが、ObjInfoの形式が異なる。ObjInfoの書式は以下の通りである。
( ObjName X Y)
( ObjName X Y VelX VelY)
( ObjName X Y Body_Angle Neck_Angle VelX VelY)
ObjNameはオブジェクトの名称で、オブジェクトの種類により異なるS式で与えられる(参考文献[1]参照)。X,Yはフィールドの中心から見たオブジェクトのXY座標である。VelX,VelYは、移動可能なオブジェクトが持つパラメータで、オブジェクトのX,Yそれぞれの方向についての速度を表している。Body_Angle,Neck_Angleはプレイヤーに固有のパラメータで、それぞれ体の向きと体の向きに対する顔の相対角度を表している。
文字列"hear"で始まるS式は聴覚情報で、その形式は2.3.3で述べたプレイヤーの得る聴覚情報と同一の形式である。

2.6 コーチエージェントのコマンド

 コーチエージェントが発行できるコマンドは、公式の試合で用いるオンラインコーチと、練習や強化学習などに用いるオフラインコーチでは若干異なり、オンラインコーチでは、試合の進行や、プレイヤーの操作に関わるコマンドの発行は行うことはできない。
以下にコーチエージェントが発行できるコマンドの書式を示す。
(change_mode NewPlayMode) (オンラインコーチの使用は不可)
(check_ball)
(ear on|off)
(eye on|off)
(look)
(move ObjectName X Y [Angle]) (オンラインコーチの使用は不可)
(say Message)
 change_modeコマンドは、2.2の表1にあるプレイモードのうち1つをNewPlayModeで指定し、そのモードへプレイモードを変更するためのコマンドである。
check_ballコマンドは、ボールの大まかな位置をサーバに要求するコマンドで、サーバはレスポンスとして以下のS式を送ってくる。
(ok check_ball Time Status)
Timeはゲーム内時間を示す。Statusはボールの位置情報で、フィールド内にあることを示す"in_field"、Side側のゴール内にあることを示す"goal_Side"、またはフィールド外にあることを示す"out_of_field"のいずれかの文字列が入る。
ear,eyeの両コマンドは、サーバが聴覚および視覚の情報をコーチに送信するかどうかを指定するコマンドで、onなら受け取り、offなら受け取らないことを示す。
lookコマンドは、サーバに視覚情報を要求するコマンドで、これは(eye off)コマンドを発行していてサーバが視覚情報の送信をしていない状態であっても、サーバから視覚情報を得ることができる。サーバがレスポンスとして送ってくるS式の形式は、クライアントに送られてくるSeeの形式に準じるが、S式の先頭の文字列"see"の代わりに文字列"ok look"が入る。
moveコマンドは、ObjectNameで指定したオブジェクトをX,Yで指定した絶対座標に移動する。さらに、必要ならばAngelパラメータを指定することにより、向きを絶対角で指定することができる。ObjectNameの形式は参考文献[1]に詳しい。
sayコマンドは、プレイヤーに対してメッセージを発信するコマンドで、2.4.2で述べたプレイヤーのsayコマンドと同等のものである。

3.本研究の目標

 本研究の目標は、大きく以下の3つにある。

(1)プレイヤーの行動判断の基準になる視覚状況をできるだけ簡単に量子化し、少ない情報量で正確な状況判断をする。
(2)状況の分類を少なくすることで、データベース的な状況に対する行動の一覧を持たせることを可能にして、少量のデータで的確なプレイをするプレイヤーを作成する
(3)(2)におけるデータベータベースの作成、改良を行うためにコーチエージェントを作成し、半自動によるエージェントの改良サイクルを作り出す

 (1)の視界情報については、視界内のプレイヤーの位置を左遠方・正面遠方・右遠方・左近傍・正面近傍・右近傍の6つの区域で認識させることで位置情報を単純化する。さらにそれらの各区域にいるプレイヤーを数について言及せず、自チーム/相手チームそれぞれについている/いないの2段階で認識することで、視界内のプレイヤー情報を非常に少ない状況に分類する。6つの区域それぞれについてプレイヤーの状況は誰もいない・自チームのプレイヤーのみ存在・相手チームのプレイヤーのみ存在・自チームと相手チーム双方が存在の2ビットの状況に分けられるため、あるプレイヤーの視界における他のプレイヤーの配置状況は4=4096通りに分類されることになる(図4)。

図4          図4
図4 プレイヤーエージェントが認識する視界の区域

さらにボールの状況も蹴れる範囲にある・視界内近傍に存在・視界内遠方に存在・視界外にあるの4つに単純化して、自身の位置を自陣内/相手陣内の2種類に、自身の向きも自陣方向/相手陣方向の2種類に分類する。最終的にプレイヤーが得る視覚情報は4096×4×2×2=65536通りの状況に分類される。
このようなごく少数の状況分類において判断をする場合、分類された65536通りの状況をキーとし、それらの状況に対応する適切な行動を取り出せるよなデータベースを与えることで、サッカーの複雑な戦略やへの専門の対応ルーチンをもたない比較的単純な構造を持つプログラムで、十分な機能を持つエージェントを作成することが可能になる。

さらに、プレイヤーエージェントが適切なデータベースを得るために、コーチングの手法を使ってデータベースの改善・最適化を試みる。RoboCup Soccerのシミュレーションリーグにおいては、コーチエージェントと呼ばれる非プレイヤーのエージェントが利用できる。コーチエージェントについては参考文献[1]に詳しいが、大きな特徴としては

 ・フィールドの完全な情報がサーバから与えられる
 ・試合の流れの制御・プレイヤー位置の設定の権限がある(オフラインコーチのみ)
 ・全てのプレイヤーに伝わるように聴覚情報を発信できる

などの点が挙げられ、これらの特徴を利用することで、プレイヤーに対して大局的な視野に基づく指示を与えることができたり、特定の状況を再現して、エージェントの行動を時間軸に沿ってデータ採取をすることでエージェントの能力を測ったりすることができる。ここではプレイヤーの位置を自在に制御できるオフライン・コーチモード(練習のために用意されるコーチエージェントのモード)の機能を利用して、プレイヤーに状況を与え、その状況でプレイヤーがすべきことと、その状況に対するプレイヤーの行動を考察することでプレイヤーの行動の是非を評価し、データベースの改良のための指示を出すコーチエージェントを作成し、コーチングを重ねることで目標達成のためのデータベースを構築するようにした。

4.プレイヤーエージェントプログラムプログラムの解説

4.1 エージェントについて

エージェントプログラムとは、それ自身が独立した状況認識能力と判断能力を持ち、入力として与えられた環境に対してそれを認識し、何らかの意図のある行動を自律的に行うプログラムのことを指す。RoboCup Soccerにおいては、サッカーフィールドに存在する自分や他人、あるいはボールといったオブジェクトの位置関係などが環境であり、プレイヤーはそれにたいして向きを変える、走る、あるいはボールを蹴るなどといったアクションを通して自分の置かれている環境を変化させるエージェントである、と言うことができる。
RoboCup Soccerのシミュレーションリーグでは、各プレイヤーをエージェントプログラムの形で作成し、それらをクライアントと してサーバプログラムに接続することでプレイヤーをゲームに参加させる。1つのエージェントは1人のプレイヤーに対応し、それぞれが独立したプログラムとして動作することが求められている。 本研究ではエージェントをJava(TM) 2 SDK, Standard Edition Version 1.4.1によって作成し、各エージェントをWindows XP Professional Edition上で複数同時に動作させたため、読み込むデータベースが共有されている。しかし、各々のプログラムが動作しているときはそのようなデータベースの共有を利用した連携をしたりはしていないため、上述のような紳士協定は守られている。

4.2 エージェントプログラムの構成

プレイヤー・エージェントのプログラムは機能分化された多くのクラスの集合体からなっており、その記述にはRoboCup Soccerとしてのルールや特殊な状況への対応はあるものの、行動に関してはサッカーそのもののルールを意識した記述がほとんどないという特徴がある。このため、同じ形式でサーバから情報を提供するような別のゲームにはほぼそのまま対応できるし、いくつかのルーチンを組み替えるなどすれば異なるデータ形式に対応するエージェントに組み替えることも比較的容易であろうという点で優れているといえる。
プレイヤーエージェントの主なクラスの構成を図5にに示す。
図5
図5

図5 プレイヤーエージェントのクラス構成

4.2.1 プレイヤーエージェントのプログラムを構成するクラスの解説

プレイヤーエージェントに使われている主要なクラスは、それぞれ以下のような機能を持っている。それぞれのクラスの動作については、4.2.2で説明する。


クラスPlayer
 クラスStudent5のインスタンスStudentを持つ。
 クラスPlayerは、プレイヤーエージェントのメインクラスでコマンドラインから与えられたパラメータをもとにして、Studentの初期化(接続の確立)を行い、その後、終了の指示を受け取るまでplayメソッドを実行し続ける。終了後の後処理はクラスSudentのquitメソッドで行っている。

クラスStudent5(インタフェース MyConstant)
 クラスHearのインスタンスmyHearing
 クラスSeeのインスタンスmySeeing
 クラスIndicatorのインスタンスmyIndicator
 クラスActionのインスタンスmyAction
 クラスDatabase2のインスタンスinformation
 クラスNetworkのインスタンスcon
 をそれぞれ持つ。
 クラスStudent5は、プレイヤーエージェントの頭脳に相当する部分で、ネットワークを通して入ってくる情報を各クラスに適切に分配して状況を把握し、それらを元に行動を決定し、行動のためのコマンドを生成してネットワークを通してサーバに送る一連の行動を司るクラスである。これらの一連の行動はplayメソッド中で行われ、1回のplayメソッドの実行で1回のコマンドを発行するようになっている。

プレイヤーエージェントの中核になるクラスstudent5のplayメソッドの流れは、以下のようになっている。

1)サーバから情報が来るのを待つ
 ↓
2)サーバからの情報をクラスDatabase2のインスタンスinformationに渡し、情報を更新させる
 ↓
3)情報が視覚情報であるなら、その情報をクラスSeeのインスタンスmySeeingに渡し、情報を更新させる
 ↓
4)情報が聴覚情報であるなら、その情報をクラスHearのインスタンスmyHearingに渡し、情報を更新させる
4')更新された聴覚情報を元に、コーチからの評価が届いていないか、あるいはコーチから状況情報をリセットするような指示が来てないかを確認し、それらの情報が届いているなら評価を反映させたり、状況情報をリセットするなどの処理を行う
 ↓
5)更新された状況をもとにした状況キーをクラスIndicatorのインスタンスmyIndicatorに渡して、自分の行動意欲を変化させる
 ↓
6)更新された行動意欲を確認して、新しい行動指針を決める
 ↓
7)現在の行動指針と、現在の状況に従った行動をするため、必要な情報をクラスActionのインスタンス

myActionに渡し、発行すべきコマンドを得る
 ↓
8)コマンドを発行して、メソッドを終了する

クラスSee
 クラスSeeは、プレイヤーエージェントの量子化した視覚情報を扱うクラスで、ネットワークからStudent5を通して入ってきた情報を分析・量子化する。視覚情報の更新はupDateDataメソッドが呼び出されることで行われ、量子化した情報や、分類のキーとなる状況の16ビット値はそれぞれ独立したメソッドを通して提供される。

クラスHear
 クラスHearは、プレイヤーエージェントの聴覚情報を扱うクラスで、主に現在のプレイモードを受信したり、コーチからの指示情報を、サーバから送られてきた情報から分析し、保存するためのクラスであるといえる。これらの情報の更新はupDateDataメソッドが呼びされることで行われ、得られた情報はそれぞれ独立したメソッドを通して提供される。

クラスIndicator
 クラスIndicatorは、プレイヤーの行動指針を決定するデータベースを扱うクラスで、量子化状況の16ビット値をパラメータとしてupDateIndicatorメソッドが実行されることでデータベースを参照して行動意欲を変化させ、その結果求まる「自分の取るべき行動」を更新する。自分の取るべき行動情報については別のメソッドを通して提供される。
また、このクラスはSoccerFileクラスのインスタンスを通してデータベースのファイルからの読み込みや、ファイルの書き込みを
行うことができる。このため、初期データの読み込みや練習などで得られたデータの更新なども、それぞれこのクラスに用意されているメソッドを通して行うことになる。

クラスAction
 クラスActionは、プレイヤーの行動指針と視覚・聴覚情報を元にして、自分が実際に行う行動をコマンド化するためのクラスである。このため、ほとんどのメソッドは外部からアクセスできないプライベートなメソッドとなっている。
コマンドはgetActionメソッドによって得ることができる。getActionメソッドはSee、Hearの両クラスのコピーと、infomationクラスから得られる自分の正確な座標情報、Indicatorクラスから得られる行動指針をパラメータとして持ち、自分の周囲の状況やゲームモードに応じた適切なコマンドを発行する。
このとき、行動指針によっては適切な移動先を指示する必要があることがある。その場合はsetMovePosToメソッドを呼び出し、事前に移動先を指示する必要がある。

クラスDatabase2
 クラスDatabase2は、プレイヤーの正確な座標や、その他のオブジェクトの正確位置関係を把握するために使われているクラスで、サーバから得られた情報をupdateメソッドを通して得て、その情報に基づいて自分の位置を計算する。今回作成したエージェントは位置情報以外の情報は全てSeeクラスが担当するため、Database2クラスは、正確な位置情報の計算と、メソッドを通したデータの提供のみを担当している。このクラスはクラスDatabaseからクラスDatabase1を経てインプリメントされたクラスである。

クラスNetwork
 クラスNetworkは、サーバとの通信を担当するクラスで、UDP/IP形式でサーバ⇔クライアント間のデータ通信を行うためのメソッドを持つ。これらの制御は全てStudent5クラスが行い、送受するデータも、全てStudent5クラスが受け取り、それを分配する形を取っている。

クラスSoccerFile
 クラスSoccerFileは、行動指針の元となるデータベースファイルの読み書きを担当するクラスである。実装しているメソッドは、ファイルへのアクセスを行う比較的低次のメソッドのみであり、データベースの読み込み/書き込みはクラスIndicatorがこのクラスを通して行っている。

4.2.2 エージェントの主要なクラスの動作

エージェントの主要なクラスの、特に重要なメソッドの動作について解説する。


クラスPlayerの動作
 クラスPlayerは、プログラム全体を統括するクラスである。プログラムはまず、このクラスのmainメソッドを実行することで始まり、mainメソッドが終了することでプログラムが終了することになる。

・mainメソッド
 mainメソッドは、プログラムとしてのエージェントのメインの部分であるが、その動作は単純で、コマンドラインから与えられたパラメータを元に、クラスstudent5のインスタンスStudentの初期化を行い、その後はstudent5がプレイ終了の指示を受け取っているかどうかをstudent5のhaveEoSメソッドで調べ、受け取ってない間sudent5のplayメソッドをループ実行し続ける動作を行うだけである。
そして、student5がプレイ終了の指示を受け取ったならstudent5のquitメソッドを実行してサーバとの接続を切断し、後始末をしてプログラムを終了する。

クラスstudent5の動作
 クラスstudent5は、サッカープレイヤーとしてのエージェントのメインクラスであり、多くのクラスのデータを管理し、プレイヤーの動作を成業するクラスである。このクラスはコンストラクタ、ゲーム中で繰り返される動作の流れを実行するplayメソッドおよび後処理を行うquitメソッドからなる。

・コンストラクタ
 コンストラクタではまず、与えられたパラメータを解読してサーバのIPアドレスなどの情報を得、それに従ってクラスNetoworkのインスタンスconを初期化し、サーバとの接続を確立する作業を行う。
このとき、サーバからのレスポンスとして自分の背番号やサイド(rまたはl)などの情報が送られてくるので、それらの値をSee,Hear,Database2,の各クラスのインスタンスmySeeing,myHearing,inforamtionに通知してそれぞれのクラスの初期化を行わせる。
その後、自分の初期位置を自分の背番号から求め、そうして求まった自分の初期位置と、背番号をもとにクラスActionのインスタンスmyActionを初期化する。

・playメソッド
 playメソッドではまず、サーバから環境情報を受け取るまで待機して、なんらの情報がサーバから通知され、最新の状況が届くのを待つ。そして、データが送られてきたら、その受け取った環境情報を元に、informationの情報を更新する、さらに、情報の先頭部分を解析して、
それが視覚情報であった場合は、受け取った情報を元にmySeeingの情報を更新し、聴覚情報を受け取った場合は、受け取った情報を元に
myHearingの情報を更新する。聴覚情報であった場合、さらにクラスHearのメソッドから解析した詳しい内容を問い合わせる。それがコーチの指導内容であった場合は、それに従った行動意欲データベースの更新を行い、聴覚情報が練習のリセットの指示であった場合には、行動意欲をリセットし、現在の視覚情報から次の学習対象となる状況を得る動作を行う。
こうして、現在の最新の状況の更新を行ったら現在の量子化した視覚情報をキーにして行動意欲の増分をデータベースから取り出し、自分の行動意欲を更新し、現在最も行動意欲の高い行動を行うように行動指針を修正する。これで、自分今持つ行動指針が求まったので、その行動指針と視覚・聴覚情報を元にして実際に発行すべきコマンドを作成する。このとき行動方針が移動に関するもので、移動が終了したと判断されるときは、コマンドの発行をキャンセルし、行動意欲をリセットする作業を別に行っておき、次のコマンド発行時に別の行動に円滑に移れるようにする。
こうして出来たコマンドはNetworkクラスのインスタンスconに渡され、ネットワークを通してサーバーに送られる。

・quitメソッド
 quitメソッドでは、必要な後処理としてmyIndicatorのsaveIndicatorメソッドを呼び出し、行動意欲データベースをファイルに保存させる。そしてサーバからの離脱をメイジするために切断コマンドをNetworkクラスのインスタンスconに渡し、サーバに切断を通知してからプログラムを終了する。

クラスNetworkの動作
 クラスNetworkは、プログラムのネットワーク関連の動作をつかさどるクラスである。
コンソールから与えられたパラメータをinitメソッドに与えて特定のサーバに対してエージェントとしての接続を確立させておくことで、
その後はSend_MessageメソッドとReceive_Messageメソッドを使うことでString型のデータのやり取りを行うことができる。
また、initメソッドの実行過程でサーバから背番号などのプレイヤーに関するパラメータが与えられるため、これらのデータを取り出すためのメソッドが用意されている。

・コンストラクタ
 コンストラクタでは、各クラス変数に適当な初期値を与え、その後でローカルにUDP/IPによる送受信用のデータソケットを作成する。もし
作成できないのなら、プログラムのこの後の動作ができないためプログラムはエラー終了する。

・initメソッド
 initメソッドでは、インスタンスとは別に行われる初期化のための手順で、パラメータをもといしてサーバとの通信を確立するためのメソッドである。このメソッドには引数としてコマンドラインから与えら得れるパラメータが与えられ、これを解析してサーバに送るチーム名やゴーキーパーであるか否かなどのプレイヤーデータに関するS式を作り、それを解析したパラメータから得られたIPアドレスに対して、を送る。
これに対して、サーバは返信を送ってくるのでその返信を待ち、返信に使われたポートを今後のデータ送受信で使うポートとして変数に記憶する。また、返信データには背番号などのプレイヤーに与えられるいくつかの初期値を含むので、データを解析し、与えられた背番号とゲームモードを変数に記憶する作業も行う。

・Send_Messageメソッド
 Send_Messageメソッドは、String型で与えられた引数を、サーバにUDP/IP形式で送信するメソッドである。まず、送信するデータはbyte型にする必要があるため、String型で与えられた引数をbyte型の配列に分解し、そうして得られたデータをデータソケットからUDP/IP形式でサーバに送信するという手順によって、サーバにでーたを送信している。

・Receive_Messageメソッド
 Receive_Messageメソッドでは、サーバからデータを送られてくるまで待機し、そのデータをString型の戻り値として返す処理を行う。
まず、データソケットからサーバからのデータが来るを待ち、得られたデータをbite型の配列に記憶する。この後、戻り値の型であるString型にbyte型のデータを変換してやり、これを戻り値として返してやる。

クラスSeeの動作
 クラスSeeは、本研究の主要な部分の1つである視覚情報の量子化に関する動作を行うためのクラスである。
このクラスは、サーバから与えられる視覚情報を解析し、それらを量子化してクラス変数に記憶させるメソッドupDateDataと、得られた視覚情報を提供したり、視覚状況から与えられる状況の通し番号indicatorHashを提供するメソッド群などからなる。

・コンストラクタ
 コンストラクタでは、チーム名や自分の左右サイドの情報など解析に必要な情報を、引数で与えられたNetworkクラスのデータから得る。

・upDateDataメソッド
 量子化した状況を認識するために、サーバから送られてきた情報と、Database2クラスから得られる自分のXY座標と、自分の向いてる絶対方向を引数としている。
このメソッドでは、主にサーバから送られてきたS式を分解し、オブジェクトごとの情報単位で解析をしていくことで、状況を把握しようとする。オブジェクトには必ず名前が含まれるため、名前によって処理を分岐し、各オブジェクトごとに個別にクラス変数への登録とオブジェクトの位置の量子化の処理が記述されている。
距離と角度については一定のしきい値を参照して遠いか近いかを判定し、プレイヤーの場合はさらにチーム名によって分類してクラス変数に適切な量子化を施した値で記憶していく。
これらの情報は仕様上、オブジェクトとの距離に反比例して誤差を含んだり、与えられなくなったりする可能性がある。そのような劣化情報に対しては、Seeで扱う距離の外であるとして、全て破棄して処理を行っている。これはSeeの仕様上、完全なデータを必要とするという事情と、それらの距離がSeeで扱う「比較的近傍の状況」に対して遠いという事実による。
メソッドの最後に、これらの状況をもとにした行動意欲の取り出しのためのキー値を再計算してメソッドが終了する。

クラスHearの動作
 クラスHearは、サーバから与えられた聴覚情報の解析を行うためのクラスである。
このクラスは、サーバから与えられるタ聴覚情報を解析し、情報をクラス変数に記憶させるメソッドupDateDataと、得られた聴覚情報を提供するためのメソッド群からなる。

・コンストラクタ
 コンストラクタでは、自分の左右サイドの情報や自分の背番号など、解析時に必要となる情報を、引数で与えられたNetworkクラスのデータから得る。

・upDateDataメソッド
 サーバから送られてきた情報を引数にして、その情報を解析するメソッドである。情報は聴覚情報のための一定の書式に従ったS式の形で送られてくるので、トークン単位に1段階分離させて、必要な情報である送信元と本文の情報を取り出す。発信元についての情報を参照するのは、審判(referee)やコーチ(便宜上、これも方向はrefereeとなる)からのシステムメッセージと、そうでないメッセージを区別するためである。
審判やコーチからのメッセージについては、さらに本文を解析する。コーチから送られてくる情報はさらにS式を含む可能性があるため、条件分岐を使って本文の先頭の文字列からそれらを判別して分岐させ、取り出したデータを用意されているクラス変数に適切に振り分けて記憶させる。審判から送られてくる情報は変更されたゲームモードの情報のみで構成されるため、前述の条件分岐に引っかからない場合は、本文そのものを新しいゲームモードであると認識して、クラス変数に記憶させている。

クラスIndicatorの動作
 クラスIndicatorでは、行動意欲の上昇値に関するデータベースを取り扱い、それから求まるプレイヤーの行動意欲と現在取る行動を管理するクラスである。このクラスはクラスSeeで計算される65536通りの状況キーに対して、適切な各行動の行動意欲の上昇値を導き出し、それに従って行動意欲を更新する。行動意欲はクラスActionで実装されている大まかな行動方針ごとに値を持ち、最も大きい行動意欲を持つ行動を「プレイヤーがとるべき行動」として設定するようになっている。
このクラスはまた、SoccerFileクラスのインスタンスを持ち、データベースの値をファイルから読み出したり、逆に書き込んだりする機能を持っている。特に、ファイルへの書き込みは他のクラスから明示的に指示できるように、saveIndicatorというメソッドが用意されている。
他には、状況のキー値に対して行動意欲を更新するupDateVoltageメソッドや、行動意欲を元に取るべき行動を規定するsetメソッド、クラスHearが聞いたコーチの評価を元にデータベースを更新するupDateIndicatorメソッドや、決定された行動指針を提供するメソッドなどを持つ。

・コンストラクタ
 コンストラクタでは、SoccerFileクラスのインスタンスFINを作成し、あらかじめ指定したデータベースの内容を記録したファイルにアクセスし、データベースの初期値を読み込む。コーチの指示のみでデータベースを新しく作成する場合を想定して、引数の指定によりこの作業を行わないようにすることもできる。

・upDateVoltageメソッド
 upDateVoltageメソッドでは、引数として与えられた状況キーをキー値としてデータベースにアクセスして行動意欲の上昇値を導き出し、行動意欲を上昇させる処理を行う。さらに、クラスSeeのメソッドから提供されるボールとの距離を引数にしてボールが現在見えているかどうかを判断し、ボールが見えてない場合はボールを蹴りに行くように補正を加えている。この処理は本来やるべきではないのだが、これにより全てのプレイヤーが常にボールに絡まないなどの事態を避けたり、フィールド外に向かって走ってしまうような事態をある程度避けることができる。

・upDateIndicatorメソッド
 upDateIndicatorメソッドでは、引数として更新すべきデータベースの位置を示す状況のキー値と、現在の行動意欲上昇値に対する差分値が与えられる。このメソッドではキー値をもとに現在の行動意欲の上昇値を取り出し、それぞれに与えられた差分値を足す処理をしている。このとき、一度に上がる行動意欲の値に上限を設けておき、特定の行動に対する行動意欲がが際限なく上がり、そのためコーチングによる修正が困難になってしまう事態にならないようにしている。最後に、こうして作られた新しい行動意欲の上昇値をデータベースへ格納してメソッドは終了する。

・setメソッド
 setメソッドでは、現在の行動意欲を元に新しい行動指針を決定する。このとき、setメソッド呼び出し前後で行動指針が変わったかどうかをチェックしておき、行動指針が変化したななら、一度行動意欲をリセットして次の行動変化がある程度起きやすいように再設定している。このような処理をすると、行動に一貫性があればこれでも同じ行動を続けることができ、逆に行動指針の変化が誤りであった場合は、他の行動指針の行動意欲が早く現在の行動指針の行動意欲を追い抜き、早期に行動を修正することが可能になる。

・saveIndicatorメソッド
 saveIndicatorメソッドでは、SoccerFileクラスのインスタンスFOUTを作成し、あらかじめ指定したファイルに対して現在の行動意欲の上昇値のデータベースの値を順次書き出していく。

クラスActionの動作
 クラスActionは、クラスIndicatorなどのほかのクラスによって決定された行動指針に沿って、実際に今とるべき行動をコマンドとして記述するためのクラスである。そのため、このクラスは行動指針を与えることでコマンドを得るためのメソッドgetActionと、getActionから呼び出されるより下位のprivateなメソッド群でそのほとんどが構成される。
これらのメソッド群に属しないメソッドとしては、一部の行動指針に必要となる移動先の情報をクラスActionに通知するためのメソッドsetMovetoPosメソッドがある。

・getAciotionメソッド
 geActionメソッドでは、クラスActionの機能である行動指針をもとにしたコマンドの発行を行う。このために必要な情報である量子化された視覚情報や聴覚情報、および自分の正確なXY座標と行動指針を引数としている。
このメソッドではまず、行動指針別に分岐を行い、それぞれの行動指針別に異なるルーチンによって行動を決定する。この段階での行動の決定は大まかに「どの方向に、どのくらいの強さで蹴る」程度の指示を下位のprivateなメソッドに送り、下位のメソッドでそれらの指示から細かなパラメータを決めてString型のコマンド列を返すようになっている。
つぎに、行動指針によって決まった行動に対して、ゲームの状態がそれを許すかどうかを検討する。これはゲーム開始前やフリーキックの時など、特別なコマンドの発行を必要とする場合などがあるための処理であり、それらのゲーム状態であった場合は、行動指針によって決まったコマンドを破棄して別のコマンドを作成する。
これで最終的なコマンドが確定するので、得られたコマンドを戻り値として返す。

・setMovePosToメソッド
 setMovePosToメソッドでは、特定の場所に移動する場合など移動先の指定が必要な行動指針が与えられたときに、その移動先をクラスActionに通知するためのメソッドである。このメソッドは移動先の絶対XY座標を示したdouble型の配列を引数として、その値をクラスActionのクラス変数に格納する。このとき、XY座標の指定がフィールド外に出るような値でないかどうかをチェックし、そのような範囲外の値にたいしては適切な範囲内に入るように移動先の値を調整しておく。

クラスDatabase2の動作
 クラスDatabase2は、[1]に掲載されていたサンプルプログラムの流用であるため、実際にこのプログラムが利用するメソッドはあまり多くない。特に関係するメソッドとしては、情報を更新するupdateメソッドと、得られた情報のうち、自分の絶対XY座標を取り出すためのメソッドがある。

・コンストラクタ(クラスDatabese内)
 コンストラクタは親クラスのDatabaseで記述されていて、引数がString型か、クラスNetwork型によって動作が違う。Stringがたの引数が与えられた場合は、それをサーバから与えられたメッセージと解釈し、updateメソッドにデータを渡して処理を行わせる。クラスNetworkで引数が渡された場合は、Netoeorkのメソッドを使って自分のチーム名などの必要な情報を取り出して、クラス変数に記憶させている。

・updateメソッド(クラスDatabase内)
 updateメソッドでは、引数として与えられたString型のデータをサーバから与えられた情報のS式として解釈し、まずそれらの情報が視覚・聴覚・身体情報のどれであるかを判別し、それぞれ適切な下位のメソッドに情報を渡す処理をしている。

・updateBySeeInfoメソッド(クラスDatabase1内)
 このプログラムで必要な情報は自身の正確なXY座標情報のみであるため、実際のプログラムの動作にかかわるメソッドはこのメソッドとupdateSelfInfoメソッドのみである。
このメソッドでは引数で与えられたS式が視覚情報であるという前提を使い、そのS式をオブジェクト単位で分解し、各オブジェクトについての情報をさらに分析していく作業を行っている。
各オブジェクトが含む情報量は、オブジェクトの種類やオブジェクトの見え方(遠近など)などによって差異があるため、まずオブジェクト名を参照してオブジェクトのの種類ごとに分岐し、それぞれのオブジェクトの種類ごとに用意された情報登録用のメソッドを実行する。
自身の位置の測定は、移動しない仮想オブジェクトである旗と線を元にした三角測量によって行われるため、特に旗と線については、見えた本数を登録しておき、位置を測量する際に利用する。
最後に、この更新された情報から自分の向いている絶対角度と絶対座標を求めるため、updateSelfInfoメソッドを呼び出してこのメソッドの動作を終了する。

・updateSelfInfoメソッド
 updateSelfInfoメソッドでは、現在自身が持っているフラッグとラインの情報を元にして自身の向いている絶対方向、絶対座標を計算する。
絶対角度は見えているラインの角度をもとにして求め、絶対座標は見えているフラッグを元に三角測量をして求める。
このとき、ラインは完全に視界がさえぎられない限り最低1本見えることが保障されているが、フラッグについてはそのような保障は存在しないため、三角測量が不可能な場合は1本のフラッグの位置から絶対座標を求めることになる。
まず、見えているラインを1本選び、そのラインが上下左右のどのラインかを解析する。これによって「どのラインが、どの角度で見えているのか」という情報が手に入るので、その情報を元に絶対座標の計算を行う。
次に、絶対座標の測量を行うには、距離情報の質が距離に反比例して悪くなる仕様を考えてできるだけ近い距離にある旗を用いるのが適切であるため、見えているすべての旗を比較して距離が近い2つの旗を選び、三角測量を行って自身の絶対座標を求める。
もし、フラッグが1本しか見えない場合はそのフラッグとの距離と角度から自身の絶対座標を計算する。
最後にこれらの情報をプレイヤー情報としてクラスに登録し、メソッドを終了する。

クラスSoccerFile
 クラスSoccerFileは、行動意欲の上昇値を決めるためのデータベースをファイルから読み込む機能と、逆にファイルに書き出す機能を提供するクラスである。読み込み/書き込みの別はコンストラクタに与える引数で決定するため、ファイルの読み込み/書き込み時には以下のような流れでSoccerFileクラスのインスタンスを使う。
1)SoccerFileのインスタンスを作成する(このとき、読み込み/書き込みのモードを引数として与える)
2)読み込み/書き込みのメソッドを呼び出して読み込み/書き込みを行う
3)読み込み/書き込みが終了したらメソッドを呼び出してファイルを閉じ、作成したインスタンスを破棄する。

・コンストラクタ
 コンストラクタでは、ファイル名と書き込みモードか否かを引数として渡されることを想定している。ファイル名のみを渡された場合は、書き込みモードという前提でコンストラクタが呼び出される。書き込みモードか否かの引数によって処理が分岐し、書き込みモードであれば書き込み用のクラス変数を初期化し、クラス変数に書き込みモードである旨を記憶する。逆に、読み込みモードであれば読み込み用のクラス変数を初期化し、クラス変数にその旨を記憶する。

・Readメソッド/Writeメソッド
 ReadメソッドおよびWriteメソッドでは、ファイルからのデータの読み出しと、ファイルへのデータの書き出しを行う。いずれもメソッド内で読み込みモードか(あるいは書き込みモードか)をチェックし、読み込みモードで書き込みを行おうとしたり、書き込みモードで読み込みを行おうとした場合は何もしないで終了するようになっている。

4.2.3 行動意欲の増減データベースの構造

 今回作成したエージェントプログラムでは、自分の得た視覚情報をキーにして、対応する行動意欲パラメータの増減値をHashMapによるデータベースから引き出している。そのデータベースの形式は以下のようなS式によって管理されている。

(I0 I1 I2 I3 .... In)

I0,I1,...,Inはそれぞれdouble型の数値で、それぞれの数値が各行動指針に対応した行動意欲の増減値になっている。現在実装されている行動指針は以下の5つであり、それぞれの行動指針とその通し番号との対応は以下表2のようになっている

行動指針の通し番号行動指針
移動せずにボールの方向を向く
ボールをパス/シュートする
ボールをドリブル/シュートする
他のプレイヤーからのパスを受けられる場所に移動する
自分の初期ポジションに戻る
表2 行動指針とその通し番号との対応

データベースから引き出したデータは、クラスSTokenizerによって分解して利用する。また、これらの値を更新するときもS式を一度分解してから各データを更新し、再びS式にすることで行っている。これらのデータは全てS式の形でファイルに保存しており、そのファイルは以下のリストのように状況の通し番号を示すコメント行と、状況に対応する行動意欲の増減を示すS式の行の集合によって構成される。。

------ Key = 12287 (0 0.01 0 0 0) ------ Key = 12288 (-0.5 2.01 1.5 0.0 -1.0) ------ Key = 12289 (0 0.01 0 0 0) ------ Key = 12290 (0 0.01 0 0 0)
行動意欲の増減を示すS式を保存したファイルのリスト(抜粋)

5.コーチエージェントの解説

5.1 コーチエージェントのプログラムの構成

コーチエージェントのプログラムは、ほぼ単一のクラスが全機能を網羅しており汎用性を有しない構造になっている。コーチエージェントのプログラムの構成を以下図6に示す

図6
図6 コーチエージェントのクラス構成

5.2 コーチエージェントのクラスの解説

コーチエージェントに使われている主なクラスは、以下のような機能を持つ。それぞれのクラスの動作については、5.3で説明する。


クラスcouach6
 クラスcouachNETのインスタンスconを持つ。
 クラスcouach6は、コーチエージェントのメインクラスで、サーバとの通信についてはクラスcouachNetを介して行うが、それ以外のすべてのコーチエージェントの動作は、このクラス内ですべて実行される。コーチングは練習用の状況をプレイヤーに与えて一定時間行動させ、プレイヤーの行動前後の状況を見て評価をプレイヤーに渡すという手続きを繰り返すことで行われる。

コーチエージェントの中核になるクラスcouach6のmainメソッドにおけるメインルーチンの流れは、以下のようになっている。

1)setFieldメソッドを呼び出し、練習する状況をランダムに1つ選んでその状況再現に必要なオブジェクトの配置コマンドを生成させる
 ↓
2)配置コマンドをもとに、オブジェクトの配置コマンドをサーバに送り、状況をフィールド上に再現させる
 ↓
3)ゲームモードをplay_onに変更し、ゲーム中の状態にする
 ↓
4)lookコマンドをサーバに送って視界情報を得て、得たデータをgetFieldメソッドに送ることで評価のための情報を得る
 ↓
5)練習開始前の評価をstartReportメソッドを呼び出すことで行う
 ↓
6)プレイヤーに"Go"メッセージを送って行動を開始させ、しばらくの間待つ
 ↓
7)lookコマンドをサーバに送って視界情報を得て、得たデータをgetFieldメソッドに送ることで評価のための情報を得る
 ↓
8)練習終了時の評価をendReportメソッドを呼び出すことで行い、最終的な評価を出す
 ↓
9)評価情報をプレイヤーにメッセージとして送る

クラスcouachNet
 クラスcouachNetは、コーチとサーバとの通信を担当するクラスで、ポートの指定などが異なるなど、コーチエージェントの接続用に変更されている以外はクラスNetworkと同じ機能を持つクラスである。

5.3 エージェントの各クラスの動作


クラスcouach6
 クラスcouach6は、コーチングを行うコーチエージェントのメインクラスで、コーチングの作業全般が1つのクラスにまとめて記述されている。
クラスの内容は大きく分けて
・メインルーチン(mainメソッド)
・練習のための状況を作る(setFieldメソッド)
・状況を把握する(getFieldDataメソッド)
・評価を行う(startReport,endReportメソッド)
の4つに分けられる。

・mainメソッド
 mainメソッドは、コーチングのメインループを含み、最初に実行されるメソッドである。
このメソッドではまず引数になるコマンドラインのパラメータをクラスcouachNetのインスタンスconに渡して、コーチとしてサーバに接続する処理を行い、接続が確立したら一連の初期化のためのコマンド群を順次送ってコーチングに必要な環境を整える。このとき、送信に対するレスポンスを待つことで、UDP/IP形式でもコマンドの送信順序を保ってコマンド群を送るようにしている。
その後は、コーチングの一連の流れのサイクルをあらかじめ決めた回数ループして、コーチングを行う。
コーチングの手順としては、まずsetFieldメソッドを呼び出し、練習用の状況をランダムに作成し、その状況を再現するためのオブジェクトの移動命令群を作成する。命令はオブジェクトごとに作成されて線形リストの形でクラス変数に記憶されるので、線形リストから1つず
るコマンドを取り出し、サーバに送信してオブジェクトを移動させている。これで、コーチが想定した状況が作成されたので、この時点で視界情報を明示的に得ることのできるlookコマンドを発行して、作成した状
況を視界情報の形でサーバから送ってもらう。そしてこの視界情報をstartReportメソッドに渡し、状況の評価を行う。評価を行ったらプレイヤーに"Go"メッセージを渡し、プレイヤーの行動を開始させ、視界情報の自動受信回数を使って一定時間の間放置する。一定時間が経過したら再びlookコマンドを発行して視界情報をサーバから受け取り、その情報をendReportメソッドに渡して状況の評価を行う。
状況を与えたときと、それに対してプレイヤーが行動した後の2つの時点で評価を行うことで、プレイヤーがコーチの意図した(よいと思われる)とおりに動いたか、あるいはプレイヤーはゲームの状況を有利にするように行動したかどうかが判断される。
この評価をS式の形に直すため、getReportメソッドを呼び出してS式の形で評価を表し、それをプレイヤーにメッセージとして渡してプレイヤーに評価情報を渡し、これで1回のコーチングのサイクルを終了する。
mainメソッドではこのサイクルを20回1セットとして繰り返し実行し、ループが終了したらプレイヤーに練習終了のメッセージを送って切断を促し、その後でサーバに切断メッセージを送って接続を切ってプログラムを終了している。

・setFieldメソッド
 setFieldメソッドでは、練習に必要な状況の設定を行うためのメソッドである。引数として、プレイヤーエージェントのクラスSeeと同じ形式で量子化された状況のキー値をとるが、引数を与えなかった場合は全状況からランダムに状況を選び、その状況の設定を行うようになっている。
まず、与えられたキー値を分解し、クラスSeeと同じ形式の配列や変数の形でプレイヤーの位置およびボールの位置などのフィールド情報の形のデータを得る。そして、このフィールド情報を解析することでプレイヤーの配置を行うためのコマンドを線形リストに入れていく。この線形リストに入れられたデータは、mainメソッドで呼び出して、実際のプレイヤー配置を行っている。
このとき、プレイヤーの背番号は若い順に割り振られるので、配置に使うプレイヤーは若い背番号から順に配置し、配置しなかったプレイヤーについても、適当なフィールドの隅に移動して練習の阻害にならないように配慮する。
また、配置したプレイヤーについては動作を可能にしておくひつようがあるため、実際に配置されたプレイヤーの番号を使って"Parmit"メッセージの配信コマンドも、コマンドの線形リストの最後に加えておく。

・getFieldDataメソッド
 getFieldDataメソッドでは、サーバからS式で与えられる視覚情報をstartReport、endReportの両メソッドで使うクラス変数の形に加工する作業を行う。引数はlookコマンドのレスポンスとして帰ってくる視覚情報のS式が与えられ、そのS式を各オブジェクト単位に分解し、さらにそれぞれのオブジェクトを仕分けする。このときボール・プレイヤーの2種類については、評価メソッドで使うためにさらに詳細に解析して座標情報などを取り出し、プレイヤーの場合は線形リストに、ボールの場合は専用の変数にそれぞれ座標などのデータを保存する。

・startReportメソッド
 staratReportメソッドでは、練習開始時にサーバから得た視覚情報を元に、プレイヤーはどういう動きをすべきかをコーチの視点かを評価することを行う。また、ボールの動きを追うために、現在のボールの位置を退避しておき、endReportメソッドでの評価を行うための準備も行う。
この段階では、コーチは評価の対象となるプレイヤーがボールを蹴りにいくべきかどうかという観点から評価を行う。コーチはすべてのプレイヤーが自分と同じ原理で動くと仮定し、その場合ボールを蹴りにいく第一の候補は「ボールにもっとも近いプレイヤー」であるべきであるという考えを持っているため、ボールと各プレイヤーとの距離を計算し、味方プレイヤーで自分よりボールに近いプレイヤーがいないかどうかどうか、また、相手チームのプレイヤーでもっともボールに近いプレイヤーはどの位置にいるのかを調べる。
そして、自分がもっともボールに近いプレイヤーである場合はボールを蹴りにいくように、そうでない場合はボールを蹴りにいかず、ほかの行動をとるようにプレイヤーの行動意欲を変化させるような評価を与える。また、自分が味方でもっともボールに近いが、相手チームプレイヤーもボールに近いような状況であれば、より積極的にボールを取りにいくように評価する。

・endReportメソッド
 endReportメソッドでは、練習の1サイクルが終了した時に得たサーバからの視覚情報を元に、ボールの移動やプレイヤーとボールの位置関係から、プレイヤーの行動が適切であったかを評価する。
評価はまず、ボールの移動距離を絶対XY座標の変化から計算し、ボールが動いたかどうか、動いた場合、相手ゴールに近づいたどうかを見る。そして、ボールが移動してなければ、プレイヤーはボールを蹴りに行くべきだったどうかをstartReportメソッド実行時の評価から求めて、その行動の妥当性について検討し、ボールが動いていればボールの移動方向や距離が適切であったかを検証して行動が妥当であったかどうかを検討する。これらの検討の結果はすべてプレイヤーの行動意欲の変化値に対する増加/減少値の形で評価され、プレイヤーにより妥当な行動をするように誘導する。そしてstartReportメソッドとendReportメソッドでの評価を合計し、それがプレイヤーに対しての評価として通知されることになる。

6.プレイヤーエージェントとコーチエージェントの評価

プレイヤーエージェントについては、行動意欲の増分の初期値を"ボールを蹴りにいく"行動についてのみ+0.1、他の行動については0という値にしたプレイヤーエージェントに対してコーチングプログラムによって30回程度のコーチングを行い、このプレイヤーエージェントを3対3で配置してミニゲームを行った。その結果、プレイヤーエージェントの行動に以下のような現象が見られることが分かった。

(1)プレイヤーエージェントが集団でボールを蹴りに行く"団子サッカー"を行う(図7)
(2)逆に、どのプレイヤーもボールを蹴ろうとせず、ボールから離れる現象が起こる(図8)
(3)すぐ後ろに相手プレイヤーがいるにも関わらず、バックパスをして相手にボールを渡す
(4)移動が中断せず、プレイヤーがフィールドの外に出てしまう(図9)

図7
図7 団子サッカーをするプレイヤー(丸囲み内)
図8
図8 ボールに興味を示さないプレイヤー(丸囲み内)

図9
図9 ボールを無視してゴールの先を目指すプレイヤー

 このうち(4)は、移動先を指定するプログラムに何らかの欠陥があることによると思われるが、(1)から(3)の問題はプログラムではなく、考案した視界と位置・方向の量子化に問題の原因を求めることができる。
2つ以上のエージェントがごく近傍で並列して同じ方向を向いている場合、クラスSeeで量子化された視界情報はまったく同じものになる可能性が非常に高いといえる。今回のようなアルゴリズムでは同じ視界情報で同じような位置にいれば同じ行動を選択する可能性が非常に高いため、結果として(1)で挙げたような団子サッカー現象が起こったり、逆に(2)で挙げたような誰もボールに触れようとしない現象が起こるのである。(3)については、後ろ方向に相手プレイヤーがいることが認識できず、かつ現在のプログラムではエージェントが自ゴール方向を向いている場合には真後ろに向けて蹴るために起こる現象である。 なお、行動指針の決定以外の部分では、ゴール方向へのシュート動作などがきちんとできていることから、最低限のプレイができていることが確認できた。

 コーチングについては、1回のプログラム起動により行われるコーチングの回数が認識されうる状況の数に対して極端に少ないため、コーチングが不十分である可能性が指摘できる。この改善のためコーチングのためにサーバの設定を変更し、時間制限をなくすことも可能であるが、時間制限のない設定ではプレイモードの変更ができないという制約があり、このためコーチングの方法を大幅に変えることは不可避である。このため、設定を蹴ることは行わなかった。ただ、コーチングによってプレイヤーエージェントは初期値では行わない"ボールを蹴りにいく"以外の行動を行ったため、プレイヤーエージェントに対するコーチングは正しく行えた可能性がある。しかし、上記(1)から(4)の問題がエージェントに存在し、それらのコーチングに沿った正しい行動をエージェントが行えていないため、それらに対して断定的な考察は行えなかった。

7.改善のアプローチ

 同じ状況に対して同じような行動をするような本アルゴリズムでは、6.で挙げた(1)(2)の問題の解決は難しいといえる。これを解決するには、複数のエージェントが近傍で同じ状況を得てしまった場合に違う回答を得るような例外アルゴリズムを組む必要がある。現在も、ボールを蹴りに行く際にエージェントが走る速度を固定せず、一定の範囲内でランダムになるようにすることで(1)の問題の原因である視界の共有の改善を試みている。遅く走ったプレイヤーからは速く走ったプレイヤーが視界に入るため両者の視覚情報が異なったものになり、違う行動を取る可能性が生じるのである。しかし、それらの改善にも関わらず同一の行動を取ることが多いため、さらに改良が必要だといえる。例えば、「ボールを蹴る」などの目標行動に対して「ボールに一直線に近づいて蹴る」という単一の行動だけでなく「他の軌道を通ってボールに近づく」などの実行動のバリエーションを用意するなどするとさらに改良される可能性があるだろう。また、パラメータの細かい調整を行えなかったが、行動意欲モデルの見直しにより、状況の変化により早くに対応するように修正することでも問題の解決が図れる可能性もある。
他にもsayコマンドを使った連携も考えられるが、sayコマンドを使うとプレイヤーが視覚情報によらない行動指針の獲得をするため、今回のエージェントの趣旨である視覚に応じた行動の決定という方針には合わなくなる可能性があり、望ましい解決方法とは言えないだろう。
また、(2)については現在も「常にボールを蹴りに行くように強制する」アルゴリズムをエージェントに組み込むことである程度の矯正に成功しているが、これは強引な解決手法であり、あまりよい解決方法と言うことはできない。
異なる評価基準を持つコーチエージェントに基づくプレイヤーエージェントを作ることで、常に積極的にボールを蹴りに行くようなエージェントことで、この問題は解決できるが、複数のエージェントが蹴りに行ったり、強引な蹴り込みを行う可能性があるなど、不安定な要素が残る。
(3)については、自分の後方を含む視界外に相手チームのプレイヤーがいることをエージェントが認識できないため、バックパスをしないようにするのが解決策となる。現在はキックインや自分が相手ゴールに対して反対側を向いてるなど、正面に蹴ることが明らかに不利になる状況においてボールを後ろに蹴っているので、これらの状況から反対側にボールを蹴るために他の手段を用いることが必要となる。

8.まとめ

 本研究では、RoboCup Soccerのシミュレーションリーグのプレイヤーエージェントを3.で挙げた視界の量子化による簡易な状況認識による行動の決定手法と、行動決定に利用するデータベースのコーチングによる強化の手法を用いて作成し、単純な構造のルーチンで実戦に耐えるレベルのプレイヤーの作成を行ったが、結論として作成されたプレイヤーエージェントおよびコーチエージェントは未成熟であり、実際の試合においての使用には耐えられるレベルのものが作成できなかったという評価をすることができる。しかし、6で挙げたように改善すべき点が多いため、それらの改善を施し、量子化の精度とデータ量とのバランスについても考察をしたエージェントが作成されたなら、より単純化された判断ルーチンを共用する多種のエージェントが作成できうる可能性があると思われる。



参考文献
 [1] 高橋友一、伊藤暢紘「RoboCupではじめる エージェントプログラミング」(2001年7月15日初版 共立出版)
 [2] 浅田 稔「RoboCup Soccer ロボットの行動学習・発達・進化」(2002年6月20日初版 共立出版)
 [3] Sun Microsystems, Inc. JavaTM 2 Platform, Standard Edition, 1.4.0 API 仕様 http://java.sun.com/j2se/1.4/ja/docs/ja/api/index.html