Python and language choice
Once you are clear about your behavior objectives and specifications, you'll need to choose your development language. Python is easier but slower. C++ is harder but faster. Python allows easy dynamic object creation whereas C++ requires a compilation pass. Python architecture is in twofold.
Python bridge
Python bridge is an embedded Python interpreter. This module will interpret script from Choregraphe or any other module.
Method | Description |
---|---|
std::string eval ( std::string pToEval ) | Evaluate a string in Python interpreter |
// C++ sample #include "alpythonbridgeproxy.h" // all module created with module generator can include this ALPythonBridgeProxy proxy(getParentBroker()); proxy.eval("print 'hello_in_python_interpreter'")
Ways to execute Python script
There is three ways to execute Python script:
- Locally in the embedded python interpreter:
- Ask to python interpreter to eval script
#include "alpythonbridgeproxy.h"
ALPtr<ALPythonBridgeProxy> proxy = ALPtr<ALPythonBridgeProxy>(new ALPythonBridgeProxy); // in initialization
proxy->eval(std::string(myScript));
- Load it locally at NAOqi startup:
Add python script in $AL_DIR/modules/lib/autoload.ini
[python]
myPythonModule.py
- Execute it manually and remotely from robot or desktop:
python.exe myPythonScript.py
- Execute it automatically and remotely from robot:
Add python script in $AL_DIR/modules/lib/autoload.ini
[remote]
myPythonScript.py
Python script will listen on address 0.0.0.0 (all available addresses) and connect to NAOqi on 127.0.0.1.
Python wrapper
broker python API (extern\python\aldebaran\naoqi.py):
Method | Description |
---|---|
ALBroker(string name, string IP,int port, string parentIP, int parentPort) | create a python broker |
module python API (extern\python\aldebaran\naoqi.py):
Method | Description |
---|---|
ALModule(string name) | create a python module |
exit() | delete module |
BIND_PYTHON(string ModuleName, string methodName) | Add function in API |
string getName() | get module name |
dataChanged(string pDataName, param, string message) | dataChanged method called if subscribe data changes |
proxy python API (extern\python\aldebaran\naoqi.py)
Method | Description |
---|---|
ALProxy(string module) | "Connect" to module (no effect with local module) |
methodName(param) | methodName is any of module API function call methodName |
post.methodName(param) | methodName is any of module API function call methodName in another thread |
The Python wrapper allows to make parallel, sequential, event based calls on any C++ module.
#python sample #in the sample we run it from external python interpreter #but we can also only evaluate it with python bridge import os import sys import time import naoqi from naoqi import ALBroker from naoqi import ALModule from naoqi import ALProxy # call C++ method try: memProxy = ALProxy("ALMemory","127.0.0.1",9559) memProxy.insertData("MyVariable","myVariableValue",0) except RuntimeError,e: print "error insert data" exit(1)
Using an external Python interpreter instead of pythonBridge is faster to develop but slower than local pythonBridge interpreter.
C++ functions can be called in python if they respect the wrapper formalism:
- Generate C++ modules with the module generator (see the SDK section for more details)
- Bind method with BIND_METHOD module function (add it to API)
- Load module in a broker (for example in autoload.ini)
Creating a Python module
Creating a module in Python allows the module to subscribe on ALMemory data and define callback when data change.
""" with sample of python documentation """ import os import sys import time import naoqi from naoqi import ALBroker from naoqi import ALModule from naoqi import ALProxy # create python module # Python documentation will apear on web browser documentation class myModule(ALModule): """python class myModule test auto documentation""" def pythondatachanged(self, strVarName, value, strMessage): """callback when data change""" print value broker = ALBroker("pythonBroker","127.0.0.1",9999,"127.0.0.1",9559) # call method try: pythonModule = myModule("pythonModule") # don't forget to have the same module name and instance name proxy = ALProxy("ALMemory") prox.raiseMicroEvent("val",0) prox.subscribeToMicroEvent("val","pythonModule", "", "pythondatachanged") prox.raiseMicroEvent("val",1) except Exception,e: print "error behavior" print e exit(1) # add a loop here or program will exit before callback