Sunday, February 12, 2012

Navigation... FINALLY, IT TURNS CONSISTENTLY!

During the competition, the battery had dropped off a significant amount, and that was enough to mess up my turns still.

I became eager to resolve this issue once and for all. There must be a way to compensate the motors when the battery is weaked. I then thought up a solution.

1. The power of the battery can be tested by having the robot run forward at a fixed power level for one second, and have the encoder measure the distance. When the power drops, the robot will travel a shorter distance.
2. By taking multiple measurements of varying motor power and how far the robot travels, via an encoder reading, one can gain the relationship between the motor power and the distance traveled by plotting the points in Excel. To my luck, there was a simple linear relationship. This was found to be DistanceTraveled(L+R) = 4.13*motorPower

3. To produce a perfect 90 degree turn, the values for the encoder and motor values are perfectly set for a specific battery level. So if I make sure the motor is always outputting the same strength, then my robot will turn consistently. I do a gauge of how strong the battery is using step 1. I then set the optimal values for a perfect 90 degree turn. This will be my reference point. Then using the equation for step two, I can compensate the motors to always have the same power no matter how strong the battery is.


This worked beautifully. In my test, I made 300 the reference point for the encoder calibration value. With the weakened battery, it only traveled 272 in that same second. Then with a second powerCompensated run, it shows that I was able to get it back to 301. 



This made the motors turn FAR more consistently during battery changes. There were still a few times it'd be off due to the erraticness of the motors. But I adjusted the power compensation factor so that sometimes it'd overshoot it and sometimes it'd undershoot it so that it averages itself out. I was now able to run multiple turns with much different battery values and still have it turn near perfectly, consistently.

SUCCESS!

Saturday, February 11, 2012

Navigation Continued...

So why does the robot not turn consistently the same time, everytime? I sought to find out.
Here are the reasons I came up with.

1. The voltage drop when the battery gets drained makes the motors weaker
2. Both motors should be turning equal amounts when turning in place, but it's very difficult to get the motors to do this consistently no matters what motor power values are used.

In realizing two, it occurred to me that the encoder should be all that is necessary to get both wheels to turn the same amount. I then tried to devise a code that can do this. I figured that I can take the difference of the encoder values between the left and right side, and use this to power the weaker motor. Essentially this will give the weaker motor a boost until both sides are turning equally, then the power would diminish.

I was able to achieve this with two lines of code.

  int delta;
  delta = SensorValue[leftEncoder] - SensorValue[rightEncoder];
  motor[motorR] = 55;
  motor[motorL] = 55 + delta;



Sucess! Both sides turns evenly during a turn.

Testing this gave me consistent turns! I tested a left turn 25 times and it turned a perfect 90 degrees every time.

Friday, February 10, 2012

Navigation continued.....

After yesterday's failed attempt at making a good straightening contraption, I set out to think of a new plan today. I thought the other method to do this is to make sure the robot was equidistant to the wall during the runs down the aisles. This can be done easily by mounting an ultrasonic sensor sideways. However, I needed the ultrasonic sensor to determine where to turn as well. So the decision was to use a servo to swivel the ultrasonic sensor sideways or forwards when needed.

I finished writing the code for this but the program crashed before I had a chance to save. But when testing it out, it was finnicky and would sometimes compensate the wrong direction. This was due to the sonar sometimes giving faulty readings or updating slowly. It felt like an unreliable means to make something unreliable more reliable.

Thursday, February 9, 2012

Navigation Continued....

Today, after testing out the code yesterday, I fully realized the challenge of having the robot turn consistently every time.

To tackle this, I decided two ultrasonic sensors can be used in the front to compare the two distances in front of them to make sure they're level. 

Programming this would probably involve that if one sensor value was bigger than the other, I should have one motor turn faster than the other to have it turn back into the correct direction. 

void stopstraighten()
{
  unsigned byte SonarValueL;
  SonarValueL = SensorValue[sonarL];
  unsigned byte SonarValueR;
  SonarValueR = SensorValue[sonarR];
  while(SonarValueR == SonarValueL);

  {
    motor[motorR] = 0;
    motor[motorL] = 0;
    wait1Msec(200);
  }
}

task main()
{
  while(1 == 1)
  {

    unsigned byte SonarValueL;
        unsigned byte SonarValueR;
    SonarValueL = SensorValue[sonarL];
    SonarValueR = SensorValue[sonarR];
    //straighten left

    while(abs(SensorValue[sonarR] - SensorValue[sonarL]) != 0)
    if (SensorValue[sonarR] < SensorValue[sonarL])
    {
      motor[motorR] = 40;
      motor[motorL] = -40;
          wait1Msec(30);
    motor[motorR] = 0;
    motor[motorL] = 0;
    wait1Msec(80);
    }
    //straighten right
    //SonarValueL = SensorValue[sonarL];
    //SonarValueR = SensorValue[sonarR];
    else //while(SonarValueR < SonarValueL)
    {
      motor[motorR] = -40;
      motor[motorL] = 40;
          wait1Msec(30);
    motor[motorR] = 0;
    motor[motorL] = 0;
    wait1Msec(80);
    }

  }
    motor[motorR] = 0;
    motor[motorL] = 0;
    wait10Msec(800000000);
}


However, I had difficulty with this design in the end. Since the ultrasonic sensor can only take readings in increments of an inch, there can still be great variability in alignment. 

Wednesday, February 8, 2012

Navigation

Today I started working on the navigation. I first had it navigate to the first room via the encoder and to stop in front of the flame.

Next I decided an overall strategy for navigation. It was going to use the ultrasonic sensor to determine the points to stop and turn. It was going to enter the closest room first. Using the schematic diagram, I determined the distances for each of the runs and translated it into sonar or encoder values.


Navigate to Room and EXTINGUISH

SUCCESS! With the efforts to install a fan last night and to tweak the design, the robot is now a functional fire extinguishing machine!

A 120mm computer fan was installed to HUFF AND PUFF comparable to the big bad wolf. It will blow as hard as it will suck.

A pink fan was specifically chosen to make enemies underestimate its true power.

This mean, pink, flame extinguishing machine was then instructed to navigate into ROOM 1 by using its encoders and run its flame finding program... and subsequently HUFF AND PUFF.


Tuesday, February 7, 2012

Ultrasonic and flame sensors... SYNERGIZE!

So the past two days, I got the flame sensor to detect the flame and have the robot move towards it. Then I had the ultrasonic sensor stop in front of a wall.

Today I put these two commands together so that the robot would follow the flame indefinitely until it stops two inches away from it.

void orientflame()
{
  while(SensorValue[flameR] < 500)
  {
    motor[motorR] =  40;
    motor[motorL] = -40
    wait1Msec(30);
    motor[motorR] = 0;
    motor[motorL] = 0;
    wait1Msec(20);
  }
}

void stopdistance(int distance)
{
  unsigned byte SonarValue;
  SonarValue = SensorValue[sonar];
  if((SonarValue < distance)
  {
    motor[motorR] = 0;
    motor[motorL] = 0;
    wait1Msec(200);
  }
}

task main()
{
  while(1==1)
  {
    orientflame();
      motor[motorR] = 40;
      motor[motorL] = 40;
  stopdistance(3);
  }
}