Artificial intelligence (Light follower)

Hi community! My problem is the this: I´m doing a school project on a ligthfollower robot that learns only where the light is (Basic IA), the problem is that the robot is spinning around trying to learn the light is, but never gets it. This is the code :

tomy_la_neurona.ino (3.21 KB)

1 Like

Please post a wiring diagram of your robot and explain how the steering works. Have you checked that the light sensors actually work?

Code, posted properly (please read "How to use this forum").

**
   @author  Tomás de Camino Beck
   @Inventoría Costa Rica
   @ tomas@funcostarica.org
   @version 1.0, 15/11/2015
   Simple perceptron for Bot learning
*/

#include <Servo.h>

//just the mid point for stopping the servos
#define MIDL 90
#define MIDR 90


//**************Class perceptron*************
class perceptron
{

    const float c = 0.00008;


  public:
    //arrays that hold inputs and weights
    float* inputs;
    float* weights;
    int n;

    perceptron(int ninputs) {
      n = ninputs;
      inputs = new float[n];
      weights = new float[n];
      inputs[n - 1] = 1;
      for (int i = 0; i < n; i++) {
        // The weights are picked randomly to start.
        //a trick to get values from -1 to 1
        weights[i] = (float)random(-1000, 1000) / 1000;
      }
    }

    //reset weights to random values
    void randomize() {
      for (int i = 0; i < n; i++) {
        // The weights are picked randomly to start.
        weights[i] = (float)random(-1000, 1000) / 1000;
      }
    }

    //training function
    void train(int desired, float f) {
      int guess = f;
      float error = desired - guess;
      for (int i = 0; i < n; i++) {
        weights[i] += c * error * inputs[i];
      }
    }

    //forward function
    float feedForward() {
      float sum = 0;
      for (int i = 0; i < n; i++) {
        sum += inputs[i] * weights[i];
      }

      return activate(sum);
    }


  private:
    //activation function
    int activate(float sum) {
      //regresa 1 si es positivo, -1 si negativo.
      if (sum > 0) {
        return 1;
      }
      else {
        return -1;
      }
    }



};

//*************main code***************

perceptron brainL(3);
perceptron brainR(3);

Servo servoL, servoR;


void setup()
{
  servoL.attach(8);
  servoR.attach(6);
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  randomSeed(analogRead(A0));
  brainL.randomize();
  brainR.randomize();
  Serial.begin(9600);
  //delay(5000);

}

void loop()
{

  //read light seonsors
  int l = analogRead(A0);
  int r = analogRead(A1);


  //set inputs
  brainL.inputs[0] = l;
  brainL.inputs[1] = r;
  brainR.inputs[0] = l;
  brainR.inputs[1] = r;

  //feed forward and calculate weighted sum
  int resL = brainL.feedForward();
  int resR = brainR.feedForward();

  //use this to move servos left and right
  moveLeft(resL);
  moveRight(resR);
  delay(200);//let move for some time then stop
  stopServo();
  delay(100);
  //train
  brainL.train(eval(l, r), resL);
  brainR.train(eval(r, l), resR);
  Serial.println(l);
  Serial.println(r);
  Serial.println(resL);
  Serial.println(resR);
 // Serial.println(weights);
  delay(1000);

}

//***** sensor functions******

int eval(int s1, int s2) {
  if (s1 > s2) {
    return 1;
  }
  else {
    return -1;
  }
}


//******servo movement functions ***************
void moveLeft(int d) {
  if (d > 0) {
    servoL.write(90);
  } else {
    servoL.write(180);
  }
}

void moveRight(int d) {
  if (d > 0) {
    servoR.write(90);
  } else {
    servoR.write(180);
  }
}


void stopServo() {
  servoR.write(MIDR);
  servoL.write(MIDL);

}

Not cool to put your email address in the code you want to distribute to the world!

Paul

Paul_KD7HB:
Not cool to put your someone else's email address in the code you want to distribute to the world!

Paul

Is this for sunlight? If it keeps moving around perhaps it is not registering the intensity of the light source. I briefly looked at the code and I am not sure if the area where you have inputs and weights is intended for this. I remember from doing a light sensor tutorial that the resistance from the sensor varies with light intensity. Maybe setting limits on the intensity will allow your sketch to hold a focus point for a given intensity?

Hi,
Have you got code that ONLY reads the light sensor, to check that it is working?

Have you written this code in stages, each stage a different part of the robot?
Get each individual part working then put them together.

At the moment, your code or hardware could be at fault.
If you have code for each specific part then it will be easier to debug.

Thanks.. Tom.. :slight_smile: