Aiming a turret (Math question)

So I have a turret and I can’t figure out the angles needed to aim the thing correctly. See the skeleton of the turret below and you will know what I mean:

The red arrow is pointing to the joint that is used to aim (via skeletal controller) and the blue arrow is pointing to the joint that needs to be aimed ie this joints forward x vector needs to point to the target. Here’s a picture of how the turrent looks when properly aimed:

The red dot is the red joint being controlled and the blue dot is the blue joint being aimed. I just can’t seem to calculate theta as a function of (x,y) the targets position.

So the first thing I tried is the following steps:

  1. Use law of sines to get the following:
  2. Then the following holds:
  3. So pluging in and simplifying:

so you get down to a linear combination of sine and cosine which according to here (or is equal to the following:

which reduces to:

But plugging this last equation into a blueprint the turret isn’t aiming correctly:

the “project onto plane polar coordiantes” node is doing just that (ie the brown line is the target’s projection onto the white plane). the white plane with the XYZ coordinate axis drawn is the (x,y) target position space relative to the joint used to aim (red arrow) and is rendering because the “draw debug helpers” is checked on that node.

I’m trying to find an analytical solution and not just iteratively reducing the aim error. I tried other methods but this is the simplest non-solution I could come up with. Any smarties out there that could scan the math and just tell me what stupid mistake I’m making? I would really appreciate it as this is bugging the hell out of me now. Thanks.

Have you tried just doing a simple “Look At” matrix for the aiming?

Thanks for the response, but unfortunately that doesn’t work. The condition for the turret to be aimed properly isn’t that one thing is looking at another thing. Because of the joints’ offset, there is an angle calculation somewhere. It’s more like an IK problem with an unknown end effector. Maybe there isn’t an analytical solution. Anyways, still appreciate your response :slight_smile:

You need to find the lookat rotation for the end of the turret and then offset it by the rotation delta between the base and the end of the turret.

It’s not so simple, to find a lookat rotation requires the source location, but in this case the source location is itself a function of the rotation.

@instantmelanie I’ve been working on a generic targeting framework that uses the iterative approach you mentioned. It’s totally fine in practice for most cases because your target distances generally dwarf your offsets and you also probably don’t want to snap to the perfect rotation on a single frame anyway. Still, an exact solution for a known fixed offset might be something I’ll want, so I had a bit of a scribble. A lot of a scribble actually, it’s not completely trivial but I’m also pretty sure it shouldn’t be so hard as I found it. If you picture it visually, the line of aim will obviously move round smoothly as you rotate, at some point passing through the target, so there should be a fairly straightforward analytical solution.

Anyhow, I ended up doing a different derivation because when I started off trying to solve for theta I got in a mess pretty quick and my trig isn’t what it used to be. I think what I got works, and plugging it back into the formula you derived, it looks like they are indeed just different forms of the same solution. I think you pretty much had it correct right up until the end. There will actually be two roots to the analytical solution (generally you can keep rotating around and the line of aim will hit the target backwards of the turret too). In my solution it came down to choosing the sign of a square root, I think in yours you have the same choice with your inverse sin (since the sine curve is symmetrical about 0). In the numbers I plugged in, I got what I think is the right answer by just taking the negative of the inverse sin term rather than the positive, but you may find it’s not always that way and you may need to do some check to determine which one is correct in a given instance. To begin with though, I’d just stick a Multiply by -1 node after your ASINd and see how that works.

Is this the behavior you’re looking for?

Yukova, I’m not OP, but I am trying to achieve a similiar behavior in your youtube video. Can you offer some insights?

namrog84, give me some time to clean up the example, and then I’ll post a full explanation (with source).

I apologize for the really long wait, but I’m back with a full analytical explanation:

You can download the project yourself here:

Let me know if you have any questions.

The best way to do this, surely, would be to use the standard functionality for calculating the aim required for a turret, then offsetting the target position based on the muzzle offset from the rotation point?

Thanks for the well documented code!