lunes, 25 de noviembre de 2013

¿Cómo empezar a construir y programar robots?

[caption id="attachment_2192" align="alignleft" width="213"]Honda Asimo Honda Asimo[/caption]

Introducción


Crear robots requiere una gran cantidad de conocimientos distintos y, dependiendo de lo sofisticado que sea el comportamiento o tareas que ha de realizar, puede ser realmente complejo y extremadamente difícil.

Los tres pilares fundamentales de la robótica son la electrónica, la mecánica y la informática; tiene otros, pero con estos tres ya podemos empezar a experimentar.

Además de conocimiento aplicable también necesitamos algunos elementos de los que partir, como motores (u otros actuadores), sensores, una computadora de pequeño tamaño, para evitar peso y consumo eléctrico, (habitualmente una SBC o microcontrolador) y una fuente de energía (batería para que sea autónomo) y algunas piezas que sustenten y mantengan unidos a todos estos elementos en sus movimientos y desplazamientos.

Estos elementos los podemos adquirir (algunos incluso fabricar)  por separado o, para facilitar la entrada a la róbótica, también los podemos adquirir de forma conjunta, como un kit.

Comparte en este foro tus dudas y comentarios

¿Qué necesito para empezar?


Sobre todo, ganas de disfrutar creando y aprendiendo.

* Adquirir unos mínimos y básicos conocimientos de:

+ electrónica o electricidad (aunque sólo sea saber distinguir voltaje e intensidad),

+mecánica (lo mínimo sería atornillar y destornillar o conectar piezas tipo Lego)

+informática (saber ejecutar un programa en un ordenador)

* Conseguir, al menos, microcontrolador (Arduino, por ejemplo), un par de motores, un sensor de distancias, unas pilas, cables y una estructura que lo soporte. El conjunto o kit básico.

Un kit, la mejor opción


Una clara ventaja de empezar con un kit es que puedes empezar YA y dedicarte a la parte fundamental (electrónica, mecánica o informática) que más te interese, porque las demás las tienes ya solucionadas; aunque en cualquier momento puedes ponerte a trabajar en cualquiera de las otras partes. Al comprar el kit, con todo el conjunto de elementos necesarios juntos, el precio además suele ser más barato.

Del más caro y complejo al más barato y sencillo

bioloid_bio_img01Bioloid: 18 potentes servomotores, 4 sensores. Ideal para humanoides, cuadrúpedos, hexápodos e incluso vehículos, y crearles software para que se comporten como seres vivos. Incluye software de programación Roboplus Tasks, también se puede programar en C, y de creación de movimientos Roboplus Motion.

Tiene un precio de unos 1000 euros. Sí, resulta algo caro, pero si dispones del dinero y de suficientes conocimientos de programación o ganas de aprender, creo que lo merece.

[caption id="attachment_76" align="alignleft" width="90"]NXT Acer Explorer con Acer NXT Acer Explorer con Acer[/caption]

Mindstorms: 2 servomotores, 1 motor, 4 sensores. Ideal para mecanismos y vehículos. Muy fácil de utilizar, pero también permite crear robots complejos. Incluye software de programacion NXT-G y, NXT es posible programarlo también en Java con Lejos y C/C++ con Osek, aún no disponible para EV3 o versiones muy preliminares.

Tiene un precio de unos 300 euros, aunque pueda parecer caro frente a otras opciones, su enorme potencial y flexibilidad en todos los aspectos (de construcción, programación y de ampliar su electrónica) lo hacen enormemente interesante.

 

[caption id="attachment_2226" align="alignleft" width="90"]Arduino robot Robot Arduino[/caption]

Vehículo basado en Arduino: 2 servomotores y los sensores con los que desees empezar. Es el más sencillo y barato, por unos 40-60 euros puedes tener lo mínimo. Ideal para profundizar en electrónica.

Se puede programar con el amigable entorno de programación Arduino.

Es el que tiene un precio más barato y que además lo puedes ir comprando por partes, a medida que vayas necesitándolas. No ofrece tanta flexibilidad como Mindstorms ni capacidad para crear robots articulados como Bioloid, pero realmente se puede aprender mucho más de lo que pueda parecer.

.

¿Y con menos dinero o sin dinero?

Por menos dinero puedes conseguir un microcontrolador tipo Arduino o sus clones, que cuestan poco más de 20 euros.

O, de forma totalmente gratuita, puedes empezar a aprender a programar en C o C++, que será muy útil para luego darle vida al robot.

¿Con qué robot empezar?


Un sencillo vehículo de dos ruedas tractoras y una libre es un buen punto de partida con el que empezar a divertirse aprendiendo.

A modo de sugerencia de un programa sencillo y cómo ir añadiéndole una mínima complejidad de comportamiento. Se puede hacer de muchísimas formas:

El típico vehículo que hacemos que evite obstáculos mediante dos sensores de contacto, uno a la derecha y otro a la izquierda.

