- Home /
How to get local angularVelocity?
Basically I have a spaceship which can gyrate in all directions, and I need to counteract those forces by AddRelativeTorque. Is there a way to get local angularVelocity?
Thank you.
To clarify - where does AddRelativeTorque adds its torque, and how can I see it?
Edit: Comments doesn't allow formatting I'll add this here.
Upon further examination, this actually produces the same results as working with angularVelocity. It works only when ship is looking forward toward its original rotation. As soon as it clears 90 degree rotation in either way everything breaks.
pos = gameObject.transform.Find("Thrusters/FrontTopCon/FrontTop").localPosition;
relVel = MyShip.rigidbody.GetRelativePointVelocity(pos);
MyShip.rigidbody.AddForceAtPosition(-relVel / 2, pos, ForceMode.Force);
When ship is looking forward this does slow it down, but when more then 90 deg. either way it speeds up.
"local angular velocity" is meaningless in this universe.
note that in unity, the concept "local" velocity, is very simple - it means nothing more than your velocity, subtracting, your parent's velocity. that's all "local" velocity means in Unity
you could (if for some reason you wanted to) take the angular velocity of an object and - if for some reason you wanted to - "subtract" the angular velocity of the parent. this is incredibly strange mathematics and you have to have deep understanding to do so! if you did it on an "axis by axis basis" it could make some sense. if they are both spinning on the same axis, it would make sense.
"AddRelativeTorque" adds torque at the center of mass - which is the only way torque can work in this universe
Answer by duck · May 10, 2010 at 02:54 PM
I don't think there is such a thing as "local angular velocity".
Angular velocity is the velocity at which the rigidbody is rotating around its centre of mass. An object can only ever be rotating around a single point, so as far as I can figure, there couldn't really be a meaningful value for anglar velocity at any other position.
If an object isn't rotating around its own centre of mass, but around some other point, it means a force is acting on it to cause the centre of mass to move in a curved path, and - even then - the physics engine still deals with this by describing the movement as a combination of angular velocity around the centre of mass, and linear velocity in the direction of travel.
You can however get the local velocity at any point in relation to the object's combined velocity and angularVelocity, which may be what you're looking for. Use rigidbody.GetPointVelocity to do this.
For example: if an object is spinning, but not moving along through space, the local velocity of a point near its edge will be in the direction of the rotation.
Another example, if a cylindrical rigidbody is rolling along a smooth surface, its local velocity measured at its top will twice the object's velocity (because the top edge is moving forward in the direction of travel), and the local velocity measured at the point where it's touching the ground will be zero.
To correct the spin of a spaceship which is spinning through space, you could read the local velocity at the booster's world space position, and then apply a force in the opposite direction to the velocity found, at the booster's position (using rigidbody.AddForceAtPosition). Because this force is applied off-centre from the centre of mass, it will result in angular velocity, which should correct the spin.
If the booster is supposed to be fixed in orientation, you could map the local velocity at that position on to the booster's forward direction vector, and only apply a force based on the Z value found. This means the booster would only correct angular motion in the direction in which it was facing.
Thanks, that was very helpful, and actually more realistic solution :) I was getting desperate and looking into neural networks to "$$anonymous$$ch" thrusters to correct the ship. Phew...
This does not actually answer the question, and there is definitely such thing as "local angular velocity".
Rigidbody.angularVelocity gives you the velocities around the worldspace X,Y, and Z axis. If your object is tilted in any way, these will be different from the local axis, which are based around your object's transform.right, transform.up, and transform.forward.
RavenBlack's answer is actually correct here.
I reckon there is such a thing as local angular velocity. Consider a ferris wheel spinning. It has angular velocity with respect to the ferris wheel's hub, the center of the earth, and the sun. In each frame of reference it has an angular velocity. Presumably the local angular velocity, in this case, would be the velocity with respect to the wheel's hub.
There is no such thing as "local angular velocity" - ask a physicist.
However, yes, imagine you have a cylinder which is spinning in unity, and inside that another is spinning. Sure, you could describe the difference as "local angular velocity difference".
Note that the whole thing is moot - the OP need only apply torque against the current angular velocity, it's that simple.
Answer by RavenBlack · Apr 13, 2012 at 10:56 PM
I think I disagree with Ben's answer (though I'm wrestling with parts of this question too). If there's no such thing as "local angular velocity" then why are there both "AddRelativeTorque" and "AddTorque"? I think what Fogsight might have been looking for is the equivalent 'Get' function for the current spin - rigidbody.angularVelocity is effectively the 'get' equivalent of AddTorque, and there is no equivalent to get the angular velocity relative to the parent object.
Ben's answer probably provided a better solution to the actual problem, but I think the answer to the actual question is to do something like
Vector3 localangularvelocity =
transform.InverseTransformDirection(rigidbody.angularVelocity).normalized
* rigidbody.angularVelocity.magnitude;
(There may be a better way and this may be horribly wrong since, as I say, I'm wrestling with stuff related to this myself right now.)
Edit: looks like the length of the vector (which is the magnitude of the angular velocity) is preserved through TransformDirection functions (I wasn't sure) so this simpler version will work:
Vector3 localangularvelocity = transform.InverseTransformDirection(rigidbody.angularVelocity);
Thank you, this does in fact answer the question as asked and was useful to me.
Definitely brilliant answer. As well were searching while for such solution.
Thank you. I am directly applying angular velocities to a ghost replay as I cannot rely on the physics engines deter$$anonymous$$istic behavior. Unfortunately the parent orientation is different during replay - hence the need for 'local' rotation. This should be the correct answer. Edit: applying this solution for my case -
// recording
localAV = parentObject.transform.TransformDirection (rb.angularVelocity);
// playback
rb.angularVelocity = parentObject.transform.TransformDirection (localAV);
@duck may give the better solution to the problem in its given context, but this is the answer to the question posed.
Answer by Murpheus · May 29, 2014 at 12:17 AM
Hi, the concept of angular velocity about a point is misleading I think. In everyday physics, the angular velocity is the a rate of spin about an axis, not a point. Angular velocity has a magnitude (rate of spin) and a direction (the axis).
I think that paired with Quaternions, the concept of Angular Velocity about a point is valid. Its simply spinning with respect to all axis combined in to one term.
Answer by TonicMind · Dec 28, 2015 at 02:26 AM
link text@FogSight I'm pretty sure I do have an answer for you. I was searching for it too, and now I've got it (with proof!).
I want to add that the code above does not work. I have worked my own solution though:
Vector3 localAngleVelo = experimentalShip.transform.InverseTransformVector(experimentalShip.GetComponent<Rigidbody>().angularVelocity);
That code will get you the local angular velocity of your object. The code posted by RavenBlack only gets you the same value you put in.
I'm 90% certain what I've got is right. I just tested it in Unity, by printing the values of both the Rigidbody angular velocity (which is in world space) and the result of this code. I used AddRelativeTorque to add to my rotation, so when I did rotate it would be added locally.
Fact: One cannot rotate on more than one axis. However to have something to refer to we need some local axes. World space is always the major reference, Ie. the rotation/position/scale of everything else is based on it. When we rotate something, then the axes local to our object change their orientation in world space. In order to apply torque (rotational velocity) to our object we must know the relation from our local reference axes to world space. Otherwise if we rotated while not on a strict world space axis (ie. straight up/down on X-axis world space) then when we rotated on two axes the rotation would be applied relative to world space instead of locally to our object!
That would be like an aircraft being controlled by external controls rather than its own! Imagine a plane like that, it would be at the mercy of the winds!
The way that I tested this was: I set up my experimentalShip object to be controlled via AddRelativeTorque. That meant that when I wanted to rotate, then it was controlled from its orientation/reference axes than outside axes (like world space). I printed the result of this code and the angularVelocity of the experimentalShip object (which is in world space remember). When I rotated to an odd orientation, instead of on one axis I could see the difference between the local calculation and what the AngularVelocity values were.
I could see that when I applied rotation, the angular velocity values changed to reflect the objects world space rotation. The local angular velocity value that I printed was zero on the axes I knew I wasn't rotating by, and non-zero on axes I knew that I was rotating by. So when I was rotating directly left to right from my point of view, but the object was actually oriented at an odd angle in world space, then the Y-axis value was non-zero, while Z and X were zero in my local value print-out!
This is all in Unity 5.3.0f4 .
I'm posting the project as proof-of-concept. Pay attention to the output in the console.
Your answer
Follow this Question
Related Questions
Accessing local system ( File Browser ) 2 Answers
How to get a rigidbody's Local Angular Velocity (Yaw, Pitch & Roll) ? 1 Answer
AddRelativeTorque results in incorrect angular acceleration (Maybe centrifugal force affects) 0 Answers
Using Torque to kill Angular Velocity 2 Answers
What factors have an affect on the AddRelativeTorque()? 0 Answers