Difference between revisions of "User:Positive/Optimal Velocity"
Jump to navigation
Jump to search
(Created page with 'To not clutter up the Talk:Robocode/Game Physics page: I believe this is the correct getClosestReachableVelocityToVelocity function (feel free to comment): <pre> double get…') |
(Posted results) |
||
Line 54: | Line 54: | ||
} | } | ||
} | } | ||
+ | </pre> | ||
+ | |||
+ | getMaxVelocity function by Voidious: | ||
+ | <pre> | ||
+ | double getMaxVelocity(double distance) | ||
+ | { | ||
+ | long decelTime = decelTime(distance); | ||
+ | double decelDist = (decelTime / 2.0) * (decelTime-1) // sum of 0..(decelTime-1) | ||
+ | * Rules.DECELERATION; | ||
+ | |||
+ | return ((decelTime - 1) * Rules.DECELERATION) + | ||
+ | ((distance - decelDist) / decelTime); | ||
+ | } | ||
+ | |||
+ | long decelTime(double distance) { | ||
+ | long x = 1; | ||
+ | do { | ||
+ | // (square(x) + x) / 2) = 1, 3, 6, 10, 15... | ||
+ | if (distance <= ((square(x) + x) / 2) * Rules.DECELERATION) { | ||
+ | return x; | ||
+ | } | ||
+ | x++; | ||
+ | } while (true); | ||
+ | } | ||
+ | |||
+ | long square(long i) { | ||
+ | return i * i; | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | The getNewVelocity function: | ||
+ | <pre> | ||
+ | double getNewVelocity(double velocity, double distance) { | ||
+ | if(distance<0) | ||
+ | return -getNewVelocity(-velocity,-distance); | ||
+ | double highestVelocity = getMaxVelocity(distance); // highest velocity without overshooting | ||
+ | double wantedVelocity = Math.min(highestVelocity,8.0); | ||
+ | // the actually wanted velocity by the robot is the highest possible, | ||
+ | // limited by what the robot set by the setMaxVelocity command | ||
+ | return getClosestReachableVelocityToVelocity(velocity, wantedVelocity); | ||
+ | // return whatever is closest to that velocity | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | Simulator: | ||
+ | <pre> | ||
+ | |||
+ | public void simulate() | ||
+ | { | ||
+ | double currentVelocity = 8.0; | ||
+ | double distanceRemain = -2.0; | ||
+ | while(distanceRemain!=0.0 || currentVelocity!=0.0) | ||
+ | { | ||
+ | out.println("velocity = "+currentVelocity+"; distance="+distanceRemain); | ||
+ | currentVelocity = getNewVelocity(currentVelocity,distanceRemain); | ||
+ | distanceRemain -=currentVelocity; | ||
+ | } | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | == Results == | ||
+ | |||
+ | StartVelocity = 0.0; StartDistance = 6.0; | ||
+ | <pre> | ||
+ | velocity = 0.0; distance=6.0 | ||
+ | velocity = 1.0; distance=5.0 | ||
+ | velocity = 2.0; distance=3.0 | ||
+ | velocity = 2.5; distance=0.5 | ||
+ | velocity = 0.5; distance=0.0 | ||
+ | </pre> | ||
+ | StartVelocity = 0.0; StartDistance = 10; | ||
+ | <pre> | ||
+ | velocity = 0.0; distance=10.0 | ||
+ | velocity = 1.0; distance=9.0 | ||
+ | velocity = 2.0; distance=7.0 | ||
+ | velocity = 3.0; distance=4.0 | ||
+ | velocity = 3.0; distance=1.0 | ||
+ | velocity = 1.0; distance=0.0 | ||
+ | </pre> | ||
+ | StartVelocity = -1.9; StartDistance = 10; | ||
+ | <pre> | ||
+ | velocity = -1.9; distance=10.0 | ||
+ | velocity = 0.10000000000000009; distance=9.9 | ||
+ | velocity = 1.1; distance=8.8 | ||
+ | velocity = 2.1; distance=6.700000000000001 | ||
+ | velocity = 3.1; distance=3.600000000000001 | ||
+ | velocity = 2.8000000000000007; distance=0.8000000000000003 | ||
+ | velocity = 0.8000000000000007; distance=-4.440892098500626E-16; | ||
+ | velocity = -4.440892098500626E-16; distance=0.0 | ||
+ | </pre> | ||
+ | StartVelocity = 8.0; StartDistance = -2.0; | ||
+ | <pre> | ||
+ | velocity = 8.0; distance=-2.0 | ||
+ | velocity = 6.0; distance=-8.0 | ||
+ | velocity = 4.0; distance=-12.0 | ||
+ | velocity = 2.0; distance=-14.0 | ||
+ | velocity = -0.0; distance=-14.0 | ||
+ | velocity = -1.0; distance=-13.0 | ||
+ | velocity = -2.0; distance=-11.0 | ||
+ | velocity = -3.0; distance=-8.0 | ||
+ | velocity = -4.0; distance=-4.0 | ||
+ | velocity = -3.0; distance=-1.0 | ||
+ | velocity = -1.0; distance=0.0 | ||
+ | </pre> | ||
+ | StartVelocity = 5.0; StartDistance = 40.0; | ||
+ | <pre> | ||
+ | velocity = 5.0; distance=40.0 | ||
+ | velocity = 6.0; distance=34.0 | ||
+ | velocity = 7.0; distance=27.0 | ||
+ | velocity = 8.0; distance=19.0 | ||
+ | velocity = 7.75; distance=11.25 | ||
+ | velocity = 5.75; distance=5.5 | ||
+ | velocity = 3.75; distance=1.75 | ||
+ | velocity = 1.75; distance=0.0 | ||
</pre> | </pre> |
Revision as of 20:34, 15 July 2009
To not clutter up the Talk:Robocode/Game Physics page:
I believe this is the correct getClosestReachableVelocityToVelocity function (feel free to comment):
double getClosestReachableVelocityToVelocity(double currentVelocity,double wantedVelocity) { // this function assumes wantedVelocity<=Rules.MAXVELOCITY // with this function you can basically assume setAhead(Infinity) or setAhead(-Infinity) // was called, and you determine the next velocity based on the max velocity // set by the robot. For example, if the current velocity is 0 and the max velocity // set was 4.0, it would return 1.0. If the current velocity was 8.0, it would return 6.0. if(wantedVelocity<0) return -getClosestReachableVelocityToVelocity(-currentVelocity,-wantedVelocity); if(currentVelocity<0) { double nextVelocity; // we are travelling the wrong way, decelerate nextVelocity = currentVelocity + Rules.DECELERATION; if(nextVelocity>Rules.ACCELERATION) // make sure we can't jump from -0.1 to 1.9 or something nextVelocity = Rules.ACCELERATION; if(nextVelocity>wantedVelocity) // if the wanted velocity is for example 0.5, limit the velocity to that. return wantedVelocity; else // else return the highest possible return nextVelocity; } else { if(currentVelocity>wantedVelocity) { // both velocities are positive, but we need to decelerate double nextVelocity = currentVelocity - Rules.DECELERATION; if(nextVelocity<wantedVelocity) // if we can decelerate more than what's wanted, return what's wanted return wantedVelocity; else // else return the closest to it return nextVelocity; } else { // the wantedVelocity is higher than current double nextVelocity = currentVelocity + Rules.ACCELERATION; if(nextVelocity>wantedVelocity) // if we can accelerate more than what's wanted, return what's wanted return wantedVelocity; else // else return the closest to it return nextVelocity; } } }
getMaxVelocity function by Voidious:
double getMaxVelocity(double distance) { long decelTime = decelTime(distance); double decelDist = (decelTime / 2.0) * (decelTime-1) // sum of 0..(decelTime-1) * Rules.DECELERATION; return ((decelTime - 1) * Rules.DECELERATION) + ((distance - decelDist) / decelTime); } long decelTime(double distance) { long x = 1; do { // (square(x) + x) / 2) = 1, 3, 6, 10, 15... if (distance <= ((square(x) + x) / 2) * Rules.DECELERATION) { return x; } x++; } while (true); } long square(long i) { return i * i; }
The getNewVelocity function:
double getNewVelocity(double velocity, double distance) { if(distance<0) return -getNewVelocity(-velocity,-distance); double highestVelocity = getMaxVelocity(distance); // highest velocity without overshooting double wantedVelocity = Math.min(highestVelocity,8.0); // the actually wanted velocity by the robot is the highest possible, // limited by what the robot set by the setMaxVelocity command return getClosestReachableVelocityToVelocity(velocity, wantedVelocity); // return whatever is closest to that velocity }
Simulator:
public void simulate() { double currentVelocity = 8.0; double distanceRemain = -2.0; while(distanceRemain!=0.0 || currentVelocity!=0.0) { out.println("velocity = "+currentVelocity+"; distance="+distanceRemain); currentVelocity = getNewVelocity(currentVelocity,distanceRemain); distanceRemain -=currentVelocity; } }
Results
StartVelocity = 0.0; StartDistance = 6.0;
velocity = 0.0; distance=6.0 velocity = 1.0; distance=5.0 velocity = 2.0; distance=3.0 velocity = 2.5; distance=0.5 velocity = 0.5; distance=0.0
StartVelocity = 0.0; StartDistance = 10;
velocity = 0.0; distance=10.0 velocity = 1.0; distance=9.0 velocity = 2.0; distance=7.0 velocity = 3.0; distance=4.0 velocity = 3.0; distance=1.0 velocity = 1.0; distance=0.0
StartVelocity = -1.9; StartDistance = 10;
velocity = -1.9; distance=10.0 velocity = 0.10000000000000009; distance=9.9 velocity = 1.1; distance=8.8 velocity = 2.1; distance=6.700000000000001 velocity = 3.1; distance=3.600000000000001 velocity = 2.8000000000000007; distance=0.8000000000000003 velocity = 0.8000000000000007; distance=-4.440892098500626E-16; velocity = -4.440892098500626E-16; distance=0.0
StartVelocity = 8.0; StartDistance = -2.0;
velocity = 8.0; distance=-2.0 velocity = 6.0; distance=-8.0 velocity = 4.0; distance=-12.0 velocity = 2.0; distance=-14.0 velocity = -0.0; distance=-14.0 velocity = -1.0; distance=-13.0 velocity = -2.0; distance=-11.0 velocity = -3.0; distance=-8.0 velocity = -4.0; distance=-4.0 velocity = -3.0; distance=-1.0 velocity = -1.0; distance=0.0
StartVelocity = 5.0; StartDistance = 40.0;
velocity = 5.0; distance=40.0 velocity = 6.0; distance=34.0 velocity = 7.0; distance=27.0 velocity = 8.0; distance=19.0 velocity = 7.75; distance=11.25 velocity = 5.75; distance=5.5 velocity = 3.75; distance=1.75 velocity = 1.75; distance=0.0