1.- El programa más sencillo simplemente evita los obstáculos girando unos pocos grados a la izquierda cuando detecte una "colisión" en el sensor derecho, y a la izquierda cuando la detecte en el sensor derecho.

2.- Se intenta evitar el obstáculo con las mínimas maniobras posibles para seguir el rumbo establecido.

Pero si el robot se nos acaba situando en un rincón o en un "callejón sin salida" (ha de girar 180 grados o salir marcha atrás) lo más probable es que nunca logre salir por sus propios medios de ahí, ya que irá de "rebotando" del lado izquierdo al derecho y viceversa hasta que se le agoten las baterías...

3.- Añadimos un poco de "inteligencia" y complejidad. En lugar de girar siempre unos determinados grados fijos vamos a hacer que cuando detecte cierta cantidad de colisiones seguidas (en determinada cantidad de milisegundos o segundos) aumente el número de grados que girará, para así acabar consiguiendo que salga del rincón o del "callejón".

4.- Ahora el problema es que tras salir del rincón o del "callejón" cuando detecte un obstáculo va a girar mucho más de lo necesario. Pues igual que se lo dimos, grados de más a girar, se lo quitamos; a medida que pasan determinados milisegundos o segundos sin detectar colisiones iremos disminuyendo los grados a girar hasta que lleguen al valor inicial.

Realmente sólo estamos utilizando dos sensores de contacto, medición del tiempo y contador de colisiones, pero ya no es ese sencillo programa inicial.

Otro paso sería añadir un sensor de luz que hiciera al robot tender hacia la fuente de luz más intensa, evitando los obtáculos del camino, claro.

Y en el siguiente artículo...

Empezando a programar


Aprendiendo a programar con Bioloid, Mindstorms o robot basado en Arduino.

miércoles, 20 de noviembre de 2013

(I) Reading sensors connected to Robotis CM-510

cm-510 sensorsUsing the Dynamixel SDK instead of RoboPlus Tasks is not possible to query sensors connected to the CM-5xx controller. But, of course, using standard programming languages, like C++, and tools, line QT Creator or Eclipse, with its full featured IDEs and debuggers is a hugue gain.

So I created a firmware for the CM-510 which can be queried and receive commands to itself, including its sensors, or to Dynamyxel devices.

The idea is very simple:

This program running in the CM-510 receives:

- commands or queries to IDs of Dynamixel devices. These are not processed, only redirected to the Dynamixel bus only if it was received by serial port ( serial cable or zigbee). If it was received from the Dynamixel bus nothing is done.

- commands or queries to the CM-510 ID (I chose ID=200), like beep, or to the sensors connected to it. This commands and queries are processed in the CM-510, basically querying the sensors.

In both cases the answer is sent to the connection from which the query or command was received.

After power on the CM-510, you can select the mode with the 4 cursor keys as showed in a terminal connected to its serial port:

"For 'Toss mode' press (Up), for 'Device mode' (Down), for 'Device debug mode' (Left),to start press (Right)"

In the Device mode:

all the receptions and sends are through the Dynamixel bus, the CM-510 is simply another device.

In the Toss mode:

- what is received from the serial connection is sent to the Dynamixel bus or processed in the CM-510 (If sent to its ID)

-what is received from the Dynamixel bus is sent to the serial connection

Finally, the Debug mode:

is like the Device mode, but all the debug messages included in the CM-510 are sent to the serial connection.

A complete sequence with code snippets from the CM-510 program and from the code running in the other computer:

Some C++ code snippets from this example: (C# in the next post)


[sourcecode language="cpp"]
enum AX12Address //and functions implemented in the CM-510 program, like
{
ReadCM510SensorRaw = 1,
Beep = 8,
ReadCM510SensorFiltered = 4,
SetSensorValuesToFilter = 5,
...
}
[/sourcecode]

[sourcecode language="cpp"]
void doBeep()
{
cout << "Beep" << endl;
mySystem.dynamixelCommunication.sendOrder(100, AXS1_Buzzer, (byte) DO, (short) 500);
usleep (200000);
mySystem.dynamixelCommunication.sendOrder(200,MyCommunications::Beep short)5);
}
[/sourcecode]

Querying sensor:

[sourcecode language="cpp"]
void doQuerySensor()
{
int sensorPort=getSensorPort();
int value=mySystem.dynamixelCommunication.readSensorValue (200,ReadCM510SensorRaw, sensorPort);
cout << "the sensor reads: [" << value << "] " << endl << endl << endl;
}
[/sourcecode]

These command and query are processed in the CM-510:

Getting the sensor value:

[sourcecode language="c"]

