add torque at position

Hey,

Rigidbody has a nice helper function AddForceAtPosition but sadly a similar function AddTorqueAtPosition is missing.

AddTorqueAtPosition should work exactly like AddForceAtPosition, thus changing not only the angular momentum but also resulting in a translation when the position is off from the center of mass.

I’m not sure how to implement this function. Any help would be cool :slight_smile:

This works pretty much like spinning a pencil on the table. Try it. You will place two fingers on the opposite side of the pencil and push in the opposite direction. This results in a torque around the point in the middle of your fingers.

Your custom AddTorqueAtPosition function needs to do the same thing. I’ll call the position of the added torque hinge and the axis of the rotation torque now.

First you need to find two vectors which are orthogonal to torque and to eachother. This is a bit tricky if you don’t know the direction of hinge. I’d suggest to copy hinge into a dummy vector. Then, if hinge does not point into (1,0,0) use dummy and ortho = new vector3(1,0,0) in Vector3.OrthoNormalize(dummy, ortho). Otherwise use (0,1,0) as ortho. The last vector force can be found by using Vector3.Cross on 0.5*hinge and ortho. Remember the right hand rule to find the direction of the new vector. We use half the vector in our calculation, because we will use force twice.

Now you can use addForceAtPosition. The parameters are: force is simply the force vector we calculated, position is the position of hinge + ortho. Do the same thing again with -force and hinge - ortho.

Your complete AddTorqueAtPosition function should take a vector3 torque , a vector3 hinge and a Forcemode which you can pass to the addForceAtPosition funktions.

This is 100% crafted by theory, so let me know whether this works or not.

TL;DWR:

Use AddTorque without considering what point on the object you are applying torque at. This is the physically correct way to do it, and is equivalent to Lockstep’s solution, except that it is guaranteed to have the correct magnitude of torque.

Explanation:

While Lockstep’s answer is a clever solution, I am sure there are those out there, who, like me, are looking for a solution that is backed by the laws of physics and mathematics. One advantage of this type of solution is that we can directly apply the correct torques and forces without using separate and opposite force applications designed to simulate such torque changes.

Before we can begin, we need to figure out what is actually meant by AddTorqueAtPosition.

This is easily defined by imagining that there is some mass M at some position. Next, we imagine that our rigid body applies some torque T to this object. Since there is an equal and opposite reaction to every action, there must be some kind of torque applied back onto our rigidbody. This torque is what we mean by “AddTorqueAtPosition”.

Now, we know something very important about the nature of this torque and force – whatever it is, it must NOT violate conservation of momentum, angular or otherwise. Traditionally speaking, this means that we must ensure that the net angular momentum and net momentum of our system stays the same.

The problem with this is that the mass we are spinning does not actually exist – thus, what we really want, is for our net angular momentum to be decreasing, at any point in time, by the amount of torque which we are applying to our imaginary object at that same point in time.

Literally, this means that whatever torque we apply to our imaginary object, we simply use AddTorque to apply the negative of this torque to our rigidbody. Since the torque we are applying to our object is actually, itself, opposite to the force we plug into AddTorqueAtPosition, the first step of our function, is simply to directly add this torque – not even the negation is required.

This has nice symmetry with AddForceAtPosition. AddForceAtPosition merely starts by simply directly applying the force you are adding to the object, and then follows this up by calculating the change in torque that this same force causes as well.

Now that we know how much torque is applied to our rigidbody, when we apply torque at a position, we must identify how much force is applied.

This requires some complex conceptual thinking – first of all, we have to recognize that, at any given point in time, we are NOT applying any force to our imaginary object. Certainly, the torque we apply would cause our rigidbody to spin, and thus the location of our imaginary object to change, and thus, we would see force being applied to both our rigidbody and our imaginary object, to account for this change in position. The reality of the matter is, though, that this acceleration of the center of mass of our rigidbody is merely caused by our imaginary object also having mass, which changes the center of mass of our system. Thus, to actually simulate this scenario, we need only transfer the mass of our imaginary object over to our rigidbody, thus changing its center of mass to the true system center of mass, and then pretending our imaginary object has zero mass. Since the center of mass is now the true system center of mass, we need not simulate position changes to the rigidbody anymore – the correct changes in relative object position are implied by the new center of mass. Even though the now massless imaginary object has no mass, it can still gain angular momentum, since we are directly applying torque – it’s angular velocity will simply be undefined.

This has a very peculiar effect! it means that, in the end, no matter what point we “apply torque at”, this is completely identical to simply applying the same torque to the center of mass of the object. I, myself, find this quite surprising, as I write this, but it is true, and it explains why Unity doesn’t offer an “AddTorqueAtPosition” function. Such a function would be useless!

Even Lockstep’s solution exhibits this behavior… Go ahead, try it! If you use AddForceAtPosition with two opposite forces, at any two points, you will notice that your rigidbody spins, but does not change position at all. Our symmetry with AddForceAtPosition truly is lost. In fact, Lockstep’s solution is practically identical in effect to simply using AddTorque – No matter what point at which you apply torque with his technique, not only will no net force be applied, but the same exact amount of torque will be applied. The only real difference is that, if you are not careful, the magnitude of this torque will not equal the magnitude of the torque vector you plug in. There may also be some floating point uncertainty issues that arise from the mathematics involved in computing AddForceAtPosition, but these will be nominal.

The Lesson To Be Learned

Just use AddTorque – don’t even worry about what position you’re applying torque to, it won’t make a difference.

Just watch out! If you’re using this to simulate two objects being connected by, say, a motor, make sure that you take the appropriate steps to ensure conservation of linear momentum. In the case of an object centered on our pivot point (like our imaginary object), this is as simple as making the imaginary object just a visual affront, and transferring its mass over to the main rigidbody. I’m not quite sure what would be involved with two objects connected at a pivot point that is mutually off-center-of-mass.

P.S: I actually came across this issue myself doing propeller simulations too! Though in my case, I’m doing underwater ROV simulations, instead of quadcopter sims. :slight_smile: