Redundant constraints on my Exo-HumanBody model

Dear seniors,

I am trying to bind my exoskeleton model to the HumanModel, and after researching many posts on forum, I have achieved some results. Here is my work. (3.8 MB)

At first, I imported my whole exoskeleton into Anybody, but in the end, I found it a bit difficult. Now my exoskeleton model only retains the both thighs, shanks, and knees. I use AnyCylindricalJoint to connect the exoskeleton kneejoints with the human model kneejoints. Nodes were created on the thighs and shanks of Exo-model and HumanModel, and constraints were implemented using AnyKinEq: the x-axis and z-axis were constrained at the thighs, and the x-axis was constrained at the shanks. Perhaps due to the lack of strict correspondence between the thigh and shank nodes on the exoskeleton and human model, the position of the exoskeleton in the completed kinematic analysis model may be slightly tilted.
kinematics completed
My thigh and shank nodes are determined based on the corresponding kneejoint node position coordinates, but postures of their kneejoints are different, that should be the reason why the thigh and shank nodes cannot be strictly matched. I don't know if my understanding is correct.

The trouble is with my inverse dynamics analysis. Based on what I have seen in other posts, the added constraints need to be balanced by adding reactions. My single leg has a thigh and a shank, introducing 12 degrees of freedom. In the kinematic section above, I added additional 7 constraints for each leg, so theoretically, I should add 7 additional reactions. I added 7 reactions using AnyReacForce for single leg and set the Constraints.Reaction.Type of AnyCylindricalJoint to {Off, Off, Off, Off}.

Unfortunately, after running the inverse dynamics analysis, it showed redundant constraints and displayed "Muscle recruitment solver : solver aborted due to singular KKT matrix

This is beyond my ability, and I hope someone can help me solve this problem :smiling_face_with_tear:.

Best Regards

Hi Meng,

Welcome to the AnyScript Forum!

This looks like a really nice model!

I am not sure I understand you correctly, so I will just try to explain the basics:
Your exoskeleton has 2 segments and that means it has 12 degrees of freedom (dof). I suppose there is a revolute joint between these two segments and that adds 5 constraints. In the kinematics, you add a cylindrical joint (4 constraints) and three additional constraints between the thighs and shanks. So here, it looks good, that you have 12 constraints for the 12 dof.

In the inverse dynamics, you still have the 5 reactions from the exo knee joint, and then you add 7 reactions so that your total comes to 12 reactions. This is also good. You switched off the reactions at the cylindrical joint, so you need to add 7 reactions. I suppose you want to add these reactions at the connecting point on the thigh and shank?

I think the problem is that you have added 3 rotational reactions at the thigh and 3 rotational reactions at the shank. This is leading to the warning of redundant reactions since practically you have added reactions twice in the same 3 rotational dofs because there are the reactions from the revolute joint as well between the exo thigh and shank. So, you should try different combination, like some linear reactions and some rotational reactions. Here is an example of what should work: 3 linear reactions at thigh, 3 linear reactions at shank, and 1 reaction along the long axis of the thigh (or shank).

I hope this helps.

Best reagrds,

Hi Dave,

Thank you very much for your help!

First of all, I apologize for my carelessness. When I opened my file again, I found that I made a mistake when adding a reaction on left thigh of Exo: I placed the name of shank in the position of
thigh :sweat_smile:. As you pointed out, I added repeated reactions. After correcting this error, I attempted to run inverse dynamics analysis, but it still showed redundant reactions. That indicated that there were sindeed errors in my code, rather than just letting others waste time on my carelessness.

I followed your suggestion and modified the added reaction. The inverse dynamics analysis successfully completed! :yum:

I noticed that in the AMMR, there is a folder named 'Plug in gaitSimple', which contains a file called 'FullBody. main'. I added my exoskeleton to the simple gait model and added the same constraints and reactions as before. I ran the analysis on this model without adding external torque, and the entire process went very smoothly. It's not an exaggeration to say that every successful operation of the dynamics fills my heart with excitement.My next step is to study applying external torque to Exo joints in order to reduce muscle activity in gait. I hope my research approach is correct. Sincere thanks again for your help!

Best regards,

Hi Meng,

I am happy to hear your model is working!

It's really nice that you are also able to add your exo model to the mocap model without hiccups. I will suggest you use the mocap model with ground reaction force prediction. This is because with the standard Plug-in-GaitSimple model, you have the GRF recorded with force plates. This recorded GRF will be applied to your model. However, when you add an exoskeleton model, I expect the GRF to change. But you will only see the recorded GRF in your trial and this may not give you a complete picture. This is why I suggest you use the GRF prediction class template so you are able to see the changes in GRF depending on the exo model.

