如何结束监听操作

huangapple go评论66阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2020年8月9日 16:57:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/63324380.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定