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