Force plate setting for measuring at buttocks

Hi, all.
Recently added posts are all from me, so I’m a little bit embarrassed :o

In sit-to-stand simulation, I used three force plates; two is for the feet, the other is for the buttocks. There was no problem to set up those platforms in the model, but I wonder the how the contact condition should be set to use the force data form the buttocks force plate.


At first, I would like to understand the force plate auto detection module.

While modifying the original ForcePlateType2AutoDetection class to new one, I mostly could understand what is going on within the class ForcePlateType2AutoDetection, but I do not know what PlateFootReactions and PlateGroundReactions actually do.
My first questions are the role of these two classes.

  1. PlateFootReactions makes general muscles between limb2 and force plate with a linear measure and InContactMuscle model.
    I think that InContactMuscle work with S=1000 when in contact, with S=0 when in non-contact? Am I right?
  2. But why between limb2 and force plate not between limb1 and force plate? It is defined in limb1.
  3. The measures in PlateGroundReactions are defined with only force plate. What does that mean?
  4. How PlateGroundReactions is working when gait analysis? In other words, what is its physical meaning?

Then, Instead of two segments (limb1, limb2) are needed for this module. I tried to change that part to one segment input (pelvis) by creating new class as following:

#class_template ForcePlateType2AutoDetectionPelvis (PlateName, Folder,AnySeg &PelvisSeg, No,VerticalDirection,HeightTolerance,VelThreshold, Fx, Fy, Fz, Mx,My,Mz)

At the same time, I tried to make a new force plate type as similar the predefined force platform for gait.

Within “EnvironmentAutoDetection.any”

ForcePlateType2AutoDetectionPelvis Plate5 (
PlateName = Plate5,
Folder =Main.ModelSetup.C3DFileData,
PelvisSeg=  .HumanModelRef.Trunk.SegmentsLumbar.PelvisSeg,
No=4,
VerticalDirection ="Z",
HeightTolerance=0.07,
VelThreshold=2.2,
Fx=Main.ModelSetup.C3DFileData.Analog.DataFiltered.Fx5,
Fy=Main.ModelSetup.C3DFileData.Analog.DataFiltered.Fy5,
Fz=Main.ModelSetup.C3DFileData.Analog.DataFiltered.Fz5,
Mx=Main.ModelSetup.C3DFileData.Analog.DataFiltered.Mx5,
My=Main.ModelSetup.C3DFileData.Analog.DataFiltered.My5,
Mz=Main.ModelSetup.C3DFileData.Analog.DataFiltered.Mz5)
={
//  Cal=Main.ModelSetup.C3DFileData.Groups.FORCE_PLATFORM.CAL_MATRIX.Data[2];
};


Second is the following.
As I do not fully understand the ForcePlateType2AutoDetection class, I think I have somethings wrong with the modified class:


AnyFolder PlateFootReactions={

      AnyKinLinear Lin={
        Ref=0;
        AnySeg &ref2=...ForcePlate;
        AnySeg &ref1=...PelvisSeg;
      };
      
      AnyKinRotational Rot={
        AnySeg &ref2=...ForcePlate;
        AnySeg &ref1=...PelvisSeg;
        Type=RotAxesAngles;
      };
    };

    AnyFolder PlateGroundReactions={
      
      AnyKinLinear Lin={
        Ref=0;
        AnySeg &ref2=...ForcePlate;
      };
      
      AnyKinRotational Rot={
        AnySeg &ref2=...ForcePlate;
        Type=RotAxesAngles;
      }; 
    };   

The format I modified is basically same, I used Pelvis segment as ref1 instead of limb2. Of cause I created two node on the pelvis segment which corresponds to the heel node and the toe node on the foot.

Some motion captured data looks to work well but I’m not sure of the result. And sometimes it fails with other data.


For the last, in the c3d file, I have additional measurement data from load cells.
In this case, is there any toolbox for load cells I can use?


Many thanks in advance.

Sincerely yours,
Sheen Dong-Pyoung

Hi,

Let me explain something to your questions.

