Tuesday, March 29, 2011

Lab 6 - Harvester

Lab 6 Write-up

For lab six, we were required to find, detect and acknowledge flat, black circular objects within the playing field followed by searching for strong light sources after a sixty second time period. The goal of this was to find all ten black objects before our sixty seconds were up and we reached the light. The playing field was finite and bounded and the black circles were scattered, so we included the obstacle avoidance and wander functions written in our previous labs.
Our design was simple and easy to implement. It required two reflective sensors pointed directly at the ground under our robot for searching for the black circles to harvest. These two sensors simply looked for any change in reflected light from the surface. This change in light signified the presence of a harvestable object. The remaining sensors were kept the same from previous labs, as their utility had not changed.
In regards to the software aspect of our robot, we had the functions for obstacle avoidance and wander activated until the sixty second timer was up at which point they were turned off. The new functions for registering the reflected light did just that. They looped until some significant change in light level came about and then sent a signal to cause a beep, which acknowledged the harvestable object. At the time when the sixty seconds were up we allowed our robot to keep harvesting while searching for the light as it might get lucky and find a piece of food along the way.
This project brought about some issues with creating new processes/threads within a loop, regardless of the time between each process of thread was called. If it hadn’t been for one of the other groups already encountering this problem, it may have taken us quite a bit of time to discover the source of these problems. Once that issue was cleared up, the rest of the processes/threads seemed to communicate well together allowing a smooth running program.
We feel that our robot competed at a premium level for the competition. Since the wander function was random, it really came down to chance and whose robot had a smoother ride. Although we did not take the competition by a landslide, we are still pleased with the rankings and results.




//code
// Line Follower - Laster, Szelagoski, Niemann


//harvester code lab 6
//laster, szelagowski, niemann

// Global Variables
int MAX_LIGHT = 115;
int MIN_LIGHT = 80;

int rVal = 0;
int lVal = 0;
int bumpCtr = 0;
int flag = 1;
int wFlag = 1;
int lock = 0;

int Lmotor = 2;
int Rmotor = 0;
int Lreflect = 5;//5
int Rreflect = 2;
int Leye = 3;
int Reye = 4;
int Lbumper = 9;
int Rbumper = 10;

int line, lineThreshold;

int main()
{

// Loop For Start Waiting
while( !start_button());

printf( "Harvester\n" );

//start thread to turn off robot when off button is pressed
//start_process(stopper());

//start_process(seek());


//start thread to count for 60 seconds
start_process(count());

//start thread to avoid obstacles
start_process(avoid());

//start thread to wander around
start_process(wander());

//start thread to harvest left
start_process(eatLeft());

//start thread to harvest right
start_process(eatRight());
}


