Cadavre Exquis, The Three Libraries.
For the software connection there are three important programming components: the libraries
- The Sending library allows the head to send values to the limbs
- The Receiving library allows the limbs to receive values from the head
- The Qlearn library allows the limbs to learn how to work together and pick actions
The first two libraries are quite simple. To include one of the libraries, you have to download the right .rar file connected to this fabMoment.
However because the FabLab website doesn't allow .RAR files to be uploaded I changed the extensions to .jpeg. To open the .rar files, save the Jpegs on your computer, right click the file, go to properties and manualy change the extension back to .rar
The rars can now be extracted. This has to be done in your arduino/libraries folder on your computer. Now you can import the libraries by opening the arduino software, click sketch/import library.. If you have extracted the file in the right place the library should be listed in the menu.
However because the FabLab website doesn't allow .RAR files to be uploaded I changed the extensions to .jpeg. To open the .rar files, save the Jpegs on your computer, right click the file, go to properties and manualy change the extension back to .rar
The rars can now be extracted. This has to be done in your arduino/libraries folder on your computer. Now you can import the libraries by opening the arduino software, click sketch/import library.. If you have extracted the file in the right place the library should be listed in the menu.
SEND
After importing a library you have to create an instance of that library, for instance for the send library you create an instance as follows:
Send <name of instance>(<number of port on the arduino used to send with>);
for instance:
Send Left(4);
Now when we use the send library again, we can call it by its name Left and it will send the values using port nr 4 of the arduino. You can also create two instances using two names and two different ports, for instance a Left and a Right one.
To send a value you type:
<name of instance>.Sender(<value to be sent>);
To send a value you type:
<name of instance>.Sender(<value to be sent>);
for instance
Left.Sender(3);
Left.Sender(3);
The arduino will now send the value 3.
RECEIVE
For the receiving library the importing works the same and you create the instance in the same way, however the port now means which port is used to receive:
Receive <name of instance>(<port used to receive>);
for instance:
Receive In(3);
Receive In(3);
We now created a receiving instance called In which uses port nr 3.
To receive a value we create the following construction:
int value = In.Value();
This newly created integer will contain the value which is received. However, because the program checks the value every time this function is called, you have to create an integer which checks if the value is actually a new value:
if (value != oldValue ) {
move(value);
oldValue = value;
}
move in this statement is a new void function which uses the value to do something. The oldValue is an integer which is initiated before the void setup.
QLEARN
In order to use the Qlearning mechanism which is explained in the "Cadavre Exquis, a short introduction" post, the leg has to be able to convert the incoming states into an action. To do this it uses a State/action matrix. The different actions in a certain state have different probabilities of being chosen. After an action is chosen the leg moves, and once an evaluation comes in the leg has to use this evaluation score to create a new probability of the action which was just tried out.
However, this might sound like a whole lot of programming, but this is all done inside the Qlearn library. All we have to do is set it up, and forward all incoming data into this library.
We import the library as explained above and create an instance:
In order to use the Qlearning mechanism which is explained in the "Cadavre Exquis, a short introduction" post, the leg has to be able to convert the incoming states into an action. To do this it uses a State/action matrix. The different actions in a certain state have different probabilities of being chosen. After an action is chosen the leg moves, and once an evaluation comes in the leg has to use this evaluation score to create a new probability of the action which was just tried out.
However, this might sound like a whole lot of programming, but this is all done inside the Qlearn library. All we have to do is set it up, and forward all incoming data into this library.
We import the library as explained above and create an instance:
Qlearn <name instance>(<empty analog port>, 5,0.05);
for example:
Qlearn Qlrn(5, 5, 0.05);
Qlearn Qlrn(5, 5, 0.05);
The empty analog port is needed to generate random numbers. Without an empty analog port the random numbers will be predictable because a binary system isn't capable of randomness. However with the open port it uses the noise which is received when no sensor is attached to create a more random random number.
The 5 and 0.05 are standard values which are used to convert the evaluation score into the new probability.
After this is done we create the following program:
The 5 and 0.05 are standard values which are used to convert the evaluation score into the new probability.
After this is done we create the following program:
int value = In.Value();
if(value != oldValue ){
int act = Qlrn.pickAction(value);
move(act);
}
The value is received just as explained in the receive library above. When the value is not an old value, it is put into the pickAction function of our qlearn library. This function returns a number varying from 1 to 4. This is the action which has been chosen and this can be put into a switch:case to preform the action.
If an evaluation score is inserted, the pickAction will return a 0.
If an evaluation score is inserted, the pickAction will return a 0.


