I'm trying to implement the simplest possible form of proportional navigation, i.e, the missile turns in the direction that its bearing-to-target is changing, and once its bearing-to-target is unchanging, it's on an intercept course.
So, I have a 2d missile moving at a constant speed in the direction it is facing, which can turn at a constant rate, and every interval I update the missile with something like:
Position += VectorProduct (Direction * Speed * TimePassed)
PreviousTargetBearing = TargetBearing
TargetBearing = AngleBetween(TargetPosition, Position)
TargetBearingDelta = TargetBearing - PreviousTargetBearing
If TargetBearingDelta > 0: MissileDirection += TurnRate * TimePassed
If TargetBearingDelta < 0: MissileDirection -= TurnRate * TimePassed
Problem is, the missile always oscillates around its launch direction, because as soon as the missile turns the first time, this reverses the sign of TargetBearingDelta, making it then turn in the opposite direction, and so on...
What is the simplest way I can resolve this problem? I'm sure I'm missing something simple.
Related StackOverflow question: How to create an “intercept missile” for a game?
To reiterate, I am interested specifically in implementing the proportional navigation algorithm, not in homing algorithms in general.
Update: I guess the obvious answer is to not check bearing and adjust heading every turn, but to alternate between the two. I'll try that.
Answer
Step 1)Calculate time to target if going in a straight line
Step 2)Calculate where the target will be with it's current heading at that time.
Step 3)Set heading of missile to be that spot.
Step 4)Update as necessary
At first, this won't be very accurate, but as the distance closes it will become more accurate; as the time to travel goes to zero, the target spot for the missile gets closer to the target.
Give that a whirl. It's simple enough to implement. Let me know how it works because I want to put homing missiles in my game and this was my first thought.
And for this part:
If TargetBearingDelta > 0: MissileDirection += TurnRate * TimePassed
If TargetBearingDelta < 0: MissileDirection -= TurnRate * TimePassed
I would instead have two missileDirection variables. One for what it really is, and one for what it should be in the future. Then, the missile move's its' heading towards the desired heading by it's turn rate. If the desired heading is bigger than the current heading, add the turn rate. If it's smaller, subtract. If you go past, set it equal.
No comments:
Post a Comment