Difference between revisions of "Darkcanuck/VelocityTest"
Jump to navigation
Jump to search
Darkcanuck (talk | contribs) (testing getNewVelocity) |
Darkcanuck (talk | contribs) (uses right version now...) |
||
Line 13: | Line 13: | ||
// init | // init | ||
− | System.out.println(" | + | System.out.println("\nDarkcanuck's VelocityTest\n"); |
− | testCase(Double.valueOf(args[0]), Double.valueOf(args[1])); | + | if (!args[0].equals("all")) { |
+ | testCase(Double.valueOf(args[0]), Double.valueOf(args[1])); | ||
+ | } else { | ||
+ | testCase(0, 6); | ||
+ | } | ||
} | } | ||
Line 23: | Line 27: | ||
int tick = 0; | int tick = 0; | ||
− | System.out.println("Starting velocity=" + velocity + " distance=" + distance | + | System.out.println("Starting velocity=" + velocity + " distance=" + distance); |
− | while (newdist > 0. | + | while ((Math.abs(newvel)>0.00001) || (Math.abs(newdist)>0.00001)) { |
newvel = getNewVelocity(newvel, newdist); | newvel = getNewVelocity(newvel, newdist); | ||
newdist -= newvel; | newdist -= newvel; | ||
tick++; | tick++; | ||
− | System.out.println(" " + tick + " velocity=" + newvel + " remain=" + newdist | + | System.out.println(" " + tick + " velocity=" + newvel + " remain=" + newdist); |
} | } | ||
System.out.println("\n"); | System.out.println("\n"); | ||
Line 34: | Line 38: | ||
− | + | private static double getNewVelocity(double velocity, double distance) { | |
// If the distance is negative, then change it to be positive and change the sign of the input velocity and the result | // If the distance is negative, then change it to be positive and change the sign of the input velocity and the result | ||
if (distance < 0) { | if (distance < 0) { | ||
Line 45: | Line 49: | ||
final double speed = Math.abs(velocity); | final double speed = Math.abs(velocity); | ||
− | // Check if we are decelerating | + | // Check if we are decelerating, i.e. if the velocity is negative. |
− | if (velocity < 0) { | + | // Note that if the speed is too high due to a new max. velocity, we must also decelerate. |
+ | if (velocity < 0 || speed > currentCommands.getMaxVelocity()) { | ||
// If the velocity is negative, we are decelerating | // If the velocity is negative, we are decelerating | ||
newVelocity = speed - Rules.DECELERATION; | newVelocity = speed - Rules.DECELERATION; | ||
Line 56: | Line 61: | ||
double accelTime = (1 - decelTime); | double accelTime = (1 - decelTime); | ||
− | // New velocity (v) = d / t, where time = 1 (i.e. 1 turn). Hence, v = d / 1 => v = d | + | // New velocity (v) = d / t, where time = 1 (i.e. 1 turn). Hence, v = d / 1 => v = d |
− | newVelocity = Math.min( | + | // However, the new velocity must be limited by the max. velocity |
− | Rules.DECELERATION * decelTime * decelTime + Rules.ACCELERATION * accelTime * accelTime, distance); | + | newVelocity = Math.min(currentCommands.getMaxVelocity(), |
+ | Math.min(Rules.DECELERATION * decelTime * decelTime + Rules.ACCELERATION * accelTime * accelTime, | ||
+ | distance)); | ||
// Note: We change the sign here due to the sign check later when returning the result | // Note: We change the sign here due to the sign check later when returning the result | ||
Line 64: | Line 71: | ||
} | } | ||
} else { | } else { | ||
− | // Else, we are not decelerating | + | // Else, we are not decelerating, but might need to start doing so due to the remaining distance |
// Deceleration time (t) is calculated by: v = a * t => t = v / a | // Deceleration time (t) is calculated by: v = a * t => t = v / a | ||
Line 84: | Line 91: | ||
if (time <= 1) { | if (time <= 1) { | ||
// When there is only one turn left (t <= 1), we set the speed to match the remaining distance | // When there is only one turn left (t <= 1), we set the speed to match the remaining distance | ||
− | newVelocity = distance; | + | newVelocity = Math.max(speed - Rules.DECELERATION, distance); |
} else { | } else { | ||
// New velocity (v) = a * t, i.e. deceleration * time | // New velocity (v) = a * t, i.e. deceleration * time | ||
Line 99: | Line 106: | ||
} | } | ||
} else { | } else { | ||
− | // Else, we | + | // Else, we need to accelerate, but only to max. velocity |
− | newVelocity = speed + Rules.ACCELERATION; | + | newVelocity = Math.min(speed + Rules.ACCELERATION, currentCommands.getMaxVelocity()); |
} | } | ||
} | } | ||
− | |||
− | |||
− | |||
// Return the new velocity with the correct sign. We have been working with the speed, which is always positive | // Return the new velocity with the correct sign. We have been working with the speed, which is always positive | ||
return (velocity < 0) ? -newVelocity : newVelocity; | return (velocity < 0) ? -newVelocity : newVelocity; | ||
− | } | + | } |
− | |||
− | |||
} | } | ||
</pre> | </pre> |
Revision as of 06:31, 15 July 2009
Some basic code to test 1.7.1.3's updated getNewVelocity() method.
The main class:
import robocode.Rules; public class VelocityTest { private static Commands currentCommands = new Commands(); public static void main(String[] args) { // init System.out.println("\nDarkcanuck's VelocityTest\n"); if (!args[0].equals("all")) { testCase(Double.valueOf(args[0]), Double.valueOf(args[1])); } else { testCase(0, 6); } } public static void testCase(double velocity, double distance) { double newvel = velocity; double newdist = distance; int tick = 0; System.out.println("Starting velocity=" + velocity + " distance=" + distance); while ((Math.abs(newvel)>0.00001) || (Math.abs(newdist)>0.00001)) { newvel = getNewVelocity(newvel, newdist); newdist -= newvel; tick++; System.out.println(" " + tick + " velocity=" + newvel + " remain=" + newdist); } System.out.println("\n"); } private static double getNewVelocity(double velocity, double distance) { // If the distance is negative, then change it to be positive and change the sign of the input velocity and the result if (distance < 0) { return -getNewVelocity(-velocity, -distance); } double newVelocity; // Get the speed, which is always positive (because it is a scalar) final double speed = Math.abs(velocity); // Check if we are decelerating, i.e. if the velocity is negative. // Note that if the speed is too high due to a new max. velocity, we must also decelerate. if (velocity < 0 || speed > currentCommands.getMaxVelocity()) { // If the velocity is negative, we are decelerating newVelocity = speed - Rules.DECELERATION; // Check if we are going from deceleration into acceleration if (newVelocity < 0) { // If we have decelerated to velocity = 0, then the remaining time must be used for acceleration double decelTime = speed / Rules.DECELERATION; double accelTime = (1 - decelTime); // New velocity (v) = d / t, where time = 1 (i.e. 1 turn). Hence, v = d / 1 => v = d // However, the new velocity must be limited by the max. velocity newVelocity = Math.min(currentCommands.getMaxVelocity(), Math.min(Rules.DECELERATION * decelTime * decelTime + Rules.ACCELERATION * accelTime * accelTime, distance)); // Note: We change the sign here due to the sign check later when returning the result velocity *= -1; } } else { // Else, we are not decelerating, but might need to start doing so due to the remaining distance // Deceleration time (t) is calculated by: v = a * t => t = v / a final double decelTime = speed / Rules.DECELERATION; // Deceleration time (d) is calculated by: d = 1/2 a * t^2 + v0 * t + t // Adding the extra 't' (in the end) is special for Robocode, and v0 is the starting velocity = 0 final double decelDist = 0.5 * Rules.DECELERATION * decelTime * decelTime + decelTime; // Check if we should start decelerating if (distance <= decelDist) { // If the distance < max. deceleration distance, we must decelerate so we hit a distance = 0 // Calculate time left for deceleration to distance = 0 double time = distance / (decelTime + 1); // 1 is added here due to the extra 't' for Robocode // New velocity (v) = a * t, i.e. deceleration * time, but not greater than the current speed if (time <= 1) { // When there is only one turn left (t <= 1), we set the speed to match the remaining distance newVelocity = Math.max(speed - Rules.DECELERATION, distance); } else { // New velocity (v) = a * t, i.e. deceleration * time newVelocity = time * Rules.DECELERATION; if (speed < newVelocity) { // If the speed is less that the new velocity we just calculated, then use the old speed instead newVelocity = speed; } else if (speed - newVelocity > Rules.DECELERATION) { // The deceleration must not exceed the max. deceleration. // Hence, we limit the velocity to the speed minus the max. deceleration. newVelocity = speed - Rules.DECELERATION; } } } else { // Else, we need to accelerate, but only to max. velocity newVelocity = Math.min(speed + Rules.ACCELERATION, currentCommands.getMaxVelocity()); } } // Return the new velocity with the correct sign. We have been working with the speed, which is always positive return (velocity < 0) ? -newVelocity : newVelocity; } }
And a support class for setting the max velocity:
import robocode.Rules; public class Commands { private static double maxVelocity = Rules.MAX_VELOCITY; public static double getMaxVelocity() { return maxVelocity; } public static void setMaxVelocity(double maxVel) { maxVelocity = maxVel; } }