Joint Angles To Drive Model?

Hi there,

I have calculated the angles for left and right hip flexion as well as left and right knee joint angles from a MATLAB script and have stored the five columns (1 column being the time array) in a text file. My question is, using only the data I have, is it possible to drive an AnyBody model (produce motion) and assume all the other joints are locked?

The data was gathered from a subject seated on a bicycle seat attached to a frame which is fixed to the ground. The subject pedals a linkage system which is picked up by rotary encoders.

I was able to input the hip flexion and knee angles into OpenSim and produce motion, however I have no idea how to do the same with AnyBody as all the tutorials I’ve found in AnyBody are for motion capture, which isn’t what I’m after.

Thanks in advance!

Hi Jared,

Yes this is possible.

You need to do it in this way:

[ol]
[li] First you need to ensure you have the same definitions of the dof int he measurement and in the model, so you need to ensure that you have zero at the same locations etc. If this is not the case you can define new rotational measured in the model using the AnyKinRotational measure.
[/li][li] Please try to use the free posture model and make changes in the mannequin.any file to see the way the joints are defined in the model to verify if you can reuse these definitions or will have to make you own like described in previous step.
[/li][li] Once you have the same measures in the models and in the experiment yu then need to construct an interpolation driver which will drive the angels.
[/li][li] The driver will look something like this:
[/li]


AnyKinEqInterpolDriver Mydriver ={
Type =BSpline;
FileName ="MyFilename.txt"
AnyMeasureOrg &ref1=.MeasureForFirstCollumData;
AnyMeasureOrg &ref2=.MeasureForSecondCollumData;
AnyMeasureOrg &ref3=.MeasureForThirdllumData;
AnyMeasureOrg &ref4=.MeasureForFourthCollumData;
Reaction.Type ={Off,Off,Off,Off};
};


Hope it make sense

[/ol]

Please also look in the reference manual example for the AnyKinEqInterpolDriver

Best regards
Søren

What is ‘AnyMeasureOrg’? I have no idea how to make use of this, and it doesn’t turn blue when I type it in AnyScript.

I can’t find the example for AnyKinEqDriver in the reference manual. Where exactly is it?

Also, I’m using the FreePostureFullBodyStatic.Main.any file using DriverSelection “FreePostureMove”. Am I supposed to put my joint angle drivers into InterpolationFunctions.any or do I put them in MannequinInterpolation.any?

I’m so confused :frowning:

Kind regards,

Jared

Hi Jared,

Sorry for your confusion.

In my sample code i sneaked in two typos sorry for that :wink:

It is AnyKinEqInterPolDriver not AnyKinEqInterpolDriver secondly it is AnyKinMeasureOrg not AnyMeasureOrg.

I see three way to create this model:
[ol]
[li] Use the drivers like described below then add extra drivers to lock all angles.
[/li][li] If you use the MocapModel you could simply alter the joint angle output files usually created by the markers to use your data instead then only run rhe inverse dynamic analysis using these joint angles… see the files in the input folder of the MocapModel the files are named eg like xxx-euler-rightlegtd.txt . Using this approach is a bit crude but it has the advantage that you will in principle only need to alter the input files assuming the joint rotations are measured same way.
[/li][li] use the free posture move model like you mention and alter the input arrays to represent your data, this is also a good way.
[/li][/ol]

Basically it is just different way to do the same thing namely to introduce some intepolation drivers to the joints as easy as possible. Using the mocap model will read these from a file and the freeposture model i think you write them in anyscriot as arrays.

Please consider to go through the tutorials this will help to understands models like this better.

Please dp not hesitate to write agian if you have further questions

Best regards
Søren

Hi Jared,

I took a closer look at the FreePostureModel.

If you want to use this one please do the following:
[ol]
[li] in the file mannequininterpolation.any make changes below
[/li][li] make your own definition of the timeserie… so something like TimeSerie3={0,0.5,1}; here you should use the values you have already in the first collumn of the file.
[/li][li] for each dof alter the vector properties. so eg AnyVector HipFlexionVec ={ 20,90,0}; to reflect the values you have in your file.
[/li][/ol]

instead of using manually copy pasting values you could use the AnyInputFile object

This will give you a T vector which you can use directly in step 2 above and it will give you a Data matrix of NoDof X TimeSteps

Then you can write something like eg AnyVector HipFlexionVec =MyInputData.Data[0]; or =MyInputData.Data[0]’ ; i did not test.

Hope it made sense.

Best regards
Søren

Hi Søren,

Thanks for your replies, I have made progress but have become stuck on the following parts:

I used FreePostureFullBodyStatic.Main.any, with DriverSelection “FreePostureMove”. I have been editing the MannequinInterpolation.any file, and have declared the following in the code:

[i] AnyInputFile JointAngles =
{
FileName = “JointArrayData.txt”;
};

AnyVector TimeSerie = JointAngles.T; 
AnyVector LKneeArray = JointAngles.Data[0];
AnyVector RKneeArray = JointAngles.Data[1];
AnyVector LHipArray = JointAngles.Data[2];
AnyVector RHipArray = JointAngles.Data[3];
AnyVector ZeroArray = JointAngles.Data[4];[/i]

1. How do I declare the above globally without having to copy and paste the above code into every AnyFolder in the MannequinInterpolation.any file?

I have locked all segments using ZeroArray which is just an array filled with zeros (the same size as the other vectors).

I have made modifications in the required AnyFolder’s, for example:
in the Left folder:
AnyVector HipFlexionVec = LHipArray;
AnyVector HipAbductionVec = ZeroArray;
AnyVector HipExternalRotationVec = ZeroArray;

I have declared TimeSeries as the following:
AnyVector TimeSerie = JointAngles.T;

When I load the model, it does so without problem.

2. The problem is that when I run Kinematic analysis, the model does not move in the whole range of trajectories that is specified in the text file. Why is this?

I have attached the text file, JointArrayData.txt, which I have used in the above code. The columns are specified in the code I pasted above. First column is the TimeSerie, the next columns are, respectively: LKneeArray, RKneeArray, LHipArray, RHipArray (knee joint angles and hip flexion angles in degrees)

I also have attached the MannequinInterpolation.any file I have been editing.

Kind regards,

Jared

Hi there,

I decided to try out the method 2 you suggested:

I wrote a MATLAB script that created the following (properly formatted) text files:
FullBody-GaitNormal_1-euler-trunk.txt
FullBody-GaitNormal_1-euler-rightlegtd.txt
FullBody-GaitNormal_1-euler-rightarm.txt
FullBody-GaitNormal_1-euler-leftarm.txt

I added my own time array for column 0 of each, and padded any components that i didn't have angle data for with zeroes (i only have hip and knee angles).

I then put these created text files and replaced the ones in the Input folder of the mocap model

I reloaded the full body mocap model and ran Inverse Dynamics, however I'm getting heaps of constraint errors. The output can be shown in the pastebin text:

I have completely ignored the markers in this analysis and haven't done anything other than what I've described. It should be mentioned that I have added GRF Prediction to the feet (it should be on the pelvis due to the subject being seated but i'll deal with that later) as followed from the GRF Prediction pdf on the wiki site.

How do I get Inverse Dynamics to properly work with what I have described?

Kind regards,

Jared

Hi Jared,

It sounds correct what you have done and do not be affraid of the long list of erros you get it may look worse than it is, since once it realize that the model does not solves within the kin tolerance it will report all errors for every single constraint.

From the error message i can see that it fails in the first timeframe.
This means that one of the reasons for it to fail could be too poor initial guess on the initial position of the segments.
The initial positions for the segments are controlled though the Mannequin.any file here you set the pelvispos xyz and pelvisRot xyz plus all joint angles, these values are used in the first frame to set the position of the skeleton. So this is the pos you see at load time. Please try to alter these values so that the skeleton is closer to the position you want.

The crude way is to simply write the values in the file the elegant way would be to use the same input files you have made to create intepolation functions.

So for example something like this: (sorry for any typos)



AnyFunInterpol TrunkInterpolFun ={
Type=Bspline;
Filename= "FullBody-GaitNormal_1-euler-trunk.txt"
};

AnyVar PelvisPosX = TrunkInterpolFun(MyStudy.tStart)[0];
AnyVar PelvisPosY = TrunkInterpolFun(MyStudy.tStart)[1];
....

If this does not help help consider to use a model with no arms this will simplify the problem.

Best regards
Søren

I added the FullBody-GaitNormal_1-euler-trunk.txt file to the same directory as the Mannequin.any file, however when I load the model I get an error:

Constructing model tree...
ERROR(SCR.PRS9) : C:/U..s/j..1/A..a/R..g/A..y/D..s/A..o/A..n/M..s/M..3/M..l/Mannequin.any(14) : 'Filename' : Unresolved object
Model loading skipped

The edited code below (for the Mocap model) is shown below in bold:

AnyFolder Mannequin = {

AnyFolder Posture = {

AnyParamFun &RASI = Main.ModelSetup.C3DFileData.Points.Markers.RASI.PosInterpol;
AnyParamFun &LASI = Main.ModelSetup.C3DFileData.Points.Markers.LASI.PosInterpol;

AnyParamFun &RPSI = Main.ModelSetup.C3DFileData.Points.Markers.RPSI.PosInterpol;
AnyParamFun &LPSI = Main.ModelSetup.C3DFileData.Points.Markers.LPSI.PosInterpol;

[i][b]AnyFunInterpol TrunkInterpolFun ={
Type=Bspline;
Filename= "FullBody-GaitNormal_1-euler-trunk.txt";
};
AnyVar PelvisPosX = TrunkInterpolFun(MyStudy.tStart)[0];
AnyVar PelvisPosY = TrunkInterpolFun(MyStudy.tStart)[1];
AnyVar PelvisPosZ = TrunkInterpolFun(MyStudy.tStart)[2];

AnyVar PelvisRotX = TrunkInterpolFun(MyStudy.tStart)[3];
AnyVar PelvisRotY = TrunkInterpolFun(MyStudy.tStart)[4];
AnyVar PelvisRotZ = TrunkInterpolFun(MyStudy.tStart)[5];

AnyVar PelvisThoraxExtension = TrunkInterpolFun(MyStudy.tStart)[6];
AnyVar PelvisThoraxLateralBending = TrunkInterpolFun(MyStudy.tStart)[7]; 
AnyVar PelvisThoraxRotation = TrunkInterpolFun(MyStudy.tStart)[8];      

AnyVar NeckExtension = TrunkInterpolFun(MyStudy.tStart)[9];[/b][/i]

Please note that I have double checked the filename and the .txt file does exist.

Kind regards,

Jared

Hi there,

I have specified the initial positions of each segment in the Mannequin.any file by hardcoding the first row of data in the text files in the Input folder.

However when I run the Inverse Dynamics operation, the model changes its orientation drastically and produces an error:

  1. InverseDynamics (Operation: Main.Studies.InverseDynamicStudy.InverseDynamics):
    0.0) PreOperation (Operation: Main.Studies.InverseDynamicStudy.InverseDynamics.PreOperation):
    0.0.0) InitialConditions (Operation: Main.Studies.InverseDynamicStudy.InitialConditions):
    0.0.0) ...Design variables have been updated.
    0.0.1) ...Load-time positions have been re-established.
    0.0.2) ...Kinematic analysis completed. The kinematic constraints have been resolved.
    0.0.3) ...Initial conditions are fully updated.
  2. Inverse dynamic analysis...
    ERROR(OBJ.MCH.MUS4) : C:/U..s/j..1/A..a/R..g/A..y/D..s/A..o/A..n/M..s/M..3/M..l/InverseDynamics.any(29) : InverseDynamicStudy.InverseDynamics : Muscle recruitment solver : solver aborted after maximum number of iterations

