Difference between revisions of "User:Positive/Optimal Velocity"

From Robowiki
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