# How to determine which thrusters to turn on to rotate the ship?

The configuration of the ship changes dynamically, so I have to determine which thruster to turn on when I want to rotate the ship clockwise or counter clockwise. The thrusters are always axis aligned with the ship (never at an angle) and are either on or off. Here's one of the possible setups:

What I've tried so far is to visualize the firing vector and the direction vector to the center of mass of the ship:

Unfortunately, I didn't get very far with that.

• You are headed in the right direction with force vectors. Try looking up formulas for ANGULAR velocity since you are trying to rotate the ship around center of mass. – Amplify91 Oct 25 '12 at 18:55
• I forget how exactly to do it, but basically its just forces on each point en.wikipedia.org/wiki/Center_of_mass and especially en.wikipedia.org/wiki/Parallel_axis_theorem – CobaltHex Oct 25 '12 at 20:38
• I had exactly same idea! One tip that may make it easier for you is that you only need to calculate angular and linear acceleration once for each thruster, so calculations may be as complex as you want. – Markus von Broady Oct 25 '12 at 23:08
• @Amplify91, your comment relly helped me figure it out, thanks! – migimunz Oct 26 '12 at 6:38
• @migimunz I was rather thinking for calculating accelerations per thruster, not per key pressed (group of thrusters). Also, giving the player a choice which thrusters should be activated on which key pressed could be interesting (some people would trade faster rotating for rotating in place) – Markus von Broady Oct 26 '12 at 8:01

Success! Here it is, and it's rotating as it should:

What I've done is the following: for each thruster, I calculate the magnitude of the torque, in relation to the center of mass.

private function thrustTorque():Float
{
// distToCom is the distance vector between the thruster and center of mass
// fire angle is a unit vector representing the direction of the thruster
var distAngle = Math.atan2(distToCOM.y, distToCOM.x);
var fireAngle = Math.atan2(dir.y, dir.x);
var theta = fireAngle - distAngle;
var torque = distToCOM.length * Math.sin(theta);
}


The equation for the mangitude of torque, according to wikipedia, is T = rF sin(theta), where :

