Individual Competition Source Code

#include <FEHMotor.h>
#include <FEHLCD.h>
#include <FEHIO.h>
#include <FEHUtility.h>
#include <FEHServo.h>
#include <LCDColors.h>
#include <FEHRPS.h>
#include <cmath>
#define PI 3.14159265
#define ENCODER_LINES 16
#define ENCODER_COUNT 4
#define WHEEL_BASE 3.625
#define MOTOR_CONSTANT 1
#define DEG_PER_SECOND 67.1743621
#define DEG_PER_SECONDR 1.05
#define INCH_PER_SECOND 8.5
#define TOLERANCE .25
#define TIMEOUT 4

//Create variable for servo arm
FEHServo arm(FEHServo::Servo0);
//Create variable for motors
FEHMotor leftMotor(FEHMotor::Motor0, 12);
FEHMotor rightMotor(FEHMotor::Motor1, 12);
//Create variables for encoders
AnalogEncoder leftEncoder(FEHIO::P0_0);
AnalogEncoder rightEncoder(FEHIO::P0_2);
//Create variable for servo gear
FEHServo gear(FEHServo::Servo2);
//Create variable for cdsCell
AnalogInputPin cdsCell(FEHIO::P3_7);
//Create variable for line detectors
AnalogInputPin rightSensor(FEHIO::P2_2);
AnalogInputPin centerSensor(FEHIO::P2_1);
AnalogInputPin leftSensor(FEHIO::P2_0);
float x_coord;
float y_coord;


void driveStraight(float distance);
void driveStraight(float distance, float motor);
void check_y_minus(float y);
void check_y_plus(float y);
void check_x_minus(float x);
void check_x_plus(float x);
void check_heading(float angle);
void check_back_heading(float angle);
void turn(float angle, bool clockwise);
void turnPivot(float angle, bool clockwise);
void turnPivotBack(float angle, bool clockwise);
void turnPivotBackIndefinitely(float angle, bool clockwise);
void turnIndefinitely(float angle, bool clockwise);
void turnPivotIndefinitely(float angle, bool clockwise);
void driveStraightIndefinitely(float distance);
void driveUpHillIndefinitely(float distance);

