User:Positive/Optimal Velocity
Jump to navigation
Jump to search
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