Best regards,

Hi Dave,

Thank you for providing guidance on my work!

After reviewing your suggestions, I researched the Fullbody_GRFPrediction model(I will abbreviate it as GRF model). Due to the shared Input folder between GRFPrediction model and Fullbody model, and my exoskeleton as well as binding and constraint related code being stored in this folder, when I opened the file of GRF model, my exoskeleton also appeared in the view. After running the analysis, I found that the results were much beyond my expectations. After repeatedly comparing the inverse dynamics analysis results of the Fullbody model and the GRF model, I found some problems. I would like to ask you the following questions.

  1. MuscleActivity, I believe it is a value between 0 and 1. In the Fullbody model, regardless of whether my exoskeleton is added or not, the MaxMuscleActivity is between 0 and 1. However, for the GRF model, even without making any changes to the model (without adding exoskeleton), the MaxMuscleActivity far exceeds 1. Is this normal? In the face of this situation, I am not sure if I should use the GRF model for simulation experiments.

  2. To apply knee joint assisted torque in Fullbody model, my approach is to check the JointMomentMeasure of KneeFlexion after wearing the exoskeleton (without applying auxiliary torque), export the data, fit the curve using sine functions, and apply it as a function of time to KneeFlexion. Please notice that there is no negative sign before my function. I believe that applying torque in this way can have an assisted effect rather than increasing the burden on the knees, and this approach does indeed reduce the MuscleActivity of many muscles. Do you think my approach is correct?

AnyForce Knee = {
    AnyKinMeasure &knee = Main.HumanModel.BodyModel.Interface.Right.KneeFlexion;
    F = {18.73*sin(10.02*t-0.0564)+16.87*sin(0.7468*t-1.484)+ 7.756*sin(7.484*t-3.084)+ 4.852*sin(14.72*t-2.199)+ 3.288*sin(20.46*t+1.5)+ 1.925*sin(18.38*t-4.61)+ 2.891*sin(27.35*t+0.5108)+ 9.702*sin(1.639*t+5.65)};
    //    F = {0 };
    viewForce = {
      Visible = On;
      ScaleToView = Off;
      AppliedForceColor = {1, 0.1, 0.1}; 
      ForceScale = 0.005;

Best regards,

Dear Meng,

I have ran a default model of Plug-in-gait-Simple/FUllBody_GFRPrediction.main and I do not see the high peaks that you see without the EXO. Here is the result of the MaxMuscleActivity, which is between 0 and 1.

I suggest that:

  1. Investigate where in your trial the picks of MaxMuscleActivity happens.
  2. Find which muscle is actually the one with MaxMuscleActivity.

And try it without the EXO first and then add the EXO and see the differences.
The big peaks in the muscle activity also can happen because of the data. Since you see the high peaks with and without the EXO, then you probably made the EXO model correctly :slight_smile: And maybe you should look at the data more closely.

You can use AnyReacForce on different joints and connections to investigate where you need to have high forces or moments, and susequently find where is the problem in the model, which cause big forces in the muscles :slight_smile:

About your second question, it is a simple and maybe a good way of simulating the EXO without the weights of the EXO and interface connections.

Best regards,

Hi Hamed,

Thank you for your suggestion. I checked the CorrectedActivity of most of the muscles in the legs and found that the MaxMuscleActivity does not seem to occur in the legs. Analyzing the default model using Hill muscles, some leg muscles have a peak activity level exceeding 1, but it has not yet reached a level exceeding 10.

The most critical issue is that I analyzed a default file that has not been modified at all, but still encountered such an issue.

I want to know if this issue may be related to the versions of AnyBody and AMMR. I am using versions 7.4 of Anybody and 2.4.3 of AMMR. May I ask which version of AnyBody and AMMR are you using?

Best regards,

Hi Meng,

I understand the reason for the confusion. When you plot the Max Muscle Activity in AMS 7.4, it also includes the general muscles that are used for simulating GRF and the weak residual forces. The overload actually happens in the weak residual general muscles and not in the physiological muscles. Of course, it is quite confusing for some users to think that a physiological muscle is with activity over 10, but you don't see any muscle being overloaded in the model view

Therefore, in AMS 8.0, we have introduced AnyRecruitedActuator, that is used to simulate recruited force such as GRF and weak residuals. Functionally, recruited actuators work exactly like general muscles, but they can be organized differently and this allows the model to make a distinction between recruited forces simulated by muscles and recruited forces simulated by recruited actuators. This is also useful when you want to work with metabolic and fatigue models. Then you can apply them to muscles only and not recruited actuators. Please see below the plot for MaxRecruitedActuatorActivity, which is similar to MaxMuscleActivity that you saw.

Best regards,