0

我正在尝试订阅一个信号,但我不知道它是如何完成的。我已阅读http://doc.aldebaran.com/2-4/dev/libqi/api/python/signal.html但仍不完全理解。这是我试图等待这个信号ALBehaviorManager.behaviorStopped('some_behavior')然后调用一些回调的代码:

service = session.service("ALBehaviorManager")

signal = qi.Signal(service.behaviorStopped('by_behavior'))

signal.connect(my_callback)

但收到以下错误消息:

Traceback (most recent call last):
  File "C:/testing.py", line 24, in <module>
    signal = qi.Signal(service.behaviorStopped('by_behavior'))
Boost.Python.ArgumentError: Python argument types in
    Signal.__init__(Signal, NoneType)
did not match C++ signature:
    __init__(struct _object *, class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)
    __init__(struct _object *)

已编辑

service = session.service("ALBehaviorManager")

signal = qi.Signal()

signal(service.behaviorStopped('my_behavior'), my_callback())

当我运行它时,它不会等待信号,它只是调用my_callback

编辑第 2 号

import qi
import sys


def on_behavior_stopped_callback(behavior_id):
    if behavior_id == "test_video_player-fdb9c9/behavior_1":
        print "Yeah"
    else:
        print "Noooooo"

if __name__ == '__main__':
    ip = "11.1.11.111"
    port = 9559

    session = qi.Session()
    try:
        session.connect("tcp://" + ip + ":" + str(port))
    except RuntimeError:
        print ("Can't connect to Naoqi at ip \"" + ip + "\" on port " + str(port))
        sys.exit(1)

    behavior_manager_service = session.service("ALBehaviorManager")

    behavior_stopped_signal = behavior_manager_service.behaviorStopped

    behavior_stopped_connection = behavior_stopped_signal.connect(on_behavior_stopped_callback)

根据您在运行此 python 脚本时的响应 (@JLS),它什么也不做。当前在"test_video_player-fdb9c9/behavior_1"正在运行的机器人上。我认为python脚本不会立即完成,但它会等待接收来自“behaviorStopped”类型的信号,并在收到信号时进行检查if behavior_id == "test_video_player-fdb9c9/behavior_1",而不是根据条件执行它应该做的事情。

编辑第 3 号

让我们有这种情况:我有一个名为“listener”的行为,其唯一目的是在任何时候停止其他行为以记录停止行为的名称。一种方法是制作一个事件,将信息发送给这个“听众”。好的。一切正常,但是当内置行为停止时该怎么办,例如“dialog_runner_dev”。我想如果任何时候行为停止,它就会发出一个可以被 this 捕获的信号ALBehaviorManager::behaviorStopped(std::string behaviorName)

我的想法是制作一个始终有效的信号监听器。此信号侦听器在行为停止时做出反应,然后继续侦听其他行为。

4

1 回答 1

2

使用 qi.Signal()创建一个信号。我猜你想在这里订阅一个现有的信号,然后它会调用一个你连接到它的回调函数:

behavior_manager_service = session.service("ALBehaviorManager")
behavior_stopped_signal = behavior_manager_service.behaviorStopped
behavior_stopped_connection = behavior_stopped_signal.connect(on_behavior_stopped_callback)

在某处定义的回调函数:

def on_behavior_stopped_callback(behavior_id):
    if behavior_id == "some_app_uuid/some_behavior":
        do_something()

最后:

behavior_stopped_signal.disconnect(behavior_stopped_connection)

附录:

如果您需要阻塞并等待信号发生,一个技巧是使用您可以等待的线程安全变量,例如从回调分配的承诺。qi.Promise只能设置一次,因此如果您需要多次设置,请改用队列

1:在您主要和回调可以访问的地方定义变量:

pAnswer = qi.Promise()
fAnswer = pAnswer.future()

2:您希望脚本阻止的地方,使用

answer = fAnswer.value()

3:在回调函数中,设置值:

pAnswer.setValue(ans)
于 2017-09-05T15:45:29.460 回答