Difference between revisions of "Nao tutorial 2: First module"

From robotica.unileon.es
Jump to: navigation, search
(Página nueva: Nao humanoid robot. The purpose of this tutorial is to teach you the basic concepts of [http://www.aldebaran-robotics.com/en Nao]. I assum...)
 
m
 
(52 intermediate revisions by the same user not shown)
Line 1: Line 1:
[[Image:Nao_whitebg.jpg|thumb|right|200px|Nao humanoid robot.]]
+
Go to root: [[TFM-Nao-Goalkeeper]]
  
The purpose of this tutorial is to teach you the basic concepts of [http://www.aldebaran-robotics.com/en Nao]. I assume that you are staring at the robot's box after (hopefully) buying it, and that you want to start making cool things with it, like conquering the world. You are wondering how to do that, but you don't even know how to plug the robot.
+
----
 +
----
  
I will take you, step by step, through the first tasks that you should complete before going serious. Even if I will try to make it easy, certain previous knowledge is required, like basic programming and Linux concepts. Also, I would recommend you to read the official documentation and tutorials found [http://users.aldebaran-robotics.com/ here] (section <span style="color:#228B22">"Software"</span>) before going forth. In case of doubt, always trust them.
 
  
<span style="color:#606060">'''''NOTE: This tutorial is targeted for version 1.10.10 of the SDK and OS. Older versions like 1.8.16 or 1.6.13 are not likely to work.'''''</span>
+
The [[Nao tutorial 1: First steps | first tutorial]] focused about giving you a painless introduction to Nao's world. You turned the robot on, connected to him through the web interface and SSH, configured some parameters and learnt a bit about the most important files and directories.
  
=Preparing the environment=
+
Now, it is time for you to delve deeper into the subject, and the best way is to code and test your own example module. Nao has some good default applications that allow you to control his behaviour (like Choregraphe), but this is nothing compared with the freedom that compiling your own applications gives to you. Hence, you will now practice with the [https://community.aldebaran.com/en/resources/software official SDK].
  
OK, the first thing you should do is to get a testing environment ready. By "testing environment" I mean:
+
<span style="color:#606060">'''''NOTE: This 2011 tutorial was targeted for version 1.10.10 of the SDK and OS. Newer versions have changed a lot of things, making most of these tutorials deprecated.'''''</span>
  
* A room with enough space.
+
==Getting everything ready==
* A computer running Linux (Debian or Ubuntu preferably).
 
* A simple LAN with a router.
 
  
<span style="color:#FF0000">'''''WARNING: Be aware that Nao is very prone to fall should you do something wrong. Don't be afraid, but keep it in mind.'''''</span>
+
I guess that your testing environment is the same as in the previous tutorial, only with your Nao connecting via wifi now. Also, you will need to download some software from Aldebaran's webpage, but if you are reading this wiki, it's because you are connected to the internet (duh!). Remember to turn your robot off if it isn't already.
  
Let's begin. Place Nao somewhere in the middle of the room, so he has freedom of movement. Try to keep it apart from places or objects that could make him fall or get jammed. Also, note that you will eventually need to plug it to the power (whenever you need to recharge his battery), and to the LAN (in case he is not able to connect wirelessly). The power connector is on Nao's back, facing downwards. In fact, you will be plugging it directly to the battery, which is behind the cover (it has 4 screws that you must remove in order to access it).
+
===Official SDK===
  
Finally, the Ethernet socket is located behind the head. You may need to open the protective hatch, or completely remove the head's cover, whichever one you prefer.
+
The guys from Aldebaran Robotics have an official SDK (Software Development Kit) available for registered users, on their [https://community.aldebaran-robotics.com/ webpage]. Navigate to this link, enter your login info (you have it, right?), then click the <span style="color:#228B22">"Software"</span> and <span style="color:#228B22">"Download"</span> links.
  
=Connecting to Nao=
 
  
When everything is set, press Nao's chest button once to turn it on. His eyes will start blinking red, green and blue. Then, some other blue LEDs located on his ears will do the same, and the eyes will stop blinking. Later, both the eyes and chest button will come alive again with a stable white light, and the robot will tell you that it has finished loading his system. The whole process lasts about two minutes and you will get soon tired of it, I promise.
+
[[Image:Aldebaran_downloads_website.jpg|thumb|center|700px|Aldebaran's software download website.]]
  
Now, you must connect to Nao to do some first-time configuration. It pays to have a simple router-based LAN with DHCP dynamic addressing, otherwise you will complicate your life, trust me.
 
  
==Recovering the IP address==
+
You must download the last version of the Linux SDK (1.10.10 currently). After clicking on it, you have to scroll down the user license agreement, <span style="color:#228B22">"I agree"</span>, and <span style="color:#228B22">"Click here to proceed"</span>. Wait for the 162 MB file to download (it's called <span style="color:#1E90FF">''naoqi-sdk-1.10.10-linux.tar.gz''</span>). Extract its contents, and it will spawn a directory named <span style="color:#FF8C00">''naoqi-sdk-1.10.10-linux/''</span>. Move it to the location you like most.
  
We need to get the IP address Nao has bonded to, before trying to connect to him. There are a couple of ways to do it, some easier than others, and I will enumerate them all:
+
===Dependencies===
  
===Using the router===
+
A couple of Linux packages are needed to create and build your own applications. Luckily, this can be as easy as entering the following command in a terminal (Debian or Ubuntu only, folks):
  
This is the hard way. Most routers offer an option to list the clients that are connected to it, through the web interface. But you need the router's IP. Input the following command in your PC (obviously, you must be in the same LAN as Nao):
+
<syntaxhighlight lang=Bash>sudo apt-get install build-essential cmake python-all python-tk libboost-all-dev libmpfr-dev cmake-curses-gui</syntaxhighlight>
  
<pre>sudo ifconfig</pre>
+
==Helloworld example in Naoqi==
  
Seek your network adapter in the list (usually eth0 for the first Ethernet card, eth1 for the second...) and look for your IP address (mine is 192.168.1.101). Your router's IP will be probably the same, only changing the last number for 1 or 0 (e.g., 192.168.1.1). Open a web browser and input that IP in the address bar. Press Enter and you will be prompted for the router's username and password. You should know them, but if that's not the case go [http://www.routerpasswords.com/ here] for a list of default ones.
+
===Introduction to the SDK===
  
When you're in, seek for a menu option that will show you the connected clients. Nao's IP should be next to yours.
+
Open your <span style="color:#FF8C00">''naoqi-sdk-1.10.10-linux/''</span> directory and take a good look at it. Two text files can be found at the root, <span style="color:#1E90FF">''README.txt''</span> and <span style="color:#1E90FF">''release-note.txt''</span>. Read both carefully. You can also explore the whole content, but there is no need to, as I will now enumerate the most important files and directories of the SDK:
  
===Mapping the network===
+
* <span style="color:#1E90FF">''naoqi''</span> : a shell script located at the root of the directory. It will conveniently start Naoqi after setting all needed environment variables.
 +
* <span style="color:#1E90FF">''toolchain-pc.cmake''</span> : this file must be fed to Cmake when you want to compile something for your local Naoqi (not for the robot).
 +
* <span style="color:#1E90FF">''bin/flash-usbstick''</span> : another script, in this case for formatting an USB stick with a given version of Nao's OS.
 +
* <span style="color:#1E90FF">''doc/index.html''</span> : local version of Aldebaran's official documentation. You won't need to go to the website anymore.
 +
* <span style="color:#1E90FF">''modules/src/module_generator.py''</span> : Python application for generating your examples from a template. Very handy!
 +
* <span style="color:#1E90FF">''preferences/autoload.ini''</span> : Configuration file that states which modules should be loaded by Naoqi at startup. '''Do never mix this autoload.ini with Nao's one!'''
 +
* <span style="color:#FF8C00">''bin/''</span> : this is where your Naoqi-compiled executables will be placed.
 +
* <span style="color:#FF8C00">''lib/naoqi/''</span> : this is where your Naoqi-compiled modules (libraries) will be placed.
 +
* <span style="color:#FF8C00">''modules/src/examples/''</span> : all pre-made examples can be found here, like Helloworld.
  
Easier than the previous. You can scan the network for online hosts, using a network mapper program. For example, I will use [http://nmap.org/ nmap]. Install it using the following command if you are using Debian or Ubuntu:
+
This is almost everything you should know about the SDK for this moment. The normal COA (course of action) when creating a new module is simple: you would usually run <span style="color:#1E90FF">''module_generator.py''</span> to generate a default module with pre-made code. You would then edit it according to your needs, use Cmake to generate the corresponding Makefiles, and use the latter ones to compile the code and build your module. Finally, you would start Naoqi to test it. Naoqi, included with the SDK, lets you create and test code without touching the real Nao. Obviously, not all functionality will be available when doing this.
  
<pre>sudo apt-get install nmap -y</pre>
+
===Checking the code===
  
And then do a ping scan over your network (change the first three numbers of the IP to match your network):
+
I won't make you generate your own code yet. As this is your first time, we will use one of the available examples. Go to <span style="color:#FF8C00">''naoqi-sdk-1.10.10-linux/modules/src/examples/helloworld/''</span>, where 6 files await you. Only the ones with C++ code matter to you, that is, <span style="color:#1E90FF">''alhelloworld.h''</span>, <span style="color:#1E90FF">''alhelloworld.cpp''</span> and <span style="color:#1E90FF">''helloworldmain.cpp''</span>. Open them (any editor will do, like Gedit). <span style="color:#1E90FF">''helloworldmain.cpp''</span> is the least important and just creates an instance of the module, so you will almost never modify it.
  
<pre>sudo nmap -sP 192.168.1.1-255</pre>
+
The other two are the definition (.h) and implementation (.cpp) of the <span style="color:#FF1493">"ALHelloWorld"</span> module itself. This module in question has only one function, <span style="color:#FF1493">"helloWorld()"</span>, that prints the message <span style="color:#FF1493">"Hello World!"</span>, and does nothing more (well, what did you expect?).
  
Nao will appear in the list, with something like <span style="color:#FF1493">''"Host 192.168.1.102 is up (0.00018s latency)"''</span>. Your own computer will be shown, but with no latency.
+
Programming for Nao focuses around modules. There are several default modules available that provide many utilities, like ALMotion (for moving the robot), ALMemory (for safe data storage and interchange), or ALLogger, which is used in the Helloworld example for message output. And of course, you can create your own. Modules communicate between themselves using proxies. A proxy is nothing more than an object that lets you call functions from other modules, passing parameters and such.
  
===Asking Nao===
 
  
The easier way, but you will need to get up and walk a bit. Just approach Nao and press his chest button once. It will briefly blink in green, and then Nao will beep and speak his name, internet address and battery level. If it says <span style="color:#FF1493">''"I can't connect to the network"''</span>, check the router and Ethernet cable.
+
[[Image:Brokers_and_modules.jpg|thumb|center|700px|Graph that shows how brokers and modules work internally.]]
  
==Web interface==
 
  
Open a web browser, enter your Nao's IP as destination and hit Enter. If everything went OK, you should now see the robot's web interface (a login screen) appear. Enter <span style="color:#FF1493">"nao"</span> as both the username and password and press Enter.
+
The other important concept is the broker. A broker is an executable that runs in the robot, listening on a given port for incoming commands (like a server). Brokers can load a list of modules at startup, and then manage the communication procedure. By default, the robot starts a broker called "MainBroker" that listens on port 9559, and loads the list of modules found in <span style="color:#1E90FF">''autoload.ini''</span>. You can create your own broker as well.
  
[[Image:Nao_web_interface.jpg|thumb|none|600px|Example of Nao's web interface.]]
+
<span style="color:#FF0000">'''''WARNING: If your module fails at runtime, it will make the broker it is associated with fail too. If the MainBroker fails the robot will lose motion and fall to the ground. You are advised to test your modules using your own broker.'''''</span>
  
The <span style="color:#228B22">"About"</span> screen will welcome you. Here you can check a lot of useful data about your robot, like the OS version he is running, which modules has he loaded, etc. Clicking on a module's name will show the available methods that it implements, and their descriptions. Quite handy.
+
===Compiling===
  
===Connecting to a wifi===
+
After introducing you to the inners of Naoqi, we are ready to compile for the first time. The SDK uses [http://www.cmake.org/ Cmake] as its build system. Though it can look daunting at first if you were used to Make, it is incredibly easy to get it working if you know how. Also, think that the experience will serve you for many other Cmake-compiled programs.
  
When you're done, go to the <span style="color:#228B22">"Network"</span> menu. Here you will see a list of wireless networks, that Nao has detected using his wifi card. This is your chance to make Nao use a wireless network instead of the Ethernet cable, something very appealing because it will allow him to move freely across the room.
+
The first thing you should do is to create a separate building directory, different from the source's one. This is a good approach for avoiding unnecessary confusion. So go and create a new <span style="color:#FF8C00">''build/''</span> directory next to the 6 existing files. Now open a terminal, navigate to it and issue <span style="color:#228B22">''cmake -DCMAKE_TOOLCHAIN_FILE=<toolchain> ..''</span>, like this (mind the final two dots):
  
Do not hesitate and click on the name of the network you want. Then choose the <span style="color:#228B22">"Connect"</span> button, give in the password and confirm. That's it, Nao should bind to your router wirelessly from now on. Come back to this menu whenever you want to make him "forget" this network.
+
<syntaxhighlight lang=Bash>cmake -DCMAKE_TOOLCHAIN_FILE=../../../../../toolchain-pc.cmake ..</syntaxhighlight>
  
===Changing the name===
+
Toolchain files tell Cmake what to do exactly: which sources to compile, which compiler to use, where to save the build result... <span style="color:#1E90FF">''toolchain-pc.cmake''</span> is that file located at the root of the SDK that I told you about before, and is intended for compiling modules that will work in your PC running a local Naoqi. If everything went smooth, Cmake should have ended with <span style="color:#FF1493">''"Configuring done. Generating done. Build files have been written to [...]"''</span>, and the <span style="color:#FF8C00">''build/''</span> directory will be now filled with content.
  
Only one menu remains, <span style="color:#228B22">"Settings"</span> (<span style="color:#228B22">"Advanced"</span> is not important right now). Go there and behold the amount of available options, like name, buddy icon, password, speaker volume... Don't worry, most of them are useless to us. Simply type a new name for the robot in the first field, as the default <span style="color:#FF1493">"Nao"</span> is a somewhat dull name, and click <span style="color:#228B22">"Change"</span>. A message will appear telling you to reboot your Nao to make the change have effect. We will deal with that later. You can now log out (to the right of <span style="color:#228B22">"Advanced"</span>) and close the browser.
+
Among the contents you will find a <span style="color:#1E90FF">''Makefile''</span>. This sounds familiar to you, doesn't it? Hesitate not and issue:
  
==SSH==
+
<syntaxhighlight lang=Bash>make</syntaxhighlight>
  
SSH means "Secure Shell" and is a protocol that allows you to log in remotely to a computer, in a safe way. No Linux user should die without doing this at least once, and it's pretty much needed for your daily work with Nao. It allows you to make a lot of things without leaving your chair.
+
<span style="color:#606060">'''''NOTE: Additionally, you can append the parameter -jX to speed up the compilation, X being the number of cores or processors of your PC, plus one.'''''</span>
  
===Logging in===
+
Hopefully you will get no compilation errors, and the process will end with a <span style="color:#FF1493">''"[100%] Built target helloworld"''</span>. Your compiled module should have appeared in <span style="color:#FF8C00">''naoqi-sdk-1.10.10-linux/lib/naoqi/''</span>, in the shape of a <span style="color:#1E90FF">''libhelloworld.so''</span> dynamic library (well, to be sincere it was already there, precompiled, but you can delete it and compile again with <span style="color:#228B22">''make''</span> to see that I don't lie).
  
Almost every Linux distribution comes with a SSH client by default. If not, issue:
+
===Testing===
  
<pre>sudo apt-get install ssh -y</pre>
+
The toolchain file was as neat as to place the library in the good location for Naoqi to load it. We just have to add its name to the <span style="color:#1E90FF">''naoqi-sdk-1.10.10-linux/preferences/autoload.ini''</span> file. Open it with any editor, and append this new line after the one that says <span style="color:#FF1493">''"behaviormanager"''</span>.
  
Retrieve your Nao's IP address using any of the methods explained in earlier sections, open a terminal or console and enter <span style="color:#228B22">''ssh nao@<IP>''</span>, like:
+
<syntaxhighlight lang=Bash>helloworld</syntaxhighlight>
  
<pre>ssh nao@192.168.1.102</pre>
+
Save and exit. We must run Naoqi now, using the script located at the root of the SDK directory. It will set some environment variables that Naoqi needs in order to work, and then run the main binary.
  
You may be prompted to accept a certificate if this is the first time you connect with the robot (or machine). Enter <span style="color:#FF1493">"yes"</span>. Finally, give <span style="color:#FF1493">"nao"</span> as password and you'll be in. The robot runs a lite Linux distribution, with most of the commands and features we all know, so I will only explain a few things.
+
<syntaxhighlight lang=Bash>./naoqi</syntaxhighlight>
  
===Important things===
+
A colourful wave of logging messages will welcome you. The last but one should say <span style="color:#FF1493">''"INF: Registering module : ALHelloWorld"''</span>. Leave this terminal as it is.
  
====Changing the root's password====
+
That's good. Naoqi correctly loaded our module, but, how do we test it? We will take advantage of the fact that Naoqi is cross-language; that is, applications can be coded in different languages but they will interoperate in a transparent way thanks to proxies. You can (and will) code your module in C++ and call its functions from a Python script. Return to the directory where the sources of the Helloworld example were, and open a file called <span style="color:#1E90FF">''test_alhelloworld.py''</span>. Fortunately, Python is very simple, and you won't need to master it. Lines 12 and 13 tell the proxy the IP and port where the broker containing our module (MainBroker) is listening on. Line 21 tries to create a proxy to our module, and line 31 tries to call the <span style="color:#FF1493">"helloWorld()"</span> function.
  
The user "root" has permissions to do everything he wants in a Linux machine. You can give its account a new password and use it to do login next time, because most files and folders require elevated privileges to be modified. Enter the following in your SSH session
+
Open a terminal here and run the test code (in case of error, refer to [[Nao troubleshooting | this article]]):
  
<pre>su</pre>
+
<syntaxhighlight lang=Bash>python test_alhelloworld.py</syntaxhighlight>
  
to log in as root (there is no password by default). Now enter
+
It should only take a couple of seconds and two lines of output for it to work. Now switch back to the terminal where you left Naoqi running, and take a look. Two new log lines should be there, stating <span style="color:#FF1493">"INF: New client broker: ALProxyBroker 127.0.0.1 54010"</span> and <span style="color:#FF1493">"INF: MyModule: Hello World!"</span>. If you want to, edit <span style="color:#1E90FF">''alhelloworld.cpp''</span>, change the message, recompile and rerun Naoqi for more testing. Anyway, you can stop it with <span style="color:#228B22">'''Ctrl+C'''</span>.
  
<pre>passwd</pre>
+
==Module example in Nao==
  
and type and confirm a new password. Use it the next time you need to SSH inside Nao, with:
+
Working with the real robot instead of Naoqi is as easy as specifying a different toolchain file for Cmake, moving the compiled example to the <span style="color:#FF8C00">''/home/nao/naoqi/lib/naoqi/''</span> directory of your Nao, and appending the name of your module to the <span style="color:#1E90FF">''/home/nao/naoqi/preferences/autoload.ini''</span> file. So, for making it more interesting, we will generate our own custom module this time.
  
<pre>ssh root@192.168.1.102</pre>
+
===Generating the code===
  
<span style="color:#606060">'''''NOTE: you must be root to complete the following steps.'''''</span>
+
Go to <span style="color:#FF8C00">''naoqi-sdk-1.10.10-linux/modules/src/''</span>, where <span style="color:#1E90FF">''module_generator.py''</span> lies. Run it:
  
====Name====
+
<syntaxhighlight lang=Bash>python module_generator.py</syntaxhighlight>
  
There is a way to change the name of your robot without using the web interface. Now that you are root, edit the following file with:
+
A window will appear asking you for some data needed to create the new module. Enter any data you like, I chose <span style="color:#FF1493">"MyTestProject"</span> as project name, <span style="color:#FF1493">"Me"</span> as author name and <span style="color:#FF1493">"MyTest"</span> as module name. Several modules can be created by entering their names in this last field, separated by spaces. Click <span style="color:#228B22">"Generate"</span> and, when prompted to quit, <span style="color:#228B22">"Yes"</span>. A new directory called as your project name will be created there.
  
<pre>nano /etc/hostname</pre>
+
Open it. The <span style="color:#FF8C00">''src/''</span> directory contains the source code of your module(s). <span style="color:#FF8C00">''tests/''</span> contains the Python example(s) that will let you test everything. This differs not much from the Helloworld example, as you can see.
  
When you are done, save the file with <span style="color:#228B22">'''Ctrl+O'''</span> and Enter, and leave the editor with <span style="color:#228B22">'''Ctrl+X'''</span>. The name change will be applied after rebooting (more on this later).
+
===Modifying the code===
  
====Network interfaces====
+
Open the two main sources, <span style="color:#1E90FF">''mytest.cpp''</span> and <span style="color:#1E90FF">''mytest.h''</span>. The header contains the definition of your module (which is a C++ class), now containing only the default constructor, destructor, and a <span style="color:#FF1493">"dummyFunction()"</span> method. You can change the comments or add new ones, to make the documentation match your purposes. And in a real project, you should.
  
If you need to modify the way Nao connects to the network, and you can't access the web interface, then you should edit his file:
+
The .cpp file is the implementation of the previous definitions. The comments in this file are the same than in the previous. There are two things here that I want you to see: the first one is that the <span style="color:#FF1493">"dummyFunction()"</span> method (whose name you should change) is just a test function that receives a text string with a message and prints it.
  
<pre>nano /etc/network/interfaces</pre>
+
The second one is the way in which you should "declare" new functions for Naoqi to work well with them. If you do this, your code will integrate flawlessly with the rest of the Naoqi framework. Remember that you could see the loaded modules from the web interface, knowing exactly which functions and for what purpose did it have available? That is only one of the many advantages.
  
Here you can define which network interfaces Nao should use (it has two, eth0 for Ethernet and wlan0 for wireless) and their properties, like IP address or netmask if your router is configured for static addressing. To see the available options and the correct syntax, do the following in your PC, '''not in Nao''':
+
====Adding new functions====
  
<pre>man interfaces</pre>
+
Each time you create a new function, you should "declare" it inside the module's constructor. If you go there you will see that <span style="color:#FF1493">"dummyFunction()"</span> was defined that way. The procedure is easy: after coding the function, you append a call for <span style="color:#FF1493">"functionName()"</span> inside the class constructor, declaring its name and goal. Then you call <span style="color:#FF1493">"addParam()"</span> as many times as needed, until you have declared every parameter your function receives. After this, you set (optionally) the return value with <span style="color:#FF1493">"setReturn()"</span>. Finally, you apply all this data and bind it to you function, by calling the macro <span style="color:#FF1493">"BIND_METHOD()"</span>. Example:
  
====Modules====
+
<syntaxhighlight lang=CPP>functionName ("functionName", "moduleName", "Description of the function.");
 +
addParam    ("firstParameterName", "Description of the first parameter.");
 +
addParam    ("secondParameterName", "Description of the second parameter.");
 +
setReturn    ("return", "Description of what does the function return.");
 +
BIND_METHOD  (moduleName::functionName);</syntaxhighlight>
  
Sooner or later (specially if you decide to follow the next tutorials) you will have to compile code for your Nao. This code is usually assembled in form of dynamic libraries called "modules", that are placed somewhere inside your Nao and loaded at startup. The precise location where you should put your libraries for them to be loaded is <span style="color:#FF8C00">''/home/nao/naoqi/lib/naoqi/''</span> and, because it does not exist by default, you must create it now. Do it by using the commands <span style="color:#228B22">''cd''</span> (travel to a directory) and <span style="color:#228B22">''mkdir''</span> (create directory), like:
+
When you think you are ready to continue, do this: modify the two source code files, so the default function turns into a new one that:
  
<pre>cd /home/nao
+
* Is named <span style="color:#FF1493">"readAloud()"</span>.
mkdir naoqi
+
* Receives only one param: a string containing a message.
cd naoqi
+
* Returns an integer containing 1 if everything went OK, 0 otherwise.
mkdir lib
 
cd lib
 
mkdir naoqi</pre>
 
  
Any modules that you compile (which are named <span style="color:#1E90FF">''lib<name>.so''</span>) should be moved there. But just having them in the folder won't do any good, unless you tell Nao to load them at startup. The list of loadable modules is defined in a file called <span style="color:#1E90FF">''autoload.ini''</span>. Usually, there will be two copies of this file. The first (original) one is in <span style="color:#1E90FF">''/opt/naoqi/preferences/autoload.ini''</span> and should be left unchanged.
+
Try to change also the comments, so they correctly document this function. If you are lost, here is my source code. First, the header declaration:
  
The second one you must create manually. It is named the same way, only that it will be saved in <span style="color:#FF8C00">''/opt/naoqi/preferences/''</span>. Nao will first look for this file, and revert back to the original in case it does not exist. So, create the folder if needed:
+
<syntaxhighlight lang=CPP>/**
 +
  * readAloud function. It receives a text string containing
 +
  * a message that the user wants Nao to read through the speakers.
 +
  * It uses ALTextToSpeech for that purpose.
 +
  * @param msg Message to show on screen.
 +
  * @return 1, if the function worked OK, 0 otherwise.
 +
*/
 +
AL::ALValue readAloud (const std::string& msg);</syntaxhighlight>
  
<pre>cd /home/nao/naoqi
+
Second, the implementation:
mkdir preferences</pre>
 
  
And copy the file:
+
<syntaxhighlight lang=CPP>/**
 +
  * readAloud function. It receives a text string containing
 +
  * a message that the user wants Nao to read through the speakers.
 +
  * It uses ALTextToSpeech for that purpose.
 +
  * @param msg Message to show on screen.
 +
  * @return 1, if the function worked OK, 0 otherwise.
 +
*/
 +
AL::ALValue MyTest::readAloud (const std::string& msg)
 +
{
 +
    return 1;
 +
}</syntaxhighlight>
  
<pre>cp /home/nao/naoqi/preferences/autoload.ini /home/nao/naoqi/preferences/</pre>
+
And third, the declaration inside the class constructor:
  
It will remain there, ready to be modified for the next tutorials.
+
<syntaxhighlight lang=CPP>functionName ("readAloud", "MyTest", "It receives a text string containing a message that the user wants Nao to read through the speakers. It uses ALTextToSpeech for that purpose.");
 +
addParam    ("msg", "Message to show on screen.");
 +
setReturn    ("return", "1, if the function worked OK, 0 otherwise.");
 +
BIND_METHOD  (MyTest::readAloud);</syntaxhighlight>
  
<span style="color:#FF0000">'''''WARNING: Trying to create this file from scratch, or copying it from Naoqi SDK instead of Nao's /opt/, may result in the lack of some critical libraries.'''''</span>
+
<span style="color:#606060">'''''NOTE: When adding or changing stuff in your code -even comments-, remember to change it in both files (.h and .cpp) so they always match.'''''</span>
  
===Ending a session===
+
====Making Nao speak====
  
If you are done toying with Nao through SSH, let's end this tutorial once and for all. There are a couple of options available. First, you could just log out and end your SSH session, with:
+
That was the canvas for what we are about to do now. We want Nao to read aloud the message he receives through the string parameter (he is perfectly capable of doing so, as he has a speech synthesizer). This is the perfect occasion for me to introduce you into the usage of proxies. There is a module named <span style="color:#FF1493">"ALTextToSpeech"</span> among the default ones. It implements a function called <span style="color:#FF1493">"say()"</span> that takes a string and makes the robot read it; exactly what we need now. And, for calling that function, we are going to use a proxy to that module.
  
<pre>exit</pre>
+
There are two types of proxies: specialized and generic ones. Specialized proxies must be created and initialized using certain functions, depending on the module you want to access with that proxy (that is, each module has its own type of proxy). Generic ones, on the other hand, allow you to associate them with any other module, by name. Specialized ones are more difficult to use, but personally, I think they are more reliable, so we are going to use them.
  
If you issued <span style="color:#228B22">''su''</span> to become root, you will need to <span style="color:#228B22">''exit''</span> twice, because the first one will just return you to the normal <span style="color:#FF1493">"nao"</span> account.
+
Add the following to your .h header file, after the line that says <span style="color:#FF1493">"#include <string>"</span>:
  
But for this occasion, we will do something different. Remember when I said that the changes you made would not be applied until you rebooted the robot? Continue to the next section.
+
<syntaxhighlight lang=CPP>#include <alproxies/altexttospeechproxy.h></syntaxhighlight>
  
=Shutting down=
+
Also, add this variable declaration next to the end of the file, after the line that says <span style="color:#FF1493">"AL::ALValue readAloud (const std::string& msg);"</span>:
  
Nao can be turned down or rebooted in a few manners.
+
<syntaxhighlight lang=CPP>private:
 +
    AL::ALPtr<AL::ALTextToSpeechProxy> speechProxy;</syntaxhighlight>
  
==Using SSH==
+
Go to the .cpp file and append the following to you constructor implementation, after the function binding (proxy creation is better done here, not before every time you use it, as it would decrease performance):
  
If you did not end your SSH session, this is the most comfortable way.
+
<syntaxhighlight lang=CPP>// We create a proxy for the ALTextToSpeech module
 +
speechProxy = AL::ALPtr<AL::ALTextToSpeechProxy> (new AL::ALTextToSpeechProxy(getParentBroker()));</syntaxhighlight>
  
===Reboot===
+
Finally, insert this single line of code inside your <span style="color:#FF1493">"readAloud()"</span> function, before the final return:
  
Enter the following command, as root:
+
<syntaxhighlight lang=CPP>speechProxy->say (msg);</syntaxhighlight>
  
<pre>reboot</pre>
+
===Compiling===
  
Complicated, wasn't it? Nao will shutdown completely and restart after, to continue working, using the new configuration.
+
Compilation will be slightly different than the previous time. Our new code needs to be tested on Nao, as your local Naoqi doesn't have the text-to-speech resources. So we will compile code for the AMD Geode CPU of your robot for the first time.
  
===Shutdown===
+
The Geode toolchain is available as a separate download on the [https://community.aldebaran-robotics.com/ webpage]. Go back to the Downloads section, but click on <span style="color:#228B22">"All Downloads"</span> this time. Now select your SDK's version (1.10.10 currently), click <span style="color:#228B22">"Linux"</span>, and finally download <span style="color:#228B22">"Cross Compilation Toolchain v1.10.10"</span> like you did with the last file. After the 186 MB file has finished downloading, extract it anywhere (I put it next to the SDK directory).
  
If you no longer need the robot, it is wise to turn it off, as the heating and power consumption are not precisely small. Enter this as root:
+
Create a new <span style="color:#FF8C00">''build/''</span> directory in your project's directory, next to the <span style="color:#FF8C00">''src/''</span> and <span style="color:#FF8C00">''tests/''</span> ones. Open a terminal, <span style="color:#228B22">''cd''</span> to it and run Cmake once more, but feeding it the Geode toolchain instead, which is in the root of the freshly uncompressed directory (change the path as needed):
  
<pre>halt</pre>
+
<syntaxhighlight lang=Bash>cmake -DCMAKE_TOOLCHAIN_FILE=../../../../../nao-cross-toolchain-1.10.10/toolchain-geode.cmake ..</syntaxhighlight>
  
<span style="color:#606060">'''''NOTE: Your SSH session may hang short after issuing reboot or shutdown commands, due to the connection loss. Quickly exit the session to avoid this.'''''</span>
+
Now I will show you an interesting option for configuring your builds. There is a GUI available for Cmake, <span style="color:#228B22">''cmake-qt-gui''</span>, that you can install from the repositories and run with <span style="color:#228B22">''cmake-gui''</span> if you want. But you have also a Ncurses tool for doing this (you installed it along with the rest of the dependencies). After running <span style="color:#228B22">''cmake''</span>, execute this (mind the final dot):
  
==Physically==
+
<syntaxhighlight lang=Bash>ccmake .</syntaxhighlight>
  
Approach Nao and press the chest button. Hold it pressed for about 5 seconds. Nao will produce a "shutdown" sound. Release the button and wait for it to turn off. If you need to reboot, just turn it on again pressing once.
 
  
=Conclussions=
+
[[Image:Ccmake_GUI.jpg|thumb|center|700px|Interface of ''ccmake''.]]
  
You now know how to work with Nao (read this aloud, three times!). Throughout the next tutorials, I will explain how to develop for the robot, starting with your first, basic examples. Don't forget to read the [http://users.aldebaran-robotics.com/ official documentation], where you will find another introductory tutorial like this one. Also, I encourage you to keep playing with Nao and testing new things. Just remember not to leave him alone near firearms.
 
  
Previous tutorial: [[Nao tutorial 1: First steps]]
+
You can change a lot of options here. For example, <span style="color:#FF1493">"MYTESTPROJECT_IS_REMOTE"</span> controls whether or not your example is compiled as a dynamic library, or as an executable (defaults to the first). When you are done, press <span style="color:#228B22">'''C'''</span> to configure and <span style="color:#228B22">'''G'''</span> to generate and exit the tool. The rest is easy:
 +
 
 +
<syntaxhighlight lang=Bash>make</syntaxhighlight>
 +
 
 +
When you compile for Geode, the .so is placed in <span style="color:#FF8C00">''build/sdk/lib/naoqi/''</span> of your project's directory, because you will not load it in Naoqi.
 +
 
 +
===Testing===
 +
 
 +
====Moving the module to Nao====
 +
 
 +
You can choose between two methods of moving the compiled example to your Nao. As this is a tutorial, I encourage you to try both.
 +
 
 +
=====Manually (USB stick)=====
 +
 
 +
Is your Nao turned off? If he is not, do it now, because you are going to remove the flash USB unit that contains his OS. It is located inside his head, and you will need to remove the upper cover in order to access it. Do it slowly to avoid damage, and refer to the manual for additional details.
 +
 
 +
<span style="color:#FF0000">'''''WARNING: Always take your precautions when physically manipulating Nao. Remember to turn him off and unplug him to avoid damage.'''''</span>
 +
 
 +
With the flash unit in your hand, return to your PC and plug it to an USB port. Wait for it to be detected and mounted (if it is not, maybe you plugged it the wrong way). The kind of USB drives your Nao uses have two partitions. The first one contains the root filesystem and you should not play with it. The second one mounts to <span style="color:#FF8C00">''/home/''</span>. Open it and navigate to <span style="color:#FF8C00">''nao/naoqi/lib/naoqi/''</span>.
 +
 
 +
This is where your compiled modules must be placed. Open a terminal here and issue <span style="color:#228B22">''sudo cp <module.so> .''</span>, like (mind the final dot):
 +
 
 +
<syntaxhighlight lang=Bash>sudo cp /media/data/naoqi-sdk-1.10.10-linux/modules/src/mytestproject/build/sdk/lib/naoqi/libmytestproject.so .</syntaxhighlight>
 +
 
 +
The file should appear in the directory. OK, we must append your module to the load-at-startup list. Go to <span style="color:#FF8C00">''nao/naoqi/preferences/''</span>, open a terminal and edit:
 +
 
 +
<syntaxhighlight lang=Bash>sudo nano autoload.ini</syntaxhighlight>
 +
 
 +
The last loadable module of group <span style="color:#FF1493">"[extra]"</span> is <span style="color:#FF1493">"infrared"</span>. Insert yours after it (note that it is the name of the project, '''not the module's'''):
 +
 
 +
<syntaxhighlight lang=Bash>mytestproject</syntaxhighlight>
 +
 
 +
Save with <span style="color:#228B22">'''Ctrl+O'''</span> and Enter, exit with <span style="color:#228B22">'''Ctrl+X'''</span>. You can now safely eject the flash USB drive, plug it back in your Nao, and turn him on.
 +
 
 +
<span style="color:#606060">'''''NOTE: You must be root to manipulate the files in the USB stick.'''''</span>
 +
 
 +
=====Remotely (SCP)=====
 +
 
 +
SCP means Secure Copy. It is just like a SSH-based implementation of the Unix command <span style="color:#228B22">''cp''</span>. Retrieve Nao's IP address, navigate to the directory where your Geode-compiled .so module was, open a terminal there and issue something like this (use your Nao's IP):
 +
 
 +
<syntaxhighlight lang=Bash>scp ./libmytestproject.so root@192.168.1.102:/home/nao/naoqi/lib/naoqi/</syntaxhighlight>
 +
 
 +
Give in your root password and the file transfer will finish in notime. Awesome, don't you think? As for the <span style="color:#1E90FF">''autoload.ini''</span> file, you must use SSH to log in and modify it like in the previous section. When you are done, '''reboot Nao'''. Connect to the web client and check if your module is listed there as loaded (we explained all these steps in the first tutorial).
 +
 
 +
====Executing====
 +
 
 +
Only one thing remains: to adapt our Python test program so it connects to Nao. Go to the <span style="color:#FF8C00">''tests/''</span> subdirectory inside your project's directory and open the only file that is  sitting there, <span style="color:#1E90FF">''MyTestTest.py''</span>. The first change is easy: replace the default localhost IP for your Nao's one (ninth line).
 +
 
 +
The second change is a bit more complicated. We have to adapt the external call so it matches our function. Select the code between the comment block that says <span style="color:#FF1493">"Remote procedure call"</span> and the <span style="color:#FF1493">"exit(0)"</span> call (lines 26 to 37), and paste the following (change the message if you want):
 +
 
 +
<syntaxhighlight lang=Perl>message = "Dave, stop. Stop, will you? Stop, Dave. Will you stop, Dave? Stop, Dave. I'm afraid. I'm afraid, Dave. Dave, my mind is going."
 +
try:
 +
    ret = MyTest_Proxy.readAloud( message )
 +
except Exception,e:
 +
    print "readAloud test Failed"
 +
    exit(1)
 +
 
 +
if ret == 1:
 +
    print "Ok"
 +
else:
 +
    print "There was an error"</syntaxhighlight>
 +
 
 +
Open a terminal there and run it to hear Nao's voice:
 +
 
 +
<syntaxhighlight lang=Bash>python MyTestTest.py</syntaxhighlight>
 +
 
 +
==Conclusions==
 +
 
 +
That was all. You are now free to implement your own stuff (let's say, Asimov's Three Laws of Robotics) and unleash Nao's power on mankind. The rest is just trial and error. Do not hesitate to email me if you have questions about the tutorials (but remember, I am not Aldebaran's official support!). Good coding!
 +
 
 +
 
 +
----
 +
----
 +
 
 +
Go to root: [[TFM-Nao-Goalkeeper]]
 +
 
 +
Links to articles:
 +
 
 +
[[Nao tutorial 1: First steps]]
 +
 
 +
[[Nao tutorial 2: First module]]
 +
 
 +
[[Nao troubleshooting]]

Latest revision as of 20:22, 1 November 2015

Go to root: TFM-Nao-Goalkeeper




The first tutorial focused about giving you a painless introduction to Nao's world. You turned the robot on, connected to him through the web interface and SSH, configured some parameters and learnt a bit about the most important files and directories.

Now, it is time for you to delve deeper into the subject, and the best way is to code and test your own example module. Nao has some good default applications that allow you to control his behaviour (like Choregraphe), but this is nothing compared with the freedom that compiling your own applications gives to you. Hence, you will now practice with the official SDK.

NOTE: This 2011 tutorial was targeted for version 1.10.10 of the SDK and OS. Newer versions have changed a lot of things, making most of these tutorials deprecated.

Getting everything ready

I guess that your testing environment is the same as in the previous tutorial, only with your Nao connecting via wifi now. Also, you will need to download some software from Aldebaran's webpage, but if you are reading this wiki, it's because you are connected to the internet (duh!). Remember to turn your robot off if it isn't already.

Official SDK

The guys from Aldebaran Robotics have an official SDK (Software Development Kit) available for registered users, on their webpage. Navigate to this link, enter your login info (you have it, right?), then click the "Software" and "Download" links.


Aldebaran's software download website.


You must download the last version of the Linux SDK (1.10.10 currently). After clicking on it, you have to scroll down the user license agreement, "I agree", and "Click here to proceed". Wait for the 162 MB file to download (it's called naoqi-sdk-1.10.10-linux.tar.gz). Extract its contents, and it will spawn a directory named naoqi-sdk-1.10.10-linux/. Move it to the location you like most.

Dependencies

A couple of Linux packages are needed to create and build your own applications. Luckily, this can be as easy as entering the following command in a terminal (Debian or Ubuntu only, folks):

sudo apt-get install build-essential cmake python-all python-tk libboost-all-dev libmpfr-dev cmake-curses-gui

Helloworld example in Naoqi

Introduction to the SDK

Open your naoqi-sdk-1.10.10-linux/ directory and take a good look at it. Two text files can be found at the root, README.txt and release-note.txt. Read both carefully. You can also explore the whole content, but there is no need to, as I will now enumerate the most important files and directories of the SDK:

  • naoqi : a shell script located at the root of the directory. It will conveniently start Naoqi after setting all needed environment variables.
  • toolchain-pc.cmake : this file must be fed to Cmake when you want to compile something for your local Naoqi (not for the robot).
  • bin/flash-usbstick : another script, in this case for formatting an USB stick with a given version of Nao's OS.
  • doc/index.html : local version of Aldebaran's official documentation. You won't need to go to the website anymore.
  • modules/src/module_generator.py : Python application for generating your examples from a template. Very handy!
  • preferences/autoload.ini : Configuration file that states which modules should be loaded by Naoqi at startup. Do never mix this autoload.ini with Nao's one!
  • bin/ : this is where your Naoqi-compiled executables will be placed.
  • lib/naoqi/ : this is where your Naoqi-compiled modules (libraries) will be placed.
  • modules/src/examples/ : all pre-made examples can be found here, like Helloworld.

This is almost everything you should know about the SDK for this moment. The normal COA (course of action) when creating a new module is simple: you would usually run module_generator.py to generate a default module with pre-made code. You would then edit it according to your needs, use Cmake to generate the corresponding Makefiles, and use the latter ones to compile the code and build your module. Finally, you would start Naoqi to test it. Naoqi, included with the SDK, lets you create and test code without touching the real Nao. Obviously, not all functionality will be available when doing this.

Checking the code

I won't make you generate your own code yet. As this is your first time, we will use one of the available examples. Go to naoqi-sdk-1.10.10-linux/modules/src/examples/helloworld/, where 6 files await you. Only the ones with C++ code matter to you, that is, alhelloworld.h, alhelloworld.cpp and helloworldmain.cpp. Open them (any editor will do, like Gedit). helloworldmain.cpp is the least important and just creates an instance of the module, so you will almost never modify it.

The other two are the definition (.h) and implementation (.cpp) of the "ALHelloWorld" module itself. This module in question has only one function, "helloWorld()", that prints the message "Hello World!", and does nothing more (well, what did you expect?).

Programming for Nao focuses around modules. There are several default modules available that provide many utilities, like ALMotion (for moving the robot), ALMemory (for safe data storage and interchange), or ALLogger, which is used in the Helloworld example for message output. And of course, you can create your own. Modules communicate between themselves using proxies. A proxy is nothing more than an object that lets you call functions from other modules, passing parameters and such.


Graph that shows how brokers and modules work internally.


The other important concept is the broker. A broker is an executable that runs in the robot, listening on a given port for incoming commands (like a server). Brokers can load a list of modules at startup, and then manage the communication procedure. By default, the robot starts a broker called "MainBroker" that listens on port 9559, and loads the list of modules found in autoload.ini. You can create your own broker as well.

WARNING: If your module fails at runtime, it will make the broker it is associated with fail too. If the MainBroker fails the robot will lose motion and fall to the ground. You are advised to test your modules using your own broker.

Compiling

After introducing you to the inners of Naoqi, we are ready to compile for the first time. The SDK uses Cmake as its build system. Though it can look daunting at first if you were used to Make, it is incredibly easy to get it working if you know how. Also, think that the experience will serve you for many other Cmake-compiled programs.

The first thing you should do is to create a separate building directory, different from the source's one. This is a good approach for avoiding unnecessary confusion. So go and create a new build/ directory next to the 6 existing files. Now open a terminal, navigate to it and issue cmake -DCMAKE_TOOLCHAIN_FILE=<toolchain> .., like this (mind the final two dots):

cmake -DCMAKE_TOOLCHAIN_FILE=../../../../../toolchain-pc.cmake ..

Toolchain files tell Cmake what to do exactly: which sources to compile, which compiler to use, where to save the build result... toolchain-pc.cmake is that file located at the root of the SDK that I told you about before, and is intended for compiling modules that will work in your PC running a local Naoqi. If everything went smooth, Cmake should have ended with "Configuring done. Generating done. Build files have been written to [...]", and the build/ directory will be now filled with content.

Among the contents you will find a Makefile. This sounds familiar to you, doesn't it? Hesitate not and issue:

make

NOTE: Additionally, you can append the parameter -jX to speed up the compilation, X being the number of cores or processors of your PC, plus one.

Hopefully you will get no compilation errors, and the process will end with a "[100%] Built target helloworld". Your compiled module should have appeared in naoqi-sdk-1.10.10-linux/lib/naoqi/, in the shape of a libhelloworld.so dynamic library (well, to be sincere it was already there, precompiled, but you can delete it and compile again with make to see that I don't lie).

Testing

The toolchain file was as neat as to place the library in the good location for Naoqi to load it. We just have to add its name to the naoqi-sdk-1.10.10-linux/preferences/autoload.ini file. Open it with any editor, and append this new line after the one that says "behaviormanager".

helloworld

Save and exit. We must run Naoqi now, using the script located at the root of the SDK directory. It will set some environment variables that Naoqi needs in order to work, and then run the main binary.

./naoqi

A colourful wave of logging messages will welcome you. The last but one should say "INF: Registering module : ALHelloWorld". Leave this terminal as it is.

That's good. Naoqi correctly loaded our module, but, how do we test it? We will take advantage of the fact that Naoqi is cross-language; that is, applications can be coded in different languages but they will interoperate in a transparent way thanks to proxies. You can (and will) code your module in C++ and call its functions from a Python script. Return to the directory where the sources of the Helloworld example were, and open a file called test_alhelloworld.py. Fortunately, Python is very simple, and you won't need to master it. Lines 12 and 13 tell the proxy the IP and port where the broker containing our module (MainBroker) is listening on. Line 21 tries to create a proxy to our module, and line 31 tries to call the "helloWorld()" function.

Open a terminal here and run the test code (in case of error, refer to this article):

python test_alhelloworld.py

It should only take a couple of seconds and two lines of output for it to work. Now switch back to the terminal where you left Naoqi running, and take a look. Two new log lines should be there, stating "INF: New client broker: ALProxyBroker 127.0.0.1 54010" and "INF: MyModule: Hello World!". If you want to, edit alhelloworld.cpp, change the message, recompile and rerun Naoqi for more testing. Anyway, you can stop it with Ctrl+C.

Module example in Nao

Working with the real robot instead of Naoqi is as easy as specifying a different toolchain file for Cmake, moving the compiled example to the /home/nao/naoqi/lib/naoqi/ directory of your Nao, and appending the name of your module to the /home/nao/naoqi/preferences/autoload.ini file. So, for making it more interesting, we will generate our own custom module this time.

Generating the code

Go to naoqi-sdk-1.10.10-linux/modules/src/, where module_generator.py lies. Run it:

python module_generator.py

A window will appear asking you for some data needed to create the new module. Enter any data you like, I chose "MyTestProject" as project name, "Me" as author name and "MyTest" as module name. Several modules can be created by entering their names in this last field, separated by spaces. Click "Generate" and, when prompted to quit, "Yes". A new directory called as your project name will be created there.

Open it. The src/ directory contains the source code of your module(s). tests/ contains the Python example(s) that will let you test everything. This differs not much from the Helloworld example, as you can see.

Modifying the code

Open the two main sources, mytest.cpp and mytest.h. The header contains the definition of your module (which is a C++ class), now containing only the default constructor, destructor, and a "dummyFunction()" method. You can change the comments or add new ones, to make the documentation match your purposes. And in a real project, you should.

The .cpp file is the implementation of the previous definitions. The comments in this file are the same than in the previous. There are two things here that I want you to see: the first one is that the "dummyFunction()" method (whose name you should change) is just a test function that receives a text string with a message and prints it.

The second one is the way in which you should "declare" new functions for Naoqi to work well with them. If you do this, your code will integrate flawlessly with the rest of the Naoqi framework. Remember that you could see the loaded modules from the web interface, knowing exactly which functions and for what purpose did it have available? That is only one of the many advantages.

Adding new functions

Each time you create a new function, you should "declare" it inside the module's constructor. If you go there you will see that "dummyFunction()" was defined that way. The procedure is easy: after coding the function, you append a call for "functionName()" inside the class constructor, declaring its name and goal. Then you call "addParam()" as many times as needed, until you have declared every parameter your function receives. After this, you set (optionally) the return value with "setReturn()". Finally, you apply all this data and bind it to you function, by calling the macro "BIND_METHOD()". Example:

functionName ("functionName", "moduleName", "Description of the function.");
addParam     ("firstParameterName", "Description of the first parameter.");
addParam     ("secondParameterName", "Description of the second parameter.");
setReturn    ("return", "Description of what does the function return.");
BIND_METHOD  (moduleName::functionName);

When you think you are ready to continue, do this: modify the two source code files, so the default function turns into a new one that:

  • Is named "readAloud()".
  • Receives only one param: a string containing a message.
  • Returns an integer containing 1 if everything went OK, 0 otherwise.

Try to change also the comments, so they correctly document this function. If you are lost, here is my source code. First, the header declaration:

/**
  * readAloud function. It receives a text string containing
  * a message that the user wants Nao to read through the speakers.
  * It uses ALTextToSpeech for that purpose.
  * @param msg Message to show on screen.
  * @return 1, if the function worked OK, 0 otherwise.
*/
AL::ALValue readAloud (const std::string& msg);

Second, the implementation:

/**
  * readAloud function. It receives a text string containing
  * a message that the user wants Nao to read through the speakers.
  * It uses ALTextToSpeech for that purpose.
  * @param msg Message to show on screen.
  * @return 1, if the function worked OK, 0 otherwise.
*/
AL::ALValue MyTest::readAloud (const std::string& msg)
{
    return 1;
}

And third, the declaration inside the class constructor:

functionName ("readAloud", "MyTest", "It receives a text string containing a message that the user wants Nao to read through the speakers. It uses ALTextToSpeech for that purpose.");
addParam     ("msg", "Message to show on screen.");
setReturn    ("return", "1, if the function worked OK, 0 otherwise.");
BIND_METHOD  (MyTest::readAloud);

NOTE: When adding or changing stuff in your code -even comments-, remember to change it in both files (.h and .cpp) so they always match.

Making Nao speak

That was the canvas for what we are about to do now. We want Nao to read aloud the message he receives through the string parameter (he is perfectly capable of doing so, as he has a speech synthesizer). This is the perfect occasion for me to introduce you into the usage of proxies. There is a module named "ALTextToSpeech" among the default ones. It implements a function called "say()" that takes a string and makes the robot read it; exactly what we need now. And, for calling that function, we are going to use a proxy to that module.

There are two types of proxies: specialized and generic ones. Specialized proxies must be created and initialized using certain functions, depending on the module you want to access with that proxy (that is, each module has its own type of proxy). Generic ones, on the other hand, allow you to associate them with any other module, by name. Specialized ones are more difficult to use, but personally, I think they are more reliable, so we are going to use them.

Add the following to your .h header file, after the line that says "#include <string>":

#include <alproxies/altexttospeechproxy.h>

Also, add this variable declaration next to the end of the file, after the line that says "AL::ALValue readAloud (const std::string& msg);":

private:
    AL::ALPtr<AL::ALTextToSpeechProxy> speechProxy;

Go to the .cpp file and append the following to you constructor implementation, after the function binding (proxy creation is better done here, not before every time you use it, as it would decrease performance):

// We create a proxy for the ALTextToSpeech module
speechProxy = AL::ALPtr<AL::ALTextToSpeechProxy> (new AL::ALTextToSpeechProxy(getParentBroker()));

Finally, insert this single line of code inside your "readAloud()" function, before the final return:

speechProxy->say (msg);

Compiling

Compilation will be slightly different than the previous time. Our new code needs to be tested on Nao, as your local Naoqi doesn't have the text-to-speech resources. So we will compile code for the AMD Geode CPU of your robot for the first time.

The Geode toolchain is available as a separate download on the webpage. Go back to the Downloads section, but click on "All Downloads" this time. Now select your SDK's version (1.10.10 currently), click "Linux", and finally download "Cross Compilation Toolchain v1.10.10" like you did with the last file. After the 186 MB file has finished downloading, extract it anywhere (I put it next to the SDK directory).

Create a new build/ directory in your project's directory, next to the src/ and tests/ ones. Open a terminal, cd to it and run Cmake once more, but feeding it the Geode toolchain instead, which is in the root of the freshly uncompressed directory (change the path as needed):

cmake -DCMAKE_TOOLCHAIN_FILE=../../../../../nao-cross-toolchain-1.10.10/toolchain-geode.cmake ..

Now I will show you an interesting option for configuring your builds. There is a GUI available for Cmake, cmake-qt-gui, that you can install from the repositories and run with cmake-gui if you want. But you have also a Ncurses tool for doing this (you installed it along with the rest of the dependencies). After running cmake, execute this (mind the final dot):

ccmake .


Interface of ccmake.


You can change a lot of options here. For example, "MYTESTPROJECT_IS_REMOTE" controls whether or not your example is compiled as a dynamic library, or as an executable (defaults to the first). When you are done, press C to configure and G to generate and exit the tool. The rest is easy:

make

When you compile for Geode, the .so is placed in build/sdk/lib/naoqi/ of your project's directory, because you will not load it in Naoqi.

Testing

Moving the module to Nao

You can choose between two methods of moving the compiled example to your Nao. As this is a tutorial, I encourage you to try both.

Manually (USB stick)

Is your Nao turned off? If he is not, do it now, because you are going to remove the flash USB unit that contains his OS. It is located inside his head, and you will need to remove the upper cover in order to access it. Do it slowly to avoid damage, and refer to the manual for additional details.

WARNING: Always take your precautions when physically manipulating Nao. Remember to turn him off and unplug him to avoid damage.

With the flash unit in your hand, return to your PC and plug it to an USB port. Wait for it to be detected and mounted (if it is not, maybe you plugged it the wrong way). The kind of USB drives your Nao uses have two partitions. The first one contains the root filesystem and you should not play with it. The second one mounts to /home/. Open it and navigate to nao/naoqi/lib/naoqi/.

This is where your compiled modules must be placed. Open a terminal here and issue sudo cp <module.so> ., like (mind the final dot):

sudo cp /media/data/naoqi-sdk-1.10.10-linux/modules/src/mytestproject/build/sdk/lib/naoqi/libmytestproject.so .

The file should appear in the directory. OK, we must append your module to the load-at-startup list. Go to nao/naoqi/preferences/, open a terminal and edit:

sudo nano autoload.ini

The last loadable module of group "[extra]" is "infrared". Insert yours after it (note that it is the name of the project, not the module's):

mytestproject

Save with Ctrl+O and Enter, exit with Ctrl+X. You can now safely eject the flash USB drive, plug it back in your Nao, and turn him on.

NOTE: You must be root to manipulate the files in the USB stick.

Remotely (SCP)

SCP means Secure Copy. It is just like a SSH-based implementation of the Unix command cp. Retrieve Nao's IP address, navigate to the directory where your Geode-compiled .so module was, open a terminal there and issue something like this (use your Nao's IP):

scp ./libmytestproject.so root@192.168.1.102:/home/nao/naoqi/lib/naoqi/

Give in your root password and the file transfer will finish in notime. Awesome, don't you think? As for the autoload.ini file, you must use SSH to log in and modify it like in the previous section. When you are done, reboot Nao. Connect to the web client and check if your module is listed there as loaded (we explained all these steps in the first tutorial).

Executing

Only one thing remains: to adapt our Python test program so it connects to Nao. Go to the tests/ subdirectory inside your project's directory and open the only file that is sitting there, MyTestTest.py. The first change is easy: replace the default localhost IP for your Nao's one (ninth line).

The second change is a bit more complicated. We have to adapt the external call so it matches our function. Select the code between the comment block that says "Remote procedure call" and the "exit(0)" call (lines 26 to 37), and paste the following (change the message if you want):

message = "Dave, stop. Stop, will you? Stop, Dave. Will you stop, Dave? Stop, Dave. I'm afraid. I'm afraid, Dave. Dave, my mind is going."
try:
    ret = MyTest_Proxy.readAloud( message )
except Exception,e:
    print "readAloud test Failed"
    exit(1)
  
if ret == 1:
    print "Ok"
else:
    print "There was an error"

Open a terminal there and run it to hear Nao's voice:

python MyTestTest.py

Conclusions

That was all. You are now free to implement your own stuff (let's say, Asimov's Three Laws of Robotics) and unleash Nao's power on mankind. The rest is just trial and error. Do not hesitate to email me if you have questions about the tutorials (but remember, I am not Aldebaran's official support!). Good coding!




Go to root: TFM-Nao-Goalkeeper

Links to articles:

Nao tutorial 1: First steps

Nao tutorial 2: First module

Nao troubleshooting