Thursday, October 30, 2008

Lesson 7

Todays lesson is to make simple vehicles, which react to light or sound levels in the environment.


We will work with 3 different vehicles as shown below:
Vehicle 1: Have one sensor and the value measured value is used to control the speed of the vehicle. In this case the more light the faster the vehicle drives.
Vehicle 2a: Have 2 sensors, which makes turning the vehicle possible. When the sensors is configured as this, the vehicle will turn away from high measurements.
Vehicle 2b: Have 2 sensors in a crossed configuration. When the sensors is configured as this, the vehicle will turn toward higher measurements.


One light sensor and one motor
In this part we made the speed of the motor depend on the light level measured by the light sensor. The physical construction consisted of the sensor, the nxt and the motor. So we can see the motor turning at different speed when pointing the sensor i different directions.
As light sensor we used the RCX light sensor, because we have 2 of them, and we will need 2 in one of the later parts.
The light sensor measure the levels i percentage, so the values returned is between 0 and 100. The motor speed is also set as a value between 0 and 100. So the first implementation the value was written directly from the sensor to the motor.
The measured light levels were so small that the motor was barely turning with most light we could find in the room.
So we changed the code a little, so it wrote the light level in the display and the set the speed level of the motor to 2 times the light level.
This experiment went well, the motor was changing speed as the sensor was pointed in direction of different light levels. At the same time we could see that the sensor was returning values between 20 and 40, from the different light levels in the room.
With light levels at 20, the motor was barely turning, so the motor don't turn with values below 40.

The code used was:
---------------------------------------------------------------------------------------------
import lejos.nxt.*;
public class simpleVehicles {
public static void main (String[] aArg)
throws Exception {
RCXLightSensor ls = new RCXLightSensor(SensorPort.S1);

int lightlevel = 0;

while (! Button.ESCAPE.isPressed())
{
lightlevel = ls.readValue();
MotorPort.A.controlMotor(2 * lightlevel, 1);

LCD.clear();
LCD.drawInt(lightlevel, 0, 0, 0);
LCD.refresh();
}
} }
---------------------------------------------------------------------------------------------

2 light sensors and 2 motors - Straight
In this experiment we have to build a car that drives away from the light. (the 2a car).

To this experiment we build the car as instructed in the LEGO Mindstorms Education NXT Base Set 9797 manual.

The light sensor is chosen because it is the most appopriate sensor. The sound sensor can't be used because the values can't be sampled at the same time and the different between the measurement may be to small or even wrong.

First experiment we just extended the code from above so it supported 2 sets of sensors and motors.

Code:
---------------------------------------------------------------------------------------------
import lejos.nxt.*;
public class simpleVehicles {

public static void main (String[] aArg)
throws Exception {

RCXLightSensor lr = new RCXLightSensor(SensorPort.S1);

RCXLightSensor ll = new RCXLightSensor(SensorPort.S2);

int lightLevelRight = 0;

int lightLevelLeft = 0;


while (! Button.ESCAPE.isPressed())
{
lightLevelRight = lr.readValue();
lightLevelLeft = ll.readValue();

MotorPort.A.controlMotor(2 * lightLevelRight, 1);
MotorPort.B.controlMotor(2 * lightLevelLeft, 1);

LCD.clear();
LCD.drawInt(lightLevelRight, 0, 0, 0);

LCD.drawInt(lightLevelLeft, 0, 0, 1);
LCD.refresh();
}
} }
---------------------------------------------------------------------------------------------

It turns away from light, so it's working. But because we use the old RCX sensors we can't turn the light of in the sensors without turning the sensors of, so when it comes near a surface it react to the reflection of the sensor light. (We tried to turn the light off, but couldn't do it without turning the hole sensor off).

2 light sensors and 2 motors - Crossed
In these experiments we use the same code as above, but cross the sensors so the left measurement controls motor A and the right measurement controls motor B.

The result is shown in the video below, where you can see the vehicle turn toward the light and when it comes to the shadow of the door it stops.



A problem with this solution is the low measurements made in darkness, so if the vehicle is placed in a vary dark area the vehicle won't drive anywhere.
To change this we made the vehicle drive fast in the darkest areas and slow in the brightest. To do this we change the code to (This is almost like replacing the + with - in figure at the top and because of this the vehicle is configured as 2a with -, so it turns toward light):
---------------------------------------------------------------------------------------------
MotorPort.A.controlMotor(100 - lightLevelRight, 1);
MotorPort.B.controlMotor(100 - lightLevelLeft, 1);
---------------------------------------------------------------------------------------------

This was working fine, but at we could conclude that the sensors wasn't calibrated, so one of them was measuring a bit more than the other, so the vehicle was turning i darkness. In the darkness it was vary clear to see, but it was invisible in the bright areas.

Normalized light sensor
We tried to make a normalized light sensor, so only the range of measured values was used. This was done with the code below:

---------------------------------------------------------------------------------------------
import lejos.nxt.*;

public class simpleVehicles {
public static void main (String[] aArg)
throws Exception
{
normalizedLightSensor lr = new normalizedLightSensor(SensorPort.S1);
normalizedLightSensor ll = new normalizedLightSensor(SensorPort.S2);

int lightLevelRight = 0;
int lightLevelLeft = 0;

while (! Button.ESCAPE.isPressed())
{
lightLevelRight = lr.readValue();
lightLevelLeft = ll.readValue();
MotorPort.A.controlMotor(lightLevelRight, 1);
MotorPort.B.controlMotor(lightLevelLeft, 1);
LCD.clear();
LCD.drawInt(lightLevelRight, 0, 0, 0);
LCD.drawInt(lightLevelLeft, 0, 0, 1);
LCD.refresh();
}
}
}
---------------------------------------------------------------------------------------------
import lejos.nxt.*;

public class normalizedLightSensor {
private RCXLightSensor ls;
private int lightlevel = 0;
private int MaxLight = 0;
private int MinLight = 100;

public normalizedLightSensor(SensorPort p)
{
ls = new RCXLightSensor(p);
}

public int readValue()
{
lightlevel = ls.readValue();
if(lightlevel < minlight =" lightlevel;"> MaxLight)
MaxLight = lightlevel;

lightlevel = (lightlevel - MinLight);
lightlevel = lightlevel * 100 /(MaxLight - MinLight);
return lightlevel;
}
}
---------------------------------------------------------------------------------------------
The max and min values measured is remembered from the start of execution to the end.

When we execute the program above we get an exception. And we ran out of time to debug it.

If we had it working, the next step would be to normalize over a shorter period and maybe normalize the values to the motor, because the motor ain't driving until it gets values above 40.

No comments: