viernes 2 de noviembre de 2007

Red neuronal para LeJOS MindStorm NXT

Este código es traducido de su original para el MindStorm RXC. Es un algoritmo de propagación hacia atras "Backpropagation Network". Nos tomamos el trabajo de
traducirlo para el nuevo modelo. Disfrutenlo.

El código y su explicación se encuentran en la siguiente dirección:
http://www.javaworld.com/javaworld/jw-05-2005/jw-0516-lego.html


import lejos.nxt.Button;
import lejos.nxt.LCD;
import lejos.nxt.Motor;
import lejos.nxt.SensorConstants;
import lejos.nxt.SensorPort;
import lejos.nxt.Sound;

public class AlgoritmoAprendizaje {
public static LegoMindstormBP bpn = new LegoMindstormBP();

public static void main(String args[]) throws InterruptedException
{


int i, white;
int inp[] = {0,0,0};
int out[] = {0,0};


Sound.beep();
LCD.drawString( "Train",10,10 );


// Train bpn 500 epochs, sit down and wait about 5 minutes!
for(i=0;i<500;i++) {
bpn.train(1);
LCD.drawInt( bpn.trainedEpochs,0,10);
}


SensorPort.S1.setTypeAndMode(SensorConstants.TYPE_SWITCH,
SensorConstants.MODE_BOOLEAN );

SensorPort.S2.setTypeAndMode(SensorConstants.TYPE_SWITCH,
SensorConstants.MODE_RAW );

SensorPort.S3.setTypeAndMode(SensorConstants.TYPE_LIGHT_ACTIVE,
SensorConstants.MODE_BOOLEAN );



Sound.twoBeeps();
SensorPort.S2.activate();
white = SensorPort.S2.readRawValue();


Motor.A.setPower(1);
Motor.C.setPower(1);


Sound.twoBeeps();


while( !Button.ENTER.isPressed() ) {


LCD.drawInt(SensorPort.S2.readRawValue(),0,20 );


if( SensorPort.S1.readBooleanValue() )
inp[0] = 1; // Sensor 1 on
else
inp[0] = 0; // Sensor 1 off


if( SensorPort.S2.readRawValue() > white + 50 )
inp[1] = 1; // Sensor 2 over black floor
else
inp[1] = 0; // Sensor 2 over white floor


if( SensorPort.S3.readBooleanValue() )
inp[2] = 1; // Sensor 3 on
else
inp[2] = 0; // Sensor 3 off


bpn.test( inp, out );


if( out[0] == 1 )
Motor.A.forward();
else
Motor.A.backward();


if( out[1] == 1 )
Motor.C.forward();
else
Motor.C.backward();


Thread.sleep( 500 );


} // while()


SensorPort.S2.passivate();
Motor.A.stop();
Motor.C.stop();
Sound.beep();


} // main()


} // class LMbpn





