How to switch from NAOqi to qi Framework¶
Introduction¶
This guide will help you switch to qi Framework. It describes how to access the qi world from NAOqi and how to take advantage of qi.
qi Framework main features¶
The main new features of qi Framework are:
- Support for map, list, object and structure.
- Support for signal and property.
- It is no longer needed to be a module to subscribe to an event.
- Asynchronous call with result value.
Getting a Session from a proxy¶
This section explains how to get a qi.Session
from NAOqi.
This can be used in NAOqi script or in Choregraphe behaviors.
import naoqi
#imagine you have a NAOqi proxy on almemory
mem = naoqi.ALProxy("ALMemory", "127.0.0.1", 9559)
#get a qi session
ses = mem.session()
#then you can use the session like you want
Subscribe to a memory event¶
When using qi, you do not have to be a module to subscribe to a memory event, you just have to specify a callback.
Warning
You have to keep the SignalSubscriber returned by ALMemory.Subscriber to keep the callback being called.
def mycallback(value):
print "val:", value
mem = session.service("ALMemory")
sub = mem.subscriber("foo/bar")
sub.signal.connect(mycallback)
If you want to have the key in your callback you can use functools.partial.
import functools
def mycallback2(key, value):
print "key:", key
print "val:", value
mem = session.service("ALMemory")
sub = mem.subscriber("foo/bar")
sub.signal.connect(functools.partial(mycallback2, "foo/bar"))
PCall vs qi.async¶
qi modules do not support pCall but they do support a more generic asynchronous mechanism qi.async()
.
If you want your call to be asynchronous you can use qi.async()
which returns a qi.Future
.
This qi.Future
allows you to object the resulting value or error.
However some NAOqi modules really depend on pCall. Most notably tts.say and motion.moveTo. In this case, you can use the pCall method provided by ALModule. It will behave the same as the old way and return a pcallId, usable with the stop and the wait method of ALModule.
Warning
the pCall method is only available on ALModule, not on qi services. So it’s availability depends on the service you are calling.
Let’s see an example with pCall:
tts = session.service("ALTextToSpeech")
pCallId = tts.pCall("say", "I love rock'n'pCall")
tts.stop(pcallId) #oops that was not what I meant
#let's try again
pCallId = tts.pCall("say", "I love rock'n'roll")
Now let’s imagine you want to call a function and do something when the function finishes:
tts = session.service("ALTextToSpeech")
fut = qi.async(tts.say, "I Love rock'n'sync")
#do some work here
#either wait and get the value
print "value:", fut.value()
#or add a callback that will be called when the function returns
def mycb(fut):
print "value:", fut.value()
fut.addCallback(mycb)
#continue working while tts.say proceeds