int executeCM510Function()
{
...
case F_GET_SENSOR_VALUE_RAW:
values[1] = getSensorValueRaw(parameters[1]);
break;

case F_GET_SENSOR_VALUE_FILTERED:
values[1] = getSensorValueFiltered(parameters[1], sensorValuesToFilterDefined);
break;

case F_GET_TWO_DMS_SENSOR_VALUES:
parametersReceived=3;
getTwoDMSSensorsValues();
break;

case F_GET_MULTIPLE_SENSOR_VALUE:
getMultipleSensorsValues();
break;

case F_DO_SENSOR_SCAN:
values[1]= sensorScan(parameters[1]);
break;

case F_SET_VALUE_DMS1 : //set default value DMS1
DMS1=parameters[1];
break;

case F_SET_VALUE_DMS2 : //set default value DMS1
DMS2=parameters[1];
break;

case F_BEEP:
if (debugMode)
printf("executeCM510Function beep\n");
beep();
break;

case F_SET_SENSOR_VALUES_TO_FILTER:
sensorValuesToFilterDefined=parameters[1];
break;
}

return function;
}

}
...
int getSensorValueRaw(unsigned char portId)
{
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1);

setPort(portId);
//PORTA &= ~0x80;
//PORTA &= ~0x20;

//_delay_us(12); // Short Delay for rising sensor signal
_delay_us(24);
ADCSRA |= (1 << ADIF); // AD-Conversion Interrupt Flag Clear
ADCSRA |= (1 << ADSC); // AD-Conversion Start

while( !(ADCSRA & (1 << ADIF)) ); // Wait until AD-Conversion complete

PORTA = 0xFC; // IR-LED Off

//printf( "%d\r\n", ADC); // Print Value on USART

//_delay_ms(50);
_delay_ms(ReadSensorDelayMS);

return ADC;
}

[/sourcecode]

 

[sourcecode language="c"]

void beep()
{
buzzOn(100);
buzzOff();
}
[/sourcecode]

But we can do a little more with the CM-510 processor, we can do some filtering to the sensor values.

The readings from the DMS are usually somewhat erratic, so we can simply:

- discard the minimum and maximum values:

- if we take 5 more than measures, then return the average if the are more than 3, if 3 or less it

Previously we should set how many readings should be done, if not, the default number of readings are 5:

[sourcecode language="c"]
int getSensorValueFiltered(unsigned char portId, int times)
{
...
switch(function)
{
case F_GET_SENSOR_VALUE_RAW:
values[1] = getSensorValueRaw(parameters[1]);
break;

case F_GET_SENSOR_VALUE_FILTERED:
values[1] = getSensorValueFiltered(parameters[1], sensorValuesToFilterDefined);
break;

case F_GET_TWO_DMS_SENSOR_VALUES:
parametersReceived=3;
getTwoDMSSensorsValues();
break;

case F_GET_MULTIPLE_SENSOR_VALUE:
getMultipleSensorsValues();
break;

case F_DO_SENSOR_SCAN:
values[1]= sensorScan(parameters[1]);
break;

case F_SET_VALUE_DMS1 : //set default value DMS1
DMS1=parameters[1];
break;

case F_SET_VALUE_DMS2 : //set default value DMS1
DMS2=parameters[1];
break;

case F_BEEP:
if (debugMode)
printf("executeCM510Function beep\n");
beep();
break;

case F_SET_SENSOR_VALUES_TO_FILTER:
sensorValuesToFilterDefined=parameters[1];
break;
}
...
[/sourcecode]

We also can take values from multiple sensors with one query, but It will be explained in the next post...

Forums opened

As l wrote in this previous post I would like to improve your participation in this site, and, in general, the interactions between all the people who visit this forum.

So I have opened some forums to post doubts, questions, comments, suggestions or opinions about the publushed posts.

Already there are some questions and answers!

miércoles, 13 de noviembre de 2013

Creating behaviors (I)

As you may guess from the domain of this site, software souls, one of my principal interests in robotics is creating behaviors, to make robots act as if they were alive. And here comes software. But I separate two aspects, because I think that to create the behavior just coding is too much complex, even for seasoned developers, and, worse, is too much rigid and difficult to change:

- The software to create, define or configure the behavior (the same way animations are created with specific software, and even hardware, tools)

- The software embedded in the robot to control it "executing" the behavior

In addition, if we can create a really easy to use tool to define and configure behaviors, not only developers could create behaviors, but anyone that could use a computer.

This post is focused in the software embedded in the robot and the two inputs that it will receive from the behavior creator: the behavior specification. The next diagram try to show the main parts:

[caption id="attachment_2136" align="alignleft" width="300"]Creating behaviors Creating behaviors[/caption]

The embedded robot software have four main components and two interfaces:

- A configurable  behavior event generator that will be arising, internally or externally triggered, needs, wishes, and other action driving "behavior events"

- The sensor perception component that receive and process the information from the robot environment

- The motion component that control the robot motion.

- The coordination component that organize all the information to generate the movements showing its behavior.

The two interfaces uncouple the event generator from the perception and motion.

The user could use the default configuration or adjust it  to change different aspects related to its behavior, perception or motion. Just using this configuration it will act stand-alone, based on the configuration and its environment. If we want it to do any specific tasks or tasks we should supply a DSL based specification of the tasks, that will be executed but conditioned by the configured behavior.