# LateralVelocity

Robo Home | Changes | Preferences | AllPages

The speed with which an enemy is moving clockwise to your robot. If they are circling you as fast as they can, this will be 8 or -8 (depending on the direction). If they are moving toward you, it will likely be small (or zero). Its direction is perpendicular to your opponent's AdvancingVelocity, the speed it is moving in on you.

``` Velocity: scannedRobotEvent?.getVelocity()
LateralVelocity: velocity * Math.sin(scannedRobotEvent?.getHeadingRadians() - scannedRobotEvent?.getBearingRadians?() + getHeadingRadians())
AngularVelocity: lateralVelocity / scannedRobotEvent?.getDistance()
```

#### Questions / Discussion

I'll post the math to it later when I have my code handy. This is useful to segment statistics (this is what FloodMini does, and I believe the robot that Nano is using also uses this information), and can also be used in a pattern-matcher (I have an experimental pattern-matcher that uses this and does fairly ok, even though the bot's movement is simply a small sine-wave). --Kawigi

Isn't this what NanoLauLectrik and Moebius uses for PatternMatching? Since you handed me the function for calculating this I now use LateralVelocity in all my bots. It's at the heart of Makos new movement as well. Still have to use it in a GuessFactorTargeting type of gun though.-- PEZ

True. They use LateralVelocity for pattern matching and the accumulated LateralVelocity for aiming. BTW, the formula to calculate LateralVelocity is the following one:

``` lateralvelocity = e.getVelocity()*Math.sin(e.getHeadingRadians()-targetBearing);
```

-- Albert

Thanks, Albert, that's what I get, too. Right now, I'm working on a robot called Teancum, which is basically FloodMini that also matches patterns on this metric and AdvancingVelocity. -- Kawigi

Is it neccesary to match both? They are directly related, if you find a pattern in one it'll be in the other, if you don't there won't be a pattern in the other. -- Kuuran

That's an assumption that NanoSatan's pattern-matcher makes. It works in some cases, but a lateral velocity of, say, 2 could mean the opponent is mostly coming at you but just a little to the side, or it could mean the same thing but away from you, or it could mean they're going slowly exactly laterally to you (as the Flood and HT robots do quite a bit, or other robots do as they are accelerating/decelerating). Why should it matter to your gun? Because it effects how long the bullet takes to reach your opponent (Teancum's pattern matcher actually attempts to reconstruct movement from this information (it's typically off by a little bit simply because it assumes its opponent's movement has something to do with its own, and it keeps moving). -- Kawigi

Sort of, the nano matcher actually assumes the distance stays the same, and distance is factored in and back out in a few places. You're right, however, I guess in a megabot you've got the space to consider that and get really good aims. If you're using something as a reference when calculating these components of velocity, I suggest you pick a constant reference. If his movement is throwing the numbers, you aren't doing it. Try origin. -- Kuuran

What's the maximum lateral velocity measured in radians / ticks? -- PEZ

+/- 8 units / tick. Lateral velocity is measured in units / tick, not radians / tick. To convert to AngularVelocity (which is how many radians the opponent is moving relative to you per tick) simply divide by the distance. --David Alves

Ah, thanks!! -- PEZ

The top of this page says LateralVelocity is the speed counter-clockwise. Is that correct? The code to calculate it seems to return the speed CLOCKWISE. It looks like the old UnitCircle? vs CompassMath? thing again... -- Tango

It is clockwise, it was written wrong before. Maybe the formula I originally came up with and posted here was a counter-clockwise one, but the one up there as well as what most people are using now is clockwise. -- Kawigi

Why does it matter what heading my robot is to determine whether the enemy is moving clockwise? -- Kinsen

You need to know the other robot's heading, not yours. The formula is:

`L.V. = enemyVelocity * Math.sin(enemyHeading - bearingToEnemy)`
If that value is positive, they are going clockwise -wcsv

I still don't get this. I tried making my robot stationary and then printing out the later velocity for walls and it kept on changing from positive to negative. As far as I know, walls is always going clockwise once it starts following the walls. -- Kinsen

Could you post the section of code where you do this? that would help me to help you. --wcsv

It is sort of messy because I was shrinking the codesize of everything else:

```variable = getHeadingRadians();
variable2 = e.getBearingRadians();

setTurnGunRightRadians(Utils.normalRelativeAngle(variable2 + variable - getGunHeadingRadians() +
enemyAverageVelocity / averageVelocityCount * e.getDistance() *
(Math.sin(e.getHeadingRadians() - variable2 + variable) >= 0? ANGLE_ADJUST : -ANGLE_ADJUST)));
```

The part that uses the lateral velocity is

```(Math.sin(e.getHeadingRadians() - variable2 + variable) >= 0? ANGLE_ADJUST : -ANGLE_ADJUST)
```

-- Kinsen

What I use is (note the brackets!):

```bearingToEnemy = getHeadingRadians() + e.getBearingRadians();
latvel = e.getVelocity() * Math.sin(e.getHeadingRadians() - (bearingToEnemy))
```
and processed the remark below -- GrubbmGait

Also, if you don't multiply by e.getVelocity(), the value you get will assume that they are going forward at velocity 1.0 --wcsv

I added a code example as a subsection to Ugluk. I didn't want to clutter up the page. -- Martin

Is the code at the top wrong then, because you are subtracting bearingToEnemy? which when multiplied through is

```Math.sin(e.getHeadingRadians() - getHeadingRadians() - e.getBearingRadians())
```
instead of adding getHeadingRadians() as the code at the top says to do. -- Kinsen

Yes, you are correct. Think of it like this:
The code from the top is like

```lateralvelocity=e.getVelocity()*Math.sin(e.getHeadingRadians() + e.getBearingRadians() - getHeadingRadians());
```
The code GrubbmGait uses:
```bearingToEnemy = getHeadingRadians() + e.getBearingRadians();
latvel = e.getVelocity() * Math.sin(e.getHeadingRadians() - (bearingToEnemy));
```
which, in other words, is:
```latvel = e.getVelocity() * Math.sin(e.getHeadingRadians() - (e.getBearingRadians()+getHeadingRadians()));
```
This is totally what we don't want, because according to the order of operations, the code from the top is different than GrubbmGait's code :(
(We can flip the getHeadingRadians() and e.getBearingRadians?() because of the commutative property of addition.)
--Starrynte Ok, slightly dumb question: Is there any simple way (as in not too much codesize) to calculate the orbital direction of YOU relative to the enemy? --Starrynte

I would like to know my direction (clockwise/counter clockWise), in reference to the battle field Center. I can't seem to get it right :( my attempts like: double lateralVelocity = getVelocity()*Math.sin( Utils.normalRelativeAngle(absoluteBearing(bfCenter, MY.location)- MY.heading); MY.direction = (int)((lateralVelocity >= 0) ? 1 : -1); ... are flawed, could some one pls help, thx - Justin

Hey - your formula looks right to me, except I think you want `absoluteBearing(MY.location, bfCenter)`. (You could also drop the Utils.normalRelativeAngle, as that won't affect the sin.) If you were figuring it out in relation to the enemy location, you could just do `getVelocity()*Math.sin(e.getBearingRadians())` (where e is a ScannedRobotEvent in onScannedRobot), and getHeadingRadians() + getBearingRadians?() = absoluteBearing(me, enemy). So I think you just need to flip those in your formula. Maybe someone else can give me a sanity check on this. =) I'm assuming here that you're using the same absoluteBearing as I am:

```public double absoluteBearing(Point2D.Double sourceLocation, Point2D.Double target) {
return Math.atan2(target.x - sourceLocation.x, target.y - sourceLocation.y);
}
```
Also, feel free to make a page for yourself and your bots - welcome to the wiki!

-- Voidious

Thx Voidious ,, but something is still wrong :( I'll be sure to make myself a page as soon as I this bot up and running :) I've been simply tring to get wallSmoothing to correctly smooth in the proper direction like so: double goAngle= MY.heading; .. goAngle = wallSmoothing(MY.location, goAngle, MY.lateralDirection );

```			goAngle =Utils.normalRelativeAngle(goAngle - MY.heading);
```

```			setTurnRightRadians?(goAngle);
setAhead(30);
```

but I still can't get a Lateral Direction, in reference to battleField center correctly.

I'm curious - why do you want to wall smooth in relation to the center of the battlefield, instead of in relation to the enemy bot? I'd think that using battlefield center instead of the enemy bot could give some strange behavior in some situations, making you smooth away from the enemy instead of towards it. What kind of behavior are you seeing right now with your current code? -- Voidious

It's a melee bot, that works the wall or corners. I have additional code that keeps it mostly perpendicular to targets and when to alternate direction and whatnot. I would like it to smooth away from current target when wall angle is less (likely towards a diff enemy) instead of sharp turn towards wall and squeezing toward/behind current target. I'm not good with trig. :( haven't found a solution to lateral direction relative to battleField center yet. it works as expected to Enemybearing though. my above code, (swithched around as you corrected) is only correct lat Velocity in clockWise direction along the top, and right wall.. -Justin

I'm not sure why the battlefield center stuff isn't working, then, but what a lot of people do in Melee is base their movement around destination points, and only "go to" a point that is on the field. This gives the effect of WallSmoothing without a 1v1 style smoothing algorithm. Maybe someone else can spot the issue you're having, or I can look sometime when I'm not at work, but I'm not seeing it at the moment... -- Voidious

double lateralVelocity = getVelocity()*Math.sin( (absoluteBearing(MY.location,bfCenter)- MY.heading)); DOESN"T work.. found a better alturnate though. -Justin

How do you find at least the sign of the lateral velocity of you to the enemy bot when you haven't, but will, start moving in the direction of a specific point --Starrynte

Math.signum(Math.sin(bearing(myLocation, enemyLocation) - bearing(myLocation,destination))) -- Skilgannon

Robo Home | Changes | Preferences | AllPages
Edit text of this page | View other revisions
Last edited May 4, 2008 19:45 EST by Skilgannon (diff)
Search: