Difference between revisions of "Linear Targeting"

From Robowiki
Jump to navigation Jump to search
m (linking to old talk page)
(Merging from Linear Targeting/NanoBot Linear Targeting)
Line 1: Line 1:
== Description ==
+
A method of [[targeting]] which assumes that the target will continue in the same direction at the same speed.
  
A method of [[:Category:Targeting|Targeting]] which assumes that the target will continue in the same direction at the same speed.
+
== Example of Iterative Linear Targeting ==
  
== Example ==
+
This is the code used in [[WaveSurfing Challenge/Bot B|WaveSurfing Challenge Bot B]]. The algorithm assumes that bots will come to a stop when they reach a wall.
 
 
This is the code used in [[WaveSurfing Challenge/Bot B|WaveSurfing Challenge Bot B]]:
 
  
 
<pre>
 
<pre>
//Add import robocode.util.* for Utils and import java.awt.geom.* for Point2D
+
// Add import robocode.util.* for Utils and import java.awt.geom.* for Point2D.
//This code goes in your onScannedRobot() event handler
+
// This code goes in your onScannedRobot() event handler.
  
 
double bulletPower = Math.min(3.0,getEnergy());
 
double bulletPower = Math.min(3.0,getEnergy());
Line 49: Line 47:
 
</pre>
 
</pre>
  
* NOTE: This algorithm assumes that bots will come to a stop when they reach a wall.  
+
== Example of Noniterative Linear Targeting ==
* NOTE: There is a simpler way to do linear targeting with the help of trigonometry. It has the disadvantage of ''not'' knowing if is aiming at a spot off of the battlefield. It has the very real advantage of being non-iterative and does not need to estimate the time for the bullet to reach the enemy.
+
 
 +
This code gives decent [[Linear Targeting]] with a very small code size. However, the aim is slightly imprecise and it ignores walls. The basic code is used in a lot of [[Nano Bots]]:
 +
 
 +
<pre>
 +
double absoluteBearing = getHeadingRadians() + e.getBearingRadians();
 +
setTurnGunRightRadians(Utils.normalRelativeAngle(absoluteBearing -
 +
    getGunHeadingRadians() + (e.getVelocity() * Math.sin(e.getHeadingRadians() -
 +
    absoluteBearing) / 13.0)));
 +
setFire(3.0);
 +
</pre>
 +
 
 +
=== How It Works ===
 +
 
 +
We first find the other robot's [[Lateral Velocity|lateral velocity]] (how fast the other robot is moving parallel to you) with <code>e.getVelocity() * Math.sin(e.getHeadingRadians() - absoluteBearing)</code>. To find an approximate angle offset, you assume they'll continue moving parallel with you at their lateral velocity until your bullet reaches them, giving you a triangle like this: 
 +
 +
<pre>               
 +
                                      /|
 +
                                      /a|
 +
bullet speed * bullet travel time  /  |
 +
                                    /  | 
 +
                                  /____|
 +
 
 +
                    lateral velocity * bullet travel time
 +
</pre>
 +
 
 +
So your angle offset is: <code>asin((lateral velocity * bullet travel time) / (bulletSpeed velocity * bulllet travel time)) = asin(lateral velocity / bullet speed)</code>. It turns out that <code>asin(lateral velocity / bullet speed)</code> is almost exactly the same as <code>(lateral velocity / bullet speed)</code>, so we get rid of the asin for some more code size. The above code uses 13.0 for bullet speed, but this actually results in aiming that works better for a slightly lower speed than 13.0 because of the distortion from removing asin. (The speed of a power 3.0 bullet is 11.0.)
 +
 
 +
Finally, we add the offset to the absolute bearing to get the firing angle, and subtract the gun heading to get the gun turn.
 +
 
  
 
== See also ==
 
== See also ==
  
* [[/NanoBot Linear Targeting|NanoBot Linear Targeting]] - An extremely small implementation of linear targeting, ideal for use in [[NanoBots]].
 
 
* [[/Buggy Implementations|Buggy Implementations of Linear Targeting]] - There are much faster algorithms to do this, but they don't seem to be correct all the time. If anyone can correct them it would be much appreciated.
 
* [[/Buggy Implementations|Buggy Implementations of Linear Targeting]] - There are much faster algorithms to do this, but they don't seem to be correct all the time. If anyone can correct them it would be much appreciated.
 
