Animating a model using generated data with C3D

Hi,

I am trying to animate a model using generated data from a mocap system through C3D.

I gathered data using the quaternions format that I converted to YZX relative Euler angles representation that I wrote in a C3D file.
The C3D part works fine, it is the animation inside Anybody that I have problems with.

I have created two C3D files (see attachment) and I have included the Main file of the FreePostureMove examples.

1- I tried the values that I gathered from the MocapSystem that I am using.
Those values are in the NotWorking.c3d.
Around the sample 430 (where we can see a clear “jump” in the values), the simulation is giving me a tolerance error.
I am not sure has to why the simulation is giving an error.
Note that I am using AnyBody version : 5. 1. 0. 2588 Build : 15245.34740.
I tried to install the latest version but as soon as I start it I get the windows crash window.

I also created a working file (Working.c3d) that is almost the same movement as the one gathered with the mocap system.
The values were generated like this:

list<Quaternion> listOfQuaternions;
listOfQuaternions << Quaternion (0.707, 0, -0.707);
for (int i = 1; i <= 100; ++i)
{
    Quaternion offsetQuat = Quaternion::fromAxisAndAngle(1, 0, 0, -(i / 100.0)*120.0);
    listOfQuaternions << listOfQuaternions.at(0)*offsetQuat;	
}
Quaternion lastQuat = listOfQuaternions.back();
for (int i = 1; i <= 100; ++i)
{
    Quaternion offsetQuat = Quaternion::fromAxisAndAngle(0, 1, 0, (i / 100.0)*90.0);
    listOfQuaternions << lastQuat*offsetQuat;	
}

This C3D is working great.

Also, I have a couple of questions regarding the driving of the model.
1- Is it better to drive the joints (like I am trying) or the segments?
2- Is there a link between the AnyKinRotational Axis{1-3} and the references (ref{1-}) used inside AnyKinEqInterPolDriver ?
3- I read that it is possible to drive the model using quaternions (Type=EulerParam) but that it is unusual. Is ti a good idea to try this?

Thanks a lot
Alexandre Roy

Hi Alexander,

We have tested both models and you are right the first of them fails, and the reason is that there is a jump in the angle of 360 deg, which makes the kinematics fail. With the inverse kinematics we are using such jumps may create problems there is no way to avoid that.

In the second model you are right it works and if you look at the input data there are no jumps seen either.

Here are some answers to the three questions:

1: it depends… you can do both generally driving an angle is a fine and a safe way to drive the model but if you can not garantee there are no jumps of 360 deg. then it would have been better to drive a position of the segment.

2: Sorry i am not sure i understand this queestion. In the AnykinRotational you choose the sequence of the rotations. In the driver you may then choose to driver one or all of these rotations.

3: No i would not go this way. If you did this would it then make the jumps in the input go away? otherwise the problem would be the same.

Do you have a way to filter away these jumps?

Best regards
Søren

Hi Søren,

I can filter the values so they go below -PI, will this be handled correctly?

1: Is it possible to drive the orientation of the segment? Or will I have the same problem as the joint? Also, do you have an example for driving the segment’s position?

2:I was pondering on this when I was searching for which convention to use when doing the conversion.

If I am not mistaken, the order of rotation in AnyKinEqInterPolDriver is important.
So If I declare ref1=Flexion, ref2=Abduction, ref3=External Rotation it is not the same as ref1=Abduction, ref2=Flexion, ref3=External Rotation.

With this in mind and assuming Euler is used to apply the rotation (I am assuming this since I get a warning for gimbal locks), I wasn’t sure if the axis in the AnyKinRotational had an impact on the value that I needed to provide the driver.

Am I correct that I can use the same values to drive an AnyKinEqInterPolDriver using ref1=Flexion, ref2=Abduction, ref3=External Rotation, regardless of the axis in the AnyKinRotationnal?

Is it possible to know which Euler convention you are using when driving the model?
Maybe it will be easier for me do to the conversion using the same convention.

Thanks
Alexandre Roy

Hi Alexandre,

Here are some answers to the questions:

Filtering the values might be ok depending on which filter… but looking at the values you have jumps exactly of 360 deg, so the position this describes is in fact correct it is just a problem that the solver will not handle such a jump. If you smooth this by filtering to be something less it will be wrong… this jump should be taken entirely away not just someway smoothed…:).

Question1:
By driving the positions this could be either rotations of linear positions. The orientations may have same problem as described earlier it all depends on the input the model, large jumps will make it fail. There migth be ways to describe the kinematics through linear positions? these will have no jumps…

Question2:
I have made a new item in our wiki please see :
http://wiki.anyscript.org/index.php/All_about_Kinematics#How_to_drive_an_AnyKinRotational_Cardan_angles_.28Type.3DRotAxesAngles.29
In the driver the sequence is not important, the example should illustrate this.
I hope this answers this question.

All AnyKinRotational measures has a sequence built in and you can find this in the rotational measure being used. It will have the properties Axis1…Axis3 which defines the used sequence. Note that you could also consider creaing a new rotational measure which would fit your exact needs and add that to the model.

Best regards
Søren

Hi Søren,

What I was actually thinking of doing is to remove 360 degrees if the there is a jump and the value is near 180. This jump happens because the algorithm that I am using to convert from Quaternion to Euler angles does not allow values below -180 and over 180.

My “filter” will add or remove 360 if there is a sign change near 180. Thus having values below (or above) 180.

Question1:
I am unfamiliar with the positioning in Anybody. To provide positions, will I have to also provide the anthropometry of the mannequin?

Question2:
Thanks a lot for the example in the wiki. I think I have a better understanding of it now!!

Thanks
Alexandre Roy

Hi Alexandre,

It sounds as your filter will do the trick and effectively remove the jumps, if these are gone it sound run smooth.

Concerning question 1 I am not exactly sure what you are trying to obtain.

In AnyBody you will need to provide the size of the model and then you can drive it. The size can be specified in numerous ways please see the tutorials on scaling which should illustrate this, you can also run the model in an unscaled form.

To drive the model you will need to provide the positions of the free dof in the model. There are endless ways to do this in, simplest is to provide joint angles, you also need to drive all six dof of one segment, typically we drive all six positions of the pelvis.

I am unsure if this answered your question?

Best regards
Søren

Hi Søren,

I just took a look at the scaling tutorial and it answered my question.

Just to be sure that I understand correctly.
If I want to drive a model, using position, with one leg longer than the other.
I scale the model according to the anthropometry that I want to use.
Then I move the pelvis to the position/orientation that I need.
Finally, I can drive the position of the segments. Which can be relative to the pelvis.

Is this accurate?

Best regards,
Alexandre Roy

Hi Alexandre,

I am glad the scaling tutorials clearified the scaling questions, the way you propose to drive the models sounds ok, this should be feasible.

Best regards
Søren