int main(){

  RPS.InitializeTouchMenu();
  float time;

  //Instantiate proper encoder Value
  //Not necessary until encoders come in
  rightEncoder.SetThresholds(2.8, 2.8);
  leftEncoder.SetThresholds(2.8, 2.8);
  
  //Wait for the user to orient robot
  while(!LCD.Touch(&x_coord, &y_coord)){
      Sleep(200);
      LCD.Write("DESIRED 18.4 XCOORD: ");
      LCD.WriteLine(RPS.X());
      LCD.Write("DESIRED 28.3 YCOORD: ");
      LCD.WriteLine(RPS.Y());
      LCD.Write("DESIRED 270 HEADING: ");
      LCD.WriteLine(RPS.Heading());
      LCD.Write("CDS Value: ");
      LCD.WriteLine(cdsCell.Value());
      Sleep(3.0);
      LCD.Clear();
  }

  //Wait for starting light
  float timeStart = TimeNow();
  while((cdsCell.Value() > 1) && ((TimeNow() - timeStart) < 30)){
      LCD.WriteLine("Waiting for start");
  }

  LCD.Clear();

  //Set servo arm values
  arm.SetMin(690);
  arm.SetMax(2200);
  arm.SetDegree(180);
  arm.SetDegree(0);
  gear.SetMin(621);
  gear.SetMax(2367);
  if (RPS.FuelType() == 1)//clockwise
  {
      gear.SetDegree(180);
  } else
  {
      gear.SetDegree(0);
  }

  //Drive forward
  driveStraightIndefinitely(2);
  check_y_minus(26);
  check_y_minus(26);//27  26.5
  LCD.WriteLine(RPS.Y());
  //Turn left
  turnPivotIndefinitely(80, false);
  /*Check heading to 1*/
  while((RPS.Heading() < 359) && (RPS.Heading() > 1)){
     rightMotor.SetPercent(40);
     leftMotor.SetPercent(0);
     Sleep(100);
     rightMotor.Stop();
     leftMotor.Stop();
     Sleep(200);
     LCD.WriteLine(RPS.Heading());
   }
  leftEncoder.ResetCounts();
  rightEncoder.ResetCounts();
  /*End of check heading*/

  //Drive over light
  driveStraightIndefinitely(5);
  check_x_plus(26.5);
  check_x_plus(26.5);
  arm.SetDegree(170);
  //If blue
  LCD.Write("CDS = ");
  LCD.WriteLine(cdsCell.Value());
  if(cdsCell.Value() > .8){
    LCD.WriteLine("BLUE");
    Sleep(500);
    driveStraightIndefinitely(-.5);
  }else{
        LCD.WriteLine("RED");
        driveStraightIndefinitely(-2.5);
    }

  turnIndefinitely(100, true);
  while(RPS.Heading() < 269 || RPS.Heading() > 271)
    check_heading(270);
  driveStraightIndefinitely(1);
  check_heading(270);
  check_y_minus(18.8);


  driveStraightIndefinitely(2);
  float time1 = TimeNow();
  while((RPS.IsDeadzoneActive() != 2) && ((TimeNow()-time1) < 8.0)){
      rightMotor.SetPercent(50);
      leftMotor.SetPercent(50);
  }
  rightMotor.Stop();
  leftMotor.Stop();
  rightEncoder.ResetCounts();
  leftEncoder.ResetCounts();

  //back out of button
  driveStraightIndefinitely(-3);
  check_y_minus(23.8);
  //double pivot to parallel with control panel
  turnIndefinitely(90, true);
  while(RPS.Heading() < 179 || RPS.Heading() > 181)
    check_heading(180);
  //drive forward a bit for clearance
   driveStraightIndefinitely(8);
   Sleep(1.0);
   check_back_heading(180);
   LCD.WriteLine("Going to 190");
   check_back_heading(190);
  //Calc angle and distance to wrench
  float x_current = RPS.X();
  float y_current = RPS.Y();
  float angle1;
  float dist1 = std::sqrt((16.9-y_current)*(16.9-y_current)+
    (9-x_current)*(9-x_current));
  for(int i = 0; i < 2; i++){
      angle1 = (std::atan((16.9-RPS.Y())/(9-RPS.X())))*180/PI;
      angle1 += 188;
      check_heading(angle1);
      LCD.WriteLine(angle1);
      driveStraightIndefinitely((dist1-.5)/2);

  }

  //Turn to face wrench
  check_heading(183.1);
  //drive into wrench
  driveStraightIndefinitely(1);
  check_x_minus(6.1);
  //lift wrench
  arm.SetDegree(10);
  Sleep(500);


  //AFTER WRENCH
  //Go back
  driveStraightIndefinitely(-2);
  check_x_minus(8.4);
  //back pivot on right wheel
  turnPivotBackIndefinitely(90, false);
  check_heading(270);
  //drive straight
  driveStraightIndefinitely(5.5);
  check_y_minus(15.7);
  //pivot turn on left wheel into jack
  turnPivotIndefinitely(80, false);
  check_heading(350);

  //pivot out of jack
  turnPivotBackIndefinitely(60,true);
  check_back_heading(270);
  //aim at final button
  turnPivotBackIndefinitely(45, true);
  check_back_heading(225);
  //drive toward button
  driveStraightIndefinitely(-1);
  //turn into button
  turnPivotBackIndefinitely(45, false);
  check_back_heading(270);
  //hit button
  driveStraightIndefinitely(-10);

  return 0;
}

