# Talk:Historical Velocity Recall

## Contents

## Lateral Velocity

I've been experimenting with this targeting method and I have found that for some reason, storing lateral velocity in the array decreases the gun's performance. Why doesn't Math.abs(latvelocity) work as well as Math.abs(e.getVelocity())?--Khanguy 03:22, 31 May 2011 (UTC)

It could be that the movements of the robots that you are testing against are more vulnerable to normal velocity, or perhaps normal velocity just works better in general(which would be especially likely if you were taking the other robots heading into account somewhere else). Note: you can sign your posts with the "Your signature with timestamp" button on the top of the editing box, which makes it easier to distinguish between comments.--CrazyBassoonist 02:14, 31 May 2011 (UTC)

Sorry, its up there now. As for the lateralvelocity problem, I was comparing velocity to lateralvelocity without any segmentation. I ran a new testbed and now the results are reversed. LateralVelocity tends to do better than velocity.I suppose that it depends on the bot that you run it up against. Now this leaves me curious, which one would do better in the rumble?--Khanguy 03:22, 31 May 2011 (UTC)

Are you planning on doing this in a stat gun, such as GuessFactor Targeting? If so, your best in the normal vs. lateral velocity issue might be to use a combination of lateral velocity and advancing velocity, or some other segments that would end up telling you the speed and direction of the other robot--CrazyBassoonist 03:42, 31 May 2011 (UTC)

Actually no, I was just experimenting to find the perfect stat gun. I'm basing this my gun off of Historical Velocity Recall where I'm currently at the first steps. Right now, I'm just comparing velocity against lateral velocity without any other segmentation-no bearing offsets... yet ;) --Khanguy 15:32, 31 May 2011 (UTC)

I'd double check that you're not getting any problems with the signs... remember that after you multiply by the sin(absbearing-eOffset) it could become negative, and then you'd be shooting at the negative instead.--Skilgannon 13:10, 4 August 2011 (UTC)

## Majorly revised this article

That old page / code example was a bit long for what a simple idea this was, so I made a much simpler page / example and abstracted out the linear targeting part. --Voidious 04:15, 21 November 2007 (UTC)

- Um... is this page supposed to be called Historical Velocity
*Recall*, not Historical Velocity*Recal*? --`AaronR`

04:39, 21 November 2007 (UTC)- Oh, maybe that's it! I was asking the exact same question - what the heck could "Recal" be? Was even talking about it out loud to someone. Yeah, let's rename it... --Voidious 05:08, 21 November 2007 (UTC)

## From old wiki's Historical Velocity Recal page

This is a method of targeting I'm developing for BlueMind.

This method basicaly uses CircularTargeting, but instead of using the current enemy's velocity, you keep a log of all of its recorded velocities: and shooting at the "highest" point in the graph.

This is achieved throught the use of a vector and array pair.

### Implementation

```
static Vector velocityMap;
double[] vArray = new double[321];
Velocity enemyV = new Velocity(e.getVelocity());
velocityMap.addElement(enemyV);
for(int flush=0;flush<321;flush++){
vArray[flush]=0;
}
Velocity temp = new Velocity(0);
double temp2=0;
out.println(velocityMap.size());
for(int index=0; index < velocityMap.size(); index++){
temp = (Velocity)velocityMap.get(index);
temp2 = (temp.v+8)*20;
vArray[(int)temp2]++;
}
Count target = new Count();
for(int scan=0; scan < 321; scan++){
if(vArray[scan]>target.threshHold){
target.value = (scan/20)-8;
target.threshHold=vArray[scan];
}
}
double power = (2200/Math.pow(e.getDistance(),1.15));
if(power>=getEnergy()){
power = getEnergy()-.1;
}
if(power>3)
power=3;
if(power<.1)
power=.1;
double dist = e.getDistance();
double playerX = getX();
double playerY = getY();
double bearing = (Math.toRadians(getHeading())+e.getBearingRadians())%(2*Math.PI);
double enemyX = playerX + (dist * Math.sin(bearing));
double enemyY = playerY + (dist * Math.cos(bearing));
double bulletV = 20 - 3 * power;
double enemyH = e.getHeadingRadians();
enemyH += (enemyH-lastH)/(getTime()-lastScanT);
double gunH = getGunHeading();
double predictD = e.getDistance();
double predictX = enemyX;
double predictY = enemyY;
double rawV = target.value;
double theta = 0;
double time2 = 0;
double t=0;
double timeTheta = 0;
double time0=dist/bulletV;
int deltaT = 0;
int others = getOthers();
double lastDiff=Double.POSITIVE_INFINITY;
for(deltaT=-1000;deltaT<=1000;deltaT++){
t = time0 + deltaT;
predictX = enemyX+((rawV*t)*Math.sin(enemyH));
predictY = enemyY+((rawV*t)*Math.cos(enemyH));
if (predictX < 20){
predictX = 20;
}else if(predictX > battleFieldWidth-20){
predictX = battleFieldWidth-20;
}
if (predictY < 20){
predictY = 20;
}else if(predictY > battleFieldHeight-20){
predictY = battleFieldHeight-20;
}
predictD = Point2D.Double.distance(playerX,playerY,predictX,predictY);
timeTheta = Utils.absoluteBearing(playerX, playerY, predictX, predictY);
timeTheta = Utils.normalizeBearing(timeTheta - gunH);
time2 = (predictD / bulletV) + (timeTheta / 20);
if(Math.abs(t-time2) <= lastDiff){
theta = Utils.absoluteBearing(playerX, playerY, predictX, predictY);
theta = Utils.normalizeBearing(theta-gunH);
lastDiff = Math.abs(t-time2);
}
}
turnGunRight(Utils.normalizeBearing(theta));
lastH = enemyH;
lastScanT = getTime();
if(getEnergy()>0.2)
fire(power);
```

This sounds very similar to the aiming method that Stampede 1.3.3 currently uses (except it has both a linear and a circular version in a VG array). I have not been able to improve it much further than the gun currently in the RR; however that is probably due to my sloppy implementation rather than a weakness in the concept. I'm curious to see how you fare with this. --wcsv