GHRot : Close to singular position

I got a warning as below in a modified AMMR model where I try to simulate a hand push or punch:
WARNING(OBJ.MCH.KIN6) : C:/Pro..es/A..y/A..1/AMMR/Body/A..n/Arm/Jnt.any(45) : GHRot : Close to singular position : Orientation close to Gimbal Lock, i.e., first and third axis of rotation being parallel
Failed to resolve kinematic constraints. Newton relaxation too small. (final kin. error = 2.274316E-003)
How could the error be possibly sorted and how can I upload my files to this forum? (I am a new user so cannot attach things to this post)
Please reply as soon as possible - I need the model fixed for my thesis. And thanks a lot.

Hi @katharine815ny and welcome to the forum!

The error you are getting is because the glenohumeral joints is in Gimbal Lock. Try and adjust the position and motion of the joint to avoid getting it locked during the simulation.

Best regards,
Bjørn
AnyBody Technology

1 Like

Thank you for your answer. Please do you how can I share my file so you can check it directly?

Hi, I just figured it out by myself: Dropbox - CrankModel_Angles_that_works.zip - Simplify your life

The first link demonstrates the motion I want to implant and the second is the AMMR model where the error occurs. Could you have a look at them for me? I will appreciate it very much.

Hi @katharine815ny

  • Are you driving the model with motion capture?
  • what version of the AMS and AMMR are you using?
  • Have you tried investigating the glenohumeral position when you experience the gimbal lock?
  • Have you tried altering the motion as I mentioned above?

If you are driving the shoulder degrees of freedom try to change the driver so it does not come close to the position where you see the gimbal lock.

Best regards,
Bjørn
AnyBody Technology

Hi Bjorn,

Thank you for your quick reply.

  1. No I am not driving the model with motion capture.
  2. I am using the AMMR model come with Anybody 7.1.
  3. No I didn't check the glen humeral position since I didn't know how-the model stopped running due to the error so the model's position doesn't change.
  4. I have tried altered the motion but it got worse - I got an unknown error instead. Maybe you can suggest which motion I should alter to?

Also by mentioning not driving the shoulder's degree of freedom, do you mean create external objects and put drivers on them?

Thanks a lot.

Katha

Hi Bjorn I am thinking it could be that I didn't constrain the hand-fingers movement, which is not my objective of study - do you know any way to eliminate the study associated with detailed hands? I have used commends
#define BM_LEG_LEFT OFF
#define BM_LEG_RIGHT OFF
to exclude the legs analysis but do not know how to extract the shoulder-arm out of the BM_ARM_RIGHT group.

Thanks a lot.

Katha

Okay.

are you using one of the ammr example models found in the AMMR/Application folder or have your made your own model?

What is the model supposed to do and how are you driving it?
Is the gimbal lock error you see occuring in the first frame of the study or does it run partial and then stop?
If you can insert the full error message or a screen shot that would help.

What unknown error do you see when changing the motion?

About the degrees of freedom i was asking if you have made a driver that drives the degrees of freedom for the GH joint? if so this is most likely the driver that you can alter to move away from the Gimbal lock

Best regards,
Bjørn
AnyBody Technology


Dear Bjorn

Sorry I don't know what change I made caused it but now the error is the unsolved velocity. I attached three screenshots here: the first is the motion I want to implant which is a crank-slider motion to mimic a karate punch; the second is the AMMR model and start of error description; the third is the end of the error description - in middle lines there are just similar claims about failure to stay within tolerance.

I await for your reply.

Katha

The script of JoitnsAndDrivers.any I am using now: (Sorry for the many invalid lines, I did tried lots of thing before.)

//Joints--------------------------------------------------------------------------------------------
AnyFolder Joints =
{
AnyStdJoint FixedPelvisCentre =
{
AnyRefFrame& InitialPoint = Main.Model.Environment.GlobalRef.Hpoint;
AnyRefFrame& PelvisCentre = Main.HumanModel.BodyModel.Trunk.SegmentsLumbar.PelvisSeg;
};//Fix Pelvis Position
//---------------------------------------------------------------------------------------------------------
AnyPrismaticJoint Rail = {
Axis = y;
AnyFixedRefFrame& Ground = Main.Model.Environment.SliderRef;
//Slider Reference Coordinates is used rather than GobalRef
AnySeg &Slider = Main.Model.Environment.Hand_Ref;
//Function: choose while locate the slider
};
//----------------------------------------------------------------------------------------------------------------
AnySphericalJoint PedalFoot =
{
AnyRefFrame& Pedal = Main.Model.Environment.Hand_Ref;
AnyRefFrame& Foot = Main.HumanModel.BodyModel.Right.ShoulderArm.Seg.Humerus.gh;
}; //Connecting the foot to the pedal
//-------------------------------------------------------------------------------------------------------
//AnyStdJoint PedalFoot2 =
// {
// AnyRefFrame& Pedal = Main.Model.Environment.Glenohumeral_Ref;
// AnyRefFrame& Foot = Main.Model.Environment.Hand_Ref;
// }; //Connecting the foot to the pedal
//---------------------------------------------------------------------------------------------------------
//AnyRevoluteJoint ShoulderDriverJoint=
//{
// Axis = z;
// AnyRefFrame& Ground = Main.Model.Environment.GlobalRef;
// AnyRefFrame& Driver = Main.Model.Environment.Glenohumeral_Ref;

// };

//------------------------------------------------------------------------------------------------------------
}; // Joints

