# "Realistic" 2d missile homing

This topic is 2566 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello, I am working on a top-down game that has missiles in it. I am writing in c++ using the Box2d engine. I want the missiles to steer only by applying torque and forward force, hence "realistic." As it is I have it turning correctly only if it starts at certain angles, and at other angles it turns away from the target. A video might help demonstrate. There's two examples in the clip, one where the missile starts facing right and one where it starts facing left. As you will see, it hits the target (the red circle) perfectly when facing right, but when facing left it goes in the opposite direction. I hope the video is not too unclear. The thick, short white line is the missile, the long lines indicate direction and such.

Here is the relevant function (called each frame):

 void Missile::update() { if (!active) { return; } // Begin direction calculations b2Vec2 pos = body->GetPosition(); b2Vec2 vel = body->GetLinearVelocity(); b2Vec2 wp = *currentWaypoint->point; float currentAngle = body->GetAngle(); float turnSpeed = body->GetAngularVelocity(); float targetAngle = pointAngleR(pos, wp); float driftCompensationAngle = targetAngle - (angleDifferenceR(vectorToAngleR(vel), targetAngle)); targetAngle = driftCompensationAngle; float aDiff = angleDifferenceR(currentAngle, targetAngle); float desiredTurnSpeed = -((aDiff) * maxTurnSpeed); /* * The constant determines the time it takes for the missile to stabilize itself. * A lower constant means it takes longer. */ float turnSpeedCorrection = (desiredTurnSpeed - turnSpeed) * 20000; // End direction calculations b2Vec2 force = getDirectionVector(); force.Normalize(); force *= -300.0f; body->ApplyTorque(turnSpeedCorrection); body->ApplyForce(force, body->GetWorldCenter()); #ifdef DEBUG // Draw lines for debugging line(screen, pos.x, pos.y, pos.x+force.x, pos.y+force.y, makecol(255,255,255)); line(screen, pos.x, pos.y, pos.x + (vel.x * 10), pos.y + (vel.y * 10), makecol(255,0,0)); line(screen, pos.x, pos.y, pos.x + (getDirectionVector().x * 100), pos.y + getDirectionVector().y * 100, makecol(0,0,255)); line(screen, pos.x, pos.y, pos.x + (angleToVectorR(driftCompensationAngle).x * 100), pos.y + (angleToVectorR(driftCompensationAngle).y * 100), makecol(0,255,255)); b2Vec2 targetAngleVector = angleToVectorR(targetAngle); targetAngleVector *= -500; line(screen, pos.x, pos.y, pos.x + targetAngleVector.x, pos.y + targetAngleVector.y, makecol(0,255,0)); #endif // Check if we've reached our target if (abs((pos - wp).Length()) < 5) { if (currentWaypoint->next != NULL) { currentWaypoint = currentWaypoint->next; } else { active = false; } graphics::textOutput(currentWaypoint->point); } } 

Thanks for any help!

##### Share on other sites
it would probably be very useful to start the simulation in a situation where the code does the wrong thing and look at variable values using a debugger. My guess is that some of the angle computations don't work well around the point where the angles change from 180 to -180 or from 360 to 0.
I would implement the whole thing without using angles. Thinking about these things in terms of angles might seem more intuitive at first, but it's easy to make mistakes. If you write the code using vectors, it generalizes to 3D naturally and it's easier to get right. Code that doesn't use angles even executes faster, although that should only be an argument if it matters.

##### Share on other sites
Agreed. I suspect it's a wraparound issue in your angle difference function.

##### Share on other sites
Stock answer: "if you haven't traced your code line-by-line, don't expect anyone else to do so."

1. 1
2. 2
Rutin
19
3. 3
4. 4
5. 5

• 14
• 30
• 13
• 11
• 11
• ### Forum Statistics

• Total Topics
631781
• Total Posts
3002315
×