今回のチュートリアルでは、PepperのAutonomous Abilityの停止と解除の方法について見ていきます。
Futureを使いますので、Futureについて知りたい人はPepper SDK入門(8) アクションの連結を参考にしてください。
###まずは新しいプロジェクトを作成する
AutonomousPepperという名前で新しいプロジェクトを作成します。
そして、QiSDKの設定とMainActivityを作成しロボットライフサイクルの実装を行ってください。
##1.Abilityを停止する
MainActivityのクラスに新しいholdAbilities
メソッドを実装します。
private void holdAbilities(QiContext qiContext) {
// AbilityのためのHolderをビルドして保存
Holder holder = HolderBuilder.with(qiContext)
.withAutonomousAbilities(
//呼吸を模した待機時間の動き
AutonomousAbilitiesType.BACKGROUND_MOVEMENT,
//周辺の物質や人の検知
AutonomousAbilitiesType.BASIC_AWARENESS,
//目のLEDの点滅
AutonomousAbilitiesType.AUTONOMOUS_BLINKING
)
.build();
// Abilityを非同期に停止
Future<Void> holdFuture = holder.async().hold();
}
Abilityを停止するにはHolderBuilderでHolderをビルドする必要があります。
Holderに停止したいAbilityのAutonomousAbilitiesType (Enum) を渡してください。
続いて、非同期でAbilityを停止するためにHolderのasync
メソッドとhold
メソッドを呼びます。
AutonomousAbilityを停止する方法を理解したところで、次はそれを解除できるようにする方法を見ていきましょう。
プログラミングでよく使う書き方をデザインパターンといいます。Builderというのはよく出てくるデザインパターンなので、ここで軽く勉強しておいてください。
##2.Abilityを解除する
ここでは、AutonomousAbilityの解除方法について見ていきます。
まずは新しくreleaseAbilities
メソッドを作成してください。
private void releaseAbilities(Holder holder) {
// Holderを非同期に解除
Future<Void> releaseFuture = holder.async().release();
}
AutonomousAbilityを非同期で解除するために、対応するHolderインスタンスのasync
メソッドとrelease
メソッドを呼びます。
続いて、機能の停止と解除をテストするための実装を行なっていきましょう。
##3.停止と解除の切り替えをテストする
Abilityの停止と解除を切り替えるためのボタンを作っていきます。
まずはレイアウトファイルのactivity_main.xmlに、下記を書き加えます。
<Button
android:id="@+id/button_switch_autonomous"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Hold"/>
続いて、MainActivityに以下のフィールドを作成します。
// button_switch_autonomousはAbilityの停止と解除の切り替えに使用
private Button buttonSwitchAutonomous;
// booleanはAbilityの状態を保存するのに使用
private boolean abilitiesHeld = false;
// AbilityのためのHolder
private Holder holder;
// QiSDKによるQiContext
private QiContext qiContext;
onRobotFocusGained
メソッドとonRobotFocusLost
メソッド用に以下のコードを書きます。
@Override
public void onRobotFocusGained(QiContext qiContext) {
// QiContextを保存
this.qiContext = qiContext;
}
@Override
public void onRobotFocusLost() {
// QiContextを外す
this.qiContext = null;
}
onCreate
メソッドのonClick listenerにbutton_switch_autonomousを設定します。
// ビューの中のbutton_switch_autonomousを検索
buttonSwitchAutonomous = (Button) findViewById(R.id.button_switch_autonomous);
//buttonSwitchAutonomousをonClick listenerに設定
buttonSwitchAutonomous.setOnClickListener(v -> {
// Activityのフォーカスをチェックする
if (qiContext != null) {
toggleAbilities();
}
});
toggleAbilities
メソッドを書き加えます。
private void toggleAbilities() {
// buttonSwitchAutonomousを利用できないようにする
buttonSwitchAutonomous.setEnabled(false);
if (abilitiesHeld) {
releaseAbilities(holder);
} else {
holdAbilities(qiContext);
}
}
holdAbilities
メソッドを次のように更新します。
// AbilityのHolderをビルドして保存
holder = HolderBuilder.with(qiContext)
.withAutonomousAbilities(
//呼吸を模した待機時間の動き
AutonomousAbilitiesType.BACKGROUND_MOVEMENT,
//周辺の物質や人の検知
AutonomousAbilitiesType.BASIC_AWARENESS,
//目のLEDの点滅
AutonomousAbilitiesType.AUTONOMOUS_BLINKING
)
.build();
// Abilityを非同期に停止
Future<Void> holdFuture = holder.async().hold();
// UIスレッド上のlambdaを停止
holdFuture.andThenConsume(Qi.onUiThread((Consumer<Void>) ignore -> {
//Abilityの状態を保存
abilitiesHeld = true;
//buttonSwitchAutonomousのテキストを変更
buttonSwitchAutonomous.setText("Release");
//buttonSwitchAutonomousを利用できるようにする
buttonSwitchAutonomous.setEnabled(true);
}));
releaseAbilities
メソッドのreleaseFutureにFutureで繋いで、ボタン制御の処理をJavaの省略式であるlambdaで記述します。
// UIスレッド上のlambdaを解除
releaseFuture.andThenConsume(Qi.onUiThread((Consumer<Void>) ignore -> {
// Abilityの状態を保存
abilitiesHeld = false;
// buttonSwitchAutonomousのテキストを変更
buttonSwitchAutonomous.setText("Hold");
// buttonSwitchAutonomousを利用できるようにする
buttonSwitchAutonomous.setEnabled(true);
}));
ConsumerオブジェクトにQi.onUiTreadを挟むと、consume
メソッドがUIスレッドでコールバックされ、button_switch_autonomousの制御がUIスレッドで行われるようになります。
###実践
このチュートリアルのソースはここから利用できます。
- アプリケーションをインストールして実行します。
- “Hold/release autonomous abilities”を選びます。
すると、Pepperはあなたの動きを視線で追いかけ始めるはずです。 - button_switch_autonomousをクリックすると、Pepperは停止します。
- 再度button_switch_autonomousをクリックすると、Pepperはまた動き始めます。