WorldViz User Forum

WorldViz User Forum (https://forum.worldviz.com/index.php)
-   Vizard (https://forum.worldviz.com/forumdisplay.php?f=17)
-   -   Quaternions (https://forum.worldviz.com/showthread.php?t=1509)

roman_suvorov 05-23-2008 02:41 PM

Quaternions
 
Hello, can anyone tell me the exact meaning of the [x,y,z,w] components of a quaternion returned by a .getQuat() function? I am particularly interested in the range these values can take, especially w.

This might seem like a silly question, but are the two quats returned in this script in the exact same format (i.e., same ordering of components, scaled in the same way, etc.)?
Code:

...
inertiaCube = viz.add('intersense.dls') # Add inertiaCube
print inertiaCube.getQuat() # 1st quaternion
vicon = viz.add('vicon.dle', 0, ipAddressAndPort) # Add the Vicon system
firstBody = vicon.getBody(0) # Get the first body
print firstBody.getQuat() # 2nd quaternion
...


farshizzo 05-27-2008 05:51 PM

The meaning of the x,y,z,w components of a quaternion are similar to the meaning of axis-angle components. the [x,y,z] values represent the axis of rotation. The amount of rotation about that axis in radians is, 2 * acos(w). Keep in mind that Vizard uses a left-handed coordinate system.

All the plugins should return quaternions in the same order (x,y,z,w). I'm assuming most devices will return normalized quaternions as well, but I'm not 100% sure about that.

roman_suvorov 05-28-2008 10:51 AM

Thanks farshizzo, I appreciate it.
Now knowing that my math is all wrong you can disregard the script I've sent you (as mentioned here).

roman_suvorov 06-11-2008 05:34 PM

All right, I've read QUITE A BIT about quaternions at this point but still don't get them .. :(

Here's some sample code. Copy/paste and run this:

Code:

import viz
viz.go(viz.FULLSCREEN)

ROTATION_INC = 2
TRANSLATE_INC = 0.1

i = 0
while (i < 50):
        redBall = viz.add("white_ball.wrl")
        redBall.setPosition([i, 0, 0])
        redBall.color([255, 0, 0])
       
        greenBall = viz.add("white_ball.wrl")
        greenBall.setPosition([0, i, 0])
        greenBall.color([0, 255, 0])
       
        blueBall = viz.add("white_ball.wrl")
        blueBall.setPosition([0, 0, i])
        blueBall.color([0, 0, 255])
       
        i += 0.1
       
viz.MainView.setQuat([0,1,0,0])
viz.MainView.setPosition(5, 0, 0.5)
       
vizact.whilekeydown(viz.KEY_UP, viz.move, 0, 0, TRANSLATE_INC)
vizact.whilekeydown(viz.KEY_DOWN, viz.move, 0, 0, -TRANSLATE_INC)
vizact.whilekeydown(viz.KEY_LEFT, viz.rotate, viz.BODY_ORI, -ROTATION_INC, 0, 0)
vizact.whilekeydown(viz.KEY_RIGHT, viz.rotate, viz.BODY_ORI, ROTATION_INC, 0, 0)
vizact.whilekeydown(viz.KEY_PAGE_UP, viz.rotate, viz.HEAD_ORI, 0, -ROTATION_INC, 0)
vizact.whilekeydown(viz.KEY_PAGE_DOWN, viz.rotate, viz.HEAD_ORI, 0, ROTATION_INC, 0)

You will see a red "line" in front of you. Look around using left/right arrow keys, tilt your "head" up/down using PgUp/PgDown keys, move forward/backward using up/down arrow keys.
What this is meant to be is "training grounds" for understanding quaternions. If you look at the code inside the while loop you'll see that X-axis is traced with red dots, Y with green, Z with blue (X-Y-Z -> R-G-B was my logic :o).
MainView's originally just slightly off red Y-axis and the rotation is set to [x,y,z,w] = [0,1,0,0].
What I'm trying to understand now that we have a well-defined system of coordinates right in front of us :) is how quaternions work: [0,1,0,0] SHOULD have defined a rotation of 0 degrees around axis [0,1,0] - the Y-axis, so the camera originally should just look down the green Y-axis. Instead we're looking down X!
I hope someone more experienced with quaternions can explain to me how they work in Vizard using this simple script, that would be great. Thanks!

farshizzo 06-11-2008 05:48 PM

In my previous post I explained what the values mean. So given the quaternion rotation of [0,1,0,0], this would mean a 180 degree rotation around the Y axis (2 * acos(0) = 180 degrees). Printing the euler and axis-angle values of the main view after applying the quaternion will confirm this. Adding the following code at the end of the script:
Code:

print viz.MainView.getEuler()
print viz.MainView.getAxisAngle()

resulted in the following output:
Code:

[-180.0, 0.0, 0.0]
[0.0, -1.0, 0.0, 180.0]

FYI, Vizard color values range from 0-1, not 0-255.

roman_suvorov 06-11-2008 06:05 PM

Damn, forgot about that acos. Then to get no rotation I need to use w=-1: 2*acos(-1) = 360 degrees. Thanks again farshizzo!

EDIT: The following code makes MainView look down X.
Code:

import viz
viz.go(viz.FULLSCREEN)

ROTATION_INC = 2
TRANSLATE_INC = 0.1

i = 0
while (i < 10):
        redBall = viz.add("white_ball.wrl")
        redBall.setPosition([i, 0, 0])
        redBall.color([1 - 0.1*i, 0, 0])
       
        greenBall = viz.add("white_ball.wrl")
        greenBall.setPosition([0, i, 0])
        greenBall.color([0, 1 - 0.1*i, 0])
       
        blueBall = viz.add("white_ball.wrl")
        blueBall.setPosition([0, 0, i])
        blueBall.color([0, 0, 1 - 0.1*i])
       
        i += 0.1
       
viz.MainView.setQuat([0,1,0,-1])
viz.MainView.setPosition(5, 0, 0.5)
       
vizact.whilekeydown(viz.KEY_UP, viz.move, 0, 0, TRANSLATE_INC)
vizact.whilekeydown(viz.KEY_DOWN, viz.move, 0, 0, -TRANSLATE_INC)
vizact.whilekeydown(viz.KEY_LEFT, viz.rotate, viz.BODY_ORI, -ROTATION_INC, 0, 0)
vizact.whilekeydown(viz.KEY_RIGHT, viz.rotate, viz.BODY_ORI, ROTATION_INC, 0, 0)
vizact.whilekeydown(viz.KEY_PAGE_UP, viz.rotate, viz.HEAD_ORI, 0, -ROTATION_INC, 0)
vizact.whilekeydown(viz.KEY_PAGE_DOWN, viz.rotate, viz.HEAD_ORI, 0, ROTATION_INC, 0)

and also produces much prettier axes. :D Hold on though, why [0,1,0]? We're speciifying no rotation around Y, not X as it seems?

farshizzo 06-12-2008 10:02 AM

Now you're dealing with non-normalized quaternions, so all bets are off. In general, you don't need to deal with quaternions at such a low level. You can use Vizards matrix routines to deal with rotation transformations.

roman_suvorov 06-17-2008 10:13 AM

Quote:

Originally Posted by farshizzo (Post 5773)
Now you're dealing with non-normalized quaternions, so all bets are off.

Do you then know by any chance what course of action does Vizard take if you try to set an object's quaternion to [x,y,z,w] such that x^2+y^2+z^2+w^2 > 1?
For example, add this function definition to my previous code:
Code:

# Normalizes the passed quaternion (which is assumed to have the form
# [x,y,z,w]) so that the vector [x,y,z,w] has unit length.
# Note: normalization is done in place (i.e., the correct way
# of calling this function is 'normalizeQuat(q1)' rather than 'q1 = normalizeQuat(q2)'.
def normalizeQuat (quat):
        i = 0
        normFactor = 0
        while (i < len(quat)):
                normFactor += quat[i]**2
                i += 1
        normFactor = normFactor**0.5

        i = 0
        while (i < len(quat)):
                quat[i] /= normFactor
                i += 1

Now if you normalize quat [0,1,0,-1] we get the same MainView orientation as with the unnormalized quaternion. Is this behavior expected? Does a function similar to my 'normalizeQuat' get called in Vizard behind the scenes if you try to set an object's quaternion to an unnormalized one?
Quote:

Originally Posted by farshizzo (Post 5773)
In general, you don't need to deal with quaternions at such a low level. You can use Vizards matrix routines to deal with rotation transformations.

Unfortunately, seems like I do. This little script is just a way to fill in the gaps I have in my understanding of quaternions.

farshizzo 06-17-2008 10:40 AM

Yes, Vizard will internally normalize all quaternions that are passed to the setQuat function of nodes, views, and bones.


All times are GMT -7. The time now is 10:02 AM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Copyright 2002-2023 WorldViz LLC