/*
  Method that pivots robot in a specified direction on the back 
  wheel.
*/
void turnPivotBack(float angle, bool clockwise){
    float distance = angle / 360 * PI * 2 * (2 * WHEEL_BASE);
    float count = distance * ENCODER_LINES / (2.5 * PI);
    if(clockwise){
      while(rightEncoder.Counts() < count){
        rightMotor.SetPercent(-60);
      }
    }else{
        while(leftEncoder.Counts() < count-2){ leftMotor.SetPercent(-60); } } LCD.WriteLine(leftEncoder.Counts()); LCD.WriteLine(rightEncoder.Counts()); leftEncoder.ResetCounts(); rightEncoder.ResetCounts(); rightMotor.Stop(); leftMotor.Stop(); } /* Method that checks robots heading and adjusts with back pivots. */ void check_back_heading(float angle){ float time = TimeNow(); LCD.WriteLine("Aligning heading"); while((angle - RPS.Heading() > 2 || angle - RPS.Heading() < -2) && TimeNow()-time < TIMEOUT){ Sleep(300); if(angle - RPS.Heading() > 2){
            rightMotor.SetPercent(0);
            leftMotor.SetPercent(-40);
        }else{
            rightMotor.SetPercent(-60);
            leftMotor.SetPercent(0);
        }
        Sleep(150);
        rightMotor.Stop();
        leftMotor.Stop();
    }

    rightEncoder.ResetCounts();
    leftEncoder.ResetCounts();
}

/*
  Method that checks y-coordinate of robot facing negative-y direction.
*/
void check_y_minus(float y){
    LCD.WriteLine("Driving into negative y");
    while(y - RPS.Y() < -TOLERANCE || y - RPS.Y() > TOLERANCE){
        Sleep(300);
        if(y - RPS.Y() < -TOLERANCE){
            rightMotor.SetPercent(40);
            leftMotor.SetPercent(40);
        }else{
            rightMotor.SetPercent(-40);
            leftMotor.SetPercent(-40);
        }
        Sleep(100);
        rightMotor.Stop();
        leftMotor.Stop();
    }
    rightEncoder.ResetCounts();
    leftEncoder.ResetCounts();
}
/*
 Method that checks y-coordinate of robot facing positive-y direction. 
*/ 
void check_y_plus(float y){ 
    LCD.WriteLine("Driving into positive y");
    while(y - RPS.Y() > TOLERANCE || y - RPS.Y() < TOLERANCE){
        Sleep(100); 
        if(y - RPS.Y() > TOLERANCE){
            rightMotor.SetPercent(40);
            leftMotor.SetPercent(40);
        }else{
            rightMotor.SetPercent(-40);
            leftMotor.SetPercent(-40);
        }
        Sleep(100);
        rightMotor.Stop();
        leftMotor.Stop();
    }

    rightEncoder.ResetCounts();
    leftEncoder.ResetCounts();
}

/*
  Method that checks x-coordinate of robot facing negative-x direction.
*/
void check_x_minus(float x){
    LCD.WriteLine("Driving into negative x");
    while(x - RPS.X() < -TOLERANCE || x - RPS.X() > TOLERANCE){
        Sleep(200);
        if(x - RPS.X() < -TOLERANCE){
            rightMotor.SetPercent(40);
            leftMotor.SetPercent(40);
        }else{
            rightMotor.SetPercent(-40);
            leftMotor.SetPercent(-40); 
        }
        Sleep(100);
        rightMotor.Stop();
        leftMotor.Stop();
    }
    rightEncoder.ResetCounts();
    leftEncoder.ResetCounts(); 
} 
/* 
Method that checks x-coordinate of robot facing positive-x direction. 
*/ 
void check_x_plus(float x){ 
    LCD.WriteLine("Driving into positive x"); 
    float time = TimeNow(); 
    while(x - RPS.X() > TOLERANCE || x - RPS.X() < TOLERANCE && TimeNow() - time < 2){
        Sleep(300); 
        if(x - RPS.X() > TOLERANCE){
            rightMotor.SetPercent(40);
            leftMotor.SetPercent(40);
        }else{
            rightMotor.SetPercent(-40);
            leftMotor.SetPercent(-40);
        }
        Sleep(100);
        rightMotor.Stop();
        leftMotor.Stop();
        LCD.WriteLine(x-RPS.X());
    }

    rightEncoder.ResetCounts();
    leftEncoder.ResetCounts();
}

