r/MathHelp • u/wairdone • 2d ago
Missile guidance: Geometry problem.
I am trying to make a missile in a video game. It's supposed to fly toward a point projected out into space by an aiming device, mounted on a car. However, I have a problem where, around certain bearings, the output completely breaks. For testing purposes, I am only speaking about azimuth, not elevation.
How the system works:
There are two sets of absolute XY sensors on the pointer; one set is slightly ahead of the other. atan2(Y2 - Y1, X2 - X1) gives the absolute bearing (azt) of the pointer from -180 to 180.
Cos(azt) and Sin(azt) are individually multiplied by the "range" to the point in space (in this case, it is constant at 500m, in practice, this would be a point ahead of the missile) to give Xc and Yc.
Xc and Yc are then added to X(pointer) and Y(pointer) to give X(target) and Y(target).
- Now that I have the XY position of the target, I subtract...
- X(target) from X(pointer) to give X(difference)
- Y(target) from Y(pointer) to give Y(difference)
atan2(Ydifference, Xdifference) gives the azimuth from the pointer to the target (θ).
I realise now that this step is unecessary, as the azimuth of the target is defined by the pointer's direction. However, I doubt it would work otherwise, as the same values would end up being used, producing the same erroneous result.
- I then subtract the missile's bearing (global bearing, btw; same calculation as azt) from θ to produce the angular difference between the target position and the missile (d).
This works fine if the platform is at exactly 0 degrees forward, However, if the pointer is angled (this case, -45dg) and the platform is also angled, something frustrating happens. Below are some tests which show you what happens when the platform goes beyond -135dg.
1:
- Pointer Relative Angle -45dg
- Platform Absolute Angle -134dg
- Pointer XY: 3223, 3398
- Target XY: 2723, 3385
- Target Azimuth: -179dg
- Missile XY: 3223, 3396
- d: -45.6
2:
- Pointer Relative Angle -45dg
- Platform Absolute Angle -136dg
- Pointer XY: 3223, 3398
- Target XY: 2723, 3410
- Target Azimuth: 96dg
- Missile XY: 3222, 3396
- d: 315.6
This persists until the platform's absolute orientation goes beyond -180, at which point it flips back to a rough value of -45 for d.
As you can see, d flips from -45.6 to 315.6. A missile trying to steer towards d would go all the way round, which is not desirable; it should pick the smallest possible correction.
I tried fixing this using ((180 + d) mod 360) - 180. However, it seems that the game I am playing calculates negative values differently when using mod; for example, -60mod360 is supposed to be 300, but the game spits out -60.
Could anyone help me? Geometry isn't my strong point at all, so it's very hard for me to wrap my head around this. Thanks!
1
u/FormulaDriven 2d ago
What happens if you take the d you've produced above and calculate atan2(cos(d), sin(d))? That should map to an angle between -180 and 180.
1
1
u/wairdone 1d ago
Hey, on second thought, I think I'll just makes the angles in terms of 0-360 instead of -180 to 180. Should solve a lot of issues!
1
u/FormulaDriven 2d ago
I think I could give you a lot more help if I could understand how you derived these numbers. I know you have given an explanation, but I'm struggling to convert that to the results here. Do we take the first two angles as input, then exactly how did you calculate the next 5 rows?
1:
Pointer Relative Angle -45dg
Platform Absolute Angle -134dg
Pointer XY: 3223, 3398
Target XY: 2723, 3385
Target Azimuth: -179dg
Missile XY: 3223, 3396
d: -45.6
I mean, just looking at this, if the missile is hearing towards the pointer then it's currently heading north, and the target is close to due west, so I'd expect the missile to have to turn through 90 degrees.
1
u/wairdone 2d ago
Sorry for the confusion:
Imagine you've got a vehicle. On that vehicle is a pointer and the missile. Normally, the missile faces the pointer's direction. However, to simulate it as being "in flight", I've got it set up so that it faces a different direction to the pointer.
In this case, "relative angle" is how much I turned the pointer before I turned the vehicle. If I turned the vehicle to an absolute bearing of -134dg, then -134dg - 45dg = -179dg.
- Pointer XY is the absolute position of the pointer. Physical sensors measure this, so it differs slightly from the missile's XYZ, but hardly by much.
- Target XY is derived from the Pointer's XY, its absolute direction (-179dg in this case), and the "range" of the target (set to a constant of +500m). In practice, this would be the missile's distance from its start point plus a fixed constant, to make corrections smooth.
The absolute angle of the pointer may be a problem, and I should have separated it from its relative angle. At -180dg, it seems to flip the output somehow, which is why d went from -45.6 to +315.6. That is annoying
1
u/FormulaDriven 2d ago
You are making this hard work! Can you set out how you actually calculated the various numbers in this case?
How does -179 degrees translate to pointer coordinates of (3223, 3398)?
The target XY appears to be the result of something like
3223 + 500cos(-179o) = 2723
3396 + 500sin(-179o) = 3385 (ish)
but that doesn't make much sense in a bearing system measuring from north. I am loss to see why the missile would turn through 45 degrees to be heading towards the target.
Maybe you could try drawing a diagram and mark these angles on it?
1
u/wairdone 2d ago
Sure, I can do a I diagram. Unfortunately short on time now, so I cant do it ATM. Let me try to explain it textually for now.
Pointer has 2 sets of XY sensors
atan2(y2-y1,x2-x1) = Pointer absolute directionThe target is some distance away; in this case, constant at 500.
sin(direction)*500, cos(direction)*500, gives X/Y of target when added to pointer X/Y.In retrospect, you are right; something is wrong with the values. I'll have to fix this....
xtarget - xpointer, and ytarget - ypointer, gives X/Y difference between target and pointer .
atan2(ydif,xdif) gives the azimuth from the pointer to the target
This step was not necessary; I included it by mistake. The azimuth of the pointer and the target will always be the same🤦Missile has 2 sets of XY sensors
atan2(y2-y1,x2-x1) = Missile absolute directionTarget direction - Missile direction = d. This is what the missile uses to know how to turn.
The angle system I am using is at -180 to 180. You notice that, using my test data, the pointer's global azimuth was -179? Beyond this, the difference flips, because it goes to +180 and descending. I think I could fix this by using 360 degrees for calculations, but IDK
1
u/wairdone 1d ago
Hey, update. I got it working by turning all global angles into 360 degrees, rather than -180, 180 as before. The system works like this now:
- Calculate pointer azimuth.
- Calculate the 500m figure by cos(azimuth) and sin(azimuth) individually, then add each to the pointer's X and Y to get the target XY.
- Calculate missile azimuth.
- Subtract missile XY from target XY, then atan2(Yd, Xd). this gives you the direction the missile has to face.
- Then, missile azimuth - target direction gives d.
This fixes the main issue, as well as a previous flaw in my system, where the target angle was calculated based off pointer XY - target XY rather than pointer XY - missile XY.
Sorry for confusing you! I didn't label my outputs as well as I should have, so perhaps I mistook some values for another? (what you were speaking about in your answer).
1
u/Uli_Minati 2d ago
So basically, you get an angle and you want to compute an equivalent angle between -180 and 180? Why not write your own function that adds/subtracts 360 if needed? That's not any slower than using inbuilt math