MoCapModel Squat

Hello,

I am trying to import my own .c3d file (of a squat motion) into the MoCapModel (lower body only) from the AMMR. My .c3d file does not contain any force platform data. I am just trying to impose the recorded movements on the model. By now I have managed to name and position all markers on the model as they have been positioned on the test subject during the mocap recordings. I used a customized marker landscape.

My problem occurs when I am asking to run the MotionAndParameterOptimizationModel as suggested in the commentary of the MoCapModel. This is the error message I get:

5.0.0.1) …Load-time positions have been re-established.
WARNING! NAN reached!
Unexpected error in computational kernel
ERROR(OBJ.MCH.KIN3) : C:/P…s/A…y/A…0/AMMR/A…n/E…s/M…l/M…l/Kinematics.any(74) : MotionOptimization.InitialConditions : Kinematic analysis failed in time step 0

I included the files I am using.
squat3.c3d contains my c3d data of the squat movement
MyMarkers.any contains my marker data

I am unsure what to do with this. Any help would be much appreciated. Thank you in advance.

Best regards,

Arnaud

Hello Arnaud,

some small things.

first, you have a different scale in your system

in teh modelsetup.any, you’ll find a C3DsSetting.any with a points scale factor, please change this:

PointsScaleFactor = 1; //1/1000;

After that, you will see the recorded markers as blue dots. You need to change the initial position in the TrailSpecificData.any

AnyVar PelvisRotZ = -90;
AnyVar PelvisRotY = 0;
AnyVar PelvisRotX = 90;

Also, you don’t have markers on the upper body, so you need to drive those with extra drivers. Those are pre-defined already and you can switch them on or off in the end of the trialspecificdata.any:

#define HeadMarkersOnOff OFF

#define TrunkMarkersOnOff OFF

Thank you very much for your help, Amir. No more errors were encountered.

Hello again,

After implementing the previously suggested solutions into the model, I am now encountering different issues, for which I would kindly ask for some help.
I included my current model once again.

When I am running the kinematic parameter optimization sequence, I notice a strange movement in the ankles and heelbones of the model. The test subject was standing on two separate force platforms, which would make the observed movements impossible. In the model, the heelbones are moving through the force plates. In reality, however, the feet of the test subject remained almost flat on the force plates. Therefore I would like to know how I can augment the accuracy of the movements made by the model. Or is this solely dependent on my initial guesses for the marker positions?

Additionally, I am having issues concerning the inclusion of the two force platforms (type 3) into the model.
In the MyForcePlates.any file I have tried to import them, based on my finalacq.c3d file.
This c3d file has been fabricated in MATLAB by merging a c3d from my MoCap system with a new c3d file containing my force platform measurements. Although I do not get any error messages, my force plates still do not show up in the model view. I do not see an immediate cause here.

I would very much appreciate any helpful advice.
Thank you in advance.

Best regards,

Arnaud

Hi Arnaud,

I have taken a look at your model and found that the forceplate are actually in the model but just very very small…

This is because the model expects currently the corner nodes of the plate to be given in mm, and your data are in [m].

To fix it please to the following
[ul]
open the forceplate class
search for 0.001 and replace it with 1 or better write “Main.ModelSetup.C3DFileData.PointsScaleFactor”
[/ul]

We will make a fix for this in a future release of this class.

Concerning the other question that the feets are going through the floor, this is mainly related to the position of the makers on the foot, but also the position of the other markers.

If the makers on the foot is placed in a way that would force the foot into the floor it will simply do that and not know this would be undesired.

It could also be that the foot makers are ok positions but the leg is too long so to avoid having a big error in the hip makers it will also sink into the floor, so it do not only need to be a question about the foot maker positions.

Best regards
Søren

Hello Søren,

Your suggestion worked out perfectly. Thank you very much.

Kind regards,

Arnaud

Hello,

Regarding the same model as I was using when I encountered above issues, I was hoping to get an answer to the following question:

