How to redefine the dimension of muscle wrapping cylinders

Hello,

I'm working on a model where I modify the length of the acromion in the medio-lateral direction by morphing the Anybody scapula. I have also modified the glenohumeral articulation to implement FDK in it, so the gh joint is positioned differently in my model.

In one of my cases, make the acromion shorter than it is in the original AMMR model.
However as you can see in the next picture, the deltoid wrapping cylinders are now too high which makes that the muscles have a path that makes less sense near the insertion of the acromion. And the muscle have also to penetrate the surface to reach the insertions in the acromion.


So I would like to know how to modify these wrapping cylinders parameters such as radius or it's not posible and I have to exclude these cylinders from the stydy and recreate them in another position by using the same function used in DeltoidWrap.any but with different parameters ?

Thanks in advance,
Best regards,

Dan

Hi Dan,

I just checked the code and seems that the option to overwrite the classtemplate values have already been used, meaning that you would need to modify the code of AMMR to change something in that area. If possible, I would advise you not to touch AMMR.

Your suggestion to exclude and add a copy would be the way to go for me personally. You probably know how to use MechObjectExclude (please search the forum if not). I would exclude all necessary deltoid branches from the analysis and then just make an exact copy, where instead of original wrapping surfaces I would add new ones with desired parameters.

Main.HumanModel.BodyModel.Right.ShoulderArm.Mus = {
  #include "MyDeltoidRedefinition.any"
};
Main.HumanModel.BodyModel.Left.ShoulderArm.Mus = {
  #include "MyDeltoidRedefinition.any"
};
// in "MyDeltoidRedefinition.any"
AnyMuscleShortestPath my_deltoideus_posterior_part_1 = {
   AnyMuscleModel &MusMdl = ..MusPar.deltoideus_posterior_part_1;
   AnyRefNode &Org = ..Seg.Scapula.O_deltoideus_posterior_part_1;
   AnyRefNode &Ins = ..Seg.Humerus.I_deltoideus_posterior_part_1;
   AnyDrawMuscle DrwMus = {
     #include "../drawSettings/MusDrawSettings.any"
   };
   SPLine.StringMesh = 50;

   AnyParamSurfAnalytical &Surf =.MyDeltoidWrappingPosterior.BASE_FRAME.Wrapping_1.Surf;
   AnyParamSurfAnalytical &Surf2 =..Seg.Scapula.deltoid_cyl.cyl;

...

};
MultiWrapSurfs MyDeltoidWrappingPosterior (
BASE_FRAME = WrappingSegment.RotNode,
TYPE = BM_ARM_DELTOID_WRAPPING,
NUMBER_OF_CYLINDERS= 4,
DEBUG=0
) =
{
// MODIFY THESE
Radius = vnorm(..Seg.Scapula.aa.sRel - ..Seg.Scapula.gh.sRel) * 0.71418;
RadiusX = 1.68891 * vnorm(..Seg.Scapula.GHReactionCenterNode.sRel - ..Seg.Scapula.gh.sRel);
RadiusHeight = 0.8626287 * vnorm(..Seg.Scapula.GHReactionCenterNode.sRel - ..Seg.Scapula.acj.sRel);
...
};

Basically just copy and paste relevant code into your include file. I know it is a bit cumbersome, but probably the quickest thing you can do. And please let me know if you need any help with excluding the muscles.

Kind regards,
Pavel

Hello Pavel,

Thank you for your help I will try this solution it seems like the best one since it doesn't change the AMMR code.

So I need to only exclude the muscles since the wrapping surfaces won't do anything ?

Best regards,

Dan

Yes, the surfaces are not active elements and do not have any other functions except guiding the muscles. Their presence should not affect anything.

Kind regards,
Pavel

Hello again,

So I have mutiple questions :

1. To exclude a muscle I have done that :

MechObjectExclude =
arrcat(
ObjSearch("Main.HumanModel.BodyModel.Right.ShoulderArm.Mus.deltoideus_lateral_part_1","AnyMechObject")
,ObjSearchRecursive("Main.HumanModel.BodyModel.Right.ShoulderArm.Mus.deltoideus_lateral_part_1","*","AnyMechObject"));

I don't know if there is a better way to exclude a muscle in only one line of code.

Also, is there a way to exclude every part of a muscle in only one line of code ? For example, the deltoideus lateral has 4 parts and it would be useful to exclude all of them in one line of code.

2. Now I have redefined the muscles and excluded the old ones and I want to create new wrapping cylinder, only for deltoideus lateral for now

I've copy the original code and changed the name but I have an error in the line that declares the MultiWrapSurfs function :

'1' : Unexpected character.

Do I need to change something else than the name of the wrapping surface ?

My code for the wrapping surfaces :

