スキップしてメイン コンテンツに移動

Pepper SDK入門(6) アクション

ロボットフォーカスとロボットライフサイクルに関しては、前回学習しました。今回はPepperのアクションについて掘り下げます。

Pepperでのアクション実行

Pepperは、話す・聞く・動く・アニメーションを再生する・人間を見つめる・チャットを行う・視線を動かす・特定の地点に留まる・写真を撮るといった動作が可能です。アプリを開発する際、これらのアクションがメインの構成要素になります。

1.アクションの作成

ビルダーを用いて、アクションを同期もしくは非同期で作成します。以下が各アクションをビルドする手順です。
  1. アクションのビルダーにQiContextを渡す
  2. ビルダーへアクションのパラメータを渡す
  3. buildメソッドかbuildAsyncメソッドを呼び、アクションを作成する

同期

アクションを同期で作成するため、ビルダーのbuildメソッドを呼びます。
Say say = SayBuilder.with(qiContext) 
                    .withText("こんにちは") 
                    .build();

非同期

アクションを非同期で作成するため、ビルダーのbuildAsyncメソッドを呼びます。
Future<say>sayActionFuture = SayBuilder.with(qiContext) 
                                        .withText("Hello!")
                                        .buildAsync();
アクションを非同期で作成すると、非同期処理と連携するためのFutureインスタンスが取得できます。

2.アクションの実行

1で作成したアクションを実行してみましょう。

同期

アクションを同期で実行するには、runメソッドを使用します。
say.run();

非同期

アクションを非同期で実行することもできます。
Say.Async sayAsync = say.async();
sayAsync.run();
asyncメソッドでAsyncオブジェクト取得し、Asyncオブジェクトのrunメソッドを呼ぶことで非同期で実行されます。一行で書くと以下のようになります。
say.async().run();
非同期の結果(処理の説明) 非同期と同期で、以下の違いがあります。
  • 非同期でアクションを実行すると、スレッドはブロックされない。
  • 非同期でアクションを実行すると、runを呼んでからすぐには終わらない。

アクションの実行管理

上記で各アクションを同期と非同期で実行したことにより、次のことが可能になりました。
  • アクション結果の獲得
  • エラーハンドリング
  • アクションのキャンセル

1.アクション結果の獲得

アクションの実行方法が分かったところで、アクションが成功した場合について見ていきます。

同期

アクションを同期で実行し、結果を受け取りたい場合にはrunメソッドを使用します。
Void ignore = say.run();
Log.i(TAG, "Say action finished with success.");
ここではSayが戻り値を持たないためVoidクラスですが、アクションによっては値を返す場合もあります。

非同期

アクションを非同期で実行する際にはrunメソッドがFutureを返すため、Futureを保持しておく必要があります。
Future<void>sayFuture = say.async().run();
FutureクラスのandThenConsumeメソッドにより、非同期で実行したアクションの結果を受け取ることが出来ます。
Future<void>sayFuture = say.async().run();
sayFuture.andThenConsume(ignore -> {
    Log.i(TAG, "Say action finished with success.");
});
asyncメソッドを使用すればボタンをクリックした時にPepperに発話させるなど、UIスレッド上から簡単にバックグラウンドで非同期アクションを実行させることが可能です。Qi.onUiThreadメソッドを使用すると、アクション終了時にUIスレッド上で操作することができます。
sayFuture.andThenConsume(Qi.onUiThread((Consumer<void>) ignore -> {
    Toast.makeText(MainActivity.this, "Say action finished with success.", Toast.LENGTH_SHORT).show();
}));

2.エラー処理

アクションを実行する際には常にエラー発生の可能性があり、その対処法はアクションの実行方法に依存します。

同期

アクションを同期で実行した場合、RuntimeExceptionがスローされるかもしれません。onRobotFocusGainedメソッドでこれが発生した場合、runメソッドを呼んだところで実行は停止してしまうため、try-catchブロックでエラーを管理しましょう。
try {
    say.run();
    Log.i(TAG, "Success");
} catch (Exception exception) {
    Log.e(TAG, "Error", exception);
}

