University of Southern CaliforniaUSC
USC ICT TwitterUSC ICT FacebookUSC ICT YouTube

How to set a joint rotation? | General SmartBody Discussion | Forum

Avatar

Please consider registering
guest

sp_LogInOut Log In sp_Registration Register

Register | Lost password?
Advanced Search

— Forum Scope —




— Match —





— Forum Options —





Minimum search word length is 3 characters - maximum search word length is 84 characters

sp_Feed Topic RSS sp_TopicIcon
How to set a joint rotation?
October 8, 2012
9:57 pm
Avatar
Member
Members
Forum Posts: 80
Member Since:
June 13, 2012
sp_UserOfflineSmall Offline

What's the proper way to set the state of a joint? It's a little confusing that SBJoint has a getQuaternion method but no setQuaternion method.

October 9, 2012
6:58 am
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

The state of the character (and thus the positions and orientations of the joints in the skeleton) are set via the controllers every time step.
So even if you explicitly set them at some point, their controller stack will be evaluated and modify the skeleton state.

So, you could:
1) Run a BML command for a posture that sets the character into the desired pose, or
2) The last controller on the controller stack is one that can override any other value (we use it when using something like the Kinect to control the character) and it can be used if you want to set the joints explicitly instead of using the standard behavior control using the controllers.
From controllers/me_ct_data_receiver.h:

void setLocalPosition(std::string jName, SrVec& pos);
void setGlobalPosition(std::string jName, SrVec& pos);
void setLocalRotation(std::string jName, SrQuat& q);
void removeLocalRotation(std::string jName);
void removeLocalPosition(std::string jName);

So, you would first obtain that controller:

int num = character->getNumControllers();
SmartBody::SBController* controller = character->getControllerByIndex(num - 1);
MeCtDataReceiver* receiver = dynamic_cast<MeCtDataReceiver*>(controller);

then you can call setLocalRotation() on a particular joint by name.

receiver->setLocalRotation("l_wrist", SrQuat(1, 0, 0, 0));

or whatever...

Ari

October 9, 2012
6:07 pm
Avatar
Member
Members
Forum Posts: 80
Member Since:
June 13, 2012
sp_UserOfflineSmall Offline

Thanks. I was thinking I should initialize the skeleton pose before starting a simulation, but maybe I don't need to.

Speaking of the SBJoint class, this is a picky thing, but I think that the setName method should take the name as a const reference.

October 9, 2012
6:22 pm
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

There are probably many places where the API could be more consistent, or better. I appreciate your input.

If you don't set an initial pose, then the characters will either blend or pop into their initial poses, so you probably want the characters to be in their initial pose immediately without seeing the t-pose. You can do this by ignoring the blend time for the idle pose:

<body posture="myidleposture" ready="0">

Ari

December 8, 2012
12:20 am
Avatar
Member
Members
Forum Posts: 20
Member Since:
November 29, 2012
sp_UserOfflineSmall Offline

is this possible through python?
I followed the mirror code through API doc but I don't see a setLocalOrientation for SBController

December 8, 2012
4:45 pm
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

I haven't added the Python API for that, but there is an older (ad-hoc) command system that I am trying to phase out that still let's you do that:

// Usage:
// receiver echo
// receiver enable
// receiver skeleton position
// receiver skeleton positions ... 20 Joints in total if emitterType == "kinect"
// receiver skeleton rotation
// receiver skeleton rotations ... 20 Joints in total if emitterType == "kinect"

so you can do this:
scene.command("receiver skeleton mycharacter foo rotation base 1 0 0 0")

(the 'foo' token is just to identify if this is a kinect sending the data, and can be anything).

I'll add a Python command when I have some time, but this should work in the meantime
Ari

December 10, 2012
8:25 pm
Avatar
Member
Members
Forum Posts: 20
Member Since:
November 29, 2012
sp_UserOfflineSmall Offline

