旗上げゲーム

「旗上げゲーム」は左右の手に持った赤と白の旗を指示に応じてあげたり下げ たりするゲームです。

ここでは、SEATの状態遷移モデル作成の例としてとりあげます。

音声認識文法を作成する

旗上げゲームの文法モデルを定義しましょう。旗上げゲームの入力は「赤あげ て」「赤あげない」「赤さげて」「赤さげない」「白あげて」「白あげない」 「白さげて」「白さげない」のいずれかです。one-ofタグを使うことで各入力 を記述しても良いのですが、ここではよりコンパクトな文法を定義してみましょ う。

flaggame-ja.grxml

<?xml version="1.0" encoding="UTF-8" ?>
<grammar xmlns="http://www.w3.org/2001/06/grammar"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://www.w3.org/2001/06/grammar
                             http://www.w3.org/TR/speech-grammar/grammar.xsd"
         xml:lang="jp"
         version="1.0" mode="voice" root="command">
 
  <rule id="command">
    <one-of>
      <item></item>
      <item></item>
    </one-of>
    <one-of>
      <item>あげて</item>
      <item>あげない</item>
      <item>さげて</item>
      <item>さげない</item>
    </one-of>
  </rule>
 
</grammar>

上記の文法モデルは、「赤」または「白」の次に、「あげて」「あげない」 「さげて」「さげない」のいずれかが続くという文法を定義しています。

グラフ表現によって文法の構造を確認してみましょう。:

$ srgstojulius flaggame-ja.grxml | juliustographviz | dot -Txlib
examples/flaggame/flaggame-ja-grammar.png

対話スクリプトを作成する

旗上げゲームでは、両手に持った旗を上げたり下げたりしますが、一度上げた 旗はもう一度上げることができません(ロボットにこれをやらせてしまうと腕 が一回転してしまいます)。

ここでは旗上げゲームを「状態遷移モデル」を使って記述してみます。

「状態遷移モデル」では、システムの「状態」を定義した上で、その状態の間 の「遷移」と「遷移条件」を記述することでシステムの振る舞いを定義します。

旗上げゲームでは、システムに以下の4つの状態があると考えられるでしょう:

  • 両方下げる
  • 左を上げる
  • 右を上げる
  • 両方上げる

旗上げゲームは両手を下げた状態で始まります。ここで、左に赤い旗、右に白 い旗を持っていたと考えると、「赤あげて」はシステムの状態を左を上げた状 態に遷移させます。

システムが左を上げた状態で「白下げて」と命令するとシステムの状態は「両 方上げる」になります。

システムが両方上げた状態で「赤あげて」と命令してもそれ以上の状態遷移は 起こりません。

SEATは状態遷移モデルをXML形式で記述することができます。上記で説明した旗 上げゲームは以下のように記述できます。

flaggame-ja.seatml

<?xml version="1.0" encoding="UTF-8"?>
<seatml>
  <general name="flaggame">
    <agent name="speechin" type="rtcin" datatype="TimedString" />
    <agent name="speechout" type="rtcout" datatype="TimedString" />
  </general>
  <state name="both_down">
    <rule>
      <key>赤あげて</key>
      <command host="speechout">はい</command>
      <statetransition>left_up</statetransition>
    </rule>
    <rule>
      <key>白あげて</key>
      <command host="speechout">はい</command>
      <statetransition>right_up</statetransition>
    </rule>
  </state>
  <state name="both_up">
    <rule>
      <key>赤さげて</key>
      <command host="speechout">はい</command>
      <statetransition>right_up</statetransition>
    </rule>
    <rule>
      <key>白さげて</key>
      <command host="speechout">はい</command>
      <statetransition>left_up</statetransition>
    </rule>
  </state>
  <state name="left_up">
    <rule>
      <key>赤さげて</key>
      <command host="speechout">はい</command>
      <statetransition>both_down</statetransition>
    </rule>
    <rule>
      <key>白あげて</key>
      <command host="speechout">はい</command>
      <statetransition>both_up</statetransition>
    </rule>
  </state>
  <state name="right_up">
    <rule>
      <key>赤あげて</key>
      <command host="speechout">はい</command>
      <statetransition>both_up</statetransition>
    </rule>
    <rule>
      <key>白さげて</key>
      <command host="speechout">はい</command>
      <statetransition>both_down</statetransition>
    </rule>
  </state>
</seatml>

グラフ表現によって状態遷移モデルの構造を確認してみましょう。:

$ seatmltographviz flaggame-ja.seatml | dot -Txlib
examples/flaggame/flaggame-ja-script.png

コンポーネントを起動し接続する

audioinput コンポーネント、audiooutputコンポーネント、juliusコンポーネ ント、openjtalkコンポーネント、SEATコンポーネントをそれぞれ起動します。

$ pulseaudioinput (portaudioinput)
$ pulseaudioutput (portaudiooutput)
$ juliusrtc flaggame-ja.grxml
$ seat flaggame-ja.seatml

RT-SystemEditorを使って以下のリンクを作成してください:

  • audioinput -> julius
  • julius (result) -> SEAT
  • SEAT -> openjtalk
  • openjtalk (result) -> audiooutput

すべてのコンポーネントをアクティベートして動作を確認してください。

SEATコンポーネントを起動したコンソールを見ると、システムが現在どの状態 にいるかが表示されます。どの状態でどの遷移条件が有効になったのかを意識 しながらコマンドを発話してください。