In the ‘ForcePlateType2AutoDetection.any’ file, ‘ForcePlate’ is a dummy AnySeg object with mass = 0. And there are ‘AnyForce3D Force’ and ‘AnyMoment3D Moment’ acting on this ForcePlate segment. So there should be some counterpart forces for this ForcePlate segment. Those are ‘PlateFootReactions’ and ‘PlateGroundReactions’ forces.
When one of limb1 and limb2 is on the ForcePlate, then PlateFootReations will transfer forces from ForcePlate to limb1 or limb2. So ForcePlate segment can be in balance. If not, then PlateGroundReactions will transfer forces from ForcePlate to the ground. So also in this case the ForcePlate segment can be in balance.

Answers to your questions:

  1. Let’s see the definition of InContactMuscle
    AnyMuscleModelUsr1 InContactMuscle = {
      F0 = 0;
      S = .NodeWithInBox.WithinBoxAndVelBelowThreshold *10000;
    };

The strength of this AnyMuscleModelUsr1 will be determined by its ‘S’ property. So I believe that you can calculate this strength.

  1. Please read the related AnyScript codes carefully. All necessary information about limb1 and limb2 are already defined in the file.

3&4) Now you can find the meaning of the PlateGroundReactions. The role of this force is a kind of counterpart force that make ForcePlate be in the balance when human foot are not on the ForcePlate.

In the ‘…\Body\AAUHuman\ToolBox\Mocap’ folder of the AMMR, you can also find the ‘ForcePlateType2.any’ file. This file assumes that the contact between the ForcePlate and a certain segment of the human will always occur.

So my suggestion is to try with this ‘ForcePlateType2.any’ file instead of ‘ForcePlateType2AutoDetection.any’ file.

It seems that in your case, the problem is that the forces recorded by the force plate does not only come from pelvis. There may be some components from the both left and right thighs in the ForcePlate forces.

So my suggestion is to make a dummy segment on the top of the ForcePlate. And make several conditional contact elements between this dummy segment and the human segments(pelvis, left and right thigh).

I hope this may help you.

Best regards,
Moonki

Thank you for the answers.
I will try with ForcePlateType2 instead of ForcePlateType2AutoDetection.

I think I made a mistake when writing question 2.
You said that PlateGroundReactions works for balancing the force plate when no contact between a foot and a force plate.
In question 2, I mean why NoContactMuscle and PlateGroundReactions in ContactDetectionLimb1 are determined by limb2 condition, not by limb1.


AnyFolder ContactDetectionLimb1 ={

    .....

    AnyMuscleModelUsr1 InContactMuscle = {
      F0 = 0;
      S = .NodeWithInBox.WithinBoxAndVelBelowThreshold *10000;
    };
    
    AnyMuscleModelUsr1 NoContactMuscle = {
      AnyVar Limb2Contact=iffun(eqfun(..ContactDetectionLimb2.NodeWithInBox.WithinBoxAndVelBelowThreshold ,1.0),0.0,1.0); //equal 0 if limb2 in contact
      S =Limb2Contact*.NodeWithInBox.OutsideBoxOrVelHigherThanThreshold*10000;
      F0 = 0;
    };

    .....

};

In addition, I asked in my post if I can import load cell’s data saved in c3d file. Is it possible?

Thank you.

Hi,
1)


      AnyVar WithinBoxAndVelBelowThreshold =WithinBox*iffun(ltfun(.P1Vel,VelThreshold),1,0);
      AnyVar OutsideBoxOrVelHigherThanThreshold=  iffun(WithinBoxAndVelBelowThreshold ,0,1);
      
    };  

AnyFolder ContactDetectionLimb1 ={

    .....

    AnyMuscleModelUsr1 InContactMuscle = {
      F0 = 0;
      S = .NodeWithInBox.WithinBoxAndVelBelowThreshold *10000;
    };
    
    AnyMuscleModelUsr1 NoContactMuscle = {
      AnyVar Limb2Contact=iffun(eqfun(..ContactDetectionLimb2.NodeWithInBox.WithinBoxAndVelBelowThreshold ,1.0),0.0,1.0); //equal 0 if limb2 in contact
      S =Limb2Contact*.NodeWithInBox.OutsideBoxOrVelHigherThanThreshold*10000;
      F0 = 0;
    };

    .....

};

This NoContactMuscle should have its non-zero strength only when no limb is on the force plate.

Let’s assume that limb1 does not contact to this force plate and limb2 contacts to this force plate.
Then NoContactMuscle in ContactDetectionLimb1 should have zero strength because then InContactMuscle in ContactDetectionLimb2 will have its non-zero strength.

