Esempio n. 1
0
void apply_power(int left_power, int right_power)
{
    if (direction > 0)
    {
        drive_custom(left_power, right_power);
    }
    else
    {
        drive_custom(-right_power, -left_power);
    }
    fprintf(stderr, "left: %d right: %d", left_power, right_power);
    // sleep(0.1);
    // all_stop();
    // sleep(5);

}
Esempio n. 2
0
int turn_right_reverse_speed(int speed){
	return drive_custom(0, -speed);
}
Esempio n. 3
0
int turn_right_speed(int speed){
	return drive_custom(speed, 0);
}
Esempio n. 4
0
int pivot_right_speed(int speed){
	return drive_custom(speed, -speed);
}
Esempio n. 5
0
int turn_left_reverse_speed(int speed){
	return drive_custom(-speed, 0);
}
Esempio n. 6
0
int turn_left_speed(int speed){
	return drive_custom(0, speed);
}
Esempio n. 7
0
int pivot_left_speed(int speed){
	return drive_custom(-speed, speed);
}
Esempio n. 8
0
int drive_speed (int speed){
	return drive_custom(speed, speed);
}
Esempio n. 9
0
void approachTargetLocation(struct RoboAI* ai, int mode){
  int targetProximity = 200;
  double angleThreshold = 20;
  // The idea behind this version of approaching the ball
  // is simple: I turn and check the angle between our facing
  // and the ball. If it's decreasing, we are turning the right way;
  // if not, we start turning the opposite way.
  // This is to avoid the problem with acos: its always positive.
 
  struct vector selfToTarget, selfDirection, selfToBall, goalToBall, goalToSelf, selfToKickPos;
  struct vector selfToGoal;
  calculateInitialVectors(&selfDirection, &selfToBall, &goalToBall, &goalToSelf, ai, SELF);
  switch(mode) {
    case TO_BALL: // for chase mode, or after oriented to goal - go directly to ball
      selfToTarget.x = selfToBall.x;
      selfToTarget.y = selfToBall.y;
      break;
    case TO_KICK_POS: // we are still approaching the optimal kicking position
      selfToGoal.x = -goalToSelf.x;
      selfToGoal.y = -goalToSelf.y;

      if (calculateAngle(&selfToBall, &selfToGoal) < 5) {
        selfToTarget.x = selfToBall.x;
        selfToTarget.y = selfToBall.y;
      } else {
        calculateKickPosition(&selfToBall, &goalToBall, &goalToSelf, &selfToKickPos, ai);
        selfToTarget.x = selfToKickPos.x;
        selfToTarget.y = selfToKickPos.y;
      }
      break;
    case TO_DEFENSE: // assume defensive positions
      getInterceptPos(ai, &selfToTarget);
      break;
    default: // this should never happen, but otherwise, just go for ball
      selfToTarget.x = selfToBall.x;
      selfToTarget.y = selfToBall.y;
      break;
  }

  printf("[%d|%d] CURRENT TARGET: [%f, %f], DIST: [%f]\n", ai->st.state, mode, selfToTarget.x, selfToTarget.y, magnitude(&selfToTarget));
  // Note how the quadrant problem still exists at this point.
  // I will fix this by forcing the robot to reset the motion vector
  // whenever our angles start increasing in distance.
 
  //////////////////// ! RESET FLAGGED ANGLE ! ////////////////////
  // First, we check if the oldAngle variable is still valid.
  // If it is flagged for a renewal, we move forwards and reset it.
  if (oldAngle == -999999){
    drive_speed(35);
    oldAngle = calculateAngle(&selfToTarget, &selfDirection);
    return;
  }
  //////////////////// ! HANDLE TURNING ! ////////////////////
  // If we, instead, have a valid old angle, we must check if after
  // turning we are increasing the angle.
  double currentAngle = calculateAngle(&selfToTarget, &selfDirection);
  // printf("ANGLE: %f from %f, difference of %f\n", currentAngle, oldAngle, currentAngle - oldAngle);
  if (currentAngle > oldAngle && currentAngle > 5){
    adjustOverturn = 1;
    // There are two possible circumstances that we are concerned with.
    // a) We just jumped into a different quadrant from the motion vector.
    // b) We are really just turning away from the target.
    // Let me first address the quadrant problem first.
    //////////////////// ! QUADRANT SOLUTION ! ////////////////////
    if (attemptedQuadrantSolution < 5){
      // The solution to this is rather simple:
      // I continue turning in the direction I already am, and
      // reset the oldAngle to update it in the new quadrant.
      // IF I was indeed turning in the right direction but the
      // angle was messed up because of the bajanxed quadrants,
      // then the (currentAngle > oldAngle) boolean above would
      // then return false and we will continue on.
      printf("ATTEMPTED QUADRANT SOLUTION\n");
      if (attemptedQuadrantSolution < 1)
        pivotRobot(25);
      else if (attemptedQuadrantSolution < 2){
        oldAngle = -999999;
      }
      else if (attemptedQuadrantSolution < 3){
        drive_speed(50);
      } else {
        // drive_speed(25);
        all_stop();
      }
      // if (attemptedQuadrantSolution == 4)
        
      attemptedQuadrantSolution++;
      return;
    } else {
      //////////////////// ! CHANGE DIRECTION ! ////////////////////
      // If I got into here, I have already attempted a quadrant
      // problem solution, and thus am most likely turning in the
      // wrong direction. I will then change the direction I have
      // been turning in, and reset the attemptedQuadrantSolution
      // flag in anticipation of further quadrant problems.
      printf("CHANGED DIRECTION\n");
      toggleTurn = !toggleTurn;
      attemptedQuadrantSolution = 0;
      pivotRobot(20);
      oldAngle = currentAngle; // Store the old angle to keep checking.
      return;
    }
  } else {
    // If we reached this part of the code, that means we are actually
    // turning towards the target location. This is great! We can
    // continue turning towards the target until the angle is within
    // an acceptable range.
    if (currentAngle > angleThreshold){
      //////////////////// ! CONTINUE TURNING ! ////////////////////
      // We need to continue turning until an optimal angle is achieved.
      attemptedQuadrantSolution = 0;
      if (mode == TO_BALL) {
        printf("SLOW YO ROLL\n");
        pivotRobot(17);
      } else {
        pivotRobot(20);
      }
      
      oldAngle = currentAngle;
      return;
    } else {
      //////////////////// ! APPROACH TARGET ! ////////////////////
      // We are facing the target location within an acceptable range.
      if (magnitude(&selfToTarget) > targetProximity){
        // Let us start moving forwards if we are not within range.
        if (mode == TO_BALL) {
          if (adjustOverturn){
            adjustOverturn = 0;
            if (toggleTurn){
              drive_custom(38, 18);
            } else {
              drive_custom(18, 38);
            }
          } else {
            drive_speed(20);
          }
        } else {
          if (adjustOverturn){
            adjustOverturn = 0;
            if (toggleTurn){
              drive_custom(18 + driveRelative(magnitude(&selfToTarget)), driveRelative(magnitude(&selfToTarget)));
            } else {
              drive_custom(driveRelative(magnitude(&selfToTarget)), 18 + driveRelative(magnitude(&selfToTarget)));
            }
          } else {
            drive_speed(driveRelative(magnitude(&selfToTarget)));
          }
        }
        attemptedQuadrantSolution = 5;

        oldAngle = currentAngle;
        return;
      } else {
        if (mode == TO_DEFENSE){
          all_stop();
          return;
        }
        // We are in an acceptable range of the target!
        // Let us then increase the state of the AI directive and
        // handle the different cases for different game modes.
        ai->st.state ++;
        return;
      }
    }
  }
}