Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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.

share|improve this question
add comment

5 Answers

As Nailer says, you can cap the movement change in some way.

Check out PID, a nice way to make things move to a certain 'value' fast but without overshooting it, it might give you some ideas.

You can also check out this question, a bit down is an explanation of the 'dog curve', a very accurate homing algorithm used by dogs.

share|improve this answer
    
I can see that I need some form of damped feedback control loop once the missile is tracking the target, but I think I have a simpler initial problem as the missile just oscillates on the initial launch direction. Just to emphasise, I definitely want to use the proportional navigation algorithm. –  e100 Apr 25 '12 at 9:40
    
Although PID is a nice instrument, it's hard to tune.. but once the three parameters (if one requires three) are found, you do have a solution for that specific mechanism. +1 from my side. –  teodron Apr 25 '12 at 11:21
    
thanks teodron ;-) @e100 : if you want to make the missile go "straight forward" when calculations are done and the target is on a steady move, check out the 'dog curve' example as it does just that. Otherwise, your 'TurnRate' equals the 'P' (IIRC) in PID, you might calculate it on the fly, say 10%of the difference and not a fixed value. If you are 2° off course you don't need the same change as if you are 20° off. –  Valmond Apr 25 '12 at 12:20
add comment

For my opinion, there would be another method involving two vectors, one for direction for a missile to hit, and another one is for itself lerping (or say transitioning its direction to match the first vector).

This way, we can produce a lag time allowing a missile to smoothly changes its direction according of a change in a first vector. I believe it will remove out the problem in "sign" of math operation.

PS. The main point is that we lerp a missle's own vector to a directional vector (to hit) with regard to some small lag in time.

share|improve this answer
    
Do note that whilst although this approach can produce results, this would give the missile a constant turn time (rather than a constant turn speed) - unless you recalculate the interpolation rate each frame based on the turn distance yet to go in order to produce a constant turn speed. –  Jonathan Hobbs Apr 25 '12 at 22:15
    
I need to search on "lerping"! –  e100 May 1 '12 at 12:45
add comment

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.

share|improve this answer
    
This doesn't seem to be using the proportional navigation method? –  e100 May 1 '12 at 12:39
    
No, but it should have about the same effect. This will plot an intercept course between the missile and the target. The purpose of the navigation is for the missile to intercept the target. The above process should do that. You wanted simple. –  Azaral May 1 '12 at 13:38
    
Fair point, +1 to you –  e100 May 1 '12 at 17:56
    
If you do try it let me know how it goes. This was my plan for homing missile in my game; I just haven't gotten to programming the missile yet. –  Azaral May 1 '12 at 21:05
    
I've implemented this method for now and it works well. I don't think I can accept this answer as it is not quite close enough to what I want to end up with, but many thanks. –  e100 May 18 '12 at 13:12
show 3 more comments

Porportional navigation is simple to implement in games.

An example of implementation in game is:

Required Acceleration = LOS * LOS_Rate * NC + APN_bias

LOS = Vector3( TargetPosition ) - Vector3( MissilePosition )

NC = Navigation Constant multiplier (depending on frame rate run)

APN_bias = LOS_Rate/delta_T * ( NC/2 )

LOS_Rate = LOS Rotation Rate is the angular rate of change in sightline between the missile and the target. This is measured by recording both the missile and the target vector positions every frame at delta_T, and subtracting each to get the difference. Delta_T is the timing reference (i.e. frame rate) at which your homing missile is running in game.

To obtain LOS_Rate, simply have your missile guidance loop do the following at each frame (delta_T):

// New LOS rate

LOS_Delta = Vector3( LOS ) - Vector3( LOS_previous_frame ) 

LOS_Rate = LOS_Delta.Vector3Length()

// Update LOS before we finish

LOS_previous_frame = Vector3( LOS )

You can find more information about how we implemented PN for World in Conflict game at the following URLs below. Hope you find these helpful.

http://www.moddb.com/mods/wicmw/features/flint-lead-pursuit-guidance-principles

http://download.wicmwmod.com/Fun_Mod/presentations/FLINT%20Jul%202012.pdf

-blahdy

share|improve this answer
add comment

Can´t you just cap the turn rate so that it can never turn past TargetBearing in one frame?

If a turn would make the missile turn past it´s target bearing you just set the new bearing equal to target bearing.

Does that make sense?

share|improve this answer
    
No, I don't think so. The idea isn't turning the missile towards TargetBearing, but turning in the direction that TargetBearing is changing. –  e100 Apr 25 '12 at 9:27
    
Ok. I guess I misunderstood. –  Nailer Apr 26 '12 at 9:24
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.