diff --git a/A_Getting_started_anyscript/index.md b/A_Getting_started_anyscript/index.md index 7d540022..8285ac7c 100644 --- a/A_Getting_started_anyscript/index.md +++ b/A_Getting_started_anyscript/index.md @@ -1,6 +1,7 @@ ::: {rst-class} break ::: +(How_to_write_AnyScript)= # How to write AnyScript This tutorial introduces the AnyScript modeling language, which is used diff --git a/Muscle_modeling/Downloads/MuscleDemo.4.any b/Muscle_modeling/Downloads/MuscleDemo.4.any index 6da2056f..0767102f 100644 --- a/Muscle_modeling/Downloads/MuscleDemo.4.any +++ b/Muscle_modeling/Downloads/MuscleDemo.4.any @@ -15,7 +15,7 @@ Main = { }; // Global reference frame // Define one simple segment -AnySeg Arm = { + AnySeg Arm = { r0 = {0.500000, 0.000000, 0.000000}; Mass = 1.000000; Jii = {0.100000, 1.000000, 1.000000}*0.03; @@ -43,7 +43,7 @@ AnySeg Arm = { DriverPos = {-10*pi/180}; DriverVel = {80*pi/180}; AnyRevoluteJoint &Jnt = .Jnt; - Reaction.Type = {0}; + Reaction.Type = {Off}; }; AnyMuscleModel SimpleModel = { @@ -57,10 +57,10 @@ AnySeg Arm = { AnyRefFrame &Ins = .Arm.M1Insertion; AnyDrawMuscle drw = { - RGB = {1, 0, 0}; + //RGB = {1, 0, 0}; //Opacity = 1; //DrawOnOff = 1; - Bulging = 1; + Bulging = 2; ColorScale = 1; RGBColorScale = {0, 0, 1}; MaxStress = 250000; diff --git a/Muscle_modeling/Downloads/MuscleDemo.5-2.any b/Muscle_modeling/Downloads/MuscleDemo.5-2.any index 9b5ddd72..5fbc077c 100644 --- a/Muscle_modeling/Downloads/MuscleDemo.5-2.any +++ b/Muscle_modeling/Downloads/MuscleDemo.5-2.any @@ -80,7 +80,7 @@ Main = { AnyMuscleModel2ELin Model2 = { F0 = 200; - Lfbar = 0.3; + Lfbar = 0.2; Lt0 = 0.3; Epsilonbar = 0.05; V0 = -0.3; @@ -95,7 +95,7 @@ Main = { AnyRefFrame &Ins = .Arm.M1Insertion; SPLine.StringMesh = 20; AnyDrawMuscle drw = { - Bulging = 0; + Bulging = 2; ColorScale = 1; MaxStress = 250000; }; @@ -109,7 +109,7 @@ Main = { SPLine.StringMesh = 20; SPLine.InitWrapPosVectors = {{-0.2, -0.2, 0},{-0.05,-0.2, 0}}; AnyDrawMuscle drw = { - Bulging = 0; + Bulging = 2; ColorScale = 1; MaxStress = 250000; }; diff --git a/Muscle_modeling/Downloads/MuscleDemo.5.any b/Muscle_modeling/Downloads/MuscleDemo.5.any index 2b2122ce..782ce56c 100644 --- a/Muscle_modeling/Downloads/MuscleDemo.5.any +++ b/Muscle_modeling/Downloads/MuscleDemo.5.any @@ -78,7 +78,7 @@ Main = { AnyRefFrame &Ins = .Arm.M1Insertion; SPLine.StringMesh = 20; AnyDrawMuscle drw = { - Bulging = 4; + Bulging = 2; ColorScale = 1; MaxStress = 250000; }; @@ -92,7 +92,7 @@ Main = { SPLine.StringMesh = 20; SPLine.InitWrapPosVectors = {{-0.2, -0.2, 0},{-0.05,-0.2, 0}}; AnyDrawMuscle drw = { - Bulging = 4; + Bulging = 2; ColorScale = 1; MaxStress = 250000; }; diff --git a/Muscle_modeling/Downloads/MuscleDemo.6.any b/Muscle_modeling/Downloads/MuscleDemo.6.any index f1a15645..a924dadf 100644 --- a/Muscle_modeling/Downloads/MuscleDemo.6.any +++ b/Muscle_modeling/Downloads/MuscleDemo.6.any @@ -102,8 +102,8 @@ Main = { // The study: Operations to be performed on the model AnyBodyStudy ArmStudy = { AnyFolder &Model = .ArmModel; -// InverseDynamics.Criterion.Type = MR_MinMaxStrict; -InverseDynamics.Criterion.Type = MR_Quadratic; + //InverseDynamics.Criterion.Type = MR_MinMaxStrict; + InverseDynamics.Criterion.Type = MR_Quadratic; Gravity = {0.0, -9.81, 0.0}; }; diff --git a/Muscle_modeling/Snippets/lesson1/snip.Muscles.main-1.any b/Muscle_modeling/Snippets/lesson1/snip.Muscles.main-1.any new file mode 100644 index 00000000..30b52582 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson1/snip.Muscles.main-1.any @@ -0,0 +1,49 @@ +//# BEGIN SNIPPET 1 +// This is a very simple model for demonstration of muscle modeling +Main = { + + AnyFolder MyModel = { + + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + AnyDrawRefFrame drw = { + RGB = {1,0,0}; + }; + }; // Global reference frame + + // Define one simple segment + AnySeg Arm = { + r0 = {0.500000, 0.000000, 0.000000}; + Mass = 1.000000; + Jii = {0.100000, 1.000000, 1.000000}*0.03; + AnyRefNode Jnt = { + sRel = {-0.5, 0.0, 0}; + }; + AnyDrawSeg drw = {}; + }; + + // Attach the segment to ground by a revolute joint + AnyRevoluteJoint Jnt = { + AnyRefFrame &ref1 = .GlobalRef; + AnyRefFrame &ref2 = .Arm.Jnt; + Axis = z; + }; + + // Drive the revolute joint at constant velocity + AnyKinEqSimpleDriver Drv = { + DriverPos = {-10*pi/180}; + DriverVel = {40*pi/180}; + AnyRevoluteJoint &Jnt = .Jnt; + Reaction.Type = {Off}; + }; + + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + InverseDynamics.Criterion.Type = MR_MinMaxStrict; + Gravity = {0.0, -9.81, 0.0}; + }; +}; // Main +//# END SNIPPET 1 \ No newline at end of file diff --git a/Muscle_modeling/Snippets/lesson1/snip.Muscles.main-2.any b/Muscle_modeling/Snippets/lesson1/snip.Muscles.main-2.any new file mode 100644 index 00000000..ee1b41b7 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson1/snip.Muscles.main-2.any @@ -0,0 +1,58 @@ +//expect_errors = ["", "Model loading skipped"] + +// This is a very simple model for demonstration of muscle modeling +Main = { + + AnyFolder MyModel = { + + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + AnyDrawRefFrame drw = { + RGB = {1,0,0}; + }; + }; // Global reference frame + + // Define one simple segment + AnySeg Arm = { + r0 = {0.500000, 0.000000, 0.000000}; + Mass = 1.000000; + Jii = {0.100000, 1.000000, 1.000000}*0.03; + AnyRefNode Jnt = { + sRel = {-0.5, 0.0, 0}; + }; + AnyDrawSeg drw = {}; + }; + + // Attach the segment to ground by a revolute joint + AnyRevoluteJoint Jnt = { + AnyRefFrame &ref1 = .GlobalRef; + AnyRefFrame &ref2 = .Arm.Jnt; + Axis = z; + }; + +//# BEGIN SNIPPET 1 +// Drive the revolute joint at constant velocity +AnyKinEqSimpleDriver Drv = { + DriverPos = {-10*pi/180}; + DriverVel = {40*pi/180}; + AnyRevoluteJoint &Jnt = .Jnt; + Reaction.Type = {Off}; +}; + +§AnyMuscleModel = +{ + F0 = 0.0; + //Lf0 = 0.0; + //Vol0 = 0.0; +};§ +//# END SNIPPET 1 + + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + InverseDynamics.Criterion.Type = MR_MinMaxStrict; + Gravity = {0.0, -9.81, 0.0}; + }; +}; // Main diff --git a/Muscle_modeling/Snippets/lesson1/snip.Muscles.main-3.any b/Muscle_modeling/Snippets/lesson1/snip.Muscles.main-3.any new file mode 100644 index 00000000..7727f349 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson1/snip.Muscles.main-3.any @@ -0,0 +1,74 @@ +//expect_errors = ["", "Model loading skipped"] + +// This is a very simple model for demonstration of muscle modeling +Main = { + + AnyFolder MyModel = { + + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + AnyDrawRefFrame drw = { + RGB = {1,0,0}; + }; + }; // Global reference frame + + // Define one simple segment + AnySeg Arm = { + r0 = {0.500000, 0.000000, 0.000000}; + Mass = 1.000000; + Jii = {0.100000, 1.000000, 1.000000}*0.03; + AnyRefNode Jnt = { + sRel = {-0.5, 0.0, 0}; + }; + AnyDrawSeg drw = {}; + }; + + // Attach the segment to ground by a revolute joint + AnyRevoluteJoint Jnt = { + AnyRefFrame &ref1 = .GlobalRef; + AnyRefFrame &ref2 = .Arm.Jnt; + Axis = z; + }; + + // Drive the revolute joint at constant velocity + AnyKinEqSimpleDriver Drv = { + DriverPos = {-10*pi/180}; + DriverVel = {40*pi/180}; + AnyRevoluteJoint &Jnt = .Jnt; + Reaction.Type = {Off}; + }; +//# BEGIN SNIPPET 1 +AnyMuscleModel §SimpleModel§ = { + F0 = §100§; + //Lf0 = 0.0; + //Vol0 = 0.0; +}; +//# END SNIPPET 1 + +//# BEGIN SNIPPET 2 +// End of AnyMuscleModel + +§AnyViaPointMuscle = +{ + //viewForce.Visible = Off; + //MetabModel = Null; + //FatigueModel = Null; + //MuscleModel = Null; + //viewMuscle.Visible = Off; + AnyMuscleModel & = ; + AnyRefFrame & = ; + AnyRefFrame & = ; + //AnyRefFrame & = ; + //AnyRefFrame & = ; You can make any number of AnyRefFrame objects! +};§ +//# END SNIPPET 2 + + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + InverseDynamics.Criterion.Type = MR_MinMaxStrict; + Gravity = {0.0, -9.81, 0.0}; + }; +}; // Main diff --git a/Muscle_modeling/Snippets/lesson1/snip.Muscles.main-4.any b/Muscle_modeling/Snippets/lesson1/snip.Muscles.main-4.any new file mode 100644 index 00000000..140b28b3 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson1/snip.Muscles.main-4.any @@ -0,0 +1,70 @@ +//expect_errors = [" = ; + AnyRefFrame & = ; +}; +//# END SNIPPET 1 + + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + InverseDynamics.Criterion.Type = MR_MinMaxStrict; + Gravity = {0.0, -9.81, 0.0}; + }; +}; // Main diff --git a/Muscle_modeling/Snippets/lesson1/snip.Muscles.main-5.any b/Muscle_modeling/Snippets/lesson1/snip.Muscles.main-5.any new file mode 100644 index 00000000..6562b377 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson1/snip.Muscles.main-5.any @@ -0,0 +1,67 @@ +// This is a very simple model for demonstration of muscle modeling +Main = { + + AnyFolder MyModel = { + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + AnyDrawRefFrame drw = { + RGB = {1,0,0}; + }; + AnyRefNode M1Origin = { + sRel = {0.0, 0.1, 0}; + }; + }; // Global reference frame + + // Define one simple segment + AnySeg Arm = { + r0 = {0.500000, 0.000000, 0.000000}; + Mass = 1.000000; + Jii = {0.100000, 1.000000, 1.000000}*0.03; + AnyRefNode Jnt = { + sRel = {-0.5, 0.0, 0}; + }; + AnyRefNode M1Insertion = { + sRel = {0.0, 0.1, 0}; + }; + AnyDrawSeg drw = {}; + }; + + // Attach the segment to ground by a revolute joint + AnyRevoluteJoint Jnt = { + AnyRefFrame &ref1 = .GlobalRef; + AnyRefFrame &ref2 = .Arm.Jnt; + Axis = z; + }; + + // Drive the revolute joint at constant velocity + AnyKinEqSimpleDriver Drv = { + DriverPos = {-10*pi/180}; + DriverVel = {40*pi/180}; + AnyRevoluteJoint &Jnt = .Jnt; + Reaction.Type = {Off}; + }; + + AnyMuscleModel SimpleModel = { + F0 = 100; + //Lf0 = 0.0; + //Vol0 = 0.0; + }; + +//# BEGIN SNIPPET 1 +AnyMuscleViaPoint Muscle1 = { + AnyMuscleModel &Model = .SimpleModel; + AnyRefFrame &§Orig = .GlobalRef.M1Origin§; + AnyRefFrame &§Ins = .Arm.M1Insertion§; + §AnyDrawMuscle drw = {};§ +}; +//# END SNIPPET 1 + + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + InverseDynamics.Criterion.Type = MR_MinMaxStrict; + Gravity = {0.0, -9.81, 0.0}; + }; +}; // Main diff --git a/Muscle_modeling/Snippets/lesson2/snip.Muscles.main-1.any b/Muscle_modeling/Snippets/lesson2/snip.Muscles.main-1.any new file mode 100644 index 00000000..e111621d --- /dev/null +++ b/Muscle_modeling/Snippets/lesson2/snip.Muscles.main-1.any @@ -0,0 +1,96 @@ +//expect_errors = ["", "Model loading skipped"] + +// This is a very simple model for demonstration of muscle modeling +Main = { + + AnyFolder MyModel = { + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + AnyDrawRefFrame drw = { + RGB = {1,0,0}; + }; + AnyRefNode M1Origin = { + sRel = {0.0, 0.1, 0}; + }; + }; // Global reference frame + + // Define one simple segment + AnySeg Arm = { + r0 = {0.500000, 0.000000, 0.000000}; + Mass = 1.000000; + Jii = {0.100000, 1.000000, 1.000000}*0.03; + AnyRefNode Jnt = { + sRel = {-0.5, 0.0, 0}; + }; + AnyRefNode M1Insertion = { + sRel = {0.0, 0.1, 0}; + }; + AnyDrawSeg drw = {}; + }; + + // Attach the segment to ground by a revolute joint + AnyRevoluteJoint Jnt = { + AnyRefFrame &ref1 = .GlobalRef; + AnyRefFrame &ref2 = .Arm.Jnt; + Axis = z; + }; + + // Drive the revolute joint at constant velocity + AnyKinEqSimpleDriver Drv = { + DriverPos = {-10*pi/180}; + DriverVel = {40*pi/180}; + AnyRevoluteJoint &Jnt = .Jnt; + Reaction.Type = {Off}; + }; + + AnyMuscleModel SimpleModel = { + F0 = 100; + //Lf0 = 0.0; + //Vol0 = 0.0; + }; + +//# BEGIN SNIPPET 1 +AnyMuscleViaPoint Muscle1 = { + AnyMuscleModel &Model = .SimpleModel; + AnyRefFrame &Orig = .GlobalRef.M1Origin; + AnyRefFrame &Ins = .Arm.M1Insertion; + §AnyDrawMuscle = + { + //Visible = On; + //Opacity = 1.0; + //Pickable = On; + //PickableZOrdering = 0; + //RGB = ; + //Transparency = 1.0; + //DrawOnOff = 1.0; + //Bulging = 0.0; + //ColorScale = 0.0; + //RGBColorScale = {0.95703125, 0.78515625, 0.78515625}; + //MaxStress = 250000.0; + //DrawScaleOnOff = Off; + /*DrawScale = + { + EnableCreasing = Off; + CreasingAngle = 0.524; + EnableWireframe = Off; + EnableSmoothing = On; + Param = 0.0; + ParamArray = ; + RGBArray = ; + OpacityArray = ; + };*/ + //AnyStyleDrawMaterial & = ; + //AnyStyleDrawMaterial & = ; You can make any number of AnyStyleDrawMaterial objects! + };§ +}; +//# END SNIPPET 1 + + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + InverseDynamics.Criterion.Type = MR_MinMaxStrict; + Gravity = {0.0, -9.81, 0.0}; + }; +}; // Main diff --git a/Muscle_modeling/Snippets/lesson2/snip.Muscles.main-2.any b/Muscle_modeling/Snippets/lesson2/snip.Muscles.main-2.any new file mode 100644 index 00000000..2affc0e5 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson2/snip.Muscles.main-2.any @@ -0,0 +1,77 @@ +// This is a very simple model for demonstration of muscle modeling +Main = { + + AnyFolder MyModel = { + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + AnyDrawRefFrame drw = { + RGB = {1,0,0}; + }; + AnyRefNode M1Origin = { + sRel = {0.0, 0.1, 0}; + }; + }; // Global reference frame + + // Define one simple segment + AnySeg Arm = { + r0 = {0.500000, 0.000000, 0.000000}; + Mass = 1.000000; + Jii = {0.100000, 1.000000, 1.000000}*0.03; + AnyRefNode Jnt = { + sRel = {-0.5, 0.0, 0}; + }; + AnyRefNode M1Insertion = { + sRel = {0.0, 0.1, 0}; + }; + AnyDrawSeg drw = {}; + }; + + // Attach the segment to ground by a revolute joint + AnyRevoluteJoint Jnt = { + AnyRefFrame &ref1 = .GlobalRef; + AnyRefFrame &ref2 = .Arm.Jnt; + Axis = z; + }; + +//# BEGIN SNIPPET 2 +// Drive the revolute joint at constant velocity +AnyKinEqSimpleDriver Drv = { + DriverPos = {-10*pi/180}; + DriverVel = {§80§*pi/180}; + AnyRevoluteJoint &Jnt = .Jnt; + Reaction.Type = {Off}; +}; +//# END SNIPPET 2 + + AnyMuscleModel SimpleModel = { + F0 = 100; + //Lf0 = 0.0; + //Vol0 = 0.0; + }; + + AnyMuscleViaPoint Muscle1 = { + AnyMuscleModel &Model = .SimpleModel; + AnyRefFrame &Orig = .GlobalRef.M1Origin; + AnyRefFrame &Ins = .Arm.M1Insertion; +//# BEGIN SNIPPET 1 +AnyDrawMuscle drw = { + //RGB = {0.554688, 0.101563, 0.117188}; + //Opacity = 1.000000; + //DrawOnOff = 1.000000; + §Bulging = 1;§ + //ColorScale = 0.000000; + //RGBColorScale = {0.957031, 0.785156, 0.785156}; + //MaxStress = 250000.000000; +}; +//# END SNIPPET 1 + }; + + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + InverseDynamics.Criterion.Type = MR_MinMaxStrict; + Gravity = {0.0, -9.81, 0.0}; + }; +}; // Main diff --git a/Muscle_modeling/Snippets/lesson2/snip.Muscles.main-3.any b/Muscle_modeling/Snippets/lesson2/snip.Muscles.main-3.any new file mode 100644 index 00000000..6aaf4850 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson2/snip.Muscles.main-3.any @@ -0,0 +1,75 @@ +// This is a very simple model for demonstration of muscle modeling +Main = { + + AnyFolder MyModel = { + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + AnyDrawRefFrame drw = { + RGB = {1,0,0}; + }; + AnyRefNode M1Origin = { + sRel = {0.0, 0.1, 0}; + }; + }; // Global reference frame + + // Define one simple segment + AnySeg Arm = { + r0 = {0.500000, 0.000000, 0.000000}; + Mass = 1.000000; + Jii = {0.100000, 1.000000, 1.000000}*0.03; + AnyRefNode Jnt = { + sRel = {-0.5, 0.0, 0}; + }; + AnyRefNode M1Insertion = { + sRel = {0.0, 0.1, 0}; + }; + AnyDrawSeg drw = {}; + }; + + // Attach the segment to ground by a revolute joint + AnyRevoluteJoint Jnt = { + AnyRefFrame &ref1 = .GlobalRef; + AnyRefFrame &ref2 = .Arm.Jnt; + Axis = z; + }; + + // Drive the revolute joint at constant velocity + AnyKinEqSimpleDriver Drv = { + DriverPos = {-10*pi/180}; + DriverVel = {80*pi/180}; + AnyRevoluteJoint &Jnt = .Jnt; + Reaction.Type = {Off}; + }; + + AnyMuscleModel SimpleModel = { + F0 = 100; + //Lf0 = 0.0; + //Vol0 = 0.0; + }; + + AnyMuscleViaPoint Muscle1 = { + AnyMuscleModel &Model = .SimpleModel; + AnyRefFrame &Orig = .GlobalRef.M1Origin; + AnyRefFrame &Ins = .Arm.M1Insertion; +//# BEGIN SNIPPET 1 +AnyDrawMuscle drw = { + §RGB = {1, 0, 0}; //Red§ + //Opacity = 1.000000; + //DrawOnOff = 1.000000; + Bulging = 1; + ColorScale = 1; + §RGBColorScale = {0, 0, 1}; //Blue§ + MaxStress = 2500; +}; +//# END SNIPPET 1 + }; + + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + InverseDynamics.Criterion.Type = MR_MinMaxStrict; + Gravity = {0.0, -9.81, 0.0}; + }; +}; // Main diff --git a/Muscle_modeling/Snippets/lesson3/snip.Muscles.main-1.any b/Muscle_modeling/Snippets/lesson3/snip.Muscles.main-1.any new file mode 100644 index 00000000..622fc7a8 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson3/snip.Muscles.main-1.any @@ -0,0 +1,77 @@ +// This is a very simple model for demonstration of muscle modeling +Main = { + + AnyFolder MyModel = { + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + AnyDrawRefFrame drw = { + RGB = {1,0,0}; + }; + AnyRefNode M1Origin = { + sRel = {0.0, 0.1, 0}; + }; + }; // Global reference frame + + // Define one simple segment +//# BEGIN SNIPPET 2 +AnySeg Arm = { + r0 = {0.500000, 0.000000, 0.000000}; + Mass = 1.000000; + Jii = {0.100000, 1.000000, 1.000000}*0.03; + AnyRefNode Jnt = { + sRel = {-0.5, 0.0, 0}; + }; + AnyRefNode M1Insertion = { + sRel = {§0.3, 0.05§, 0}; + }; + AnyDrawSeg drw = {}; +}; +//# END SNIPPET 2 + + // Attach the segment to ground by a revolute joint + AnyRevoluteJoint Jnt = { + AnyRefFrame &ref1 = .GlobalRef; + AnyRefFrame &ref2 = .Arm.Jnt; + Axis = z; + }; + + // Drive the revolute joint at constant velocity + AnyKinEqSimpleDriver Drv = { + DriverPos = {-10*pi/180}; + DriverVel = {80*pi/180}; + AnyRevoluteJoint &Jnt = .Jnt; + Reaction.Type = {Off}; + }; + + AnyMuscleModel SimpleModel = { + F0 = 100; + //Lf0 = 0.0; + //Vol0 = 0.0; + }; + + AnyMuscleViaPoint Muscle1 = { + AnyMuscleModel &Model = .SimpleModel; + AnyRefFrame &Orig = .GlobalRef.M1Origin; + AnyRefFrame &Ins = .Arm.M1Insertion; +//# BEGIN SNIPPET 1 +AnyDrawMuscle drw = { + //RGB = {1, 0, 0}; //Red + //Opacity = 1.000000; + //DrawOnOff = 1.000000; + Bulging = §2§; + ColorScale = 1; + //RGBColorScale = {0, 0, 1}; //Blue + MaxStress = 2500§00§; +}; +//# END SNIPPET 1 + }; + + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + InverseDynamics.Criterion.Type = MR_MinMaxStrict; + Gravity = {0.0, -9.81, 0.0}; + }; +}; // Main diff --git a/Muscle_modeling/Snippets/lesson3/snip.Muscles.main-2.any b/Muscle_modeling/Snippets/lesson3/snip.Muscles.main-2.any new file mode 100644 index 00000000..775e6cb3 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson3/snip.Muscles.main-2.any @@ -0,0 +1,81 @@ +// This is a very simple model for demonstration of muscle modeling +Main = { + + AnyFolder MyModel = { + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + AnyDrawRefFrame drw = { + RGB = {1,0,0}; + }; + AnyRefNode M1Origin = { + sRel = {0.0, 0.1, 0}; + }; + }; // Global reference frame + + // Define one simple segment +//# BEGIN SNIPPET 1 +AnySeg Arm = { + r0 = {0.500000, 0.000000, 0.000000}; + Mass = 1.000000; + Jii = {0.100000, 1.000000, 1.000000}*0.03; + AnyRefNode Jnt = { + sRel = {-0.5, 0.0, 0}; + }; + AnyRefNode M1Insertion = { + sRel = {0.3, 0.05, 0}; + }; + §AnyRefNode ViaPoint = { + sRel = {0.0, 0.1, 0}; + };§ + AnyDrawSeg drw = {}; +}; +//# END SNIPPET 1 + + // Attach the segment to ground by a revolute joint + AnyRevoluteJoint Jnt = { + AnyRefFrame &ref1 = .GlobalRef; + AnyRefFrame &ref2 = .Arm.Jnt; + Axis = z; + }; + + // Drive the revolute joint at constant velocity + AnyKinEqSimpleDriver Drv = { + DriverPos = {-10*pi/180}; + DriverVel = {80*pi/180}; + AnyRevoluteJoint &Jnt = .Jnt; + Reaction.Type = {Off}; + }; + + AnyMuscleModel SimpleModel = { + F0 = 100; + //Lf0 = 0.0; + //Vol0 = 0.0; + }; + +//# BEGIN SNIPPET 2 +AnyMuscleViaPoint Muscle1 = { + AnyMuscleModel &Model = .SimpleModel; + AnyRefFrame &Orig = .GlobalRef.M1Origin; + §AnyRefFrame &Via = .Arm.ViaPoint;§ + AnyRefFrame &Ins = .Arm.M1Insertion; + AnyDrawMuscle drw = { + //RGB = {1, 0, 0}; //Red + //Opacity = 1.000000; + //DrawOnOff = 1.000000; + Bulging = 2; + ColorScale = 1; + //RGBColorScale = {0, 0, 1}; //Blue + MaxStress = 250000; + }; +}; +//# END SNIPPET 2 + + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + InverseDynamics.Criterion.Type = MR_MinMaxStrict; + Gravity = {0.0, -9.81, 0.0}; + }; +}; // Main diff --git a/Muscle_modeling/Snippets/lesson4/snip.Muscles.main-1.any b/Muscle_modeling/Snippets/lesson4/snip.Muscles.main-1.any new file mode 100644 index 00000000..bd28d4b1 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson4/snip.Muscles.main-1.any @@ -0,0 +1,82 @@ +// This is a very simple model for demonstration of muscle modeling +Main = { + + AnyFolder MyModel = { +//# BEGIN SNIPPET 1 +// Global Reference Frame +AnyFixedRefFrame GlobalRef = { + AnyDrawRefFrame drw = { + RGB = {1,0,0}; + }; + AnyRefNode M1Origin = { + sRel = {0.0, 0.1, 0}; + }; + §AnyRefNode CylCenter = { + sRel = {0, 0, -0.2}; + };§ +}; // Global reference frame +//# END SNIPPET 1 + + // Define one simple segment + AnySeg Arm = { + r0 = {0.500000, 0.000000, 0.000000}; + Mass = 1.000000; + Jii = {0.100000, 1.000000, 1.000000}*0.03; + AnyRefNode Jnt = { + sRel = {-0.5, 0.0, 0}; + }; + AnyRefNode M1Insertion = { + sRel = {0.3, 0.05, 0}; + }; + AnyRefNode ViaPoint = { + sRel = {0.0, 0.1, 0}; + }; + AnyDrawSeg drw = {}; + }; + + // Attach the segment to ground by a revolute joint + AnyRevoluteJoint Jnt = { + AnyRefFrame &ref1 = .GlobalRef; + AnyRefFrame &ref2 = .Arm.Jnt; + Axis = z; + }; + + // Drive the revolute joint at constant velocity + AnyKinEqSimpleDriver Drv = { + DriverPos = {-10*pi/180}; + DriverVel = {80*pi/180}; + AnyRevoluteJoint &Jnt = .Jnt; + Reaction.Type = {Off}; + }; + + AnyMuscleModel SimpleModel = { + F0 = 100; + //Lf0 = 0.0; + //Vol0 = 0.0; + }; + + AnyMuscleViaPoint Muscle1 = { + AnyMuscleModel &Model = .SimpleModel; + AnyRefFrame &Orig = .GlobalRef.M1Origin; + AnyRefFrame &Via = .Arm.ViaPoint; + AnyRefFrame &Ins = .Arm.M1Insertion; + AnyDrawMuscle drw = { + //RGB = {1, 0, 0}; //Red + //Opacity = 1.000000; + //DrawOnOff = 1.000000; + Bulging = 2; + ColorScale = 1; + //RGBColorScale = {0, 0, 1}; //Blue + MaxStress = 250000; + }; + }; + + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + InverseDynamics.Criterion.Type = MR_MinMaxStrict; + Gravity = {0.0, -9.81, 0.0}; + }; +}; // Main diff --git a/Muscle_modeling/Snippets/lesson4/snip.Muscles.main-2.any b/Muscle_modeling/Snippets/lesson4/snip.Muscles.main-2.any new file mode 100644 index 00000000..c7d6881f --- /dev/null +++ b/Muscle_modeling/Snippets/lesson4/snip.Muscles.main-2.any @@ -0,0 +1,90 @@ +// This is a very simple model for demonstration of muscle modeling +Main = { + + AnyFolder MyModel = { +// Global Reference Frame +AnyFixedRefFrame GlobalRef = { + AnyDrawRefFrame drw = { + RGB = {1,0,0}; + }; + AnyRefNode M1Origin = { + sRel = {0.0, 0.1, 0}; + }; +//# BEGIN SNIPPET 1 + AnyRefNode CylCenter = { + sRel = {0, 0, -0.2}; + + §AnySurfCylinder WrapSurf = { + Radius = 0.15; + Length = 0.4; + //CapRatio = 0.1; + //CapRatio2 = 0.1; + AnyDrawParamSurf drw = {}; + };§ + }; +}; // Global reference frame +//# END SNIPPET 1 + + // Define one simple segment + AnySeg Arm = { + r0 = {0.500000, 0.000000, 0.000000}; + Mass = 1.000000; + Jii = {0.100000, 1.000000, 1.000000}*0.03; + AnyRefNode Jnt = { + sRel = {-0.5, 0.0, 0}; + }; + AnyRefNode M1Insertion = { + sRel = {0.3, 0.05, 0}; + }; + AnyRefNode ViaPoint = { + sRel = {0.0, 0.1, 0}; + }; + AnyDrawSeg drw = {}; + }; + + // Attach the segment to ground by a revolute joint + AnyRevoluteJoint Jnt = { + AnyRefFrame &ref1 = .GlobalRef; + AnyRefFrame &ref2 = .Arm.Jnt; + Axis = z; + }; + + // Drive the revolute joint at constant velocity + AnyKinEqSimpleDriver Drv = { + DriverPos = {-10*pi/180}; + DriverVel = {80*pi/180}; + AnyRevoluteJoint &Jnt = .Jnt; + Reaction.Type = {Off}; + }; + + AnyMuscleModel SimpleModel = { + F0 = 100; + //Lf0 = 0.0; + //Vol0 = 0.0; + }; + + AnyMuscleViaPoint Muscle1 = { + AnyMuscleModel &Model = .SimpleModel; + AnyRefFrame &Orig = .GlobalRef.M1Origin; + AnyRefFrame &Via = .Arm.ViaPoint; + AnyRefFrame &Ins = .Arm.M1Insertion; + AnyDrawMuscle drw = { + //RGB = {1, 0, 0}; //Red + //Opacity = 1.000000; + //DrawOnOff = 1.000000; + Bulging = 2; + ColorScale = 1; + //RGBColorScale = {0, 0, 1}; //Blue + MaxStress = 250000; + }; + }; + + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + InverseDynamics.Criterion.Type = MR_MinMaxStrict; + Gravity = {0.0, -9.81, 0.0}; + }; +}; // Main diff --git a/Muscle_modeling/Snippets/lesson4/snip.Muscles.main-3.any b/Muscle_modeling/Snippets/lesson4/snip.Muscles.main-3.any new file mode 100644 index 00000000..90a16ab0 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson4/snip.Muscles.main-3.any @@ -0,0 +1,118 @@ +// This is a very simple model for demonstration of muscle modeling +Main = { + + AnyFolder MyModel = { +//# BEGIN SNIPPET 2 +// Global Reference Frame +AnyFixedRefFrame GlobalRef = { + AnyDrawRefFrame drw = { + RGB = {1,0,0}; + }; + AnyRefNode M1Origin = { + sRel = {0.0, 0.1, 0}; + }; + §AnyRefNode M2Origin = { + sRel = {0.0, 0.15, -0.05}; + };§ +//# END SNIPPET 2 + +//# BEGIN SNIPPET 1 +AnyRefNode CylCenter = { + sRel = {0, 0, -0.2}; + §ARel = RotMat(20*pi/180,y);§ + + AnySurfCylinder WrapSurf = { + Radius = 0.15; + Length = 0.4; + //CapRatio = 0.1; + //CapRatio2 = 0.1; + AnyDrawParamSurf drw = {}; + }; +}; +//# END SNIPPET 1 +}; // Global reference frame + +//# BEGIN SNIPPET 3 +// Define one simple segment +AnySeg Arm = { + r0 = {0.500000, 0.000000, 0.000000}; + Mass = 1.000000; + Jii = {0.100000, 1.000000, 1.000000}*0.03; + AnyRefNode Jnt = { + sRel = {-0.5, 0.0, 0}; + }; + AnyRefNode M1Insertion = { + sRel = {0.3, 0.05, 0}; + }; + §AnyRefNode M2Insertion = { + sRel = {-0.2, 0.05, 0.05}; + };§ +//# END SNIPPET 3 + + AnyRefNode ViaPoint = { + sRel = {0.0, 0.1, 0}; + }; + AnyDrawSeg drw = {}; + }; + + // Attach the segment to ground by a revolute joint + AnyRevoluteJoint Jnt = { + AnyRefFrame &ref1 = .GlobalRef; + AnyRefFrame &ref2 = .Arm.Jnt; + Axis = z; + }; + + // Drive the revolute joint at constant velocity + AnyKinEqSimpleDriver Drv = { + DriverPos = {-10*pi/180}; + DriverVel = {80*pi/180}; + AnyRevoluteJoint &Jnt = .Jnt; + Reaction.Type = {Off}; + }; + + AnyMuscleModel SimpleModel = { + F0 = 100; + //Lf0 = 0.0; + //Vol0 = 0.0; + }; + +//# BEGIN SNIPPET 4 +AnyMuscleViaPoint Muscle1 = { + AnyMuscleModel &Model = .SimpleModel; + AnyRefFrame &Orig = .GlobalRef.M1Origin; + AnyRefFrame &Via = .Arm.ViaPoint; + AnyRefFrame &Ins = .Arm.M1Insertion; + AnyDrawMuscle drw = { + //RGB = {1, 0, 0}; //Red + //Opacity = 1.000000; + //DrawOnOff = 1.000000; + Bulging = 2; + ColorScale = 1; + //RGBColorScale = {0, 0, 1}; //Blue + MaxStress = 250000; + }; +}; + +§AnyMuscleShortestPath Muscle2 = { + AnyMuscleModel &Model = .SimpleModel; + AnyRefFrame &Orig = .GlobalRef.M2Origin; + AnySurface &srf = .GlobalRef.CylCenter.WrapSurf; + AnyRefFrame &Ins = .Arm.M2Insertion; + SPLine.StringMesh = 20; + AnyDrawMuscle drw = { + Bulging = 2; + ColorScale = 1; + MaxStress = 250000; + }; +};§ +//# END SNIPPET 4 + + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + InverseDynamics.Criterion.Type = MR_MinMaxStrict; + Gravity = {0.0, -9.81, 0.0}; + }; +}; // Main diff --git a/Muscle_modeling/Snippets/lesson4/snip.Muscles.main-4.any b/Muscle_modeling/Snippets/lesson4/snip.Muscles.main-4.any new file mode 100644 index 00000000..636aa5d7 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson4/snip.Muscles.main-4.any @@ -0,0 +1,112 @@ +// This is a very simple model for demonstration of muscle modeling +Main = { + + AnyFolder MyModel = { + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + AnyDrawRefFrame drw = { + RGB = {1,0,0}; + }; +//# BEGIN SNIPPET 2 +AnyRefNode M1Origin = { + sRel = {0.0, 0.1§5§, 0}; +}; +//# END SNIPPET 2 + AnyRefNode M2Origin = { + sRel = {0.0, 0.15, -0.05}; + }; + AnyRefNode CylCenter = { + sRel = {0, 0, -0.2}; + ARel = RotMat(20*pi/180,y); + + AnySurfCylinder WrapSurf = { + Radius = 0.15; + Length = 0.4; + //CapRatio = 0.1; + //CapRatio2 = 0.1; + AnyDrawParamSurf drw = {}; + }; + }; + }; // Global reference frame + + // Define one simple segment + AnySeg Arm = { + r0 = {0.500000, 0.000000, 0.000000}; + Mass = 1.000000; + Jii = {0.100000, 1.000000, 1.000000}*0.03; + AnyRefNode Jnt = { + sRel = {-0.5, 0.0, 0}; + }; + AnyRefNode M1Insertion = { + sRel = {0.3, 0.05, 0}; + }; + AnyRefNode M2Insertion = { + sRel = {-0.2, 0.05, 0.05}; + }; + AnyRefNode ViaPoint = { + sRel = {0.0, 0.1, 0}; + }; + AnyDrawSeg drw = {}; + }; + + // Attach the segment to ground by a revolute joint + AnyRevoluteJoint Jnt = { + AnyRefFrame &ref1 = .GlobalRef; + AnyRefFrame &ref2 = .Arm.Jnt; + Axis = z; + }; + + // Drive the revolute joint at constant velocity + AnyKinEqSimpleDriver Drv = { + DriverPos = {-10*pi/180}; + DriverVel = {80*pi/180}; + AnyRevoluteJoint &Jnt = .Jnt; + Reaction.Type = {Off}; + }; + + AnyMuscleModel SimpleModel = { + F0 = 100; + //Lf0 = 0.0; + //Vol0 = 0.0; + }; + +//# BEGIN SNIPPET 1 +§AnyMuscleShortestPath§ Muscle1 = { + AnyMuscleModel &Model = .SimpleModel; + AnyRefFrame &Orig = .GlobalRef.M1Origin; + AnyRefFrame &Via = .Arm.ViaPoint; + §AnySurface &srf = .GlobalRef.CylCenter.WrapSurf;§ + AnyRefFrame &Ins = .Arm.M1Insertion; + §SPLine.StringMesh = 20;§ + AnyDrawMuscle drw = { + Bulging = 2; + ColorScale = 1; + MaxStress = 250000; + }; +}; +//# END SNIPPET 1 + +//# BEGIN SNIPPET 3 +AnyMuscleShortestPath Muscle2 = { + AnyMuscleModel &Model = .SimpleModel; + AnyRefFrame &Orig = .GlobalRef.M2Origin; + AnySurface &srf = .GlobalRef.CylCenter.WrapSurf; + AnyRefFrame &Ins = .Arm.M2Insertion; + SPLine.StringMesh = 20; + §SPLine.InitWrapPosVectors = {{-0.2, -0.2, 0}, {-0.05, -0.2, 0}};§ + AnyDrawMuscle drw = { + Bulging = 2; + ColorScale = 1; + MaxStress = 250000; + }; +}; +//# END SNIPPET 3 + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + InverseDynamics.Criterion.Type = MR_MinMaxStrict; + Gravity = {0.0, -9.81, 0.0}; + }; +}; // Main diff --git a/Muscle_modeling/Snippets/lesson5/snip.Muscles.main-1.any b/Muscle_modeling/Snippets/lesson5/snip.Muscles.main-1.any new file mode 100644 index 00000000..ddbe4f89 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson5/snip.Muscles.main-1.any @@ -0,0 +1,120 @@ +//expect_errors = ["", "Model loading skipped"] + +// This is a very simple model for demonstration of muscle modeling +Main = { + + AnyFolder MyModel = { + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + AnyDrawRefFrame drw = { + RGB = {1,0,0}; + }; + AnyRefNode M1Origin = { + sRel = {0.0, 0.15, 0}; + }; + AnyRefNode M2Origin = { + sRel = {0.0, 0.15, -0.05}; + }; + AnyRefNode CylCenter = { + sRel = {0, 0, -0.2}; + ARel = RotMat(20*pi/180,y); + + AnySurfCylinder WrapSurf = { + Radius = 0.15; + Length = 0.4; + //CapRatio = 0.1; + //CapRatio2 = 0.1; + AnyDrawParamSurf drw = {}; + }; + }; + }; // Global reference frame + + // Define one simple segment + AnySeg Arm = { + r0 = {0.500000, 0.000000, 0.000000}; + Mass = 1.000000; + Jii = {0.100000, 1.000000, 1.000000}*0.03; + AnyRefNode Jnt = { + sRel = {-0.5, 0.0, 0}; + }; + AnyRefNode M1Insertion = { + sRel = {0.3, 0.05, 0}; + }; + AnyRefNode M2Insertion = { + sRel = {-0.2, 0.05, 0.05}; + }; + AnyRefNode ViaPoint = { + sRel = {0.0, 0.1, 0}; + }; + AnyDrawSeg drw = {}; + }; + + // Attach the segment to ground by a revolute joint + AnyRevoluteJoint Jnt = { + AnyRefFrame &ref1 = .GlobalRef; + AnyRefFrame &ref2 = .Arm.Jnt; + Axis = z; + }; + + // Drive the revolute joint at constant velocity + AnyKinEqSimpleDriver Drv = { + DriverPos = {-10*pi/180}; + DriverVel = {80*pi/180}; + AnyRevoluteJoint &Jnt = .Jnt; + Reaction.Type = {Off}; + }; + +//# BEGIN SNIPPET 1 +AnyMuscleModel SimpleModel = { + F0 = 100; + //Lf0 = 0.0; + //Vol0 = 0.0; +}; + +§AnyMuscleModel2ELin = +{ + F0 = 0.0; + //Lf0 = 0.0; + //Vol0 = 0.0; + Lt0 = 0.0; + //Epsilon0 = 0.05; + V0 = 0.0; +};§ +//# END SNIPPET 1 + + AnyMuscleShortestPath Muscle1 = { + AnyMuscleModel &Model = .SimpleModel; + AnyRefFrame &Orig = .GlobalRef.M1Origin; + AnyRefFrame &Via = .Arm.ViaPoint; + AnySurface &srf = .GlobalRef.CylCenter.WrapSurf; + AnyRefFrame &Ins = .Arm.M1Insertion; + SPLine.StringMesh = 20; + AnyDrawMuscle drw = { + Bulging = 2; + ColorScale = 1; + MaxStress = 250000; + }; + }; + + AnyMuscleShortestPath Muscle2 = { + AnyMuscleModel &Model = .SimpleModel; + AnyRefFrame &Orig = .GlobalRef.M2Origin; + AnySurface &srf = .GlobalRef.CylCenter.WrapSurf; + AnyRefFrame &Ins = .Arm.M2Insertion; + SPLine.StringMesh = 20; + SPLine.InitWrapPosVectors = {{-0.2, -0.2, 0}, {-0.05, -0.2, 0}}; + AnyDrawMuscle drw = { + Bulging = 2; + ColorScale = 1; + MaxStress = 250000; + }; + }; + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + InverseDynamics.Criterion.Type = MR_MinMaxStrict; + Gravity = {0.0, -9.81, 0.0}; + }; +}; // Main diff --git a/Muscle_modeling/Snippets/lesson5/snip.Muscles.main-2.any b/Muscle_modeling/Snippets/lesson5/snip.Muscles.main-2.any new file mode 100644 index 00000000..bb7fa64b --- /dev/null +++ b/Muscle_modeling/Snippets/lesson5/snip.Muscles.main-2.any @@ -0,0 +1,118 @@ +// This is a very simple model for demonstration of muscle modeling +Main = { + + AnyFolder MyModel = { + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + AnyDrawRefFrame drw = { + RGB = {1,0,0}; + }; + AnyRefNode M1Origin = { + sRel = {0.0, 0.15, 0}; + }; + AnyRefNode M2Origin = { + sRel = {0.0, 0.15, -0.05}; + }; + AnyRefNode CylCenter = { + sRel = {0, 0, -0.2}; + ARel = RotMat(20*pi/180,y); + + AnySurfCylinder WrapSurf = { + Radius = 0.15; + Length = 0.4; + //CapRatio = 0.1; + //CapRatio2 = 0.1; + AnyDrawParamSurf drw = {}; + }; + }; + }; // Global reference frame + + // Define one simple segment + AnySeg Arm = { + r0 = {0.500000, 0.000000, 0.000000}; + Mass = 1.000000; + Jii = {0.100000, 1.000000, 1.000000}*0.03; + AnyRefNode Jnt = { + sRel = {-0.5, 0.0, 0}; + }; + AnyRefNode M1Insertion = { + sRel = {0.3, 0.05, 0}; + }; + AnyRefNode M2Insertion = { + sRel = {-0.2, 0.05, 0.05}; + }; + AnyRefNode ViaPoint = { + sRel = {0.0, 0.1, 0}; + }; + AnyDrawSeg drw = {}; + }; + + // Attach the segment to ground by a revolute joint + AnyRevoluteJoint Jnt = { + AnyRefFrame &ref1 = .GlobalRef; + AnyRefFrame &ref2 = .Arm.Jnt; + Axis = z; + }; + + // Drive the revolute joint at constant velocity + AnyKinEqSimpleDriver Drv = { + DriverPos = {-10*pi/180}; + DriverVel = {80*pi/180}; + AnyRevoluteJoint &Jnt = .Jnt; + Reaction.Type = {Off}; + }; + + AnyMuscleModel SimpleModel = { + F0 = 100; + //Lf0 = 0.0; + //Vol0 = 0.0; + }; + +//# BEGIN SNIPPET 1 +AnyMuscleModel2ELin §Model2§ = { + F0 = §200§; + Lf0 = §0.2§; + Lt0 = §0.5§; + Epsilon0 = §0.05§; + V0 = §-8.0§; + }; +//# END SNIPPET 1 + +//# BEGIN SNIPPET 2 +AnyMuscleShortestPath Muscle1 = { + AnyMuscleModel &Model = .§Model2§; + AnyRefFrame &Orig = .GlobalRef.M1Origin; + AnyRefFrame &Via = .Arm.ViaPoint; + AnySurface &srf = .GlobalRef.CylCenter.WrapSurf; + AnyRefFrame &Ins = .Arm.M1Insertion; + SPLine.StringMesh = 20; + AnyDrawMuscle drw = { + Bulging = 2; + ColorScale = 1; + MaxStress = 250000; + }; +}; +//# END SNIPPET 2 + + AnyMuscleShortestPath Muscle2 = { + AnyMuscleModel &Model = .SimpleModel; + AnyRefFrame &Orig = .GlobalRef.M2Origin; + AnySurface &srf = .GlobalRef.CylCenter.WrapSurf; + AnyRefFrame &Ins = .Arm.M2Insertion; + SPLine.StringMesh = 20; + SPLine.InitWrapPosVectors = {{-0.2, -0.2, 0}, {-0.05, -0.2, 0}}; + AnyDrawMuscle drw = { + Bulging = 2; + ColorScale = 1; + MaxStress = 250000; + }; + }; + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + InverseDynamics.Criterion.Type = MR_MinMaxStrict; + Gravity = {0.0, -9.81, 0.0}; + }; +}; // Main diff --git a/Muscle_modeling/Snippets/lesson5/snip.Muscles.main-3.any b/Muscle_modeling/Snippets/lesson5/snip.Muscles.main-3.any new file mode 100644 index 00000000..6fe955c5 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson5/snip.Muscles.main-3.any @@ -0,0 +1,125 @@ +// This is a very simple model for demonstration of muscle modeling +Main = { + + AnyFolder MyModel = { + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + AnyDrawRefFrame drw = { + RGB = {1,0,0}; + }; + AnyRefNode M1Origin = { + sRel = {0.0, 0.15, 0}; + }; + AnyRefNode M2Origin = { + sRel = {0.0, 0.15, -0.05}; + }; + AnyRefNode CylCenter = { + sRel = {0, 0, -0.2}; + ARel = RotMat(20*pi/180,y); + + AnySurfCylinder WrapSurf = { + Radius = 0.15; + Length = 0.4; + //CapRatio = 0.1; + //CapRatio2 = 0.1; + AnyDrawParamSurf drw = {}; + }; + }; + }; // Global reference frame + +//# BEGIN SNIPPET 2 +// Define one simple segment +AnySeg Arm = { + r0 = {0.500000, 0.000000, 0.000000}; + Mass = 1.000000; + Jii = {0.100000, 1.000000, 1.000000}*0.03; + AnyRefNode Jnt = { + sRel = {-0.5, 0.0, 0}; + }; + AnyRefNode M1Insertion = { + sRel = {0.3, 0.05, 0}; + }; + AnyRefNode M2Insertion = { + sRel = {-0.2, 0.05, 0.05}; + }; + AnyRefNode ViaPoint = { + sRel = {0.0, 0.1, 0}; + }; + §AnyRefNode Hand = { + sRel = {0.5, 0.0, 0}; + };§ + AnyDrawSeg drw = {}; +}; +§AnyForce3D Load = { + AnyRefNode &Attachment = .Arm.Hand; + F = {-100, -100, 0}; +};§ +//# END SNIPPET 2 + + // Attach the segment to ground by a revolute joint + AnyRevoluteJoint Jnt = { + AnyRefFrame &ref1 = .GlobalRef; + AnyRefFrame &ref2 = .Arm.Jnt; + Axis = z; + }; + + // Drive the revolute joint at constant velocity + AnyKinEqSimpleDriver Drv = { + DriverPos = {-10*pi/180}; + DriverVel = {80*pi/180}; + AnyRevoluteJoint &Jnt = .Jnt; + Reaction.Type = {Off}; + }; + + AnyMuscleModel SimpleModel = { + F0 = 100; + //Lf0 = 0.0; + //Vol0 = 0.0; + }; + +//# BEGIN SNIPPET 1 +AnyMuscleModel2ELin Model2 = { + F0 = 200; + Lf0 = 0.2; + Lt0 = 0.5; + Epsilon0 = 0.05; + V0 = §-0.3§; +}; +//# END SNIPPET 1 + + AnyMuscleShortestPath Muscle1 = { + AnyMuscleModel &Model = .Model2; + AnyRefFrame &Orig = .GlobalRef.M1Origin; + AnyRefFrame &Via = .Arm.ViaPoint; + AnySurface &srf = .GlobalRef.CylCenter.WrapSurf; + AnyRefFrame &Ins = .Arm.M1Insertion; + SPLine.StringMesh = 20; + AnyDrawMuscle drw = { + Bulging = 2; + ColorScale = 1; + MaxStress = 250000; + }; + }; + + AnyMuscleShortestPath Muscle2 = { + AnyMuscleModel &Model = .SimpleModel; + AnyRefFrame &Orig = .GlobalRef.M2Origin; + AnySurface &srf = .GlobalRef.CylCenter.WrapSurf; + AnyRefFrame &Ins = .Arm.M2Insertion; + SPLine.StringMesh = 20; + SPLine.InitWrapPosVectors = {{-0.2, -0.2, 0}, {-0.05, -0.2, 0}}; + AnyDrawMuscle drw = { + Bulging = 2; + ColorScale = 1; + MaxStress = 250000; + }; + }; + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + InverseDynamics.Criterion.Type = MR_MinMaxStrict; + Gravity = {0.0, -9.81, 0.0}; + }; +}; // Main diff --git a/Muscle_modeling/Snippets/lesson5/snip.Muscles.main-4.any b/Muscle_modeling/Snippets/lesson5/snip.Muscles.main-4.any new file mode 100644 index 00000000..09970012 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson5/snip.Muscles.main-4.any @@ -0,0 +1,143 @@ +// This is a very simple model for demonstration of muscle modeling +Main = { + + AnyFolder MyModel = { + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + AnyDrawRefFrame drw = { + RGB = {1,0,0}; + }; + AnyRefNode M1Origin = { + sRel = {0.0, 0.15, 0}; + }; + AnyRefNode M2Origin = { + sRel = {0.0, 0.15, -0.05}; + }; + AnyRefNode CylCenter = { + sRel = {0, 0, -0.2}; + ARel = RotMat(20*pi/180,y); + + AnySurfCylinder WrapSurf = { + Radius = 0.15; + Length = 0.4; + //CapRatio = 0.1; + //CapRatio2 = 0.1; + AnyDrawParamSurf drw = {}; + }; + }; + }; // Global reference frame + + // Define one simple segment + AnySeg Arm = { + r0 = {0.500000, 0.000000, 0.000000}; + Mass = 1.000000; + Jii = {0.100000, 1.000000, 1.000000}*0.03; + AnyRefNode Jnt = { + sRel = {-0.5, 0.0, 0}; + }; + AnyRefNode M1Insertion = { + sRel = {0.3, 0.05, 0}; + }; + AnyRefNode M2Insertion = { + sRel = {-0.2, 0.05, 0.05}; + }; + AnyRefNode ViaPoint = { + sRel = {0.0, 0.1, 0}; + }; + AnyRefNode Hand = { + sRel = {0.5, 0.0, 0}; + }; + AnyDrawSeg drw = {}; + }; +//# BEGIN SNIPPET 3 +§/*§ +AnyForce3D Load = { + AnyRefNode &Attachment = .Arm.Hand; + F = {-100, -100, 0}; +}; +§*/§ +//# END SNIPPET 3 + + // Attach the segment to ground by a revolute joint + AnyRevoluteJoint Jnt = { + AnyRefFrame &ref1 = .GlobalRef; + AnyRefFrame &ref2 = .Arm.Jnt; + Axis = z; + }; + + // Drive the revolute joint at constant velocity + AnyKinEqSimpleDriver Drv = { + DriverPos = {-10*pi/180}; + DriverVel = {80*pi/180}; + AnyRevoluteJoint &Jnt = .Jnt; + Reaction.Type = {Off}; + }; + + AnyMuscleModel SimpleModel = { + F0 = 100; + //Lf0 = 0.0; + //Vol0 = 0.0; + }; + + AnyMuscleModel2ELin Model2 = { + F0 = 200; + Lf0 = 0.2; + Lt0 = 0.3; + Epsilon0 = 0.05; + V0 = -0.3; + }; + +//# BEGIN SNIPPET 1 +AnyMuscleModel3E §Model3§ = { + F0 = §100§; + Lf0 = §0.3§; + Gamma0 = §30*pi/180§; + Epsilon0 = §0.05§; + Lt0 = §0.5§; + Fcfast = §0.4§; + §Jt = 3.0§; + §Jpe = 3.0§; + §K1 = 2§; + §K2 = 8§; + §PEFactor = 5§; +}; +//# END SNIPPET 1 + + AnyMuscleShortestPath Muscle1 = { + AnyMuscleModel &Model = .Model2; + AnyRefFrame &Orig = .GlobalRef.M1Origin; + AnyRefFrame &Via = .Arm.ViaPoint; + AnySurface &srf = .GlobalRef.CylCenter.WrapSurf; + AnyRefFrame &Ins = .Arm.M1Insertion; + SPLine.StringMesh = 20; + AnyDrawMuscle drw = { + Bulging = 2; + ColorScale = 1; + MaxStress = 250000; + }; + }; + +//# BEGIN SNIPPET 2 +AnyMuscleShortestPath Muscle2 = { + AnyMuscleModel &Model = .§Model3§; + AnyRefFrame &Orig = .GlobalRef.M2Origin; + AnySurface &srf = .GlobalRef.CylCenter.WrapSurf; + AnyRefFrame &Ins = .Arm.M2Insertion; + SPLine.StringMesh = 20; + SPLine.InitWrapPosVectors = {{-0.2, -0.2, 0}, {-0.05, -0.2, 0}}; + AnyDrawMuscle drw = { + Bulging = 2; + ColorScale = 1; + MaxStress = 250000; + }; +}; +//# END SNIPPET 2 + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + InverseDynamics.Criterion.Type = MR_MinMaxStrict; + Gravity = {0.0, -9.81, 0.0}; + }; +}; // Main diff --git a/Muscle_modeling/Snippets/lesson6/snip.Muscles.main-1.any b/Muscle_modeling/Snippets/lesson6/snip.Muscles.main-1.any new file mode 100644 index 00000000..2421a6f8 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson6/snip.Muscles.main-1.any @@ -0,0 +1,125 @@ +//expect_errors = ["", "Model loading skipped"] + +// Demo example for general muscles. + +Main = { + + // The actual body model goes in this folder + AnyFolder ArmModel = { + + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + + AnyRefNode Shoulder = { + sRel = {0,0,0}; + }; + }; // Global reference frame + + // Segments + AnyFolder Segs = { + + AnySeg UpperArm = { + r0 = {0,-0.15,0}; + Axes0 = {{0,1,0},{-1,0,0},{0,0,1}}; + Mass = 2.0; + Jii = {0.002,0.005,0.005}; + AnyDrawSeg DrwSeg = {}; + AnyRefNode ShoulderNode = { + sRel = {-0.2,0,0}; + }; + AnyRefNode ElbowNode = { + sRel = {0.2,0,0}; + }; + }; // UpperArm + + AnySeg LowerArm = { + r0 = {0.25,-0.3,0}; + Mass = 2.0; + Jii = {0.002,0.005,0.005}; + AnyRefNode ElbowNode = { + sRel = {-0.2,0,0}; + }; + AnyRefNode HandNode = { + sRel = {0.2,0,0}; + }; + AnyRefNode PalmNode = { + sRel = {0.27,0,0}; + ARel = {{0,0,1},{0,1,0},{-1,0,0}}; + }; + AnyDrawSeg DrwSeg = {}; + }; // LowerArm + + }; // Segs folder + + AnyFolder Jnts = { + + //--------------------------------- + AnyRevoluteJoint Shoulder = { + Axis = z; + AnyRefNode &GroundNode = ..GlobalRef.Shoulder; + AnyRefNode &UpperArmNode = ..Segs.UpperArm.ShoulderNode; + }; // Shoulder joint + + AnyRevoluteJoint Elbow = { + Axis = z; + AnyRefNode &UpperArmNode = ..Segs.UpperArm.ElbowNode; + AnyRefNode &LowerArmNode = ..Segs.LowerArm.ElbowNode; + }; // Elbow joint + + }; // Jnts folder + +//# BEGIN SNIPPET 1 +AnyFolder Drivers = { + + //--------------------------------- + AnyKinEqSimpleDriver ShoulderMotion = { + AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; + DriverPos = {-1.7}; + DriverVel = {0.4}; + Reaction.Type = {Off}; + }; // Shoulder driver + + //--------------------------------- + AnyKinEqSimpleDriver ElbowMotion = { + AnyRevoluteJoint &Jnt = ..Jnts.Elbow; + DriverPos = {1.5}; + DriverVel = {0.7}; + Reaction.Type = {Off}; + }; // Elbow driver +}; // Driver folder + +§AnyMuscleGeneric = +{ + //viewForce.Visible = Off; + //MetabModel = Null; + //FatigueModel = Null; + //MuscleModel = Null; + //Type = NonPositive; + AnyMuscleModel & = ; + AnyKinMeasure & = ; +};§ +//# END SNIPPET 1 + + AnyFolder Loads = { + + //--------------------------------- + AnyForce3D Dumbbell = { + AnyRefNode &PalmNode = ..Segs.LowerArm.PalmNode; + F = {0,-100,0}; // Force in Newton + }; + }; // Loads folder + + // Todo. Add the model elements such as + // segments, joints, and muscles here. + + }; // ArmModel + + // The study: Operations to be performed on the model + AnyBodyStudy ArmStudy = { + AnyFolder &Model = .ArmModel; + //InverseDynamics.Criterion.Type = MR_MinMaxStrict; + InverseDynamics.Criterion.Type = MR_Quadratic; + Gravity = {0.0, -9.81, 0.0}; + }; + +}; // Main \ No newline at end of file diff --git a/Muscle_modeling/Snippets/lesson6/snip.Muscles.main-2.any b/Muscle_modeling/Snippets/lesson6/snip.Muscles.main-2.any new file mode 100644 index 00000000..20cb3ca9 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson6/snip.Muscles.main-2.any @@ -0,0 +1,131 @@ +//expect_errors = ["", "Model loading skipped"] + +// Demo example for general muscles. + +Main = { + + // The actual body model goes in this folder + AnyFolder ArmModel = { + + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + + AnyRefNode Shoulder = { + sRel = {0,0,0}; + }; + }; // Global reference frame + + // Segments + AnyFolder Segs = { + + AnySeg UpperArm = { + r0 = {0,-0.15,0}; + Axes0 = {{0,1,0},{-1,0,0},{0,0,1}}; + Mass = 2.0; + Jii = {0.002,0.005,0.005}; + AnyDrawSeg DrwSeg = {}; + AnyRefNode ShoulderNode = { + sRel = {-0.2,0,0}; + }; + AnyRefNode ElbowNode = { + sRel = {0.2,0,0}; + }; + }; // UpperArm + + AnySeg LowerArm = { + r0 = {0.25,-0.3,0}; + Mass = 2.0; + Jii = {0.002,0.005,0.005}; + AnyRefNode ElbowNode = { + sRel = {-0.2,0,0}; + }; + AnyRefNode HandNode = { + sRel = {0.2,0,0}; + }; + AnyRefNode PalmNode = { + sRel = {0.27,0,0}; + ARel = {{0,0,1},{0,1,0},{-1,0,0}}; + }; + AnyDrawSeg DrwSeg = {}; + }; // LowerArm + + }; // Segs folder + + AnyFolder Jnts = { + + //--------------------------------- + AnyRevoluteJoint Shoulder = { + Axis = z; + AnyRefNode &GroundNode = ..GlobalRef.Shoulder; + AnyRefNode &UpperArmNode = ..Segs.UpperArm.ShoulderNode; + }; // Shoulder joint + + AnyRevoluteJoint Elbow = { + Axis = z; + AnyRefNode &UpperArmNode = ..Segs.UpperArm.ElbowNode; + AnyRefNode &LowerArmNode = ..Segs.LowerArm.ElbowNode; + }; // Elbow joint + + }; // Jnts folder + + AnyFolder Drivers = { + + //--------------------------------- + AnyKinEqSimpleDriver ShoulderMotion = { + AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; + DriverPos = {-1.7}; + DriverVel = {0.4}; + Reaction.Type = {Off}; + }; // Shoulder driver + + //--------------------------------- + AnyKinEqSimpleDriver ElbowMotion = { + AnyRevoluteJoint &Jnt = ..Jnts.Elbow; + DriverPos = {1.5}; + DriverVel = {0.7}; + Reaction.Type = {Off}; + }; // Elbow driver + }; // Driver folder + +//# BEGIN SNIPPET 1 +§AnyMuscleModel = { + F0 = 0; + //Lf0 = 0; + //Vol0 = 0; + };§ + +AnyMuscleGeneric = +{ + //viewForce.Visible = Off; + //MetabModel = Null; + //FatigueModel = Null; + //MuscleModel = Null; + //Type = NonPositive; + AnyMuscleModel & = ; + AnyKinMeasure & = ; +}; +//# END SNIPPET 1 + + AnyFolder Loads = { + + //--------------------------------- + AnyForce3D Dumbbell = { + AnyRefNode &PalmNode = ..Segs.LowerArm.PalmNode; + F = {0,-100,0}; // Force in Newton + }; + }; // Loads folder + + // Todo. Add the model elements such as + // segments, joints, and muscles here. + + }; // ArmModel + + // The study: Operations to be performed on the model + AnyBodyStudy ArmStudy = { + AnyFolder &Model = .ArmModel; + //InverseDynamics.Criterion.Type = MR_MinMaxStrict; + InverseDynamics.Criterion.Type = MR_Quadratic; + Gravity = {0.0, -9.81, 0.0}; + }; + +}; // Main \ No newline at end of file diff --git a/Muscle_modeling/Snippets/lesson6/snip.Muscles.main-3.any b/Muscle_modeling/Snippets/lesson6/snip.Muscles.main-3.any new file mode 100644 index 00000000..c2d68791 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson6/snip.Muscles.main-3.any @@ -0,0 +1,132 @@ +// Demo example for general muscles. + +Main = { + + // The actual body model goes in this folder + AnyFolder ArmModel = { + + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + + AnyRefNode Shoulder = { + sRel = {0,0,0}; + }; + }; // Global reference frame + + // Segments + AnyFolder Segs = { + + AnySeg UpperArm = { + r0 = {0,-0.15,0}; + Axes0 = {{0,1,0},{-1,0,0},{0,0,1}}; + Mass = 2.0; + Jii = {0.002,0.005,0.005}; + AnyDrawSeg DrwSeg = {}; + AnyRefNode ShoulderNode = { + sRel = {-0.2,0,0}; + }; + AnyRefNode ElbowNode = { + sRel = {0.2,0,0}; + }; + }; // UpperArm + + AnySeg LowerArm = { + r0 = {0.25,-0.3,0}; + Mass = 2.0; + Jii = {0.002,0.005,0.005}; + AnyRefNode ElbowNode = { + sRel = {-0.2,0,0}; + }; + AnyRefNode HandNode = { + sRel = {0.2,0,0}; + }; + AnyRefNode PalmNode = { + sRel = {0.27,0,0}; + ARel = {{0,0,1},{0,1,0},{-1,0,0}}; + }; + AnyDrawSeg DrwSeg = {}; + }; // LowerArm + + }; // Segs folder + + AnyFolder Jnts = { + + //--------------------------------- + AnyRevoluteJoint Shoulder = { + Axis = z; + AnyRefNode &GroundNode = ..GlobalRef.Shoulder; + AnyRefNode &UpperArmNode = ..Segs.UpperArm.ShoulderNode; + }; // Shoulder joint + + AnyRevoluteJoint Elbow = { + Axis = z; + AnyRefNode &UpperArmNode = ..Segs.UpperArm.ElbowNode; + AnyRefNode &LowerArmNode = ..Segs.LowerArm.ElbowNode; + }; // Elbow joint + + }; // Jnts folder + + AnyFolder Drivers = { + + //--------------------------------- + AnyKinEqSimpleDriver ShoulderMotion = { + AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; + DriverPos = {-1.7}; + DriverVel = {0.4}; + Reaction.Type = {Off}; + }; // Shoulder driver + + //--------------------------------- + AnyKinEqSimpleDriver ElbowMotion = { + AnyRevoluteJoint &Jnt = ..Jnts.Elbow; + DriverPos = {1.5}; + DriverVel = {0.7}; + Reaction.Type = {Off}; + }; // Elbow driver + }; // Driver folder + +AnyMuscleModel MusModel = { + F0 = 100.0; +}; + +//# BEGIN SNIPPET 1 +AnyMuscleGeneric ShoulderTorque = +{ + //viewForce.Visible = Off; + //Type = NonPositive; + AnyMuscleModel &Model = .MusModel; + AnyKinMeasure &Angle = .Jnts.Shoulder; +}; + +§AnyMuscleGeneric ElbowTorque = +{ + //viewForce.Visible = Off; + //Type = NonPositive; + AnyMuscleModel &Model = .MusModel; + AnyKinMeasure &Angle = .Jnts.Elbow; +};§ +//# END SNIPPET 1 + + AnyFolder Loads = { + + //--------------------------------- + AnyForce3D Dumbbell = { + AnyRefNode &PalmNode = ..Segs.LowerArm.PalmNode; + F = {0,-100,0}; // Force in Newton + }; + }; // Loads folder + + // Todo. Add the model elements such as + // segments, joints, and muscles here. + + }; // ArmModel + + // The study: Operations to be performed on the model + AnyBodyStudy ArmStudy = { + AnyFolder &Model = .ArmModel; + //InverseDynamics.Criterion.Type = MR_MinMaxStrict; + InverseDynamics.Criterion.Type = MR_Quadratic; + Gravity = {0.0, -9.81, 0.0}; + }; + +}; // Main \ No newline at end of file diff --git a/Muscle_modeling/Snippets/lesson6/snip.Muscles.main-4.any b/Muscle_modeling/Snippets/lesson6/snip.Muscles.main-4.any new file mode 100644 index 00000000..a5244859 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson6/snip.Muscles.main-4.any @@ -0,0 +1,150 @@ +// Demo example for general muscles. + +Main = { + + // The actual body model goes in this folder + AnyFolder ArmModel = { + + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + + AnyRefNode Shoulder = { + sRel = {0,0,0}; + }; + }; // Global reference frame + + // Segments + AnyFolder Segs = { + + AnySeg UpperArm = { + r0 = {0,-0.15,0}; + Axes0 = {{0,1,0},{-1,0,0},{0,0,1}}; + Mass = 2.0; + Jii = {0.002,0.005,0.005}; + AnyDrawSeg DrwSeg = {}; + AnyRefNode ShoulderNode = { + sRel = {-0.2,0,0}; + }; + AnyRefNode ElbowNode = { + sRel = {0.2,0,0}; + }; + }; // UpperArm + + AnySeg LowerArm = { + r0 = {0.25,-0.3,0}; + Mass = 2.0; + Jii = {0.002,0.005,0.005}; + AnyRefNode ElbowNode = { + sRel = {-0.2,0,0}; + }; + AnyRefNode HandNode = { + sRel = {0.2,0,0}; + }; + AnyRefNode PalmNode = { + sRel = {0.27,0,0}; + ARel = {{0,0,1},{0,1,0},{-1,0,0}}; + }; + AnyDrawSeg DrwSeg = {}; + }; // LowerArm + + }; // Segs folder + +AnyFolder Jnts = { + + //--------------------------------- + AnyRevoluteJoint Shoulder = { + Axis = z; + AnyRefNode &GroundNode = ..GlobalRef.Shoulder; + AnyRefNode &UpperArmNode = ..Segs.UpperArm.ShoulderNode; + }; // Shoulder joint + + AnyRevoluteJoint Elbow = { + Axis = z; + AnyRefNode &UpperArmNode = ..Segs.UpperArm.ElbowNode; + AnyRefNode &LowerArmNode = ..Segs.LowerArm.ElbowNode; + }; // Elbow joint +//# BEGIN SNIPPET 2 +}; // END of Jnts folder + +§AnyKinLinear HandPos = { + AnyRefFrame &ref1 = .GlobalRef.Shoulder; + AnyRefFrame &ref2 = .Segs.LowerArm.PalmNode; +};§ + +AnyFolder Drivers = { + §AnyKinEqSimpleDriver HandDriver = { + AnyKinLinear &Measure = ..HandPos; + MeasureOrganizer = {0,1}; + DriverPos = {0.45, -0.6}; + DriverVel = {0, 0.5}; + Reaction.Type = {Off, Off}; + }; + + /*§ + + //--------------------------------- + AnyKinEqSimpleDriver ShoulderMotion = { + AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; + DriverPos = {-1.7}; + DriverVel = {0.4}; + Reaction.Type = {Off}; + }; // Shoulder driver + + //--------------------------------- + AnyKinEqSimpleDriver ElbowMotion = { + AnyRevoluteJoint &Jnt = ..Jnts.Elbow; + DriverPos = {1.5}; + DriverVel = {0.7}; + Reaction.Type = {Off}; + }; // Elbow driver + + §*/§ + +}; // Driver folder +//# END SNIPPET 2 + + AnyMuscleModel MusModel = { + F0 = 100.0; + }; + +//# BEGIN SNIPPET 1 +AnyMuscleGeneric ShoulderTorque = +{ + //viewForce.Visible = Off; + §Type = NonNegative;§ + AnyMuscleModel &Model = .MusModel; + AnyKinMeasure &Angle = .Jnts.Shoulder; +}; + +AnyMuscleGeneric ElbowTorque = +{ + //viewForce.Visible = Off; + §Type = NonNegative;§ + AnyMuscleModel &Model = .MusModel; + AnyKinMeasure &Angle = .Jnts.Elbow; +}; +//# END SNIPPET 1 + + AnyFolder Loads = { + + //--------------------------------- + AnyForce3D Dumbbell = { + AnyRefNode &PalmNode = ..Segs.LowerArm.PalmNode; + F = {0,-100,0}; // Force in Newton + }; + }; // Loads folder + + // Todo. Add the model elements such as + // segments, joints, and muscles here. + + }; // ArmModel + + // The study: Operations to be performed on the model + AnyBodyStudy ArmStudy = { + AnyFolder &Model = .ArmModel; + //InverseDynamics.Criterion.Type = MR_MinMaxStrict; + InverseDynamics.Criterion.Type = MR_Quadratic; + Gravity = {0.0, -9.81, 0.0}; + }; + +}; // Main \ No newline at end of file diff --git a/Muscle_modeling/Snippets/lesson6/snip.Muscles.main-5.any b/Muscle_modeling/Snippets/lesson6/snip.Muscles.main-5.any new file mode 100644 index 00000000..1c301a92 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson6/snip.Muscles.main-5.any @@ -0,0 +1,158 @@ +// Demo example for general muscles. + +Main = { + + // The actual body model goes in this folder + AnyFolder ArmModel = { + + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + + AnyRefNode Shoulder = { + sRel = {0,0,0}; + }; + }; // Global reference frame + + // Segments + AnyFolder Segs = { + + AnySeg UpperArm = { + r0 = {0,-0.15,0}; + Axes0 = {{0,1,0},{-1,0,0},{0,0,1}}; + Mass = 2.0; + Jii = {0.002,0.005,0.005}; + AnyDrawSeg DrwSeg = {}; + AnyRefNode ShoulderNode = { + sRel = {-0.2,0,0}; + }; + AnyRefNode ElbowNode = { + sRel = {0.2,0,0}; + }; + }; // UpperArm + + AnySeg LowerArm = { + r0 = {0.25,-0.3,0}; + Mass = 2.0; + Jii = {0.002,0.005,0.005}; + AnyRefNode ElbowNode = { + sRel = {-0.2,0,0}; + }; + AnyRefNode HandNode = { + sRel = {0.2,0,0}; + }; + AnyRefNode PalmNode = { + sRel = {0.27,0,0}; + ARel = {{0,0,1},{0,1,0},{-1,0,0}}; + }; + AnyDrawSeg DrwSeg = {}; + }; // LowerArm + + }; // Segs folder + + AnyFolder Jnts = { + + //--------------------------------- + AnyRevoluteJoint Shoulder = { + Axis = z; + AnyRefNode &GroundNode = ..GlobalRef.Shoulder; + AnyRefNode &UpperArmNode = ..Segs.UpperArm.ShoulderNode; + }; // Shoulder joint + + AnyRevoluteJoint Elbow = { + Axis = z; + AnyRefNode &UpperArmNode = ..Segs.UpperArm.ElbowNode; + AnyRefNode &LowerArmNode = ..Segs.LowerArm.ElbowNode; + }; // Elbow joint + }; // END of Jnts folder + +AnyKinLinear HandPos = { + AnyRefFrame &ref1 = .GlobalRef.Shoulder; + AnyRefFrame &ref2 = .Segs.LowerArm.PalmNode; +}; + + AnyFolder Drivers = { + AnyKinEqSimpleDriver HandDriver = { + AnyKinLinear &Measure = ..HandPos; + MeasureOrganizer = {0,1}; + DriverPos = {0.45, -0.6}; + DriverVel = {0, 0.5}; + Reaction.Type = {Off, Off}; + }; + + /* + + //--------------------------------- + AnyKinEqSimpleDriver ShoulderMotion = { + AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; + DriverPos = {-1.7}; + DriverVel = {0.4}; + Reaction.Type = {Off}; + }; // Shoulder driver + + //--------------------------------- + AnyKinEqSimpleDriver ElbowMotion = { + AnyRevoluteJoint &Jnt = ..Jnts.Elbow; + DriverPos = {1.5}; + DriverVel = {0.7}; + Reaction.Type = {Off}; + }; // Elbow driver + + */ + +//# BEGIN SNIPPET 1 +}; // END of Driver folder + +§AnyRecruitedActuator WallReaction = { + Type = NonPositive; + Volume = 1e-6; // Ignore this value. Only used in special volume weighted recruitement + Strength = 10000; + AnyKinMeasureOrg Org = { + AnyKinMeasure &wall = ..HandPos; + MeasureOrganizer = {0}; + }; +};§ +//# END SNIPPET 1 + + AnyMuscleModel MusModel = { + F0 = 100.0; + }; + + AnyMuscleGeneric ShoulderTorque = + { + //viewForce.Visible = Off; + Type = NonNegative; + AnyMuscleModel &Model = .MusModel; + AnyKinMeasure &Angle = .Jnts.Shoulder; + }; + + AnyMuscleGeneric ElbowTorque = + { + //viewForce.Visible = Off; + Type = NonNegative; + AnyMuscleModel &Model = .MusModel; + AnyKinMeasure &Angle = .Jnts.Elbow; + }; + + AnyFolder Loads = { + + //--------------------------------- + AnyForce3D Dumbbell = { + AnyRefNode &PalmNode = ..Segs.LowerArm.PalmNode; + F = {0,-100,0}; // Force in Newton + }; + }; // Loads folder + + // Todo. Add the model elements such as + // segments, joints, and muscles here. + + }; // ArmModel + + // The study: Operations to be performed on the model + AnyBodyStudy ArmStudy = { + AnyFolder &Model = .ArmModel; + //InverseDynamics.Criterion.Type = MR_MinMaxStrict; + InverseDynamics.Criterion.Type = MR_Quadratic; + Gravity = {0.0, -9.81, 0.0}; + }; + +}; // Main \ No newline at end of file diff --git a/Muscle_modeling/Snippets/lesson6/snip.Muscles.main-6.any b/Muscle_modeling/Snippets/lesson6/snip.Muscles.main-6.any new file mode 100644 index 00000000..22563272 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson6/snip.Muscles.main-6.any @@ -0,0 +1,157 @@ +// Demo example for general muscles. + +Main = { + + // The actual body model goes in this folder + AnyFolder ArmModel = { + + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + + AnyRefNode Shoulder = { + sRel = {0,0,0}; + }; + }; // Global reference frame + + // Segments + AnyFolder Segs = { + + AnySeg UpperArm = { + r0 = {0,-0.15,0}; + Axes0 = {{0,1,0},{-1,0,0},{0,0,1}}; + Mass = 2.0; + Jii = {0.002,0.005,0.005}; + AnyDrawSeg DrwSeg = {}; + AnyRefNode ShoulderNode = { + sRel = {-0.2,0,0}; + }; + AnyRefNode ElbowNode = { + sRel = {0.2,0,0}; + }; + }; // UpperArm + + AnySeg LowerArm = { + r0 = {0.25,-0.3,0}; + Mass = 2.0; + Jii = {0.002,0.005,0.005}; + AnyRefNode ElbowNode = { + sRel = {-0.2,0,0}; + }; + AnyRefNode HandNode = { + sRel = {0.2,0,0}; + }; + AnyRefNode PalmNode = { + sRel = {0.27,0,0}; + ARel = {{0,0,1},{0,1,0},{-1,0,0}}; + }; + AnyDrawSeg DrwSeg = {}; + }; // LowerArm + + }; // Segs folder + + AnyFolder Jnts = { + + //--------------------------------- + AnyRevoluteJoint Shoulder = { + Axis = z; + AnyRefNode &GroundNode = ..GlobalRef.Shoulder; + AnyRefNode &UpperArmNode = ..Segs.UpperArm.ShoulderNode; + }; // Shoulder joint + + AnyRevoluteJoint Elbow = { + Axis = z; + AnyRefNode &UpperArmNode = ..Segs.UpperArm.ElbowNode; + AnyRefNode &LowerArmNode = ..Segs.LowerArm.ElbowNode; + }; // Elbow joint + }; // END of Jnts folder + +AnyKinLinear HandPos = { + AnyRefFrame &ref1 = .GlobalRef.Shoulder; + AnyRefFrame &ref2 = .Segs.LowerArm.PalmNode; +}; + + AnyFolder Drivers = { + AnyKinEqSimpleDriver HandDriver = { + AnyKinLinear &Measure = ..HandPos; + MeasureOrganizer = {0,1}; + DriverPos = {0.45, -0.6}; + DriverVel = {0, 0.5}; + Reaction.Type = {Off, Off}; + }; + + /* + + //--------------------------------- + AnyKinEqSimpleDriver ShoulderMotion = { + AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; + DriverPos = {-1.7}; + DriverVel = {0.4}; + Reaction.Type = {Off}; + }; // Shoulder driver + + //--------------------------------- + AnyKinEqSimpleDriver ElbowMotion = { + AnyRevoluteJoint &Jnt = ..Jnts.Elbow; + DriverPos = {1.5}; + DriverVel = {0.7}; + Reaction.Type = {Off}; + }; // Elbow driver + + */ + }; // END of Driver folder + +//# BEGIN SNIPPET 1 +AnyRecruitedActuator WallReaction = { + Type = §NonNegative§; + Volume = 1e-6; // Ignore this value. Only used in special volume weighted recruitement + Strength = 10000; + AnyKinMeasureOrg Org = { + AnyKinMeasure &wall = ..HandPos; + MeasureOrganizer = {0}; + }; +}; +//# END SNIPPET 1 + + AnyMuscleModel MusModel = { + F0 = 100.0; + }; + + AnyMuscleGeneric ShoulderTorque = + { + //viewForce.Visible = Off; + Type = NonNegative; + AnyMuscleModel &Model = .MusModel; + AnyKinMeasure &Angle = .Jnts.Shoulder; + }; + + AnyMuscleGeneric ElbowTorque = + { + //viewForce.Visible = Off; + Type = NonNegative; + AnyMuscleModel &Model = .MusModel; + AnyKinMeasure &Angle = .Jnts.Elbow; + }; + + AnyFolder Loads = { + + //--------------------------------- + AnyForce3D Dumbbell = { + AnyRefNode &PalmNode = ..Segs.LowerArm.PalmNode; + F = {0,-100,0}; // Force in Newton + }; + }; // Loads folder + + // Todo. Add the model elements such as + // segments, joints, and muscles here. + + }; // ArmModel + + // The study: Operations to be performed on the model + AnyBodyStudy ArmStudy = { + AnyFolder &Model = .ArmModel; + //InverseDynamics.Criterion.Type = MR_MinMaxStrict; + InverseDynamics.Criterion.Type = MR_Quadratic; + Gravity = {0.0, -9.81, 0.0}; + }; + +}; // Main \ No newline at end of file diff --git a/Muscle_modeling/Snippets/lesson7/snip.Ligaments.main-1.any b/Muscle_modeling/Snippets/lesson7/snip.Ligaments.main-1.any new file mode 100644 index 00000000..657e2785 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson7/snip.Ligaments.main-1.any @@ -0,0 +1,69 @@ +// This model demonstrates the properties of the polynomial +// ligament model, AnyLigamentModelPol + +Main = { + + AnyFolder LigModel = { + + // Global Reference Frame + AnyFixedRefFrame Ground = { + AnyRefNode OriNode = { + sRel = {0.0,0.5,0}; + AnyDrawNode drw = {}; + }; + AnyDrawRefFrame drw = {}; + }; // Global reference frame + + // The one and only segment - an arm joined to ground + AnySeg Arm = { + Mass = 0.0; + Jii = {0,0,0}; + AnyRefNode JointNode = { sRel = {-5,0,0}; }; + AnyRefNode ViaNode = { sRel = {-4.5,0.5,0}; }; + AnyRefNode InsNode = { sRel = {-4.0,0.0,0}; }; + AnyDrawSeg drw = { RGB = {0,0,1}; }; + }; + + AnyRevoluteJoint Joint = { + AnyFixedRefFrame &Ground = Main.LigModel.Ground; + AnyRefNode &ArmNode = .Arm.JointNode; + }; + + // Definition of the ligament and its model + AnyLigamentViaPoint Lig = { + AnyRefNode &Ori = .Ground.OriNode; + AnyRefNode &Via = .Arm.ViaNode; + AnyRefNode &Ins = .Arm.InsNode; + AnyLigamentModelPol &Model = .LigModel; + AnyDrawPLine drw = { + Thickness = 0.05; + RGB = {1,0,0}; + }; + }; + +//# BEGIN SNIPPET 1 +AnyLigamentModelPol LigModel = { + L0 = 1.30; // Slack length + eps1 = 0.2; // Strain where F1 is valid + F1 = 1000; // Force in the ligament at strain eps1 + §a0 = 0.0;§ +}; // LigModel +//# END SNIPPET 1 + + }; + + // The study: Operations to be performed on the model + AnyBodyStudy LigStudy = { + AnyFolder &Model = .LigModel; + + // We include the driver directly in the study to be able to + // exclude it from a calibration study + AnyKinEqSimpleDriver Movement = { + DriverPos = {0.0}; + DriverVel = {-pi/2}; + AnyRevoluteJoint &Jnt = Main.LigModel.Joint; + }; + InverseDynamics.Criterion.Type = MR_MinMaxStrict; + Gravity = {0.0, -9.81, 0.0}; + }; +}; // Main \ No newline at end of file diff --git a/Muscle_modeling/Snippets/lesson7/snip.Ligaments.main-2.any b/Muscle_modeling/Snippets/lesson7/snip.Ligaments.main-2.any new file mode 100644 index 00000000..b86095f4 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson7/snip.Ligaments.main-2.any @@ -0,0 +1,70 @@ +// This model demonstrates the properties of the polynomial +// ligament model, AnyLigamentModelPol + +Main = { + + AnyFolder LigModel = { + + // Global Reference Frame + AnyFixedRefFrame Ground = { + AnyRefNode OriNode = { + sRel = {0.0,0.5,0}; + AnyDrawNode drw = {}; + }; + AnyDrawRefFrame drw = {}; + }; // Global reference frame + + // The one and only segment - an arm joined to ground + AnySeg Arm = { + Mass = 0.0; + Jii = {0,0,0}; + AnyRefNode JointNode = { sRel = {-5,0,0}; }; + AnyRefNode ViaNode = { sRel = {-4.5,0.5,0}; }; + AnyRefNode InsNode = { sRel = {-4.0,0.0,0}; }; + AnyDrawSeg drw = { RGB = {0,0,1}; }; + }; + + AnyRevoluteJoint Joint = { + AnyFixedRefFrame &Ground = Main.LigModel.Ground; + AnyRefNode &ArmNode = .Arm.JointNode; + }; + + // Definition of the ligament and its model + AnyLigamentViaPoint Lig = { + AnyRefNode &Ori = .Ground.OriNode; + AnyRefNode &Via = .Arm.ViaNode; + AnyRefNode &Ins = .Arm.InsNode; + AnyLigamentModelPol &Model = .LigModel; + AnyDrawPLine drw = { + Thickness = 0.05; + RGB = {1,0,0}; + }; + }; + +//# BEGIN SNIPPET 1 +AnyLigamentModelPol LigModel = { + L0 = 1.30; // Slack length + eps1 = 0.2; // Strain where F1 is valid + F1 = 1000; // Force in the ligament at strain eps1 + a0 = 0.5; + §a1 = 0.0;§ +}; // LigModel +//# END SNIPPET 1 + + }; + + // The study: Operations to be performed on the model + AnyBodyStudy LigStudy = { + AnyFolder &Model = .LigModel; + + // We include the driver directly in the study to be able to + // exclude it from a calibration study + AnyKinEqSimpleDriver Movement = { + DriverPos = {0.0}; + DriverVel = {-pi/2}; + AnyRevoluteJoint &Jnt = Main.LigModel.Joint; + }; + InverseDynamics.Criterion.Type = MR_MinMaxStrict; + Gravity = {0.0, -9.81, 0.0}; + }; +}; // Main \ No newline at end of file diff --git a/Muscle_modeling/Snippets/lesson7/snip.Ligaments.main-3.any b/Muscle_modeling/Snippets/lesson7/snip.Ligaments.main-3.any new file mode 100644 index 00000000..41075d56 --- /dev/null +++ b/Muscle_modeling/Snippets/lesson7/snip.Ligaments.main-3.any @@ -0,0 +1,85 @@ +// This model demonstrates the properties of the polynomial +// ligament model, AnyLigamentModelPol + +Main = { + + AnyFolder LigModel = { + + // Global Reference Frame + AnyFixedRefFrame Ground = { + AnyRefNode OriNode = { + sRel = {0.0,0.5,0}; + AnyDrawNode drw = {}; + }; + AnyDrawRefFrame drw = {}; + }; // Global reference frame + + // The one and only segment - an arm joined to ground + AnySeg Arm = { + Mass = 0.0; + Jii = {0,0,0}; + AnyRefNode JointNode = { sRel = {-5,0,0}; }; + AnyRefNode ViaNode = { sRel = {-4.5,0.5,0}; }; + AnyRefNode InsNode = { sRel = {-4.0,0.0,0}; }; + AnyDrawSeg drw = { RGB = {0,0,1}; }; + }; + + AnyRevoluteJoint Joint = { + AnyFixedRefFrame &Ground = Main.LigModel.Ground; + AnyRefNode &ArmNode = .Arm.JointNode; + }; + + // Definition of the ligament and its model + AnyLigamentViaPoint Lig = { + AnyRefNode &Ori = .Ground.OriNode; + AnyRefNode &Via = .Arm.ViaNode; + AnyRefNode &Ins = .Arm.InsNode; + AnyLigamentModelPol &Model = .LigModel; + AnyDrawPLine drw = { + Thickness = 0.05; + RGB = {1,0,0}; + }; + }; + +//# BEGIN SNIPPET 1 +AnyLigamentModelPol LigModel = { + L0 = 1.30; // Slack length + eps1 = 0.2; // Strain where F1 is valid + F1 = 1000; // Force in the ligament at strain eps1 + a0 = 0.5; + a1 = 1.0; + §LinRegionOnOff = Off;§ +}; // LigModel +//# END SNIPPET 1 + + }; + + // The study: Operations to be performed on the model + AnyBodyStudy LigStudy = { + AnyFolder &Model = .LigModel; + + // We include the driver directly in the study to be able to + // exclude it from a calibration study + AnyKinEqSimpleDriver Movement = { + DriverPos = {0.0}; + DriverVel = {-pi/2}; + AnyRevoluteJoint &Jnt = Main.LigModel.Joint; + }; + InverseDynamics.Criterion.Type = MR_MinMaxStrict; + Gravity = {0.0, -9.81, 0.0}; + }; + +//# BEGIN SNIPPET 2 +§AnyBodyCalibrationStudy LigCali = { + AnyFolder &Model = .LigModel; + nStep = 1; + + // This driver puts the joint into the calibration position + AnyKinEqSimpleDriver Position = { + DriverPos = {-pi/4}; + DriverVel = {0.0}; + AnyRevoluteJoint &Jnt = Main.LigModel.Joint; + }; +};§ + //# END SNIPPET 2 +}; // Main \ No newline at end of file diff --git a/Muscle_modeling/_static/lesson5/image10.png b/Muscle_modeling/_static/lesson5/image10.png index 9520d89c..d452dec2 100644 Binary files a/Muscle_modeling/_static/lesson5/image10.png and b/Muscle_modeling/_static/lesson5/image10.png differ diff --git a/Muscle_modeling/_static/lesson5/image11.png b/Muscle_modeling/_static/lesson5/image11.png index 30cb4439..20a4a79e 100644 Binary files a/Muscle_modeling/_static/lesson5/image11.png and b/Muscle_modeling/_static/lesson5/image11.png differ diff --git a/Muscle_modeling/_static/lesson5/image2.png b/Muscle_modeling/_static/lesson5/image2.png index e7be0e01..275346e4 100644 Binary files a/Muscle_modeling/_static/lesson5/image2.png and b/Muscle_modeling/_static/lesson5/image2.png differ diff --git a/Muscle_modeling/_static/lesson5/image3.png b/Muscle_modeling/_static/lesson5/image3.png index dc81cb7f..8c29a776 100644 Binary files a/Muscle_modeling/_static/lesson5/image3.png and b/Muscle_modeling/_static/lesson5/image3.png differ diff --git a/Muscle_modeling/_static/lesson5/image33.png b/Muscle_modeling/_static/lesson5/image33.png index 58eb6c5f..b5d16593 100644 Binary files a/Muscle_modeling/_static/lesson5/image33.png and b/Muscle_modeling/_static/lesson5/image33.png differ diff --git a/Muscle_modeling/_static/lesson5/image34.png b/Muscle_modeling/_static/lesson5/image34.png index ebfbae7b..2f4994f1 100644 Binary files a/Muscle_modeling/_static/lesson5/image34.png and b/Muscle_modeling/_static/lesson5/image34.png differ diff --git a/Muscle_modeling/_static/lesson5/image5.png b/Muscle_modeling/_static/lesson5/image5.png index ca1a5d16..01e29aaa 100644 Binary files a/Muscle_modeling/_static/lesson5/image5.png and b/Muscle_modeling/_static/lesson5/image5.png differ diff --git a/Muscle_modeling/_static/lesson5/image6.png b/Muscle_modeling/_static/lesson5/image6.png index 8be75f6f..b72dcb00 100644 Binary files a/Muscle_modeling/_static/lesson5/image6.png and b/Muscle_modeling/_static/lesson5/image6.png differ diff --git a/Muscle_modeling/_static/lesson5/image7.png b/Muscle_modeling/_static/lesson5/image7.png index 2f220176..f762fc21 100644 Binary files a/Muscle_modeling/_static/lesson5/image7.png and b/Muscle_modeling/_static/lesson5/image7.png differ diff --git a/Muscle_modeling/_static/lesson5/image8.png b/Muscle_modeling/_static/lesson5/image8.png index aba596a6..09a7a8bc 100644 Binary files a/Muscle_modeling/_static/lesson5/image8.png and b/Muscle_modeling/_static/lesson5/image8.png differ diff --git a/Muscle_modeling/_static/lesson7/image9.png b/Muscle_modeling/_static/lesson7/image9.png index d021416f..52353323 100644 Binary files a/Muscle_modeling/_static/lesson7/image9.png and b/Muscle_modeling/_static/lesson7/image9.png differ diff --git a/Muscle_modeling/lesson1.md b/Muscle_modeling/lesson1.md index a6e892fa..9e84a394 100644 --- a/Muscle_modeling/lesson1.md +++ b/Muscle_modeling/lesson1.md @@ -20,54 +20,10 @@ enable us to examine the properties of muscles. Here's an extremely simple {download}`one-degree-of-freedom model `. -```AnyScriptDoc -// This is a very simple model for demonstration of muscle modeling -Main = { - -   AnyFolder MyModel = { - -     // Global Reference Frame -     AnyFixedRefFrame GlobalRef = { -       AnyDrawRefFrame drw = { -         RGB = {1,0,0}; -       }; -     };  // Global reference frame - -     // Define one simple segment -     AnySeg Arm = { -       r0 = {0.500000, 0.000000, 0.000000}; -       Mass = 1.000000; -       Jii = {0.100000, 1.000000, 1.000000}*0.035; -       AnyRefNode Jnt = { -         sRel = {-0.5, 0.0, 0}; -       }; -       AnyDrawSeg drw = {}; -     }; - -     // Attach the segment to ground by a revolute joint -     AnyRevoluteJoint Jnt = { -       AnyRefFrame &ref1 = .GlobalRef; -       AnyRefFrame &ref2 = .Arm.Jnt; -       Axis = z; -     }; - -     // Drive the revolute joint at constant velocity -     AnyKinEqSimpleDriver Drv = { -       DriverPos = {-10*pi/180}; -       DriverVel = {40*pi/180}; -       AnyRevoluteJoint &Jnt = .Jnt; -       Reaction.Type = {0}; -     }; - -   }; // MyModel - -   // The study: Operations to be performed on the model -   AnyBodyStudy MyStudy = { -     AnyFolder &Model = .MyModel; -     InverseDynamics.Criterion.Type = MR_MinMaxStrict; -     Gravity = {0.0, -9.81, 0.0}; -   }; - };  // Main +```{literalinclude} Snippets/lesson1/snip.Muscles.main-1.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` When you load the model, open a model view window, and run the @@ -85,7 +41,8 @@ frame. If you try to run the InverseDynamicAnalysis, you will get an error: ```none -ERROR(OBJ1) : C:/../MuscleDemo.Ini.any(43) : MyStudy.InverseDynamics : No solution found : There are fewer unknown forces (muscles and reactions) than dynamic equations. +NOTICE(OBJ1): MuscleDemo.Ini.any(43): MyStudy.InverseDynamics: No muscles or other recruited actuators in the model. +ERROR(OBJ1): MuscleDemo.Ini.any(43): MyStudy.InverseDynamics: No solution found: There are fewer unknown forces (muscles and reactions) than dynamic equations. ``` This is because the model does not have any muscles to balance the arm @@ -109,24 +66,14 @@ Notice that this class has three derived classes. These are more advanced muscle models, and we shall get to those later. However for the time being, place the cursor in the Editor View on an empty line just after the end brace of the driver definition, right-click the -AnyMuscleModel class in the tree, and select "Insert Class -Template".This causes an instance of the AnyMuscleModel class to be +`AnyMuscleModel` class in the tree, and select "Insert Class +Template".This causes an instance of the `AnyMuscleModel` class to be inserted into the model (new code marked with red): -```AnyScriptDoc -// Drive the revolute joint at constant velocity -AnyKinEqSimpleDriver Drv = { -  DriverPos = {-10*pi/180}; -  DriverVel = {40*pi/180}; -  AnyRevoluteJoint &Jnt = .Jnt; -  Reaction.Type = {0}; -}; - -§AnyMuscleModel = { -  F0 = 0.0; - //Lf0 = 0.0; - //Vol0 = 0.0; -};§ +```{literalinclude} Snippets/lesson1/snip.Muscles.main-2.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` ```{raw} html @@ -150,7 +97,7 @@ this simplicity, it is used with considerable success for many studies where the movements or postures are within the normal range of the involved joints, and where contraction velocities are small. -There are two optional parameters for this model. Vol0 can be used in muscle +There are two optional parameters for this model. `Vol0` can be used in muscle recruitment to form a muscle volume weighted sum of muscle activations; see e.g. [^cite_happee_van_der_hel_1995]. `Lf0` can be tuned in a calibration study; then using `Vol0`, modified physiological cross sectional area (`PCSA`) of the @@ -160,12 +107,10 @@ used afterwards to modify the value for `F0`. Let us perform the necessary modifications to make the model useful to us: -```AnyScriptDoc -AnyMuscleModel §SimpleModel§ = { -  F0 = §100§; - //Lf0 = 0.0; - //Vol0 = 0.0; -}; +```{literalinclude} Snippets/lesson1/snip.Muscles.main-3.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` The next step is to define a muscle that can use the model. This is @@ -181,7 +126,7 @@ also provides force. These two properties are reflected in the way the muscle classes are derived from a kinematic measure as well as force classes. -The simplest type of muscle is the AnyViaPoint muscle. It spans the path +The simplest type of muscle is the `AnyViaPoint` muscle. It spans the path between origin and insertion by passing through any number of via points on the way. The via points are fixed to segments or to the global reference frame. It is a simple and convenient way to define many of the @@ -189,40 +134,22 @@ simpler muscles of the body, primarily those in the extremities and the spine. You can, in fact, make a pretty decent model of the legs entirely with via point muscles. -Place the cursor right after the end brace of the musle model, in the Class -List scroll down to find AnyMuscleViaPoint and insert an instance of it: - -```AnyScriptDoc -AnyMuscleModel SimpleModel = { -   F0 = 100; - //Lf0 = 0; - //Vol0 = 0; -}; - -§AnyViaPointMuscle = -{ - //viewForce.Visible = Off; - //MetabModel = Null; - //FatigueModel = Null; - //MuscleModel = Null; - //viewMuscle.Visible = Off; - AnyRefFrame & = ; - AnyRefFrame & = ; - //AnyRefFrame & = ; - //AnyRefFrame & = ; You can make any number of AnyRefFrame objects! - AnyMuscleModel & = ; -};§ +Place the cursor right after the end brace of the muscle model, open the *Class* +*List*, scroll down to find `AnyMuscleViaPoint` and insert an instance of it: + +```{literalinclude} Snippets/lesson1/snip.Muscles.main-3.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 2 +:end-before: //# END SNIPPET 2 ``` Let us start by filling out what we can and removing what we have no use for: -```AnyScriptDoc -AnyMuscleViaPoint §Muscle1§ = { -  AnyMuscleModel &§Model§ = §.SimpleModel§; -  AnyRefFrame & = ; -  AnyRefFrame & = ; -}; +```{literalinclude} Snippets/lesson1/snip.Muscles.main-4.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` Notice that we have left only two points in the list of via points. This @@ -232,44 +159,21 @@ definition of the muscle we must define the necessary points on the model to attach the muscle to. We shall define the origin on the global reference frame and the insertion on the segment: -```AnyScriptDoc -// Global Reference Frame -AnyFixedRefFrame GlobalRef = { -  AnyDrawRefFrame drw = { -    RGB = {1,0,0}; -  }; -  §AnyRefNode M1Origin = { -    sRel = {0.0, 0.1, 0}; -  };§ -};  // Global reference frame - -// Define one simple segment -AnySeg Arm = { -  r = {0.500000, 0.000000, 0.000000}; -  Mass = 1.000000; -  Jii = {0.100000, 1.000000, 1.000000}*0.1; -  AnyRefNode Jnt = { -    sRel = {-0.5, 0.0, 0}; -  }; - § AnyRefNode M1Insertion = { -    sRel = {0.0, 0.1, 0}; -  };§ -  AnyDrawSeg drw = {}; -}; +```{literalinclude} Snippets/lesson1/snip.Muscles.main-4.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 2 +:end-before: //# END SNIPPET 2 ``` - With these two points, we can complete the definition of the muscle: +With these two points, we can complete the definition of the muscle: -```AnyScriptDoc -AnyMuscleViaPoint Muscle1 = { -    AnyMuscleModel &Model = .SimpleModel; -    AnyRefFrame &§Orig = .GlobalRef.M1Origin§; -    AnyRefFrame &§Ins = .Arm.M1Insertion§; -    §AnyDrawMuscle drw = {};§ -  }; +```{literalinclude} Snippets/lesson1/snip.Muscles.main-5.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` -Notice that we have added an AnyDrawMuscle object to the definition. +Notice that we have added an `AnyDrawMuscle` object to the definition. Like other classes in AnyScript, muscles are not drawn in the Model View window unless you specifically ask for it. When you load the model and run the SetInitialConditions study you will get the following picture @@ -284,14 +188,15 @@ run the SetInitialConditions study you will get the following picture Notice that the muscle is now able to balance the gravity, and we are able to run the InverseDynamicAnalysis. If you try it out and -subsequently open a chart view, you are able to plot the muscle force: +subsequently open a chart view, you are able to plot the muscle force under +`Main.MyStudy.Output.Model.Muscle1.Fm`: ```{image} _static/lesson1/image5.png :alt: muscle force :align: center ``` -The muscle force is the item Fm in the list of properties you can plot +The muscle force is the item `Fm` in the list of properties you can plot for a muscle. As you can see, lots of other properties are available, but if you try to plot them you will find that many of them are zero. This is because they are not relevant for this very simple type of diff --git a/Muscle_modeling/lesson2.md b/Muscle_modeling/lesson2.md index c8817248..3b5bd335 100644 --- a/Muscle_modeling/lesson2.md +++ b/Muscle_modeling/lesson2.md @@ -4,7 +4,7 @@ # Lesson 2: Controlling Muscle Drawing Muscles can be displayed in a variety of fashions depending on the -specifications in the AnyDrawMuscle object. Let us take a look at its +specifications in the `AnyDrawMuscle` object. Let us take a look at its definition again: ```AnyScriptDoc @@ -21,46 +21,19 @@ value leading to the following display of the muscle: ``` Let us play around with the settings a bit. An easy way to display all the -settings is to discard our manually defined AnyDrawMuscle object and insert a -template from the class list instead. Find the AnyDrawMuscle object in the Class -List, erase the previous AnyDrawMuscle, right-click the AnyDrawMuscle in the -tree view, and insert an instance: - -```AnyScriptDoc -AnyMuscleViaPoint Muscle1 = { -  AnyMuscleModel &Model = .SimpleModel; -  AnyRefFrame &Orig = .GlobalRef.M1Origin; -  AnyRefFrame &Ins = .Arm.M1Insertion; - §AnyDrawMuscle drw = { - //Visible = On; - //Opacity = 1.0; - //Pickable = On; - //RGB = {0.5546875, 0.1015625, 0.1171875}; - //Transparency = 1.0; - //DrawOnOff = 1.0; - //Bulging = 0.0; - //ColorScale = 0.0; - //RGBColorScale = {0.95703125, 0.78515625, 0.78515625}; - //MaxStress = 250000.0; - //DrawScaleOnOff = Off; - /*DrawScale = - { - EnableCreasing = Off; - CreasingAngle = 0.524; - EnableWireframe = Off; - EnableSmoothing = On; - Param = 0.0; - ParamArray = ; - RGBArray = ; - OpacityArray = ; - };*/ - //AnyStyleDrawMaterial & = ; You can make any number of these objects! - };§ -}; +settings is to discard our manually defined `AnyDrawMuscle` object and insert a +template from the *Class List* instead. First erase the previous +`AnyDrawMuscle`, find the `AnyDrawMuscle` object in the Class List, right-click +the `AnyDrawMuscle` in the tree view, and insert an instance: + +```{literalinclude} Snippets/lesson2/snip.Muscles.main-1.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` -Notice that the \ must be manually changed to drw (or any -other sensible name). The commented lines (with // in front) are the +Notice that the \ must be manually changed to "drw" (or any +other sensible name). The commented lines with // in front are the optional settings. Un-commenting them will not change much because the values they have listed are the default settings. So we need to change some of the values. @@ -69,16 +42,10 @@ The first thing we shall try is to make the muscle bulge. We do this by setting the value of the Bulge variable to 1. What this translates to is to make the muscle bulging proportional to the force in the muscle: -```AnyScriptDoc -AnyDrawMuscle drw = { -  //RGB = {0.554688, 0.101563, 0.117188}; -  //Opacity = 1.000000; -  //DrawOnOff = 1.000000; -  §Bulging = 1;§ -  //ColorScale = 0.000000; -  //RGBColorScale = {0.957031, 0.785156, 0.785156}; -  //MaxStress = 250000.000000; -}; +```{literalinclude} Snippets/lesson2/snip.Muscles.main-2.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` When you try this, you will find that the muscle has become thinner, but @@ -113,14 +80,10 @@ bit more, then the moment arm of the muscle will become progressively smaller, and we will get a larger muscle force. The easy way to accomplish this is to increase the angular velocity of the joint driver: -```AnyScriptDoc -// Drive the revolute joint at constant velocity -AnyKinEqSimpleDriver Drv = { -  DriverPos = {-10*pi/180}; -  DriverVel = {§80§*pi/180}; -  AnyRevoluteJoint &Jnt = .Jnt; -  Reaction.Type = {0}; -}; +```{literalinclude} Snippets/lesson2/snip.Muscles.main-2.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 2 +:end-before: //# END SNIPPET 2 ``` Reload the model and run the InverseDynamicAnalysis operation again. You @@ -129,7 +92,7 @@ you plot the muscle force, Fm, again in a chart view, then you can see how the muscle force goes up drastically with the reduced moment arm: Consequently the muscle now bulges more towards the end of the movement -than it does in the beginning: +than it does in the beginning. The muscle force is now also much larger: ```{image} _static/lesson2/image3.gif :alt: Chart view Muscle1.Fm @@ -180,23 +143,17 @@ For instance, if you want the color interpolated from a cold blue to a warm red as the muscle activity increases, you can use the following settings: -```AnyScriptDoc -AnyDrawMuscle drw = { -  §RGB = {1, 0, 0};  //Red§ -  //Opacity = 1.000000; -  //DrawOnOff = 1.000000; -  Bulging = 1; -  ColorScale = 1; -  §RGBColorScale = {0, 0, 1}; //Blue§ -  MaxStress = 2500; -}; +```{literalinclude} Snippets/lesson2/snip.Muscles.main-3.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` Finally, the muscle drawing object has a couple of properties in common with other drawing objects: You can control the transparency of the -object through the property of that name. Opacity = 1 means opaque, and -with Opacity = 0, the object becomes completely invisible. All values in +object through the property of that name. `Opacity = 1` means opaque, and +with `Opacity = 0`, the object becomes completely invisible. All values in between causes the object to be semi-transparent. You can also turn of -the display of the object entirely off by setting DrawOnOff = 0; +the display of the object entirely off by setting `DrawOnOff = 0`; diff --git a/Muscle_modeling/lesson3.md b/Muscle_modeling/lesson3.md index 2456a908..e9ecd738 100644 --- a/Muscle_modeling/lesson3.md +++ b/Muscle_modeling/lesson3.md @@ -4,7 +4,7 @@ # Lesson 3: Via-point Muscles Although the name of the muscle class we have used so far is -AnyMuscleViaPoint, the example has only shown the muscle passing in a +`AnyMuscleViaPoint`, the example has only shown the muscle passing in a straight line between two points. Real muscles in the body rarely do so. They are usually constrained by various obstacles on their way from origin to insertion, either by connective tissues or by the contact with @@ -12,7 +12,7 @@ bone surfaces. In the former case, the muscle tends to pass as a piecewise straight line between the constrained points, and this is relatively easy to -accomplish by means of an AnyMuscleViaPoint. In the latter case, the +accomplish by means of an `AnyMuscleViaPoint`. In the latter case, the muscle may engage and release contact with the bone surfaces it encounters. This wrapping over bones is a problem of contact mechanics and optimization. It requires a different muscle class and it is @@ -56,79 +56,40 @@ that bisects the angle formed by the muscle on the two sides of the via point. Let us modify the model we have been working on to investigate the -properties of via point muscles. Initially we reduce the bulging to +properties of via point muscles. Initially we edit the bulging to facilitate study of the muscle path. -```AnyScriptDoc -AnyDrawMuscle drw = { -  //RGB = {0.554688, 0.101563, 0.117188}; -  //Opacity = 0.2; -  //DrawOnOff = 1; -  Bulging = 2; -  ColorScale = 1; -  //RGBColorScale = {0.957031, 0.785156, 0.785156}; -  MaxStress = 2500§00§; -}; +```{literalinclude} Snippets/lesson3/snip.Muscles.main-1.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` We then move the insertion point of the muscle a bit further out and closer to the axis of the Arm segment to make room for a via point: -```AnyScriptDoc -AnySeg Arm = { -  r0 = {0.500000, 0.000000, 0.000000}; -  Mass = 1.000000; -  Jii = {0.100000, 1.000000, 1.000000}*0.1; -  AnyRefNode Jnt = { -    sRel = {-0.5, 0.0, 0}; -  }; -  AnyRefNode M1Insertion = { -    sRel = {§0.3, 0.05§, 0}; -  }; -  AnyDrawSeg drw = {}; -}; +```{literalinclude} Snippets/lesson3/snip.Muscles.main-1.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 2 +:end-before: //# END SNIPPET 2 ``` The next step is to introduce a new point on the Arm segment to function as the via point: -```AnyScriptDoc -AnySeg Arm = { -  r = {0.500000, 0.000000, 0.000000}; -  Mass = 1.000000; -  Jii = {0.100000, 1.000000, 1.000000}*0.1; -  AnyRefNode Jnt = { -    sRel = {-0.5, 0.0, 0}; -  }; -  AnyRefNode M1Insertion = { -    sRel = {0.3, 0.05, 0}; -  }; - §AnyRefNode ViaPoint = { -    sRel = {0.0, 0.1, 0}; -  };§ -  AnyDrawSeg drw = {}; -}; +```{literalinclude} Snippets/lesson3/snip.Muscles.main-2.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` We can then introduce the new point in the sequence of points defining the muscle: -```AnyScriptDoc -AnyMuscleViaPoint Muscle1 = { -  AnyMuscleModel &Model = .SimpleModel; -  AnyRefFrame &Orig = .GlobalRef.M1Origin; - §AnyRefFrame &Via = .Arm.ViaPoint;§ -  AnyRefFrame &Ins = .Arm.M1Insertion; -  AnyDrawMuscle drw = { -    //RGB = {0.554688, 0.101563, 0.117188}; -    //Opacity = 0.2; -    //DrawOnOff = 1; -    Bulging = 2; -    ColorScale = 1; -    //RGBColorScale = {0.957031, 0.785156, 0.785156}; -    MaxStress = 250000; -  }; -}; +```{literalinclude} Snippets/lesson3/snip.Muscles.main-2.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 2 +:end-before: //# END SNIPPET 2 ``` The figure below shows the result: diff --git a/Muscle_modeling/lesson4.md b/Muscle_modeling/lesson4.md index c09625a0..a0e2fd68 100644 --- a/Muscle_modeling/lesson4.md +++ b/Muscle_modeling/lesson4.md @@ -15,37 +15,26 @@ A wrapping muscle is presumed to have an origin and an insertion just like the via point muscle. However, instead of interior via points it passes a set of surfaces. If the surfaces are blocking the way then the muscles finds the shortest geodetic path around the surface. For that reason, the -name of the class is AnyMuscleShortestPath. The fact that the muscle +name of the class is `AnyMuscleShortestPath`. The fact that the muscle always uses the shortest path means that it slides effortlessly on the surfaces, and hence there is no friction between the muscle and the surface. Enough talk! Let us prepare for addition of a wrapping muscle to our model. If for some reason you do not have a working model from the -previous lessons, {download}`you can download onehere `. +previous lessons, {download}`you can download one here `. A wrapping muscle needs one or several surfaces to wrap on, so the first thing to do is to define a surface. For convenience we shall attach the surface to the global reference frame, but such wrapping surfaces can be attached to any reference frame in the system, including segments. To be able to play around with the position of the surface, we initially -define a point on GlobalRef for the purpose: +define a point on `GlobalRef` for the purpose: -```AnyScriptDoc -// Global Reference Frame -AnyFixedRefFrame GlobalRef = { -  AnyDrawRefFrame drw = { -    RGB = {1,0,0}; -  }; -  AnyRefNode M1Origin = { -    sRel = {0.0, 0.1, 0}; -  }; - -§ AnyRefNode CylCenter = { -    sRel = {0, 0, -0.2}; -  };§ - -};  // Global reference frame +```{literalinclude} Snippets/lesson4/snip.Muscles.main-1.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` Having defined the point, we can proceed to create a surface. The @@ -56,24 +45,15 @@ really a lot of small planar triangles, and the corners and edges of the triangles will cause the muscles to slide discontinuously over the surface, which disturbs the analysis result. The parametric surfaces currently available are cylinders and ellipsoids. Let us try our luck -with a cylinder. Go to the class tree, locate the class AnySurfCylinder, -and insert an instance into the newly defined node on GlobalRef. -Then define the name of the cylinder, add an AnyDrawParamSurf +with a cylinder. Go to the *Class List*, locate the class `AnySurfCylinder`, +and insert an instance into the newly defined node on `GlobalRef`. +Then define the name of the cylinder, add an `AnyDrawParamSurf` statement, and change the cylinder parameters as shown below: -```AnyScriptDoc -  AnyRefNode CylCenter = { -    sRel = {0, 0, -0.2}; - -    §AnySurfCylinder WrapSurf = { - Radius = 0.15; - Length = 0.4; - //CapRatio = 0.1; - //CapRatio2 = 0.1; - AnyDrawParamSurf drw = {}; -    };§ -  }; -};  // Global reference frame +```{literalinclude} Snippets/lesson4/snip.Muscles.main-2.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` Most of this should be self explanatory. However, notice that we inserted a @@ -91,26 +71,17 @@ to be inserted symmetrically about the xy plane as illustrated below: The cylinder direction is always z in the coordinate direction of the object that the cylinder is inserted into. So, if the cylinder does not have the orientation you want, then the key to rotate it correctly is to -control the direction of the AnyRefNode that it is inserted into. In +control the direction of the `AnyRefNode` that it is inserted into. In fact, let us rotate it just a little bit to make things a bit more interesting: -```AnyScriptDoc -AnyRefNode CylCenter = { -  sRel = {0, 0, -0.2}; - §ARel = RotMat(20*pi/180,y);§ - -  AnySurfCylinder WrapSurf = { -    Radius = 0.15; -    Length = 0.4; - //CapRatio = 0.1; - //CapRatio2 = 0.1; - AnyDrawParamSurf drw = {}; -  }; -}; +```{literalinclude} Snippets/lesson4/snip.Muscles.main-3.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` - Which causes the cylinder to rotate 20 degrees about the y axis. +Which causes the cylinder to rotate 20 degrees about the y axis. ```{image} _static/lesson4/image2.jpeg :alt: Wrap cylinder rotated @@ -124,7 +95,7 @@ case. Graphically it is displayed with facets out of consideration of the efficiency of the graphics display, but from the point-of-view of the muscle it is a perfect cylinder. The second thing to notice is that the ends are capped in such a way that the edges are rounded. You can -control the curvature of this cap by means of the CapRatio variable that +control the curvature of this cap by means of the `CapRatio` variable that is currently commented out in the cylinder object definition. If you play a bit around with different values of the cap ratio then you will quickly get a feel for the effect of the variable. The caps allow you to @@ -135,38 +106,18 @@ on the global reference frame and one point on the arm, and we can then articulate the joint and study the behavior of the wrapping algorithm. The point on the global reference frame is added like this: -```AnyScriptDoc -// Global Reference Frame -AnyFixedRefFrame GlobalRef = { -  AnyDrawRefFrame drw = { -    RGB = {1,0,0}; -  }; -  AnyRefNode M1Origin = { -    sRel = {0.0, 0.1, 0}; -  }; - -§ AnyRefNode M2Origin = { -    sRel = {0.0, 0.15, -0.05}; -  };§ +```{literalinclude} Snippets/lesson4/snip.Muscles.main-3.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 2 +:end-before: //# END SNIPPET 2 ``` Similarly we add a point to the arm: -```AnyScriptDoc -// Define one simple segment -AnySeg Arm = { -  r = {0.500000, 0.000000, 0.000000}; -  Mass = 1.000000; -  Jii = {0.100000, 1.000000, 1.000000}*0.1; -  AnyRefNode Jnt = { -    sRel = {-0.5, 0.0, 0}; -  }; -  AnyRefNode M1Insertion = { -    sRel = {0.3, 0.05, 0}; -  }; - §AnyRefNode M2Insertion = { -    sRel = {-0.2, 0.05, 0.05}; -  };§ +```{literalinclude} Snippets/lesson4/snip.Muscles.main-3.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 3 +:end-before: //# END SNIPPET 3 ``` Notice that we have given the origin and insertion points a bit of @@ -175,39 +126,14 @@ offset will cause the muscles to cross the cylinder in a non-perpendicular path to the cylinder axis such as for instance the pronator muscles of the human forearm do. -It is now possible to define the muscle wrapping over the cylinder. The -easiest way to do it is to make a copy of the via point muscle, Muscle1, -and then make the necessary changes: +It is now possible to define the muscle wrapping over the cylinder by using the +`AnyMuscleShortestPath` object. The easiest way to do it is to make a copy of +the via point muscle, Muscle1, and then make the necessary changes: -```AnyScriptDoc -  AnyMuscleViaPoint Muscle1 = { -    AnyMuscleModel &Model = .SimpleModel; -    AnyRefFrame &Orig = .GlobalRef.M1Origin; -    AnyRefFrame &Via = .Arm.ViaPoint; -    AnyRefFrame &Ins = .Arm.M1Insertion; -    AnyDrawMuscle drw = { -      //RGB = {0.554688, 0.101563, 0.117188}; -      //Opacity = 0.2; -      //DrawOnOff = 1; -      Bulging = 2; -      ColorScale = 1; -      //RGBColorScale = {0.957031, 0.785156, 0.785156}; -      MaxStress = 250000; -    }; -  }; - -§AnyMuscleShortestPath Muscle2 = { -    AnyMuscleModel &Model = .SimpleModel; -    AnyRefFrame &Orig = .GlobalRef.M2Origin; -    AnySurface &srf = .GlobalRef.CylCenter.WrapSurf; -    AnyRefFrame &Ins = .Arm.M2Insertion; -    SPLine.StringMesh = 20; -    AnyDrawMuscle drw = { -      Bulging = 2; -      ColorScale = 1; -      MaxStress = 250000; -    }; -  };§ +```{literalinclude} Snippets/lesson4/snip.Muscles.main-3.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 4 +:end-before: //# END SNIPPET 4 ``` The two muscles are very similar in their definitions. They both have an @@ -258,25 +184,15 @@ As mentioned above, wrapping muscles can also have via points. In fact, we can easily change the via point muscle, Muscle1,  to wrap over the cylinder even though it also has a via point: -```AnyScriptDoc -§AnyMuscleShortestPath§ Muscle1 = { -  AnyMuscleModel &Model = .SimpleModel; -  AnyRefFrame &Orig = .GlobalRef.M1Origin; -  AnyRefFrame &Via = .Arm.ViaPoint; - §AnySurface &srf = .GlobalRef.CylCenter.WrapSurf;§ -  AnyRefFrame &Ins = .Arm.M1Insertion; -  §SPLine.StringMesh = 20;§ -  AnyDrawMuscle drw = { -    Bulging = 2; -    ColorScale = 1; -    MaxStress = 250000; -  }; -}; +```{literalinclude} Snippets/lesson4/snip.Muscles.main-4.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` The definition of the two muscle types is very similar, so we only had -to change the type from AnyMuscleViaPoint to AnyMuscleShortestPath and -insert the wrapping surface and the StringMesh specification. This gives +to change the type from `AnyMuscleViaPoint` to `AnyMuscleShortestPath` and +insert the wrapping surface and the `StringMesh` specification. This gives us the following result: ```{image} _static/lesson4/image4.jpeg @@ -289,7 +205,9 @@ As you can see, both muscles are now wrapping over the cylinder, and we can run the InverseDynamics analysis. It seems to work, but the system provides the following warning: -`WARNING(OBJ.MCH.KIN7): MuscleDemo.Ini.any(75): Muscle1.SPLine: Penetration of surface: WrapSurf: Via-point 'M1Origin' on 'SPLine' is located below the wrapping surface'WrapSurf` +```none +WARNING(OBJ.MCH.KIN7): MuscleDemo.Ini.any(72): Muscle1.SPLine: Penetration of surface: WrapSurf: Via-point 'M1Origin' on 'SPLine' is located below the wrapping surface'WrapSurf +``` This is a warning that you will see rather frequently when working with complex models with wrapping. The warning comes when one of the end @@ -302,10 +220,10 @@ present case, the origin point of Muscle1 is only slightly below the cylinder surface, so the problem can be rectified by a small offset on the origin point: -```AnyScriptDoc -AnyRefNode M1Origin = { -  sRel = {0.0, 0.1§5§, 0}; -}; +```{literalinclude} Snippets/lesson4/snip.Muscles.main-4.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 2 +:end-before: //# END SNIPPET 2 ``` If you are analytically inclined, you may be thinking that the muscles @@ -320,24 +238,14 @@ vectors. These are really points that the muscle initially should pass through. You can specify as many of these points as you like. In the example below we have used two: -```AnyScriptDoc -AnyMuscleShortestPath Muscle2 = { -  AnyMuscleModel &Model = .SimpleModel; -  AnyRefFrame &Orig = .GlobalRef.M2Origin; -  AnySurface &srf = .GlobalRef.CylCenter.WrapSurf; -  AnyRefFrame &Ins = .Arm.M2Insertion; -  SPLine.StringMesh = 20; -  §SPLine.InitWrapPosVectors = {{-0.2, -0.2, 0}, {-0.05, -0.2, 0}};§ -  AnyDrawMuscle drw = { -    Bulging = 2; -    ColorScale = 1; -    MaxStress = 250000; -  }; -}; +```{literalinclude} Snippets/lesson4/snip.Muscles.main-4.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 3 +:end-before: //# END SNIPPET 3 ``` -Notice that the InitWrapPosVectors like the StringMesh is part of an -object called SPLine. This is an object in its own right that gets +Notice that the `InitWrapPosVectors` like the `StringMesh` is part of an +object called `SPLine`. This is an object in its own right that gets defined automatically inside a shortest path muscle. It is a special kind of {doc}`kinematic measure <../The_mechanical_elements/lesson4>` that is really a string that wraps just like a muscle but does nothing else than @@ -345,9 +253,9 @@ measure its own length. These objects can be used outside the muscle definition for various purposes in the model, for instance for definition of springs or rubber bands. -After you load the model with the added InitWrapVectors, try using the -Step button rather than the run button. This will show you how the -system uses the InitWrapVectors to pull the muscle to the other side of +After you load the model with the added `InitWrapVectors`, try using the +*Step button* rather than the run button. This will show you how the +system uses the `InitWrapVectors` to pull the muscle to the other side of the cylinder: ```{image} _static/lesson4/image5.jpeg diff --git a/Muscle_modeling/lesson5.md b/Muscle_modeling/lesson5.md index 3998d666..af45a6ee 100644 --- a/Muscle_modeling/lesson5.md +++ b/Muscle_modeling/lesson5.md @@ -3,7 +3,7 @@ # Lesson 5: Muscle Models -Muscle model is a description of how a muscle behaves under different +Muscle models are a description of how a muscle behaves under different operating conditions. There are two schools of thought within this area. - The first school pursues phenomenological models based on @@ -111,39 +111,25 @@ different muscle models and muscle model calibration. The AnyScript model from the previous lesson will suffice very nicely. You can download a functional version of the model here: {download}`MuscleDemo.5.any`. +Right-click and save the file to your local disk, and subsequently open the +model in the AnyBody Modeling System. ## AnyMuscleModel2ELin -Right-click and save the file to your local disk, and subsequently open the -model in the AnyBody Modeling System. We have already seen the consequences of -using the simple muscle model, so we shall proceed directly to the two-element -muscle, the AnyMuscleModel2ELin. Let us define such a muscle model. If you click -the Classes tab in the tree view left of the edit window, expand the class tree, -right-click the AnyMuscleModel2ELin class, and insert a template, you will -obtain the following: - -```AnyScriptDoc - AnyMuscleModel SimpleModel = { -   F0 = 100; - //Lf0 = 0; - //Vol0 = 0; - }; +We have already seen the consequences of using the simple muscle model, so we +shall proceed directly to the two-element muscle, the `AnyMuscleModel2ELin`. Let +us define such a muscle model. If you click the Classes tab, expand the *class* +*list*, right-click the `AnyMuscleModel2ELin` class, and insert a template, you +will obtain the following: -§AnyMuscleModel2ELin = -{ - F0 = 0.0; - //Lf0 = 0.0; - //Vol0 = 0.0; - Lt0 = 0.0; - //Epsilon0 = 0.05; - V0 = 0.0; -};§ +```{literalinclude} Snippets/lesson5/snip.Muscles.main-1.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` Let us briefly review the parameters: - - `````{list-table} --- header-rows: 1 @@ -199,68 +185,54 @@ variables in the Chart View. Let us assign a name and some reasonable parameters to our two-element muscle model: -```AnyScriptDoc -AnyMuscleModel2ELin §Model2§ = { -   F0 = §200§; -   Lf0 = §0.3§; -   Lt0 = §0.5§; -   Epsilon0 = §0.05§; -   V0 = §-8.0§; - }; +```{literalinclude} Snippets/lesson5/snip.Muscles.main-2.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` The parameters here are more or less random. In a moment we shall explain the ones that are less random, but first we must assign the new model to Muscle1: -```AnyScriptDoc -AnyMuscleShortestPath Muscle1 = { -  AnyMuscleModel &Model = §.Model2§; -  AnyRefFrame &Orig = .GlobalRef.M1Origin; -  AnyRefFrame &Via = .Arm.ViaPoint; -  AnySurface &srf = .GlobalRef.CylCenter.WrapSurf; -  AnyRefFrame &Ins = .Arm.M1Insertion; -  SPLine.StringMesh = 20; -  AnyDrawMuscle drw = { -    Bulging = 0; -    ColorScale = 1; -    MaxStress = 250000; -  }; -}; +```{literalinclude} Snippets/lesson5/snip.Muscles.main-2.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 2 +:end-before: //# END SNIPPET 2 ``` -We are ready to run the analysis again and investigate the results. Pick -the InverseDynamics analysis in the tree of operations and click the Run -button. Then open a new Chart View and expand the tree in the Chart View -as far down as Muscle1. You will see a whole list of muscle properties -that you can chart simply by clicking them. Let us initially see how the -properties Lm and Lmdot affecting the strength of the model. You can -plot several properties simultaneously in the Chart View by use of an -asterix in the variable specification field at the top of the window -like this: +We are ready to run the analysis again and investigate the results. Pick the +InverseDynamics analysis in the tree of operations and click the Run button. +Then open a new Chart View and expand the tree in the Chart View as far down as +Muscle1, `Main.MyStudy.Output.Model.Muscle1`. You will see a whole list of +muscle properties that you can chart simply by clicking them. Let us initially +see how the properties `Lm` and `Lmdot` affecting the strength of the model. You can +plot several properties simultaneously in the Chart View by use of an asterix (*) in +the variable specification field at the top of the window like this: ```{image} _static/lesson5/image2.png :alt: chart view: muscle1.L :align: center ``` -Now we can compare the variation of Lm and Lmdot to our settings of -Lf0 and V0. Lm seems to vary between approximately 0.31 and 0.15. With -an Lf0 of 0.3 (= 2x0.15) this means that the muscle must come close to +Now we can compare the variation of `Lm` and `Lmdot` to our settings of +`Lf0` and `V0`. `Lm` seems to vary between approximately 0.33 and 0.15. With +an `Lf0` of 0.2 (= 2x0.10) this means that the muscle must come close to the minimum length at which it has low strength when we approach the end -of the movement. Lmdot varies between -0.24 and -0.06, and this is far +of the movement. `Lmdot` varies between -0.24 and -0.05, and this is far from its speed limit V0 = -8, so the contraction speed is not expected to have much effect. We can investigate the effect very easily simply by -clicking the Strength property of the muscle and obtain the following +clicking the `Strength` property of the muscle and obtain the following graph: ```{image} _static/lesson5/image3.png :alt: muscle strength plot :align: center +:width: 75% ``` -The strength does indeed decrease drastically from around 200 N to -almost nothing as we expected when the muscle contracts. +The strength does indeed decrease drastically from around 350 N to +around 100 N as we expected when the muscle contracts. Now that we have muscle data available, let us briefly review the parameters presented in the Chart View: @@ -270,8 +242,6 @@ parameters presented in the Chart View: :align: center ``` - - `````{list-table} --- header-rows: 1 @@ -371,25 +341,21 @@ about the velocity? Well, the specified values of -8 m/s is a reasonable estimate for many physiological muscles, but let us try to decrease it and thereby make the muscle more sensitive to contraction velocity: -```AnyScriptDoc -AnyMuscleModel2ELin Model2 = { -   F0 = 200; -   Lf0 = 0.3; -   Lt0 = 0.5; -   Epsilon0 = 0.05; -   §V0 = -0.3§; - }; +```{literalinclude} Snippets/lesson5/snip.Muscles.main-3.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` A value of V0 = -0.3 is close to the contraction velocity of the muscle in the beginning of the simulation. This, this decreases the strength of the muscle significantly as we can see by reloading, rerunning and -plotting the Strength variable again: +plotting the `Strength` variable again: ```{image} _static/lesson5/image5.png :alt: muscle strength plot, v0=-0.3 :align: center -:width: 80% +:width: 75% ``` Instead of being monotonically decreasing, the muscle strength now @@ -400,24 +366,24 @@ velocity, so this muscle model in spite of its simplicity is capable of balancing several of the effects of real muscle physiology. Another of the important input parameters in this example is the nominal -tendon length, Lt0. This is a parameter that has a very large influence +tendon length, `Lt0`. This is a parameter that has a very large influence on the muscle's performance. The total origin-insertion length of the muscle-tendon unit depends on the size and posture of the body. The -muscle spans this length with the sum of muscle length, Lm, and tendon -length, Lt, such that Lmt = Lm + Lt. Both Lm and Lt change during the -movement of the body. Lt is given by its initial length, Lt0, and the -elastic deformation. Lm has to take up whatever rest of Lmt that is -available after Lt has been subtracted. In some cases, the tendon is +muscle spans this length with the sum of muscle length, `Lm`, and tendon +length, `Lt`, such that `Lmt = Lm + Lt`. Both `Lm` and `Lt` change during the +movement of the body. `Lt` is given by its initial length, `Lt0`, and the +elastic deformation. `Lm` has to take up whatever rest of `Lmt` that is +available after `Lt` has been subtracted. In some cases, the tendon is significantly longer than the muscle, and this means that a relatively small variation of the tendon length results in a large relative -variation of the portion of Lmt that the muscle has to fill. Obviously -Lt0 plays a significant role for Lt and hence influences the working -length of the muscle. Let us investigate this effect by reducing Lt0: +variation of the portion of `Lmt` that the muscle has to fill. Obviously +`Lt0` plays a significant role for `Lt` and hence influences the working +length of the muscle. Let us investigate this effect by reducing `Lt0`: ```AnyScriptDoc AnyMuscleModel2ELin Model2 = {    F0 = 200; -   Lf0 = 0.3; +   Lf0 = 0.2;    Lt0 = §0.3§;    Epsilon0 = 0.05;    V0 = -0.3; @@ -425,13 +391,14 @@ AnyMuscleModel2ELin Model2 = { ``` This reduction of the tendon length from 0.5 to 0.3 m is very -significant compared to the nominal muscle fiber length of Lf0 = 0.3 -m. Reducing the length of the tendon increases the length and thereby +significant compared to the nominal muscle fiber length of `Lf0 = 0.3 m`. +Reducing the length of the tendon increases the length and thereby the strength of the muscle: ```{image} _static/lesson5/image6.png :alt: muscle strength plot, Lt0= 0.3 :align: center +:width: 75% ``` The interdependency between the stretch of the tendon, the length of the @@ -442,45 +409,23 @@ is not taken into account in the computation of the muscle strength. Nevertheless, let us investigate how the stretch of the tendon influences the muscle. We shall define an external load on the arm, which causes the tendon to stretch. But before we change anything, let -us just notice that the variation of muscle length, Lm, over the +us just notice that the variation of muscle length, `Lm`, over the movement in the absence of an external load is as shown below: ```{image} _static/lesson5/image7.png :alt: Lm plot, no external load :align: center +:width: 75% ``` Definition of an external force requires two new elements in the model: The force itself and a new node on the arm, which we shall call hand, to which the load can be applied: -```AnyScriptDoc - // Define one simple segment - AnySeg Arm = { -   r = {0.500000, 0.000000, 0.000000}; -   Mass = 1.000000; -   Jii = {0.100000, 1.000000, 1.000000}*0.1; -   AnyRefNode Jnt = { -     sRel = {-0.5, 0.0, 0}; -   }; -   AnyRefNode M1Insertion = { -     sRel = {0.3, 0.05, 0}; -   }; -   AnyRefNode M2Insertion = { -     sRel = {-0.2, 0.05, 0.05}; -   }; -   AnyRefNode ViaPoint = { -     sRel = {0.0, 0.1, 0}; -   }; -  §AnyRefNode Hand = { -     sRel = {0.5, 0.0, 0}; -   };§ -   AnyDrawSeg drw = {}; - }; -§AnyForce3D Load = { -   AnyRefNode &Attachment = .Arm.Hand; -   F = {-100, -100, 0}; - };§ +```{literalinclude} Snippets/lesson5/snip.Muscles.main-3.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 2 +:end-before: //# END SNIPPET 2 ``` The load is pointing down and backward at a 45 degree angle, so that it @@ -491,6 +436,7 @@ following fashion: ```{image} _static/lesson5/image8.png :alt: Muscle length plot :align: center +:width: 75% ``` The interesting point here is that with the long tendon and the high @@ -509,7 +455,7 @@ So far we have been focusing our attention on Muscle1 in the demo model and left Muscle2 with the simple muscle model. Let us briefly study what Muscle2 is actually doing (if you need an updated working model, you can download it here: -{download}`MuscleDemo.5-2.any `. Muscle2 wraps +{download}`MuscleDemo.5-2.any `). Muscle2 wraps about the cylinder and obviously extends significantly as the arm turns upward. If you run the analysis and plot the length of Muscle2, you will see that it increases from 0.7 to 1 meter. For a normal muscle (actually a @@ -608,61 +554,34 @@ information: : This factor is related to Jpe. Where Jpe controls the shape of the nonlinearity, PEFactor controls the steepness of the force in the parallel-elastic element as it is elongated. If we imagine a completely inactive muscle and load the muscle with a force corresponding to the active strength of the muscle, i.e. F0, then the length of the elongated muscle fibers will be PEFactor x Lf0. In other words PEFactor is a dimensionless measure of the flexibility of the parallel-elastic element of the muscle. -`Gammabar` - -: This is the deprecated parameter replaced by Gamma0. - Knowing the significance of the different parameters, let us pick reasonable values for Muscle2 and study their influences: -```AnyScriptDoc -AnyMuscleModel3E §Model3§ = { - F0 = §100§; - Lf0 = §0.3§; - Gamma0 = §30*pi/180§; - Epsilon0 = §0.05§; - Lt0 = §0.5§; - Fcfast = §0.4§; - §Jt = 3.0§; - §Jpe = 3.0§; - §K1 = 2§; - §K2 = 8§; - §PEFactor = 5§; -}; +```{literalinclude} Snippets/lesson5/snip.Muscles.main-4.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` -Notice that Lf0 + Lt0 = 0.8, which is in the range of the Lmt +Notice that `Lf0 + Lt0 = 0.8`, which is in the range of the `Lmt` variation of Muscle2. This is important because it gives the muscle a reasonable chance of spanning the origin-insertion length. We also have to associate Muscle2 with the new muscle model: -```AnyScriptDoc -AnyMuscleShortestPath Muscle2 = { -  AnyMuscleModel &Model = .§Model3§; -  AnyRefFrame &Orig = .GlobalRef.M2Origin; -  AnySurface &srf = .GlobalRef.CylCenter.WrapSurf; -  AnyRefFrame &Ins = .Arm.M2Insertion; -  SPLine.StringMesh = 20; -  SPLine.InitWrapPosVectors = {{-0.2, -0.2, 0},{-0.05,-0.2, 0}}; -  AnyDrawMuscle drw = { -    Bulging = 0; -    ColorScale = 1; -    MaxStress = 250000; -  }; -}; +```{literalinclude} Snippets/lesson5/snip.Muscles.main-4.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 2 +:end-before: //# END SNIPPET 2 ``` Finally, to have a more clean-cut case, we temporarily remove the -external force that we previously added +external force that we previously added. -```AnyScriptDoc -§/*§ -    AnyForce3D Load = { -      AnyRefNode &Attachment = .Arm.Hand; -      F = {-100, -100, 0}; -    }; -§*/§ +```{literalinclude} Snippets/lesson5/snip.Muscles.main-4.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 3 +:end-before: //# END SNIPPET 3 ``` We are ready to try running the InverseDynamics analysis again. Load the @@ -673,17 +592,17 @@ the Chart View's tree, expand the folders as far as Muscle2, and try charting some of the parameters. The key to understanding the muscle's behavior is to study the forces in -the muscle's different elements. The chart of Fm, which is the force in +the muscle's different elements. The chart of `Fm`, which is the force in the muscle's contractile element, is very uninteresting. This muscle does not contribute to carrying the load, and hence the system does not -activate it. But the muscle is not without force. The property Fp, which +activate it. But the muscle is not without force. The property `Fp`, which is the force in the parallel-elastic element of the muscle has the following behavior: ```{image} _static/lesson5/image10.png :alt: Force parallel elastic element :align: center -:width: 70% +:width: 75% ``` In the initial phase of the movement, the parallel-elastic element is @@ -692,7 +611,7 @@ the passive muscle force sets in, and it continues to rise as the movement progresses. Notice that this passive force acts against the movement and hence requires Muscle1 to work that much more. But the passive force has another interesting effect, which we can see if we -chart the property Lt, i.e. the length of the tendon (Notice that we +chart the property `Lt`, i.e. the length of the tendon (Notice that we have changed the scale of the ordinate axis): ```{image} _static/lesson5/image11.png @@ -705,7 +624,7 @@ From the time the passive force sets in, the tendon starts to elongate a little bit. The total origin-insertion length of the muscle-tendon unit is the -tendon length plus the muscle length, i.e. Lm + Lt. When Lt is +tendon length plus the muscle length, i.e. `Lm + Lt`. When `Lt` is stretched, the effect is that the muscle fibers stretch that much less, and since the muscle's strength depends on the momentary length of the contractile element, the strain in the tendon can influence the strength @@ -740,33 +659,10 @@ not done by the system; the correction is local to each muscle. So much for passive properties! It is more instructive to investigate a muscle model with active force. The easiest way to do so is to enable -our hand force again and change it to point directly upward. This causes +our hand force again and change it to *point directly upward*. This causes the previously inactive Muscle2 to become active: ```AnyScriptDoc - // Define one simple segment - AnySeg Arm = { -   r = {0.500000, 0.000000, 0.000000}; -   Mass = 1.000000; -   Jii = {0.100000, 1.000000, 1.000000}*0.1; -   AnyRefNode Jnt = { -     sRel = {-0.5, 0.0, 0}; -   }; -   AnyRefNode M1Insertion = { -     sRel = {0.3, 0.05, 0}; -   }; -   AnyRefNode M2Insertion = { -     sRel = {-0.2, 0.05, 0.05}; -   }; -   AnyRefNode ViaPoint = { -     sRel = {0.0, 0.1, 0}; -   }; -   AnyRefNode Hand = { -     sRel = {0.5, 0.0, 0}; -   }; -   AnyDrawSeg drw = {}; - }; - §AnyForce3D Load = {    AnyRefNode &Attachment = .Arm.Hand;    F = {0, 10, 0}; @@ -898,15 +794,22 @@ header-rows: 1 ## Calibration -**Note:** This section describes calibration of muscle-tendon units briefly; for more details and more examples, please refer to {doc}`Inverse Dyanmics of Muscle Systems: Calibration <../MuscleRecruitment/lesson_calibration>`. +:::{note} +This section describes calibration of muscle-tendon units briefly; for more +details and more examples, please refer to +{doc}`Inverse Dyanmics of Muscle Systems: Calibration <../MuscleRecruitment/lesson_calibration>`. +::: -One of the practical challenges in working with detailed muscle models -in complex musculoskeletal systems is the dependency on defined fiber and tendon -length (i.e. Lf0 and Lt0, respectively). These are input to the model but they must match accurately to the operation range of the model, which governed by the skeletal structure. The challenge is to make matching skeletal and muscle parameters, also when the model is scaled to match different anthropometrics. +One of the practical challenges in working with detailed muscle models in +complex musculoskeletal systems is the dependency on defined fiber and tendon +length (i.e. `Lf0` and `Lt0`, respectively). These are input to the model but they +must match accurately to the operation range of the model, which governed by the +skeletal structure. The challenge is to make matching skeletal and muscle +parameters, also when the model is scaled to match different anthropometrics. A brief experiment with our model can reveal where the difficulty lies. In the model we have just investigated, the activity of -Muscle2 has the following development over the movement: +Muscle2, has the following development over the movement: ```{image} _static/lesson5/image31.png :alt: Calibration. Lt0 plot @@ -914,7 +817,7 @@ Muscle2 has the following development over the movement: :width: 65% ``` -But what would happen if our guess of tendon length, Lt0, in the muscle +But what would happen if our guess of tendon length, `Lt0`, in the muscle model definition was just slightly off the correct value? Well if we change the current value from 0.5 m to 0.45 m, i.e. a reduction of 10%, we get the following activity: @@ -947,15 +850,20 @@ and the other one requires additional information. There are two approaches for calibration in AnyBody (AnyBodyCalibrationStudy class): -- Tendon-length calibration (operation: TendonLengthAdjustment) - adjusts the tendon length (Lt0) to obtain optimal conditions at a specific location under the assumption that the inputted fiber length is correct. -- Two-parameter calibration adjusts both Lt0 and Lf0 (operation: FiberAndTendonAdjustment). - This method requires input about two specific points of the muscles' operation range and thereby it can match both fiber and tendon length. This method is a fairly new feature in AnyBody (version 7) and is not the default method in AMMR (e.g. version 1.x and 2.0). +- Tendon-length calibration (operation: `TendonLengthAdjustment`) + adjusts the tendon length (`Lt0`) to obtain optimal conditions at a specific + location under the assumption that the inputted fiber length is correct. +- Two-parameter calibration adjusts both `Lt0` and `Lf0` (operation: `FiberAndTendonAdjustment`). + This method requires input about two specific points of the muscles' operation + range and thereby it can match both fiber and tendon length. This method is a + fairly new feature in AnyBody (version 7) and is not the default method in + AMMR (e.g. version 1.x and 2.0). For details, please visit {doc}`Inverse Dyanmics of Muscle Systems: Calibration <../MuscleRecruitment/lesson_calibration>`. -In the following, we demonstrate calibration by examples using the tendon-length calibration, i.e. calibrating Lt0. -In the following two sections, we disucss two calibration strategies: "Cheap and dirty" and "Detailed" calibration. +In the following, we demonstrate calibration by examples using the tendon-length +calibration, i.e. calibrating `Lt0`. In the following two sections, we disucss two +calibration strategies: "Cheap and dirty" and "Detailed" calibration. ### "Cheap and dirty" calibration @@ -979,8 +887,8 @@ InverseDynamics operation of the original AnyBodyStudy. But when the analysis is done, the following message appears in the message window: ```none -The tendon length of muscle Main.MyModel.Muscle2 was calibrated. -The muscle properties have been updated. +The tendon/fiber length was calibrated successfully. +Design variables of the calibration model have been updated. ``` Try running the InverseDynamics again and plot the Activity of Muscle2. @@ -989,7 +897,7 @@ You should see the following: ```{image} _static/lesson5/image33.png :alt: Cheap n dirty calibration, Activity plot :align: center -:width: 65% +:width: 75% ``` As you can see, this is again very different from what we have seen @@ -1003,9 +911,9 @@ before. Plotting the strength will reveal what has happened: What FiberAndTendonAdjustment does is to run through the specified movement and compute the variation of the origin-insertion length of the -muscle. It subsequently changes the user-defined value of Lt0 such that +muscle. It subsequently changes the user-defined value of `Lt0` such that the length of the contractile element equals the optimum fiber length, -Lf0, when the origin-insertion length is at its mean value. Notice that +`Lf0`, when the origin-insertion length is at its mean value. Notice that this does not necessarily correspond to the length when 50% of the movement has passed. @@ -1018,7 +926,7 @@ work if you are modeling a movement that is outside the typical posture of the joints in the model. Please notice that the tendon lengths specified in the AnyScript model -are not altered by this method. Every time you reload the model you must +are not altered by this method. Every time you *reload* the model you must run the FiberAndTendonAdjustment again. ### Detailed calibration diff --git a/Muscle_modeling/lesson6.md b/Muscle_modeling/lesson6.md index 01215730..a7c14b10 100644 --- a/Muscle_modeling/lesson6.md +++ b/Muscle_modeling/lesson6.md @@ -17,8 +17,10 @@ acting along strings. There is an {doc}`an entire tutorial lesson <../The_mechanical_elements/lesson4>` devoted to the subject *Kinematic Measures* in the section on {doc}`The Mechanical Elements <../The_mechanical_elements/intro>`. ::: -The solution to our problem involves two classes: `AnyRecruitedActuator` and `AnyMuscleGeneric`. These classes can act on *Kinematic Measures*, which are an abstract -classes representing anything you can measure on a model.. + +The solution to our problem involves two classes: `AnyRecruitedActuator` and +`AnyMuscleGeneric`. These classes can act on *Kinematic Measures*, which are an +abstract class representing anything you can measure on a model. For example: @@ -35,10 +37,11 @@ Both classes are similar, but `AnyRecruitedActuator` is used for non-physiological elements like boundary conditions, contact forces, and residual forces. On the other hand, `AnyMuscleGeneric` is used for forces and moments that still represent the effect of real muscles, such as joint torques. -The activity of `AnyMuscleGeneric` is included in the 'MaxMuscleActivity' output +The activity of `AnyMuscleGeneric` is included in the `MaxMuscleActivity` output variable of the model. -In this lesson, we will demonstrate how recruited actuators (and generic muscles) can be used for various modeling tasks. +In this lesson, we will demonstrate how recruited actuators (and generic +muscles) can be used for various modeling tasks. ## Recruited joint torque providers @@ -85,63 +88,23 @@ ERROR(OBJ1): MuscleDemo.6.any(103): ArmStudy.InverseDynamics: No solution found: This error message means that the model can't be balanced without muscles. But we won't add real muscles. Instead, we'll add generic muscles to the revolute -joints. The easiest way to add a generic muscle is from the class tree. Just +joints. The easiest way to add a generic muscle is from the *class list*. Just place your cursor after the Drivers folder, find the AnyGeneralMuscle in the class tree, and insert a template. -```AnyScriptDoc -  AnyFolder Drivers = { - - //--------------------------------- - AnyKinEqSimpleDriver ShoulderMotion = { - AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; - DriverPos = {-1.7}; - DriverVel = {0.4}; - Reaction.Type = {0}; - }; // Shoulder driver - - //--------------------------------- - AnyKinEqSimpleDriver ElbowMotion = { - AnyRevoluteJoint &Jnt = ..Jnts.Elbow; - DriverPos = {1.5}; - DriverVel = {0.7}; - Reaction.Type = {0}; - }; // Elbow driver - }; // Driver folder - -§AnyMuscleGeneric = -{ - //viewForce.Visible = Off; - //MetabModel = Global.Null; - //FatigueModel = Global.Null; - //MuscleModel = Global.Null; - //Type = NonPositive; - AnyMuscleModel & = ; - AnyKinMeasure & = ; -};§ +```{literalinclude} Snippets/lesson6/snip.Muscles.main-1.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` Just as normal muscles, generic muscles must be associated with a muscle model. Let us insert a simple one: -```AnyScriptDoc -§AnyMuscleModel = { - F0 = 0; - //Lf0 = 0; - //Vol0 = 0; - };§ - -AnyMuscleGeneric = -{ - //viewForce.Visible = Off; - //MetabModel = Global.Null; - //FatigueModel = Global.Null; - //MuscleModel = Global.Null; - //Type = NonPositive; - AnyMuscleModel & = ; - AnyKinMeasure & = ; -}; - +```{literalinclude} Snippets/lesson6/snip.Muscles.main-2.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` The empty fields in the muscle model must be filled in: @@ -175,22 +138,10 @@ AnyMuscleGeneric §ShoulderTorque§ = Providing a torque for the shoulder is not enough. We also need a torque in the elbow: -```AnyScriptDoc -AnyMuscleGeneric ShoulderTorque = -{ - //viewForce.Visible = Off; - //Type = NonPositive; - AnyMuscleModel &Model = .MusModel; - AnyKinMeasure &Angle = .Jnts.Shoulder; -}; - -§AnyMuscleGeneric ElbowTorque = -{ - //viewForce.Visible = Off; - //Type = NonPositive; - AnyMuscleModel &Model = .MusModel; - AnyKinMeasure &Angle = .Jnts.Elbow; -};§ +```{literalinclude} Snippets/lesson6/snip.Muscles.main-3.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` Having provided torques for the shoulder and elbow we can try to run the @@ -199,14 +150,13 @@ inverse dynamic analysis again. If you try to run the program now, you'll encounter a new error message: ``` -ERROR(OBJ.MCH.MUS4) : MuscleDemo.6.any(122) : ArmStudy.InverseDynamics : Muscle recruitment solver : infeasible problem with upper bounds +ERROR(OBJ.MCH.MUS4): MuscleDemo.6.any(125): ArmStudy.InverseDynamics: Muscle recruitment solver: infeasible problem with upper bounds ``` - This error occurs because generic muscles, like normal muscles, can only act in one direction. The Type variable controls this direction. If the muscle acts in -the positive direction of the joint angle, set Type = NonNegative. If it acts in -the negative direction, set Type = NonPositive. +the positive direction of the joint angle, set `Type = NonNegative`. If it acts in +the negative direction, set `Type = NonPositive`. :::{note} The terms NonNegative and NonPositive can be confusing. They will be changed in future software versions. The current terms were chosen to show that @@ -217,30 +167,16 @@ In this case, the external load tends to move in the negative angle direction for both the shoulder and elbow. So, the muscles should counteract in the positive direction. - -```AnyScriptDoc -AnyMuscleGeneric ShoulderTorque = -{ - //viewForce.Visible = Off; - §Type = NonNegative;§ - AnyMuscleModel &Model = .MusModel; - AnyKinMeasure &Angle = .Jnts.Shoulder; -}; - -AnyMuscleGeneric ElbowTorque = -{ - //viewForce.Visible = Off; - §Type = NonNegative;§ - AnyMuscleModel &Model = .MusModel; - AnyKinMeasure &Angle = .Jnts.Elbow; -}; - +```{literalinclude} Snippets/lesson6/snip.Muscles.main-4.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` Now, you can run the InverseDynamics operation. After running it, open a new Chart View. Look up the two joint torques as the Fm property of the general -muscles. You can plot both of them at the same time using an asterisk (`*`), as -shown below: +muscles. You can plot both of them at the same time using an asterisk (`*`), +like this `Main.ArmStudy.Output.Model.*Torque.Fm`. ```{image} _static/lesson6/image2.png :alt: Chart view, Torques @@ -300,58 +236,10 @@ need to change the kinematics so the arm slides along the wall. It's hard to figure out the joint angle variations needed for vertical hand movement, so we'll drive the hand directly instead. -```AnyScriptDoc - AnyFolder Jnts = { - - //--------------------------------- - AnyRevoluteJoint Shoulder = { - Axis = z; - AnyRefNode &GroundNode = ..GlobalRef.Shoulder; - AnyRefNode &UpperArmNode = ..Segs.UpperArm.ShoulderNode; - }; // Shoulder joint - - AnyRevoluteJoint Elbow = { - Axis = z; - AnyRefNode &UpperArmNode = ..Segs.UpperArm.ElbowNode; - AnyRefNode &LowerArmNode = ..Segs.LowerArm.ElbowNode; - }; // Elbow joint - - }; // Jnts folder - -§AnyKinLinear HandPos = { - AnyRefFrame &ref1 = .GlobalRef.Shoulder; - AnyRefFrame &ref2 = .Segs.LowerArm.PalmNode; - };§ - - AnyFolder Drivers = { - §AnyKinEqSimpleDriver HandDriver = { - AnyKinLinear &Measure = ..HandPos; - MeasureOrganizer = {0,1}; - DriverPos = {0.45, -0.6}; - DriverVel = {0, 0.5}; - Reaction.Type = {Off, Off}; - };§ - - § /*§ - //--------------------------------- - AnyKinEqSimpleDriver ShoulderMotion = { -   AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; -   DriverPos = {-1.7}; -   DriverVel = {0.4}; -   Reaction.Type = {Off}; - }; // Shoulder driver - - //--------------------------------- - AnyKinEqSimpleDriver ElbowMotion = { -   AnyRevoluteJoint &Jnt = ..Jnts.Elbow; -   DriverPos = {1.5}; -   DriverVel = {0.7}; -   Reaction.Type = {Off}; - }; // Elbow driver - - §*/§ - - }; // Driver folder +```{literalinclude} Snippets/lesson6/snip.Muscles.main-4.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 2 +:end-before: //# END SNIPPET 2 ``` The previous two joint angle drivers have been disabled to avoid making the @@ -363,9 +251,7 @@ provide any reaction forces to the arm. When you plot the `MaxMuscleActivity`, you'll see that the muscle activity remains fairly constant. This is because the moment arms are also constant. The -gravity and the applied load of 100 N are both vertical. You might think that a -horizontal support wouldn't make much of a difference. But let's test this by -turning on the horizontal support of the driver. +gravity and the applied load of 100 N are both vertical. ```{image} _static/lesson6/image4.gif :alt: no reaction MaxMuscleActivity plot @@ -373,10 +259,8 @@ turning on the horizontal support of the driver. :width: 65% ``` -The muscle activity stays fairly constant. This is because the moment arms are -also constant. Both the gravity and the applied load of 100 N are vertical. You -might think that a horizontal support wouldn't make much of a difference. But -let's test this by turning on the horizontal support of the driver: +You might think that a horizontal support wouldn't make much of a difference. +But let's test this by turning on the horizontal support of the HandDriver: ```AnyScriptDoc Reaction.Type = {§On§, Off}; @@ -406,19 +290,10 @@ Reaction.Type = {§Off§, Off}; Subsequently we define a `AnyRecruitedActutor` object: -```AnyScriptDoc - - }; // Driver folder - - §AnyRecruitedActuator WallReaction = { - Type = NonPositive; - Volume = 1e-6; // Ignore this value. Only used in special volume weighted recruitement - Strength = 10000; - AnyKinMeasureOrg Org = { - AnyKinMeasure &wall = ..HandPos; - MeasureOrganizer = {0}; - }; - };§ +```{literalinclude} Snippets/lesson6/snip.Muscles.main-5.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` Two things to note here: @@ -439,9 +314,9 @@ the specification line `Main.ArmStudy.Output.Model.*Torque.Fm`: :width: 65% ``` -The red curve represents the shoulder joint torque, and the green curve +The blue curve represents the shoulder joint torque, and the orange curve represents the elbow torque. Notice that the envelope of these two curves is -identical to the MaxMuscleActivity curve we plotted earlier for the case of no +identical to the `MaxMuscleActivity` curve we plotted earlier for the case of no support. You might think that the support would be beneficial in the final stages of the @@ -453,16 +328,10 @@ benefit of the support. Let's see what happens if we turn the reaction force the other way, like if the hand could pull against the far side of the wall: -```AnyScriptDoc -AnyRecruitedActuator WallReaction = { - Type = §NonNegative§; - Volume = 1e-6; // Ignore this value. Only used in special volume weighted recruitement - Strength = 10000; - AnyKinMeasureOrg Org = { - AnyKinMeasure &wall = ..HandPos; - MeasureOrganizer = {0}; - }; - }; +```{literalinclude} Snippets/lesson6/snip.Muscles.main-6.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` When you run the model again and look at the same graphs, you'll see this: diff --git a/Muscle_modeling/lesson7.md b/Muscle_modeling/lesson7.md index 8ade9794..310bf74c 100644 --- a/Muscle_modeling/lesson7.md +++ b/Muscle_modeling/lesson7.md @@ -25,7 +25,7 @@ hinged at the Ground's origin, and a driver bends it downwards. With the movement, the red ligament is stretched, and a force builds up in it. Try running the InverseDynamics operation. You will see the arm move, and you can subsequently open a Chart View to investigate the -results: +results. Start by plotting `Main.LigStudy.Output.Model.Lig.Fin`: ```{image} _static/lesson7/image2.gif :alt: Chart view Model.Lig.Fin @@ -39,6 +39,15 @@ works in the opposite direction of the stretching. Notice that the graph has an initial flat part. This is because force does not build up until the ligament is stretched beyond its slack length, L0. +:::{note} +When running the InverseDynamics operation, you will get the following error +message, which is expected: +``` +WARNING(OBJ.MCH.MUS1): Demo.Ligament.any(53): LigStudy: The muscles in the model are not loaded due to kinetically over-constrained mechanical system. +NOTICE(OBJ1): Demo.Ligament.any(53): LigStudy.InverseDynamics: No muscles or other recruited actuators in the model. +``` +::: + ## Basic Mathematical Behavior It looks like the force development is slightly nonlinear. This would @@ -47,9 +56,8 @@ this case it just shows that the abscissa is not the ligament length but rather an artificial "time" that is proportional to the joint angle. In the Chart View you can plot any output data against each other. Let's -select instead of time the ligament length. Click the "Out" button, and -the field containing the abscissa becomes white. You can now type -"Main.LigStudy.Output.Model.Lig.Pos" in the abscissa field: +select instead of time the ligament length. In the abscissa field write +`Main.LigStudy.Output.Model.Lig.Pos`: ```{image} _static/lesson7/image3.gif :alt: Chart view Model.Lig.Fin 2 @@ -63,18 +71,18 @@ ligament model: ```AnyScriptDoc AnyLigamentModelPol LigModel = { -L0 = 1.30; // Slack length -eps1 = 0.2; // Strain where F1 is valid -F1 = 1000; // Force in the ligament at strain eps1 + L0 = 1.30; // Slack length + eps1 = 0.2; // Strain where F1 is valid + F1 = 1000; // Force in the ligament at strain eps1 }; ``` -As you can see, we have only defined three properties. L0 is the slack -length. The ligament is not stretched until its length goes beyond L0, -so its strain is zero at L0. When the ligament is stretched, it also +As you can see, we have only defined three properties. `L0` is the slack +length. The ligament is not stretched until its length goes beyond `L0`, +so its strain is zero at `L0`. When the ligament is stretched, it also builds up a force. The rate of force development with stretching can be thought of as the stiffness of the ligament, and it is defined as the -pair (eps1,F1), where F1 is the force in the ligament at strain eps1. +pair `(eps1,F1)`, where `F1` is the force in the ligament at strain `eps1`. Why do we choose to work with strain here rather than absolute length change? The reason is that ligaments are rather stiff structures, so small length changes can cause large forces, and it is therefore @@ -102,24 +110,21 @@ the significance of each term. For this reason, the nonlinearity in the model is defined by two parameters with an easier interpretation than the above-mentioned $c_2$ and $c_4$. -These two parameters are named a0 and a1, respectively. The first -parameter, a0, defines the slope of the curve at slack length. If you +These two parameters are named `a0` and `a1`, respectively. The first +parameter, `a0`, defines the slope of the curve at slack length. If you study the curve above, you can see that it has a sharp kink at the slack length. It changes abruptly from zero slope to the nominal slope given -by (eps1,F1). The default value of a0 is 1, and this corresponds to the -slope right after the kink being defined entirely by (eps1,F1). In other -words, the curve is pointing directly at the point (eps1,F1). In fact, -the significance of the a0 is that it interpolates the slope between -zero (for a0 = 0) and the linear slope you see in the curve above for a0 -= 1. Try inserting the following: - -```AnyScriptDoc -AnyLigamentModelPol LigModel = { - L0 = 1.30; // Slack length - eps1 = 0.2; // Strain where F1 is valid - F1 = 1000; // Force in the ligament at strain eps1 - §a0 = 0.0;§ -}; +by `(eps1,F1)`. The default value of `a0` is 1, and this corresponds to the +slope right after the kink being defined entirely by `(eps1,F1)`. In other +words, the curve is pointing directly at the point `(eps1,F1)`. In fact, +the significance of the `a0` is that it interpolates the slope between +zero (for `a0 = 0`) and the linear slope you see in the curve above for `a0 += 1`. Try inserting the following: + +```{literalinclude} Snippets/lesson7/snip.Ligaments.main-1.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` Subsequently reload the model, run InverseDynamics, and plot @@ -133,16 +138,16 @@ the ligament force again. You will see the following: The specification has created a continuous slope of 0 where the curve previously had a kink. Notice that the curve converges back to the -"nominal" slope given by the two points (L0,0) and (eps1,F1) +"nominal" slope given by the two points `(L0,0)` and `(eps1,F1)`. If you try the following: ```AnyScriptDoc AnyLigamentModelPol LigModel = { -L0 = 1.30; // Slack length -eps1 = 0.2; // Strain where F1 is valid -F1 = 1000; // Force in the ligament at strain eps1 -a0 = 0.§5§; + L0 = 1.30; // Slack length + eps1 = 0.2; // Strain where F1 is valid + F1 = 1000; // Force in the ligament at strain eps1 + a0 = 0.§5§; }; ``` @@ -154,20 +159,16 @@ then you get something in between, as the following curve: :width: 90% ``` -The significance of a1 is much the same, except it has its effect at the -point (eps1,F1) rather than at (L0,0). If, for instance you insert +The significance of `a1` is much the same, except it has its effect at the +point `(eps1,F1)` rather than at `(L0,0)`. If, for instance you insert, -```AnyScriptDoc -AnyLigamentModelPol LigModel = { -L0 = 1.30; // Slack length -eps1 = 0.2; // Strain where F1 is valid -F1 = 1000; // Force in the ligament at strain eps1 -a0 = 0.5; -§a1 = 0.0;§ -}; +```{literalinclude} Snippets/lesson7/snip.Ligaments.main-2.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` -then you will get a curve that attains zero slope at (eps1,F1): +then you will get a curve that attains zero slope at `(eps1,F1)`: ```{image} _static/lesson7/image7.png :alt: Model.Lig.Fin zero slope @@ -175,9 +176,9 @@ then you will get a curve that attains zero slope at (eps1,F1): :width: 90% ``` -So, a1 = 0.0 corresponds to zero slope, and the default value of a1 = -1.0 corresponds to the slope given by the values of L0, eps1, and F1. -You can similarly increase the slopes by increasing a1: +So, `a1 = 0.0` corresponds to zero slope, and the default value of `a1 = 1.0` +corresponds to the slope given by the values of `L0`, `eps1`, and `F1`. You can +similarly increase the slopes by increasing `a1`: ```{image} _static/lesson7/image8.png :alt: Model.Lig.Fin plot different slopes @@ -186,26 +187,21 @@ You can similarly increase the slopes by increasing a1: ``` Unlike normal fourth order polynomials, these curves will continue -predictably with no oscillation for as long as desired after (eps1,F1). +predictably with no oscillation for as long as desired after `(eps1,F1)`. The reason for this behavior is the default setting of the parameter ```AnyScriptDoc LinRegionOnOff = On ``` -which causes the curve to continue a linear behavior after (eps1,F1). +which causes the curve to continue a linear behavior after `(eps1,F1)`. You can, however, obtain the clean fourth order polynomial behavior as you like by switching this setting off: -```AnyScriptDoc -AnyLigamentModelPol LigModel = { -L0 = 1.30; // Slack length -eps1 = 0.2; // Strain where F1 is valid -F1 = 1000; // Force in the ligament at strain eps1 -a0 = 0.5; -a1 = 1.0; -§LinRegionOnOff = Off;§ -}; +```{literalinclude} Snippets/lesson7/snip.Ligaments.main-3.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` ```{image} _static/lesson7/image9.png @@ -214,12 +210,12 @@ a1 = 1.0; :width: 65% ``` -Clearly, this causes the curve to diverge after (eps1,F1), which is +Clearly, this causes the curve to diverge after `(eps1,F1)`, which is typical for higher order polynomials. Unless you have some special reason to prefer the pure fourth-order behavior, we recommend that you leave -LinRegionOnOff = On. +`LinRegionOnOff = On`. -### Calibration +## Calibration Most ligaments in the body are rather stiff structures in which the force builds up quickly when they are stretched beyond the slack length. @@ -231,28 +227,20 @@ The easiest way to determine ligament slack lengths is by means of joint angles. For most joints where ligaments play an important role, it is obvious in which position of the joint the ligament becomes taut. Therefore, ligaments are calibrated just like muscles by positioning the -joints in question and letting the system automatically change L0 of +joints in question and letting the system automatically change `L0` of each ligament to the length in that position. Lets try to calibrate our ligament. The first thing we must do is to -create a Calibration Study: +create a Calibration Studybelow our AnyBodyStudy LigStudy: -```AnyScriptDoc -§AnyBodyCalibrationStudy LigCali = { - AnyFolder &Model = .LigModel; - nStep = 1; - - // This driver puts the joint into the calibration position - AnyKinEqSimpleDriver Position = { - DriverPos = {-pi/4}; - DriverVel = {0.0}; - AnyRevoluteJoint &Jnt = Main.LigModel.Joint; - }; -};§ +```{literalinclude} Snippets/lesson7/snip.Ligaments.main-3.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 2 +:end-before: //# END SNIPPET 2 ``` Notice the driver in the study. It positions the joint at the angle of --pi/4. This becomes the position in which the ligament has its slack +$-pi/4$. This becomes the position in which the ligament has its slack length. Try loading the model and then browse your way through the tree to the L0 property of the ligament model: @@ -271,7 +259,7 @@ Now, run the `LigCali.LigamentLengthAdjustment` operation, and subsequently double-click the L0 property again. Now you will see a value of `Main.LigModel.LigModel.L0 = 1.573132`. The system has extended the ligament length a bit to fit the joint angle -of -pi/4. Run the InverseDynamics study again, and see the +of $-pi/4$. Run the InverseDynamics study again, and see the influence of the increased slack length: ```{image} _static/lesson7/image11.png