1   import interfaces.Controller;
2   import interfaces.AbstractRobot;
3   
4   
5   /**
6   * This class is a 3-1 net (plus bias) whos input comes from
7   * preprocessing 3 sensor inputs.
8   * The net was trained on 3 training patterns and generalises
9   * across 8 possible sets of binary inputs.
10  * see GBN3.training file for details.
11  * This robot tends to go wrong if it starts pointing the wrong
12  * way. This is because there is no training pattern to indicate
13  * how to deal with this circumstance.
14  * See GBN3 for an implementation that turns itself around, using 
15  * 4 training patterns and generalising across 16 possible sets 
16  * of binary inputs.
17  *
18  * @author Graeme Bell
19  * @see GBN3
20  */
21  
22  public class GBN4 extends Controller {
23  
24  AbstractRobot r;
25  boolean initcalled;
26  boolean running;
27  private boolean paused=false;
28  
29  private int[] sensors={Controller.SENSOR_TYPE_LIGHT,Controller.SENSOR_TYPE_LIGHT,Controller.SENSOR_TYPE_LIGHT};
30  
31  // this looks rubbish - but it will compile to run extremely fast 
32  // this is because the weights will be inlined and the inputs/outputs
33  // won't need dereferencing or array overhead.
34  
35  float sens0;
36  float sens1;
37  float sens2;
38  
39  float input0;
40  float input1;
41  float input2;
42  
43  // bias input is assumed to be +1
44  
45  float output0;
46  
47  final float weight00 = -0.896f;
48  final float weight10 = 0f;
49  final float weight20 = 0.896f;
50  final float weightb0 = 0f;
51  
52      public void run(){
53  
54          running=true;
55              
56          while (running) {
57  
58                  // get input
59                                                          
60                  sens0=r.getSensor1()/100.0f;
61                  sens1=r.getSensor2()/100.0f;
62                  sens2=r.getSensor3()/100.0f;
63  
64                  // preprocessing
65                  
66                  if (sens0>sens1 && sens1>sens2) { input0=1.0f; } else {input0=0.0f;}
67                  if (sens0<sens1 && sens1>sens2) { input1=1.0f; } else {input2=0.0f;}
68                  if (sens0<sens1 && sens1<sens2) { input2=1.0f; } else {input2=0.0f;}
69  
70                  // this could be optimised by just adding weights according to value of inputs.
71                  // want to keep it looking like an FF neural net though to avoid worried looks.
72  
73                  //Sigmoidal activation function 1.0/1.0+exp(excitation)
74  
75                  output0 = 1.0f/(1.0f+(float)(Math.exp(  weight00*input0+
76                              weight10*input1+
77                              weight20*input2+
78                              weightb0)));
79  
80                  //decide what to do.
81  
82                  if (output0<0.4) {r.right();}
83                  if (output0<0.6 && output0>=0.4) {r.forward();}
84                  if (output0>=0.6) {r.left();}
85                  
86                  try{Thread.sleep(500);}catch(Exception e){}
87           }
88      }
89  
90      
91      public void initController(AbstractRobot r) {
92  
93          this.r=r;
94          initcalled=true;
95      }
96      
97      public int[] getSensors(){
98      
99          return sensors;
100     }
101     
102     public void halt(){
103     
104         running=false;
105         r.stopMoving();
106     }
107     
108     public AbstractRobot getRobot(){
109     
110         return r;
111     }
112     
113     public GBN4() { }
114 }   
115