Social Icons

twitterfacebookgoogle plusemail

lunes, 8 de octubre de 2012

Reporte de proyecto de medio curso

A continuación presentaré los avances que se han realizado en el proyecto desde el código hasta el hardware. Antes de comenzar a explicar sería bueno recordar de que trata mi proyecto, la idea del proyecto es hacer una red neuronal que por medio de unos electrodos en el antebrazo de una persona determine los movimientos que quiere realizar en el brazo, esto se puede por medio de frecuencias que manda el cerebro hacia el brazo, y lo que se busca es interceptar esas frecuencias en el antebrazo, para poder controlar un brazo robótico aunque lo ideal sería primero simularlo.

Comparado lo propuesto con lo actual que se tiene avanzado, se están tomando en cuenta solamente un motor DC del brazo a controlar para este avance donde el brazo se mueve de 0º a 180º y de 180º a 0º.


Ahora mostaré una imágen del brazo robótico,


El sensor utilizado fue un EMG con la ayuda de un arduino y unos cables que conectan a unos electrodos que nos facilitan la lectura de datos del músculo,
 
para más información sobre que es un EMG vayan a esta página http://es.wikipedia.org/wiki/Electromiografía y para datos relacionados al sensor podrían ir a esta página

https://docs.google.com/file/d/0B8Wy2qiwirwyWnBkM09JT29LaXM/edit

donde muestra el manual de uso del mismo.

Por parte del código que nos ayuda a comunicar el brazo donde toma como salida el resultado de la red neuronal es el siguiente:

char val; // variable que tomara el valor escuchado del puerto
int ledpingreen = 13; // LED en el pin 13
//Salidas del motor shield
int E1 = 10;
int M1 = 12;
int E2 = 11;
int M2 = 13;
void setup()
{
pinMode(ledpingreen, OUTPUT);
pinMode(M1, OUTPUT);
pinMode(M2, OUTPUT);
pinMode(E1, OUTPUT);
pinMode(E2, OUTPUT);
Serial.begin(115200); // Comenzar comunicacion serial en 115200bps
}
void loop() {
val = Serial.read(); // lee y almacena en val
if(val == 'D'){ // Si se recibe D cambia la direccion del brazo
digitalWrite(ledpingreen, HIGH); // Encender led verde
digitalWrite(M2,HIGH);
digitalWrite(E1, HIGH);
digitalWrite(E2, HIGH);
Serial.println("Derecha");
delay(500);
}
if(val == 'I'){ // Si se recibe I cambia la direccion del brazo
digitalWrite(ledpingreen, HIGH); // Sigue encendido el led
digitalWrite(M1,LOW);
digitalWrite(M2,LOW);
digitalWrite(E1, HIGH);
digitalWrite(E2, HIGH);
Serial.println("Izquierda");
delay(500);
}
if(val == 'N'){ // Si recibe N deja de dar voltaje al shield
digitalWrite(ledpingreen, LOW); // Apaga el led
digitalWrite(M2,LOW);
digitalWrite(E1, LOW);
digitalWrite(E2, LOW);
Serial.println("Apagado");
delay(500);
}
}
view raw gistfile1.c hosted with ❤ by GitHub
El código es tan simple como se explica en los comentarios, entendiendo eso y el siguiente que es el que normaliza los datos de entrada del sensor pasaremos a ver el código de la red neuronal.