Would it be possible to add some kind of additional constraint to the heelbones of the model, wherein it restricts this segment from making any vertical downwards movements? Or would this jeopardise the general accuracy of the complete model which is driven by the motion capture? If it is indeed a viable solution to restrict the feet from making an unrealistic movement, I would like to learn the way to implement this.
Could anyone point me in the right direction?

Also, the forces from the force platforms are not visualised anymore in the model view, although this used to be the case. I did not change any settings regarding these forces, so I am quite puzzled to not see them appear in the model view. If anyone knows what is going on with this, I would very much appreciate to find a solution. I included my current model as an attachment.

Thank you in advance.

Best regards,
Arnaud

Dear Arnaud,

First, I could not load your model properly because of some mismatches of marker names.

For your first question, you can’t implement such a restriction on a certain degree of freedom kinematics.

Internally we are working on the implementation of the joint limit kinematics feature, but it will be released in our future versions.

Best regards,
Moonki

Dear Moonki,

I forgot to add that I have been working with the MoCap_LowerBody.main so when opening this file instead of the FullBody one, everything should load fine.

In the mean time, I have tried to create a (fictive) RevoluteJoint at one point on the feet (where one of the markers is located), and I was thinking of adding a second one at another point on the feet, as to restrict the motion of that particular foot segment. Unfortunately I can’t get the joint set up to correctly display the natural position of the foot. Would you mind taking a look at the code I commented out in the Environment.any file?

Furthermore, I am still puzzled about the disappearance of the force platform vectors. They used to be displayed from the different points that are still visible on the force plates but for some reason they are not anymore. When I take a look at the folder Main.ModelSetup.C3DFileData.Analog.DataFiltered in the chart view, I see that the force components are definitely there. If you could discover what is going on here I would be very grateful.

Thank you for your assistance.

Best regards,
Arnaud

Dear Arnaud,

  1. I could implement a revolute joint constraint between the nodes which you mentioned.
    And it should only exist in the MotionAndParameterOptimizationModel mode.

  2. In your ‘TrialSpecificData.any’ file, you can’t optimize the trunk height because there is no marker in the trunk segment.
    So you should turn off the scaling of the trunk segment.

  Main.ModelSetup = 
  {
    // For FullBody model    
    #if UseUpperExtremities == 1
    OptimizeAnthropometricsOnOff OptimizeOnOff (
    PelvisWidthOnOff ="On", 
    ThighLengthOnOff="On", 
    ShankLengthOnOff="On", 
    FootLengthOnOff="On", 
    HeadHeightOnOff="Off", 
    TrunkHeightOnOff="[b]Off[/b]", 
    UpperArmLengthOnOff="On",
    LowerArmLengthOnOff="On",
    Model1=MotionAndParameterOptimizationModel, Model2= InverseDynamicModel
    ) ={};
    #endif
    // For LowerBody model
    #if UseUpperExtremities == 0
    OptimizeAnthropometricsOnOff OptimizeOnOff (
    PelvisWidthOnOff ="On", 
    ThighLengthOnOff="On", 
    ShankLengthOnOff="On", 
    FootLengthOnOff="On", 
    HeadHeightOnOff="Off", 
    TrunkHeightOnOff="[b]Off[/b]", 
    UpperArmLengthOnOff="Off",
    LowerArmLengthOnOff="Off",
    Model1=MotionAndParameterOptimizationModel, Model2= InverseDynamicModel
    ) ={};
    #endif    
    //
  };
  1. Also it seems that I have to ‘CUSTOMIZE’ our force plate class template for your C3D file. So I could make a new force plate class template for you.
    It’s name is ‘ForcePlateType3_Gent.any’ and it is included in the main file just in front of the ‘Main’ folder declaration.

I attached a modified model and now you can see both COP(center of pressure) and the force vector correctly.

I hope this may be helpful to you.

Best regards,
Moonki

Dear Moonki,

Thank you so much for customizing my model. It really is a great improvement and the forces are being displayed again.