If you see the ‘S’ function(strength) of this NoContactMuscle,
this ‘S’ strength can be zero either ‘Limb2Contact’ can be zero or ‘.NodeWithInBox.OutsideBoxOrVelHigherThanThreshold’ can be zero.

‘Limb2Contact’ value can be zero if limb2 contacts this force plate.
‘NodeWithInBox.OutsideBoxOrVelHigherThanThreshold’ value can be zero if limb1 contacts to this force plate.

  1. If the force data from load cell is recorded in your C3D file,
    then you can extract those values from C3D file.
    But you should make your own code to apply those values as a force in AnyScript.
    In this ForcePlateType2AutoDetection.any file, there is a good example code for your purpose.
  AnyFunInterpol load ={
    Type=PiecewiseLinear;
    T=.Time;
    Data={Fx,Fy,Fz,Mx,My,Mz};
    //  Data=.Cal'*{.LowPassFilter(Fx),.LowPassFilter(Fy),.LowPassFilter(Fz),.LowPassFilter(Mx),.LowPassFilter(My),.LowPassFilter(Mz)};
    
  }; 
  
  
  AnyVar FzTotal=load(ForcePlateDriver.t)[2];
  AnyVar OnOff=iffun(gtfun(-FzTotal,10.0),1.0,0.0);
  
  AnyForce3D Force ={
    
    AnyRefFrame  &ref=.ForcePlate.TransducerLocation ;
    Flocal=.OnOff*{.load(.ForcePlateDriver.t)[0],.load(.ForcePlateDriver.t)[1],.load(.ForcePlateDriver.t)[2]};
    AnyDrawVector DrawForce =     {
      AnyRefFrame &ref=.ref;
      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;
    };
    
    
  };  
  
  
  AnyMoment3D Moment ={
    
    AnyRefFrame  &ref=.ForcePlate.TransducerLocation ;
    Mlocal=.OnOff*{.load(.ForcePlateDriver.t)[3],.load(.ForcePlateDriver.t)[4],.load(.ForcePlateDriver.t)[5]}*Folder.PointsScaleFactor;
    AnyDrawVector DrawMoment =     {
      AnyRefFrame &ref=.ref;
      Vec=.Mlocal*1/1000;
      PointAway = Off;
      DrawCoord = Off;
      
      Line.RGB ={1,0,0};
      Line.Thickness = 0.01;
      Line.End.Thickness = 2*0.01;
      Line.End.Length = 4*0.01;
      GlobalCoord=Off;
    };
    
    
  }; 

I hope this may help you.

Best regards,
Moonki

If you see the ‘S’ function(strength) of this NoContactMuscle,
this ‘S’ strength can be zero either ‘Limb2Contact’ can be zero or '.NodeWithInBox.OutsideBoxOrVelHigherThanThreshold ’ can be zero.

I think I missed this point when reading the script.
This function contains that any limb (limb1 or limb2) is contacted on the force plate then S of NoContactMuscle becomes zero. That means only when the foot is off from the place, NoContactMuscle’s strength is non-zero and roles as a countraction for the force plate balancing.

Thank you for your answer, I believe that will be helpful for me.

Sheen Dong-Pyoung

Hi,
I have tried with conditional contacts under the pelvis and thigh, but I still have problems on it.

I attached 4 conditional contacts on the pelvis and 2 on a thigh.
One thing is that I’m not sure that I gave a right condition on the model.
The other thing is that here comes over-strained muscles, Vastus Lateralis and Rectus Femoris of the right thigh, from the first frame with the static position and the analysis stopped before the actual action starts.

I attached the script which was worked on AMMRV 1.3.1.

Thank you.

Sheen Dong-Pyoung

Hi

I had a quick look at the post, from your description and picture i can think of the following which often goes wrong:

On your surface you need a node which has a normal vector pointing upward from the surface, this must be your “basenode” in the support element(conditional contact). If this is the z component the direction vector will be

Direction={2,0,1};

Secondly the Radius, limit_low and limit_high needs to be high enough otherwise there will be no contact forces…

Best regards
Søren

Dear Søren,

On your surface you need a node which has a normal vector pointing upward from the surface, this must be your “basenode” in the support element(conditional contact). If this is the z component the direction vector will be

Direction={2,0,1};

