lugu/qiloop

replicate FrontTactilTouched python example

ng2dev opened this issue · 4 comments

I am trying to implement this example of a memory service subscription and a callback function
like referenced in this python example.

import qi

app = qi.Application()
session = qi.Session() 
session.connect("tcp://nao.local:9559") 
memory = session.service("ALMemory")
tts = session.service("ALTextToSpeech")

def on_touched(event):
    # value is 1 when pressed, 0 when released
    if event > 0:
        tts.say("ouch")

subscriber = memory.subscriber("FrontTactilTouched")
subscriber.signal.connect(on_touched)

app.run()

I am trying to understand how to subscribe to that memory service signal through examples/signals/main.go where you subscribe to a serviceAdded callback channel that seems similar to the related functions inside the ALMemoryInterface

interface ALMemory
     	fn subscriber(eventName: str) -> obj
        fn subscribeToEvent(name: str,callbackModule: str,callbackMethod: str)
        fn unsubscribeToEvent(name: str,callbackModule: str)
 end

What I don't understand is that the services.idl file does not contain the subscribe methods for the serviceAdded example - so how is that subscribeServiceAdded method being generated inside bus/services/gen_proxy.go - so that I could run something similar to this:

// Obtain a proxy to the service
alm, err = proxies.ALMemory(nil)
if err != nil {
	panic(err)
}

var unsubscribe func()
var sig chan int 
// subscribe to the signal "FrontTactilTouched" of AlMemory service.
unsubscribe, sig, err = alm.Subscribe("FrontTactilTouched")

Thanks for your help!

I did understand by now that the sig key word generates the subscriber methods - unfortunately that sig method does not exist in the ALMemory interface.

lugu commented

Thanks, this is an excellent question! Looking at the documentation, it seems the subscriber method return an object but qiloop scan did not generate the IDL for this object (since it is not a service and qiloop scan only look at services).

We need to scan this object to get a description of it and then update the IDL description of ALMemory (just like LogManager which returns a log listener).

Here is a blind fix (sorry i don't have time right now). It seems this object have a signal called "signal" which is of type a Value type.

interface Subscriber
   sig signal(data: any)
end

interface ALMemory
    [...]
    fn subscriber(eventName: str) -> Subscriber
    [...]
end

I hope this makes sense. i will come back to you when i can.
http://doc.aldebaran.com/2-5/naoqi/core/almemory-api.html#ALMemoryProxy::subscriber__ssCR

Ha you are right that was the trick - I added a working example to the PR.

lugu commented

Thanks a lot, I love the "ouch" example !