Thursday, 8 March 2012

Legolab 6

Legolab 6
Date: 08-03-12
Duration: 3 hours
Group members attending: Tore & Troels


Goal
The goal of todays exercises was to control a car with sound and light.

Plan
1. Build a robot.
2. Write and test a program, that has the bot drive faster, when the sound is louder (exitatory)
3. Make the bot go faste, the more silent is. (inhibitory)
4. Mount two light sensors and use them to steer the bot away from or towards the light source.

Execution
1. We found this (*1) nxt 5 minute bot, which was rather fast to build. We modified it a bit, so it had a turnable third wheel. The bot now looks like this:


2. We wrote a simple program, that takes a sound input and transforms it to a power output to the motors. The program can be seen here (*2). We had some touble with the car dragging to the left, even though the to motors was set to the same amount of power. We changed the motors, and got it to drive straight. Apparently one of the motors is more powerful than the other two.
When we clap the bot speeds up for a second or two and then slows down again. When we play a song, the volume of the sound is constant and the bot maintains speed.
The mapping was done like this:

public int normalizeSound() {
          int input = soundSensor.readValue();
          int output = 55 + (input * 45) / 100;
          return output;
      }

3. We just changed a few signs to accomplish this.

public int normalizeSound() {
          int input = soundSensor.readValue();
          int output = 100 - (input * 45) / 100;
          return output;
}

Since the initial value for the motor is close to 100 it becomes quite unmanageable, since it will drive fast all the time if there is no steady sound source nearby. As a result of the way we mapped it we needed a lot of noise to slow it down to a manageable level.  

4. We mounted the two light sensor as seen in the picture below:


There is about a 45 degree angle between the sensors, this will make them read more different values and the direction of the bot should be easier to control. We changed this later however, so the sensors both pointed forward.
Our two light sensors did not seem to measure the same values. Where the two values should be the same, we had a motor power difference of about 10. Testing the light sensors by themselves, we found out the normalized value read from the two sensors had a difference of about 30-40, which had a rather noticeable impact on the motor powers.
We basically just took the formulas from (*3), and the program can be seen here (*2). This program has the bot turn away from the light.
Show below are the differences between the two bots in (*3).
Bot2a: When we shine light on the left sensor, the right motor would slow down and vice versa.
Bot2b: This bots turns toward the light.


Bot2a
public int normalize(int input) {
int MIN_VALUE = 400;
int MAX_VALUE = 800;
int output = ((input - MIN_VALUE) * 100) / (MAX_VALUE - MIN_VALUE);
return output;
}

Bot2b
public int normalize(int input) {
      int MIN_VALUE = 400;
      int MAX_VALUE = 800;
      int output = ((input - MAX_VALUE) * 100) / (MIN_VALUE - MAX_VALUE);
      return output;
}


Status

We got through todays exercises and got the different vehicles to work, although we had some trouble with the motors not being equally strong, and the light sensors measuring different values, so the turns was a bit uneven. But the vehicles worked well enough despite these flaws.

We accidentally skipped a part with the one sound sensor controller. We could have had the car drive forward in some volume interval and backwards in another. Then the car might drive forward towards the sound until it became too loud, and then backwards instead. This would have the car oscillate at some distance.
We did not do the vehicle 3, but a quick thought about it is to have two sound and two light sensors. To make the bot drive towards the light we use the 2b bot, and then have claps decrease the power, so the bot turns away from the sound. Then the power to the motors would be the sum of the power from the light and the power from the sound. Or maybe have the sound add “negative power”.

references
(*1) http://www.nxtprograms.com/five_minute_bot/index.html
(*2) http://troelskristiantore.blogspot.com/2012/03/legolab-6-code.html
(*3) Notes on construction of Braitenberg's Vehicles, Chapter 1-5 of Braitenbergs book

Legolab 6 - code

One sound sensor program

import lejos.nxt.*;

public class Bot1 {
   private SoundSensor soundSensor;
   
   public Bot1() {
       soundSensor = new SoundSensor(SensorPort.S1, true);
   }
   
