Performance Test 3 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 69.46853775
#define DEG_PER_SECONDR 1.05
#define INCH_PER_SECOND 9.212081
#define TOLERANCE .25

//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);
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 pivotTurn(float angle, bool clockwise);
void pivotTurnBack(float angle, bool clockwise);

int main(){

  RPS.InitializeTouchMenu();
  float XPosition = RPS.X();
  float YPosition = RPS.Y();
  float Heading = RPS.Heading();
  float time;
  //while(cdsCell.Value() > .5){}

  //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(500);
      LCD.Write("DESIRED 17.3 XCOORD: ");
      LCD.WriteLine(RPS.X());
      LCD.Write("DESIRED 28.2 YCOORD: ");
      LCD.WriteLine(RPS.Y());
      LCD.Write("DESIRED 270 HEADING: ");
      LCD.WriteLine(RPS.Heading());
      Sleep(3.0);
      LCD.Clear();
  }


  while(cdsCell.Value() > 1){
      LCD.WriteLine("Waiting for start");
  }
  LCD.Clear();

  arm.SetMin(690);
  arm.SetMax(2200);
  arm.SetDegree(180);
  arm.SetDegree(0);
  gear.SetMin(621);
  gear.SetMax(2367);


  //Drive forward
  driveStraight(2);
  check_y_minus(24.6);
  LCD.WriteLine(RPS.Y());
  //Turn left
  pivotTurn(45, false);
  check_heading(347);
  LCD.WriteLine(RPS.Heading());
  //Turn Right
  LCD.WriteLine("Run into button");
  Sleep(300);
  time = TimeNow();
  while(TimeNow()-time < 7){
    if(TimeNow()-time < 3){
        rightMotor.SetPercent(0);
        leftMotor.SetPercent(80);
    }else{
        rightMotor.SetPercent(0);
        leftMotor.SetPercent(40);
    }
  }
  rightMotor.Stop();
  leftMotor.Stop();
  rightEncoder.ResetCounts();
  leftEncoder.ResetCounts();
  //Turn out of white
  pivotTurnBack(65, false);
  check_back_heading(347);
  //Reverse
  pivotTurnBack(40, true);
  check_back_heading(270);
  arm.SetDegree(180);
  //Turn right
  pivotTurn(40, true);
  check_heading(225);
  //Go Straight
  driveStraight(2);
  check_y_minus(18.9);
  //Turn
  pivotTurn(40, true);
  check_heading(180);
  //Drive straight into wrench
  driveStraight(1.5);
  check_x_minus(6.8);
  //Adjust to align w wrench
  check_heading(180);
  //Drive into wrench
  check_x_minus(6.1);
  //Lift Wrench
  arm.SetDegree(0);
  Sleep(1.0);
  //Go back
  driveStraight(-2);
  check_x_minus(12);
  //Turnright
  pivotTurnBack(45, true);
  check_back_heading(135);
  //drive forward
  driveStraight(4);
  check_x_minus(10.9);
  //turn left
  pivotTurn(80, false);
  check_heading(235);
  //turn more left
  pivotTurnBack(35, false);
  check_heading(270);
  //Drive up hill
  driveStraight(-25, 90);
  check_y_minus(42);
  //turn right
  pivotTurnBack(45, true);
  check_back_heading(225);

  driveStraightIndefinitely(-50);

  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();
}

/*
  A method that turns the robot a certain angle. Implemented
  with encoders.
/*
void pivotTurn(float angle, bool clockwise){
  float distance = angle / 360 * PI * 2 * (2 * WHEEL_BASE);
  float count = distance * ENCODER_LINES / (2.5 * PI);
  if(clockwise){
    while(leftEncoder.Counts() < count){
          leftMotor.SetPercent(60);
    }

  }else{
    while(rightEncoder.Counts() < count-2){
            rightMotor.SetPercent(60);
    }
  }
  LCD.WriteLine(leftEncoder.Counts());
  LCD.WriteLine(rightEncoder.Counts());
  leftEncoder.ResetCounts();
  rightEncoder.ResetCounts();
  rightMotor.Stop();
  leftMotor.Stop();
}

/*
  Method that drives the robot a distance at a certain speed. 
  Implemented with encoders.
*/
void driveStraight(float distance, float motorSpeed){
  float count = distance * ENCODER_LINES / (2.5 * PI);
  if(count > 0){
    while(leftEncoder.Counts() < count && rightEncoder.Counts() < count){
      leftMotor.SetPercent(motorSpeed+2);
      rightMotor.SetPercent(motorSpeed);
    }
  }else{
      count *= -1;
      while(leftEncoder.Counts() < count && rightEncoder.Counts() < count){
        leftMotor.SetPercent(-motorSpeed-7);
        rightMotor.SetPercent(-motorSpeed);
    }
  }
  rightMotor.Stop();
  leftMotor.Stop();
  leftEncoder.ResetCounts();
  rightEncoder.ResetCounts();
}

/*
  Method that drives robot a distance. Implemented with encoders.
*/
void driveStraight(float distance){
  float count = distance * ENCODER_LINES / (2.5 * PI);
  if(count > 0){
    while(leftEncoder.Counts() < count && rightEncoder.Counts() < count){
      leftMotor.SetPercent(57);
      rightMotor.SetPercent(50);
    }
  }else{
      count *= -1;
      while(leftEncoder.Counts() < count && rightEncoder.Counts() < count){
        leftMotor.SetPercent(-57);
        rightMotor.SetPercent(-50);
    }
  }
  rightMotor.Stop();
  leftMotor.Stop();
  leftEncoder.ResetCounts();
  rightEncoder.ResetCounts();
}