- Home /
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 :)
I'm not exactly sure what this would mean in the real world. I guess you're saying "pretend there's a rigid line with zero mass between the object and this position, and apply a torque at this position"?
This could become complicated because you would have to calculate the moment of inertia of the object relative to the point in space you apply the offset torque. Is it desired behaviour for you that the further you are from the center of the object, the less torque is applied as a result?
What, exactly, are you trying to do?
Thanks for your comment:)
What, exactly, are you trying to do?
i'm trying to simulate a quadcopter. i have a rotating motor at a known position attached to the rigidbody and offset from its center of mass. a rotor is attached to the motor and I can calculate the "thrust" (parallel to the motor axis).
But the motor should also transfer a torque (in the exact opposite turning direction of the turning direction of the rotor) to the rigidbody and that's what i'm trying to calculate.
Is it desired behaviour for you that the further you are from the center of the object, the less torque is applied as a result?
Yes, i guess the farther the motor is from the center of mass the more of the "energy" will be transformed to a translation of the rigidbody.
Answer by Lockstep · Feb 27, 2013 at 11:49 PM
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.
The original post was pretty wrong. This version should be fixed now.
Hey thank you very much for your detailed answer. :)
I will try it out as soon as i get to my pc!
Edit: Works perfectly :)
I don't understand what the following means "Then, if hinge does not point into (1,0,0)...", at what point do you use the torque variable passed into the function and why do you say " Remember the right hand rule to find the direction of the new vector"? What do you need that for? Basically I'm having a hard time translating the explanation into code.
For your first question, he's using the direction of the hinge and a random other direction to create a coordinate system by doing cross products. If you have two vectors that are pointing in the same direction, cross products will fail, so he gives you a backup vector for that edge case.
The right hand rule is used in cross products. Just go to the Wikipedia page ( http://en.wikipedia.org/wiki/Cross_product ) and do a search for right hand rule to find the applicable explanation.
Thanks for replying but I'm still confused and missing answers. The hinge is just the position in world coordinates I want to torque around correct? When you say direction of the hinge is that relative to the world origin? Am I to normalize it and check it doesn't exactly equal (1,0,0) or am I understanding the answer wrong?
I still don't see where you actually use the torque variable that gets passed in. Without it being used in any of the equations described how can the forces be calculated at all?
Finally I understand the use of cross product but do I need to do anything with the result of "Vector3.Cross on 0.5*hinge and ortho" before using it as the force in AddForceAtPosition? The description implies I need to know the direction of this but not what to do with it afterwards.
Answer by Flynn · Jul 22, 2015 at 10:16 PM
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. :)