FDK stability

Hello guys,

I tried to implement FDK features to the shoulder-joint.
First of all I only tried to implement it to the anterior-posterior plane of the gh-joint (z direction of scapula-gh).

    
AnyKinEqSimpleDriver GHLinCon = {
      AnyKinMeasure &GHLinCon = .GHLin;
      Reaction.Type={Off,Off,Off};
      CType = {Hard, Hard, ForceDep};
      DriverPos={0,0,0};
      DriverVel={0,0,0};
    };
    
  AnyFloatVar GrThanZero = gteqfun(GHLin.Pos[2], 0.001);
  AnyFloatVar const = iffun(GrThanZero, -40, 40);

   AnyForce ShoulderStiffnessAntPost = {
      AnyKinLinear &lin = .GHLin;
      F = {0,0,-(.const + 2.5*1000*lin.Pos[2])};
    };

since I have 2 dircetions to cover I tried to turn the stiffness function at the point of GHLin.Pos[2] = 0.001 (because 0 results in an iteration over negative and positive and doesn’t lead to results) so I have the stiffness effect in both directions positive and negative.

I also used following options for FDK:

        
        InverseDynamics.ForceDepKinOnOff=On;
        InverseDynamics.ForceDepKin.LocalSearchOnOff = Off;
        InverseDynamics.ForceDepKin.MaxIteration = 10;
        InverseDynamics.ForceDepKin.ForceTol = 0.5;      

My problem now is, that the FDK is not stable. I get an Error like that

Failed to resolve force-dependent kinematic constraints. Newton relaxation too small. (final force error = 3.495372E+000)

Therefore i have some questions:

How are the residuals for FDK calculated?

How can i stabilizise the FDK?

How does AnyBody decide which forces are used for FDK and which one are translated to the thorax segment?

Is there a publication which explains the functions of FDK in detail?

Thanks for your effort :wink:

Greetings,

Mischa

Hi Mishia,

Please see the wiki page on FDK:
https://github.com/AnyBody/support/wiki/All-about-Force-Dependent-Kinematics

I think the stiffness function looks discontinous it will jump 40N around zero, this will not lead to smooth convergence.

Please try to test your stiffness function in the same manner as described here for the surface contact, i know stiffness is differently defined but for the solver it is the same it “feels” the stiffness. https://github.com/AnyBody/support/wiki/All-about-Force-Dependent-Kinematics#anyforcesurfacecontact

So ensure there are no jumps in the stiffness.

I think your MaxIteration too small please use default value for this.

Q: How are the residuals for FDK calculated?
A: Basically the solver adds initially a reaction force on the FDK dofs, then it iterates the position on these DOF until there is no longer the need of the reaction. It will stop when the reaction is less than ForceTol.

Q: How can i stabilizise the FDK?
A: Short answer: stiffness
If you move manually the FDK DOF you need to have a smooth function for the stiffness, if there are jumps on the stiffness the solver will not be able to find a solution, also if the stiffness disapears, it will fail.

Q: How does AnyBody decide which forces are used for FDK and which one are translated to the thorax segment?

A:This question i do not understand, in this case you have FDK on the GH joint between scapula and humerus… not thorax…

Q: Is there a publication which explains the functions of FDK in detail?
A: Please see the tutorial on FDK.

and this reference:

2011 Andersen, M.S., Damsgaard, M. & Rasmussen, J.*(2011),*"Force-dependent kinematics: a new analysis method for non-conforming joints",*Presented at the 13th Biennial International Symposium on Computer Simulation in Biomechanics,*pp.*2 pp.. [PDF]  

Dear Mishia,

Just a small addition to Søren’s answer. I previously wrote a lecture note about FDK. This I have attached. Also, have a look at the publication list on AnyBody Technology. There are several papers about FDK.

We also have journal publication describing the theory of FDK on its way. I expect that it will be published within the next 1-2 months.

Best regards
Michael

Hey,

first of all thank you for your fast reply!

