double absoluteBearing = getHeadingRadians() + e.getBearingRadians(); setTurnGunRightRadians(Utils.normalRelativeAngle(absoluteBearing - getGunHeadingRadians() + (e.getVelocity() * Math.sin(e.getHeadingRadians() - absoluteBearing) / 13.0)));
How It Works:
We first find the other robot's LateralVelocity (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 you're 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 because of the distortion from removing asin.
Finally, we add the offset to the absolute bearing to get the firing angle, and subtract the gun heading to get the gun turn. -- Kev