//Drivers----------------------------------------------------------------------------------------------------
AnyFolder Drivers =
{
//-------------------------------------------------------------------------------------------------------------
AnyKinEqSimpleDriver SkullThoraxDriver =
{
AnyKinMeasure& ref0 = ...HumanModel.BodyModel.Interface.Trunk.SkullThoraxFlexion;
AnyKinMeasure& ref1 = ...HumanModel.BodyModel.Interface.Trunk.SkullThoraxLateralBending;
AnyKinMeasure& ref2 = ...HumanModel.BodyModel.Interface.Trunk.SkullThoraxRotation;

DriverPos = pi/180*{0,0,0};
DriverVel = pi/180*{0,0,0};

};//Locking neck motion
//-----------------------------------------------------------------------------------------------
AnyKinEqSimpleDriver PelvisThoraxDriver =
{
AnyKinMeasure& ref0 = ...HumanModel.BodyModel.Interface.Trunk.PelvisThoraxExtension;
AnyKinMeasure& ref1 = ...HumanModel.BodyModel.Interface.Trunk.PelvisThoraxLateralBending;
AnyKinMeasure& ref2 = ...HumanModel.BodyModel.Interface.Trunk.PelvisThoraxRotation;

DriverPos = pi/180*{0,0,0};
DriverVel = pi/180*{0,0,0};
Reaction.Type = {Off, Off, Off};

};// Locking pelvis-thorax rotation
//-----------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------
AnyKinEqSimpleDriver AnkleDriver =
{
AnyKinMeasure& ref0 = Main.HumanModel.BodyModel.Interface.Right.WristFlexion;
AnyKinMeasure& ref1 = Main.HumanModel.BodyModel.Interface.Right.WristAbduction;
DriverPos = pi/180*{0, 0};
DriverVel = pi/180*{0, 0};
Reaction.Type = {Off, Off};
};//Locking the ankle angles

 //----------------------------------------------------------------------------  

AnyKinEqSimpleDriver KneeDriver =
{
AnyKinLinear lin =
{
AnyRefFrame& ref0 = Main.Model.Environment.GlobalRef;
AnyRefFrame& ref1 = Main.HumanModel.BodyModel.Right.ShoulderArm.Seg.Ulna.AnatomicalFrame;
Ref = 0;
};
MeasureOrganizer = {2};
DriverPos = {0};
DriverVel = {0};
Reaction.Type = {Off};
};
//--------------------------------------------------------------------------------------------------------------------------
//AnyKinEqSimpleDriver Shouder_Driver =
// {
// AnyKinMeasure &ref0 = Main.Model.ModelEnvironmentConnection.Joints.ShoulderDriverJoint;
// DriverPos = pi/180*{0};
// DriverVel = pi/180*{5};
// Reaction.Type = {Off};
// };//Specify pedal movement

//-----------------------------------------------------------------------------------------------------------------------
//AnyKinEqSimpleDriver KneeDriver2 =
//{
//AnyKinLinear lin =
//{
//AnyRefFrame& ref0 = Main.Model.TargetBoard.Target;
//AnyRefFrame& ref1 = Main.Model.Environment.Hand_Ref;
//Ref = 0;
//};
//MeasureOrganizer = {2};
//DriverPos = {0};
//DriverVel = {0};
//Reaction.Type = {Off};
//};

//--------------------------------------------------------------------------------------------------
AnyKinEqSimpleDriver ShoulderDriver =
{
AnyKinMeasure & Shoulder = Main.HumanModel.BodyModel.Interface.Right.GlenohumeralFlexion;
AnyKinMeasure &ref0 = Main.HumanModel.BodyModel.Right.ShoulderArm.Jnt.GHRot;
MeasureOrganizer = {2};
DriverPos = pi/180*{0};
DriverVel = pi/180*{0};
Reaction.Type = {Off};
};//Specify movement

As for the AMMR model I trimmed the standard standing model by cancelling the lower parts and the left shoulder-arm part.
The main script is as below:

#include "../libdef.any"

Main = {
// ----------------------------------------------------------
// Model configuration:
// For more info on body model configuration options please load the model and double click on:
// #path HTML_DOC "<AMMR_PATH_DOC>/bm_config/index.html"
// ----------------------------------------------------------

//If you want to use your own draw settings, please outcomment the next line
//#path BM_DRAWSETTINGS_FILE "Model\DrawSettings.any"

// Using your own Mannequin.any file in the Model folder of your model
#path BM_MANNEQUIN_FILE "Model\Mannequin.any"

//-->BM statements
// Excluding the muscles in the trunk segments
#define BM_TRUNK_MUSCLES MUSCLES_NONE
// Excluding the left arm segments
#define BM_ARM_LEFT OFF
// Excluding muscles in the right arm segments
#define BM_ARM_MUSCLES_RIGHT MUSCLES_NONE
// Excluding the left leg segments
#define BM_LEG_LEFT OFF
// Excluding the right leg segments
#define BM_LEG_RIGHT OFF
// Using the right leg as 'TLEM' model
//#define BM_LEG_RIGHT LEG_MODEL_TLEM1
// Excluding the muscles in the right leg segments
// #define BM_LEG_MUSCLES_RIGHT MUSCLES_NONE

// Include default human model
#include "<ANYBODY_PATH_BODY>\HumanModel.any"

AnyFolder Model = {
// A link to the human model
AnyFolder &HumanModel=.HumanModel.BodyModelWithDefaultDrivers;

// Environment files are used to include objects surrounding human, e.g. global reference frame
#include "Model\Environment.any"   

AnyFolder ModelEnvironmentConnection = {
  // This file contains all joint and foot reaction forces to simulate standing human
 #include "Model\JointsAndDrivers.any"
};

};

AnyBodyStudy Study = {
AnyFolder &Model = .Model;
Gravity={0.0, -9.81, 0.0};
tStart = 0.0;
tEnd = 4;
nStep = 50;

// these settings are needed for adding drivers without removing the default set 
Kinematics.SolverType = KinSolOverDeterminate;
InitialConditions.SolverType = Kinematics.SolverType ;

};

#include "Model\RunAppSequence.any"

}; //Main

Hi @katharine815ny

I think you are overcomplicating your model a little.

Is the motion you have on the slider-crank model very complicated or is it a fairly simple "punch" i.e. the arm just doing a simple extension of the elbow and flexion of the shoulder?

if yes then you can skip all the added joints and just drive the two joint angles by a driver on the elbow and one on the shoulder.

If you have issues with the changes you have made try and revert them one by one to see when your model starts behaving as expected. FOr now i think you have drivers that are working at the same degrees of freedom and you need to be careful when orchestrating a motion like that

Best regards,
Bjørn
AnyBody Technology

1 Like

Thank you for your advice! I will work on it and see if simply controlling the two joints works for me. Also, could you give me the technical terms of these two joints? I am not familiar with the biomechanical terms in the repository and sometimes take a long defining the element I am interested.

Regards,
Katha

Hi Bjorn,

I am trying to drive the GlenohumeralFlexion, ElbowFlexion and ElbowPronation but the intial position does not run as I expected. Though by adjusting Mannequin.any I made the model load with the initial position I want. Could you try to spot where the problem lays?

I attach the screenshot for 1) Mannequin.any and the loaded model vision and 2) The simple drives and calculated initial position vision.

I look forward to your reply.

Regards,
Katha

Hi @katharine815ny

It is correct that you adjust the values in the mannequin file to set the initial position of the model.
The values you set on the drivers do not set the initial position but how much that joint angle is going to move throughout the simulation.

Be aware that setting the DriverPos = pi/180*{90}; means the the measure you point to will move 90^ \circ/sec so you need to think about how long your study is (i.e. from tStart to tEnd)
So if you have tStart = 0 and tEnd = 4 the measure will move 4*90^\circ which is going to make the arm go crazy.

Best regards,
Bjørn
AnyBody Technology

Hi Bjorn,

I see. But shouldn't DriverVel define how much angle will the joint move in one sec?
So if I don't want the model to switch position when it is initialized, I just need to set DriverPos = {0}; right?

Regards,
Katha