I'm struggling to understand how, and if it is possible, to end a listen action on Pepper after it is started. What i want to achieve in my application is the following:
This is the part of the code to handle voice input, and it works as expected:
public void onRobotFocusGained(QiContext qiContext) {
...
//Pepper greets the approached user
animation_future = greeting_animation.async().run();
//After the animation is finished, wait for human input
animation_future.andThenConsume(chatting ->{
listen = ListenBuilder.with(qiContext).withPhraseSet(response).buildAsync();
listen.andThenConsume(heardPhrase->{
//Pepper start listening
result = heardPhrase.run();
//If the response contains "yes"
if( (result.getHeardPhrase().getText().toLowerCase()).equals("si")){
//User need helps, Pepper start discussing with it
helpNeeded_chat.async().run();
//Otherwise
}else if( (result.getHeardPhrase().getText().toLowerCase()).equals("no")){
//No help is required, Pepper says goodbye
animation_future = goodbye_animation.async().run();
//A new user comes by - Restart scenario
animation_future.andThenConsume(restart->{
Log.i(TAG, "Interaction ended. Restarting.");
//Restart by starting this same activity
startActivity(new Intent(this, MainActivity.class));
});
}
});
});
}
While this is the part that handles touch inputs (defined in its own method outside onRobotFocusGained):
final Button button_no = findViewById(R.id.button_no);
button_no.setOnClickListener(v->{
...
listen.requestCancellation();
//Help is refused - Restart scenario
animation_future = goodbye_animation.async().run();
animation_future.andThenConsume(restart->{
Log.i(TAG, "Interaction ended. Restarting.");
//Restart by starting this same activity
startActivity(new Intent(this, MainActivity.class));
});
});
In this case since the Listen action keeps running then the warning Pepper can not speak while is listening is thrown thus preventing correct ending of the task. What I have found is that the only method that might allow to terminate actions is requestCancellation() but it doesn't seems to work in my case, the boolean method isCancelled() to check whether the action is terminated keeps returning always False.
It is actually possible to stop the Listen action or do I have to entirely change the way in which my code is structured (i.e. use a chatbot from the very beginning)?
When you are calling listen.requestCancellation()
, you are in fact cancelling the building of the listen action.
You defined listen
with:
listen = ListenBuilder.with(qiContext).withPhraseSet(response).buildAsync();
.
Instead, you should cancel the future returned when you run the action: result = heardPhrase.run();
.
Calling result.requestCancellation()
should do the trick for you.
The thumb rule is that Qi SDK actions are first built then run.