C´omo hacer m´odulos y librer´ıas para ejecutarse a bordo del NAO Mauricio Josafat Garc´ıa V´azquez Abril 2011 ´Indice general 1. Como hacer m´ odulos y librer´ıas para ejecutarse a bordo NAO 1.1. T´erminos importantes . . . . . . . . . . . . . . . . . . . . 1.2. Arquitectura del NAO . . . . . . . . . . . . . . . . . . . . 1.2.1. Broker . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.2. Proxy . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.3. M´odulos locales o remotos . . . . . . . . . . . . . . 1.3. Generador de m´odulos . . . . . . . . . . . . . . . . . . . . 1.4. Compilaci´on cruzada . . . . . . . . . . . . . . . . . . . . . 1.5. Compilar una librer´ıa externa . . . . . . . . . . . . . . . . 1 del . . . . . . . . . . . . . . . . 2 2 3 3 4 5 6 7 8 Cap´ıtulo 1 Como hacer m´ odulos y librer´ıas para ejecutarse a bordo del NAO 1.1. T´ erminos importantes M´ odulo: es una unidad de c´odigo, implementada como clase C++, que contiene c´odigo que sirve a realizar alguna funcionalidad. Como esta clase tiene que tener ciertos m´etodos necesariamente implementados, existe un generador de m´odulos que genera autom´aticamente un esqueleto de un modulo. Librer´ıa: est´a compuesta por trozos de c´odigo que contienen alguna funcionalidad pre-compilada. Las librer´ıas proporcionan servicios a programas independientes (ejecutables), esto permite que el c´odigo se pueda construir de manera modular. Los ejecutables y las librer´ıas hacen referencia entre si a trav´es de un enlace (link). Ejecutable: es un archivo binario que es interpretado por la computadora. Contiene instrucciones en lenguaje de m´aquina y se puede enlazar con librer´ıas para a˜ nadir funcionalidades. Naoqi: es el nombre del programa-servidor que corre en el robot y al cual un programa-cliente se puede conectar para recuperar datos, o hacer una pedida. 2 1.2. Arquitectura del NAO La arquitectura de Naoqi se puede observar en la figura 1.1. Es una arquitectura modular, con las varias funcionalidades encapsuladas en diferentes unidades de c´odigo. Figura 1.1: Arquitectura de naoqi. (Imagen extra´ıda de la documentaci´on de naoqi.) 1.2.1. Broker Un broker es un ejecutable y un servidor que puede atender comandos remotos en un IP (el de la m´aquina en que est´a corriendo) y un puerto, es decir por red. En pr´actica, para implementar una funcionalidad en el robot, tienes que pasar por un broker. Dos casos son posibles: o el generador de m´odulos generar´a un ejecutable y este se conectar´a al robot (en este caso, este ejecutable es un broker secundario), o generar´a una librer´ıa para cargarla en el broker principal, es decir el programa Naoqi, que es el que provee las funcionalidades b´asicas en el robot (adquisici´on de datos por sensores, actuaci´on. . . ). En este ultimo caso, se tiene que agregar en autoload.ini (del robot) el nombre de tu librer´ıa. El generador de m´odulos tambi´en maneja los enlaces y los caminos a las librer´ıas. Hay que entender bien las implicaciones de cada una de esas dos elecciones en cuanto a tu m´odulo: en el primer caso, tu m´odulo est´a encapsulado en 3 un ejecutable diferente del ejecutable que corre las operaciones cr´ıticas en el robot. Eso significa que en caso de que haya un gran error en tu c´odigo, tu ejecutable podr´a fallar sin que los sistemas de control cr´ıticos del robot fallen tambi´en. En el segundo caso, tu c´odigo compilado est´a usado por el mism´ısimo ejecutable Naoqi : en caso de problemas graves (error de segmentaci´on), el robot puede caer. Sin embargo, en el segundo caso, ya que tu c´odigo est´a en el mismo ejecutable que los m´odulos-core del robot, puedes acceder mucho m´as r´apido a datos del robot (por ejemplo, la imagen de la c´amara), ya que la memoria es compartida entre m´odulos del mismo ejecutable. En resumen, para tu m´odulo, tienes siempre dos opciones: correrlo en un broker separado (modo “remote”): seguro pero un poco menos eficiente; correrlo en el broker principal (modo “local”): arriesgado pero muy eficiente. En la figura 1.2 se ilustra un simple ejemplo de un m´odulo creado por el usuario, llamado “myModule”. myModule corre como un broker separado (modo “remote”) llamado “myBroker”que se comunica con el broker principal sobre 127.0.0.1:9559. Observaci´ on: Un punto importante que observar es que, en este caso particular, “Main Broker” y sus m´odulos est´an corriendo a bordo del robot, igualmente a “myBroker”(ya que la IP especificada corresponde a la maquina hu´esped). Pero, hubi´eramos podido muy bien correr el “myBroker” en una m´aquina remota, especificando a este programa una IP correspondiendo a la direcci´on del robot en la red. El desempe˜ no es en este caso limitado por las propiedades de la red, pero permite por ejemplo correr procesamientos tal vez m´as pesados, en tu m´aquina local m´as poderosa que la CPU del robot. 1.2.2. Proxy Debido a que la arquitectura software del NAO es modular, un m´odulo no necesariamente “conoce” el c´odigo de otro m´odulo. En particular, nunca incluimos (#include) una cabecera de otro m´odulo. En vez de esto, creamos un objeto especial, enteramente dedicado a la comunicaci´on con otros modulos, el proxy. Es lo mismo cuando el m´odulo se ejecuta de manera local o de manera remota. Veremos ejemplos de ellos al momento de implementar un primer m´odulo. 4 Figura 1.2: Broker. (Imagen extra´ıda de la documentaci´on de Naoqi). 1.2.3. M´ odulos locales o remotos Los m´odulos, como es mencionado arriba, son clases que est´an compiladas como librer´ıas. Para especificar que esta librer´ıa tiene que estar cargada en el sistema, se la tiene que mencionar explicitamente en el archivo de configuraci´on autoload.ini, con el cual se instanciar´a automaticamente el m´odulo de la clase principal. El generador de m´odulos crea una clase que ser´a comprendida por el broker, ya sea el broker principal, o un broker creado por el usuario si es separado/remoto. Como hay dos tipos de m´odulos, hay tambi´en dos maneras de compilar un m´odulo: Como un ejecutable (m´odulo remoto): Cada paquete de m´odulo crea un ejecutable independiente en “/path/to/aldebaran-sdk/bin/”. Como una librer´ıa (m´odulo local): Cada paquete de m´odulo crea una librer´ıa din´amica guardada en “/path/to/aldebaran-sdk/lib/naoqi/”. 5 Observaci´ on: En el secundo caso, para hacer que el broker principal cargue tus m´odulos al iniciar, el archivo autoload.ini tiene que tener el nombre de tu proyecto. Observaci´ on: Puedes escoger si tu m´odulo va a ser remoto o local configurando la variable de CMake llamada MY_MODULE_IS_REMOTE usando ccmake. 1.3. Generador de m´ odulos El generador de m´odulos es una aplicaci´on incluida en el sdk, y escrita en python. Para ejecutar el generador de m´odulos tenemos que hacer lo siguiente (en Linux, pero se har´ıa de manera equivalente en otros OS): $∼cd /path/to/aldebaran-cpp-sdk/modules/src/ $∼python module generator.py Figura 1.3: Generador de m´odulos En Project Name ponemos el nombre del proyecto, este va a ser el nombre de la librer´ıa que va a contener tus m´odulos, una sola librer´ıa puede contener varios m´odulos. En Modules Names ponemos el nombre de los m´odulos que queremos generar, separados por un espacio en blanco. El Author es opcional. Damos click en generar y nos aparece lo siguiente: Your project has been generated in /path/to/generator/ El generador de m´odulos nos crea un directorio donde se encuentra todo el c´odigo generado para nuestro proyecto. En la ra´ız hay dos archivos .cmake, que solo vamos a modificar en caso de que queramos cambiar los par´ametros 6 de compilaci´on. En src/ nos genera un archivo .cpp y un .h por cada m´odulo que hayamos querido generar, adem´as de un archivo .cpp con el nombre del proyecto. En ese ultimo est´a la funci´on main del ejecutable generado, si es el caso. En cada archivo .h se define una clase heredada de ALModule, con su constructor por default. A partir de este esqueleto, nosotros ya podemos seguir el c´odigo y definir las variables miembro y los m´etodos que va a tener nuestro m´odulo. Para poder usar funciones de nuestro m´odulo mediante un proxy (usarlas en otro m´odulo o directamente), tenemos que “enlazarlas” mediante la macro BIND METHOD. Para que esta macro funcione correctamente tenemos que llamar antes las funciones functionName, en caso que la funci´on tenga par´ametros la funci´on addParam por cada uno y por u ´ltimo la funci´on setReturn en caso de que tenga valor de retorno (ver ejemplo). Por u ´ltimo en el directorio tests/ genera un archivo .py (un script python) para lanzar m´etodos de nuestros m´odulos. Esto tambi´en lo podemos hacer de manera an´aloga con un programa en C++. 1.4. Compilaci´ on cruzada Para poder correr tu c´odigo a bordo del NAO y no en tu m´aquina, tienes que hacer una compilaci´on cruzada. Esto por el momento s´olo es posible en linux. La compilaci´on cruzada es necesaria para asegurar que se compila con las banderas correctas de optimizaci´on y ligas a las correctas librer´ıas. Para hacer una compilaci´on cruzada simplemente hacemos el proceso siguiente: $∼cd /path/to/sources $∼mkdir buildcross $∼cd buildcross $∼cmake -DCMAKE TOOLCHAIN FILE=/path/to/ctc/toolchain-geode.cmake .. $∼make Antes de hacer la compilaci´on cruzada tenemos que definir lo siguiente: SDK: El SDK es un directorio com´ un para todos nuestros proyectos. Por ejemplo, las librer´ıas est´an siempre en lib/, los archivos de cabecera en include/, los datos en share/ etc. El archivo toolchain.cmake: Para poder usar c´odigo desde lib/cmake, tenemos que usar el archivo toolchain.cmake. Esta es la forma de cmake para hacer compilaci´on cruzada. Para especificar un archivo tool7 chain.cmake a usar, se tiene que pasar la siguiente bandera en la l´ınea de comandos: cmake -DCMAKE TOOLCHAIN FILE==path/to/sdk/toolchain.cmake As´ı es como est´a definido el archivo toolchain.cmake: #DO NOT EDIT #DO NOT CHANGE LOCATION, THIS FILE ONLY WORKS IN THE ROOT #OF A FULL SDK cmake_minimum_required(VERSION 2.6.4) get_filename_component(_ROOT_DIR ${CMAKE_CURRENT_LIST_FILE} PATH) set(TOOLCHAIN_DIR ’${_ROOT_DIR}/lib/’ CACHE STRING ’’ FORCE) set(SDK_DIRS ’${_ROOT_DIR}’) set(SDK_ARCH linux) include(’${TOOLCHAIN_DIR}/cmake/Toolchain-generic.cmake’) # This is a bit unusual: result of the compilation will always # be put in this directory set(SDK_DIR ’${_ROOT_DIR}’ ) Las principales variables son: • TOOLCHAIN DIR: Para encontrar el c´odigo en lib/cmake. • SDK ARCH: Para especificar si estas usando linux, windows, compilaci´on cruzada, los valores aceptados son: linux,macosx,win-vc8, win-vc9, nao-geode. Para nuestro caso en particular debe ser naogeode. • SDK DIRS: Una lista de posibles directorios SDK donde se buscar´an archivos de cabecera y librer´ıas creadas por el usuario. • SDK DIR: (opcional) Es donde se pondr´a el resultado de la compilaci´on. El default es build/sdk. 1.5. Compilar una librer´ıa externa Para compilar una librer´ıa externa hacemos nuestra librer´ıa tal como el generador de m´odulos lo hace: 8 $∼mkdir librer´ıa $∼cd librer´ıa $∼mkdir src $∼nano bootstrap.cmake $∼nano CMakeLists.txt En src/ colocamos los archivos fuente (.h y .cpp) de manera similar a como el generador de m´odulos lo hace. El archivo bootstrap.cmake podemos copiarlo tal cual de cualquier m´odulo generado. El archivo CMakeLists.txt lo adaptamos del ejemplo siguiente1 : ### # This is a dummy package project. # Always put this: this won’t work if version # is less than 2.6.4 cmake_minimum_required(VERSION 2.6.4 FATAL_ERROR) # Name of your project: (use for the .snl filename among other things) project(packaging) # Always include() this: this performs a few checks, and makes # sure everything will work. # The bootstrap.cmake file should be at the top of your project. # it’s always the same. include(’${CMAKE_CURRENT_SOURCE_DIR}/bootstrap.cmake’) # Create a library: # first arg: the name of a CMake _target_. # following args: list of sources, or keywords such as SHARED, STATIC ... create_lib(world ’src/world.cpp’) # Make the lib available for other projects: # first arg: the name of the CMake target # second arg: the name of the ’staged’ library stage_lib(world WORLD) # to use in an other project: # use_lib(my_target WORLD) # Create a binary using world library: 1 Del foro de academics.aldebaran-robotics.com 9 create_bin(hello ’src/main.cpp’) use_lib(hello WORLD) # Install rules for headers: # WORLD is the name of the ’staged’ library, so that # that you can also use the lib for compilation in # an other project _after_ installation. install_header(WORLD ’src/world.h’ SUBFOLDER ’world’) # This is how you can install data files install_data(hello ’data/hello.dat’) Posteriormente hacemos el procedimiento ya mencionado para compilar. Para poder usar esta librer´ıa, no basta con poner use lib en el archivo CMakeLists.txt de nuestros m´odulos donde la queremos usar; tenemos que incluir el directorio sdk creado dentro de buildcross/ en nuestra librer´ıa en el archivo toolchain.cmake de la siguiente manera: en la parte #it’s possible to add more sdk here set(SDK_DIRS "${OE_CROSS_DIR}/staging/geode-linux/usr/") debemos agregar: set(SDK_DIRS "/path/to/the/library/buildcross/sdk") Esto lo hacemos por cada librer´ıa que queramos cargar en nuestros m´odulos, por u ´ltimo compilamos la librer´ıa. 10
© Copyright 2024