How do I fix this? I have attached a screenshot of before and after

Kind regards,

Jared

I found that the following assignments for nStep, tStart and tEnd might be causing issues, as I'm not inputting any C3D file (I don't want to).

AnyIntVar nStep =(LastFrame-FirstFrame+1);
AnyFloatVar tStart = FirstFrame/C3DFileData.Header.VideoFrameRate;
AnyFloatVar tEnd = LastFrame/C3DFileData.Header.VideoFrameRate;

So I changed these three lines to the following:

AnyIntVar nStep = 150;
AnyFloatVar tStart = 0.00;
AnyFloatVar tEnd = 4.00;

However now when I load the model, I get an error:

Configuring model...
Evaluating model...
ERROR(SCR.EXP0) : C:/U..s/j..1/A..a/R..g/A..y/D..s/A..o/A..n/M..s/M..3/I..t/Markers.any(30) : Defined at : C:/P..s/A..y/A..0/AMMR/Body/A..n/T..x/M..p/CreateMarkerDriverClass.any(243) : 'Vec' : Error in expression. Please refer to the following error messages for details ...
ERROR(OBJ1) : C:/U..s/j..1/A..a/R..g/A..y/D..s/A..o/A..n/M..s/M..3/M..l/ModelSetup.any(13) : C3DFileData.Points.Markers.LPSI.PosInterpol : Parameter has an invalid value for this interpolation; extrapolations are not allowed.
Model loading skipped

How exactly do I get this to load successfully? I'm just hardcoding my tStart and tEnd for my specific trial to test if Inverse Dynamics works.

Also, my full Times.any script is now this:

AnyIntVar nStep = 150;
AnyFloatVar tStart = 0.00;
AnyFloatVar tEnd = 4.00;
AnyFolder Macros={};

Kind regards,

Jared

Hi Jared,

The error you get is related to a marker driver which is looking for its data… which does not exist in this model.

Please go the file Marker.any and outcomment all marker drivers, otherwise it will not load.

Best regards
Søren

Hi Jared,

Please note that that when you load a model the position you see until you have been running inverse or kinematics comes from the values set by the mannequin.any file.

Once you run the analysis it will use these values as starting guess and solve the constraints.

This is what you see on the picture i think.

So to make these images the same you need to ensure that the values you set in the mannequin file corresponds to the values from your input data.

I think i made an example of this in an earlier post

Best regards
Søren

Hi Jared,

Filename should be FileName, then it will load

Best regards
Søren

After making the adjustments, I’m still getting the error with new warnings.

The message window is displayed here: http://pastebin.com/GhbsC8Vz

I have attached the entire mocap model in a .zip file, as it might help you to pinpoint where I’m going wrong. I’m using MoCap_FullBody.main.any

Kind regards,

Jared