如何订阅信号

时间:2017-08-30 11:46:32

标签: python nao-robot pepper

我正在尝试订阅信号,但我不知道它是如何完成的。 我看过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 *)

EDITED

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)

基于你的响应(@JLS),当我运行这个python脚本时,它什么也没做。目前在机器人上"test_video_player-fdb9c9/behavior_1"正在运行。我认为python脚本不会立即完成,但它会等待来自类型&#34; behaviorStopped&#34;的信号。被收到以及何时收到以检查if behavior_id == "test_video_player-fdb9c9/behavior_1"而不是根据情况做它应该做的事情。

编辑第3号

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

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

1 个答案:

答案 0 :(得分: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只能设置一次,因此如果您需要多次设置,请改用Queue

1:将变量定义在主要和回调可以访问的位置:

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

2:您希望脚本阻止的位置,请使用

answer = fAnswer.value()

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

pAnswer.setValue(ans)