You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何终止Pepper机器人的Listen动作?现有实现遇问题求助

如何终止Pepper机器人的Listen动作并解决监听与说话冲突问题

我来帮你解决这个Pepper机器人Listen动作无法终止的问题——首先明确:Listen动作确实可以被终止,你的问题大概率出在Listen实例的引用管理或者异步代码的执行顺序上,咱们一步步来梳理:

问题根源分析

看你的代码,有两个关键问题导致requestCancellation()无效:

  1. Listen实例引用错误:你用ListenBuilder.buildAsync()创建Listen时,直接把返回的Future<Listen>赋值给了listen变量,但Future并不是实际运行的Listen实例,后续调用requestCancellation()自然不会作用到真正的监听动作上。
  2. 异步执行顺序问题:触控点击的回调里调用listen.requestCancellation()时,可能此时Listen还没被创建(比如问候动画还没跑完,Listen还没初始化),或者listen变量指向的不是当前正在运行的Listen实例,导致取消请求无效。

具体解决方案

1. 正确获取并保存Listen实例

修改语音处理部分的代码,确保listen变量指向实际创建的Listen对象,而不是Future:

animation_future.andThenConsume(chatting ->{
    // 先异步构建Listen实例,再获取到实际对象后保存
    ListenBuilder.with(qiContext).withPhraseSet(response).buildAsync()
        .andThenConsume(listenInstance -> {
            // 将实际的Listen实例保存到成员变量
            listen = listenInstance;
            // 异步启动监听,避免阻塞线程
            listen.runAsync().andThenConsume(heardPhrase -> {
                // 处理语音输入逻辑
                String userResponse = heardPhrase.getHeardPhrase().getText().toLowerCase();
                if(userResponse.equals("si")){
                    helpNeeded_chat.async().run();
                }else if(userResponse.equals("no")){
                    handleNoResponse();
                }
            });
        });
});

2. 安全调用终止方法

在触控点击的回调里,先检查Listen实例是否有效,再调用取消:

button_no.setOnClickListener(v->{
    // 先确认Listen实例存在且未完成
    if(listen != null && !listen.isDone()){
        boolean cancellationSuccess = listen.requestCancellation();
        Log.i(TAG, "Listen cancellation status: " + cancellationSuccess);
    }
    handleNoResponse();
});

3. 统一处理否定响应逻辑

把重复的“拒绝帮助”逻辑抽成单独方法,避免代码冗余:

private void handleNoResponse() {
    animation_future = goodbye_animation.async().run();
    animation_future.andThenConsume(restart->{
        Log.i(TAG, "Interaction ended. Restarting.");
        startActivity(new Intent(this, MainActivity.class));
    });
}

4. 更省心的备选方案:使用Chatbot组件

如果上述调整后还是有问题,或者你想简化代码结构,强烈建议使用Pepper内置的Chatbot功能——它已经封装了“提问-等待回答-处理响应”的完整流程,会自动管理监听和说话的状态,从根源上避免“无法在监听时说话”的冲突:

// 初始化Chatbot
Chatbot chatbot = ChatbotBuilder.with(qiContext)
    .withPhraseSet(response)
    .build();

// 设置响应监听
chatbot.addOnHeardPhraseListener(heardPhrase -> {
    String userResponse = heardPhrase.getText().toLowerCase();
    if(userResponse.equals("si")){
        helpNeeded_chat.async().run();
    }else if(userResponse.equals("no")){
        handleNoResponse();
    }
});

// 启动Chatbot
chatbot.runAsync();

总结

  • Listen动作完全可以通过requestCancellation()终止,核心是确保你引用的是正在运行的实际Listen实例。
  • 异步代码里一定要注意实例初始化的顺序,避免在Listen未创建时调用取消方法。
  • 如果你想避免手动管理状态的麻烦,Chatbot是更可靠的选择,它会自动处理监听与说话的状态切换。

内容的提问来源于stack exchange,提问作者R.Go

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 19:22:39