class LegoMindstormBP {


public static int data1[][] = {{0,0,0}, {1,1}};
public static int data2[][] = {{1,0,0}, {1,0}};
public static int data3[][] = {{0,0,1}, {0,1}};
public static int data4[][] = {{0,1,0}, {0,0}};


public static double input[] = {0,0,0,1};
public static double w1[][] = {{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}};
public static double hidden[] = {0,0,1};
public static double w2[][] = {{0,0}, {0,0}, {0,0}};
public static double output[] = {0,0};
public static double delta2[] = {0,0};
public static double delta1[] = {0,0,0};


public static int trainedEpochs = 0;


LegoMindstormBP() {
byte i, j;
// Initialize weights randomly between 0.1 and 0.9
for(i=0; i< w1.length; i++)
for(j=0; j< w1[i].length; j++)
w1[i][j] = Math.random()*0.8+0.1;


for(i=0; i< w2.length; i++)
for(j=0; j< w2[i].length; j++)
w2[i][j] = Math.random()*0.8+0.1;
}


public static void train(int e) {
for(int i=0; i< e; i++) {
// Call method learn with training data
learn( data1[0], data1[1] );
learn( data2[0], data2[1] );
learn( data3[0], data3[1] );
learn( data4[0], data4[1] );
trainedEpochs++;
}
}


public static void learn( int inp[], int out[] ) {
int i, j;
double sum, out_j;


// Initialize input units
for(i=0; i< inp.length; i++)
input[i] = inp[i];


// Calculate hidden units
for(j=0; j< hidden.length-1; j++) {
sum = 0;
for(i=0; i< input.length; i++)
sum = sum + w1[i][j]*input[i];


hidden[j] = 1 / ( 1 + Math.exp(-sum));
}


// Calculate output units
for(j=0; j< output.length; j++) {
sum = 0;
for(i=0; i< hidden.length; i++)
sum = sum + w2[i][j]*hidden[i];


output[j] = 1 / (1 + Math.exp(-sum));
}





// Calculate delta2 errors
for(j=0; j< output.length; j++) {
if( out[j] == 0 )
out_j = 0.1;
else if( out[j] == 1 )
out_j = 0.9;
else
out_j = out[j];
delta2[j] = output[j]*(1-output[j])*(out_j-output[j]);
}


// Calculate delta1 errors
for(j=0; j< hidden.length; j++) {
sum = 0;
for(i=0; i< output.length; i++)
sum = sum + delta2[i]*w2[j][i];


delta1[j] = hidden[j]*(1-hidden[j])*sum;
}


// Adjust weights w2
for(i=0; i< hidden.length; i++)
for(j=0; j< output.length; j++)
w2[i][j] = w2[i][j] + 0.35*delta2[j]*hidden[i];


// Adjust weights w1
for(i=0; i< input.length; i++)
for(j=0; j< hidden.length; j++)
w1[i][j] = w1[i][j] + 0.35*delta1[j]*input[i];
}


public static void test(int inp[], int out[]) {
int i, j;
double sum;


// Initialize input units
for(i=0; i< inp.length; i++)
input[i] = inp[i];


// Calculate hidden units
for(j=0; j< hidden.length-1; j++) {
sum = 0;
for(i=0; i< input.length; i++)
sum = sum + w1[i][j]*input[i];


hidden[j] = 1 / ( 1 + Math.exp(-sum));
}


// Calculate output units
for(j=0; j< output.length; j++) {


sum = 0;
for(i=0; i< hidden.length; i++)
sum = sum + w2[i][j]*hidden[i];


output[j] = 1 / (1 + Math.exp(-sum));
}


// Assign output to param out[]
for(i=0; i< output.length; i++)
if( output[i] >= 0.5 )
out[i] = 1;
else
out[i] = 0;
}
}

Convierte a tu MindStorm NXT en un reproductor de sonido

/*
*Este código reproduce los sonidos que el Lego MindStorm NXT escucha.
*Puede ser un código base para hacer cosas interesantes tales como emular
*el comportamiento de un loro para melodías...jejeje
*/
import lejos.nxt.Button;
import lejos.nxt.LCD;
import lejos.nxt.SensorPort;
import lejos.nxt.SensorPortListener;
import lejos.nxt.Sound;
import lejos.nxt.SoundSensor;



public class Canta implements SensorPortListener{

/**
* @param args
*/
String changed = "State changed";
String val = "Value:";
String oldVal = "old Value:";
String free = "Free Mem:";
SoundSensor sound = new SoundSensor(SensorPort.S1);


public static void main(String[] args) {
// TODO Auto-generated method stub

Canta canta= new Canta();
try {
canta.run();
Button.ESCAPE.waitForPressAndRelease();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
//System.out.println(e);
}

LCD.clear();
LCD.drawString("Finished", 3, 4);
LCD.refresh();


}

@Override
public void stateChanged(SensorPort source, int oldValue, int newValue) {
// TODO Auto-generated method stub
if (source == SensorPort.S2)
{
LCD.clear();
LCD.drawString(changed,0,0);
LCD.drawString(val, 0, 1);
LCD.drawInt(newValue,7,1);
LCD.drawInt(sound.readValue(), 12, 1);
LCD.drawString(oldVal, 0, 2);
LCD.drawInt(oldValue, 11, 2);
LCD.drawString(free, 0, 4);
LCD.drawInt((int)(Runtime.getRuntime().freeMemory()),10,4);
LCD.refresh();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {}
Sound.playTone(newValue, 1000);

}


}

private void run()

{
SensorPort.S2.addSensorPortListener(this);


}


}

Pon a caminar a tu Mindstorm NXT con LeJOS

/*El siguiente programa es el script para poner a caminar a tu MindStorm NXT
*cuando le presionas el Touch Sensor camina para atras...
*/

import lejos.nxt.Button;
import lejos.nxt.LCD;
import lejos.nxt.Motor;
import lejos.nxt.SensorPort;
import lejos.nxt.TouchSensor;

public class Caminar {

/**
* @param args
*/


public static void main(String[] args) {
// TODO Auto-generated method stub
Motor.B.setSpeed(200);
Motor.C.setSpeed(200);


while(!Button.ESCAPE.isPressed()){
Motor.B.forward();
Motor.C.forward();
if(SensorPort.S1.readValue()==0){
Motor.B.backward();
Motor.C.backward();
}


}

LCD.clear();
LCD.drawString("Finished", 3, 4);
LCD.refresh();
}

}