AnimGraph getting Position of Characters


I am trying out the new features of AnimGraph. I have a scene with 2 characters connected to an Animgraph that makes them follow a series of points that I define in my ActionGraph. This works without a problem.

I would like now to access the information of the characters position in the scene programatically. For this I wrote the following code that I execute in the Script Editor:

import omni

stage = omni.usd.get_context().get_stage()

character1 = stage.GetPrimAtPath('/World/Character/Root/Root')
character2 = stage.GetPrimAtPath('/World/Character_01/Root/Root')

character_position1 = character1.GetAttribute('xformOp:translate').Get()
character_position2 = character2.GetAttribute('xformOp:translate').Get()


To my surprise this works only sometimes. I get sometimes both positions as ‘None’, and other times only one of them is correct and the other one is ‘None’. If I get rid of the ‘.Get()’ I see the following error (but as I said only sometimes):

[Info] [] [py stdout]: invalid attribute ‘xformOp:translate’ on ‘SkelJoint’ prim </World/Character/Root/Root> on stage

[Info] [] [py stdout]: invalid attribute ‘xformOp:translate’ on ‘SkelJoint’ prim </World/Character_01/Root/Root> on stage

Is this a bug or am I approaching this problem from the wrong angle?

Hello @jominga! Let me get a developer to help answer your question!

Hi @jominga!

The root joint prims you are accessing are generated by the SkelJoint extension and are not actual permanent prims as a part of your scene - and not required for the animation to process. These SkelJoint prims also only get transform attributes updated when selected, which accounts for why it seems to work sometimes - I suspect whether it works is directly related to whether or not you’ve selected it before. Either way, that’s not an intended way to leverage that extension.

The omni.anim.graph.core extension provides a function on characters that will get you the world-space root transform you’re looking for: get_world_transform(). The code will look something like this:

import omni.anim.graph.core as ag
c = ag.get_character(“/World/Character”)

t = carb.Float3(0, 0, 0)
q = carb.Float4(0, 0, 0, 1)
c.get_world_transform(t, q)

This will populate t with the root’s translation and q with the root’s rotation as a quaternion.

Note: this and other related functionality should also be accessible through Action Graph soon, so be on the lookout for that.

Hello @rrypka ,

thanks for the quick response and for pointing me in the right direction!
I still can’t get it to work with your code. Here’s how to reproduce it:

I open the “path-points” scene from the “Animation Graph Samples”. I click play and I run this code on the Script editor:

import omni.anim.graph.core as ag
c = ag.get_character("/World/Character")

t = carb.Float3(0, 0, 0)
q = carb.Float4(0, 0, 0, 1)

print(c.get_world_transform(t, q))

This prints “None” every time.

Actually I get

[Error] [] [py stderr]: NameError: name ‘carb’ is not defined

and after import it with

import carb

I get None

The function doesn’t return a value (so printing that will always give null), but t and q should contain the values you are looking for after the call.

It worked! Thank you so much!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.