我正在尝试订阅信号,但我不知道它是如何完成的。
我看过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)
捕获的信号。
我的想法是让信号监听器始终有效。此信号侦听器在行为停止时作出反应,然后继续侦听其他行为。
答案 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)