torsdag den 28. oktober 2010

lab note 7


Attendances: Carsten, Dan
Duration: 11:30 - 13:45

** Simple program
Simply set the light value to the appropriate motor value.

*** Program
motor1 = light1;
motor2 = light2

*** Results
Both motors run at full speed at all times. This is because the light
sensors are between 300 and 600 which is more than the motor's max
value of 100.

Normalizing this could result in motors going forward the darker it is
(instead of the expected of going towards the light). But we use the
API function getNormalizedValue, which has already negated the sensor
values.

** Setup
After the modifications, the robot looked as follows:

** Advanced program
We have extended the program by calculating running min and max light
values. This is used to normalize the light sensor output to the same
range of values as the motors input.

*** Program
import lejos.nxt.Button;
import lejos.nxt.LCD;
import lejos.nxt.MotorPort;
import lejos.nxt.SensorPort;
import lejos.nxt.addon.RCXLightSensor;


public class LightFollower {

private int MAXLIGHT;
private int MINLIGHT;

RCXLightSensor lightSensorLeft = new RCXLightSensor(SensorPort.S3);
RCXLightSensor lightSensorRight = new RCXLightSensor(SensorPort.S2);
MotorPort leftMotor = MotorPort.C;
MotorPort rightMotor= MotorPort.B;

private final int forward = 1,
backward = 2,
stop = 3;

int averageLeft = 0,averageRight = 0;

final int BETA = 25;

public LightFollower(){
MAXLIGHT = 0;
MINLIGHT = 1000;
while(! Button.ESCAPE.isPressed()){
int normalizedLightLeft = normalize(lightSensorLeft.getNormalizedLightValue());
int normalizedLightRight = normalize(lightSensorRight.getNormalizedLightValue());
averageLeft = average(averageLeft,normalizedLightLeft);
averageRight = average(averageRight,normalizedLightRight);
LCD.drawString("NLeft: " + normalizedLightLeft+" ", 0, 0);
LCD.drawString("NRight: " + normalizedLightRight+" ", 0, 1);
LCD.drawString("ALeft: " + averageLeft, 0, 2);
LCD.drawString("ARight: " + averageRight, 0, 3);
LCD.drawString("MaxLight:" + MAXLIGHT, 0, 4);
LCD.drawString("MinLight:" + MINLIGHT, 0, 5);
int powerToLeft = 0;
int powerToRight = 0;
if(normalizedLightLeft > averageLeft){
powerToLeft = normalizedLightLeft;
}
if(normalizedLightRight > averageRight){
powerToRight = normalizedLightRight;
}
leftMotor.controlMotor(powerToLeft, forward);
rightMotor.controlMotor(powerToRight, forward);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
}
}

int normalize(int light){
if (light > MAXLIGHT)
MAXLIGHT = light;
if (light < minlight =" light;" minlight ="="" output =" 100" output =" 0;"> 100)
output = 100;
LCD.drawString("output is: " + output, 0, 7);
return output;
}

int average(int formerAverage, int light){
int output = formerAverage + (BETA*(light - formerAverage))/100;
return output;
}

static void main(String[] args){
LightFollower lf = new LightFollower();
}

}

*** Results
The motors both ran slowly and didn't respond to small
fluctuations. Holding the robot up to a lamp would set both wheels
going full speed though. We think this is because our max/min light
values are the overall max/min instead of a running average (to adapt
to light/dark environments).

We added a bunch of debug output to see what was happening.

Some weird results of a value not being in range 0-100 despite clearly
stated in program. This was fixed by adding a extra LCD.drawstring. We
suspect this was a output error and the value was actually correct.

We initially forgot to set our minimum light value (so it was
defaulted to 0). This resulted in our average always being 0.

We had some trouble getting the average to work because we used
doubles. We fixed this by switching to using ints and multiplying then
dividing by 100.

We also forgot to set the motor values to 0 if the current light
values were below the average.

We ended up with an beta value of 0.25 (25 in our program). Which would
stabilize to a new value after 5 seconds (with 10ms delay).

We could have improved the robot further by calculating a separate
min/max value for each light sensor (one of our sensors were
noticeably different than the other).

But in the end our robot worked and could be seen to go towards/away
from light areas, depending on which sensors were connected to which
motors.