非同期

アクションを非同期で実行した場合、アクションの中のエラーを取り扱うにはthenConsumeメソッドを使用しましょう。Futureクラスにはアクションが非同期実行中にエラーがないかチェックするhasErrorメソッドがあります。
Future<void>sayFuture = say.async().run();
sayFuture.thenConsume(future -> {
    if (future.isSuccess()) {
        Log.i(TAG, "Success");
    } else if (future.hasError()) {
        Log.e(TAG, "Error", future.getError());
    }
});

3.アクションのキャンセル

アクションをキャンセルしたい場合の操作についてです。 該当するFutureクラスのrequestCancellationメソッドを呼ぶことでアクションをキャンセルします。
Future<void>sayFuture = say.async().run();
sayFuture.requestCancellation();
FutureクラスのthenConsumeメソッドを使用している場合には、isCancelledメソッドでアクションがキャンセルされているかどうか確認できます。
Future<void>sayFuture = say.async().run();
sayFuture.thenConsume(future -> {
    if (future.isSuccess()) {
        Log.i(TAG, "Success");
    } else if (future.isCancelled()) {
        Log.i(TAG, "Cancelled");
    }
});
sayFuture.requestCancellation();

複数のアクションを使用する

以下で複数のアクションを使用する場合について確認していきます。

1.複数のアクションを連続実行する

ここでも同期、非同期に分けてそれぞれの方法を解説します。

同期

アクションを同期で連続実行してみましょう。
Say sayHello = SayBuilder.with(qiContext)
                         .withText("こんにちは")
                         .build();
Say sayPepper = SayBuilder.with(qiContext)
                          .withText("私はPepperです")
                          .build();
sayHello.run();
sayPepper.run();
最初のアクションが成功すると、2つ目のアクションが実行されるはずです。

非同期

FutureクラスのthenComposeとandThenComposeで、複数のアクションを非同期で連続実行できます。
Say sayHello = SayBuilder.with(qiContext)
                         .withText("こんにちは")
                         .build();
Future<void> sayHelloFuture = sayHello.async().run();
sayHelloFuture.andThenCompose(ignore -> {
    Say sayPepper = SayBuilder.with(qiContext)
                              .withText("私はPepperです")
                              .build();
    return sayPepper.async().run();
});

2.アクションを同時に実行する

Pepperに複数のアクションを同時に実行させたい場合、アクションを非同期で続けて実行してください。ただし複数の発話や、発話と聞き取りなどは同時に実行することが出来ません。
Say say = SayBuilder.with(qiContext)
                    .withText("こんにちは")
                    .build();
Animate animate = AnimateBuilder.with(qiContext)
                                .withAnimation(animation)
                                .build();
say.async().run();
animate.async().run();

コメント

このブログの人気の投稿

Pepper SDK入門(1) Pepper SDKプラグインのインストール

Pepper SDK for Androidのサイトが黙々とアップデートされています。そろそろ感もありますので、Pepper SDK for Androidの公式サイトを読みつつ、理解したことをまとめていきたいと思います。 Android Studio対応版Pepperでは、AndroidのActivityからAPIを使用して、会話や動きを制御することが出来るようです。Pepper SDK for AndroidはAndroid Studioのプラグインであり、グラフィカルツール、Javaライブラリ、QiSDKを提供します。 Android Studio対応版Pepper向けのロボアプリを開発するため、以下に従って開発環境を整えましょう。 《OSバージョンの確認》 まずは、OSとバージョンの互換性を確認してください。 Linux … Ubuntu 16.04 Xenial Xerus - 64bits only Windows … Microsoft Windows 10 - 64bits only Mac … Mac OS X 10.12 Sierra 《Android Studioのインストール》 ロボアプリはPepperにビルトインされたAndroidのタブレット上で動くアプリであり、それによって開発を行うため、Android Studioのインストールが必要です。 <必要なもの> ・Android Studio Version 2.3かそれ以降 最新の安定したバージョンのインストールを推奨しています。 ・Java Development Kit (JDK) Android Studioの動作環境 Android Studioのインストールにあたっては、以下の公式インストールガイドに従ってください: http://developer.android.com/sdk/index.html 《Android SDKとビルドツールの入手》 Androidのアプリを開発するために、Android SDKとビルドツールのインストールが必要です。 <手順> ① Android Studioのツールバーから、 SDK Managerをクリックすると、SDK Managerが表示さ

