Pepperのタブレットで画像や動画を表示する方法についてみてきましたが、JavaScriptなどを含むHTMLコンテンツをタブレットで実行することで、よりリッチなコミュニケーションを実現することができます。
ここでは、HTMLコンテンツの基本的な表示方法と、QiMessaging JavaScriptライブラリによる、HTMLコンテンツとビヘイビアとを連携する方法について紹介します。
なお、**このサンプルはバーチャルロボットでの動作確認手段はなく、Pepper実機が必要になります。**アルデバラン・アトリエ秋葉原などでPepper実機を使って実験などおこなってみていただければと思います。 (予約URL:http://pepper.doorkeeper.jp/events)
#Pepperとタブレット
Pepperでタブレットアプリケーションを作成するにあたり、Pepperで動作しているNAOqi OSとタブレットで動作しているソフトウェアの関係を簡単に説明していきます。
##NAOqiでのアプリケーション実行
これまで紹介してきたサンプルの多くが、Choregraphe上でボックスをつないで振る舞いを作成し、実行する形式のサンプルでした。
これらの実行時には、接続されているPepperのNAOqi OS上にアプリケーションのファイル一式がアップロードされたのち、NAOqi OS上でアプリケーションのビヘイビアが実行されるという処理がおこなわれています。
ビヘイビアは、その中に配置されたボックスがNAOqi API(ALMemory, ALTextToSpeech など)にアクセスすることで、さまざまな処理を実現することができます。
このように、Choregrapheで作成したアプリケーションはPepper上で実行される形になります。
##タブレットでの画像や動画の表示
PepperのタブレットではAndroid OSが動作しており、Pepperで動作しているNAOqi OSとは独立したものとして動作しています。
NAOqi OSとAndroid OSは内部的なネットワークで接続されており、ビヘイビアからは ALTabletService API を通じてタブレットに対してブラウザを起動するなどの指示を出したり、タッチイベントを取得したりといったことが可能になっています。
たとえば、tabletボックスライブラリはこれらのAPIを用いることで、NAOqi上からタブレットへの画像表示や動画表示を指示している形になります。
また、タブレット内のブラウザはALTabletService
経由で受けた指示に従い、アプリケーションの画像ファイルやHTMLファイルを取得し、表示をおこないます。
これまで「タブレットに表示したいコンテンツはプロジェクト中の html
ディレクトリに配置する」と説明してきましたが、これはNAOqiが、タブレットのようなNAOqi外のシステムに対してはhtml
ディレクトリ内のファイルにのみアクセスを許可するような構造になっているためです。
##QiMessaging JavaScript
タブレットのブラウザでは、通常のWebのコンテンツと同様にJavaScriptを記述し、実行させることができます。
加えて、NAOqiが提供するQiMessaging JavaScriptライブラリをHTMLコンテンツ内で読み込むことで、JavaScriptからNAOqiのAPIに対して操作をおこなうことが可能になります。
つまり、QiMessaging JavaScriptを用いることで、HTMLコンテンツからもNAOqiの各機能にアクセスできるようになります。
今回は例として、ALMemory
を介したビヘイビアとHTMLコンテンツの連携についてみていきます。
#試してみる
ここでは、ChoregrapheでのHTMLコンテンツの作成方法から、QiMessaging JavaScriptの利用までを、簡単な例を追ってみていきます。
##プロジェクトファイルの入手方法
このチュートリアルに関するプロジェクトファイルはGitHub https://github.com/Atelier-Akihabara/pepper-qimessaging-examples にて公開しています。
GitHubにあるコードの取得方法にはいくつかありますが、[Download ZIP]リンクからアーカイブを取得するのが簡単な方法のひとつです。他にもgit関連ツールを利用する方法などさまざまな方法がありますので、状況に応じて調べてみてください。
##簡単なHTMLをタブレットに表示
まずは、プロジェクト内にHTMLで単純なコンテンツを作成し、タブレットに表示させてみます。
サンプルプロジェクトは show-app です。GitHubから取得したファイルのうち、 show-app
フォルダ内の show-app.pml
をダブルクリックするなどして開くことができます。
-
html
ディレクトリを作成する
プロジェクトの内容パネルの追加ボタンをクリックし、[ディレクトリの作成...] をクリックします。
-
index.html
ファイルを作成する
以下のようなファイルをテキストエディタで作成し、適当な場所に保存します。なお、保存する際の文字コードはUTF-8を指定してください。<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>タブレットに表示したいページ</title> </head> <body> <div style="font-size: 6em"> タブレットに表示したいページ </div> </body> </html>
-
index.html
ファイルをインポートし、html
ディレクトリ内に配置します
プロジェクトの内容パネルの追加ボタンをクリックし、[ファイルのインポート...] をクリックします。
インポートするファイルを問い合わせるダイアログが開きますので、2.で作成した
index.html
を選択します。すると、プロジェクトファイルにindex.html
がインポートされます。
index.html
をhtml
ディレクトリにマウスドラッグして移動します。
これでHTMLコンテンツの準備は完了です。
-
ビヘイビアにShow Appボックスを配置する
tabletボックスライブラリ > Show Appボックスをフローダイアグラムにドラッグ&ドロップし、以下のように接続します。
-
Show Appボックスを修正する
Show AppボックスはShow Imageボックスと同様のパス問題を持っています。そのため、Show Appボックスの_getAppName
関数のコードを修正します。fragment = behaviorPath.split(appsFolderFragment, 1)[1] # 以下の1行を追加 fragment = fragment.split("/")[1] return fragment.lstrip("\\/")
これで、index.html
の内容をタブレットに表示するアプリケーションの完成です。
###実行する
ChoregrapheでPepperに接続し、**[ロボットにアップロードして再生]**をおこないます。
以下のようにタブレットに index.html
の内容が表示されれば成功です。
##簡単なJavaScriptを実行
次に、HTML中に簡単なJavaScriptを記述してみます。JavaScriptの例として、HTMLコンテンツ上のボタンが押されたらログメッセージを表示することをおこなってみます。
一般にブラウザ上のJavaScriptでは console.log
APIを用いてログ出力をおこなうことができますが、PepperのタブレットでもこのAPIが提供されており、出力したログメッセージはALMemory
のメモリイベント ALTabletService/message
から取得することが可能です。
サンプルプロジェクトは simple-js です。GitHubから取得したファイルのうち、 simple-js
フォルダ内の simple-js.pml
をダブルクリックするなどして開くことができます。
-
先ほど作成した [簡単なHTMLをタブレットに表示] と同じ手順で
html
ディレクトリ、Show Appボックスを準備する -
以下のような
index.html
ファイルを作成する
先と同様の手順でhtml
ディレクトリ内に配置します。<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>単純なJavaScript (ログ出力)</title> <script> // ログを出力するだけの関数 // <button>が押されると、onclick属性に指定されたスクリプトが実行され、この関数が // 実行されます。 function sampleButtonClicked() { console.log("sampleButtonClicked") } </script> </head> <body> <div style="font-size: 6em"> 単純なJavaScript (ログ出力) </div> <button style="font-size: 6em" type="button" onclick="sampleButtonClicked();">ログ出力</button> </body> </html>
script
要素に関数sampleButtonClicked
を記述し、これを[ログ出力]ボタンクリック時に実行(onclick
属性で指定)する形にしています。 -
ALTabletService/message
メモリイベントをLogボックスにつなぐ
**メモリイベント追加[+]ボタンをクリック[A]し、フィルターにALTabletServiceと入力[B]**し、ALTabletService/messageをチェック[C] し[OK]ボタンを押します。
standardボックスライブラリ > System > Logボックスをフローダイアグラムに配置し、以下のように **ALTabletService/message 入力とつなぎ[A]**ます。また、ログがタブレットからのものとわかりやすいように、**パラメータのMessage prefixをTabletに変更[B]**します。
このようにして、HTMLで呼び出した console.log
によるメッセージをメモリイベントとして取得し、Choregrapheのログ出力で確認することが可能になります。
###実行する
ログビューアを開いてログが確認可能な状態にして、プロジェクトを実行してみてください。
まず、タブレットでのブラウザの起動処理などが動作し、以下のようなログが表示されます。
[INFO ] behavior.box :onInput_message:27 _Behavior__lastUploadedChoregrapheBehaviorbehavior_11027515016__root__Log_1: Tablet: [INFO] TabletService : Loading application .lastUploadedChoregrapheBehavior
[INFO ] behavior.box :onInput_message:27 _Behavior__lastUploadedChoregrapheBehaviorbehavior_11027515016__root__Log_1: Tablet: [INFO] TabletService : Loading url: 'http://198.18.0.1/apps/.lastUploadedChoregrapheBehavior'
[INFO ] behavior.box :onInput_message:27 _Behavior__lastUploadedChoregrapheBehaviorbehavior_11027515016__root__Log_1: Tablet: [INFO] TabletService : Ping url : http://198.18.0.1/apps/.lastUploadedChoregrapheBehavior response : 200
[INFO ] behavior.box :onInput_onStart:56 _Behavior__lastUploadedChoregrapheBehaviorbehavior_11027515016__root__ShowApp_2: Successfully set application: .lastUploadedChoregrapheBehavior
[INFO ] behavior.box :onInput_message:27 _Behavior__lastUploadedChoregrapheBehaviorbehavior_11027515016__root__Log_1: Tablet: [INFO] TabletService : Show web view
この後、タブレットに [ログ出力] というボタンがあらわれますので、タブレットをタッチしてボタンを押してみてください。以下のようなログメッセージが表示されるはずです。
[INFO ] behavior.box :onInput_message:27 _Behavior__lastUploadedChoregrapheBehaviorbehavior_11027515016__root__Log_1: Tablet: [INFO] WebView : onConsoleMessage : sampleButtonClicked
これは、Pepperのタブレット内でJavaScriptが実行され、そこで実行された console.log
の内容が ALTabletService/message
メモリイベントを通じてログに出力されたことを意味しています。
JavaScriptでの開発の際は、console.log
を活用することでスクリプトの動作の把握がしやすくなります。
##アプリケーションとの連携
JavaScriptが動作することが確認できたので、QiMessaging JavaScriptを用いてJavaScriptからNAOqi APIにアクセスしてみましょう。
今回は ALMemory
を介して、ビヘイビアとHTMLコンテンツを連携させてみます。
###タブレット→アプリケーション
まず、タブレットのJavaScript側からイベントを発行し、これをビヘイビア側で取得してみます。
簡単な例として、タブレットのボタンが押されたら独自メモリイベント PepperQiMessaging/fromtablet を発行し、ビヘイビア側で渡された値をしゃべる ということをやってみます。
サンプルプロジェクトは memory-from-tablet です。GitHubから取得したファイルのうち、 memory-from-tablet
フォルダ内の memory-from-tablet.pml
をダブルクリックするなどして開くことができます。
-
先ほど作成した [簡単なJavaScriptを実行] と同じ手順で
html
ディレクトリ、Show Appボックス、console.log
の確認用Logボックスを配置する -
PepperQiMessaging/fromtablet
メモリイベント入力を作成する
今回は独自のキーを持つメモリイベントを利用します。フローダイアグラム上でメモリイベント追加[+]ボタンをクリックし、[メモリイベントの選択]ダイアログを開き、**[新しいキーの追加...]**をクリックします。
-
PepperQiMessaging/fromtablet
メモリイベント入力をSay Textボックスに出力する
advancedボックスライブラリ > Audio > Voice > Say Textボックスを配置し、以下のように接続します。
-
index.html
を修正する
今回は以下のようなHTMLを記述します。<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>QiMessaging (メモリに出力)</title> <script src="/libs/qimessaging/1.0/qimessaging.js"></script> <script> var session = new QiSession(); function sampleButtonClicked() { session.service("ALMemory").done(function (ALMemory) { console.log("ALMemory取得成功"); ALMemory.raiseEvent("PepperQiMessaging/fromtablet", "押したね"); }); } </script> </head> <body> <div style="font-size: 6em"> QiMessaging (メモリに出力) </div> <button style="font-size: 6em" type="button" onclick="sampleButtonClicked();">メモリイベント発生</button> </body> </html>
重要なのは以下の3点です。
-
qimessaging.js
の読み込み
以下のscript
要素により、タブレットにqimessaging.js
をダウンロード・実行します。<script src="/libs/qimessaging/1.0/qimessaging.js"></script>
-
QiSession
オブジェクトの作成
ページのロード時に、qimessaging.js
に定義されたQiSession
オブジェクトを初期化しています。JavaScriptは、このオブジェクトを介してNAOqi APIにアクセスできるようになります。var session = new QiSession();
-
QiSession
からのALMemory
取得、ALMemory.raiseEvent
呼び出し
ボタンが押された際の処理で、session
オブジェクトに対してservice
関数を通じてALMemory
へのアクセス用オブジェクトを要求します。
この取得処理は非同期的に実行され、取得完了時にfunction (ALMemory) { ... }
関数がアクセス用オブジェクトALMemory
をともなって呼び出されます。session.service("ALMemory").done(function (ALMemory) { console.log("ALMemory取得成功"); ALMemory.raiseEvent("PepperQiMessaging/fromtablet", "押したね"); });
-
このようにして、JavaScript側でボタンが押された際に、ALMemory.raiseEvent
を実行することで、独自メモリイベント PepperQiMessaging/fromtablet
に 押したね
という値をつけて発火させています。
ビヘイビア側ではPepperQiMessaging/fromtablet
の値をSay Textボックスに入力することで、JavaScriptで指定された文字列(押したね)をしゃべらせています。
####実行する
このアプリケーションをPepperで再生してみてください。
タブレットに[メモリイベント発生]ボタンが表示されるので、これを押すとPepperが「押したね」としゃべります。
このように、ALMemory.raiseEvent
により、メモリイベントを介してタブレットからビヘイビアへと処理を伝達することができます。
###アプリケーション→タブレット
今度は逆に、アプリケーションで発火したイベントをJavaScript側で取得してみます。
簡単な例として、Basic Awarenessで得られた人のIDをメモリイベントを介してタブレットに渡す ということをやってみます。
サンプルプロジェクトは memory-to-tablet です。GitHubから取得したファイルのうち、 memory-to-tablet
フォルダ内の memory-to-tablet.pml
をダブルクリックするなどして開くことができます。
-
[簡単なJavaScriptを実行] と同じ手順で
html
ディレクトリ、Show Appボックス、console.log
の確認用Logボックスを配置する -
Basic Awarenessボックスを配置する
standardボックスライブラリ > Trackers > Basic Awarenessボックスをドラッグ&ドロップします。 -
Raise Eventボックスを配置する
ビヘイビア側でイベントを発火させるため、 advancedボックスライブラリ > Memory > Raise Eventボックスを配置し、パラメータkeyにPepperQiMessaging/totabletを設定します。
-
ボックスをつなげる
以下のようにボックスをつなげます。なお、Show AppボックスとBasic Awarenessボックスの間は3秒程度のWaitボックスを挿入しています。今回の例では、タブレットでのコンテンツがロードされたのちにBasic Awarenessが起動するように制御する必要があったのですが、例として単純化するためにWaitで実現しています。
-
index.html
を修正する
HTMLは以下のようにします。<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>QiMessaging (メモリを監視)</title> <script src="/libs/qimessaging/1.0/qimessaging.js"></script> <script> var session = new QiSession(); function toTabletHandler(value) { console.log("PepperQiMessaging/totabletイベント発生: " + value); document.getElementById("memory").innerHTML = value; } function startSubscribe() { session.service("ALMemory").done(function (ALMemory) { console.log("ALMemory取得成功"); ALMemory.subscriber("PepperQiMessaging/totablet").done(function(subscriber) { subscriber.signal.connect(toTabletHandler); }); }); } </script> </head> <body onLoad="startSubscribe();"> <div style="font-size: 6em"> QiMessaging (メモリを監視) </div> <div style="font-size: 4em"> 現在のPepperQiMessaging/totabletの値: <span id="memory">不明</span> </div> </body> </html>
先の例に加えて重要なのは
ALMemory.subscriber
によるイベントの監視部分です。以下の処理により、PepperQiMessaging/totablet
メモリイベントが発生した際にJavaScriptで定義したtoTabletHandler
関数が呼び出されるように設定しています。ALMemory.subscriber("PepperQiMessaging/totablet").done(function(subscriber) { subscriber.signal.connect(toTabletHandler); });
####実行する
このアプリケーションをPepperで再生してみて、Pepperに近づいたり、離れたりしてみてください。
Pepperのビヘイビア内、Basic Awarenessボックスが検出した人のIDがタブレットに表示されるはずです。
このように、ALMemory.subscriber
により、ビヘイビアからタブレットへとメモリイベントを伝達することができるようになります。
以上のように、QiMessaging JavaScriptを利用することで、Choregrapheのボックスとタブレットを密接に連携させたアプリケーションを実現することが可能になります。
また、QiMessaging JavaScriptでは、ALMemory
以外に他にもALMotion
などのさまざまなAPIにアクセスすることが可能です。今後は、QiMessagingからAPIへとアクセスする例も扱っていく予定です。