void wander()
{
float rand;
int randDir;

while(wFlag)
{
//check if robot is avoiding
if(!lock)
{
//go straight for 3 sec
motor(Lmotor, 70);
motor(Rmotor, 50);
sleep(3.0);

rand = (float)random(10) / 10.0;
randDir = random(2);

//check if robot is avoiding
if(!lock)
{
//turn right
if(randDir)
{
motor(Lmotor, 50);
motor(Rmotor, -50);
}
//turn left
else if(randDir == 0)
{
motor(Lmotor, -50);
motor(Rmotor, 50);
}
//else don't turn


//turn for random 0.5 < time < 1.5 sec sleep(rand + 0.5); } } } } void seek() { //turn till it senses light motor(Lmotor, -50); motor(Rmotor, 50); while(analog(Leye) > 95 || analog(Reye) > 95)
{
//printf("Leye= %d, Reye= %d\n", analog(Leye), analog(Reye) );
}
start_process(beeper());

off(Lmotor);
off(Rmotor);

motor(Lmotor, 100);
motor(Rmotor, 75);

while(!digital(Lbumper) && !digital(Rbumper));

off(Lmotor);
off(Rmotor);

}

void eatLeft()
{
//loop until time > 60 or off button pressed
while( 1 )
{
//get left reflective sensor value
lVal = analog(Lreflect);

//if the value is > 50 then it sensed a black dot
if( lVal > 50 )
{
//start_process(beeper());
beep();
lVal = analog(Lreflect);
//loop until it passes the dot
while( lVal > 50)
lVal = analog(Lreflect);
}

}


}

void eatRight()
{
//loop until time > 60 or off button pressed
while( 1 )
{
//get right reflective sensor value
rVal = analog(Rreflect);

//if the value is > 50 then it sensed a black dot
if( rVal > 50 )
{
//start_process(beeper());
beep();
rVal = analog(Rreflect);
//loop until it passes the dot
while( rVal > 50)
rVal = analog(Rreflect);
}

}


}

void avoid()
{
while( wFlag )
{
if (digital(Lbumper))//left
{
lock = 1;
avoidLeft();
motor(Lmotor, 70);
motor(Rmotor, 50);
}

if (digital(Rbumper))//right
{
lock = 1;
avoidRight();
motor(Lmotor, 70);
motor(Rmotor, 50);
}
lock = 0;

}
}



void avoidLeft()
{
bk(Lmotor);
bk(Rmotor);
sleep(0.25);
motor(Lmotor, 50);
motor(Rmotor, -50);
sleep(0.5);
}

void avoidRight()
{
bk(Lmotor);
bk(Rmotor);
sleep(0.25);
motor(Rmotor, 50);
motor(Lmotor, -50);
sleep(0.5);
}



void count()
{
//count till 60
sleep(60.);
//turn off wandering
wFlag = 0;
flag = 0;
lock = 1;

//turn off the motors
off(Lmotor);
off(Rmotor);

tone(500.0, 1.);
//start thread to start searching for light
start_process(seek());



}

Wednesday, March 9, 2011

Lab 5 - line follow

Nick Niemann, Keith Szelagowski, Kevin Laster


For our Lab 5 , we were required to find and detect a line, then follow the line without jumping off of it. The goal is to complete the loop as quickly as possible without jumping off of the line.  We also had to include wandering with obstacle avoidance just in case our robot would jump off the line, it would have to find the line again and complete the loop. This would then be tested in a competition amongst other CPE470 students at the University of Nevada, Reno.


Our design was simple, we mounted the two optosensors on each side of the robot as far away as possible. This allowed for less adjustment and helped with time. For our software, we would move forward until the robot encountered a reflection off of the black line. If the reflection came from the right sensor, then we would back up a bit and turn right slightly. The opposite would happen for our left sensor. The robot would back up and turn left slightly. We added the back up feature because the robot wouldn't turn sharp enough and just go off of the line. We also had another thread going at the same time to deal with going off the line. We simply just incorperated obsticle avoidance from a previous lab.



At first we had some problems with mounting the optosensors because they wouldnt stay in the right place. We then built something a little sturdier that would allow the sensor to be a bit more stable. Another problem we were facing was that our turning wasn't as sharp as we would like it to be. This was fixed by just adding the back up feature as mentioned before. The cause of the robot not turning sharp enough was because of our front wheels. The front wheels were creating friction against the robot when turning. For the next assignment we will more than likely incorperate the nubs in replace of the front wheels.

As the contest went on we felt really confident that our robot was going to perform substantially. While seeing other robots conquer at such fast speeds, we now realize we could have made great improvements to our robot to compete better. Next lab I feel that we need to modify our robots hardware and not focus so much on the software to make up for the hardware flaws. Although our robot was not the fastest, we felt as if it was really reliable for not jumping off of the line. We felt that this was the ultimate goal as other robots were jumping off of the line.

// Line Follower - Laster, Szelagoski, Niemann

// Global Variables
int MAX_LIGHT = 115;
int MIN_LIGHT = 80;
float _timer;
int RIGHT_EYE = 6;
int LEFT_EYE = 5;
int rVal = 0;
int lVal = 0;
int bumpCtr = 0;
int flag = 1;
int wFlag = 1;
int lock = 0;
int onLine = 0;

int leftMotor = 0;
int rightMotor = 1;

int Lsensor = 4;
int Rsensor = 3;
int line, lineThreshold;

// Main Function
void main()
{
    // Initialize Variables
    int time;
    int lightLeft, lightRight;
  
    // Loop For Start Waiting  
    while( !start_button());
    reset_timer();
    printf( "Line Followerv2\n" );
    start_process(lineDetect());
    //start_process(straight());
    start_process(avoid());
    start_process(stopper());
  
}

/*
void straight()
{
    while(flag)
      {
        //loop till left sensor hits while
        while(!lVal&&!rVal && !lock)
          {
            motor(leftMotor, 20);
            motor(rightMotor, 20);
        }
    }
  
}
*/

void lineDetect()
{
  
    while(flag)
      {
        lVal = analog( Lsensor );
        lVal = normalize(lVal);
      
      
        printf("lVal=%d \n", lVal);
      
        // if Rsensor>Lsesnor
        while(lVal)
          {
            //start lock
            lock = 1;
          
            // Turn left
            if(onLine)
              {
                motor(rightMotor, -25);
                motor(leftMotor, -100);
                sleep(0.1);
            }
          
            motor(rightMotor, 50);
            sleep(0.5);
            lVal = analog( Lsensor );
            lVal = normalize(lVal);
            onLine = 1;
        }
      
        rVal = analog( Rsensor );
        rVal = normalize(rVal);
      
      
        printf("rVal=%d \n", rVal);
      
        // If Rsensor>Lsensor
        while (rVal)
          {
            //start lock
            lock = 1;
          
            // Turn right
            if(onLine)
              {
                motor(leftMotor, -25);
                motor(rightMotor, -100);
                sleep(0.1);
            }
            motor(leftMotor, 50);
            sleep(0.5);
            rVal = analog( Rsensor );
            rVal = normalize(rVal);
            onLine = 1;
          
        }              
        //end lock
        lock = 0;
      
        motor(leftMotor, 100);
        motor(rightMotor, 100);
      
      
      
    }
}








// Function Definitions
void avoid()
{
    while( wFlag )
      {
        if( digital( 11 )) // Left Motor
          {
            if( timer() < 7. )
              {
                if( bumpCtr == 4 )
                  {
                    randomTurn();
                    bumpCtr=0;
                }
                else
                  {
                    avoidLeft();
                    bumpCtr++;
                }
            }
            else
              {
                avoidLeft();
                bumpCtr = 1;
                reset_timer();
            }
        }
      
        if( digital( 9 )) // Right Motor
          {
            if( timer() < 7. )
              {
                if( bumpCtr==4 )
                  {
                    randomTurn();
                    bumpCtr=0;
                }
                else
                  {
                    avoidRight();
                    bumpCtr++;
                }
            }
            else
              {
                avoidRight();
                bumpCtr=1;
                reset_timer();
            }
        }
      
    }
}

void randomTurn()
{
    int i;
    float randNum = (float)random(100)/100. + 1.5;
    int randMotor = (int)random(2);
  
    fd(0);
    fd(1);
    tone(940.0, 0.7);
    motor(randMotor, 100);
    motor((randMotor-1)*-1, -100);
    sleep(randNum);
  
}


void avoidLeft()
{
    bk(0);
    bk(1);
    sleep(0.5);
    motor(0, 100);
    motor(1, -100);
    sleep(0.7);
}

void avoidRight()
{
    bk(0);
    bk(1);
    sleep(0.5);
    motor(1, 100);
    motor(0, -100);
    sleep(0.7);
}

void reset_timer()
{
    _timer= seconds();
}

float timer()
{
    return seconds() - _timer;
}
int normalize( int light )
{
    if(light < 50)
      {
        return 0;
    }
  
    else //( light > 50)
      {
        return 1;
    }
}

void stopper()
{
    while (flag)
      {
        if (stop_button())
          {
            flag = 0;
        }
    }
}