Q: How can i stabilizise the FDK?
A: Short answer: stiffness
If you move manually the FDK DOF you need to have a smooth function for the stiffness, if there are jumps on the stiffness the solver will not be able to find a solution, also if the stiffness disapears, it will fail.

The problem is I want to have the same stiffness-function in both directions negative and positive. So in my mind, if I only describe it for the positive direction it will appear as stiffness for this but amplification for the negative direction.

Is this right or completely wrong? :slight_smile:

Thanks guys!

Greetings,

Mischa

Hi Mischa,

What i did not understand in your code was the reason for the “const” term

So i think something like below would work it would have same stiffness behavior positive or negative.

 
 AnyForce ShoulderStiffnessAntPost = {
    AnyKinLinear &lin = .GHLin;
    F = {0,0,-( 2.5*1000*lin.Pos[2])};
 };

Best regards
Søren

Hey Søren,

the const term is based on the anterior-posterior stiffness function of McQuade 2004: “Anterior glenohumeral force/translation behavior with and without rotator cuff contraction during clinical stability testing”.

I just tried to implement the whole function.

Which leads me to the point I was asking about.

If the humerus is translated by FDK in positive direction the function (-2.51000deltaPos - 40) will appear as stiffness function where deltaPos is positive.
If the hummerus is translated by FDK in negative direction the function (-2.51000deltaPos + 40) will appear as stiffness function where deltaPos is negative.

Thats why I implemented the switch from 40 to -40 at the point of 0 (which didnt find a solution at step 0 so I changed that to 0.001).

I hope my way of thinking is clear now :slight_smile:

Thank you!

Greetings,

Mischa

Hi Mishia,

I have tested the stiffness defintion you have and it introduces a jump like i expected.

Please try the attached model and evaluate the stiffness output, as you can see it has a ±40 jump around the zero point, this will make it hard for the optimization to converge.

Best regards
Søren

Hey Søren,

thank you for the example.

So I am trying to get the model stable.
Therefore I excluded the jump and took a simple stiffness function like:

  
 AnyForce ShoulderStiffnessAntPost = {
      AnyKinLinear &lin = .GHLin;
      F = {0,0,-(4*1000*lin.Pos[2])};
    };

But at some point the model still falls into an error.

Failed to resolve force-dependent kinematic constraints. Newton relaxation too small. (final force error = 2.759988E+001)
Constraint no. 0 above error tolerance 0.500000, error = 16.448512.
Constraint no. 1 above error tolerance 0.500000, error = 27.599885.
70) ...Inverse dynamic analysis terminated
ERROR(OBJ.MCH.KIN3) :   Z:/0..a/O..r/O..r/A..n/Beta/e..d/eththorax_any_stand.main.any(57)  :   Study.InverseDynamics  :  Kinematic analysis failed in time step 70

Should I increase the stiffness to avoid these errors?

I am not sure where this comes from eventho I read the FDK lecture from Michael (thank you for that Michael!).
(The wiki and the tutorial is not helping too much)

Thank you again!

Greetings,

Mischa

Hi Mischa,

The error indicates that the kinematics failed.

So this is different from what you saw previously “Newton relaxation too small force error …”

The current error indicates that the FDK solver wanted to move the FDK dof into a postion where the model could not assemble.

Please try to use the Force recreate view or press CTRL + F12 while the model is running this forces the ModelView to update and it may provide some insight into which solution the solver is trying to find.

Please try to decrease the InverseDynamics.ForceDepKin.MaxNewtonStep,
https://github.com/AnyBody/support/wiki/All-about-Force-Dependent-Kinematics#maxnewtonstep

If none of this helps try to increase stiffness and see how low you can go to figure out what goes on.

Best regards
Søren

Hi Søren,

increasing the stiffness helped stabilizise the model.
I decided to chose a higher stiffness function to limit the maximum translation by FDK.

Thank you for your help!

Greetings,

Mischa

Hi Misha,

Great that it worked

Best regards
Søren

Hi Mischa,
I worked during my PhD on the same type of development, and we’re still having some research projects about it in our lab.

Maybe this wiki page could help you : https://github.com/AnyBody/LIOAnyEpaule

Cheers,
Lauranne