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

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();
}

3.ロボットフォーカスの獲得 

ロボットフォーカスの獲得に関して詳述します。 ロボットフォーカスはActivityがフォアグラウンドに遷移したタイミングでActivityに与えられ、QiSDKからRobotLifecycleCallbacksオブジェクトのonRobotFocusGainedメソッドがコールバックされます。
void onRobotFocusGained(QiContext qiContext);
以下が許可されているQiContextです。
  •  アクションの作成
    Say say = SayBuilder.with(qiContext)
                        .withText("こんにちは")
                        .build();
  • アクション用リソースの作成
    Animation animation = AnimationBuilder.with(qiContext)
                                          .withResources(R.raw.elephant_a001)
                                          .build();
  • ロボットサービスの取り扱い
    HumanAwareness humanAwareness = qiContext.getHumanAwareness();
    
  • このコールバックで、アクションを実行することが出来ます。
  • アクションの実行
         say.run();
    
         say.async().run();
    

4.ロボットフォーカスの喪失

ロボットフォーカス喪失について詳述します。 ロボットフォーカスを喪失したActivityと一緒に登録されたRobotLifecycleCallbacksオブジェクトのonRobotFocusLostメソッドがコールバックされます。
void onRobotFocusLost();

アクションの影響

ロボットフォーカスを喪失した場合、このActivityはロボットフォーカスを再獲得するまでPepperのアクションを実行できません。 
//ロボットフォーカスを喪失している場合、実行されません。
say.run();
また、アクションの実行中にonRobotFocusLostが呼ばれた場合、実行中のアクションは停止し例外がスローされます。 
//例外がスローされます。
say.run();
say.async().run().thenConsume(future -> {
    if (future.isSuccess()) {
//コールされません。
    } else if (future.hasError()) {
//コールされます。
    }
});
ロボットフォーカスなしでコールバックされるリスナーは、onRobotFocusLostメソッドで出来るだけ解除しておきましょう。
if (lookAt != null) {
    lookAt.removeAllOnPolicyChangedListeners();
}

ロボットサービスの影響 

ロボットサービスはロボットフォーカスの喪失に影響されず実行を継続します。
Future<List<Human>> humansAroundFuture = humanAwareness.async().getHumansAround();
humanAwareness.addOnHumansAroundChangedListener(listener);
ロボットフォーカスなしでコールバックされるリスナーは、onRobotFocusLostメソッドで出来るだけ解除しておきましょう。
if (humanAwareness != null) {
    humanAwareness.removeAllOnHumansAroundChangedListeners();
}
ロボットサービスに設定したリスナーを解除し忘れた場合には、アプリが終了するまで実行されることになります。

5. ロボットフォーカス拒否

ロボットフォーカス拒否について詳述します。 ロボットが不安定な時などは、Activityがフォアグラウンドに遷移したにもかかわらずロボットフォーカスが与えられない場合があります。その場合、このActivityと一緒に登録したRobotLifecycleCallbacksオブジェクトのonRobotFocusRefusedメソッドがコールバックされます。
void onRobotFocusRefused(String reason);
ロボットフォーカスが与えられなかった原因は、onRobotFocusRefusedメソッドの引数で通知されます。

6. 制約事項

制約事項についてです。 onRobotFocusGained、あるいはonRobotFocusRefusedのコールバックは保証されていません。onRobotFocusGainedやonRobotFocusRefusedを待ち続けることのないよう、必ずタイムアウトを実装しましょう。

7.UIスレッドでの処理

UIスレッドでの処理に関して説明します。 Robot lifecycleの各メソッドで画面更新を行いたい場合には、2つの方法があります。

Androidベースの解決策

ActivityクラスのrunOnUiThreadメソッドにRunnableオブジェクトを渡すと、UIスレッドでの処理の実行が可能になります。
@Override
public void onRobotFocusGained(QiContext qiContext) {

    Say say = SayBuilder.with(qiContext)
                        .withText("こんにちは")
                        .build();
   
    say.run();

    runOnUiThread(() -> textView.setText("完了"));
}

QiSDKベースの解決策

QiSDKクラスのonUiThreadメソッドにConsumerオブジェクトを渡すと、UIスレッドで処理を実行できるようになります。
@Override
public void onRobotFocusGained(QiContext qiContext) {

    Say say = SayBuilder.with(qiContext)
                        .withText("こんにちは")
                        .build();

    Future<void> sayFuture = say.async().run();

    sayFuture.andThenConsume(Qi.onUiThread((Consumer<void>) ignore -> {
            textView.setText("完了");
    }));
}

8.Activityライフサイクルとのリンク

Activityライフサイクルとロボットライフサイクルのリンクに関して説明します。
ロボットライフサイクルは完全にActivityライフサイクルとリンクしているわけではありません。しかしAとBの2つのActivityインスタンスがある時には、次のような条件でActivity Aがロボットフォーカスを喪失します。
  • フォアグラウンドのActivityがAからBに遷移したとき
  • アプリがバックグラウンドに遷移したとき
  • アプリが終了させられたとき
重要  Activityがバックグラウンドに遷移した場合は、必ずロボットフォーカスを失います。

コメント

このブログの人気の投稿

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が選択されてい