const int analogInPin = A0; // Analog input pin
int sensorValue = 0; // lee el valor del pin analogo
int aux = 0;
int sum = 0;
int salida = 0;
void setup() {
Serial.begin(9600); //Puerto donde enviara datos
}
//Tomara 50 datos donde se sacara su promedio para luego
//normalizar los datos entre 1 y -1 para darselo como entrada
// a la red neuronal
void loop() {
aux+=1
sensorValue = analogRead(analogInPin);
sum+=sensorValue;
Serial.print(sensorValue);
Serial.print("\t output = ");
Serial.println(outputValue);
if(aux == 50){
salida = sum / 50;
salida = ( ( 2 * ( salida / 500) ) -1);
Serial.println(salida);
salida = 0;
aux = 0;
}
}
view raw gistfile1.c hosted with ❤ by GitHub
Ahora veremos el código de la red neuronal.
from numpy import array
from sys import argv
import random
ACTIVACION = 1.0
DESACTIVACION = -1.0
TASA_DE_APRENDIZAJE = 0.05
class Neurona:
def __init__(self, dim):
self.w = self.pesos(dim) # generacion de pesos
self.e = 0.0 # error de neurona
return
#Metodo donde toma como entrada un vector de entrada y un vector de respuesta esperada
def entrena(self, entrada, respuestaDeseada):
global TASA_DE_APRENDIZAJE
self.calcula(entrada)
if self.y != respuestaDeseada: #Si no es la respuesta esperada este hace un cambio en sus pesos
self.cambio = TASA_DE_APRENDIZAJE * (respuestaDeseada - self.y) * entrada
self.w += self.cambio
return
#Genera los pesos de la neurona
def pesos(self, dim):
global ACTIVACION, DESACTIVACION
lista = list()
for i in range(dim):
lista.append(random.uniform(DESACTIVACION, ACTIVACION))
lista = array(lista)
return lista
#Nos da la respuesta esperada apartir de el vector de entrada
def calcula(self, entrada):
global ACTIVACION, DESACTIVACION
self.x = entrada
self.a = sum(self.x * self.w)
if self.a >= 0.0:
self.y = ACTIVACION
else:
self.y = DESACTIVACION
return self.y
class Capa:
#Crea una lista de neuronas dandole un tamanio de neuronas y una dimension de cada una
def __init__(self, tamanio, dim):
self.neuronas = list()
for e in xrange(tamanio):
self.neuronas.append(Neurona(dim + 1))
return
#Calcula la respuesta esperada tomando como referencia un vector de entrada
def calcula(self, entrada):
self.y = list()
entrada.append(-1.0)
entrada = array(entrada)
for neurona in self.neuronas:
self.y.append(neurona.calcula(entrada))
return self.y
#Aqui es donde realiza un backpropagation donde primero se calcula el valor de error
# de la primera capa para darselo como entrada a la siguiente capa y así sucesivamente
# llegando hasta la ultima capa cambiando sus pesos si acaso hay un error
def entrena(self, desada, siguiente):
global TASA_DE_APRENDIZAJE
if deseada is not None:
self.e = deseada - self.y
else:
self.e = 0.0
for neurona in siguiente:
self.e+= neurona.w * neurona.e
self.w += self.e * self.x * TASA_DE_APRENDIZAJE
return
class Red:
#Genera una lista de capas donde dentro de esas capas genera una lista de neuronas
#dependiendo su configuracion.
def __init__(self, archivo):
dato = open(archivo,"r")
d = dato.readlines()
dato.close()
dim = int(d.pop(0))
self.capas = list()
while len(d) > 0:
cantidad = int(d.pop(0))
self.capas.append(Capa(cantidad, dim))
dim = cantidad
return
#Nos calcula la respuesta esperada
def calcula(self, entrada):
for c in self.capas:
entrada = c.calcula(entrada)
return entrada
#Entrena las neuronas de cada capa
def entrena(self):
self.capas[-1].entrena(t,None)
n = len(self.capas) - 1
for i in n:
self.capas[n -i -1].entrena(None, self.capas[n -i])
return
def genera(dimension):
global ACTIVACION, DESACTIVACION
lista = list()
for i in range(dimension):
value = random.uniform(DESACTIVACION, ACTIVACION)
lista.append(value)
return lista
def main():
try:
red = Red(argv[1])
except:
red = Red("configuration.dat")
for i in xrange(20):
entrada = genera(4)
print entrada, red.calcula(entrada)
main()
view raw gistfile1.py hosted with ❤ by GitHub

El control de versiones del proyecto puede ser accedido a través de esta liga:


Pruebas con las neuronas:


**ACTUALIZADO** 9/10/2012 9:28AM Actividad de los commits

1 comentarios:

  1. Todo en una semana... Deberían haber comenzado el trabajo en el control de versiones desde hace mucho, o sea, cuando lo crearon. El reporte está bien, pero en el código castigo un punto por casi dos meses de inactividad. Van 10 y 9.

    ResponderEliminar