   public static void main(String[] args) {
       Bot1 bot = new Bot1();
       bot.botControl();
   }
   
   public void botControl() {
       while (!Button.ESCAPE.isPressed()) {
           int power = normalizeSound();
           MotorPort.B.controlMotor(power, 1);
           MotorPort.C.controlMotor(power, 1);
       }
   }
   
   public int normalizeSound() {
       int input = soundSensor.readValue();
       int output = 55 + (input * 45) / 100;
       return output;
   }
}

Bot2a - Two light sensors with the bot moving away from the light

import lejos.nxt.*;


public class Bot2a {
   private LightSensor ls1;
   private LightSensor ls2;
   
   //private int MIN;
   //private int MAX;
   
   public Bot2a() {
       ls1 = new LightSensor(SensorPort.S1, true);
       ls2 = new LightSensor(SensorPort.S2, true);
   }
   
   public static void main(String[] args) {
       Bot2a bot = new Bot2a();
       //bot.measureMIN_MAX();
       bot.botControl();
       
   }
   
   public void botControl() {
       while (!Button.ESCAPE.isPressed()) {            
           int power1 = normalize(ls1.readNormalizedValue());
           int power2 = normalize(ls2.readNormalizedValue());
           power1 = power1 + 15;
           power2 = power2 + 25;
           LCD.drawInt(power1, 0, 0);
           LCD.drawInt(power2, 0, 2);
           
           LCD.refresh();
           MotorPort.C.controlMotor(power1, 1);
           MotorPort.B.controlMotor(power2, 1);
       }
   }
   
   public int normalize(int input) {
       int MIN_VALUE = 400;
       int MAX_VALUE = 800;
       int output = ((input - MIN_VALUE) * 100) / (MAX_VALUE - MIN_VALUE);
       return output;
   }
 
}

Legolab 5

Legolab 5
Date: 01-03-12
Duration: 3 hours
Group members attending: Tore, Troels & Kristian

Goal
The goal for today is to build a legway, using the light sensor to control the distance and make the robot balance from the input.

Plan:
1. Build the new robot according to the images(*1).
2. Convert the code so it fits the new version.
3. Setup blue tooth connection between computer and robot.
4. Configure the PID constants.


Execution of the plan
1. We used the photos at the buttom of the page (*1) to build our own legway. We have used larger wheels, thinking it would be easier to balance on big wheels. With small wheels, however, it is probably easier to make small corrections in the direction. We might change wheels later. Our legway is seen in the image below:
2. This was just some simple corrections so the code can run on the new version, as seen below:

if (pid_val > 0) {
          MotorPort.B.controlMotor(power, 1);
          MotorPort.C.controlMotor(power, 1);
      }
     else {
          MotorPort.B.controlMotor(power, 2);
          MotorPort.C.controlMotor(power, 2);
      }

3. We got bluetooth working with the robot and paired it with our computer. BTCarController won’t connect to the robot, so we just manually upload the program every time we try out new values.

4. We tried to adjust the kp,ki and kd constants (from the article on PID controllers (*2)), basically just by trial and error. After a few tests, we realized that when holding the robot at the start, our arms shadowed the table, and we got a wrong value for the offset. Most times the legway would balance a few seconds, then tilt backwards.

A problem with using the light sensor as primary and only input device is that light emitted from surfaces differs a lot. On a table the light can differ from one end to another depending on the shadows and where the light source is placed. This is a problem since we measure a starting value which we use to correct the movement of the robot all the time. If the light emitted from the surface changes a lot, we can not use the start value across the table.


Status
We completed the exercises as best we could. Our robot was build according to the images (*1), but we used bigger wheels, thinking that would make it better at balancing. This however made it a little harder to make small corrections.
We had the robot balance only a few seconds before toppling over. The light sensor was too sensitive to shadows from different objects. And our constants may not have been tuned correctly, but it was a lot harder than making corrections to have the robot follow a line.
We should have used an accelerometer instead.


References:
(*1) http://www.philohome.com/nxtway/nxtway.htm
(*2) http://www.inpharmix.com/jps/PID_Controller_For_Lego_Mindstorms_Robots.html