En lo relativo al montaje no voy a aburrir al lector con muchísima información, pues es muy variada la oferta que hay en internet de componentes, placas y esquemas, y muy probablemente cada uno de nosotros ya haya implementado sus propios robots con 2 motores de acuerdo a sus preferencias concretas. Yo voy a exponer cómo es mi robot, que no deja de ser una propuesta más y si estáis interesados en ver algo más en detalle pues siempre puedes ponerte en contacto para tratar cualquier duda o propuesta.
Características de mi robot Arduino 2WD:
Como podéis ver estamos hablando de un robot siguelíneas muy básico y construido con componentes más que asequibles en el mercado. El conjunto no debería sobrepasar los 20€. Y como digo hay muchas otras soluciones y kits que pueden ser perfectamente compatibles con el procedimiento que veremos a continuación. De hecho en otras entregas veremos como se puede llevar a cabo con kits comerciales como por ejemplo Makeblock.
El conexionado tampoco supone algo realmente complejo, pues ya hemos hablado de la conexión de los sensores y actuadores. Todo lo demás es alimentación y poco más. De cualquier modo, para cualquier duda tenéis el contacto en la página principal. Aunque con más tiempo iré poniéndolo casi seguro aquí.
El código final se compone, primeramente de la parte de percepción y actuación vistas en la unidad 7. A saber, la definición de las etiquetas que usaremos para identificar nuestros sensores y actuadores. Pero también tenemos la parte de los coeficientes del modelo de Regresión Final.
//Definimos las etiquetes que usaremos con los
//dispositivos de percepción y actuación (UD7)
#define SensorIzquierda 2
#define SensorDerecha 3
#define MotorDA 6
#define MotorDB 7
#define MotorDEn 11
#define MotorIA 8
#define MotorIB 9
#define MotorIEn 10
#define Speed 125
//Incluimos también en la cabecera los coeficientes
//obtenidos del modelo de regresión final (UD9)
double w[] = {2.0, 0.9999999999999996};
double c = 2.220446049250313e-16;
Seguimos con el programa y a continuación en el setup le hacemos saber a Arduino cómo vamos a usar los puertos de entrada/salida:
//Función Setup con la configuración de los dispositivos
//definidos para los bloques de percepción/actuación (UD7)
void setup() {
pinMode(MotorDA, OUTPUT);
pinMode(MotorDB, OUTPUT);
pinMode(MotorDEn, OUTPUT);
pinMode(MotorIA, OUTPUT);
pinMode(MotorIB, OUTPUT);
pinMode(MotorIEn, OUTPUT);
pinMode(SensorIzquierda,INPUT);
pinMode(SensorDerecha,INPUT);
}
A continuación incluimos las funciones que también vimos en la unidad 7 de percepción y actuación, aquellas que nos permitirán mover el robot una vez la predicción (bloque aprendizaje) haya determinado qué hacer. Estas funciones son las siguientes:
void pararMotorD() {
digitalWrite(MotorDA, LOW);
digitalWrite(MotorDB, LOW);
}
void adelanteMotorD() {
analogWrite(MotorDEn, Speed);
digitalWrite(MotorDA, HIGH);
digitalWrite(MotorDB, LOW);
}
void atrasMotorD() {
analogWrite(MotorDEn, Speed);
digitalWrite(MotorDA, LOW);
digitalWrite(MotorDB, HIGH);
}
void pararMotorI() {
digitalWrite(MotorIA, LOW);
digitalWrite(MotorIB, LOW);
}
void adelanteMotorI() {
analogWrite(MotorIEn, Speed);
digitalWrite(MotorIA, HIGH);
digitalWrite(MotorIB, LOW);
}
void atrasMotorI() {
analogWrite(MotorIEn, Speed);
digitalWrite(MotorIA, LOW);
digitalWrite(MotorIB, HIGH);
}
Es cierto que ahora podríamos crear un programa que a través de un condicional como es el caso de if, preguntara por el estado de los sensores y actuara en consecuencia sobre los motores. Pero eso sería un algoritmo y nosotros vamos a usar la predicción obtenida del bloque de aprendizaje. Por lo que incluimos en este punto la parte obtenida de la unidad 9 que va a definir el comportamiento del robot.
//Función Loop con el código procedente del aprendizaje (UD9)
//pero también del razonamiento lógico (UD8) para la toma de decisiones
void loop() {
//Data Section: To Be Coded Manually
float data[2]; //This is your feature vector. Retrive your data into this array.
data[0] = digitalRead(SensorIzquierda);
data[1] = digitalRead(SensorDerecha);
//ML Inference Section
double prediction = 0.0;
for(int i=0; i<2; i++)
{
prediction += data[i]*w[i];
}
prediction += c;
//Do something with the prediction.
switch((int)prediction) {
case 0:
/* En este caso he preferido
no hacer nada, pues así al
principio está parado hasta
que lo movemos sobre una línea,
y en caso de salirse pues ya está
girando así que genial */
break;
case 1:
adelanteMotorI();
atrasMotorD();
break;
case 2:
adelanteMotorD();
atrasMotorI();
break;
case 3:
adelanteMotorI();
adelanteMotorD();
break;
}
}
Este ya es el programa final que grabaremos en Arduino y que dependiendo de lo que lea de los sensores y el comportamiento definido a través de los coeficientes del Machine Learning seguirá la línea.
Como podemos ver, tenemos un siguelineas cuyo comportamiento obedece a un aprendizaje a través de un sencillo algoritmo de Machine Learning. Si bien estamos aún lejos de lo que es IA, ya no tenemos que programar algoritmo a algoritmo la respuesta de un robot frente al contexto definido por una serie de sensores.
Esta propuesta no deja de ser un ejemplo simple, ampliable y mejorable por supuesto, pero teniendo en cuenta la edad de nuestros estudiantes y el carácter introductorio de la materia.