According to your mention, the aqua blue nodes need the normal vector if it is to be base node. Is that right?
I believe this means the BaseObject of ConditionalContactClass below.
As you can see, I already set up NormalDirection = Z, FrictionDirection1 = X, FrictionDirection2 = Y; this makes Direction= {2,0,1}.

One thing I am worrying other than the radius and height you said is that the location of CC cylinders.
The CC cylinders’ location when model is loaded and the location when model begins analysis is different; I set up the locations based on the dummy segment but they rotates 90 degrees about the z axis when analysis begins.
Doesn’t this harm the analysis?

With Regards,
Dong-Pyoung

Dear Dong-Pyoung,

I took a breif look at the model,

A few things looked strange.

I did not find any applied force on the new forceplate segment, the dummy seg definition look ok, but there seem to be no force applied to it. To test the setup i would try appling an AnyForce to the segment to see you can get some forces shown in the support elements.

Concerning load positions this is not important waht counts is the direction once the model is running.

Best regards
Søren

Dear Søren,

You mean that I missed something between the force plate and the newly added dummy plate thus force is not exerted between them?
I have applied the conditional contact example with pedaling to this model and now I looked though the script but I don’t find what I missed yet.
Please let me know what I can do.

Dong-Pyoung

Dear Dong-Pyoung,

I do not think you are missing anything concernig the conditional contact but i did not see any force applied to the new force plate.

In the pedaldemo example there is a spring load applied. In your case i assume you have measured something on the buttocks, these forces needs to be applied to the plate. If no forces was measured the reactions forces on the plate should be on instead of off.

Best regards
Søren

Dear Søren,

as you said, the force plate under the buttocks measures the force and it should be applied to the dummy force plate.
That means the model need something to add for defining force interaction between the segments, isn’t it?
AnyReacForce looks to work and now I’m trying to use it for force definition, but still have problems of overloaded muscles.

Is my approach wrong?

Dong-Pyoung

Dear Dong-Pyoung,

If you have measured forces you will need to use an AnyForce3D element and apply the measured force to the new segment.

So something like this (sorry for typos…)

First you need to read in the forces from a file? (if you have them in the c3d already skip the next lines…)

AnyFunInterpol MyForceInterpolFunc={
Filename =…Mydatafile.txt
Type=BSpline;
BSplineOrder =4?;
};

AnyForce3D myforce ={
AnyRefFrame &ref=…MyPlate.MyNode;
Flocal ={MyForceInterpolFunc(.t)};
};

This will apply the measured force on the plate segment and it should have the reactions swicthed off in the joint.The applied force is then automatically transferred to the buttocks through the support elements.

Best regards
Søren

Dear Søren,

Hi, I has been doing other work so I could not deal with this model for a time.
Now I have applied what you said; the force transaction between the setup force plate and my own dummy plate.
In this case, the dummy has four conditional contacts on the plate; two for pelvis and two for thighs. And their corresponding nodes are two on the pelvis, one on the right thigh, and one on the left thigh.
As you can see in the figure, however, only one conditional contact is activated on left thigh which is defined at the last time; other three conditions are not working.
I used the toolbox defined in AAUHuman and applied the example of PedalDemoConditional in AMMRV1.3.1.

Another is that, as you can see in another figure, there is overload on the right thigh muscle, which accompanies a large amount of knee torque.
However, when I used only two force plates of ForcePlateType2AutoDetection.any under the feet of the without buttock force plate, it showed the knee torque like third figure.

Could you please help me with these issues?

Thank you.

Hi,

Attached please find the fixed version of your model.

I had to spend much time to modify this model.

I changed many things in your code, but I would point out two important mistakes of your previous model.

  1. In the ‘AnyBodyStudy InverseDynamicStudy’ object, you set the wrong direction of gravity.

  2. In the ‘Environment.any’ file, for ‘ForcePlateType2 Plate1’ object, you should set its Limb parameter as ‘.HumanModelRef.Left.Leg.Seg.Foot’.

Please read the attached modified code carefully to understand well. And if you have other questions then ask to us again.

Best regards,
MJ

P.S) If your code uses a kind of modified model repository, then please modify your code to use the original repository.
We can’t manage the modified repository from all of users. :slight_smile:

Thank you for your help.
I looked though the scripts, and I found the main difference is that the base of conditional contact is single corresponding to the hip plate, and this base is commonly used for the target nodes on the body segments.
I appreciated your assistance.

With regards,
Sheen Dong-Pyoung