Python SDK 入门(3)——对事件做出反应

​ 这一节,我想让 NAO 在每一次侦测到人脸的时候都说一句“你好,人类”。为了达到这一点,我们需要使用 ALFacedetection 模型下的”FaceDetected”事件。

​ 所以我们需要用 Python 写一个 NAOqi 模型出来。而要创建模型,我们首先需要一个中间件(Broker)。

​ 下面是一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# -*- encoding: UTF-8 -*-

"""每当侦测到人脸时都要说一声“你好,人类”"""

import sys
import time

from naoqi import ALProxy
from naoqi import ALBroker
from naoqi import ALModule

from optparse import OptionParser

pip = "nao.local"

# 用全局变量来存储"HumanGreeter"模型中的实例
HumanGreeter = None
memory = None

class HumanGreeterModule(ALModule):

def __init__(self, name):
ALmodule.__init__(self, name)
#在这里不需要IP和端口,
#因为我们可以在之后用自己写的中间件去连NAOqi中的中间件

#创建一个ALTextToSpeech稍后使用
self.tts = ALProxy("ALTextToSpeech")

#使用FaceDetected事件
global memory
memory = ALProxy("ALMemory")
memory.subscribeToEvent("FaceDetected",
"HumanGreeter", "onFaceDetected")

def onFaceDetected(self,*_args):
#这个方法将会在每次侦测到人脸的时候被调用

#当走路的时候不使用该事件
#以避免多次重复
memory.unsubscribeToEvent("FaceDetected", "HumanGreeter")

self.tts.setLanguage("Chinese")
self.tts.say("你好,人类")

#再次使用上面那个方法
memory.subscribeToEvent("FaceDetected",
"HumanGreeter", "onFaceDetected")

def main():
""" Main entry point

"""
parser = OptionParser()
parser.add_option("--pip",
help="Parent broker port. The IP address or your robot",
dest="pip")
parser.add_option("--pport",
help="Parent broker port. The port NAOqi is listening to",
dest="pport",
type="int")
parser.set_defaults(
pip=NAO_IP,
pport=9559)

(opts, args_) = parser.parse_args()
pip = opts.pip
pport = opts.pport


#我们需要用这个中间件来构建NAOqi模型并使用其他模型
#这个中间件必须在运行期间始终有效
myBroker = ALBroker("myBroker",
"0.0.0.0", # 监听所有的
0, # 找到一个空端口并使用它
pip, # 父类中间件IP
pport) # 父类中间件端口

#注意:HumanGreeter必须是全局变量
#传入结构体的名字必须是这个变量的名字
global HumanGreeter
HumanGreeter = HumanGreeterModule("HumanGreeter")

try:
while True:
time.sleep(1)
except KeyboardInterrupt:
print
print "Interrupted by user, shutting down"
myBroker.shutdown()
sys.exit(0)



if __name__ == "__main__":
main()

一些注意事项:

  • 要确保我们对实例使用的是全局变量
  • 要确保我们传入 ALModule 的结构体的名字是自己的变量的名字
  • 如果我们为此方法编写了文档字符串,且它不以下划线开头,则我们的类的方法会自动转换为绑定方法。(The method of your class are automatically transform into bound methods, providing that you wrote a doc string for this method, and it does not start with an underscore.)
  • 一旦建立了 ALBroker 对象,我们需要使这个对象一直有效,以使订阅(the subscribing)工作。 我们还需要中间件处于有效状态才能创建代理而不必指定 IP 或端口。
  • 脚本必须有—pip 和—pport 才能工作

补充内容: 让 Python 脚本在 NAO 上运行的方法:

​ 将脚本传到 NAO 上,如/home/nao/reacting_to_events.py,然后编辑/home/nao/naoqi/preferences 下的 autoload.ini 文件,加上:

1
2
[python]
/home/nao/reacting_to_events.py

请注意,在运行脚本时 NAOqi 会自动设置-pip 和-pport 值。

最后,运行这个脚本,然后把你的脸放在 NAO 的面前,你将会听到一声”你好,人类“。