Main.HumanModel.BodyModel.Right.ShoulderArm.Mus = {

MultiWrapSurfs My_DeltoidWrappingLateral (
BASE_FRAME = WrappingSegment.RotNode,
NUMBER_OF_CYLINDERS= 4,
TYPE=BM_ARM_DELTOID_WRAPPING,
DEBUG=0
) =
{
RadiusX = 1.45* vnorm(..Seg.Scapula.GHReactionCenterNode.sRel - ..Seg.Scapula.gh.sRel);
Radius = vnorm(..Seg.Scapula.acj.sRel - ..Seg.Scapula.gh.sRel)0.8613933;
RadiusHeight = 0.86
vnorm(..Seg.Scapula.GHReactionCenterNode.sRel - ..Seg.Scapula.acj.sRel);

WrapSurfLength = 2 * vnorm(..Seg.Humerus.I_deltoideus_lateral_part_1.sRel - ..Seg.Humerus.gh.sRel);
Angles = ..Sign*{68, 85, 100, 120};

AnySeg WrappingSegment ={
//^ Segment on which the wrapping cylinders are placed.
//^ The ssegment follows scapula kinematically, but is dynamically
//^ attached to both scapula and humerus to ensure that forces on
//^ the wrapping cylinders are distributed correctly between humerus
//^ scapula

Mass=0;
Jii={0.0,0.0,0.0};    

r0= ...Seg.Scapula.gh.sRel*...Seg.Scapula.Axes0'+...Seg.Scapula.r0;  
Axes0=...Seg.Scapula.Axes0
#if _LEFT_RIGHT_ == "LEFT"
* RotMat(pi,y) 
#endif;

AnyRefNode RotNode = 
{
  AnyVar PosteriorTilt = 7;
  //AnyDrawRefFrame drwf ={ScaleXYZ=0.1*{1,1,1};RGB={0,1,1};};
  #if _LEFT_RIGHT_ == "LEFT"
  ARel = RotMat(-0.1,y)*RotMat(pi,x)*RotMat(PosteriorTilt*pi/180,x);
  #else
  ARel = RotMat(-0.1,y)*RotMat(PosteriorTilt*pi/180,x);
  #endif
};  

};

AnySphericalJoint WrapSegmentHumerusJnt ={
AnyRefNode &ref1=...Seg.Humerus.gh ;
AnySeg &ref2=.WrappingSegment;
};

AnyFolder &ScapulaRef=..Seg.Scapula;

ScapulaRef={
AnyRefNode gh_rotated1={
sRel=.gh.sRel;
ARel={{....Sign1,0,0},{0,1,0},{0,0,....Sign1}};
};
};

AnyFolder &HumerusRef =..Seg.Humerus;
HumerusRef={
AnyRefNode gh_rotated1={
sRel=.gh.sRel;
ARel={{1,0,0},{0,....Sign1,0},{0,0,....Sign1}};
};
};

AnyKinMotion WrappingSegmentDriver={
AnyKinMeasureLinComb LinComb = {
AnyKinRotational HumerusScapulaRot={
AnyRefNode &ref2=...ScapulaRef.gh_rotated1;
AnyRefNode &ref1=...HumerusRef.gh_rotated1;
Type = RotVector;
};
AnyKinRotational HumerusWrapSegmentRot={
AnyRefFrame &ref1=...ScapulaRef.gh_rotated1;
AnyRefFrame &ref2=...WrappingSegment;
Type =RotVector;
};
OutDim = 3;
Coef={
{0.25,0,0,-1,0,0},
{ 0,0.05,0,0,-1,0}, //this one controls the rotaion around the long axis og humerus
{0,0,0.32,0,0,-1}
};

}; // Measure  

};

AnyReacForce MomentsToScapula =
{
AnyKinRotational rot ={
AnyRefFrame &ref1=..WrappingSegment;
AnyRefFrame &ref2=....Seg.Scapula;
Type=RotVector;
};
};

};

//Deltoideus Lateral Wrapping

};//Mus

[EDIT]
For 2. I found the solution,

I had to changed TYPE to 2 instead of BM_ARM_DELTOID_WRAPPING and rename some nodes that already existed (gh_rotated) and delete the #if statements on _LEFT_RIGHT.

Best Regards,

Dan

Hi Dan,

To select all deltoid lateral parts:

AnyObjectPtrArray test1 =  ObjSearch("Main.HumanModel.BodyModel.Right.ShoulderArm.Mus.deltoideus_lateral_part_*","AnyMechObject");

To select all deltoid parts:

AnyObjectPtrArray test2 =  ObjSearch("Main.HumanModel.BodyModel.Right.ShoulderArm.Mus.deltoideus_*","AnyMechObject");

We can use wildcards to select more than one object. But please always check in the model tree what it selects before trusting the search code :slight_smile:

Kind regads,
Pavel

Hello Pavel,

When I make the search to exclude the muscles with your command I get this error for the 4 muscles excluded :

WARNING(OBJ1) : Muscle.any(384) : deltoideus_lateral_part_1.SPLine : Velocity called before positions
WARNING(OBJ1) : Muscle.any(405) : deltoideus_lateral_part_3.SPLine : Velocity called before positions
WARNING(OBJ1) : Muscle.any(426) : deltoideus_lateral_part_2.SPLine : Velocity called before positions
WARNING(OBJ1) : Muscle.any(444) : deltoideus_lateral_part_4.SPLine : Velocity called before positions

I have checked and the search works, it selected the 4 muscles parts.
This is why I had to use an ObjSearchRecursive to also exclude the muscle's SPLine so that there are no error.

So I have done that and it works but I don't understand why only excluding the muscle didn't work.

MechObjectExclude =ObjSearch("Main.HumanModel.BodyModel.Right.ShoulderArm.Mus.deltoideus_lateral_part_*.*","AnyMechObject");

It is just a warning and the muscles still trying to wrap over wrapping surfaces, but they are not included in the dynamic analysis and do not contribute to the equilibrium of the system. But your approach with excluding SPLines makes it cleaner. So you can do that:

AnyObjectPtrArray test =  arrcat(
  ObjSearch("Main.HumanModel.BodyModel.Right.ShoulderArm.Mus.deltoideus_lateral_part_*","AnyMechObject"),
  ObjSearchRecursive("Main.HumanModel.BodyModel.Right.ShoulderArm.Mus","deltoideus_lateral_part_*.*", "AnyMechObject")
  );

Kind regards,
Pavel

Hello,

Thank you for your help and very quick answers :slight_smile:

Regards,

Dan

This topic was automatically closed 125 days after the last reply. New replies are no longer allowed.