/*
  Method that refines the heading of the robot using pivot turns.
*/
void check_heading(float angle){
    float time = TimeNow();
    LCD.WriteLine("Aligning heading");
    while((angle - RPS.Heading() > 2 || angle - RPS.Heading() < -2) && TimeNow()-time < TIMEOUT){ Sleep(300); if(angle - RPS.Heading() > 2){
            rightMotor.SetPercent(50); //40
            leftMotor.SetPercent(0);
        }else{
            rightMotor.SetPercent(0);
            leftMotor.SetPercent(50);  //70
        }
        Sleep(100); //150
        rightMotor.Stop();
        leftMotor.Stop();
    }
    rightEncoder.ResetCounts();
    leftEncoder.ResetCounts();
}

/*
  Method that drives robot a distance. Implemented with TimeNow().
*/
void driveStraightIndefinitely(float distance){
    float seconds = distance/INCH_PER_SECOND;
    float time = TimeNow();
    if(seconds < 0){
         seconds*= -1;
         while(TimeNow() - time < seconds){
             leftMotor.SetPercent(-60);
             rightMotor.SetPercent(-60);
         }
    }else{
        while(TimeNow() - time < seconds){
            leftMotor.SetPercent(60);
            rightMotor.SetPercent(60);
        }
    }

    rightMotor.Stop();
    leftMotor.Stop();
    rightEncoder.ResetCounts();
    leftEncoder.ResetCounts();
}

/*
  Method that drives a robot uphill. Implemented with TimeNow().
*/
void driveUpHillIndefinitely(float distance){
    float seconds = distance/INCH_PER_SECOND;
    float time = TimeNow();
    if(seconds < 0){
         seconds*= -1;
         while(TimeNow() - time < seconds){
             leftMotor.SetPercent(-80);
             rightMotor.SetPercent(-80);
         }
    }else{
        while(TimeNow() - time < seconds){
            leftMotor.SetPercent(80);
            rightMotor.SetPercent(80);
        }
    }

    rightMotor.Stop();
    leftMotor.Stop();
}

/*
  Makes a point turn on a specified angle in a certain direction.
  Implemented using the TimeNow() Function.
*/
void turnIndefinitely(float angle, bool clockwise){
    float time = TimeNow();
    if(clockwise){
      float seconds = angle/(DEG_PER_SECOND)/2;
      while(TimeNow() - time < seconds){
          leftMotor.SetPercent(60);
          rightMotor.SetPercent(-60);
      }
      leftMotor.Stop();
      rightMotor.Stop();
    }else{
        float seconds = angle/DEG_PER_SECOND/2;
        while(TimeNow() - time < seconds){
          rightMotor.SetPercent(60);
          leftMotor.SetPercent(-60);
      }
      rightMotor.Stop();
      leftMotor.Stop();
    }
    leftEncoder.ResetCounts();
    rightEncoder.ResetCounts();
    rightMotor.Stop();
    leftMotor.Stop();
}

/*
  Makes a pivot turn on a specified angle in a certain direction.
  Implemented using the TimeNow() Function.
*/
void turnPivotIndefinitely(float angle, bool clockwise){
    float seconds = angle/DEG_PER_SECOND;
    float time = TimeNow();
    if(clockwise){
      while(TimeNow() - time < seconds){
          leftMotor.SetPercent(60);
          rightMotor.SetPercent(0);
      }
      leftMotor.Stop();
    }else{
      while(TimeNow() - time < seconds){
          rightMotor.SetPercent(60);
          leftMotor.SetPercent(0);
      }
      rightMotor.Stop();
    }
    leftEncoder.ResetCounts();
    rightEncoder.ResetCounts();
    rightMotor.Stop();
    leftMotor.Stop();
}