简体   繁体   中英

How to subscribe to event in Naoqi using Python and ROS?

How can I subscribe to an event using ALMemory 's subscribeToEvent function, which requires the correct Python scope while using ROS (rospy) that initiates modules outside my code?

This question is similar to this Naoqi subscription question , but differs in the sense that rospy was not used, which is critical to the implementation.

My current code is as such;
mainBehaviour.py

from nao.nao import Nao


class mainBehaviour(AbstractBehaviour):
    def init(self):
        global mainBehaviourMethod
        mainBehaviourMethod = self
        self.nao.setCallOnFall("mainBehaviourMethod", "robotHasFallen")

    def update(self):
        print("Update")

    def robotHasFallen(self, eventName, val, subscriberIdentifier):
        print("FALLING")

nao.py

from naoqi import ALProxy, ALModule, ALBroker
import rospy
from math import radians
import weakref
class Nao(object):

    def __init__(self):
        self.nao_ip = rospy.get_param("nao_ip")
        self.port = 9559
        self.memory_proxy = ALProxy("ALMemory", self.nao_ip, self.port)

    def setCallOnFall(self, module, method):
        self.memory_proxy.subscribeToEvent("robotHasFallen", module, method)

What I want is that mainBehaviour.py, using nao.py, has its function robotHasFallen fire when the robot has fallen. However, the current code does not produce this behaviour (it ignores any fall), but does not produce an error either. I attempted to implement this using this ALMemory tutorial . However, this tutorial makes use of a single python file, in which methods aren't instantiated by ROS. Therefore I cannot make use of the line pythonModule = myModule("pythonModule") . I attempted to still obtain this Python scope (on which the answer to the previously linked question states "the python variable must have the same name than the module name you create"), by declaring a global variable pointing to self .

How can I create the desired behaviour, detecting a fallen robot using subscribeToEvent , using ROS with its consequences of not initiating modules myself and therefore not being able to pass its constructor?
I cannot install any further libraries because I use a university computer.

Your example code uses the "naoqi" library, but it's now more convenient to use the "qi" library (you can get it with "pip install qi", it's already present on your robot in versions 2.1 or above). In that version you can directly pass a callback, see here for a helper library that allows you to do events.connect("MyALMemoryKey", my_callback) (you pass the function and not just it's name - and it doesn't care where the function comes from).

Under the hood, it does this:

ALMemory.subscriber("MyALMemoryKey").signal.connect(my_callback)

(note that here ALMemory is a Service (qi framework) and not a module (naoqi framework).

You can directly use that helper lib (see the doc here , and some samples using it here ), or use the same logic in your code (it's not very complicated, once you have a working example to start from).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM