FDK model of cadaver knee

Dear AnyBody Community

I'm attempting to replicate a cadaver experiment within AnyBody software. The experiment involved scanning a cadaver's lower limbs (femur, tibia-fibula, and patella) in four different positions. We used these scans to interpolate and generate 28 frames of leg motion data. Subsequently, seven bone markers were applied, and the data was converted into a C3D file.

I've successfully created a model with revolute joints between the femur and tibia and between the femur and patella. However, I'm aiming to expand this to a 6-degree-of-freedom model for the femur-tibia joint. To achieve this, I incorporated the relevant ligaments and cartilage layers.

While the FDK tutorial and KneeSimulator example provided valuable insights, I'm uncertain about how to proceed further since:

  • The experiment involved a cadaver with no active muscle contribution.
  • The scans were obtained with the cadaver in a lying position, lacking data on ground reaction forces (GRF) or loads like the hip axial force mentioned in the examples.

Given these constraints, I would appreciate guidance on the best course of action:

  • Should I introduce a minimal stabilizing force at the hip joint?
  • Can the FDK simulation function solely with the ligament information and the C3D data?

Thank you for your time and assistance.

Best regards
Kate Duquesne

Hi Kate,

This sounds an interesting problem to model. I didn't quite understand what exactly are you trying to investigate from the model. So, it's a little bit hard to suggest what you should do.

But here are some thoughts:

  • There are no active muscle contributions, but is the passive contribution from the muscles important for your investigation (for example, if you are at the limit of range of motion of the joint)? If yes, then you may need to use the Hill muscle model with very low strength. If not, then probably you can stick with simple muscles with very low strength. Another option could be to switch off muscles completely (this will however introduce joint actuators that will provide the torque for the motion). You can also exclude that through AnyMechObjectExcluder.
  • But since the movement is obviously not generated by the cadaver, you must also consider some external force that resulted in this movement and can help achieve dynamic equilibrium. Since you don't have these loads, then you should probably introduce some kind of stabilizing force at either end.
  • The FDK simulation can, technically, run with ligaments and C3D data. But, I am not sure if it will be enough because I don't understand what exactly are you trying to investigate.

I hope this helps.

Best regards,
Dave

Dear Dave

We developed a method for evaluating the joint kinematics of passive systems. We aim to benchmark our method against the state-of-the-art FDK approach. In the experiment, we want to utilize the FDK method to determine the joint angles and translations for the femur-tibial knee joint based on the created C3D data.

In the experiment, we positioned the cadaver in the CT scanner and kept the foot in place using a mesh plate with cylinder sticks. So indeed, there was a "Ground Reaction Force" applied. However, this force is unknown.

The model I created now contains

  • 3 segments: Femur, Tibia-Fibula, and Patella.
  • 10 ligaments
  • 2 joints: Femur-Patella (revolute joint) and Femur-Tibia (6 degree of freedom joint)
  • contact surfaces (and consequently a contact force between femur and tibia)
  • a part to set the parameters of the ligaments taking into account the rest length

When running the study without applying any muscles or external forces, the following error: ' There are fewer unknown forces (muscles and reactions) than dynamic equations.' appears, which seems very logical.

However, I am not sure how to proceed.

  • Should I exclude the joint actuators, even if I don't want to include the muscles?
  • Would you have any guidance on how to apply a stabilizing force at the hip and ankle joint?

Best regards
Kate

Hi Kate,

Thanks for your reply. Now, I understand the situation better. So, what I would suggest is that you add 6 reaction forces at the foot. This will take care of the "GRF" at the foot. You may even consider excluding the ankle and foot altogether, and just applying the 6 reactions at the shank itself and simplify it even more.

Then, you should remove all the muscles. If you switch off the muscles using the BM statements, please make sure to exclude the joint actuator as well.

Let's say the femur will be moving freely while the tibia is grounded at one end. From your motion data, you will need to estimate the knee flexion movement and prescribe this as a knee flexion driver. But some force must carry this knee flexion movement. So, you can consider either keeping the reactions on for this driver or keeping the knee joint actuator muscle (that I asked to exclude just above).

The rest of 5 degrees of freedom (movement and reactions) at the femur-tibia knee joint will be estimated from the ligament properties that you define. These are typically the constraints in the revolute joint.

So, to kind of sum up the simplified mechanical system, you have the femur and the tibia. You add 6 reactions to take care of the grounding/stabilizing force. Then, you add 1 torque generator for the knee flexion movement. And finally, you have 5 reactions from the FDK ligament model.

I hope this helps.

Best regards,
Dave

Dear Dave

Thank you for your reply!
To further clarify, I started building the model from scratch so I do not have a foot or muscles :wink:

I have some smaller questions before proceeding:
From my C3D data, when employing a revolute joint for the knee joint, both tibia and femur move. Is there an easy way to define the 6 reactions at the tibia distal end?

Is there an efficient way to convert the knee flexion movement from the C3D file to a knee flexion driver?

Best regards
Kate

Hi Kate,

For the first question, you can simply add AnyReacForce. This will create the reaction forces according to the kinematic measure you provide without adding any kinematic constraints. That, is you can supply a kinematic measure between the tibia and the global ref.

Second question is a little bit more tricky. The most efficient way will be to setup the processing pipeline like we have in our mocap models. So, first you run the marker tracking study to export the joint angle. Then, you run the inverse dynamics study using the extracted joint angle as a driver.

I think, it should be possible to use the c3d data directly in the FDK study. However, the speed will take a significant hit as you will need to run an over determinate analysis along with FDK analysis.

Best regards,
Dave

Dear Dave

I finally got around to testing your suggestions, but I wasn't able to get the entire model to function completely.

Currently, the model includes 18 degrees of freedom representing the femur, tibia, and patella. I implemented the marker tracking and successfully exported data for knee flexion, patellofemoral flexion, as well as the position and orientation of the ground contact point on the tibia. As you recommended, I imported this data as optimized drivers. Additionally, I defined a reaction force at the dorsal part of the tibia, following your suggestion

Main.Model = {
  Interface = {
    AnyKinLinear Tibia_Global_Linear = {
      AnyRefFrame &Tib = Main.Model.Seg.Tibia;
      AnyRefFrame &Glob = Main.Model.GlobalRef;
    };
    AnyKinRotational Tibia_Global_Rot = {
      AnyRefFrame &Tib = Main.Model.Seg.Tibia;
      AnyRefFrame &Glob = Main.Model.GlobalRef;
      Type = RotAxesAngles;
    };
  };
  
  AnyFolder Loads = {  
    AnyReacForce Ankle_Lin = {
      AnyKinMeasure& ref = ..Interface.Tibia_Global_Linear;
    };
    AnyReacForce Ankle_Rot = {
      AnyKinMeasure& ref = ..Interface.Tibia_Global_Rot;
    };
  }; 
};

In the inverse dynamics study, the model view confirms that I applied the kinematics correctly. However, I still encounter an error when running the model without FDK features:

No solution found : There are fewer unknown forces (muscles and reactions) than dynamic equations.

However, when I check the object description of the inverse dynamics study, it shows 18 degrees of freedom (DOF), 2 joint coordinates, 18 drivers, and a total of 13 active reaction and driver forces.
Would you have any recommendations to resolve this?

I continued by including and (successfully) calibrating the ligaments in the model. Following this, I incorporated cartilage layers and utilized the AnyForceSurfaceContact feature. With these additions, I ran the inverse dynamics analysis with FDK features enabled. I encountered two errors:

  • The same error as above (fewer unknown forces (muscles and reactions) than dynamic equations.)
  • Failed to resolve force-dependent kinematics. Too many iterations used (final force error = 1.636619E+10). Continue anyhow...
    Constraint no. 0 above error tolerance 0.001000, error = 30297118.219720.

The model view indicates that the femur and tibia are initially separated. I'm unsure if the lack of initial contact between the femur and tibia is causing the errors. Should I address this or focus on other potential issues?

I'd appreciate any insights you might have on these issues.

Best regards
Kate Duquesne

Hi Kate,

It seems you are on the right-track. For your FDK model, you should have 13 active reaction and driver forces and 5 FDK reactions at the knee. However, you mentioned that even without the FDK features you only see 13 active reactions and driver forces. It maybe that when you disabled the FDK features, you forgot to set the Reaction.Type back to {On}?

But I am guessing, you are probably missing some reactions somewhere, since you see the same error of fewer unknown forces even with FDK. If you can paste a screenshot of the study description, it might give a clue.

But for the model without FDK, it should be something like this:

  • 6 reactions between tibia and global ref (this you have already).
  • 5 reactions and 1 driver force at knee joint (tibia-femur).
  • 5 reactions and 1 driver force the patella-femur revolute joint.

It could look a little bit different depending on how your model is driven.

First of all, the error with unknown forces must be solved.

Then, it can be sensible to check the ligament properties. If you are facing some error with FDK, it could be a good idea to firstly add some simulated stiffness on the linear and rotational measures rather than defining ligaments directly. And do this step-by-step, switching one hard constraint of the revolute joint at a time to ForceDep type. This way you can see exactly which DOF and stiffness properties create issues.

 AnyForce KneeStiffness = {
    AnyKinLinear &lin = .KneeLinMeas;
    AnyKinRotational &rot = .KneeRotMeas;
    F = {-1e3*lin.Pos[0], -5e3*lin.Pos[1],-5e3*lin.Pos[2], 0, -1e1*rot.Pos[1], -5e1*rot.Pos[2]};
    // assuming z axis is the axis of rotation
 };

You can also read a bit more about FDK on our wiki page.

Best regards,
Dave

Dear Dave
Thanks for getting back to me! I'm making progress :smiley:
I indeed forgot to re-enable the reactions when I ran the model without the FDK features.

Good news, the model is now running! However, I still have a couple of things I'd appreciate your advice on.

First, I'm getting a warning about there being no muscles or actuators in the model. This makes sense as I am not using any muscles. Can I safely ignore this warning, or is there something else I should be aware of?

WARNING(OBJ.MCH.MUS1) : Main.any(77) : InverseDynamicStudy : The muscles in the model are not loaded due to kinetically over-constrained mechanical system.
NOTICE(OBJ1) : Main.any(77) : InverseDynamicStudy.InverseDynamics : No muscles or other recruited actuators in the model.

Second, I'm seeing some unusual rotations in the model (see attached GIF).
KneeBending_SlackLigaments

I have a couple of ideas about what might be causing this:

  1. I suspect some ligaments might be getting slack too early in the movement. For calibration, I positioned the leg straight and assigned reference strains in that pose for all ligaments. While the calibration sequence updates rest lengths, it happens before the inverse dynamics simulation (at the initial straight leg pose). In this position, there is still a small gap between the femur and tibia. This might lead to an overestimation of the rest lengths?
    How can I optimize the calibration sequence to avoid overestimating ligament rest lengths? Should I optimize the rotation center of the knee so that the surfaces are already in closer contact to each other?
  2. In contrast to the GitHub page and posts on the forum, I can get the model only working with very low pressure modules (a pressure module of 10^3 and 10^4). Working with a pressure module of 10^11 like suggested in (All about Force Dependent Kinematics · AnyBody/support Wiki · GitHub ), results in a incorrectly positioned knee, with the femur and tibia ending up next to each other and instead of overlapping. Would you have any advice on this?
  3. To prevent (2) from happing, I tried to split up the medial and lateral condyle by importing separate stl files and adding two 'AnyForceSurfaceContact's. This did help me a bit (as I could now run the model with a pressure module of 10^11). However, I am unsure on whether this is good practice. Do you have any insights here?
    KneeBending_SlackLigaments_PressureModule11

For my post-processing needs, I plan to calculate joint angles using a custom script. This will involve exporting the surface data of the tibia and femur in each frame, registering the surfaces, and then calculating the angles. My question is:
Is the exported bone position data accurate enough for this purpose, or will there be additional errors introduced by the export process. In other words, is the model view accurate enough for this purpose?

Thank you for your time and expertise. Please let me know if you have any suggestions.

Best regards
Kate Duquesne

Hi Kate,

Good to hear you are making progress!

I agree, you can safely ignore the warning about no muscles in the model.

I will say again, you are on the right track :slight_smile:

  1. It would make sense to ensure that there is a small contact when you calibrate the ligaments. Otherwise, you will overestimate the slack length. You should also consider adding some wrapping surfaces for your ligaments, especially the ones connecting the patella on the proximal side. Also, I can't see for sure, but do you have the cruciate ligaments?

  2. I think the most important point about the pressure module is that you don't see penetration. For sure, there has to be some penetration for the contact force, but it should be minimal. So, you should look at the simulation and if you see too much penetration, then you need to raise the pressure module.

  3. That is a good idea. Then you can see the force on either side.

The model view should be accurate. It reflects what's happening in the model and studies. When you export the surface, you should export them in global ref frame.

Best regards,
Dave

Dear Dave

Thanks again for your helpful answers! Yes, I included the cruciate ligaments (it was indeed hard to see in the above gifs).

For the ligament calibration, I now remove the knee joint and use a driver to drive the relative position of the femur and tibia. However, this results in contact only on the medial side, not the lateral side. By adjusting the driver I can achieve bilateral contact (see picture). However, this approach remains arbitrary based on the chosen driver settings. Is there a way to leverage the contact information, or the FDK output, to automatically compute the correct position instead of relying on manual driver adjustments?
image

Best regards
Kate

Hi Kate,

It is a catch-22 situation. You can possibly use some kind of pretension to drive the model into a "correct" posture. In this pretension model, you can add a couple of springs that try to push the femur and tibia into each other. Then, you should see contact on medial and lateral sides. Finally, you can use this pretensed position to calibrate the ligaments.

Maybe you will need to run a few iterations before you get your model correct.

Best regards,
Dave