I can't seem to get that command do anything. Calling it right after dll->update() (Also tried before)

scene.command("receiver enable")
scene.command("receiver skeleton brad default rotation l_wrist 1 0 0 0")

I also tried the position one to see if my quaternion values are wrong, that also doesn't seem to have any effect either

scene.command("receiver enable")
scene.command("receiver skeleton brad default position l_wrist 500 500 500")

There are no errors in the log.

December 10, 2012
11:43 pm
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

I've just tested this with the ogreviewer, and was able to get it working. How about throwing in some random rotation data:

scene.command("receiver skeleton brad default rotation l_wrist .7 .7 .7 .7")

?

If not, can you trace the code flow through the debugger? You should see the effects of running the command at:
mcontrol_util.cpp:5231

in the:

int mcu_joint_datareceiver_func()

function.

I'll add direct Python commands and check that in soon.

Ari

December 10, 2012
11:50 pm
Avatar
Member
Members
Forum Posts: 20
Member Since:
November 29, 2012
sp_UserOfflineSmall Offline

I'm using the smartbody-dll. Where can I test the code flow?

December 11, 2012
12:01 am
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

If you are on Windows, you can build the project in Debug mode using Visual Studio, run your application, then Debug->Attach to Process.

If you are Linux/OSX, you can build the project with debug symbols by chaning the smartbody/CMakeLists.txt line near the top from this:

add_definitions( -fPIC )

to this:

add_definitions( -g3 -fPIC )

Ari

December 11, 2012
8:26 pm
Avatar
Admin
Forum Posts: 983
Member Since:
December 1, 2011
sp_UserOfflineSmall Offline

Any luck?

Ari

December 13, 2012
1:31 am
Avatar
Member
Members
Forum Posts: 20
Member Since:
November 29, 2012
sp_UserOfflineSmall Offline

For now I am switched to using constraints to fix location when available. And it works very well.

However I can't seem to apply rotational constraints. For instance, I am trying to have the wrist follow the orientation of a pawn. Even though pawn is only moving and its orientation doesn't change, the body constantly rotates in arbitrary directions (breaks down) and is not controlled at all by the static orientation of the pawn.

Is this not correct?

bml.execBML('brad', ' sbm:constraint effector="r_wrist" sbm:effector-root="r_elbow" sbm:handle="cbrad" target="brad_right_wrist" sbm:constraint-type="rot"/ ')

note: Again I had to remove the XML brackets

December 21, 2012
12:37 am
Avatar
Admin
Forum Posts: 52
Member Since:
August 8, 2012
sp_UserOfflineSmall Offline

I tested this problem on the latest code, and can not seem to reproduce the problem.

Here is the BML call I used :

bml.execBMLAt(2, 'ChrBrad3', 'sbm:constraint effector="l_wrist" sbm:effector-root="l_elbow" sbm:handle="cbrad3" target="pawn1" sbm:constraint-type="rot" sbm:fade-in="0.5"/')

This is a similar BML call to what you did. I tested this by slightly modifying "ConstraintDemo.py" in the data/example/ folder. If you are getting this problem, can you provide us the setup script you used ? Thanks.

March 26, 2013
4:32 pm
Avatar
Member
Members
Forum Posts: 13
Member Since:
August 1, 2012
sp_UserOfflineSmall Offline

To set the idle pose instantly I found I had to use this BML (adding relax="0"):

<body posture="myidleposture" ready="0" relax="0">
Forum Timezone: America/Los_Angeles

Top Posters:

jwwalker: 80

jyambao: 52

rbaral: 47

adiaz: 30

WargnierP: 29

lucky7456969: 28

mbarros: 28

avida.matt: 26

JonathanW: 24

laguerre: 23

Member Stats:

Guest Posters: 69

Members: 122211

Moderators: 3

Admins: 4

Forum Stats:

Groups: 1

Forums: 5

Topics: 531

Posts: 2495