Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
2
Question by PeterReeves · Nov 01, 2014 at 03:33 AM · rotationaccelerationtorquecalculatetensor

Calculating the rotational acceleration from torque

I'm trying to write a function that takes a Vector3 of torque and calculates the resulting radial acceleration in radians per second per second. I understand that I'll need to use the rigidbody.inertiaTensor and rigidbody.inertiaTensorRotation to do this, but I don't know how they work. Does anybody know how to do this? I would like it to be as accurate as possible. I imagine the signature of the function would be something like the below.

 public static Vector3 TorqueToAcceleration(Vector3 torque, Vector3 inertialTensor, Quaternion inertialTensorRotation, float rigidbodyMass) {
     // Magic happens here
 }
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by PeterReeves · Nov 05, 2014 at 10:38 AM

Well, I manged to find an answer.

Thanks to help from a friend, the vector seems to contain an object's resistance to being rotated on each axis, and the quaternion only changes if you have a shape that is not symmetrical.

 // copied from comment below
 public static Vector3 TorqueToAcceleration(Vector3 relativeTorque, Vector3 inertialTensor, Quaternion inertialTensorRotation) {
     inertialTensor = inertialTensorRotation * inertialTensor;
     
     float x = Mathf.Abs(relativeTorque.x / inertialTensor.x);
     float y = Mathf.Abs(relativeTorque.y / inertialTensor.y);
     float z = Mathf.Abs(relativeTorque.z / inertialTensor.z);
     
     return new Vector3(x, y, z);
 }
Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Nimred · Oct 17, 2015 at 04:25 PM 0
Share

Nice, I was looking for this... but why * 50.0f? It seems a bit magical...

avatar image PeterReeves Nimred · Oct 18, 2015 at 12:28 AM 1
Share

The * 50.0f was there since the default physics timestep is a 50th of a second.

I've updated the code by the way (the original I posted turns out to be not quite correct):

 public static Vector3 TorqueToAcceleration(Vector3 relativeTorque, Vector3 inertialTensor, Quaternion inertialTensorRotation) {
         inertialTensor = inertialTensorRotation * inertialTensor;
         
         float x = $$anonymous$$athf.Abs(relativeTorque.x / inertialTensor.x);
         float y = $$anonymous$$athf.Abs(relativeTorque.y / inertialTensor.y);
         float z = $$anonymous$$athf.Abs(relativeTorque.z / inertialTensor.z);
         
         return new Vector3(x, y, z);
     }
avatar image Nimred PeterReeves · Oct 18, 2015 at 11:18 AM 1
Share

Thanks, but now I have to wonder why there's a $$anonymous$$athf.Abs :) Angular acceleration should be a Vector3 representing the axis of rotation, multiplied by an amount of rotation around that axis... So the values shouldn't always be positive.

On the other hand, I tried to invert the answer from this question, which solves how to find the (world space) angular acceleration from torque:

 Quaternion tensorRotationWS = rigidbody.transform.rotation * rigidbody.inertiaTensorRotation;
 Vector3 torque = tensorRotationWS * Vector3.Scale(rigidbody.inertiaTensor, Quaternion.Inverse(tensorRotationWS ) * angularAcceleration );

I don't completely understand it, so I don't really know if it's correct - but it works ingame. Converted to relative torque, with a world-space angular acceleration input, it should be this:

 Quaternion tensorRotationWS = rigidbody.transform.rotation * rigidbody.inertiaTensorRotation;
 Quaternion tensorRotationLS = rigidbody.inertiaTensorRotation;
 Vector3 relativeTorque = tensorRotationLS * Vector3.Scale(rigidbody.inertiaTensor, Quaternion.Inverse(tensorRotationWS) * angularAcceleration);

Once inverted to convert relative torque to angular acceleration, I get this:

 Quaternion tensorRotationLS = rigidBody.inertiaTensorRotation;
 Vector3 tensorLocalTorque= Quaternion.Inverse(tensorRotationLS) * relativeTorque;
 
 Vector3 tensorLocalAcceleration; 
 tensorLocalAcceleration.x = tensorLocalTorque.x / rigidbody.inertiaTensor.x;
 tensorLocalAcceleration.y = tensorLocalTorque.y / rigidbody.inertiaTensor.y;
 tensorLocalAcceleration.z = tensorLocalTorque.z / rigidbody.inertiaTensor.z;
 
 Vector3 angularAccelerationLS = tensorRotationLS * tensorLocalAcceleration;
 Vector3 angularAccelerationWS = transform.rotation * angularAccelerationLS;

Unfortunately since this is based on a formula I don't fully understand, I can't be 100% sure that it's right. The inversion itself is consistent, so that when I convert an acceleration to torque and back again I get the same acceleration; and it also works properly with my spaceship ingame. But I can't explain the differences with your formula...

Show more comments
avatar image
0

Answer by Bunny83 · Oct 18, 2015 at 02:32 PM

Converted the comment into an answer.

@Nimred
Yes, it seems you're right ^^. I just copied his comment into the question but hadn't a closer look at what he has done there. Your code looks right to me.

Vector3.Scale just does a component wise multiplication. So Vector3.Scale(A,B) == new Vector3(A.x*B.x, A.y*B.y, A.z*B.z); So one vector scales the other component wise.

Unfortunately there's no component wise reciprocal operator or method. However we could simply write one ^^:

 public static class Vector3Extension
 {
     public static Vector3 Reciprocal(this Vector3 v)
     {
         return new Vector3(1f/v.x, 1f/v.y, 1f/v.z);
     }
 }

With that helper method I've created this method which seems to be correct:

 public static Vector3 ApplyTensor(Rigidbody rb, Vector3 worldAcceleration)
 {
     var q = rb.transform.rotation * rb.inertiaTensorRotation;
     var qi = Quaternion.Inverse(q);
     var acc = qi * worldAcceleration;
     acc = Vector3.Scale(acc, rb.inertiaTensor.Reciprocal());
     return q * acc;
 }

I've created a test scene where i added two identical rigidbodies. In FixedUpdate i used

     R1.AddTorque(torque,ForceMode.Force);
     
     acc = ApplyTensor(R2, torque);
     R2.AddTorque(acc, ForceMode.Acceleration);

And the result is identical. Even when i select both objects, the inspector shows all rotation values as identical. I also tested with a rotated tensor.

edit
The following is actually wrong ^^. I was under the impression that the inertia tensor just contains the "mass distribution" for a given collider setup and the mass would be somehow included in the actual calculation when a force is "converted" to the angular acceleration. However it turns out that it's not possible to linearly "scale" the inertia tensor by the actual mass.

So what Unity / Physx does is to calculate the inertia tensor based on the given mass and collider setup. The tensor already contains the mass. So the above method is actually correct.

It seems that the "acceleration" mode for torque is internally also dividing the acceleration by the rigidbodies mass. That actually must be a bug in Unity. See ForceMode. The acceleration is not dependent on the mass, only forces are. So usually to get the real "acceleration" you would need to divide by the mass as well.

The same thing seems to apply for "VelocityChange". VelocityChange and Acceleration both ignore the tensor but still divide by the mass.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Compute the torque needed to rotate an object at a constant rate 3 Answers

Input.acceleration Y and Z are the same? 1 Answer

How to get a ball with physics2d to move instead of spin? 1 Answer

Rigidbody Turning 2 Answers

Rotate a rigid body while it's constrained. 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges