lugu / qiloop

An implementation of QiMessaging in Go
MIT License
9 stars 1 forks source link

replicate FrontTactilTouched python example #25

Closed ng2dev closed 4 years ago

ng2dev commented 4 years ago

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!

ng2dev commented 4 years ago

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 4 years ago

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

ng2dev commented 4 years ago

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

lugu commented 4 years ago

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