I have just one question regarding the force vectors on the force plates parallel to the x-direction (of the global ref frame). I would have expected them to be oriented outwards of the human body, in stead of inward like they are now. This would then result in the large reaction force vectors being tilted towards the body in stead of outwards, if I am not mistaken. So, how come the forces are oriented the way they are now? Or am I interpreting this wrong? (I included a screenshot of the model for clarification.)

Thank you once again for your assistance!

Kind regards,

Arnaud

Dear Arnaud,

When we test some C3D files, then we usually use a kind of free software which is called ‘Mokka’:
https://b-tk.googlecode.com/svn/web/mokka/index.html

And I also attached the snapshot of your C3D file in Mokka.

Mokka and AnyBody(with my modified force plate class template) show the same direction of the ground reaction force.

Also when I looked the center of pressure, then its movement seems right.

But if you don’t agree, then you should refer to the software of your motion capture system which will be the most correct for your hardware.

We can only make our force plate class templates based on the specification on the C3D.ORG website.

Of course there may be some variations according to different hardware manufacturers. But we can’t figure out everything without proper input of its specification document.

Best regards,
Moonki

Dear Moonki,

You are absolutely right. I will check this with the manufacturer’s software.

Thank you for all your help!

Kind regards,
Arnaud

Dear Moonki,

I am sorry to bother you again with this issue. But I have looked into this matter with the software I used from the manufacturer and I believe that there is nothing unusual going on there. I included a screenshot of my .c3d file opened in MLSviewer. This program allows me to take a look at the data from the force plates. For the FX12 component of the left force plate, a clearly negative value is shown. Additionally, when I look in my Excel file containing the initial values of these measurements of FX12L, they are also negative. But in the AnyBody model the vector is pointing inwards (in the positive x-direction), with the left force plate being shown on the right in the screenshot. Could it be that the force plate handling in AnyBody reverses these vectors by any chance?

I would greatly appreciate any thoughts of yours about this.

Thank you in advance.

Best regards,
Arnaud

Dear Arnaud,

In the new force plate class template that I made for your model, you will be able to find the following pieces of code.

Locations of the force nodes:

    AnyVar z_check = 1;
    
    AnyFloat Origins= Folder.Groups.FORCE_PLATFORM.ORIGIN.Data;
    AnyVar xdist=Origins[plnr][0];//distance from x axis on transducer to x axis of center of plate
    AnyVar ydist=Origins[plnr][1]; //distance from y axis on transducer to y axis of center of plate
    AnyVar zdist=z_check*Origins[plnr][2];//distance from z axis on transducer to z surface of plate
    
    AnyRefNode P1={
      sRel=1.0*{.xdist,.ydist,.zdist};
      AnyDrawNode drw={ScaleXYZ = 0.02*{1,1,0.1}; RGB={1,0,0};};
    };
    AnyRefNode P2={
      sRel=1.0*{-.xdist,.ydist,.zdist};
      AnyDrawNode drw={ScaleXYZ = 0.02*{1,1,0.1}; RGB={1,0,0};};
    };
    AnyRefNode P3={
      sRel=1.0*{-.xdist,-.ydist,.zdist};
      AnyDrawNode drw={ScaleXYZ = 0.02*{1,1,0.1}; RGB={1,0,0};};
    };
    AnyRefNode P4={
      sRel=1.0*{.xdist,-.ydist,.zdist};
      AnyDrawNode drw={ScaleXYZ = 0.02*{1,1,0.1}; RGB={1,0,0};};
    };
    AnyRefNode P1P2={
      sRel=0.5*(.P1.sRel+.P2.sRel);
      AnyDrawNode drw={ScaleXYZ = 0.02*{1,1,0.1}; RGB={1,0,0};};
    };
    AnyRefNode P3P4={
      sRel=0.5*(.P3.sRel+.P4.sRel);
      AnyDrawNode drw={ScaleXYZ = 0.02*{1,1,0.1}; RGB={1,0,0};};
    };
    AnyRefNode P1P4={
      sRel=0.5*(.P1.sRel+.P4.sRel);
      AnyDrawNode drw={ScaleXYZ = 0.02*{1,1,0.1}; RGB={1,0,0};};
    };
    AnyRefNode P2P3={
      sRel=0.5*(.P2.sRel+.P3.sRel);
      AnyDrawNode drw={ScaleXYZ = 0.02*{1,1,0.1}; RGB={1,0,0};};
    };

