Comments and answers for "Compute the torque needed to rotate an object at a constant rate"
http://answers.unity.com/questions/1413778/compute-the-torque-needed-to-rotate-an-object-at-a.html
The latest comments and answers for the question "Compute the torque needed to rotate an object at a constant rate"Comment by Bunny83 on Bunny83's comment
http://answers.unity.com/comments/1419892/view.html
In this case you could simply set the angularVelocity to your target velocity. You don't really apply a constant force or acceleration. It's just a more complicated way to say:
body.angularVelocity = targetAngularVelocity;
Velocity change is basically just this:
body.angularVelocity = body.angularVelocity + (targetAngularVelocity - body.angularVelocity);
The term in brackets is your supplied velocity delta. As you can see the old angular velocity just cancels and you effectively just setting the angularVelocity to your target velocity.Thu, 12 Oct 2017 23:55:02 GMTBunny83Comment by ImpOfThePerverse on ImpOfThePerverse's answer
http://answers.unity.com/comments/1419729/view.html
Sorry for not answering questions about the other solution, I was posting a solution to the underlying problem. The code I supplied does rotate the object at a constant speed - the target rotation, bodyRotationY, is incremented every frame, so the object keeps rotating to keep up. rotationRate specifies the rotation rate, in degrees per second.
Looking over what you posted again though, it looks like the easiest way to do it would be to use ForceMode.VelocityChange:
public Vector3 targetAngularVelocity;
public Rigidbody body;
void FixedUpdate()
{
AddTorque(targetAngularVelocity - body.angularVelocity, ForceMode.VelocityChange);
}
The difference between that and the code I already posted is that ForceMode.VelocityChange will cause the object to immediately rotate at the desired rotation, and never deviate from it regardless of other applied torques. I'm not sure why you want to use torque rather than kinematics, but if you want it to look realistic and interact with other torques (the two primary advantages of using torques rather than kinematics) the PID code is better.Thu, 12 Oct 2017 16:13:03 GMTImpOfThePerverseAnswer by Bunny83
http://answers.unity.com/answers/1419681/view.html
I'm not sure you fully understand the difference between velocity, acceleration and force. If the object **doesn't** have any angular drag, once the object has a certain angular velocity it keeps rotating at this speed forever (same with linear velocity and drag). You only need to constantly apply a force if there is any kind of counter force. So if you just want the object to rotate freely, don't set any drag. For example objects in space would have 0 drag and 0 angular drag. You kick them off and they keep moving / rotating until the end of time (or some external force might hit them, like a collision)
If you do use any angular drag you have an actual counter force which depends on the current velocity. So you would have to constantly accelerate the object to keep it moving. In this case the object will always reach some final angular velocity as long as you apply a constant torque to it. However you will always approach that final angular velocity slowly. The closer you get to that velocity the smaller the change will get. At some point the drag and the acceleration cancel each other so the net force is 0 and the object will keep it's current speed.
Actually calculating which torque is needed to reach a certain final velocity is a bit tricky as the torque that is required depends not only on the inertia tensor of the object but also on the way how the drag is actually applied.
Here's basically the solution:
First you have to calculate the required acceleration or velocity change that has to be applied each (physics) frame. How to do that, see [my answer over here][1]. The question over there was about linear motion but the same formula applies to angular velocity.
Note that unlike when dealing with linear velocity you can not just multiply the acceleration with the mass of the object to get the actual torque. For this you have to use the inertia tensor. I haven't checked [the answer you already linked in your question][2] but something like that would be required if you really want to use a torque.
Note that the **smaller** the angular drag value is the **slower** you will approach the final velocity. If the drag is 0 you can't apply any force to keep a constant velocity. That's why using a PID controller would probably be the better choice.
Also keep in mind if the angular drag value is set to a value equal or greater than the physics framerate you can't rotate the object at all as the drag would cancel 100% of the angular velocity each frame.
***edit***
If you still want to go the "force route" I'll explain a bit about the inertia tensor.
A [Tensor][3] can be seen as a generalisation of most other mathematical structures. A tensor of order 0 is basically just a single value or scalar. A tensor of order 1 represents a vector. Note that the order doesn't specify the dimension. A 4D vector or a 100D vector is still a tensor of order 1. A tensor of order 2 is a matrix. Again the dimensions are not specified here. So a 2x2 and a 20x42 matrix are both tensors of order 2.
A rigidbody actually has a [3x3 matrix of inertia][4] to specify the moment of inertia for all 3 primary axis at an arbitrary rotation. However instead of using a 3x3 matrix we actually specify a single Vector3 which specifies the moment of inertia for each principal axis.
However this becomes a problem when the object isn't nicely aligned with the local coordinate axis. This is where the tensor rotation comes into play. It actually rotates the local coordinate system so the local axis are aligned with the actual object. This is especially necessary when you have compound colliders which are arranged in a not symmetrical way. The physics system has to combine the moments of inertia for all child objects which may also be rotated arbitrarily. The resulting moment of inertia is probably not aligned with the local coordinate axis of the rigidbody.
Now have a look at the two lines:
Quaternion q = transform.rotation * rigidbody.inertiaTensorRotation;
T = q * Vector3.Scale(rigidbody.inertiaTensor, (Quaternion.Inverse(q) * w));
"q" is a rotation that rotates from local "tensor space" to worldspace. If the actual inertia tensor is aligned with the local axis the intertiaTensorRotation would be Quaternion.identity. So in this case "q" just transfers from local to worldspace.
This is what happens in order in the second line:
- we transform "w" from worldspace into "tensor space". So each axis of our acceleration will be aligned with the principal axes of the inertia tensor. This is done by multiplying the inverse of "q" with "w"
- Now we scale the resulting vector by the inertia tensor component wise using Vector3.Scale
- Finally we just convert the acceleration vector back into worldspace by multiplying q with our scaled vector.
[1]: http://answers.unity3d.com/answers/819474/view.html
[2]: http://answers.unity3d.com/answers/49388/view.html
[3]: https://en.wikipedia.org/wiki/Tensor
[4]: https://en.wikipedia.org/wiki/Moment_of_inertia#Inertia_matrix_in_different_reference_framesThu, 12 Oct 2017 14:07:35 GMTBunny83Comment by zuraneur on zuraneur's answer
http://answers.unity.com/comments/1419506/view.html
Hello and thanks for your answer.
Bunny83 is right, you neither didn't answer to the question nor explaied things that I don't understand (listed with bullet points).Thu, 12 Oct 2017 07:43:26 GMTzuraneurComment by Bunny83 on Bunny83's answer
http://answers.unity.com/comments/1413918/view.html
Uhm, he does not want to reach a certain angle but simply rotate the object at a constant speed.Fri, 29 Sep 2017 19:21:18 GMTBunny83Answer by ImpOfThePerverse
http://answers.unity.com/answers/1413891/view.html
To do a PID system, compute a target angle and increment it to signify a rotation. Your torque will be proportional to how far your current angle of rotation is from your target angle, minus a component that is proportional to your angular velocity.
bodyRotationY += rotationRate * Time.deltaTime;
Vector3 currentRotation = body.transform.rotation.eulerAngles;
Vector3 currentVelocity = body.angularVelocity;
Vector3 yawTorque = (bodyRotationY - PlusMinus180(currentRotation.y, bodyRotationY)) * Mathf.Deg2Rad * torqueSpring * Vector3.up;
yawTorque -= (currentVelocity.y - bodyAVY) * torqueDamping * Vector3.up;
body.AddTorque(yawTorque, ForceMode.Force);
bodyRotationY is the target rotation. It starts at zero and gets incremented every frame. rotationRate is the rate of rotation. PlusMinus180 is a function that makes sure the angle read from the Euler angles is within 180 degrees of bodyRotationY. torqueSpring is a constant that will need to be tuned based on the mass of the rigidbody - higher values will cause the body to snap to the desired rotation more quickly, but will cause stronger oscillations. torqueDamping is the damping coefficient, it also needs to be tuned, with higher values cancelling out oscillations more quickly, but if it's too high it will cause the object to lag behind the desired rotation.
If your axis of rotation isn't the x, y, or z axis it gets a bit trickier.Fri, 29 Sep 2017 18:23:56 GMTImpOfThePerverseAnswer by FortisVenaliter
http://answers.unity.com/answers/1413844/view.html
Someone may post here later with a more correct solution, but the way I'd go about it would be as a PID system. Basically, it just incrementally changes the value to get it closer and closer to the target.Fri, 29 Sep 2017 16:51:39 GMTFortisVenaliter