英文:
How to end Listen action
问题
我正在努力理解如何以及是否可能在启动后结束Pepper上的听动作。我想在我的应用程序中实现以下目标:
- Pepper向用户提出问题,用户可以通过语音或平板上的触摸输入回答。
- 如果答案是否定的,Pepper将执行一个动画,同时回复一句话。
以下是处理语音输入的代码部分,它按预期工作:
public void onRobotFocusGained(QiContext qiContext) {
...
// Pepper向接近的用户问候
animation_future = greeting_animation.async().run();
// 动画完成后,等待人类输入
animation_future.andThenConsume(chatting -> {
listen = ListenBuilder.with(qiContext).withPhraseSet(response).buildAsync();
listen.andThenConsume(heardPhrase -> {
// Pepper开始倾听
result = heardPhrase.run();
// 如果响应包含“是”
if ((result.getHeardPhrase().getText().toLowerCase()).equals("si")) {
// 用户需要帮助,Pepper开始与之讨论
helpNeeded_chat.async().run();
} else if ((result.getHeardPhrase().getText().toLowerCase()).equals("no")) {
// 不需要帮助,Pepper道别
animation_future = goodbye_animation.async().run();
// 新用户经过 - 重新启动场景
animation_future.andThenConsume(restart -> {
Log.i(TAG, "交互结束。重新启动。");
// 通过启动相同的活动来重新启动
startActivity(new Intent(this, MainActivity.class));
});
}
});
});
}
而这是处理触摸输入的部分(在onRobotFocusGained之外的自己的方法中定义):
final Button button_no = findViewById(R.id.button_no);
button_no.setOnClickListener(v -> {
...
listen.requestCancellation();
// 拒绝帮助 - 重新启动场景
animation_future = goodbye_animation.async().run();
animation_future.andThenConsume(restart -> {
Log.i(TAG, "交互结束。重新启动。");
// 通过启动相同的活动来重新启动
startActivity(new Intent(this, MainActivity.class));
});
});
在这种情况下,由于Listen动作仍在运行,因此会引发警告"Pepper无法在听的同时说话",从而阻止了任务的正确结束。我发现唯一可能允许终止操作的方法是requestCancellation(),但在我的情况下似乎不起作用,用于检查操作是否已终止的布尔方法**isCancelled()**一直返回False。
是否真的可以停止Listen动作,还是我必须完全改变代码结构的方式(例如从一开始就使用聊天机器人)?
英文:
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:
- Pepper asks a question to the user, which in turn can answer either with voice or a touch input on the tablet.
- If the answer is negative, Pepper will have to execute an animation and at the same time reply with a phrase.
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)?
答案1
得分: 0
当您调用 listen.requestCancellation()
时,实际上是取消了 listen 动作的构建。
您使用以下方式定义了 listen
:
listen = ListenBuilder.with(qiContext).withPhraseSet(response).buildAsync();
。
相反,您应该取消在您 运行 该动作时返回的未来:result = heardPhrase.run();
。
调用 result.requestCancellation()
应该适用于您。
拇指规则是,Qi SDK 动作首先 构建 然后 运行。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论