• r is the distance between the thruster and COM
• F is the magnitude of the force applied (I leave that out, pretending it's just one, because I only care about the sign).
• theta is the angle between the two vectors

When the player presses left, I check the sign of torque for that thruster - if it's less than zero, I fire the thruster. It's just the opposite for turning clockwise.

This could probably be improved by using the dot product to calculate the cosine of the angle between the vectors, but that'll have to wait until tomorrow.

Finally, here's a live demo.

• Nearly there I think. It seems to not be exactly at the center of mass. Using only the left/right arrows the ship can easily go off screen. Very close though. Perhaps the point you're measuring from is slightly off. Or it could be a timing issue since it seems to stabilize into a good spin after a while. Nice work though. – MichaelHouse Oct 25 '12 at 22:23
• I don't think that's anything to do with this logic. There's nothing here to ensure that the vehicle doesn't receive a net translational force from firing the set of thursters selected by this mechanism. If maintaining no net translational force is a requirement, it will require being able to modulate the force of individual thrusters (and will probably become a much more difficult problem to solve) – Trevor Powell Oct 26 '12 at 4:51
• @TrevorPowell, exactly. For the sake of simplicity (and also fun, since how well your ship performs will depend on how well you design it), I decided that thrusters are either on or off. I will probably include a threshold so that those that cause too little torque (and therefore too much lateral movement) are not turned on, but exactly how much is "too much/little" will probably be determined by trial and error. – migimunz Oct 26 '12 at 6:32
• What you want to do to avoid angle calculations is to use the perpendicular dot product (derived from the cross product definition of torque T = r cross F if you use 3D vectors with z = 0). You take the vector (-ry, rx), which is perpendicular to r with the same magnitude, and you calculate the dot product of that vector with F. The result is T = rx * Fy - ry * Fx. Then abs(T) is the magnitude of the torque, and its sign indicates direction: T > 0 is counterclockwise, T < 0 is clockwise. – Joren Oct 26 '12 at 12:30
• The reason why it works is easy to see intuitively: r dot F = r F cos θ. If you rotate r counterclockwise by 90 degrees and take the dot product, you get r F sin θ because cos (θ - 90˚) = sin(θ). – Joren Oct 26 '12 at 12:38

The general 3D expression for torque is the cross product of displacement and force: T = rF. In two dimensions, a scalar value for the torque will suffice, and given only four orthogonal orientations for the thrusters, we can write in piecewise form:

• Force in direction +x: T = F * (-ry)
• Force in direction -x: T = F * (ry)
• Force in direction +y: T = F * (rx)
• Force in direction -y: T = F * (-rx)

Here, F is the magnitude of the force generated by the thrusters, rx and ry are x- and y-components of the vector from pivot point to thruster. Positive torques tend to rotate the ship counter-clockwise. Using the four formulae above, it is trivial to deduce the sign of the torque each thruster produces.

For a modestly accurate representation of physics, you need not only know the sign of the thrust, but also its total magnitude and the rotational inertia. Moreover, you might not simply want to activate all properly aligned thrusters to do a rotation.

As drawn, full power to thrusters B, D and E will maximize the rotation, but will also accelerate the ship to the right. Shutting down D will prevent this. If instead, accelerating right is intended, but a clockwise rotation is not, the most efficient way to go is enabling both C and F at two thirds of full power along with D.

If this isn't beyond the scope of what you're trying to do, you would have to write some sort of solver for the equations of motion, clearly not a simple task.

A few different things. First, we need to recognize that this is an under-constrained problem. That is, there are many different combinations of thrusters which can fire to result in rotation in the same direction. I'm assuming that in your situation there are only two states for the thrusters, "on", and "off", and all thrusters output equal force.

Second, eyeballing your model, it looks like your "center of mass" is not actually your center of mass. Luckily, this won't effect your calculations for the torque. However, it will effect your calculations for the center of mass displacement. I'm not sure if you care about accuracy on that level though, since your "center of mass" is at least the closest square to the true center of mass.

Third, if you want to calculate how a certain thruster will affect the rotation, you have it right, although you are using an inefficient formula. Torque can be calculated as r x F, which has magnitude r*F*sin(theta). However, calculating the angles in this case is an inefficient method. Instead, you should use the cross-product definition of torque directly, as this will be much simpler using the representations you have. Because all your vectors have no z component, the formula for cross product simplifies greatly.

Without changing the results of your computation at all, we can just update your code

private function thrustTorque():Float
{
var torque = distToCOM.x*dir.y-distToCOM.y*dir.x;
}


That's much nicer (and faster).

You suggest in your own answer that your solution is to fire all the thrusters with torque in the right direction. Now, that pretty much solves the question that you asked. However, I expect that some point along the line, you're going to find that your strategy is not so satisfactory, if a user holds down the "rotate" button, and all thrusters with a positive torque rotate, potentially moving them on top of rotating them (I'm not sure of the level of detail of your simulation, if you actually do calculate the forces from the thrusters, or if you just visually show them firing and then rotate your model with a constant acceleration or something. Either way, you want the thrusters to be firing at least approximately accurately).

You make no consideration of the net force on the ship. If you had arbitrary thruster amounts, then this could turn into a pretty complicated problem. However, since our thrusters have only two states, it's pretty simple to analyze. I'm not sure exactly what our goal is here, so I could imagine two different ones: first, we want to minimize the total force, while still keeping the torque in the direction we want. Second, we want to maximize the ratio of torque to total force.

As an aside, if you could imagine an additional "thruster volume" control that affects the power of all thrusters simultaneously, then you could set this control so that your two solutions have equal torque, and you see that the second solution can only have a smaller displacement than the first. However, we need to remember that if it is possible to fire the thrusters so that you only rotate and do not move at all, then both solutions will be the same.

So, we're going to go with the second solution, based on the arguments of the previous paragraph. Now, when analyzing the total force, we can simply note that there are only four directions the engines can point. Thus the total force in the x direction is just the number of thrusters pointing left minus the number pointing right, and likewise for the y direction.

After writing up this far, I have to think some more about the algorithm to optimize it. I think the rest of my post is helpful as is, so I'm posting it, but I'll update when I figure out the best way to optimize this configuration (I've thought of a few ways to get approximate answers, but none of them are exact).

• Thank you for the answer (and the faster and cleaner solution to calculating torque). The red circle is not the ship's COM though, it's the power core. I'm using a physics engine and I'm merely applying a local impulse to the ship. I'm alright with the solution not being perfect as it makes it very fun to play around with different configurations, but I'd love to know what you come up with. – migimunz Oct 26 '12 at 20:20
• You can calculate the torque from an arbitrary point of reference. The resulting number will change, but as long as you rotate the ship around this point, which need not be the center of mass, the physical behaviour will not. In fact, without information on the mass distribution, the center of mass is arbitrary itself and cannot be calculated as such. – Marcks Thomas Oct 27 '12 at 17:04