Re-did the methods in Position04. There now exists a method that has a coordinate as a parameter that moves the robot to that coordinate.
Also, I minimized the spin rotation. My previous code initially spins the robot to point to 0 degrees. This made for simpler code but lengthened the spin time. The code below now spins in direction that will produce the shortest rotation to point towards a destination coordinate.
Then, using Pythagorean, the robot moves from it's current position to the destination coordinate.
*************************************************************
package kgl;
import robocode.Robot;
/**
* Position 04 Robot
*
* Move to the center of the playing field, spin around in a circle, and stop.
*
* @class ICS 413
* @author Kevin Leong
* @date 9/2/10
*/
public class Position04 extends Robot{
/*
* Run Method
*/
public void run(){
//Get battlefield dimensions
double width = getBattleFieldWidth();
double height = getBattleFieldHeight();
//Assign coordinates for center and starting position 'current'
Position center = new Position(width/2, height/2);
//Go to the Center
goToCoordinate(center);
//Spin - We're Done!
double heading = getHeading();
turnRight(360 + 360 - heading);
}
/*
* Method that allows input of a coordinate and robot will go to
* that coordinate and stop
*
* @param Position p - x and y coordinate of destination
* @return Void
*/
private void goToCoordinate(Position p){
//Get Current Position
Position current = new Position(getX(), getY());
//Get current heading
double currentHeading = getHeading();
//Variable for recalibrating heading to -180 < 0 < 180
//based on turnRight()
double currentHeadingNormalized;
//Calculate the Distance and angle from the current point
//to the destination point
DistanceAngle ad = current.angleDistanceBetweenTwoPoints(p);
//Convert Heading to be between -180 and 180 only
if(currentHeading > 180){
currentHeadingNormalized = (-1) * (360 - currentHeading);
}
else
currentHeadingNormalized = currentHeading;
//Get the absolute difference between normalized heading and
//angle to destination point
double angleDeltaAbsolute = Math.abs(Math.abs(currentHeadingNormalized)
- Math.abs(ad.angle));
//Following Statements minimize spinning to point robot in position of
//destination point
//If current heading (normalized) is negative spin in the appropriate
//direction and the necessary rotation.
if (currentHeadingNormalized < 0){
//If angle and heading are both negative and angle is larger negative
if (ad.angle < currentHeadingNormalized){
turnLeft(angleDeltaAbsolute);
}
else if (ad.angle < 0){
turnRight(angleDeltaAbsolute);
}
else{
//If angle is positive then spin left or right depending on shortest
//rotation.
if (360 + ad.angle - currentHeading > 180){
turnLeft(currentHeading - ad.angle);
}
else{
turnRight(360 + ad.angle - currentHeading);
}
}
}
//Similar conditions for positive heading (normalized)
else{
if(ad.angle > currentHeadingNormalized){
turnRight(angleDeltaAbsolute);
}
else if(ad.angle > 0){
turnLeft(angleDeltaAbsolute);
}
else{
if (360 - currentHeading + ad.angle > 180){
turnLeft(currentHeading - ad.angle);
}
else{
turnRight(360 + currentHeading + ad.angle);
}
}
}
//At this point, the robot should be positioned to point towards
//the destiation point.
//Move Robot ahead the correct distance to the destination point
ahead(ad.distance);
}
}
/**
* Position Class to store position of center and starting position
* as coordinates. Also calculates:
*
* - Distance between two points
* - Angle between two points in degrees
*/
class Position{
double x;
double y;
public Position(double x, double y){
this.x = x;
this.y = y;
}
DistanceAngle angleDistanceBetweenTwoPoints(Position p){
double a = this.x - p.x;
double b = this.y - p.y;
//Calculate distance using Pythagorean Theorem
double distance = Math.sqrt(Math.pow(a, 2) + Math.pow(b,2));
//Angle variables for converting angle to degrees
double angleRadians, angleDegrees;
//Get angle in radians to center
angleRadians = Math.atan(a/b);
//Convert radians to degrees. This represents angle
//if robot starts in quadrant III
angleDegrees = 180 * angleRadians/Math.PI;
//If robot starts in quadrant I or II
if(b > 0){
angleDegrees = (180 - Math.abs(angleDegrees));
//If we are in quadrant I
if(a > 0){
angleDegrees *= -1;
}
}
return new DistanceAngle(distance, angleDegrees);
}
}
/**
* Object to hold calculations on Distance and Angle
* Calculated in the Position Class
*/
class DistanceAngle{
double distance;
double angle;
public DistanceAngle(double distance, double angle){
this.distance = distance;
this.angle = angle;
}
}
No comments:
Post a Comment