Pepper SDK入門(3) はじめてのロボアプリ開発②

Androidプロジェクトの作成及びロボアプリの初期設定を行った前回に引き続き、Pepperのエミュレータと実機でアプリを実行するために必要な手順を確認していきます。 1.Pepperのエミュレータ  まずは、Pepperのエミュレータで動作確認するための方法についてです。 <手順> エミュレータボタン をクリックしてください。すると、ロボットエミュレータが表示されます。 プロジェクトにおける実行の構成でappが選択されているか を確認し、 選択されていない場合はそれを選択してください。 実行ボタン をクリックしてください。すると、Select Deployment Targetダイアログが表示されます。 ダイアログからPepperのエミュレータを選択してください。アプリがエミュレータにインストールされ、Robot Viewer上のバーチャルロボットで動作確認することが出来ます。 2.Pepperの実機  次に、Pepperの実機で動作確認するための方法を見ていきます。 <手順> Pepperのタブレットの設定を確認します。タブレットのホームにある設定アイコンをタップし、以下の設定を確認してください。 開発者モードが有効になっていること 開発者向けオプション、デバッグ、ADBも有効になっていること Android studioで、接続ボタン をクリックし、Robots Browserを表示してください。 Use fix portとUse fixed IP/hostnameにチェックを入れ、接続先のPepperのIPアドレスを入力してください。PepperのIPアドレスはタブレットの通知バーか、胸部ボタンを一回押すことで確認できます。 Selectボタンをクリックしてください。すると、セキュリティの警告が表示されます。 Pepperのパスワードを入力してください。初期パスワードはnaoです。変更している場合は管理者に確認して下さい。パスワード入力後にOKボタンをクリックすると、Robot Viewerが表示されます。 Pepperの実機に接続すると、同時にタブレットにもADB経由で接続されます。 プロジェクトにおける実行の構成でappが選択されてい

Pepper SDK入門(5) Robot focus と Robot lifecycle

Pepper SDK Plugin導入から始まり、簡単なロボアプリの開発を行ってきました。今回は、QiSDKの基本となるRobot focus と Robot lifecycleについて説明します。 1.フォーカスを理解する まずはロボットフォーカスについての簡単な説明です。 Activityがロボットのアクションを実行するためには、ロボットフォーカスが必要です。ロボットフォーカスはフォアグラウンドのActivityだけが保持することができ、ロボットフォーカスオーナーと呼ばれます。ロボットフォーカスはQiSDKに管理されており、Activityはいつでもロボットフォーカスを獲得したり喪失したりする可能性があります。  2.ロボットライフサイクル Pepper SDK入門(2) はじめてのロボアプリ開発①で登場したロボットライフサイクルについてです。 QiSDKがそれぞれのActivity用のロボットフォーカスを渡すために、RobotLifecycleCallbacksインタフェースを実装したオブジェクトが必要になります。以下はActivityにRobotLifecycleCallbacksインタフェースを実装した例です。 public class MyActivity extends RobotActivity implements RobotLifecycleCallbacks また、RobotLifecycleCallbacksオブジェクトにコールバックさせるにはonCreateメソッドでActivityとRobotLifecycleCallbacksオブジェクトをQiSDKに登録する必要があります。 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); QiSDK.register(this, this); } その上で、onDestroyメソッドでの登録解除も必要です。  @Override protected void onDestroy() { QiSDK.unregister(this, this); super.onDestroy(