I am using the AnyMocap framework to analyze the lower back forces in a movement that includes external forces on the hands. However, since we measured GRF, I set residuals at trunk to see the effect of ground reaction forces on the L5/S1 compression force. However, I don't think that the model is working ok because I see unnormal muscle activation and overload in the trunk. Could you please take a look and let me know if you have any suggestion? S_3.zip (4.5 MB)
Before I look at your model, can you maybe share a screenshot showing the muscle activation overload?
Also, does the model also applies the external forces on the hands? Or is it something that you didn't measure? If it's not applied to the model, can you describe what these external forces are?
Thanks for your response. Please see the new model attached instead of previous one (I made some adjustments). This task is holding an object with a weight of 50 kg (this is done by two persons each holding one side of the object).
We measured hand forces you can see values in the input folder (handforce.csv)
I tried to apply hand forces using the Anyforce3D like this :
AnyInputFile readcsv =
{
FileName = "C:\Users\salehim\Documents\AMMR.v3.0.1-Demo\Application\MocapExamples\PTOP\S03\Input\handforce.csv";
};
AnyVector fz = readcsv.Data[3];
AnyFloat time = readcsv.T;
AnyFunInterpol LeftHand_Fz = {
Type = Bspline;
T = Main.Studies.InverseDynamicStudy.tArray;
Data = .fz;
};
but I keep getting this error:
ERROR(SCR.EXP1) : AnyMocapModel.any(104) : Operator '=' : Illegal operation for given argument types : 'AnyFloat' '=' 'AnyFloat[635]'
So I though maybe only using GRF and applying residuals to the Trunk will make it easier. The moment where muscle overload happens is shown in the picture. I also have tried activating muscles in the lower and upper body but it did not help.
I can see why the error happens. Firstly, I would suggest using the time vector from the input file when you make the interpolation function and not the tarray from the inverse dynamics study since they can have different length (for example if you change the first and last frame for the analysis). Moreover, it can lead to issues in synchronization of force and motion if you provide another time vector instead of the recorded vector.
Another point that I am concerned about was the direction of the applied hand force. You mentioned about holding an object, so I expect the most important force would be in the vertical direction, which is the Y-axis in your model, but you are trying to pass in the fz force in the z direction. I am not sure about the sensor reference frame, but in AnyForce3D, you should provide something in the y component. It looks like you have the data in the input file.
Next, your hand force data is unfiltered and that is not good since you will have many spikes in your data. I tried to use the low-pass filter function that is used to process the marker data. You should check if the settings are alright and you are also welcome to make a new filter function.
Here is the updated code for the hand force. Place this in your main file:
Main = {
Main.Studies.InverseDynamicStudy = {
AnyFolder HandForce = {
AnyInputFile readcsv =
{
FileName = "Input\handforce.csv";
};
AnyVector fz = Main.ModelSetup.C3DFileData.LowPassFilter(readcsv.Data[3]); // filter raw data
AnyFloat time = readcsv.T;
AnyFunInterpol LeftHand_Fz = {
Type = Bspline;
// T = Main.Studies.InverseDynamicStudy.tArray;
T = .time; // use the time column available in the input file.
Data = {.fz}; // Data is defined to be multidimensional
};
AnyForce3D LeftHand ={
F={0, 0, .LeftHand_Fz(Main.Studies.InverseDynamicStudy.t)[0]}; // as data is multidimensional, the value must be correctly indexed
AnyRefFrame &ref= Main.HumanModel.BodyModel.Right.ShoulderArm.Seg.Hand.HandRef;
};
}; // HandForce
}; // Study
}; // Main
Try to fix the input hand force and run the analysis again. As far as the overload is concerned, I am guessing that the load is genuinely too much, and it may not be unreasonable to see overloaded muscles.
I would also suggest enabling the arm muscles and the full trunk muscles.
Thanks to your guidance, I was able to run the interpolation function to assign the force. Regarding the direction of the force, the force values are based on the axes of the sensor that was used for force measurement. I have motion of the sensor from the C3D file based on the three markers that we placed on the sensor.
To model the force correctly, I added a reference frame and derived that based on the 3 mentioned markers. (Please see the attached picture: person hold the object and then rotate that to the left side
)
Now I need to transfer the force from sensor to some point on the hand. Also I don't want to attach sensor using a joint since sensor moves independent to the hand. Is there any way I can do it in AnyBody? I have heard about contact node but I am not sure if this is the best way also it seems a little complicated to me.
For simplification is it possible to apply the force directly to the palm but somehow express the force based on the sensor rotation axes?
I agree that contact node is a bit complicated but it is probably the best suited for this application. From what I understand, you may not have contact at the object with both hands for all the simulation as you mentioned that the sensor moves independent to the hand.
Moreover, I think using the recruited force is probably the best way to distribute the force from the object on the two hands. It will be the model that decides how to best use the two arms to support the object.
Third point that I am thinking about is the grip type. If the object has no handles, then you should use the contact class that simulates friction. But if the object has handles, then you should add recruited actuators in the linear directions (without making frictional constraints) for both hands and two rotational recruited actuators probably, excluding the axis of the handle, since the hand would be able to rotate about the handle. For simplicity, maybe you can avoid the rotational recruited actuators.
You can see some examples in the AMMR. In the seated human model, it uses the frictional contact between the seat and the human. In the Standing Lift model, the recruited force is added individually in the linear directions between the hand and the box.
The simplest case would be to add reaction force between the object and the hands. You can see several sports examples in the AMMR, like the bench press model. But look around the other models to see how else it has been done. I believe this simplistic approach won't be sufficient for you since in your case, the hands keep moving with respect to the object and they may not be always in contact.