Forces which are applied to these nodes:

 AnyForce3D Fx12 ={
    
    AnyFunInterpol f ={
      Type=PiecewiseLinear;
      T=..Time;
      Data={Fx_12} ;
    }; 
    
    
    AnyRefNode &ref1=.ForcePlate.P1P2;
    Flocal=.OnOff*{f(.ForcePlateDriver.t )[0],0,0};  
    
    AnyDrawVector DrawForce =     {
     AnyRefFrame &ref=.ref1;
     Vec=.Flocal*1/1000;
     PointAway = Off;
     DrawCoord = Off;
     
     Line.RGB ={0,0,1};
     Line.Thickness = 0.01;
     Line.End.Thickness = 2*0.01;
     Line.End.Length = 4*0.01;
     GlobalCoord=Off;
   };
    
  };
  
  AnyForce3D Fx34 ={
    AnyFunInterpol f ={
      Type=PiecewiseLinear;
      T=..Time;
      Data={Fx_34} ;
    }; 
    
    
    AnyRefNode &ref1=.ForcePlate.P3P4;
    
    Flocal=.OnOff*{f(.ForcePlateDriver.t )[0],0,0};      
    
    AnyDrawVector DrawForce =     {
     AnyRefFrame &ref=.ref1;
     Vec=.Flocal*1/1000;
     PointAway = Off;
     DrawCoord = Off;
     
     Line.RGB ={0,0,1};
     Line.Thickness = 0.01;
     Line.End.Thickness = 2*0.01;
     Line.End.Length = 4*0.01;
     GlobalCoord=Off;
   };
  };
  
  
  AnyForce3D Fy14 ={
    AnyFunInterpol f ={
      Type=PiecewiseLinear;
      T=..Time;
      Data={Fy_14} ; 
    };
    AnyRefNode &ref1=.ForcePlate.P1P4;
    Flocal=.OnOff*{0,f(.ForcePlateDriver.t)[0],0};  
    
   
    AnyDrawVector DrawForce =     {
     AnyRefFrame &ref=.ref1;
     Vec=.Flocal*1/1000;
     PointAway = Off;
     DrawCoord = Off;
     
     Line.RGB ={0,0,1};
     Line.Thickness = 0.01;
     Line.End.Thickness = 2*0.01;
     Line.End.Length = 4*0.01;
     GlobalCoord=Off;
   };
  };
  
  
  
  
  AnyForce3D Fy23 ={
    AnyFunInterpol f ={
      Type=PiecewiseLinear;
      T=..Time;
      Data={Fy_23} ; 
    }; 
    
    AnyRefNode &ref1=.ForcePlate.P2P3;
    Flocal=.OnOff*{0,f(.ForcePlateDriver.t)[0],0};  
    
   
    AnyDrawVector DrawForce =     {
     AnyRefFrame &ref=.ref1;
     Vec=.Flocal*1/1000;
     PointAway = Off;
     DrawCoord = Off;
     
     Line.RGB ={0,0,1};
     Line.Thickness = 0.01;
     Line.End.Thickness = 2*0.01;
     Line.End.Length = 4*0.01;
     GlobalCoord=Off;
   };
  };
  
  
  
  AnyForce3D Fz1 ={
    AnyFunInterpol f ={
      Type=PiecewiseLinear;
      T=..Time;
      Data={Fz_1}; 
    }; 
    
    
    AnyRefNode &ref1=.ForcePlate.P1;
    Flocal=.OnOff*{0,0,f(.ForcePlateDriver.t)[0]};  
    
   
    AnyDrawVector DrawForce =     {
     AnyRefFrame &ref=.ref1;
     Vec=.Flocal*1/1000;
     PointAway = Off;
     DrawCoord = Off;
     
     Line.RGB ={0,0,1};
     Line.Thickness = 0.01;
     Line.End.Thickness = 2*0.01;
     Line.End.Length = 4*0.01;
     GlobalCoord=Off;
   };
  };
  
  
  
  AnyForce3D Fz2 ={
    AnyFunInterpol f ={
      Type=PiecewiseLinear;
      T=..Time;
      Data={Fz_2} ; 
    }; 
    
    AnyRefNode &ref1=.ForcePlate.P2;
    Flocal=.OnOff*{0,0,f(.ForcePlateDriver.t)[0]};  
   
    AnyDrawVector DrawForce =     {
     AnyRefFrame &ref=.ref1;
     Vec=.Flocal*1/1000;
     PointAway = Off;
     DrawCoord = Off;
     
     Line.RGB ={0,0,1};
     Line.Thickness = 0.01;
     Line.End.Thickness = 2*0.01;
     Line.End.Length = 4*0.01;
     GlobalCoord=Off;
   };
  };
  
  AnyForce3D Fz3 ={
    AnyFunInterpol f ={
      Type=PiecewiseLinear;
      T=..Time;
      Data={Fz_3}; 
    }; 
    
    AnyRefNode &ref1=.ForcePlate.P3;
    Flocal=.OnOff*{0,0,f(.ForcePlateDriver.t)[0]};  
    
   
    AnyDrawVector DrawForce =     {
     AnyRefFrame &ref=.ref1;
     Vec=.Flocal*1/1000;
     PointAway = Off;
     DrawCoord = Off;
     
     Line.RGB ={0,0,1};
     Line.Thickness = 0.01;
     Line.End.Thickness = 2*0.01;
     Line.End.Length = 4*0.01;
     GlobalCoord=Off;
   };
  };
  
  
  AnyForce3D Fz4 ={
    AnyFunInterpol f ={
      Type=PiecewiseLinear;
      T=..Time;
      Data={Fz_4}; 
    }; 
    
    AnyRefNode &ref1=.ForcePlate.P4;
    Flocal=.OnOff*{0,0,f(.ForcePlateDriver.t)[0]};  
    
   
    AnyDrawVector DrawForce =     {
     AnyRefFrame &ref=.ref1;
     Vec=.Flocal*1/1000;
     PointAway = Off;
     DrawCoord = Off;
     
     Line.RGB ={0,0,1};
     Line.Thickness = 0.01;
     Line.End.Thickness = 2*0.01;
     Line.End.Length = 4*0.01;
     GlobalCoord=Off;
   };
  };

So you can try to change the signs of these force input functions in order to match it to what you believe correct.

Best regards,
Moonki

Dear Moonki,

I have found the issue in the C3D processing software as you initially assumed. I am sorry for not discovering this earlier. In the mean time I have corrected this and the model view now looks like the included screenshot.
I just have one problem left: I would expect the vertical forceplate force component to be pointing downwards as it has a negative value, which I checked in the chart view. Do you have an idea why it has a reversed direction in the model view? I noticed the same phenomenon with the other force components, and by extension with the ground reaction force. As I have seen in other MoCap models from the AMMR this is usually pointing upwards and not downwards as in my model.

Thank you once again for you assistance!

Best regards,
Arnaud

Dear Arnaud,

Please try to compare the actual values in the force components in the c3d file with a similar c3d having same forceplate type “forcetype”, i would expect these to be opposite, if this is the case the there is something wrong with the c3d file.

Alternative if these are ok it could be the orientation of the plate which is somehow flipped upside down, if this is the case it could possible be related to the sequence of the corner nodes which decides plate orientation.

Best regards
Søren