* [[/Archived_Talk_20071111|Archived discussions about linear targeting]] - Discussions culled from the LinearTargeting and LinearTargeting/Discussions pages of the old wiki.
 
* [[/Archived_Talk_20071111|Archived discussions about linear targeting]] - Discussions culled from the LinearTargeting and LinearTargeting/Discussions pages of the old wiki.
  
 
[[Category:Simple Targeting Strategies]]
 
[[Category:Simple Targeting Strategies]]

Revision as of 00:40, 12 November 2007

A method of targeting which assumes that the target will continue in the same direction at the same speed.

Example of Iterative Linear Targeting

This is the code used in WaveSurfing Challenge Bot B. The algorithm assumes that bots will come to a stop when they reach a wall.

// Add import robocode.util.* for Utils and import java.awt.geom.* for Point2D.
// This code goes in your onScannedRobot() event handler.

double bulletPower = Math.min(3.0,getEnergy());
double myX = getX();
double myY = getY();
double absoluteBearing = getHeadingRadians() + e.getBearingRadians();
double enemyX = getX() + e.getDistance() * Math.sin(absoluteBearing);
double enemyY = getY() + e.getDistance() * Math.cos(absoluteBearing);
double enemyHeading = e.getHeadingRadians();
double enemyVelocity = e.getVelocity();


double deltaTime = 0;
double battleFieldHeight = getBattleFieldHeight(), 
       battleFieldWidth = getBattleFieldWidth();
double predictedX = enemyX, predictedY = enemyY;
while((++deltaTime) * (20.0 - 3.0 * bulletPower) < 
      Point2D.Double.distance(myX, myY, predictedX, predictedY)){		
	predictedX += Math.sin(enemyHeading) * enemyVelocity;	
	predictedY += Math.cos(enemyHeading) * enemyVelocity;
	if(	predictedX < 18.0 
		|| predictedY < 18.0
		|| predictedX > battleFieldWidth - 18.0
		|| predictedY > battleFieldHeight - 18.0){
		predictedX = Math.min(Math.max(18.0, predictedX), 
                    battleFieldWidth - 18.0);	
		predictedY = Math.min(Math.max(18.0, predictedY), 
                    battleFieldHeight - 18.0);
		break;
	}
}
double theta = Utils.normalAbsoluteAngle(Math.atan2(
    predictedX - getX(), predictedY - getY()));

setTurnRadarRightRadians(
    Utils.normalRelativeAngle(absoluteBearing - getRadarHeadingRadians()));
setTurnGunRightRadians(Utils.normalRelativeAngle(theta - getGunHeadingRadians()));
fire(bulletPower);

Example of Noniterative Linear Targeting

This code gives decent Linear Targeting with a very small code size. However, the aim is slightly imprecise and it ignores walls. The basic code is used in a lot of Nano Bots:

double absoluteBearing = getHeadingRadians() + e.getBearingRadians();
setTurnGunRightRadians(Utils.normalRelativeAngle(absoluteBearing - 
    getGunHeadingRadians() + (e.getVelocity() * Math.sin(e.getHeadingRadians() - 
    absoluteBearing) / 13.0)));
setFire(3.0);

How It Works

We first find the other robot's lateral velocity (how fast the other robot is moving parallel to you) with e.getVelocity() * Math.sin(e.getHeadingRadians() - absoluteBearing). To find an approximate angle offset, you assume they'll continue moving parallel with you at their lateral velocity until your bullet reaches them, giving you a triangle like this:

                 
                                       /|
                                      /a|
 bullet speed * bullet travel time   /  |
                                    /   |  
                                   /____|

                    lateral velocity * bullet travel time

So your angle offset is: asin((lateral velocity * bullet travel time) / (bulletSpeed velocity * bulllet travel time)) = asin(lateral velocity / bullet speed). It turns out that asin(lateral velocity / bullet speed) is almost exactly the same as (lateral velocity / bullet speed), so we get rid of the asin for some more code size. The above code uses 13.0 for bullet speed, but this actually results in aiming that works better for a slightly lower speed than 13.0 because of the distortion from removing asin. (The speed of a power 3.0 bullet is 11.0.)

Finally, we add the offset to the absolute bearing to get the firing angle, and subtract the gun heading to get the gun turn.


See also