PDA

View Full Version : Dtrack and avatar -coordinates question


sircedric4
08-25-2009, 07:46 AM
I am using the A.R.Track and Dtrack system to provide position data in WorldViz. I was able to get my avatars head to work with it correctly using setEuler on the headbone. When I go and try to add a left hand, I cannot get my avatar's left hand to match what my hand with the position sensor is doing.

For the record, I have swapped the Pos and Quat to work with Dtrack. (The documentation says I should use headTrkr.swapPos([1,2,-3]) and headTrkr.swapQuat([-1,-2,3,4]) but in order to make my head work correctly I ended up having to use headTrkr.swapPos([-2,3,1]) and headTrkr.swapQuat([2,-3,-1,4]).)

I have also been using the bone.setEuler in viz.AVATAR_WORLD mode so I do not believe that is the issue. Like I said, my head bone works 100% correctly and I applied the same transformations and such to my left hand with the other sensor.

I think my problem is that I do not understand how the coordinate system of the individual bones are modeled so that I can adjust my euler positions correctly.

Is there a printout or webpage or something that shows the vcc_male model with the x,y,z and yaw, pitch, roll coordinate system mapped onto each bone model?

I have done a thorough search of the board and saw someone else asking for this bone coordinates definition but I did not see where he got an answer. I have reached the limits of my patience with the trial and error technique and am now seeking assistance from anyone that might have already dealt with this problem.

farshizzo
08-25-2009, 09:59 AM
The following script will load an avatar and display the skeletal structure of its bones and the local coordinate system of each bone (r=x,g=y,b=z).import viz
viz.go()

def CreateSkeleton(avatar):

AXIS_SIZE = 0.03
viz.startlayer(viz.LINES)
viz.linewidth(2)
viz.vertexcolor(viz.RED)
viz.vertex(0,0,0)
viz.vertex(AXIS_SIZE,0,0)
viz.vertexcolor(viz.GREEN)
viz.vertex(0,0,0)
viz.vertex(0,AXIS_SIZE,0)
viz.vertexcolor(viz.BLUE)
viz.vertex(0,0,0)
viz.vertex(0,0,AXIS_SIZE)
axes = viz.endlayer()

points = []
lines = []

def traverse(bone):
points.append(bone)
for b in bone.getChildren():
lines.append((bone,b))
traverse(b)

#Collect list of bones for drawing points and lines
for b in avatar.getRootBoneList():
traverse(b)

#Create OTF object
viz.startlayer(viz.LINES)
viz.linewidth(1)
viz.pointsize(6)
viz.vertexcolor(viz.WHITE)

for l in lines:
viz.vertex(0,0,0)
viz.vertex(0,0,0)

viz.startlayer(viz.POINTS)

for p in points:
viz.vertex(0,0,0)

skeleton = viz.endlayer()
skeleton.dynamic()

#Link each vertex to corresponding bone
count = 0
for b1,b2 in lines:
viz.link(b1,skeleton.Vertex(count))
count += 1
viz.link(b2,skeleton.Vertex(count))
count += 1

for b in points:
viz.link(b,skeleton.Vertex(count))
count += 1
viz.link(b,axes.clone(),srcFlag=viz.ABS_GLOBAL)

axes.remove()

return skeleton

model = viz.add('vcc_male.cfg',alpha=0.7)

CreateSkeleton(model)

import vizcam
cam = vizcam.PivotNavigate(distance=3)
cam.centerNode(model)

#Toggle avatar mesh on space key
vizact.onkeydown(' ',model.visible,viz.TOGGLE)
I believe the actual problem is that you are not applying an offset rotation when transferring the sensor data to the avatar. If you are using viz.AVATAR_WORLD coordinates to apply the data, then keep in mind that the initial pose of the avatar is the zeroed rotation of the hand. If the zeroed rotation of your hand sensor is pointing in a different direction, then you will need to compute the rotation difference between the two and apply that offset when transferring the data.

If you are using link objects, then you will need to apply a preEuler operator to the link to get the data to match the avatar.

sircedric4
08-27-2009, 08:56 AM
...

I believe the actual problem is that you are not applying an offset rotation when transferring the sensor data to the avatar. If you are using viz.AVATAR_WORLD coordinates to apply the data, then keep in mind that the initial pose of the avatar is the zeroed rotation of the hand. If the zeroed rotation of your hand sensor is pointing in a different direction, then you will need to compute the rotation difference between the two and apply that offset when transferring the data.

If you are using link objects, then you will need to apply a preEuler operator to the link to get the data to match the avatar.

Thanks, I pretty much had the same conclusion but was having a hard time calculating what that rotation difference was, which is why I asked for the coordinate axis image. Thank you for the code, that helped as well as letting me know that the avatar initial position is 0 for all the coordinates involved. I am still trying to figure out the math but this did answer my question.

sircedric4
09-08-2009, 11:32 AM
Thanks, I pretty much had the same conclusion but was having a hard time calculating what that rotation difference was, which is why I asked for the coordinate axis image. Thank you for the code, that helped as well as letting me know that the avatar initial position is 0 for all the coordinates involved. I am still trying to figure out the math but this did answer my question.

The math for my problem is still driving me crazy. I obviously do not have a handle on whether to use quaternion, axis angle or euler to easily adjust my axis to match those of the hand. I am attaching a picture of the two points and how they relate to each other. The smaller red-blue-green lines is the avatar axis system, the larger red-blue-green lines are what my Dtrack is giving me for my euler position.

As you can see, I need to rotate the system around the green axis by 90 degrees in one direction, and then rotate the system 90 degrees around the new position of the blue axis in order to get my axis to match the avatar axis.

Can someone point me to a good, easy to understand reference/web site on how to get what rotation value I need, and which of the coordinate systems in Vizard will be easiest to use to do the rotation. It has not been as simple as just subtracting 90 from the euler numbers that represent the green and blue axis. I think I am probably supposed to use quarternion but I really could use some help.