diff --git a/A_Getting_started/intro.md b/A_Getting_started/intro.md index 1cfefc0b..f99a58d4 100644 --- a/A_Getting_started/intro.md +++ b/A_Getting_started/intro.md @@ -21,7 +21,7 @@ the model view window This tutorial relies heavily on using the AnyBody Managed Model Repository (AMMR). Follow the steps below to unpack a local version of the AMMR. -# Setup the AMMR +## Setup the AMMR Before you continue, you must unpack the entire repository and save it on your hard disk. To get a copy of the AMMR, press the Demo tab in the AnyBody @@ -34,7 +34,7 @@ your documents folder by default. It is good practice to create a second local copy of the AMMR so that you do not overwrite the original AMMR folder by accident. -# AMMR structure +## AMMR structure Open a file manager and navigate to the directory where you unpacked the repository. You should see a folder structure that includes the following diff --git a/A_Getting_started_anyscript/Downloads/demo.arm2d.any b/A_Getting_started_anyscript/Downloads/demo.arm2d.any index 25c07e82..3a245978 100644 --- a/A_Getting_started_anyscript/Downloads/demo.arm2d.any +++ b/A_Getting_started_anyscript/Downloads/demo.arm2d.any @@ -123,17 +123,18 @@ Main = { AnyFolder Drivers = { //--------------------------------- - AnyKinEqSimpleDriver ShoulderMotion = { + AnyKinDriver ShoulderMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; - DriverPos = {-100*pi/180}; - DriverVel = {30*pi/180}; + DriverPos0 = {-100*pi/180}; + DriverVel0 = {30*pi/180}; Reaction.Type = {Off}; }; // Shoulder driver + //--------------------------------- - AnyKinEqSimpleDriver ElbowMotion = { + AnyKinDriver ElbowMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Elbow; - DriverPos = {90*pi/180}; - DriverVel = {45*pi/180}; + DriverPos0 = {90*pi/180}; + DriverVel0 = {45*pi/180}; Reaction.Type = {Off}; }; // Elbow driver }; // Driver folder diff --git a/A_Getting_started_anyscript/Downloads/demo.arm2d.zip b/A_Getting_started_anyscript/Downloads/demo.arm2d.zip index 8d8e2e8f..a83186fb 100644 Binary files a/A_Getting_started_anyscript/Downloads/demo.arm2d.zip and b/A_Getting_started_anyscript/Downloads/demo.arm2d.zip differ diff --git a/A_Getting_started_anyscript/Downloads/demo.lesson2.any b/A_Getting_started_anyscript/Downloads/demo.lesson2.any index c06ae363..f740143a 100644 --- a/A_Getting_started_anyscript/Downloads/demo.lesson2.any +++ b/A_Getting_started_anyscript/Downloads/demo.lesson2.any @@ -1,4 +1,4 @@ - // Todo: Write a small description of your model here +// Todo: Write a small description of your model here Main = { // The actual body model goes in this folder @@ -15,6 +15,7 @@ Main = { // segments, joints, and muscles here. }; + // The study: Operations to be performed on the model AnyBodyStudy ArmStudy = { AnyFolder &Model = .ArmModel; diff --git a/A_Getting_started_anyscript/Downloads/demo.lesson5.any b/A_Getting_started_anyscript/Downloads/demo.lesson5.any index 891e8e13..d3472f54 100644 --- a/A_Getting_started_anyscript/Downloads/demo.lesson5.any +++ b/A_Getting_started_anyscript/Downloads/demo.lesson5.any @@ -114,22 +114,21 @@ Main = { AnyFolder Drivers = { //--------------------------------- - AnyKinEqSimpleDriver ShoulderMotion = { + AnyKinDriver ShoulderMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; - DriverPos = {-100*pi/180}; - DriverVel = {30*pi/180}; + DriverPos0 = {-100*pi/180}; + DriverVel0 = {30*pi/180}; }; // Shoulder driver //--------------------------------- - AnyKinEqSimpleDriver ElbowMotion = { + AnyKinDriver ElbowMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Elbow; - DriverPos = {90*pi/180}; - DriverVel = {45*pi/180}; - }; // Elbow driver + DriverPos0 = {90*pi/180}; + DriverVel0 = {45*pi/180}; + }; // Elbow driver }; // Driver folder - - }; // The study: Operations to be performed on the model - // ArmModel - + }; // MyModel + + // The study: Operations to be performed on the model AnyBodyStudy ArmStudy = { AnyFolder &Model = .ArmModel; Gravity = {0.0, -9.81, 0.0}; diff --git a/A_Getting_started_anyscript/Downloads/demo.lesson6.any b/A_Getting_started_anyscript/Downloads/demo.lesson6.any index 4f21159d..c0a3a2f3 100644 --- a/A_Getting_started_anyscript/Downloads/demo.lesson6.any +++ b/A_Getting_started_anyscript/Downloads/demo.lesson6.any @@ -117,21 +117,21 @@ Main = { AnyFolder Drivers = { //--------------------------------- - AnyKinEqSimpleDriver ShoulderMotion = { + AnyKinDriver ShoulderMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; - DriverPos = {-100*pi/180}; - DriverVel = {30*pi/180}; + DriverPos0 = {-100*pi/180}; + DriverVel0 = {30*pi/180}; Reaction.Type = {Off}; }; // Shoulder driver //--------------------------------- - AnyKinEqSimpleDriver ElbowMotion = { + AnyKinDriver ElbowMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Elbow; - DriverPos = {90*pi/180}; - DriverVel = {45*pi/180}; + DriverPos0 = {90*pi/180}; + DriverVel0 = {45*pi/180}; Reaction.Type = {Off}; - }; // Elbow driver + }; // Elbow driver }; // Driver folder - + AnyFolder Muscles = { // Simple muscle model with constant strength = 400 Newton AnyMuscleModel MusMdl = { diff --git a/A_Getting_started_anyscript/Snippets/lesson1/snip.NewModel.main-1.any b/A_Getting_started_anyscript/Snippets/lesson1/snip.NewModel.main-1.any index 48bb4c75..8cd0a1c2 100644 --- a/A_Getting_started_anyscript/Snippets/lesson1/snip.NewModel.main-1.any +++ b/A_Getting_started_anyscript/Snippets/lesson1/snip.NewModel.main-1.any @@ -16,11 +16,10 @@ AnyFolder §ArmModel§ = { // segments, joints, and muscles here. }; +// The study: Operations to be performed on the model +AnyBodyStudy §ArmStudy§ = { + AnyFolder &Model = .§ArmModel§; + Gravity = {0.0, -9.81, 0.0}; +}; //# END SNIPPET 1 - // The study: Operations to be performed on the model - AnyBodyStudy ArmStudy = { - AnyFolder &Model = .ArmModel; - Gravity = {0.0, -9.81, 0.0}; - }; - }; \ No newline at end of file diff --git a/A_Getting_started_anyscript/Snippets/lesson2/snip.NewModel.main-3.any b/A_Getting_started_anyscript/Snippets/lesson2/snip.NewModel.main-3.any index d8ed2799..c4dbffd3 100644 --- a/A_Getting_started_anyscript/Snippets/lesson2/snip.NewModel.main-3.any +++ b/A_Getting_started_anyscript/Snippets/lesson2/snip.NewModel.main-3.any @@ -11,16 +11,16 @@ AnyFolder ArmModel = { // Segments - AnyFolder Segs = { - //# BEGIN SNIPPET 1 -AnySeg §UpperArm§ = { - //r0 = {0.0, 0.0, 0.0}; - //Axes0 = {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}}; - Mass = §2§; - Jii = {§0.001, 0.01, 0.01§}; -}; §//UpperArm§ - //# END SNIPPET 1 - }; // Segs folder +//# BEGIN SNIPPET 1 +AnyFolder Segs = { + AnySeg §UpperArm§ = { + //r0 = {0.0, 0.0, 0.0}; + //Axes0 = {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}}; + Mass = §2§; + Jii = {§0.001, 0.01, 0.01§}; + }; §//UpperArm§ +}; // Segs folder +//# END SNIPPET 1 }; // The study: Operations to be performed on the model diff --git a/A_Getting_started_anyscript/Snippets/lesson4/snip.NewModel.main-1.any b/A_Getting_started_anyscript/Snippets/lesson4/snip.NewModel.main-1.any index c6f731ea..bebe9eec 100644 --- a/A_Getting_started_anyscript/Snippets/lesson4/snip.NewModel.main-1.any +++ b/A_Getting_started_anyscript/Snippets/lesson4/snip.NewModel.main-1.any @@ -116,18 +116,18 @@ Main = { §AnyFolder Drivers = { //--------------------------------- - AnyKinEqSimpleDriver ShoulderMotion = { + AnyKinDriver ShoulderMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; - DriverPos = {-100*pi/180}; - DriverVel = {30*pi/180}; + DriverPos0 = {-100*pi/180}; + DriverVel0 = {30*pi/180}; }; // Shoulder driver //--------------------------------- - AnyKinEqSimpleDriver ElbowMotion = { + AnyKinDriver ElbowMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Elbow; - DriverPos = {90*pi/180}; - DriverVel = {45*pi/180}; - }; // Elbow driver + DriverPos0 = {90*pi/180}; + DriverVel0 = {45*pi/180}; + }; // Elbow driver }; // Driver folder§ //# END SNIPPET 1 diff --git a/A_Getting_started_anyscript/Snippets/lesson4/snip.NewModel.main-2.any b/A_Getting_started_anyscript/Snippets/lesson4/snip.NewModel.main-2.any index 71dcdc22..9666ee5d 100644 --- a/A_Getting_started_anyscript/Snippets/lesson4/snip.NewModel.main-2.any +++ b/A_Getting_started_anyscript/Snippets/lesson4/snip.NewModel.main-2.any @@ -114,21 +114,21 @@ Main = { AnyFolder Drivers = { //--------------------------------- - AnyKinEqSimpleDriver ShoulderMotion = { + AnyKinDriver ShoulderMotion = { //# BEGIN SNIPPET 1 AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; //# END SNIPPET 1 - DriverPos = {-100*pi/180}; - DriverVel = {30*pi/180}; + DriverPos0 = {-100*pi/180}; + DriverVel0 = {30*pi/180}; }; // Shoulder driver //--------------------------------- - AnyKinEqSimpleDriver ElbowMotion = { + AnyKinDriver ElbowMotion = { //# BEGIN SNIPPET 2 AnyRevoluteJoint &Jnt = ..Jnts.Elbow; //# END SNIPPET 2 - DriverPos = {90*pi/180}; - DriverVel = {45*pi/180}; - }; // Elbow driver + DriverPos0 = {90*pi/180}; + DriverVel0 = {45*pi/180}; + }; // Elbow driver }; // Driver folder }; // The study: Operations to be performed on the model diff --git a/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-1.any b/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-1.any index 9bfd4525..9af7f8a4 100644 --- a/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-1.any +++ b/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-1.any @@ -114,17 +114,17 @@ Main = { AnyFolder Drivers = { //--------------------------------- - AnyKinEqSimpleDriver ShoulderMotion = { + AnyKinDriver ShoulderMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; - DriverPos = {-100*pi/180}; - DriverVel = {30*pi/180}; + DriverPos0 = {-100*pi/180}; + DriverVel0 = {30*pi/180}; }; // Shoulder driver //--------------------------------- - AnyKinEqSimpleDriver ElbowMotion = { + AnyKinDriver ElbowMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Elbow; - DriverPos = {90*pi/180}; - DriverVel = {45*pi/180}; - }; // Elbow driver + DriverPos0 = {90*pi/180}; + DriverVel0 = {45*pi/180}; + }; // Elbow driver //# BEGIN SNIPPET 1 }; // Driver folder diff --git a/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-2.any b/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-2.any index 72434c2b..aa4b08c3 100644 --- a/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-2.any +++ b/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-2.any @@ -114,17 +114,18 @@ Main = { AnyFolder Drivers = { //--------------------------------- - AnyKinEqSimpleDriver ShoulderMotion = { + AnyKinDriver ShoulderMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; - DriverPos = {-100*pi/180}; - DriverVel = {30*pi/180}; + DriverPos0 = {-100*pi/180}; + DriverVel0 = {30*pi/180}; }; // Shoulder driver //--------------------------------- - AnyKinEqSimpleDriver ElbowMotion = { + AnyKinDriver ElbowMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Elbow; - DriverPos = {90*pi/180}; - DriverVel = {45*pi/180}; - }; // Elbow driver + DriverPos0 = {90*pi/180}; + DriverVel0 = {45*pi/180}; + }; // Elbow driver + //# BEGIN SNIPPET 1 }; // Driver folder diff --git a/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-3.any b/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-3.any index 91d3191c..8a303812 100644 --- a/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-3.any +++ b/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-3.any @@ -114,17 +114,17 @@ Main = { AnyFolder Drivers = { //--------------------------------- - AnyKinEqSimpleDriver ShoulderMotion = { + AnyKinDriver ShoulderMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; - DriverPos = {-100*pi/180}; - DriverVel = {30*pi/180}; + DriverPos0 = {-100*pi/180}; + DriverVel0 = {30*pi/180}; }; // Shoulder driver //--------------------------------- - AnyKinEqSimpleDriver ElbowMotion = { + AnyKinDriver ElbowMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Elbow; - DriverPos = {90*pi/180}; - DriverVel = {45*pi/180}; - }; // Elbow driver + DriverPos0 = {90*pi/180}; + DriverVel0 = {45*pi/180}; + }; // Elbow driver }; // Driver folder //# BEGIN SNIPPET 1 diff --git a/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-4.any b/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-4.any index 5830b60a..4f7b55de 100644 --- a/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-4.any +++ b/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-4.any @@ -114,17 +114,17 @@ Main = { AnyFolder Drivers = { //--------------------------------- - AnyKinEqSimpleDriver ShoulderMotion = { + AnyKinDriver ShoulderMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; - DriverPos = {-100*pi/180}; - DriverVel = {30*pi/180}; + DriverPos0 = {-100*pi/180}; + DriverVel0 = {30*pi/180}; }; // Shoulder driver //--------------------------------- - AnyKinEqSimpleDriver ElbowMotion = { + AnyKinDriver ElbowMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Elbow; - DriverPos = {90*pi/180}; - DriverVel = {45*pi/180}; - }; // Elbow driver + DriverPos0 = {90*pi/180}; + DriverVel0 = {45*pi/180}; + }; // Elbow driver }; // Driver folder AnyFolder Muscles = { diff --git a/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-5.any b/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-5.any index de8524a2..85a83a76 100644 --- a/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-5.any +++ b/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-5.any @@ -114,17 +114,17 @@ Main = { AnyFolder Drivers = { //--------------------------------- - AnyKinEqSimpleDriver ShoulderMotion = { + AnyKinDriver ShoulderMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; - DriverPos = {-100*pi/180}; - DriverVel = {30*pi/180}; + DriverPos0 = {-100*pi/180}; + DriverVel0 = {30*pi/180}; }; // Shoulder driver //--------------------------------- - AnyKinEqSimpleDriver ElbowMotion = { + AnyKinDriver ElbowMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Elbow; - DriverPos = {90*pi/180}; - DriverVel = {45*pi/180}; - }; // Elbow driver + DriverPos0 = {90*pi/180}; + DriverVel0 = {45*pi/180}; + }; // Elbow driver }; // Driver folder AnyFolder Muscles = { diff --git a/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-6.any b/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-6.any index 15448de6..af8622d8 100644 --- a/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-6.any +++ b/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-6.any @@ -93,7 +93,14 @@ Main = { AnyRefNode Triceps = { sRel = {-0.25,0,-0.05}; }; - }; // ForeArm + AnyDrawSeg DrwSeg = {}; +//# BEGIN SNIPPET 2 + §AnyRefNode PalmNode = { + sRel = {0.27,0,0}; + };§ +}; // ForeArm +//# END SNIPPET 2 + }; // Segs folder // Joints @@ -112,20 +119,21 @@ Main = { }; // Elbow joint }; // Jnts folder - AnyFolder Drivers = { - //--------------------------------- //# BEGIN SNIPPET 1 - AnyKinEqSimpleDriver ShoulderMotion = { +AnyFolder Drivers = { + //--------------------------------- + AnyKinDriver ShoulderMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; - DriverPos = {-100*pi/180}; - DriverVel = {30*pi/180}; + DriverPos0 = {-100*pi/180}; + DriverVel0 = {30*pi/180}; §Reaction.Type = {Off};§ }; // Shoulder driver + //--------------------------------- - AnyKinEqSimpleDriver ElbowMotion = { + AnyKinDriver ElbowMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Elbow; - DriverPos = {90*pi/180}; - DriverVel = {45*pi/180}; + DriverPos0 = {90*pi/180}; + DriverVel0 = {45*pi/180}; §Reaction.Type = {Off};§ }; // Elbow driver }; // Driver folder @@ -200,11 +208,21 @@ Main = { AnyRefNode &Ins = ..Segs.ForeArm.Triceps; viewMuscle.Visible = On; }; - }; // Muscles folder - }; // The study: Operations to be performed on the model - // ArmModel +//# BEGIN SNIPPET 3 + }; // Muscles folder + §AnyFolder Loads = { + //--------------------------------- + AnyForce3D Dumbbell = { + AnyRefNode &PalmNode = ..Segs.ForeArm.PalmNode; + F = {0,-100,0}; // Force in Newton + }; + }; // Loads folder§ +}; // ArmModel +//# END SNIPPET 3 + + // The study: Operations to be performed on the model AnyBodyStudy ArmStudy = { AnyFolder &Model = .ArmModel; Gravity = {0.0, -9.81, 0.0}; diff --git a/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-7.any b/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-7.any index ba84cbe1..47c49666 100644 --- a/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-7.any +++ b/A_Getting_started_anyscript/Snippets/lesson5/snip.NewModel.main-7.any @@ -90,15 +90,12 @@ Main = { AnyRefNode Biceps = { sRel = {-0.15,0,0.01}; }; -//# BEGIN SNIPPET 1 - AnyRefNode Triceps = { - sRel = {-0.25,0,-0.05}; - }; - §AnyRefNode PalmNode = { - sRel = {0.27,0,0}; - };§ -}; // ForeArm -//# END SNIPPET 1 + AnyRefNode Triceps = { + sRel = {-0.25,0,-0.05}; + }; + AnyDrawSeg DrwSeg = {}; + }; // ForeArm + }; // Segs folder // Joints @@ -116,24 +113,23 @@ Main = { AnyRefNode &ForeArmNode = Main.ArmModel.Segs.ForeArm.ElbowNode; }; // Elbow joint }; // Jnts folder +//# BEGIN SNIPPET 1 +AnyFolder Drivers = { + //--------------------------------- + §AnyKinMotion§ ShoulderMotion = { + AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; + DriverPos0 = {-100*pi/180}; + DriverVel0 = {30*pi/180}; + }; // Shoulder driver - AnyFolder Drivers = { - //--------------------------------- - AnyKinEqSimpleDriver ShoulderMotion = { - AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; - DriverPos = {-100*pi/180}; - DriverVel = {30*pi/180}; - Reaction.Type = {Off}; - }; // Shoulder driver - //--------------------------------- - AnyKinEqSimpleDriver ElbowMotion = { - AnyRevoluteJoint &Jnt = ..Jnts.Elbow; - DriverPos = {90*pi/180}; - DriverVel = {45*pi/180}; - Reaction.Type = {Off}; - }; // Elbow driver - }; // Driver folder - + //--------------------------------- + §AnyKinMotion§ ElbowMotion = { + AnyRevoluteJoint &Jnt = ..Jnts.Elbow; + DriverPos0 = {90*pi/180}; + DriverVel0 = {45*pi/180}; + }; // Elbow driver +}; // Driver folder +//# END SNIPPET 1 AnyFolder Muscles = { // Simple muscle model with constant strength = 400 Newton AnyMuscleModel MusMdl = { @@ -203,19 +199,9 @@ Main = { AnyRefNode &Ins = ..Segs.ForeArm.Triceps; viewMuscle.Visible = On; }; -//# BEGIN SNIPPET 2 - }; // Muscles folder + }; // Muscles folder + }; // MyModel - §AnyFolder Loads = { - //--------------------------------- - AnyForce3D Dumbbell = { - AnyRefNode &PalmNode = ..Segs.ForeArm.PalmNode; - F = {0,-100,0}; // Force in Newton - }; - }; // Loads folder§ - -};// ArmModel -//# END SNIPPET 2 // The study: Operations to be performed on the model AnyBodyStudy ArmStudy = { diff --git a/A_Getting_started_anyscript/Snippets/lesson6/snip.NewModel.main-1.any b/A_Getting_started_anyscript/Snippets/lesson6/snip.NewModel.main-1.any index e374b686..cff39146 100644 --- a/A_Getting_started_anyscript/Snippets/lesson6/snip.NewModel.main-1.any +++ b/A_Getting_started_anyscript/Snippets/lesson6/snip.NewModel.main-1.any @@ -122,17 +122,19 @@ Main = { AnyFolder Drivers = { //--------------------------------- - AnyKinEqSimpleDriver ShoulderMotion = { + + AnyKinDriver ShoulderMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; - DriverPos = {-100*pi/180}; - DriverVel = {30*pi/180}; + DriverPos0 = {-100*pi/180}; + DriverVel0 = {30*pi/180}; Reaction.Type = {Off}; }; // Shoulder driver + //--------------------------------- - AnyKinEqSimpleDriver ElbowMotion = { + AnyKinDriver ElbowMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Elbow; - DriverPos = {90*pi/180}; - DriverVel = {45*pi/180}; + DriverPos0 = {90*pi/180}; + DriverVel0 = {45*pi/180}; Reaction.Type = {Off}; }; // Elbow driver }; // Driver folder diff --git a/A_Getting_started_anyscript/Snippets/lesson6/snip.NewModel.main-2.any b/A_Getting_started_anyscript/Snippets/lesson6/snip.NewModel.main-2.any index 0b98930e..3cc9cf34 100644 --- a/A_Getting_started_anyscript/Snippets/lesson6/snip.NewModel.main-2.any +++ b/A_Getting_started_anyscript/Snippets/lesson6/snip.NewModel.main-2.any @@ -123,17 +123,19 @@ AnyDrawSTL DrwSTL = { AnyFolder Drivers = { //--------------------------------- - AnyKinEqSimpleDriver ShoulderMotion = { + + AnyKinDriver ShoulderMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; - DriverPos = {-100*pi/180}; - DriverVel = {30*pi/180}; + DriverPos0 = {-100*pi/180}; + DriverVel0 = {30*pi/180}; Reaction.Type = {Off}; }; // Shoulder driver + //--------------------------------- - AnyKinEqSimpleDriver ElbowMotion = { + AnyKinDriver ElbowMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Elbow; - DriverPos = {90*pi/180}; - DriverVel = {45*pi/180}; + DriverPos0 = {90*pi/180}; + DriverVel0 = {45*pi/180}; Reaction.Type = {Off}; }; // Elbow driver }; // Driver folder diff --git a/A_Getting_started_anyscript/Snippets/lesson6/snip.NewModel.main-3.any b/A_Getting_started_anyscript/Snippets/lesson6/snip.NewModel.main-3.any index 653f264d..77c9b4c8 100644 --- a/A_Getting_started_anyscript/Snippets/lesson6/snip.NewModel.main-3.any +++ b/A_Getting_started_anyscript/Snippets/lesson6/snip.NewModel.main-3.any @@ -123,17 +123,19 @@ Main = { AnyFolder Drivers = { //--------------------------------- - AnyKinEqSimpleDriver ShoulderMotion = { + + AnyKinDriver ShoulderMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; - DriverPos = {-100*pi/180}; - DriverVel = {30*pi/180}; + DriverPos0 = {-100*pi/180}; + DriverVel0 = {30*pi/180}; Reaction.Type = {Off}; }; // Shoulder driver + //--------------------------------- - AnyKinEqSimpleDriver ElbowMotion = { + AnyKinDriver ElbowMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Elbow; - DriverPos = {90*pi/180}; - DriverVel = {45*pi/180}; + DriverPos0 = {90*pi/180}; + DriverVel0 = {45*pi/180}; Reaction.Type = {Off}; }; // Elbow driver }; // Driver folder diff --git a/A_Getting_started_anyscript/Snippets/lesson6/snip.NewModel.main-4.any b/A_Getting_started_anyscript/Snippets/lesson6/snip.NewModel.main-4.any index 272b7580..14dd9c52 100644 --- a/A_Getting_started_anyscript/Snippets/lesson6/snip.NewModel.main-4.any +++ b/A_Getting_started_anyscript/Snippets/lesson6/snip.NewModel.main-4.any @@ -124,17 +124,19 @@ AnyRefNode PalmNode = { AnyFolder Drivers = { //--------------------------------- - AnyKinEqSimpleDriver ShoulderMotion = { + + AnyKinDriver ShoulderMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; - DriverPos = {-100*pi/180}; - DriverVel = {30*pi/180}; + DriverPos0 = {-100*pi/180}; + DriverVel0 = {30*pi/180}; Reaction.Type = {Off}; }; // Shoulder driver + //--------------------------------- - AnyKinEqSimpleDriver ElbowMotion = { + AnyKinDriver ElbowMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Elbow; - DriverPos = {90*pi/180}; - DriverVel = {45*pi/180}; + DriverPos0 = {90*pi/180}; + DriverVel0 = {45*pi/180}; Reaction.Type = {Off}; }; // Elbow driver }; // Driver folder diff --git a/A_Getting_started_anyscript/Snippets/lesson6/snip.NewModel.main-5.any b/A_Getting_started_anyscript/Snippets/lesson6/snip.NewModel.main-5.any index 62b92796..37170e18 100644 --- a/A_Getting_started_anyscript/Snippets/lesson6/snip.NewModel.main-5.any +++ b/A_Getting_started_anyscript/Snippets/lesson6/snip.NewModel.main-5.any @@ -125,17 +125,19 @@ AnyDrawSTL DrwSTL = { AnyFolder Drivers = { //--------------------------------- - AnyKinEqSimpleDriver ShoulderMotion = { + + AnyKinDriver ShoulderMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; - DriverPos = {-100*pi/180}; - DriverVel = {30*pi/180}; + DriverPos0 = {-100*pi/180}; + DriverVel0 = {30*pi/180}; Reaction.Type = {Off}; }; // Shoulder driver + //--------------------------------- - AnyKinEqSimpleDriver ElbowMotion = { + AnyKinDriver ElbowMotion = { AnyRevoluteJoint &Jnt = ..Jnts.Elbow; - DriverPos = {90*pi/180}; - DriverVel = {45*pi/180}; + DriverPos0 = {90*pi/180}; + DriverVel0 = {45*pi/180}; Reaction.Type = {Off}; }; // Elbow driver }; // Driver folder diff --git a/A_Getting_started_anyscript/_static/lesson4/image6.png b/A_Getting_started_anyscript/_static/lesson4/image6.png index c9594d28..d98b9b91 100644 Binary files a/A_Getting_started_anyscript/_static/lesson4/image6.png and b/A_Getting_started_anyscript/_static/lesson4/image6.png differ diff --git a/A_Getting_started_anyscript/lesson1.md b/A_Getting_started_anyscript/lesson1.md index 5ca73f47..667c0388 100644 --- a/A_Getting_started_anyscript/lesson1.md +++ b/A_Getting_started_anyscript/lesson1.md @@ -71,7 +71,7 @@ with the class type, followed by a chosen object name, and then assign it a value. The value can be a number, a string, or another object. ` = ;`. -**👉 Now** reename `MyStudy` to `ArmModelStudy`, and replace all occurences of +**👉 Now** rename `MyStudy` to `ArmModelStudy`, and replace all occurences of `MyModel` with `ArmModel`. :::{attention} diff --git a/A_Getting_started_anyscript/lesson2.md b/A_Getting_started_anyscript/lesson2.md index b820f8c7..942cdfe8 100644 --- a/A_Getting_started_anyscript/lesson2.md +++ b/A_Getting_started_anyscript/lesson2.md @@ -176,6 +176,7 @@ initial guess, on the way to enforcing specified motions and constraints (such as joints between segments). More on this in the next lesson. For now, let us first change `r0` - the global position of the segment at load-time. +First for the "UpperArm": ```{literalinclude} Snippets/lesson2/snip.NewModel.main-7.any :language: AnyScriptDoc @@ -183,7 +184,7 @@ For now, let us first change `r0` - the global position of the segment at load-t :end-before: //# END SNIPPET 1 ``` -and +and then the "ForeArm": ```{literalinclude} Snippets/lesson2/snip.NewModel.main-7.any :language: AnyScriptDoc diff --git a/A_Getting_started_anyscript/lesson3.md b/A_Getting_started_anyscript/lesson3.md index 6a9d6826..4ab6739b 100644 --- a/A_Getting_started_anyscript/lesson3.md +++ b/A_Getting_started_anyscript/lesson3.md @@ -124,8 +124,8 @@ refer to the point as "GroundNode" instead of the longer external reference. **You will also realize that `GroundNode` is merely a reference (a pointer) to `GlobalRef.Shoulder` rather than a copy of it. We denote this by the** {literal}`&` **sign.** -If "Main.ArmModel.GlobalRef.Shoulder" moves around, -"Main.ArmModel.Jnts.Shoulder.GroundNode" will keep up with those changes in +If `Main.ArmModel.GlobalRef.Shoulder` moves around, +`Main.ArmModel.Jnts.Shoulder.GroundNode` will keep up with those changes in position. Hit F7 to reload the model again to make sure that the definition is correct. @@ -213,8 +213,7 @@ It seems like everything is connected now, but we still get this annoying error message when we reload the model: ```none -Model Warning: Study 'Main.ArmStudy' contains too few kinematic -constraints to be kinematically determinate. +Model Warning: Study 'Main.ArmStudy' contains too few kinematic constraints to be kinematically determinate. ``` The explanation is that we have created joints, but we have not diff --git a/A_Getting_started_anyscript/lesson4.md b/A_Getting_started_anyscript/lesson4.md index cc52f5a3..20f99268 100644 --- a/A_Getting_started_anyscript/lesson4.md +++ b/A_Getting_started_anyscript/lesson4.md @@ -29,20 +29,26 @@ the values of muscle forces which produce the motion. ## Measures & drivers -We need to specify the motion for two degrees of freedom (DOF) of our arm mechanism, because it has hinge joints at the -shoulder and at the elbow. +We need to specify the motion for two degrees of freedom (DOF) of our arm +mechanism, because it has hinge joints at the shoulder and at the elbow. -- **Measures** are AnyBody objects which literally measure the value of a user-specified DOF within the model. -- **Drivers** are AnyBody objects which constrain the value of a measure to a constant value or a mathematical function of time. Drivers essentially assemble and impart motion to your mechanisms. +- **Measures** are AnyBody objects which literally measure the value of a + user-specified DOF within the model. +- **Drivers** are AnyBody objects which constrain the value of a measure to a + constant value or a mathematical function of time. Drivers essentially + assemble and impart motion to your mechanisms. -In this model, we therefore need two drivers, to specify motions for the two DOF. We therefore also need two measures, -which we will chose to be measures of the shoulder and elbow joint angle values. +In this model, we therefore need two drivers, to specify motions for the two +DOF. We therefore also need two measures, which we will chose to be measures of +the shoulder and elbow joint angle values. :::{note} -**It is only important that the constrained measures represent independent DOFs of the model. The exact measures themselves are your choice**. +It is only important that the constrained measures represent independent DOFs +of the model. The exact measures themselves are your choice -Eg: For this arm model with 2 remaining DOFs, we can either apply motion drivers to the shoulder (1 DOF) and elbow joints (+1 DOF) OR the X (1 DOF) and Y (+1 DOF) coordinates -of the end-point of the ForeArm segment (the wrist). +Eg: For this arm model with 2 remaining DOFs, we can either apply motion drivers +to the shoulder (1 DOF) and elbow joints (+1 DOF) OR the X (1 DOF) and Y (+1 +DOF) coordinates of the end-point of the ForeArm segment (the wrist). Creating more than 2 driver constraints will over-constrain the model and lead to errors. ::: @@ -59,19 +65,24 @@ Let's create a new folder and define two drivers: :end-before: //# END SNIPPET 1 ``` -The folder contains two objects named `ShoulderMotion` and `ElbowMotion`, belonging to the -`AnyKinEqSimpleDriver` class. +The folder contains two objects named `ShoulderMotion` and `ElbowMotion`, +belonging to the `AnyKinDriver ` class. -**All AnyBody drivers only work on the measures that are supplied to them. The** `AnyKinEqSimpleDriver` **class used in this case, constrains -the supplied measure's positions to a given value at time = 0 (`DriverPos`) and changes this position at constant velocity thereon (`DriverVel`).** +**All AnyBody drivers only work on the measures that are supplied to them**. The +`AnyKinDriver` class used in this case, constrains the supplied +measure's positions to a given value at time = 0 (`DriverPos0`) and changes this +position at constant velocity thereon (`DriverVel0`). -Since the measures supplied to the above drivers are rotational joints, the drivers produce joint rotation. -But the same driver class could be used to drive translations, for instance a sliding joint. +Since the measures supplied to the above drivers are rotational joints, the +drivers produce joint rotation. But the same driver class could be used to drive +translations, for instance a sliding joint. -The following lines assign the shoulder and elbow joint angle measures to the respective drivers. -Standard AnyBody joints created using classes such as `AnyRevoluteJoint`, `AnySphericalJoint` etc. automatically function as measures. -More customized measures can be created using classes such as `AnyKinLinear`, `AnyKinRotational` etc. -(see {doc}`this lesson <../The_mechanical_elements/lesson4>`).: +The following lines assign the shoulder and elbow joint angle measures to the +respective drivers. Standard AnyBody joints created using classes such as +`AnyRevoluteJoint`, `AnySphericalJoint` etc. automatically function as measures. +More customized measures can be created using classes such as `AnyKinLinear`, +`AnyKinRotational` etc. (see +{doc}`this lesson<../The_mechanical_elements/lesson4>`).: ```{literalinclude} Snippets/lesson4/snip.NewModel.main-2.any :language: AnyScriptDoc @@ -87,40 +98,45 @@ and :end-before: //# END SNIPPET 2 ``` -Since the measures constrained by these drivers are angles, the units -of `DriverPos` and `DriverVel` are radians and radians/sec respectively. +Since the measures constrained by these drivers are angles, the units of +`DriverPos0` and `DriverVel0` are radians and radians/sec respectively. -Just like in {ref}`Lesson 3 `, these lines also -use the reference operator `&` to point the local variable `Jnt` towards the -actual shoulder/elbow joint objects existing in a different folder +Just like in {ref}`Lesson 3 `, these lines also use the +reference operator `&` to point the local variable `Jnt` towards the actual +shoulder/elbow joint objects existing in a different folder -Since `Jnt` is a reference, it will automatically update as the joint angles change during motion. +Since `Jnt` is a reference, it will automatically update as the joint angles +change during motion. ## Running a kinematic simulation -Re-load the model by hitting F7, and you should see the message "Loaded successfully" with NO -warning messages about the lack of kinematic constraints. You're now ready to get this model moving. +Re-load the model by hitting F7, and you should see the message "Loaded +successfully" with NO warning messages about the lack of kinematic constraints. +You're now ready to get this model moving. :::{note} -The object named "ArmModelStudy" (of `AnyBodyStudy` class) creates simulations to run your model through. "ArmModelStudy" -contains a reference object (created with a `&`) pointing to the "ArmModel" folder. +The object named "ArmModelStudy" (of `AnyBodyStudy` class) creates simulations +to run your model through. "ArmModelStudy" contains a reference object (created +with a `&`) pointing to the "ArmModel" folder. -This allows you to create -multiple `AnyBodyStudy` objects, each of which contains a reference to same mechanical model, and a second reference object pointing to a folder with motion drivers, -that are specific to that study. +This allows you to create multiple `AnyBodyStudy` objects, each of which +contains a reference to same mechanical model, and a second reference object +pointing to a folder with motion drivers, that are specific to that study. ::: -**You must now run the "Main.ArmModelStudy.Kinematics" operation. If you need to refer back to how this is done, look at** -{ref}`this prior tutorial `. +You must now run the **"ArmStudy.Kinematics"** operation. If you need to +refer back to how this is done, look at +{ref}`this prior tutorial`. -Since we have no muscles so far, a kinematic analysis is really all that -makes sense. With a kinematic analysis, you can investigate positions, velocities, and -accelerations. But force, power, energy or other such things are not computed. These properties are calculated by the -"InverseDynamics" study. +Since we have no muscles so far, a kinematic analysis is really all that makes +sense. With a kinematic analysis, you can investigate positions, velocities, and +accelerations. But force, power, energy or other such things are not computed. +These properties are calculated by the "InverseDynamics" study. ## Replaying a simulation -While the analysis is running, you can see the model move in the Model View window. +While the analysis is running, you can see the model move in the Model View +window. When the analysis in finished, you can use the replay panel to replay the motion as you would in a movie player. @@ -133,32 +149,42 @@ the motion as you would in a movie player. ## Viewing simulation outputs -If you look at the "ArmModelStudy" object in the AnyScript window, start/end times and the -number of simulation steps (time frames) are not specified. These are actually optional parameters -when using the `AnyBodyStudy` class, which by default creates an analysis of 100 steps and spanning 1 second. +If you look at the "ArmStudy" object in the AnyScript window, start/end +times and the number of simulation steps (time frames) are not specified. These +are actually optional parameters when using the `AnyBodyStudy` class, which by +default creates an analysis of 100 steps and spanning 1 second. -**To view the output variables of the study that was run, open the "ArmModelStudy" folder in the model tree and expand the "Output" folder.** +**To view the output variables of the study that was run, open the "ArmStudy"** +**folder in the model tree and expand the "Output" folder.** -Since the "ArmModelStudy" contained a reference object ("Model") pointing to the "ArmModel" folder, the "Output" -folder contains the instantaneous values of all the time varying variables (including variables in sub-folders) within "ArmModel". +Since the "ArmStudy" contained a reference object ("Model") pointing to the +"ArmModel" folder, the "Output" folder contains the instantaneous values of all +the time varying variables (including variables in sub-folders) within +"ArmModel". -In "ArmModelStudy.Output.Model.Segs.ForeArm" in the model tree, you find all the nodes on the segment. Within the "HandNode" -sub-folder, you will find {literal}`r` - the position vector of the node. Clicking on {literal}`r` -shows the hand position vector (w.r.t global) for each time instant in the Information Window. +In `ArmStudy.Output.Model.Segs.ForeArm` in the model tree, you find all the +nodes on the segment. Within the "HandNode" sub-folder, you will find +{literal}`r` - the position vector of the node. Clicking on {literal}`r` shows +the hand position vector (w.r.t global) for each time instant in the Information +Window. ## Plotting simulation results :::{note} -The chart view contains a filtered down version of the model tree, which only displays "AnyBodyStudy" objects. This -tree can also be used for plotting purposes. +The chart view contains a filtered down version of the model tree, which only +displays "AnyBodyStudy" objects. This tree can also be used for plotting +purposes. ::: -Let us say, you want to plot the position vector of the hand node over the course of movement. +Let us say, you want to plot the position vector of the hand node over the +course of movement. -You need to find and plot the variable ".....ForeArm.HandNode.r" in the chart view. If you need help with the chart view, -refer to {ref}`this prior tutorial on plotting `. +You need to find and plot the variable `.....ForeArm.HandNode.r` in the chart +view. If you need help with the chart view, refer to +{ref}`this prior tutorial on plotting `. -If you're having trouble finding the correct output variable in the chart view's filtered model tree, refer to the figure below. +If you're having trouble finding the correct output variable in the chart view's +filtered model tree, refer to the figure below. ```{image} _static/lesson4/image6.png :alt: Chart hand movement diff --git a/A_Getting_started_anyscript/lesson5.md b/A_Getting_started_anyscript/lesson5.md index 1793973f..faad93bd 100644 --- a/A_Getting_started_anyscript/lesson5.md +++ b/A_Getting_started_anyscript/lesson5.md @@ -11,19 +11,22 @@ previous lesson: {download}`demo.lesson5.any `. The model so far has been capable of motion despite lacking muscles. This is because a kinematic analysis that does not consider forces. -Skeletal muscles produce movement by pulling on our bones. Muscle actions -are coordinated in complicated patterns determined by our central nervous system. +Skeletal muscles produce movement by pulling on our bones. Muscle actions are +coordinated in complicated patterns determined by our central nervous system. -**AnyBody helps you predict realistic muscle activation patterns for a given movement and external load.** +AnyBody helps you predict realistic muscle activation patterns for a given +movement and external load. ## Creating a muscle model The exact behaviour of muscle tissue is a widely researched (and debated) topic. -AnyBody offers several models of varying sophistication, for modelling muscle behaviour. A detailed introduction -to muscle modeling can be found here {doc}`its own tutorial <../Muscle_modeling/intro>`. +AnyBody offers several models of varying sophistication, for modelling muscle +behaviour. A detailed introduction to muscle modeling can be found here +{doc}`its own tutorial <../Muscle_modeling/intro>`. -Here, we will create a very simple muscle model and use it to model our arm model muscles. We start by creating a folder for the muscles: +Here, we will create a very simple muscle model and use it to model our arm +model muscles. We start by creating a folder for the muscles: ```{literalinclude} Snippets/lesson5/snip.NewModel.main-1.any :language: AnyScriptDoc @@ -31,7 +34,8 @@ Here, we will create a very simple muscle model and use it to model our arm mode :end-before: //# END SNIPPET 1 ``` -The next step is to create a muscle model that defines the properties that will be assumed common for all the muscles. +The next step is to create a muscle model that defines the properties that will +be assumed common for all the muscles. :::{note} Since properties such as Max muscle strength, fiber length etc. differ between muscles, realistic AMMR human body models @@ -137,23 +141,29 @@ a gravity vector in the "ArmModelStudy" object. :::{note} :class: margin A kinematic constraint needs to be enforced by an accompanying constraint force. -For example, when you lean on a table, the normal reaction force on your hand maintains the -surface-surface constraint between hand and table. Were it not for the force you would have fallen, with your hand -passing through the table surface. Similarly motion constraints such as joint angle motions need a driving +For example, when you lean on a table, the normal reaction force on your hand +maintains the surface-surface constraint between hand and table. Were it not for +the force you would have fallen, with your hand passing through the table +surface. Similarly motion constraints such as joint angle motions need a driving force to maintain the specified trajectory. ::: -By default, all drivers in your model apply the necessary constraint forces (also called driver reactions) for their respective kinematic constraints. +By default, all drivers in your model apply the necessary constraint forces +(also called driver reactions) for their respective kinematic constraints. -**The constraint "force" is actually a generalized force i.e. whether it is actually a force or torque -depends on the type of measure that a driver constrains.** For example, a driver on a rotational measure, will apply torques, while one on -a linear measure will apply forces. AnyBody reports all of these simply as "forces", and it is up to you to interpret them. +The constraint "force" is actually a **generalized force** i.e. whether it is +actually a force or torque depends on the type of measure that driver +constrains. For example, a driver on a rotational measure, will apply torques, +while one on a linear measure will apply forces. AnyBody reports all of these +simply as "forces", and it is up to you to interpret them. -**The drivers for shoulder and elbow motion thus default to applying the required constraint reaction torques to sustain the joint motions.** -This is problematic, since we wish the muscles forces to be causing the motion instead. - -**👉 Now** The default driver reactions must therefore be switched off by setting the "Reaction.Type" property. +The drivers for shoulder and elbow motion thus default to applying the +**required constraint reaction torques to sustain the joint motions**. This is +problematic, since we wish the muscles forces to be causing the motion instead. +**👉 Now** The default driver reactions must therefore be switched off by +setting the `Reaction.Type` property, for the muscles to cause the motion and +not the drivers. ```{literalinclude} Snippets/lesson5/snip.NewModel.main-6.any :language: AnyScriptDoc @@ -161,13 +171,81 @@ This is problematic, since we wish the muscles forces to be causing the motion i :end-before: //# END SNIPPET 1 ``` -On the other hand, the driver reactions come in handy in models under development, while you are still adding -muscles or other force elements to enforce the constraints. The driver reactions will allow you to successfully run -inverse dynamic simulations at the intermediate model stages, by ensuring dynamic consistency. +On the other hand, the driver reactions come in handy in models under +development, while you are still adding muscles or other force elements to +enforce the constraints. The driver reactions will allow you to successfully run +inverse dynamic simulations at the intermediate model stages, by ensuring +dynamic consistency. + +The single `Off` is encapsulated in braces, `{Off}`, because it is a vector. A +driver can theoretically have any number of total DOF from all the measures that +it drives. Therefore all data in a driver are vector quantities, even when it is +a 1 DOF driver. + +(AnyKinMotion)= +### An Alternative Driver - AnyKinMotion + +As an alternative to the `AnyKinDriver` class and setting the +`Reaction.Type={Off}`, you can also use the `AnyKinMotion` class. This other +driver is basically identical to the general `AnyKinDriver`, except that all +constraint reaction forces are by default switched off. This implies that this driver only +specifies motion but not a mechanical actuator that produces the motion. In +contrast, AnyKinDriver has reaction forces switched on by default, implying +that the object is an “infinitely strong” mechanical actuator that will produce +the motion no matter the external loads. + +In the following studies, try using both drivers, to see that they generate the +same result. Make the following changes to use the `AnyKinMotion` driver (note, +the line defining the `Reaction.Type` is not needed): + +```{literalinclude} Snippets/lesson5/snip.NewModel.main-7.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 +``` + +Another important option for both of the drivers, is that you can define a +**driver function** - meaning the function for the movement of the driver. This is +done by defining a time-dependent function for the `AnyParamFun` option. +`AnyParamFun` is the base class for parameter functions that are functions of a +single scalar (floating point) quantity. + +AnyBody contains a number of predefined function types that you can find in the +Classes Tree or in the Reference Manual, for instance `AnyFunPolynomial`. As the +name indicates, this is polynomial driver function: + +```AnyScriptDoc +AnyKinMotion ShoulderMotion = { + AnyRevoluteJoint &Jnt = ..Jnts.Shoulder; + DriverPos0 = {-100*pi/180}; + DriverVel0 = {30*pi/180}; + §AnyFunPolynomial DriverFun = { + PolyCoef = {{0, 1, -0.9}}; + };§ +}; +``` + +In the matrix `PolyCoef`, each row contains the coefficients for a time +function driving one degree of freedom. The revolute joint we are +driving only has one degree of freedom, so the matrix only has one row, +but it still has to be defined as a matrix rather than a vector, i.e. +with double braces at each end. The polynomial coefficients then come in +increasing order and define the following driver function: + +$$ +\textrm{Joint angle} = 0 + 1t - 0.9t^2 \textrm{[rad]} +$$ + +To get higher polynomial orders, simply add more terms to the vector. A common +use is to drive motion either in a very standardized way, for instance with +constant velocity or constant acceleration, or to drive a motion by data to +which a polynomial has been fitted. -The single `Off` is encapsulated in braces, `{Off}` because it is a vector. -A driver can theoretically have any number of total DOF from all the measures -that it drives. Therefore all data in a driver are vector quantities, even when it is a 1 DOF driver . +:::{note} +In the following, **we will NOT use any driver function**, but simply the default +option. So, do not insert the above defined `AnyFunPolynomial DriverFun`. +Furthermore, it is optional to use either the `AnyKinMotion` or the `AnyKinDriver` class. +::: ## The InverseDynamicAnalysis and plotting muscle forces @@ -177,8 +255,9 @@ In this analysis, the AnyBody system computes all muscle, joint forces and much Review the instructions from {ref}`this prior tutorial ` on plotting simulation results. To plot the muscle forces in the brachialis muscle, open -"Main.Study.Output.Model.Muscles.Brachialis" in the chart view's model tree, and plot the variable named `Fm`. -You should get a curve that looks like the one below. +`Main.Study.Output.Model.Muscles.Brachialis` in the chart view's model tree, and +plot the variable named `Fm`. You should get a curve that looks like the one +below. ```{image} _static/lesson5/image3.png :alt: Brachialis muscle force @@ -187,8 +266,9 @@ You should get a curve that looks like the one below. :width: 75% ``` -The drop in muscle force with movement progression is due to the decreasing moment arm of the -gravity vector about the elbow joint, as the elbow flexes. Therefore lesser the muscle force. +The drop in muscle force with movement progression is due to the decreasing +moment arm of the gravity vector about the elbow joint, as the elbow flexes. +Therefore lesser the muscle force. If you look at the muscle force in the BicepsLong, you see a different pattern: @@ -199,35 +279,38 @@ If you look at the muscle force in the BicepsLong, you see a different pattern: :width: 75% ``` -This muscle's force increases during the movement because this muscle supports both, the shoulder and the -elbow. In addition, it collaborates both with DeltoidusA on shoulder -flexion, and with the other elbow flexors, and all these muscles have to -adjust their work in relation to each other. +This muscle's force increases during the movement because this muscle supports +both, the shoulder and the elbow. In addition, it collaborates both with +DeltoidusA on shoulder flexion, and with the other elbow flexors, and all these +muscles have to adjust their work in relation to each other. ## Creating external loads -You may want to investigate the model's behavior in different loading situations, such as when the hand -is carrying a dumbbell. Let us imagine that the model is performing a dumbbell curl. +You may want to investigate the model's behavior in different loading +situations, such as when the hand is carrying a dumbbell. Let us imagine that +the model is performing a dumbbell curl. -We start by creating a node on the forearm at the location of the palm. Add this within the curly braces of the "ForeArm" object: +We start by creating a node on the forearm at the location of the palm. Add this +within the curly braces of the "ForeArm" object: -```{literalinclude} Snippets/lesson5/snip.NewModel.main-7.any +```{literalinclude} Snippets/lesson5/snip.NewModel.main-6.any :language: AnyScriptDoc -:start-after: //# BEGIN SNIPPET 1 -:end-before: //# END SNIPPET 1 +:start-after: //# BEGIN SNIPPET 2 +:end-before: //# END SNIPPET 2 ``` -The next step is to add an external force. We make a new sub-folder for this purpose, within ArmModel: +The next step is to add an external force. We make a new sub-folder for this +purpose, within ArmModel: -```{literalinclude} Snippets/lesson5/snip.NewModel.main-7.any +```{literalinclude} Snippets/lesson5/snip.NewModel.main-6.any :language: AnyScriptDoc -:start-after: //# BEGIN SNIPPET 2 -:end-before: //# END SNIPPET 2 +:start-after: //# BEGIN SNIPPET 3 +:end-before: //# END SNIPPET 3 ``` -Now you can reload the model and re-run inverse dynamics to analyze how the model reacts -to a downward force of 100 N (approximately 10 kg dumbbell weight). The BicepsLong force again, you -should see this: +Now you can reload the model and re-run inverse dynamics to analyze how the +model reacts to a downward force of 100 N (approximately 10 kg dumbbell weight). +The BicepsLong force again, you should see this: ```{image} _static/lesson5/image5.png :alt: Biceps long with added force @@ -238,9 +321,9 @@ should see this: :::{note} :class: margin -Applied forces do not have to be constant. They can change with time -and other properties in the model. Please refer to the {doc}`tutorial on forces <../The_mechanical_elements/intro>` for more -details. +Applied forces do not have to be constant. They can change with time and other +properties in the model. Please refer to the +{doc}`tutorial on forces<../The_mechanical_elements/intro>` for more details. ::: The muscle force is obviously much larger than before, and the @@ -249,7 +332,7 @@ movement and drops off again. **The model you've built here was anatomically simplified, and it can be a difficult job to define a realistic body model from scratch. We recommend that users -start out with the body models available in the** [AnyBody Managed Model -Repository](https://www.anybodytech.com/software/ammr/). +start out with the body models available in the** +[AnyBody Managed Model Repository](https://www.anybodytech.com/software/ammr/). Now, let's continue to {doc}`Lesson 6: Adding real bone geometrics `. \ No newline at end of file diff --git a/A_Getting_started_anyscript/lesson6.md b/A_Getting_started_anyscript/lesson6.md index 2055a3dc..4d1c747c 100644 --- a/A_Getting_started_anyscript/lesson6.md +++ b/A_Getting_started_anyscript/lesson6.md @@ -10,27 +10,26 @@ previous lesson: {download}`demo.lesson6.any `. So far, the model graphically resembles a "stick figure representation". However, realistic bone geometries can improve both aesthetics and -visual comprehension of a model's anatomy, as illustrated -by the two pictures below. - -![oldleg1](_static/lesson6/image1.jpeg) ![oldleg2](_static/lesson6/image2.jpeg) +visual comprehension of a model's anatomy. ## File formats for visualization objects -3-D geometric models for model components such as bones can be specified using files -of the STL ASCII format. +3-D geometric models for model components such as bones can be specified using +files of the STL ASCII format. STL is a very simple graphical file format that represents object surfaces as -triangles. Virtually all CAD systems can export an object in the STL format. So if your files are in the IGES, -STEP, DXF, etc. formats, load them in your favorite CAD system and convert to STL. +triangles. Virtually all CAD systems can export an object in the STL format. So +if your files are in the IGES, STEP, DXF, etc. formats, load them in your +favorite CAD system and convert to STL. -STL files come in two varieties: ASCII and binary. AnyBody needs an ASCII file, so please make sure to choose that -option during the export process. +STL files come in two varieties: ASCII and binary. AnyBody needs an ASCII file, +so please make sure to choose that option during the export process. ## Importing an STL file -Since the bone models shown in the above tutorial may be a bit too elaborate for a -basic tutorial, we will demonstrate this by adding an STL file for the dumbbell in the arm model. +Since the bone models shown in the above tutorial may be a bit too elaborate for +a basic tutorial, we will demonstrate this by adding an STL file for the +dumbbell in the arm model. Download the dumbbell model {download}`here ` and save the STL file in the same folder as your AnyBody main script. @@ -46,9 +45,10 @@ file into AnyBody - within the `ArmModel.Segs.ForeArm` object: Re-loading the model now will *not* result in a sensible model view. -This is because the STL file's units was millimeters, whereas the arm model -is in meters. This means the dumbbell's STL swallowed up the entire arm model in the model view. -We will therefore scale the dumbbell model down a 1000 times, in the following way: +This is because the STL file's units was millimeters, whereas the arm model is +in meters. This means the dumbbell's STL swallowed up the entire arm model in +the model view. We will therefore scale the dumbbell model down a 1000 times, in +the following way: ```{literalinclude} Snippets/lesson6/snip.NewModel.main-2.any :language: AnyScriptDoc @@ -69,12 +69,13 @@ the lower arm rather than at the hand, and is not oriented correctly. ## Relocating your STL object -When you attach something to a segment, it is by default positioned -at the segment's origin which is also its center of mass. (This was discussed earlier {ref}`over here `) +When you attach something to a segment, it is by default positioned at the +segment's origin which is also its center of mass. (This was discussed earlier +{ref}`over here `) -Therfore moving the dumbbell to the hand is as simple as relocating the "DrwSTL" object -from the "ForeArm" folder to the "PalmNode" subfolder. Cut-paste the entire code for the -"DrwSTL" folder into "PalmNode", as shown below: +Therfore moving the dumbbell to the hand is as simple as relocating the "DrwSTL" +object from the "ForeArm" folder to the "PalmNode" subfolder. Cut-paste the +entire code for the "DrwSTL" folder into "PalmNode", as shown below: ```{literalinclude} Snippets/lesson6/snip.NewModel.main-3.any :language: AnyScriptDoc @@ -82,8 +83,8 @@ from the "ForeArm" folder to the "PalmNode" subfolder. Cut-paste the entire code :end-before: //# END SNIPPET 1 ``` -Upon reloading, we see that the dumbbell attached to the -right location, but is still not oriented correctly. +Upon reloading, we see that the dumbbell attached to the right location, but is +still not oriented correctly. ```{image} _static/lesson6/image4.png :alt: Dumbbell attached at Palm @@ -94,14 +95,16 @@ right location, but is still not oriented correctly. ## Reorienting your STL object -:::{note} -You can visualize a node's local reference system, by selecting the node in the model tree -(e.g., "Main.ArmModel.Segs.ForeArm.PalmNode") and right-clicking and selecting "Model View->This object->View". +:::{note} +You can visualize a node's local reference system, by selecting the +node in the model tree (e.g., `Main.ArmModel.Segs.ForeArm.PalmNode`) and +right-clicking and selecting "Model View->This object->View". ::: -An STL (or other geometrical) object's axes are always oriented parallel to the local coordinate system it is attached to. -By visualizing the palm node's local reference system, you will realize that the dumbbell needs to be rotated 90 degrees -about the local Y-axis. +An STL (or other geometrical) object's axes are always oriented parallel to the +local coordinate system it is attached to. By visualizing the palm node's local +reference system, you will realize that the dumbbell needs to be rotated 90 +degrees about the local Y-axis. To rotate the dumbbell by 90 degrees around the Y-axis, adjust the orientation of the `PalmNode`, where the dumbbell is attached. The `sRel` vector specifies @@ -118,7 +121,8 @@ You can use the `RotMat` function to generate the 3x3 rotation matrix: :end-before: //# END SNIPPET 1 ``` -The dumbbell's color can be changed adding the property RGB to the STL file reference: +The dumbbell's color can be changed adding the property RGB to the STL file +reference: ```{literalinclude} Snippets/lesson6/snip.NewModel.main-5.any :language: AnyScriptDoc @@ -136,5 +140,5 @@ normalized scale of 0 to 1. :width: 50% ``` -This completes the Getting Started with AnyScript tutorial. The final -result of your efforts is in {download}`demo.arm2d.zip `. +This completes the Getting Started with AnyScript tutorial. The final result of +your efforts is in {download}`demo.arm2d.zip `. diff --git a/Making_things_move/_static/intro/image1.jpeg b/Making_things_move/_static/intro/image1.jpeg deleted file mode 100644 index 276e56cc..00000000 Binary files a/Making_things_move/_static/intro/image1.jpeg and /dev/null differ diff --git a/Making_things_move/_static/intro/image2.png b/Making_things_move/_static/intro/image2.png deleted file mode 100644 index 4a6fada2..00000000 Binary files a/Making_things_move/_static/intro/image2.png and /dev/null differ diff --git a/Making_things_move/_static/lesson1/run_operation.png b/Making_things_move/_static/lesson1/run_operation.png deleted file mode 100644 index 84da7559..00000000 Binary files a/Making_things_move/_static/lesson1/run_operation.png and /dev/null differ diff --git a/Making_things_move/_static/lesson2/image1.png b/Making_things_move/_static/lesson2/image1.png deleted file mode 100644 index e1a5ea67..00000000 Binary files a/Making_things_move/_static/lesson2/image1.png and /dev/null differ diff --git a/Making_things_move/_static/lesson2/image3.png b/Making_things_move/_static/lesson2/image3.png deleted file mode 100644 index 5320b96a..00000000 Binary files a/Making_things_move/_static/lesson2/image3.png and /dev/null differ diff --git a/Making_things_move/_static/lesson3/image1.png b/Making_things_move/_static/lesson3/image1.png deleted file mode 100644 index 8be0ef87..00000000 Binary files a/Making_things_move/_static/lesson3/image1.png and /dev/null differ diff --git a/Making_things_move/_static/lesson3/image2.png b/Making_things_move/_static/lesson3/image2.png deleted file mode 100644 index 8566612c..00000000 Binary files a/Making_things_move/_static/lesson3/image2.png and /dev/null differ diff --git a/Making_things_move/_static/lesson3/image3.png b/Making_things_move/_static/lesson3/image3.png deleted file mode 100644 index f5903ba7..00000000 Binary files a/Making_things_move/_static/lesson3/image3.png and /dev/null differ diff --git a/Making_things_move/_static/lesson3/image4.png b/Making_things_move/_static/lesson3/image4.png deleted file mode 100644 index a41fd8a3..00000000 Binary files a/Making_things_move/_static/lesson3/image4.png and /dev/null differ diff --git a/Making_things_move/_static/lesson4/image3.png b/Making_things_move/_static/lesson4/image3.png deleted file mode 100644 index 88edc67a..00000000 Binary files a/Making_things_move/_static/lesson4/image3.png and /dev/null differ diff --git a/Making_things_move/_static/lesson4/image4.jpeg b/Making_things_move/_static/lesson4/image4.jpeg deleted file mode 100644 index 54923b51..00000000 Binary files a/Making_things_move/_static/lesson4/image4.jpeg and /dev/null differ diff --git a/Making_things_move/_static/lesson4/image5.png b/Making_things_move/_static/lesson4/image5.png deleted file mode 100644 index ffa4b15d..00000000 Binary files a/Making_things_move/_static/lesson4/image5.png and /dev/null differ diff --git a/Making_things_move/_static/lesson5/Main.RunAnalysis.png b/Making_things_move/_static/lesson5/Main.RunAnalysis.png deleted file mode 100644 index 964acee2..00000000 Binary files a/Making_things_move/_static/lesson5/Main.RunAnalysis.png and /dev/null differ diff --git a/Making_things_move/_static/lesson5/charview_higher_hip_forces.png b/Making_things_move/_static/lesson5/charview_higher_hip_forces.png deleted file mode 100644 index 4468cc2c..00000000 Binary files a/Making_things_move/_static/lesson5/charview_higher_hip_forces.png and /dev/null differ diff --git a/Making_things_move/_static/lesson5/image1.png b/Making_things_move/_static/lesson5/image1.png deleted file mode 100644 index 319431b5..00000000 Binary files a/Making_things_move/_static/lesson5/image1.png and /dev/null differ diff --git a/Making_things_move/_static/lesson5/image10.png b/Making_things_move/_static/lesson5/image10.png deleted file mode 100644 index bff5787c..00000000 Binary files a/Making_things_move/_static/lesson5/image10.png and /dev/null differ diff --git a/Making_things_move/_static/lesson5/image11.png b/Making_things_move/_static/lesson5/image11.png deleted file mode 100644 index 390e0742..00000000 Binary files a/Making_things_move/_static/lesson5/image11.png and /dev/null differ diff --git a/Making_things_move/_static/lesson5/image4.png b/Making_things_move/_static/lesson5/image4.png deleted file mode 100644 index 906b0b13..00000000 Binary files a/Making_things_move/_static/lesson5/image4.png and /dev/null differ diff --git a/Making_things_move/_static/lesson5/image5.png b/Making_things_move/_static/lesson5/image5.png deleted file mode 100644 index bd55cc32..00000000 Binary files a/Making_things_move/_static/lesson5/image5.png and /dev/null differ diff --git a/Making_things_move/_static/lesson5/image6.png b/Making_things_move/_static/lesson5/image6.png deleted file mode 100644 index 36bf249a..00000000 Binary files a/Making_things_move/_static/lesson5/image6.png and /dev/null differ diff --git a/Making_things_move/_static/lesson5/image7.png b/Making_things_move/_static/lesson5/image7.png deleted file mode 100644 index 39b8068f..00000000 Binary files a/Making_things_move/_static/lesson5/image7.png and /dev/null differ diff --git a/Making_things_move/_static/lesson5/image8.emf b/Making_things_move/_static/lesson5/image8.emf deleted file mode 100644 index ecc45b7c..00000000 Binary files a/Making_things_move/_static/lesson5/image8.emf and /dev/null differ diff --git a/Making_things_move/_static/lesson6/image1.emf b/Making_things_move/_static/lesson6/image1.emf deleted file mode 100644 index ae316733..00000000 Binary files a/Making_things_move/_static/lesson6/image1.emf and /dev/null differ diff --git a/Making_things_move/_static/lesson6/image2.jpeg b/Making_things_move/_static/lesson6/image2.jpeg deleted file mode 100644 index 4f1f248f..00000000 Binary files a/Making_things_move/_static/lesson6/image2.jpeg and /dev/null differ diff --git a/Making_things_move/_static/lesson6/image3.emf b/Making_things_move/_static/lesson6/image3.emf deleted file mode 100644 index b5973a3d..00000000 Binary files a/Making_things_move/_static/lesson6/image3.emf and /dev/null differ diff --git a/Making_things_move/_static/lesson6/image4.emf b/Making_things_move/_static/lesson6/image4.emf deleted file mode 100644 index 08d71cb2..00000000 Binary files a/Making_things_move/_static/lesson6/image4.emf and /dev/null differ diff --git a/Making_things_move/_static/lesson6/image5.emf b/Making_things_move/_static/lesson6/image5.emf deleted file mode 100644 index 8ccddfbe..00000000 Binary files a/Making_things_move/_static/lesson6/image5.emf and /dev/null differ diff --git a/Making_things_move/_static/lesson6/image6.emf b/Making_things_move/_static/lesson6/image6.emf deleted file mode 100644 index c0408e47..00000000 Binary files a/Making_things_move/_static/lesson6/image6.emf and /dev/null differ diff --git a/Making_things_move/_static/lesson6/image7.emf b/Making_things_move/_static/lesson6/image7.emf deleted file mode 100644 index e01a1703..00000000 Binary files a/Making_things_move/_static/lesson6/image7.emf and /dev/null differ diff --git a/Making_things_move/index.md b/Making_things_move/index.md deleted file mode 100644 index f4fdc1c6..00000000 --- a/Making_things_move/index.md +++ /dev/null @@ -1,27 +0,0 @@ -::: {rst-class} break -::: - -# Making things move - -The objective of this tutorial is to give an overview of the different -possibilities to apply a motion to a body model. - -In the following lessons the different drivers from simple drivers to using -motion capture data will be explained. - -::::{if-builder:: html -```{rubric} Tutorial content -``` -:::: - -```{toctree} -:maxdepth: 1 - -Introduction -lesson1 -lesson2 -lesson3 -lesson4 -lesson5 -lesson6 -``` diff --git a/Making_things_move/lesson2.md b/Making_things_move/lesson2.md deleted file mode 100644 index e40a2805..00000000 --- a/Making_things_move/lesson2.md +++ /dev/null @@ -1,487 +0,0 @@ -::: {rst-class} break -::: - -# Lesson 2: Using motion capture data - -In biomechanics, we often want to make our models move as we have measured in -the laboratory and the measurement technique would often be tracking of optical -markers in space by means of synchronized cameras. - -There are many such systems available commercially, but a common feature of most -of the systems is that they are capable of saving data on a standard format -called a C3D file. - -A C3D file contains data of the spatial trajectory of optical markers fixed to -the object whose motion we want to record. The file can also contain analog data -such as force platform measurements or EMG. - -AnyBody can read the data from a C3D file directly. Please download and save the -file {download}`pendulum.c3d ` in the directory where -you saved the {file}`Pendulum.any` file. - -Next, place the cursor in the editor window just before the {code}`AnyKinMotion` -object, click the Classes tab (on the right side of the screen), unfold the class list, and locate the -{code}`AnyInputC3D` class. Right-click the class and choose “Insert Class -Template”. - -```AnyScriptDoc -AnyInputC3D = -{ -FileName = ""; -//ReadAllDataOnOff = On; -//TruncateExtraCharsInNamesOnOff = On; -//MakeNameUniqueStr = "_"; -//PointsScaleFactor = 1.0; -//ConstructModelOnOff = On; -//ConstructChartOnOff = On; -//ConstructWeightFunUsingResidualOnOff = Off; -//GapFillUsingResidualsOnOff = Off; -//MarkerUseAllPointsOnOff = Off; -//MarkerUseCamMaskOnOff = On; -//MarkerIndices = ; -//MarkerLabels = ; -//MarkerFilterIndex = 0; -//ProcessedDataFilterIndex = 0; -//AnalogFilterIndex = -1; -/*Filter = -{ -z0 = ; -AutomaticInitialConditionOnOff = On; -FilterForwardBackwardOnOff = On; -N = 2; -W = ; -Fs = 0.0; -Fc = {10.0}; -Type = LowPass; -};*/ -//WeightThreshold = 0.0; -//WeightOutput = {{0.0, 1.0}, {0.0, 1.0}, {0.0, 1.0}}; -//WeightTransitionTime = 0.1; -//SearchAndReplace = ; -//WriteMarkerDataToFilesOnOff = Off; -//MarkerScaleXYZ = {0.025, 0.025, 0.025}; -//MarkerRGB = {0.65, 0.65, 0.65}; -//MarkerDrawOnOff = On; -//MarkerInterPolType = Bspline; -//MarkerBsplineOrder = 4; -}; -``` - -As you can see, the class has a lot of settings, but for now we shall -only use two of them, namely FileName and ConstructChartOnOff. We also -give a name to the object: - -```AnyScriptDoc -AnyInputC3D §C3D§ = { - FileName =§ "pendulum.c3d";§ - //TruncateExtraCharsInNamesOnOff = On; - //MakeNameUniqueStr = "_"; - //PointsScaleFactor = 1; - //ConstructModelOnOff = On; - §ConstructChartOnOff = Off;§ -``` - -`ConstructChartOnOff` instructs the C3D object to not draw 3D -trajectories. - -Now, try loading the model again. You may get the following error -message: - -```none -Time, 't', has an invalid value for this interpolation -``` - -C3D files contain marker trajectories covering a certain time span and -what goes on outside that interval is undefined. Furthermore, the very -beginning and very end of that time span may not be useful for the -motion interpolation due to initial transients. - -If you have a C3D file of unknown duration, then you somehow have to figure out -its start and end times to enable AnyBody to analyze it. A simple way to do this -is to allow AnyBody to load the file by temporarily disabling the study section -of your model. This will eliminate the study’s conflicting start and end times. -Just block-select the study section and click the “Comment out” tool button over -the editor window (or press {literal}`Ctrl+Shift+k`): - -```AnyScriptDoc -// The study: Operations to be performed on the model -§//§ AnyBodyStudy MyStudy = { -§//§ AnyFolder &Model = .MyModel; -§//§ Gravity = {0.0, -9.81, 0.0}; -§//§ }; -``` - -Now the model should load with no problems, and you can go to the tree -view in the left hand side of the screen, click the Model tab and unfold -the MyModel tree down to the C3D object as shown below. - -![Model tree](_static/lesson2/image1.png) - -A bit down in this object you find the Header section. When you unfold -it you get access to a number of basic properties of the C3D file. Each -time you double-click a property, a window will pop up and give you its -value. The important properties in question are these: - -```AnyScriptDoc -FirstFrameNo = 1 -LastFrameNo = 1000 -VideoFrameRate = 100 -``` - -This shows that the file has a total of 1000 frames at 100 frames/sec, -i.e. the simulation time spans ten seconds. We can now go to the editor -window and remove the temporary double slashes in front of each line in -the study section. - -```AnyScriptDoc -// The study: Operations to be performed on the model -§AnyBodyStudy MyStudy = { - AnyFolder &Model = .MyModel; - Gravity = {0.0, -9.81, 0.0}; -};§ -``` - -…and insert specifications of simulation time: - -```AnyScriptDoc -AnyBodyStudy MyStudy = { - AnyFolder &Model = .MyModel; - Gravity = {0.0, -9.81, 0.0}; - §tStart = 0.05; - tEnd = 9.95;§ -}; -``` - -There is also an automated way to handle the problem. The frame rate -variables we have just processed manually can also be referred to -directly in the study section, such that the tStart and tEnd parameters -automatically adapt to the C3D file. Try this instead: - -```AnyScriptDoc -AnyBodyStudy MyStudy = { - AnyFolder &Model = .MyModel; - Gravity = {0.0, -9.81, 0.0}; - §AnyIntVar FirstFrame = Main.MyModel.C3D.Header.FirstFrameNo; - AnyIntVar LastFrame = Main.MyModel.C3D.Header.LastFrameNo; - tStart = FirstFrame/Main.MyModel.C3D.Header.VideoFrameRate+2*Kinematics.ApproxVelAccPerturb; - tEnd = LastFrame/Main.MyModel.C3D.Header.VideoFrameRate-2*Kinematics.ApproxVelAccPerturb;§ -}; -``` - -Notice that we start the simulation `2*Kinematics.ApproxVelAccPerturb` -after the beginning of the recorded motion and we end it similarly -before the end of the recording. The variable -`Kinematics.ApproxVelAccPerturb` contains information about the -algorithm’s necessary elbow room on each side of the analyzed interval. -This eliminates possible numerical trouble with end points. - -Now the model should load and the Model View window will display a small, grey -dot to the right of the pendulum end. - -![small dot](_static/lesson2/image2.jpeg) - -The small dot is in fact the single marker contained in {file}`Pendulum.c3d`. A -typical file from a real motion capture experiment can contain dozens of -markers, but in the interest of simplicity we have just included a single one -here. The `AnyInputC3D` object automatically creates the small dots and the -drivers necessary to move them around as they were recorded. If you run the -Kinematics operation, you will see the pendulum move as before, while the marker -performs an oscillating motion back and forth - -So how do we get the marker to drive the pendulum? This can be done -quite easily with the AnyKinDriverMarker object. The steps are: - -1. Remove the existing driver that makes the pendulum rotate. -2. Drive the marker point, `P1`, on the pendulum to follow the data - recorded in the C3D file. - -Start by selecting the existing `AnyKinMotion` driver and comment it out -of the model. That takes care of step 1. - -Then click the Classes tab on the right side of the screen, -insert a new `AnyKinDriverMarker` template, and give it a name: - -```AnyScriptDoc -§AnyKinDriverMarker = -{ - //RefFrames = ; - //Surfaces = ; - //KinMeasureArr = ; - //KinMeasureIndexArr = ; - //MeasureOrganizer = ; - //CType = ; - //WeightFun = ; - //DriverPos0 = ; - //DriverVel0 = ; - //DriverAcc0 = ; - AnyRefFrame & = ; - //AnyRefFrame & = ; - //AnyParamFun & = ; -};§ -``` - -Just as before, the `AnyKinDriverMarker` object needs to know what to -drive and what to drive it with. The “what to drive” part is the -position of `P1` on the pendulum. This is specified with the first -reference frame in the object: - -```AnyScriptDoc -AnyKinDriverMarker §C3DMotion§ = -{ - //RefFrames = ; - //Surfaces = ; - //KinMeasureArr = ; - //KinMeasureIndexArr = ; - //MeasureOrganizer = ; - //CType = ; - //WeightFun = ; - //DriverPos0 = ; - //DriverVel0 = ; - //DriverAcc0 = ; - §AnyRefFrame &Marker = .Pendulum.P1;§ - //AnyRefFrame & = ; - //AnyParamFun & = ; -}; -``` - -The marker coordinates in the C3D file are recorded in the laboratory -coordinate system, which we shall assume is our global reference frame. -Driving from `GlobalRef` is default in linear measures, so we need not -mention `GlobalRef` explicitly in the `AnyKinDriverMarker` object. - -We are going to drive the point directly by means of the interpolation -function specifying the marker trajectory in the C3D object. First, give -a reasonable name to the `AnyParamFun` and remove the stuff after the -equality sign: - -```AnyScriptDoc -AnyKinDriverMarker C3DMotion = -{ - //RefFrames = ; - //Surfaces = ; - //KinMeasureArr = ; - //KinMeasureIndexArr = ; - //MeasureOrganizer = ; - //CType = ; - //WeightFun = ; - //DriverPos0 = ; - //DriverVel0 = ; - //DriverAcc0 = ; - AnyRefFrame &Marker = .Pendulum.P1; - //AnyRefFrame & = ; - AnyParamFun §&Trajectory = ;§ -}; -``` - -Then click the Model tab in the tree view on the left hand side of the editor -window, unfold the MyModel branch and subsequently the `C3D` object -> -`Points` -> `Markers` -> `L000` and arrive at `PosInterpol` as shown -below. - -![Model tree 2](_static/lesson2/image3.png) - -This is the actual interpolation function of the marker in question. -Place the cursor after the equality sign of the `AnyParamFun` line, -right-click the PosInterpol object, and choose “Insert object name”. You -should get this: - -```AnyScriptDoc -AnyKinDriverMarker C3DMotion = -{ - //RefFrames = ; - //Surfaces = ; - //KinMeasureArr = ; - //KinMeasureIndexArr = ; - //MeasureOrganizer = ; - //CType = ; - //WeightFun = ; - //DriverPos0 = ; - //DriverVel0 = ; - //DriverAcc0 = ; - AnyRefFrame &Marker = .Pendulum.P1; - //AnyRefFrame & = ; - AnyParamFun &Trajectory = §Main.MyModel.C3D.Points.Markers.L000.PosInterpol§; -}; -``` - -Now load the model and run the kinematic analysis. You will get the -following error message: - -```none -ERROR(OBJ.MCH.KIN3) : ... Kinematic analysis failed in time step 0 : System is kinematically over-constrained -``` - -It is time to think back to the concept of degrees-of-freedom, DoF. In the -beginning of the tutorial, we established that the free pendulum has one DoF. -But the marker trajectory has three coordinates and therefore wants to drive -`P1` of the pendulum in $x$, $y$ and $z$, i.e. two DoFs more -than we have available. - -There are two possible solutions to this problem. Either we pick only one of the -directions given by the marker and let the revolute joint decide the rest, or we -have to accept that the pendulum cannot follow the marker completely in all -three DoFs, i.e. something has to give. - -Driving just one direction would be fairly simple in this case, but in a -more complicated model with many markers, the selection of a subset of -directions to drive can be a very tedious process. - -Another aspect to -consider is that marker data are measured and therefore always infested -with various types of errors and noise. One of the serious errors in -motion capture technology is the so-called soft tissue artifact or skin -artifact. It comes from the fact that markers are placed on the skin at -some distance from the bone whose motion they are supposed to record. -Between the marker and the bone are layers of skin, fat and muscle, so -the marker never moves exactly with the bone. It is therefore natural in -the model to presume that the connection between the marker and the bone -is not a rigid one, and when that is the case, AnyBody will accept -drivers on more DoFs than the model actually has. - -Resolving the kinematics in the presence of moving markers is somewhat -more complicated numerically, so we have to ask for a specific -kinematics solver that can handle it. This is done in the study section: - -```AnyScriptDoc -AnyBodyStudy MyStudy = { - AnyFolder &Model = .MyModel; - Gravity = {0.0, -9.81, 0.0}; - AnyIntVar FirstFrame = Main.MyModel.C3D.Header.FirstFrameNo; - AnyIntVar LastFrame = Main.MyModel.C3D.Header.LastFrameNo; - tStart =FirstFrame/Main.MyModel.C3D.Header.VideoFrameRate+2*Kinematics.ApproxVelAccPerturb; - tEnd = LastFrame/Main.MyModel.C3D.Header.VideoFrameRate-2*Kinematics.ApproxVelAccPerturb; - §InitialConditions.SolverType = KinSolOverDeterminate; - Kinematics.SolverType = KinSolOverDeterminate;§ - -}; -``` - -The two additional lines select a kinematic solver for the -InitialConditions and Kinematics operations that will accept more -kinematic constraints than the system has DoFs. - -:::{note} -See [Andersen MS, Damsgaard M, and Rasmussen J. 2007](https://doi.org/10.1080/10255840802459412) -for detailed information about the algorithm behind the overdeterminate kinematic analysis. -::: - -Now you can reload and run the kinematic analysis and you should see the -pendulum following the marker movement. You cannot see the marker during the -movement because it is hidden inside the pendulum. In fact, the marker is not -strictly necessary for the analysis and we can get rid of it altogether by an -additional specification in the C3D object: - -```AnyScriptDoc -AnyInputC3D C3D = -{ - FileName = "pendulum.c3d"; - //ReadAllDataOnOff = On; - //TruncateExtraCharsInNamesOnOff = On; - //MakeNameUniqueStr = "_"; - //PointsScaleFactor = 1.0; - §ConstructModelOnOff = Off;§ - ConstructChartOnOff = Off; - //ConstructWeightFunUsingResidualOnOff = Off; - //GapFillUsingResidualsOnOff = Off; - //MarkerUseAllPointsOnOff = Off; - //MarkerUseCamMaskOnOff = On; - ... -``` - -With the unnecessary marker gone from the model, the kinematic analysis -runs much faster than before. Each marker adds DoFs and constraints to -the model, and they require solution time. It is therefore more -efficient to leave the markers out unless you really need them. - -Now that there is driver between pendulum and the marker, it is possible -to simultaneously draw both the point on the pendulum and the marker -from the C3D file. To do this, start by placing the cursor inside the -AnyKinDriverMarker object. - -Then click the Classes tab on the right side of screen, insert a new -`AnyDrawKinMeasure` template, remove the properties we will not need and give -it a name: - -```AnyScriptDoc -AnyKinDriverMarker C3Dmotion = -{ - //MeasureOrganizer = {}; - //CType = ; - //WeightFun = {}; - //DriverPos0 = {}; - //DriverVel0 = {}; - //DriverAcc0 = {}; - AnyRefFrame &Marker = .Pendulum.P1; - //AnyRefFrame & = ; - AnyParamFun &Trajectory = - Main.MyModel.C3D.Points.Markers.L000.PosInterpol; - - §AnyDrawKinMeasure drw = - { - //Label = On; - //Size = 0.02; - //Line = On; - };§ -}; -``` - -If you reload the model, you should see something like this: - -![Model view AnyKinDriver marker](_static/lesson2/image4.jpeg) - -The blue dot illustrates the marker from the c3d file and the red line -is drawn to illustrate the difference between the point on the segment -and the measured point. Please notice that there is a small ball hidden -inside yellow sphere from the drawing of the segment. The plot also -shows a label “KDM”, which indicates that it is an `AnyKinDriverMarker` -that is drawn. - -The line between the two points and the label can be removed by changing -the `Label` and `Line` settings to Off. Let us also change the size of the -dots such that we can see both the point on the segment as well as the -measured point. - -```AnyScriptDoc -AnyDrawKinMeasure drw = -{ - §Label = Off; - Size = 0.07; - Line = Off;§ -}; -``` - -Reloading the model should show you something like this: - -![Model view DrawKinMeasure](_static/lesson2/image5.jpeg) - -Let us briefly investigate the kinematic constraints of our model. Click -the Model tab in the tree view on the left hand side of the screen and -unfold the `Joint` branch. Inside you find `Constraints`, and after -unfolding that branch you find the property `CType`. If you double-click -it, the popup window shows the following: - -```AnyScriptDoc -CType = {Hard, Hard, Hard, Hard, Hard} -``` - -`CType` appears to be a vector with five components, owing to the fact -that a revolute joint has five constraints, and CType specifies that all -of these are `Hard`. This means that the kinematic solver is not allowed -to violate any of them. - -If you similarly locate and unfold the `C3DMotion` object you again find a -`CType`, and double-clicking it reveals - -```AnyScriptDoc -CType = {Soft, Soft, Soft} -``` - -We have implicitly specified that the joint is a hard constraint while -the marker is a soft constraint. Joints automatically have their -constraint types set to Hard and `AnyKinDriverMarker` objects -automatically have soft constraints, but these rules can be overridden -by the user by explicit specification of `CType` in the respective -objects. - -In {doc}`Lesson 3 ` we investigate how to filter noise out of -the measured data. diff --git a/Making_things_move/Downloads/PendulumID.any b/Motion_Capture_Movement/Downloads/PendulumID.any similarity index 100% rename from Making_things_move/Downloads/PendulumID.any rename to Motion_Capture_Movement/Downloads/PendulumID.any diff --git a/Making_things_move/Downloads/multiple.c3d b/Motion_Capture_Movement/Downloads/multiple.c3d similarity index 100% rename from Making_things_move/Downloads/multiple.c3d rename to Motion_Capture_Movement/Downloads/multiple.c3d diff --git a/Making_things_move/Downloads/multiple_with_dropout.c3d b/Motion_Capture_Movement/Downloads/multiple_with_dropout.c3d similarity index 100% rename from Making_things_move/Downloads/multiple_with_dropout.c3d rename to Motion_Capture_Movement/Downloads/multiple_with_dropout.c3d diff --git a/Making_things_move/Downloads/pendulum.any b/Motion_Capture_Movement/Downloads/pendulum.any similarity index 82% rename from Making_things_move/Downloads/pendulum.any rename to Motion_Capture_Movement/Downloads/pendulum.any index 4ebda8b6..f380bbe2 100644 --- a/Making_things_move/Downloads/pendulum.any +++ b/Motion_Capture_Movement/Downloads/pendulum.any @@ -21,6 +21,14 @@ Main = { AnyDrawSeg drw = {}; }; + AnyKinMotion JointDriver = + { + AnyRevoluteJoint &Jnt = .Joint; + AnyFunPolynomial DriverFun = { + PolyCoef = {{0, 5, -0.4}}; + }; + }; + AnyRevoluteJoint Joint = { AnyRefFrame &Ground = .GlobalRef; AnyRefFrame &Pendulum = .Pendulum.Origin; diff --git a/Making_things_move/Downloads/pendulum.c3d b/Motion_Capture_Movement/Downloads/pendulum.c3d similarity index 100% rename from Making_things_move/Downloads/pendulum.c3d rename to Motion_Capture_Movement/Downloads/pendulum.c3d diff --git a/Making_things_move/Downloads/pendulumtri.any b/Motion_Capture_Movement/Downloads/pendulumtri.any similarity index 100% rename from Making_things_move/Downloads/pendulumtri.any rename to Motion_Capture_Movement/Downloads/pendulumtri.any diff --git a/Making_things_move/material/pendulum.c3d b/Motion_Capture_Movement/Snippets/lesson2/pendulum.c3d similarity index 100% rename from Making_things_move/material/pendulum.c3d rename to Motion_Capture_Movement/Snippets/lesson2/pendulum.c3d diff --git a/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-1.any b/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-1.any new file mode 100644 index 00000000..039c5cdb --- /dev/null +++ b/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-1.any @@ -0,0 +1,89 @@ +//expect_errors = ["''", "Model loading skipped"] + +// Model for the "Making Things Move" tutorial. + +Main = { + + // The actual body model goes in this folder + AnyFolder MyModel = { + + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + }; // Global reference frame + + AnySeg Pendulum = { + Mass = 1; + Jii = {1, 0.01, 1}/15; + AnyRefNode Origin = { + sRel = {0, 0.5, 0}; + }; + AnyRefNode P1 = { + sRel = {0, -0.5, 0}; + }; + AnyDrawSeg drw = {}; + }; + +//# BEGIN SNIPPET 1 +AnyInputC3D = +{ + FileName = ""; + //ReadAllDataOnOff = On; + //TruncateExtraCharsInNamesOnOff = On; + //MakeNameUniqueStr = "_"; + //PointsScaleFactor = 1.0; + //ConstructModelOnOff = On; + //ConstructChartOnOff = On; + //ConstructWeightFunUsingResidualOnOff = Off; + //GapFillUsingResidualsOnOff = Off; + //MarkerUseAllPointsOnOff = Off; + //MarkerUseCamMaskOnOff = On; + //MarkerIndices = ; + //MarkerLabels = ; + //MarkerFilterIndex = 0; + //ProcessedDataFilterIndex = 0; + //AnalogFilterIndex = -1; + /*Filter = + { + AutomaticInitialConditionOnOff = On; + FilterForwardBackwardOnOff = On; + N = 2; + W = ; + Fs = 0.0; + Fc = {10.0}; + Type = LowPass; + };*/ + //WeightThreshold = 0.0; + //WeightOutput = {{0.0, 1.0}, {0.0, 1.0}, {0.0, 1.0}}; + //WeightTransitionTime = 0.1; + //SearchAndReplace = ; + //WriteMarkerDataToFilesOnOff = Off; + //MarkerScaleXYZ = {0.025, 0.025, 0.025}; + //MarkerRGB = {0.65, 0.65, 0.65}; + //MarkerDrawOnOff = On; + //MarkerInterPolType = Bspline; + //MarkerBsplineOrder = 4; +}; +//# END SNIPPET 1 + + AnyKinMotion JointDriver = + { + AnyRevoluteJoint &Jnt = .Joint; + AnyFunPolynomial DriverFun = { + PolyCoef = {{0, 5, -0.4}}; + }; + }; + + AnyRevoluteJoint Joint = { + AnyRefFrame &Ground = .GlobalRef; + AnyRefFrame &Pendulum = .Pendulum.Origin; + }; + + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + Gravity = {0.0, -9.81, 0.0}; + }; + +}; // Main diff --git a/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-2.any b/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-2.any new file mode 100644 index 00000000..1edb4a12 --- /dev/null +++ b/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-2.any @@ -0,0 +1,58 @@ +// Model for the "Making Things Move" tutorial. + +Main = { + + // The actual body model goes in this folder + AnyFolder MyModel = { + + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + }; // Global reference frame + + AnySeg Pendulum = { + Mass = 1; + Jii = {1, 0.01, 1}/15; + AnyRefNode Origin = { + sRel = {0, 0.5, 0}; + }; + AnyRefNode P1 = { + sRel = {0, -0.5, 0}; + }; + AnyDrawSeg drw = {}; + }; + +//# BEGIN SNIPPET 1 +AnyInputC3D §C3D§ = { + FileName = §"pendulum.c3d"§; + //TruncateExtraCharsInNamesOnOff = On; + //MakeNameUniqueStr = "_"; + //PointsScaleFactor = 1; + //ConstructModelOnOff = On; + §ConstructChartOnOff = Off;§ +}; +//# END SNIPPET 1 + + AnyKinMotion JointDriver = + { + AnyRevoluteJoint &Jnt = .Joint; + AnyFunPolynomial DriverFun = { + PolyCoef = {{0, 5, -0.4}}; + }; + }; + + AnyRevoluteJoint Joint = { + AnyRefFrame &Ground = .GlobalRef; + AnyRefFrame &Pendulum = .Pendulum.Origin; + }; + + }; // MyModel + +//# BEGIN SNIPPET 2 +// The study: Operations to be performed on the model +§//§ AnyBodyStudy MyStudy = { +§//§ AnyFolder &Model = .MyModel; +§//§ Gravity = {0.0, -9.81, 0.0}; +§//§ }; +//# END SNIPPET 2 + +}; // Main diff --git a/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-3.any b/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-3.any new file mode 100644 index 00000000..70718d75 --- /dev/null +++ b/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-3.any @@ -0,0 +1,58 @@ +// Model for the "Making Things Move" tutorial. + +Main = { + + // The actual body model goes in this folder + AnyFolder MyModel = { + + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + }; // Global reference frame + + AnySeg Pendulum = { + Mass = 1; + Jii = {1, 0.01, 1}/15; + AnyRefNode Origin = { + sRel = {0, 0.5, 0}; + }; + AnyRefNode P1 = { + sRel = {0, -0.5, 0}; + }; + AnyDrawSeg drw = {}; + }; + + AnyInputC3D C3D = { + FileName = "pendulum.c3d"; + //TruncateExtraCharsInNamesOnOff = On; + //MakeNameUniqueStr = "_"; + //PointsScaleFactor = 1; + //ConstructModelOnOff = On; + ConstructChartOnOff = Off; + }; + + AnyKinMotion JointDriver = + { + AnyRevoluteJoint &Jnt = .Joint; + AnyFunPolynomial DriverFun = { + PolyCoef = {{0, 5, -0.4}}; + }; + }; + + AnyRevoluteJoint Joint = { + AnyRefFrame &Ground = .GlobalRef; + AnyRefFrame &Pendulum = .Pendulum.Origin; + }; + + }; // MyModel + +// The study: Operations to be performed on the model +//# BEGIN SNIPPET 1 +AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + Gravity = {0.0, -9.81, 0.0}; + §tStart = 0.05; + tEnd = 9.95;§ +}; +//# END SNIPPET 1 + +}; // Main diff --git a/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-4.any b/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-4.any new file mode 100644 index 00000000..7a2c7693 --- /dev/null +++ b/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-4.any @@ -0,0 +1,78 @@ +//expect_errors = ["''", "Model loading skipped"] + +// Model for the "Making Things Move" tutorial. + +Main = { + + // The actual body model goes in this folder + AnyFolder MyModel = { + + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + }; // Global reference frame + + AnySeg Pendulum = { + Mass = 1; + Jii = {1, 0.01, 1}/15; + AnyRefNode Origin = { + sRel = {0, 0.5, 0}; + }; + AnyRefNode P1 = { + sRel = {0, -0.5, 0}; + }; + AnyDrawSeg drw = {}; + }; + + AnyInputC3D C3D = { + FileName = "pendulum.c3d"; + //TruncateExtraCharsInNamesOnOff = On; + //MakeNameUniqueStr = "_"; + //PointsScaleFactor = 1; + //ConstructModelOnOff = On; + ConstructChartOnOff = Off; + }; + +// AnyKinMotion JointDriver = +// { +// AnyRevoluteJoint &Jnt = .Joint; +// AnyFunPolynomial DriverFun = { +// PolyCoef = {{0, 5, -0.4}}; +// }; +// }; + +//# BEGIN SNIPPET 2 +§AnyKinDriverMarker = +{ + //viewKinMeasure.Visible = Off; + //MeasureOrganizer = ; + //CType = ; + //WeightFun = ; + //DriverPos0 = ; + //DriverVel0 = ; + //DriverAcc0 = ; + AnyRefFrame & = ; + //AnyRefFrame & = ; + //AnyParamFun & = ; +};§ +//# END SNIPPET 2 + + AnyRevoluteJoint Joint = { + AnyRefFrame &Ground = .GlobalRef; + AnyRefFrame &Pendulum = .Pendulum.Origin; + }; + + }; // MyModel + +// The study: Operations to be performed on the model +//# BEGIN SNIPPET 1 +AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + Gravity = {0.0, -9.81, 0.0}; + §AnyIntVar FirstFrame = Main.MyModel.C3D.Header.FirstFrameNo; + AnyIntVar LastFrame = Main.MyModel.C3D.Header.LastFrameNo; + tStart = FirstFrame/Main.MyModel.C3D.Header.VideoFrameRate+2*Kinematics.ApproxVelAccPerturb; + tEnd = LastFrame/Main.MyModel.C3D.Header.VideoFrameRate-2*Kinematics.ApproxVelAccPerturb;§ +}; +//# END SNIPPET 1 + +}; // Main diff --git a/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-5.any b/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-5.any new file mode 100644 index 00000000..32714137 --- /dev/null +++ b/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-5.any @@ -0,0 +1,74 @@ +// Model for the "Making Things Move" tutorial. + +Main = { + + // The actual body model goes in this folder + AnyFolder MyModel = { + + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + }; // Global reference frame + + AnySeg Pendulum = { + Mass = 1; + Jii = {1, 0.01, 1}/15; + AnyRefNode Origin = { + sRel = {0, 0.5, 0}; + }; + AnyRefNode P1 = { + sRel = {0, -0.5, 0}; + }; + AnyDrawSeg drw = {}; + }; + + AnyInputC3D C3D = { + FileName = "pendulum.c3d"; + //TruncateExtraCharsInNamesOnOff = On; + //MakeNameUniqueStr = "_"; + //PointsScaleFactor = 1; + //ConstructModelOnOff = On; + ConstructChartOnOff = Off; + }; + +// AnyKinMotion JointDriver = +// { +// AnyRevoluteJoint &Jnt = .Joint; +// AnyFunPolynomial DriverFun = { +// PolyCoef = {{0, 5, -0.4}}; +// }; +// }; + +//# BEGIN SNIPPET 1 +AnyKinDriverMarker §C3DMotion§ = +{ + //viewKinMeasure.Visible = Off; + //MeasureOrganizer = ; + //CType = ; + //WeightFun = ; + //DriverPos0 = ; + //DriverVel0 = ; + //DriverAcc0 = ; + §AnyRefFrame &Marker = .Pendulum.P1;§ + //AnyRefFrame & = ; + //AnyParamFun & = ; +}; +//# END SNIPPET 1 + + AnyRevoluteJoint Joint = { + AnyRefFrame &Ground = .GlobalRef; + AnyRefFrame &Pendulum = .Pendulum.Origin; + }; + + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + Gravity = {0.0, -9.81, 0.0}; + AnyIntVar FirstFrame = Main.MyModel.C3D.Header.FirstFrameNo; + AnyIntVar LastFrame = Main.MyModel.C3D.Header.LastFrameNo; + tStart = FirstFrame/Main.MyModel.C3D.Header.VideoFrameRate+2*Kinematics.ApproxVelAccPerturb; + tEnd = LastFrame/Main.MyModel.C3D.Header.VideoFrameRate-2*Kinematics.ApproxVelAccPerturb; + }; + +}; // Main diff --git a/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-6.any b/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-6.any new file mode 100644 index 00000000..e1fb3e1e --- /dev/null +++ b/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-6.any @@ -0,0 +1,80 @@ +// Model for the "Making Things Move" tutorial. + +Main = { + + // The actual body model goes in this folder + AnyFolder MyModel = { + + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + }; // Global reference frame + + AnySeg Pendulum = { + Mass = 1; + Jii = {1, 0.01, 1}/15; + AnyRefNode Origin = { + sRel = {0, 0.5, 0}; + }; + AnyRefNode P1 = { + sRel = {0, -0.5, 0}; + }; + AnyDrawSeg drw = {}; + }; + +//# BEGIN SNIPPET 3 +AnyInputC3D C3D = { + FileName = "pendulum.c3d"; + //TruncateExtraCharsInNamesOnOff = On; + //MakeNameUniqueStr = "_"; + //PointsScaleFactor = 1; + §ConstructModelOnOff = Off;§ + ConstructChartOnOff = Off; +}; +//# END SNIPPET 3 + +// AnyKinMotion JointDriver = +// { +// AnyRevoluteJoint &Jnt = .Joint; +// AnyFunPolynomial DriverFun = { +// PolyCoef = {{0, 5, -0.4}}; +// }; +// }; + +//# BEGIN SNIPPET 1 +AnyKinDriverMarker C3DMotion = +{ + //viewKinMeasure.Visible = Off; + //MeasureOrganizer = ; + //CType = ; + //WeightFun = ; + //DriverPos0 = ; + //DriverVel0 = ; + //DriverAcc0 = ; + AnyRefFrame &Marker = .Pendulum.P1; + //AnyRefFrame & = ; + §AnyParamFun &Trajectory = Main.MyModel.C3D.Points.Markers.L000.PosInterpol;§ +}; +//# END SNIPPET 1 + + AnyRevoluteJoint Joint = { + AnyRefFrame &Ground = .GlobalRef; + AnyRefFrame &Pendulum = .Pendulum.Origin; + }; + + }; // MyModel + + // The study: Operations to be performed on the model +//# BEGIN SNIPPET 2 +AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + Gravity = {0.0, -9.81, 0.0}; + AnyIntVar FirstFrame = Main.MyModel.C3D.Header.FirstFrameNo; + AnyIntVar LastFrame = Main.MyModel.C3D.Header.LastFrameNo; + tStart = FirstFrame/Main.MyModel.C3D.Header.VideoFrameRate+2*Kinematics.ApproxVelAccPerturb; + tEnd = LastFrame/Main.MyModel.C3D.Header.VideoFrameRate-2*Kinematics.ApproxVelAccPerturb; + §InitialConditions.SolverType = KinSolOverDeterminate; + Kinematics.SolverType = KinSolOverDeterminate;§ +}; +//# END SNIPPET 2 + +}; // Main diff --git a/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-7.any b/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-7.any new file mode 100644 index 00000000..e9c69e29 --- /dev/null +++ b/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-7.any @@ -0,0 +1,83 @@ +// Model for the "Making Things Move" tutorial. + +Main = { + + // The actual body model goes in this folder + AnyFolder MyModel = { + + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + }; // Global reference frame + + AnySeg Pendulum = { + Mass = 1; + Jii = {1, 0.01, 1}/15; + AnyRefNode Origin = { + sRel = {0, 0.5, 0}; + }; + AnyRefNode P1 = { + sRel = {0, -0.5, 0}; + }; + AnyDrawSeg drw = {}; + }; + + AnyInputC3D C3D = { + FileName = "pendulum.c3d"; + //TruncateExtraCharsInNamesOnOff = On; + //MakeNameUniqueStr = "_"; + //PointsScaleFactor = 1; + ConstructModelOnOff = Off; + ConstructChartOnOff = Off; + }; + +// AnyKinMotion JointDriver = +// { +// AnyRevoluteJoint &Jnt = .Joint; +// AnyFunPolynomial DriverFun = { +// PolyCoef = {{0, 5, -0.4}}; +// }; +// }; + +//# BEGIN SNIPPET 1 +AnyKinDriverMarker C3DMotion = +{ + //viewKinMeasure.Visible = Off; + //MeasureOrganizer = ; + //CType = ; + //WeightFun = ; + //DriverPos0 = ; + //DriverVel0 = ; + //DriverAcc0 = ; + AnyRefFrame &Marker = .Pendulum.P1; + //AnyRefFrame & = ; + AnyParamFun &Trajectory = Main.MyModel.C3D.Points.Markers.L000.PosInterpol; + + §AnyDrawKinMeasure drw = + { + //Label = On; + //Size = 0.02; + //Line = On; + };§ +}; +//# END SNIPPET 1 + + AnyRevoluteJoint Joint = { + AnyRefFrame &Ground = .GlobalRef; + AnyRefFrame &Pendulum = .Pendulum.Origin; + }; + + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + Gravity = {0.0, -9.81, 0.0}; + AnyIntVar FirstFrame = Main.MyModel.C3D.Header.FirstFrameNo; + AnyIntVar LastFrame = Main.MyModel.C3D.Header.LastFrameNo; + tStart = FirstFrame/Main.MyModel.C3D.Header.VideoFrameRate+2*Kinematics.ApproxVelAccPerturb; + tEnd = LastFrame/Main.MyModel.C3D.Header.VideoFrameRate-2*Kinematics.ApproxVelAccPerturb; + InitialConditions.SolverType = KinSolOverDeterminate; + Kinematics.SolverType = KinSolOverDeterminate; + }; + +}; // Main diff --git a/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-8.any b/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-8.any new file mode 100644 index 00000000..29b047f8 --- /dev/null +++ b/Motion_Capture_Movement/Snippets/lesson2/snip.Pendulum.main-8.any @@ -0,0 +1,82 @@ +// Model for the "Making Things Move" tutorial. + +Main = { + + // The actual body model goes in this folder + AnyFolder MyModel = { + + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + }; // Global reference frame + + AnySeg Pendulum = { + Mass = 1; + Jii = {1, 0.01, 1}/15; + AnyRefNode Origin = { + sRel = {0, 0.5, 0}; + }; + AnyRefNode P1 = { + sRel = {0, -0.5, 0}; + }; + AnyDrawSeg drw = {}; + }; + + AnyInputC3D C3D = { + FileName = "pendulum.c3d"; + //TruncateExtraCharsInNamesOnOff = On; + //MakeNameUniqueStr = "_"; + //PointsScaleFactor = 1; + ConstructModelOnOff = Off; + ConstructChartOnOff = Off; + }; + +// AnyKinMotion JointDriver = +// { +// AnyRevoluteJoint &Jnt = .Joint; +// AnyFunPolynomial DriverFun = { +// PolyCoef = {{0, 5, -0.4}}; +// }; +// }; + +AnyKinDriverMarker C3DMotion = +{ + //viewKinMeasure.Visible = Off; + //MeasureOrganizer = ; + //CType = ; + //WeightFun = ; + //DriverPos0 = ; + //DriverVel0 = ; + //DriverAcc0 = ; + AnyRefFrame &Marker = .Pendulum.P1; + //AnyRefFrame & = ; + AnyParamFun &Trajectory = Main.MyModel.C3D.Points.Markers.L000.PosInterpol; +//# BEGIN SNIPPET 1 +AnyDrawKinMeasure drw = +{ + §Label = Off; + Size = 0.07; + Line = Off;§ +}; +//# END SNIPPET 1 +}; + + AnyRevoluteJoint Joint = { + AnyRefFrame &Ground = .GlobalRef; + AnyRefFrame &Pendulum = .Pendulum.Origin; + }; + + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + Gravity = {0.0, -9.81, 0.0}; + AnyIntVar FirstFrame = Main.MyModel.C3D.Header.FirstFrameNo; + AnyIntVar LastFrame = Main.MyModel.C3D.Header.LastFrameNo; + tStart = FirstFrame/Main.MyModel.C3D.Header.VideoFrameRate+2*Kinematics.ApproxVelAccPerturb; + tEnd = LastFrame/Main.MyModel.C3D.Header.VideoFrameRate-2*Kinematics.ApproxVelAccPerturb; + InitialConditions.SolverType = KinSolOverDeterminate; + Kinematics.SolverType = KinSolOverDeterminate; + }; + +}; // Main diff --git a/Motion_Capture_Movement/Snippets/lesson3/pendulum.c3d b/Motion_Capture_Movement/Snippets/lesson3/pendulum.c3d new file mode 100644 index 00000000..3f448426 Binary files /dev/null and b/Motion_Capture_Movement/Snippets/lesson3/pendulum.c3d differ diff --git a/Motion_Capture_Movement/Snippets/lesson3/snip.Pendulum.main-1.any b/Motion_Capture_Movement/Snippets/lesson3/snip.Pendulum.main-1.any new file mode 100644 index 00000000..2ff07e33 --- /dev/null +++ b/Motion_Capture_Movement/Snippets/lesson3/snip.Pendulum.main-1.any @@ -0,0 +1,95 @@ +//expect_errors = ["';' unexpected", "Model loading skipped"] + +// Model for the "Making Things Move" tutorial. + +Main = { + + // The actual body model goes in this folder + AnyFolder MyModel = { + + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + }; // Global reference frame + + AnySeg Pendulum = { + Mass = 1; + Jii = {1, 0.01, 1}/15; + AnyRefNode Origin = { + sRel = {0, 0.5, 0}; + }; + AnyRefNode P1 = { + sRel = {0, -0.5, 0}; + }; + AnyDrawSeg drw = {}; + }; + +//# BEGIN SNIPPET 1 +AnyInputC3D C3D = { + FileName = "pendulum.c3d"; + //TruncateExtraCharsInNamesOnOff = On; + //MakeNameUniqueStr = "_"; + //PointsScaleFactor = 1; + ConstructModelOnOff = Off; + ConstructChartOnOff = Off; + §Filter = + { + z0 = ; + AutomaticInitialConditionOnOff = On; + FilterForwardBackwardOnOff = On; + N = 2; + W = ; + Fs = 0.0; + Fc = {10.0}; + Type = LowPass; + };§ +}; +//# END SNIPPET 1 + +// AnyKinMotion JointDriver = +// { +// AnyRevoluteJoint &Jnt = .Joint; +// AnyFunPolynomial DriverFun = { +// PolyCoef = {{0, 5, -0.4}}; +// }; +// }; + + AnyKinDriverMarker C3DMotion = + { + //viewKinMeasure.Visible = Off; + //MeasureOrganizer = ; + //CType = ; + //WeightFun = ; + //DriverPos0 = ; + //DriverVel0 = ; + //DriverAcc0 = ; + AnyRefFrame &Marker = .Pendulum.P1; + //AnyRefFrame & = ; + AnyParamFun &Trajectory = Main.MyModel.C3D.Points.Markers.L000.PosInterpol; + AnyDrawKinMeasure drw = + { + Label = Off; + Size = 0.07; + Line = Off; + }; + }; + + AnyRevoluteJoint Joint = { + AnyRefFrame &Ground = .GlobalRef; + AnyRefFrame &Pendulum = .Pendulum.Origin; + }; + + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + Gravity = {0.0, -9.81, 0.0}; + AnyIntVar FirstFrame = Main.MyModel.C3D.Header.FirstFrameNo; + AnyIntVar LastFrame = Main.MyModel.C3D.Header.LastFrameNo; + tStart = FirstFrame/Main.MyModel.C3D.Header.VideoFrameRate+2*Kinematics.ApproxVelAccPerturb; + tEnd = LastFrame/Main.MyModel.C3D.Header.VideoFrameRate-2*Kinematics.ApproxVelAccPerturb; + InitialConditions.SolverType = KinSolOverDeterminate; + Kinematics.SolverType = KinSolOverDeterminate; + }; + +}; // Main diff --git a/Motion_Capture_Movement/Snippets/lesson3/snip.Pendulum.main-2.any b/Motion_Capture_Movement/Snippets/lesson3/snip.Pendulum.main-2.any new file mode 100644 index 00000000..417bbe5f --- /dev/null +++ b/Motion_Capture_Movement/Snippets/lesson3/snip.Pendulum.main-2.any @@ -0,0 +1,95 @@ +//expect_errors = ["';' unexpected", "Model loading skipped"] + +// Model for the "Making Things Move" tutorial. + +Main = { + + // The actual body model goes in this folder + AnyFolder MyModel = { + + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + }; // Global reference frame + + AnySeg Pendulum = { + Mass = 1; + Jii = {1, 0.01, 1}/15; + AnyRefNode Origin = { + sRel = {0, 0.5, 0}; + }; + AnyRefNode P1 = { + sRel = {0, -0.5, 0}; + }; + AnyDrawSeg drw = {}; + }; + +AnyInputC3D C3D = { + FileName = "pendulum.c3d"; + //TruncateExtraCharsInNamesOnOff = On; + //MakeNameUniqueStr = "_"; + //PointsScaleFactor = 1; + ConstructModelOnOff = Off; + ConstructChartOnOff = Off; +//# BEGIN SNIPPET 1 +Filter = +{ + §// z0 = ;§ + AutomaticInitialConditionOnOff = On; + FilterForwardBackwardOnOff = On; + N = 2; + W = ; + Fs = 0.0; + Fc = {10.0}; + Type = LowPass; +}; +//# END SNIPPET 1 +}; + +// AnyKinMotion JointDriver = +// { +// AnyRevoluteJoint &Jnt = .Joint; +// AnyFunPolynomial DriverFun = { +// PolyCoef = {{0, 5, -0.4}}; +// }; +// }; + + AnyKinDriverMarker C3DMotion = + { + //viewKinMeasure.Visible = Off; + //MeasureOrganizer = ; + //CType = ; + //WeightFun = ; + //DriverPos0 = ; + //DriverVel0 = ; + //DriverAcc0 = ; + AnyRefFrame &Marker = .Pendulum.P1; + //AnyRefFrame & = ; + AnyParamFun &Trajectory = Main.MyModel.C3D.Points.Markers.L000.PosInterpol; + AnyDrawKinMeasure drw = + { + Label = Off; + Size = 0.07; + Line = Off; + }; + }; + + AnyRevoluteJoint Joint = { + AnyRefFrame &Ground = .GlobalRef; + AnyRefFrame &Pendulum = .Pendulum.Origin; + }; + + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + Gravity = {0.0, -9.81, 0.0}; + AnyIntVar FirstFrame = Main.MyModel.C3D.Header.FirstFrameNo; + AnyIntVar LastFrame = Main.MyModel.C3D.Header.LastFrameNo; + tStart = FirstFrame/Main.MyModel.C3D.Header.VideoFrameRate+2*Kinematics.ApproxVelAccPerturb; + tEnd = LastFrame/Main.MyModel.C3D.Header.VideoFrameRate-2*Kinematics.ApproxVelAccPerturb; + InitialConditions.SolverType = KinSolOverDeterminate; + Kinematics.SolverType = KinSolOverDeterminate; + }; + +}; // Main diff --git a/Motion_Capture_Movement/Snippets/lesson3/snip.Pendulum.main-3.any b/Motion_Capture_Movement/Snippets/lesson3/snip.Pendulum.main-3.any new file mode 100644 index 00000000..632d24c8 --- /dev/null +++ b/Motion_Capture_Movement/Snippets/lesson3/snip.Pendulum.main-3.any @@ -0,0 +1,91 @@ +// Model for the "Making Things Move" tutorial. + +Main = { + + // The actual body model goes in this folder + AnyFolder MyModel = { + + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + }; // Global reference frame + + AnySeg Pendulum = { + Mass = 1; + Jii = {1, 0.01, 1}/15; + AnyRefNode Origin = { + sRel = {0, 0.5, 0}; + }; + AnyRefNode P1 = { + sRel = {0, -0.5, 0}; + }; + AnyDrawSeg drw = {}; + }; + +AnyInputC3D C3D = { + FileName = "pendulum.c3d"; + //TruncateExtraCharsInNamesOnOff = On; + //MakeNameUniqueStr = "_"; + //PointsScaleFactor = 1; + ConstructModelOnOff = Off; + ConstructChartOnOff = Off; +//# BEGIN SNIPPET 1 +Filter = +{ + // z0 = ; + AutomaticInitialConditionOnOff = On; + FilterForwardBackwardOnOff = On; + N = 2; + Fc = {§2§}; + Type = LowPass; +}; +//# END SNIPPET 1 +}; + +// AnyKinMotion JointDriver = +// { +// AnyRevoluteJoint &Jnt = .Joint; +// AnyFunPolynomial DriverFun = { +// PolyCoef = {{0, 5, -0.4}}; +// }; +// }; + + AnyKinDriverMarker C3DMotion = + { + //viewKinMeasure.Visible = Off; + //MeasureOrganizer = ; + //CType = ; + //WeightFun = ; + //DriverPos0 = ; + //DriverVel0 = ; + //DriverAcc0 = ; + AnyRefFrame &Marker = .Pendulum.P1; + //AnyRefFrame & = ; + AnyParamFun &Trajectory = Main.MyModel.C3D.Points.Markers.L000.PosInterpol; + AnyDrawKinMeasure drw = + { + Label = Off; + Size = 0.07; + Line = Off; + }; + }; + + AnyRevoluteJoint Joint = { + AnyRefFrame &Ground = .GlobalRef; + AnyRefFrame &Pendulum = .Pendulum.Origin; + }; + + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + Gravity = {0.0, -9.81, 0.0}; + AnyIntVar FirstFrame = Main.MyModel.C3D.Header.FirstFrameNo; + AnyIntVar LastFrame = Main.MyModel.C3D.Header.LastFrameNo; + tStart = FirstFrame/Main.MyModel.C3D.Header.VideoFrameRate+2*Kinematics.ApproxVelAccPerturb; + tEnd = LastFrame/Main.MyModel.C3D.Header.VideoFrameRate-2*Kinematics.ApproxVelAccPerturb; + InitialConditions.SolverType = KinSolOverDeterminate; + Kinematics.SolverType = KinSolOverDeterminate; + }; + +}; // Main diff --git a/Making_things_move/material/multiple.c3d b/Motion_Capture_Movement/Snippets/lesson4/multiple.c3d similarity index 100% rename from Making_things_move/material/multiple.c3d rename to Motion_Capture_Movement/Snippets/lesson4/multiple.c3d diff --git a/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-1.any b/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-1.any new file mode 100644 index 00000000..54e6edd4 --- /dev/null +++ b/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-1.any @@ -0,0 +1,66 @@ +// Todo: Write a small description of your model here +//# BEGIN SNIPPET 1 +Main = { + + // The actual body model goes in this folder + AnyFolder MyModel = { + + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + + }; + + AnyInputC3D §C3D§ = + { + FileName = §"multiple.c3d"§; + //ReadAllDataOnOff = On; + //TruncateExtraCharsInNamesOnOff = On; + //MakeNameUniqueStr = "_"; + //PointsScaleFactor = 1.0; + //ConstructModelOnOff = On; + §ConstructChartOnOff = Off;§ + //ConstructWeightFunUsingResidualOnOff = Off; + //GapFillUsingResidualsOnOff = Off; + //MarkerUseAllPointsOnOff = Off; + //MarkerUseCamMaskOnOff = On; + //MarkerIndices = ; + //MarkerLabels = ; + //MarkerFilterIndex = 0; + //ProcessedDataFilterIndex = 0; + //AnalogFilterIndex = -1; + §Filter = + { + AutomaticInitialConditionOnOff = On; + FilterForwardBackwardOnOff = On; + N = 2; + Fc = {3}; + Type = LowPass; + };§ + //WeightThreshold = 0.0; + //WeightOutput = {{0.0, 1.0}, {0.0, 1.0}, {0.0, 1.0}}; + //WeightTransitionTime = 0.1; + //SearchAndReplace = ; + //WriteMarkerDataToFilesOnOff = Off; + //MarkerScaleXYZ = {0.025, 0.025, 0.025}; + §MarkerRGB = {0, 0, 1};§ + //MarkerDrawOnOff = On; + //MarkerInterPolType = Bspline; + //MarkerBsplineOrder = 4; + }; + //# END SNIPPET 1 + + }; + +//# BEGIN SNIPPET 2 +// The study: Operations to be performed on the model +AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + Gravity = {0.0, -9.81, 0.0}; + §AnyIntVar FirstFrame = Main.MyModel.C3D.Header.FirstFrameNo; + AnyIntVar LastFrame = Main.MyModel.C3D.Header.LastFrameNo; + tStart = FirstFrame/Main.MyModel.C3D.Header.VideoFrameRate+2*Kinematics.ApproxVelAccPerturb; + tEnd = LastFrame/Main.MyModel.C3D.Header.VideoFrameRate-2*Kinematics.ApproxVelAccPerturb;§ +}; +//# END SNIPPET 2 + +}; \ No newline at end of file diff --git a/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-2.any b/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-2.any new file mode 100644 index 00000000..05d57c8b --- /dev/null +++ b/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-2.any @@ -0,0 +1,106 @@ +// Todo: Write a small description of your model here +//# BEGIN SNIPPET 1 +Main = { + + // The actual body model goes in this folder + AnyFolder MyModel = { + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + }; + + §AnySeg Leg = { + Mass = 1; + Jii = {1, 0.01, 1}/15; + AnyRefNode R1 = { + sRel = {0.038, 0.18, 0.022}; + }; + AnyRefNode R2 = { + sRel = {-0.015, -0.104, 0.028}; + }; + AnyRefNode R3 = { + sRel = {-0.022, -0.403, -0.023}; + }; + AnyDrawSeg drw = {}; + };§ + //# END SNIPPET 1 + +//# BEGIN SNIPPET 3 +AnyInputC3D C3D = +{ + FileName = "multiple.c3d"; + //ReadAllDataOnOff = On; + //TruncateExtraCharsInNamesOnOff = On; + //MakeNameUniqueStr = "_"; + //PointsScaleFactor = 1.0; + §ConstructModelOnOff = Off;§ + ConstructChartOnOff = Off; + //ConstructWeightFunUsingResidualOnOff = Off; + //GapFillUsingResidualsOnOff = Off; +//# END SNIPPET 3 + //MarkerUseAllPointsOnOff = Off; + //MarkerUseCamMaskOnOff = On; + //MarkerIndices = ; + //MarkerLabels = ; + //MarkerFilterIndex = 0; + //ProcessedDataFilterIndex = 0; + //AnalogFilterIndex = -1; + Filter = + { + AutomaticInitialConditionOnOff = On; + FilterForwardBackwardOnOff = On; + N = 2; + Fc = {3}; + Type = LowPass; + }; + //WeightThreshold = 0.0; + //WeightOutput = {{0.0, 1.0}, {0.0, 1.0}, {0.0, 1.0}}; + //WeightTransitionTime = 0.1; + //SearchAndReplace = ; + //WriteMarkerDataToFilesOnOff = Off; + //MarkerScaleXYZ = {0.025, 0.025, 0.025}; + MarkerRGB = {0, 0, 1}; + //MarkerDrawOnOff = On; + //MarkerInterPolType = Bspline; + //MarkerBsplineOrder = 4; + }; + + //# BEGIN SNIPPET 2 + §AnyKinDriverMarker C3Dmotion1 = { + AnyRefFrame &Marker = .Leg.R1; + AnyParamFun &Trajectory= + Main.MyModel.C3D.Points.Markers.L000.PosInterpol; + AnyDrawKinMeasure drw = { + Label = Off;Size = 0.03;Line = Off; + }; + }; + AnyKinDriverMarker C3Dmotion2 = { + AnyRefFrame &Marker = .Leg.R2; + AnyParamFun &Trajectory = + Main.MyModel.C3D.Points.Markers.L001.PosInterpol; + AnyDrawKinMeasure drw = { + Label = Off;Size = 0.03;Line = Off; + }; + }; + AnyKinDriverMarker C3Dmotion3 = { + AnyRefFrame &Marker = .Leg.R3; + AnyParamFun &Trajectory = + Main.MyModel.C3D.Points.Markers.L002.PosInterpol; + AnyDrawKinMeasure drw = { + Label = Off;Size = 0.03;Line = Off; + }; + };§ +}; // MyModel + +// The study: Operations to be performed on the model +AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + Gravity = {0.0, -9.81, 0.0}; + AnyIntVar FirstFrame = Main.MyModel.C3D.Header.FirstFrameNo; + AnyIntVar LastFrame = Main.MyModel.C3D.Header.LastFrameNo; + tStart = FirstFrame/Main.MyModel.C3D.Header.VideoFrameRate+2*Kinematics.ApproxVelAccPerturb; + tEnd = LastFrame/Main.MyModel.C3D.Header.VideoFrameRate-2*Kinematics.ApproxVelAccPerturb; + §InitialConditions.SolverType = KinSolOverDeterminate; + Kinematics.SolverType = KinSolOverDeterminate;§ +}; +//# END SNIPPET 2 +}; \ No newline at end of file diff --git a/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-3.any b/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-3.any new file mode 100644 index 00000000..01e5a25e --- /dev/null +++ b/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-3.any @@ -0,0 +1,107 @@ +// Todo: Write a small description of your model here +Main = { + + // The actual body model goes in this folder +//# BEGIN SNIPPET 2 +AnyFolder MyModel = { + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + §AnyDrawRefFrame drw = {};§ + }; + //# END SNIPPET 2 + +//# BEGIN SNIPPET 1 +AnySeg Leg = { + Mass = 1; + Jii = {1, 0.01, 1}/15; + AnyRefNode R1 = { + sRel = {0.038, 0.18, 0.022}; + }; + AnyRefNode R2 = { + sRel = {-0.015, -0.104, 0.028}; + }; + AnyRefNode R3 = { + sRel = {-0.022, -0.403, -0.023}; + }; + AnyDrawSeg drw = { + §Opacity = 0.5;§ + }; +}; +//# END SNIPPET 1 + + AnyInputC3D C3D = + { + FileName = "multiple.c3d"; + //ReadAllDataOnOff = On; + //TruncateExtraCharsInNamesOnOff = On; + //MakeNameUniqueStr = "_"; + //PointsScaleFactor = 1.0; + ConstructModelOnOff = Off; + ConstructChartOnOff = Off; + //ConstructWeightFunUsingResidualOnOff = Off; + //GapFillUsingResidualsOnOff = Off; + //MarkerUseAllPointsOnOff = Off; + //MarkerUseCamMaskOnOff = On; + //MarkerIndices = ; + //MarkerLabels = ; + //MarkerFilterIndex = 0; + //ProcessedDataFilterIndex = 0; + //AnalogFilterIndex = -1; + Filter = + { + AutomaticInitialConditionOnOff = On; + FilterForwardBackwardOnOff = On; + N = 2; + Fc = {3}; + Type = LowPass; + }; + //WeightThreshold = 0.0; + //WeightOutput = {{0.0, 1.0}, {0.0, 1.0}, {0.0, 1.0}}; + //WeightTransitionTime = 0.1; + //SearchAndReplace = ; + //WriteMarkerDataToFilesOnOff = Off; + //MarkerScaleXYZ = {0.025, 0.025, 0.025}; + MarkerRGB = {0, 0, 1}; + //MarkerDrawOnOff = On; + //MarkerInterPolType = Bspline; + //MarkerBsplineOrder = 4; + }; + + AnyKinDriverMarker C3Dmotion1 = { + AnyRefFrame &Marker = .Leg.R1; + AnyParamFun &Trajectory= + Main.MyModel.C3D.Points.Markers.L000.PosInterpol; + AnyDrawKinMeasure drw = { + Label = Off;Size = 0.03;Line = Off; + }; + }; + AnyKinDriverMarker C3Dmotion2 = { + AnyRefFrame &Marker = .Leg.R2; + AnyParamFun &Trajectory = + Main.MyModel.C3D.Points.Markers.L001.PosInterpol; + AnyDrawKinMeasure drw = { + Label = Off;Size = 0.03;Line = Off; + }; + }; + AnyKinDriverMarker C3Dmotion3 = { + AnyRefFrame &Marker = .Leg.R3; + AnyParamFun &Trajectory = + Main.MyModel.C3D.Points.Markers.L002.PosInterpol; + AnyDrawKinMeasure drw = { + Label = Off;Size = 0.03;Line = Off; + }; + }; + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + Gravity = {0.0, -9.81, 0.0}; + AnyIntVar FirstFrame = Main.MyModel.C3D.Header.FirstFrameNo; + AnyIntVar LastFrame = Main.MyModel.C3D.Header.LastFrameNo; + tStart = FirstFrame/Main.MyModel.C3D.Header.VideoFrameRate+2*Kinematics.ApproxVelAccPerturb; + tEnd = LastFrame/Main.MyModel.C3D.Header.VideoFrameRate-2*Kinematics.ApproxVelAccPerturb; + InitialConditions.SolverType = KinSolOverDeterminate; + Kinematics.SolverType = KinSolOverDeterminate; + }; +}; \ No newline at end of file diff --git a/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-4.any b/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-4.any new file mode 100644 index 00000000..32185ea0 --- /dev/null +++ b/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-4.any @@ -0,0 +1,142 @@ +//expect_errors = ["''", "Model loading skipped"] + +// Todo: Write a small description of your model here +Main = { + + // The actual body model goes in this folder + AnyFolder MyModel = { + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + AnyDrawRefFrame drw = {}; + }; +//# BEGIN SNIPPET 1 +AnySeg Leg = { + Mass = 1; + Jii = {1, 0.01, 1}/15; + §AnyRefNode Joint = { + sRel = {0, 0.45, 0}; + };§ + AnyRefNode R1 = { + sRel = {0.038, 0.18, 0.022}; + }; + AnyRefNode R2 = { + sRel = {-0.015, -0.104, 0.028}; + }; + AnyRefNode R3 = { + sRel = {-0.022, -0.403, -0.023}; + }; + AnyDrawSeg drw = { + Opacity = 0.5; + }; +}; +//# END SNIPPET 1 + +//# BEGIN SNIPPET 2 +§AnyRevoluteJoint Joint = { + AnyRefFrame &Ground = .GlobalRef; + AnyRefFrame &Pendulum = .Leg.Joint; +};§ + +AnyInputC3D C3D = +{ + FileName = "multiple.c3d"; +//# END SNIPPET 2 + //ReadAllDataOnOff = On; + //TruncateExtraCharsInNamesOnOff = On; + //MakeNameUniqueStr = "_"; + //PointsScaleFactor = 1.0; + ConstructModelOnOff = Off; + ConstructChartOnOff = Off; + //ConstructWeightFunUsingResidualOnOff = Off; + //GapFillUsingResidualsOnOff = Off; + //MarkerUseAllPointsOnOff = Off; + //MarkerUseCamMaskOnOff = On; + //MarkerIndices = ; + //MarkerLabels = ; + //MarkerFilterIndex = 0; + //ProcessedDataFilterIndex = 0; + //AnalogFilterIndex = -1; + Filter = + { + AutomaticInitialConditionOnOff = On; + FilterForwardBackwardOnOff = On; + N = 2; + Fc = {3}; + Type = LowPass; + }; + //WeightThreshold = 0.0; + //WeightOutput = {{0.0, 1.0}, {0.0, 1.0}, {0.0, 1.0}}; + //WeightTransitionTime = 0.1; + //SearchAndReplace = ; + //WriteMarkerDataToFilesOnOff = Off; + //MarkerScaleXYZ = {0.025, 0.025, 0.025}; + MarkerRGB = {0, 0, 1}; + //MarkerDrawOnOff = On; + //MarkerInterPolType = Bspline; + //MarkerBsplineOrder = 4; + }; + + AnyKinDriverMarker C3Dmotion1 = { + AnyRefFrame &Marker = .Leg.R1; + AnyParamFun &Trajectory= + Main.MyModel.C3D.Points.Markers.L000.PosInterpol; + AnyDrawKinMeasure drw = { + Label = Off;Size = 0.03;Line = Off; + }; + }; + AnyKinDriverMarker C3Dmotion2 = { + AnyRefFrame &Marker = .Leg.R2; + AnyParamFun &Trajectory = + Main.MyModel.C3D.Points.Markers.L001.PosInterpol; + AnyDrawKinMeasure drw = { + Label = Off;Size = 0.03;Line = Off; + }; + }; + AnyKinDriverMarker C3Dmotion3 = { + AnyRefFrame &Marker = .Leg.R3; + AnyParamFun &Trajectory = + Main.MyModel.C3D.Points.Markers.L002.PosInterpol; + AnyDrawKinMeasure drw = { + Label = Off;Size = 0.03;Line = Off; + }; + }; + }; // MyModel + + // The study: Operations to be performed on the model +//# BEGIN SNIPPET 3 +AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + Gravity = {0.0, -9.81, 0.0}; + AnyIntVar FirstFrame = Main.MyModel.C3D.Header.FirstFrameNo; + AnyIntVar LastFrame = Main.MyModel.C3D.Header.LastFrameNo; + tStart = FirstFrame/Main.MyModel.C3D.Header.VideoFrameRate+2*Kinematics.ApproxVelAccPerturb; + tEnd = LastFrame/Main.MyModel.C3D.Header.VideoFrameRate-2*Kinematics.ApproxVelAccPerturb; + InitialConditions.SolverType = KinSolOverDeterminate; + Kinematics.SolverType = KinSolOverDeterminate; +}; + +§AnyOptKinStudy = +{ + //LogFile = ""; + /*Analysis = + { + Settings = + { + Echo = On; + ModelSceneUpdate = On; + DisplayPriority = PriorityNormal; + SelectOnLoad = Off; + EchoRunDuration = Off; + }; + //AnyOperation & = ; + //AnyOperation & = ; You can make any number of AnyOperation objects! + };*/ + //MaxIterationStep = 100; + //AnyDesVar & = ; + //AnyDesVar & = ; You can make any number of AnyDesVar objects! + AnyDesMeasure & = ; + //AnyDesMeasure & = ; + //AnyDesMeasure & = ; You can make any number of AnyDesMeasure objects! +};§ +//# END SNIPPET 3 +}; \ No newline at end of file diff --git a/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-5.any b/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-5.any new file mode 100644 index 00000000..9caeb387 --- /dev/null +++ b/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-5.any @@ -0,0 +1,122 @@ +//expect_errors = ["' = ; +}; +//# END SNIPPET 1 +}; \ No newline at end of file diff --git a/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-6.any b/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-6.any new file mode 100644 index 00000000..6dbfa207 --- /dev/null +++ b/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-6.any @@ -0,0 +1,128 @@ +// Todo: Write a small description of your model here +Main = { + + // The actual body model goes in this folder + AnyFolder MyModel = { + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + AnyDrawRefFrame drw = {}; + }; + AnySeg Leg = { + Mass = 1; + Jii = {1, 0.01, 1}/15; + AnyRefNode Joint = { + sRel = {0, 0.45, 0}; + }; + AnyRefNode R1 = { + sRel = {0.038, 0.18, 0.022}; + }; + AnyRefNode R2 = { + sRel = {-0.015, -0.104, 0.028}; + }; + AnyRefNode R3 = { + sRel = {-0.022, -0.403, -0.023}; + }; + AnyDrawSeg drw = { + Opacity = 0.5; + }; + }; + AnyRevoluteJoint Joint = { + AnyRefFrame &Ground = .GlobalRef; + AnyRefFrame &Pendulum = .Leg.Joint; + }; + + AnyInputC3D C3D = + { + FileName = "multiple.c3d"; + //ReadAllDataOnOff = On; + //TruncateExtraCharsInNamesOnOff = On; + //MakeNameUniqueStr = "_"; + //PointsScaleFactor = 1.0; + ConstructModelOnOff = Off; + ConstructChartOnOff = Off; + //ConstructWeightFunUsingResidualOnOff = Off; + //GapFillUsingResidualsOnOff = Off; + //MarkerUseAllPointsOnOff = Off; + //MarkerUseCamMaskOnOff = On; + //MarkerIndices = ; + //MarkerLabels = ; + //MarkerFilterIndex = 0; + //ProcessedDataFilterIndex = 0; + //AnalogFilterIndex = -1; + Filter = + { + AutomaticInitialConditionOnOff = On; + FilterForwardBackwardOnOff = On; + N = 2; + Fc = {3}; + Type = LowPass; + }; + //WeightThreshold = 0.0; + //WeightOutput = {{0.0, 1.0}, {0.0, 1.0}, {0.0, 1.0}}; + //WeightTransitionTime = 0.1; + //SearchAndReplace = ; + //WriteMarkerDataToFilesOnOff = Off; + //MarkerScaleXYZ = {0.025, 0.025, 0.025}; + MarkerRGB = {0, 0, 1}; + //MarkerDrawOnOff = On; + //MarkerInterPolType = Bspline; + //MarkerBsplineOrder = 4; + }; + + AnyKinDriverMarker C3Dmotion1 = { + AnyRefFrame &Marker = .Leg.R1; + AnyParamFun &Trajectory= + Main.MyModel.C3D.Points.Markers.L000.PosInterpol; + AnyDrawKinMeasure drw = { + Label = Off;Size = 0.03;Line = Off; + }; + }; + AnyKinDriverMarker C3Dmotion2 = { + AnyRefFrame &Marker = .Leg.R2; + AnyParamFun &Trajectory = + Main.MyModel.C3D.Points.Markers.L001.PosInterpol; + AnyDrawKinMeasure drw = { + Label = Off;Size = 0.03;Line = Off; + }; + }; + AnyKinDriverMarker C3Dmotion3 = { + AnyRefFrame &Marker = .Leg.R3; + AnyParamFun &Trajectory = + Main.MyModel.C3D.Points.Markers.L002.PosInterpol; + AnyDrawKinMeasure drw = { + Label = Off;Size = 0.03;Line = Off; + }; + }; + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + Gravity = {0.0, -9.81, 0.0}; + AnyIntVar FirstFrame = Main.MyModel.C3D.Header.FirstFrameNo; + AnyIntVar LastFrame = Main.MyModel.C3D.Header.LastFrameNo; + tStart = FirstFrame/Main.MyModel.C3D.Header.VideoFrameRate+2*Kinematics.ApproxVelAccPerturb; + tEnd = LastFrame/Main.MyModel.C3D.Header.VideoFrameRate-2*Kinematics.ApproxVelAccPerturb; + InitialConditions.SolverType = KinSolOverDeterminate; + Kinematics.SolverType = KinSolOverDeterminate; + }; + +//# BEGIN SNIPPET 1 +AnyOptKinStudy OptKinStudy = +{ + Analysis = { + AnyOperation &Operation= ..MyStudy.Kinematics; + }; + //MaxIterationStep = 100; + AnyDesVar Jointx = { + Val = Main.MyModel.Leg.Joint.sRel[0]; + }; + §AnyDesVar Jointy = { + Val = Main.MyModel.Leg.Joint.sRel[1]; + }; + AnyDesVar Jointz = { + Val = Main.MyModel.Leg.Joint.sRel[2]; + };§ +}; +//# END SNIPPET 1 +}; \ No newline at end of file diff --git a/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-7.any b/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-7.any new file mode 100644 index 00000000..91ac513e --- /dev/null +++ b/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-7.any @@ -0,0 +1,137 @@ +// Todo: Write a small description of your model here +Main = { + + // The actual body model goes in this folder + AnyFolder MyModel = { + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + AnyDrawRefFrame drw = {}; + }; + AnySeg Leg = { + Mass = 1; + Jii = {1, 0.01, 1}/15; + AnyRefNode Joint = { + sRel = {0, 0.45, 0}; + }; + AnyRefNode R1 = { + sRel = {0.038, 0.18, 0.022}; + }; + AnyRefNode R2 = { + sRel = {-0.015, -0.104, 0.028}; + }; + AnyRefNode R3 = { + sRel = {-0.022, -0.403, -0.023}; + }; + AnyDrawSeg drw = { + Opacity = 0.5; + }; + }; + AnyRevoluteJoint Joint = { + AnyRefFrame &Ground = .GlobalRef; + AnyRefFrame &Pendulum = .Leg.Joint; + }; + + AnyInputC3D C3D = + { + FileName = "multiple.c3d"; + //ReadAllDataOnOff = On; + //TruncateExtraCharsInNamesOnOff = On; + //MakeNameUniqueStr = "_"; + //PointsScaleFactor = 1.0; + ConstructModelOnOff = Off; + ConstructChartOnOff = Off; + //ConstructWeightFunUsingResidualOnOff = Off; + //GapFillUsingResidualsOnOff = Off; + //MarkerUseAllPointsOnOff = Off; + //MarkerUseCamMaskOnOff = On; + //MarkerIndices = ; + //MarkerLabels = ; + //MarkerFilterIndex = 0; + //ProcessedDataFilterIndex = 0; + //AnalogFilterIndex = -1; + Filter = + { + AutomaticInitialConditionOnOff = On; + FilterForwardBackwardOnOff = On; + N = 2; + Fc = {3}; + Type = LowPass; + }; + //WeightThreshold = 0.0; + //WeightOutput = {{0.0, 1.0}, {0.0, 1.0}, {0.0, 1.0}}; + //WeightTransitionTime = 0.1; + //SearchAndReplace = ; + //WriteMarkerDataToFilesOnOff = Off; + //MarkerScaleXYZ = {0.025, 0.025, 0.025}; + MarkerRGB = {0, 0, 1}; + //MarkerDrawOnOff = On; + //MarkerInterPolType = Bspline; + //MarkerBsplineOrder = 4; + }; + + AnyKinDriverMarker C3Dmotion1 = { + AnyRefFrame &Marker = .Leg.R1; + AnyParamFun &Trajectory= + Main.MyModel.C3D.Points.Markers.L000.PosInterpol; + AnyDrawKinMeasure drw = { + Label = Off;Size = 0.03;Line = Off; + }; + }; + AnyKinDriverMarker C3Dmotion2 = { + AnyRefFrame &Marker = .Leg.R2; + AnyParamFun &Trajectory = + Main.MyModel.C3D.Points.Markers.L001.PosInterpol; + AnyDrawKinMeasure drw = { + Label = Off;Size = 0.03;Line = Off; + }; + }; + AnyKinDriverMarker C3Dmotion3 = { + AnyRefFrame &Marker = .Leg.R3; + AnyParamFun &Trajectory = + Main.MyModel.C3D.Points.Markers.L002.PosInterpol; + AnyDrawKinMeasure drw = { + Label = Off;Size = 0.03;Line = Off; + }; + }; + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + Gravity = {0.0, -9.81, 0.0}; + AnyIntVar FirstFrame = Main.MyModel.C3D.Header.FirstFrameNo; + AnyIntVar LastFrame = Main.MyModel.C3D.Header.LastFrameNo; + tStart = FirstFrame/Main.MyModel.C3D.Header.VideoFrameRate+2*Kinematics.ApproxVelAccPerturb; + tEnd = LastFrame/Main.MyModel.C3D.Header.VideoFrameRate-2*Kinematics.ApproxVelAccPerturb; + InitialConditions.SolverType = KinSolOverDeterminate; + Kinematics.SolverType = KinSolOverDeterminate; + }; + +//# BEGIN SNIPPET 1 +AnyOptKinStudy OptKinStudy = +{ + Analysis = { + AnyOperation &Operation= ..MyStudy.Kinematics; + }; + //MaxIterationStep = 100; + AnyDesVar Jointx = { + Val = Main.MyModel.Leg.Joint.sRel[0]; + }; + AnyDesVar Jointy = { + Val = Main.MyModel.Leg.Joint.sRel[1]; + }; + AnyDesVar Jointz = { + Val = Main.MyModel.Leg.Joint.sRel[2]; + }; + §AnyDesVar R1x = { + Val = Main.MyModel.Leg.R1.sRel[0]; + }; + AnyDesVar R1y = { + Val = Main.MyModel.Leg.R1.sRel[1]; + }; + AnyDesVar R1z = { + Val = Main.MyModel.Leg.R1.sRel[2]; + };§ +}; +//# END SNIPPET 1 +}; \ No newline at end of file diff --git a/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-8.any b/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-8.any new file mode 100644 index 00000000..cf8058b8 --- /dev/null +++ b/Motion_Capture_Movement/Snippets/lesson4/snip.Multiple.main-8.any @@ -0,0 +1,146 @@ +// Todo: Write a small description of your model here +Main = { + + // The actual body model goes in this folder + AnyFolder MyModel = { + // Global Reference Frame + AnyFixedRefFrame GlobalRef = { + AnyDrawRefFrame drw = {}; + }; + AnySeg Leg = { + Mass = 1; + Jii = {1, 0.01, 1}/15; + AnyRefNode Joint = { + sRel = {0, 0.45, 0}; + }; + AnyRefNode R1 = { + sRel = {0.038, 0.18, 0.022}; + }; + AnyRefNode R2 = { + sRel = {-0.015, -0.104, 0.028}; + }; + AnyRefNode R3 = { + sRel = {-0.022, -0.403, -0.023}; + }; + AnyDrawSeg drw = { + Opacity = 0.5; + }; + }; + AnyRevoluteJoint Joint = { + AnyRefFrame &Ground = .GlobalRef; + AnyRefFrame &Pendulum = .Leg.Joint; + }; + + AnyInputC3D C3D = + { + FileName = "multiple.c3d"; + //ReadAllDataOnOff = On; + //TruncateExtraCharsInNamesOnOff = On; + //MakeNameUniqueStr = "_"; + //PointsScaleFactor = 1.0; + ConstructModelOnOff = Off; + ConstructChartOnOff = Off; + //ConstructWeightFunUsingResidualOnOff = Off; + //GapFillUsingResidualsOnOff = Off; + //MarkerUseAllPointsOnOff = Off; + //MarkerUseCamMaskOnOff = On; + //MarkerIndices = ; + //MarkerLabels = ; + //MarkerFilterIndex = 0; + //ProcessedDataFilterIndex = 0; + //AnalogFilterIndex = -1; + Filter = + { + AutomaticInitialConditionOnOff = On; + FilterForwardBackwardOnOff = On; + N = 2; + Fc = {3}; + Type = LowPass; + }; + //WeightThreshold = 0.0; + //WeightOutput = {{0.0, 1.0}, {0.0, 1.0}, {0.0, 1.0}}; + //WeightTransitionTime = 0.1; + //SearchAndReplace = ; + //WriteMarkerDataToFilesOnOff = Off; + //MarkerScaleXYZ = {0.025, 0.025, 0.025}; + MarkerRGB = {0, 0, 1}; + //MarkerDrawOnOff = On; + //MarkerInterPolType = Bspline; + //MarkerBsplineOrder = 4; + }; + + AnyKinDriverMarker C3Dmotion1 = { + AnyRefFrame &Marker = .Leg.R1; + AnyParamFun &Trajectory= + Main.MyModel.C3D.Points.Markers.L000.PosInterpol; + AnyDrawKinMeasure drw = { + Label = Off;Size = 0.03;Line = Off; + }; + }; + AnyKinDriverMarker C3Dmotion2 = { + AnyRefFrame &Marker = .Leg.R2; + AnyParamFun &Trajectory = + Main.MyModel.C3D.Points.Markers.L001.PosInterpol; + AnyDrawKinMeasure drw = { + Label = Off;Size = 0.03;Line = Off; + }; + }; + AnyKinDriverMarker C3Dmotion3 = { + AnyRefFrame &Marker = .Leg.R3; + AnyParamFun &Trajectory = + Main.MyModel.C3D.Points.Markers.L002.PosInterpol; + AnyDrawKinMeasure drw = { + Label = Off;Size = 0.03;Line = Off; + }; + }; + }; // MyModel + + // The study: Operations to be performed on the model + AnyBodyStudy MyStudy = { + AnyFolder &Model = .MyModel; + Gravity = {0.0, -9.81, 0.0}; + AnyIntVar FirstFrame = Main.MyModel.C3D.Header.FirstFrameNo; + AnyIntVar LastFrame = Main.MyModel.C3D.Header.LastFrameNo; + tStart = FirstFrame/Main.MyModel.C3D.Header.VideoFrameRate+2*Kinematics.ApproxVelAccPerturb; + tEnd = LastFrame/Main.MyModel.C3D.Header.VideoFrameRate-2*Kinematics.ApproxVelAccPerturb; + InitialConditions.SolverType = KinSolOverDeterminate; + Kinematics.SolverType = KinSolOverDeterminate; + }; + +//# BEGIN SNIPPET 1 +AnyOptKinStudy OptKinStudy = +{ + Analysis = { + AnyOperation &Operation= ..MyStudy.Kinematics; + }; + //MaxIterationStep = 100; + AnyDesVar Jointx = { + Val = Main.MyModel.Leg.Joint.sRel[0]; + }; + AnyDesVar Jointy = { + Val = Main.MyModel.Leg.Joint.sRel[1]; + }; + AnyDesVar Jointz = { + Val = Main.MyModel.Leg.Joint.sRel[2]; + }; + AnyDesVar R1x = { + Val = Main.MyModel.Leg.R1.sRel[0]; + }; + AnyDesVar R1y = { + Val = Main.MyModel.Leg.R1.sRel[1]; + }; + AnyDesVar R1z = { + Val = Main.MyModel.Leg.R1.sRel[2]; + }; + §AnyDesVar R2x = { + Val = Main.MyModel.Leg.R2.sRel[0]; + }; + AnyDesVar R2y = { + Val = Main.MyModel.Leg.R2.sRel[1]; + }; + AnyDesVar R2z = { + Val = Main.MyModel.Leg.R2.sRel[2]; + };§ +}; +//# END SNIPPET 1 +}; \ No newline at end of file diff --git a/Making_things_move/_static/intro/cutting.jpg b/Motion_Capture_Movement/_static/intro/cutting.jpg similarity index 100% rename from Making_things_move/_static/intro/cutting.jpg rename to Motion_Capture_Movement/_static/intro/cutting.jpg diff --git a/Motion_Capture_Movement/_static/lesson1/Main.RunAnalysis.png b/Motion_Capture_Movement/_static/lesson1/Main.RunAnalysis.png new file mode 100644 index 00000000..fcde239b Binary files /dev/null and b/Motion_Capture_Movement/_static/lesson1/Main.RunAnalysis.png differ diff --git a/Motion_Capture_Movement/_static/lesson1/charview_higher_hip_forces.png b/Motion_Capture_Movement/_static/lesson1/charview_higher_hip_forces.png new file mode 100644 index 00000000..4fa84bf0 Binary files /dev/null and b/Motion_Capture_Movement/_static/lesson1/charview_higher_hip_forces.png differ diff --git a/Making_things_move/_static/lesson5/disable_modelview.png b/Motion_Capture_Movement/_static/lesson1/disable_modelview.png similarity index 100% rename from Making_things_move/_static/lesson5/disable_modelview.png rename to Motion_Capture_Movement/_static/lesson1/disable_modelview.png diff --git a/Making_things_move/_static/lesson5/flow.png b/Motion_Capture_Movement/_static/lesson1/flow.png similarity index 100% rename from Making_things_move/_static/lesson5/flow.png rename to Motion_Capture_Movement/_static/lesson1/flow.png diff --git a/Motion_Capture_Movement/_static/lesson1/image1.png b/Motion_Capture_Movement/_static/lesson1/image1.png new file mode 100644 index 00000000..9c790e56 Binary files /dev/null and b/Motion_Capture_Movement/_static/lesson1/image1.png differ diff --git a/Motion_Capture_Movement/_static/lesson1/image11.png b/Motion_Capture_Movement/_static/lesson1/image11.png new file mode 100644 index 00000000..0206bf7a Binary files /dev/null and b/Motion_Capture_Movement/_static/lesson1/image11.png differ diff --git a/Making_things_move/_static/lesson5/image12.png b/Motion_Capture_Movement/_static/lesson1/image12.png similarity index 100% rename from Making_things_move/_static/lesson5/image12.png rename to Motion_Capture_Movement/_static/lesson1/image12.png diff --git a/Making_things_move/_static/lesson5/image2.png b/Motion_Capture_Movement/_static/lesson1/image2.png similarity index 100% rename from Making_things_move/_static/lesson5/image2.png rename to Motion_Capture_Movement/_static/lesson1/image2.png diff --git a/Making_things_move/_static/lesson5/image3.png b/Motion_Capture_Movement/_static/lesson1/image3.png similarity index 100% rename from Making_things_move/_static/lesson5/image3.png rename to Motion_Capture_Movement/_static/lesson1/image3.png diff --git a/Motion_Capture_Movement/_static/lesson1/image5.png b/Motion_Capture_Movement/_static/lesson1/image5.png new file mode 100644 index 00000000..3a644952 Binary files /dev/null and b/Motion_Capture_Movement/_static/lesson1/image5.png differ diff --git a/Motion_Capture_Movement/_static/lesson1/image6.png b/Motion_Capture_Movement/_static/lesson1/image6.png new file mode 100644 index 00000000..aab8ff7b Binary files /dev/null and b/Motion_Capture_Movement/_static/lesson1/image6.png differ diff --git a/Motion_Capture_Movement/_static/lesson1/image7.png b/Motion_Capture_Movement/_static/lesson1/image7.png new file mode 100644 index 00000000..ee5a1444 Binary files /dev/null and b/Motion_Capture_Movement/_static/lesson1/image7.png differ diff --git a/Making_things_move/_static/lesson5/image9.png b/Motion_Capture_Movement/_static/lesson1/image9.png similarity index 100% rename from Making_things_move/_static/lesson5/image9.png rename to Motion_Capture_Movement/_static/lesson1/image9.png diff --git a/Motion_Capture_Movement/_static/lesson2/image1.png b/Motion_Capture_Movement/_static/lesson2/image1.png new file mode 100644 index 00000000..297bf66d Binary files /dev/null and b/Motion_Capture_Movement/_static/lesson2/image1.png differ diff --git a/Making_things_move/_static/lesson2/image2.jpeg b/Motion_Capture_Movement/_static/lesson2/image2.jpeg similarity index 100% rename from Making_things_move/_static/lesson2/image2.jpeg rename to Motion_Capture_Movement/_static/lesson2/image2.jpeg diff --git a/Motion_Capture_Movement/_static/lesson2/image3.png b/Motion_Capture_Movement/_static/lesson2/image3.png new file mode 100644 index 00000000..e3279e62 Binary files /dev/null and b/Motion_Capture_Movement/_static/lesson2/image3.png differ diff --git a/Making_things_move/_static/lesson2/image4.jpeg b/Motion_Capture_Movement/_static/lesson2/image4.jpeg similarity index 100% rename from Making_things_move/_static/lesson2/image4.jpeg rename to Motion_Capture_Movement/_static/lesson2/image4.jpeg diff --git a/Making_things_move/_static/lesson2/image5.jpeg b/Motion_Capture_Movement/_static/lesson2/image5.jpeg similarity index 100% rename from Making_things_move/_static/lesson2/image5.jpeg rename to Motion_Capture_Movement/_static/lesson2/image5.jpeg diff --git a/Motion_Capture_Movement/_static/lesson3/image1.png b/Motion_Capture_Movement/_static/lesson3/image1.png new file mode 100644 index 00000000..cee88487 Binary files /dev/null and b/Motion_Capture_Movement/_static/lesson3/image1.png differ diff --git a/Motion_Capture_Movement/_static/lesson3/image2.png b/Motion_Capture_Movement/_static/lesson3/image2.png new file mode 100644 index 00000000..b8f9d5a3 Binary files /dev/null and b/Motion_Capture_Movement/_static/lesson3/image2.png differ diff --git a/Motion_Capture_Movement/_static/lesson3/image3.png b/Motion_Capture_Movement/_static/lesson3/image3.png new file mode 100644 index 00000000..34c13854 Binary files /dev/null and b/Motion_Capture_Movement/_static/lesson3/image3.png differ diff --git a/Motion_Capture_Movement/_static/lesson3/image4.png b/Motion_Capture_Movement/_static/lesson3/image4.png new file mode 100644 index 00000000..c888d03e Binary files /dev/null and b/Motion_Capture_Movement/_static/lesson3/image4.png differ diff --git a/Making_things_move/_static/lesson4/image1.jpeg b/Motion_Capture_Movement/_static/lesson4/image1.jpeg similarity index 100% rename from Making_things_move/_static/lesson4/image1.jpeg rename to Motion_Capture_Movement/_static/lesson4/image1.jpeg diff --git a/Making_things_move/_static/lesson4/image2.jpeg b/Motion_Capture_Movement/_static/lesson4/image2.jpeg similarity index 100% rename from Making_things_move/_static/lesson4/image2.jpeg rename to Motion_Capture_Movement/_static/lesson4/image2.jpeg diff --git a/Motion_Capture_Movement/_static/lesson4/image3.png b/Motion_Capture_Movement/_static/lesson4/image3.png new file mode 100644 index 00000000..85ec5578 Binary files /dev/null and b/Motion_Capture_Movement/_static/lesson4/image3.png differ diff --git a/Motion_Capture_Movement/_static/lesson4/image4.jpeg b/Motion_Capture_Movement/_static/lesson4/image4.jpeg new file mode 100644 index 00000000..846f3aa2 Binary files /dev/null and b/Motion_Capture_Movement/_static/lesson4/image4.jpeg differ diff --git a/Motion_Capture_Movement/_static/lesson4/image5.png b/Motion_Capture_Movement/_static/lesson4/image5.png new file mode 100644 index 00000000..d302ba23 Binary files /dev/null and b/Motion_Capture_Movement/_static/lesson4/image5.png differ diff --git a/Making_things_move/_static/lesson4/image6.jpeg b/Motion_Capture_Movement/_static/lesson4/image6.jpeg similarity index 100% rename from Making_things_move/_static/lesson4/image6.jpeg rename to Motion_Capture_Movement/_static/lesson4/image6.jpeg diff --git a/Motion_Capture_Movement/_static/lesson4/image7.png b/Motion_Capture_Movement/_static/lesson4/image7.png new file mode 100644 index 00000000..d4103d4b Binary files /dev/null and b/Motion_Capture_Movement/_static/lesson4/image7.png differ diff --git a/Motion_Capture_Movement/index.md b/Motion_Capture_Movement/index.md new file mode 100644 index 00000000..f0e69881 --- /dev/null +++ b/Motion_Capture_Movement/index.md @@ -0,0 +1,28 @@ +::: {rst-class} break +::: + +# Motion Capture Movement + +The objective of this tutorial is to give a general understanding of how to use +motion capture data in AnyBody models. + +The first lesson introduces a gait model from AMMR of a walking human driven by +motion capture data, and the subsequent lessons explain how to build your own +simple model using motion capture data. + + +::::{if-builder:: html +```{rubric} Tutorial content +``` +:::: + +```{toctree} +:maxdepth: 1 + +Introduction +lesson1 +lesson2 +lesson3 +lesson4 +lesson5 +``` diff --git a/Making_things_move/intro.md b/Motion_Capture_Movement/intro.md similarity index 87% rename from Making_things_move/intro.md rename to Motion_Capture_Movement/intro.md index b9c97a7c..2914d4a1 100644 --- a/Making_things_move/intro.md +++ b/Motion_Capture_Movement/intro.md @@ -6,8 +6,8 @@ Most biomechanical investigations involve some sort of movement, so getting the model to move in the desired way is at the core of musculoskeletal modeling. The AnyBody Modeling System offers many and -rather advanced methods to make this happen. This tutorial explains the -basics and some of the more common approaches. +rather advanced methods to make this happen. This tutorial explains +some of the common approaches. :::{figure} _static/intro/cutting.jpg :align: center @@ -36,6 +36,8 @@ independent possibilities, so the concept of DoF is rather general, and we shall explore it in a little more detail in the following on a very simple model. + -In the following lessons we will look at simple and more advanced ways -to drive a model. For simplicity, we’ll stick with the simple pendulum, -but exactly the same principles apply to much more complex models. + +In the following lessons we will look at simple and more advanced ways to drive +a model. First, lesson 1 introduces an advanced gait model from AMMR of a +walking human driven by motion capture data. The following lessons will explain +how to build your own model to drive a simple pendulum using motion capture +data, where exactly the same principles apply to much more complex models. diff --git a/Making_things_move/lesson5.md b/Motion_Capture_Movement/lesson1.md similarity index 71% rename from Making_things_move/lesson5.md rename to Motion_Capture_Movement/lesson1.md index 0b24e5f0..f68de017 100644 --- a/Making_things_move/lesson5.md +++ b/Motion_Capture_Movement/lesson1.md @@ -3,13 +3,23 @@ (making-things-move-move-real-mocap)= -# Lesson 5: Using real data +# Lesson 1: Using real data -Without further ado, let us import a real C3D file and drive a complete model. +In biomechanics, we often want to make our models move as we have measured in +the laboratory and the measurement technique would often be tracking of optical +markers in space by means of synchronized cameras. + +There are many such systems available commercially, but a common feature of most +of the systems is that they are capable of saving data on a standard format +called a C3D file. + +A C3D file contains data of the spatial trajectory of optical markers fixed to +the object whose motion we want to record. The file can also contain analog data +such as force platform measurements or EMG. AnyBody can read the data from a C3D +file directly. The AnyBody Modeling System offers you virtually unlimited ways of doing -things, and probably more than the average user can comprehend, so we -are going to start with a simple and top-down procedure. +things, and probably more than the average user can comprehend. The AnyBody Model Repository (> 2.0), contains some pre-cooked examples which are easy to drive with your own data and which contain some really neat features @@ -17,7 +27,8 @@ for data processing. :::{note} Make sure you have installed your own copy of the AnyBody Model repository (AMMR). -See the {doc}`AMMR documentation `. +See the {doc}`AMMR documentation ` for instructions on how +to install it. ::: 1. Go to the folder {file}`Application/MocapExamples/Plug-in-gait_Simple`. @@ -48,11 +59,11 @@ file to drive the model with. #include "" ``` -The model defines three section/files which must be customized. +The model defines three sections/files which must be customized. -- {file}`LabSpecificData.any` -- {file}`SubjectSpecificData.any` - {file}`TrialSpecificData.any`. +- {file}`SubjectSpecificData.any` +- {file}`LabSpecificData.any` Following this structure is not strictly necessary, but good practice. Finally, on line 13 we include the *AnyMocap* framework or base model. @@ -60,7 +71,9 @@ on line 13 we include the *AnyMocap* framework or base model. Now please load the model and open up a new Model View. You should see the following model: -```{image} _static/lesson5/image1.png +```{image} _static/lesson1/image1.png +:alt: View of the model +:align: center ``` The model consist of number of operations which must be executed in the correct @@ -68,7 +81,7 @@ order. The flow of the model is illustrated in the following figure. (model-flow-chart)= -:::{figure} _static/lesson5/flow.png +:::{figure} _static/lesson1/flow.png Illustration of the three processes for the Mocap models. Parameter identification, Marker tracking, and Inverse Dynamic analysis. See [Lund et al. 2015](https://doi.org/10.1080/23335432.2014.993706) @@ -81,7 +94,10 @@ If you look closely at the model view, you can see that the skeleton is equipped markers and if you zoom in a little, you can also see that the markers carry small coordinate systems with red and green arrows. -```{image} _static/lesson5/image2.png +```{image} _static/lesson1/image2.png +:alt: Close up view of leg +:align: center +:width: 60% ``` ```{raw} html @@ -111,7 +127,7 @@ points wrong, the resulting motion of the model will also be inaccurate. So the green arrows designate directions in which we have the greatest uncertainty about whether the marker is placed in the model as it was in the experiment. The good news is that we can optimize those marker -placements exactly as we did in {doc}`lesson 4 `. +placements exactly as we are going to do in {doc}`lesson 4 `. The model is set up to do this automatically, and if you are happy with the choice that has been made, you need not do anymore. @@ -119,7 +135,7 @@ choice that has been made, you need not do anymore. :::{note} If you use a different marker protocol, or customize what is optimized you will need to modify the marker protocol. In this example, the marker -protocol is define in the file The {file}`Setup/MarkerProtocol.any`. In the +protocol is defined in the file {file}`Setup/MarkerProtocol.any`. In the interest of simplicity, we shall postpone the discussion of the marker protocol setup. ::: @@ -144,14 +160,18 @@ Without further ado, let us perform the optimization: Find the `Main.RunParameterIdentification` in the operations dropdown, and run it. -![Opertions RunModtionAndParameterOpt](_static/lesson5/image3.png) +```{image} _static/lesson1/image3.png +:alt: Opertions RunModtionAndParameterOpt +:align: center +``` You will see the model walking repeatedly over the force platforms, sometimes slowly and sometimes a bit faster depending on the speed of your computer and the progress of the computation. :::{note} -The process speeds up significantly if you switch off the Model View. +The process speeds up significantly if you switch off the Model View +![ModelViewOff](_static/lesson1/disable_modelview.png). ::: When operation is done you will see the line `Optimization converged` in the *Output* windows @@ -189,14 +209,14 @@ the full optimization for each trial as we shall do later in this tutorial. ## Marker tracking and Inverse dynamics -Let us proceed with the kinematic analysis. As we saw in {doc}`lesson2` marker -based models usually require an over-determinate kinematic solver to handle the -excess in information that the optical markers provide. The over-determinate -solver in AMS works great, but it will calculate velocities and accelerations -numerically. That has some performance issues when running inverse dynamics -analysis. To overcome this problem, the MOCAP analysis is split into a two-step -procedure, as illustrated on figure {numref}`model-flow-chart`, separating -the Marker tracking from the Inverse dynamic analysis. +Let us proceed with the kinematic analysis. As we will see later in +{doc}`lesson2` marker based models usually require an over-determinate kinematic +solver to handle the excess in information that the optical markers provide. The +over-determinate solver in AMS works great, but it will calculate velocities and +accelerations numerically. That has some performance issues when running inverse +dynamics analysis. To overcome this problem, the MOCAP analysis is split into a +two-step procedure, as illustrated on figure {numref}`model-flow-chart`, +separating the Marker tracking from the Inverse dynamic analysis. The overdeterminate kinematic analysis solves the model for positions, and stores the joint angles as function of time. This step is the "Marker tracking" @@ -204,10 +224,12 @@ step in figure {numref}`model-flow-chart`. These joint angles are then used in t second step with the determinate kinematic solver in the inverse dynamic analysis. -In the Model the *Marker tracking* and *Inverse Dynamics* are combined into +In the Model the *Marker tracking* and *Inverse Dynamics* are combined into a single operation called `Main.RunAnalysis`. -```{image} _static/lesson5/Main.RunAnalysis.png +```{image} _static/lesson1/Main.RunAnalysis.png +:alt: Operations tree +:align: center ``` The operation contains everything @@ -224,7 +246,9 @@ continuously calculate forces in more than 300 muscles. When the analysis is finished, you can open up a Chart view and investigate the results, for instance the hip joint reaction forces: -```{image} _static/lesson5/image5.png +```{image} _static/lesson1/image5.png +:alt: Chart Fout +:align: center ``` ## Importing new motion data @@ -242,12 +266,12 @@ point at a different file. A few lines into the Main file, you find this: ```AnyScriptDoc -#path MOCAP_TRIAL_SPECIFIC_DATA "TrialSpecificData.any" +#path MOCAP_TRIAL_SPECIFIC_DATA "Setup/TrialSpecificData_LowerExtremity.any" ``` This file contains the settings you typically want to change when switching trials. -Double-click the `TrialSpecificData.any` file name, and the file opens up +Double-click the `TrialSpecificData_LowerExtremity.any` file name, and the file opens up in a new tab. Then, just a few lines down, refer to the new filename into the model: @@ -259,19 +283,48 @@ TrialFileName = §"GaitFast_1"§; Since this is a new C3D file from a new trial, we also need to run the kinematic optimization again. -This is all there is to it. We can now reload the model. To see the -model moving (without doing the parameter optimization just now), locate -and run the Kinematics (Marker tracking) operation in the Operation tree: +Since we have included a new C3D file containing a different amount of frames, +we have to adjust the first and last frame of the simulation. This is done in +the `TrialSpecificData_LowerExtremity.any` file, where we have to make the +following changes: + +```AnyScriptDoc +TrialFileName = "GaitFast_1"; + +// This the C3D frame where the analysis starts +// If not specified it defaults to the first frame of the C3D file +//FirstFrame = .C3DFileData.Header.FirstFrameNo; +FirstFrame = §.C3DFileData.Header.FirstFrameNo+5§; -![Operations, kinematics](_static/lesson5/image6.png) +// This the C3D frame where the analysis ends +// If not specified it defaults the first frame of the C3D file +//LastFrame = .C3DFileData.Header.LastFrameNo; +LastFrame = §.C3DFileData.Header.LastFrameNo-5§; +``` + +This defines that the simulation starts 5 frames after the first frame in the C3D +file and ends 5 frames before the last frame in the C3D file. + +We can now load the model and see it moving (without doing the parameter +optimization just now). Locate and run the Kinematics ("Marker tracking") +operation in the Operation tree: + +```{image} _static/lesson1/image6.png +:alt: Operations, kinematics +:align: center +``` The movement seems to work fine and you will notice that this gait pattern is a little different from before. The steps are longer and the posture indicates that this is a person in a hurry. -![Model view, marker tracking](_static/lesson5/image7.png) +```{image} _static/lesson1/image7.png +:alt: Model view, marker tracking +:align: center +:width: 80% +``` -Now is the time to run the `Main.ParameterIdentification`. It +Now is the time to run the `Main.RunParameterIdentification`. It takes a bit of time, and again you can speed up the process by switching off the update of the Model View window. Eventually, the process comes to an end and you get the message: @@ -292,7 +345,7 @@ Next, we run the combined *Marker tracking* and *Inverse dynamics* (`Main.RunAna Which, after the analysis can provide a new hip joint force profile documenting that faster gait lead to higher hip joint forces. -```{image} _static/lesson5/charview_higher_hip_forces.png +```{image} _static/lesson1/charview_higher_hip_forces.png ``` ## Using full-body models @@ -302,28 +355,36 @@ lower extremities. The Model Repository contains another pre-cooked model for this purpose, and it will reveal that there is more data in the C3D file we just imported than we saw in lower extremity model. -Open the full body example model `Plug-in-gait_Simple/FullBody.main.any`, then run -`Main.ParameterIdentification` - +Open the full body example model `Plug-in-gait_Simple/FullBody.main.any`. Please load the model and open a Model View if you do not already have one. You will see the model as before, but now with the arms included. -![Model view Fullbody initial load](_static/lesson5/image9.png) +```{image} _static/lesson1/image9.png +:alt: Model view Fullbody initial load +:align: center +:width: 80% +``` -Select and run the RunMotionAndParameterOptimizationSequence in the +Select and run the `Main.RunParameterIdentification` in the Operations tree: -![Opertions RunModtionAndParameterOpt](_static/lesson5/image3.png) +```{image} _static/lesson1/image3.png +:alt: Opertions RunModtionAndParameterOpt +:align: center +``` The model starts walking repeatedly over the force platforms including the arm motions while it tries to optimize segment lengths and marker -positions. It takes 7 iterations and more time than before +positions. It takes 4 iterations and **considerable more time** than before to optimize the model because this is a much larger problem, but as before you can speed up the process if you switch off the update of the Model View window. It is possible to monitor the convergence of the optimization problem from a Chart window like this: -![Chart view, Kin objective](_static/lesson5/image11.png) +```{image} _static/lesson1/image11.png +:alt: Chart view, Kin objective +:align: center +``` Eventually, the optimization process terminates and you can switch run the *Marker tracking* and *inverse dynamics* (`Main.RunAnalysis`) and perform the @@ -333,7 +394,11 @@ This full-body model with almost 1000 muscle fascicles takes considerable more time to analyze but will reward you with very detailed information about the function of the muscle system in gait as illustrated below. -![Model view, full body inverse dynamics](_static/lesson5/image12.png) - -The final {doc}`lesson ` of this tutorial is about problems that may arise with -C3D files. +```{image} _static/lesson1/image12.png +:alt: Model view, full body inverse dynamics +:align: center +``` +This concludes the introduction on how to use motion capture data in a complex +musculoskeletal model. The following three lessons show how to set up a simple +model using motion capture data, while the final {doc}`lesson ` of this +tutorial is about problems that may arise with C3D files. diff --git a/Making_things_move/lesson1.md b/Motion_Capture_Movement/lesson1Deleted.txt similarity index 97% rename from Making_things_move/lesson1.md rename to Motion_Capture_Movement/lesson1Deleted.txt index 5c260165..209de005 100644 --- a/Making_things_move/lesson1.md +++ b/Motion_Capture_Movement/lesson1Deleted.txt @@ -1,7 +1,7 @@ ::: {rst-class} break ::: -# Lesson1: Simple drivers +# OLD Lesson 1: Simple drivers DELETED As mentioned above, we often have preconceived ideas about a system’s natural DoFs, such as abduction of the shoulder or flexion of the knee. @@ -11,7 +11,7 @@ can very easily drive the pendulum using this DoF. The simplest mechanism of motion drivers in AnyBody is called `AnyKinMotion`. With Pendulum.any open in an editor and the model loaded, -please place the cursor in the editor window just below then ending +please place the cursor in the editor window just below the ending brace of the `AnySeg Pendulum` definition. Then click the Classes tab on the right-hand side of the editor window. Unfold the class list and scroll down to find `AnyKinMotion` . Right-click and insert an instance at diff --git a/Motion_Capture_Movement/lesson2.md b/Motion_Capture_Movement/lesson2.md new file mode 100644 index 00000000..2f0d87c7 --- /dev/null +++ b/Motion_Capture_Movement/lesson2.md @@ -0,0 +1,355 @@ +::: {rst-class} break +::: + +# Lesson 2: Using motion capture data + +In the previous lesson, we explored how a large and complex AMMR model can be +driven using motion capture data. Now, let's take a step back and start building +our own simple model driven by motion capture data. + +Please download and save this +{download}`AnyBody Model of a pendulum ` and this file +{download}`pendulum.c3d` in the same folder. Load +the model into AnyBody and open a new model view. You should see a vertical +segment with a point at each end. It is, in fact, a pendulum model linked to the +global reference frame by a revolute joint at its upper end point. We use this +example because it is very simple and has a remote similarity with a human limb. + +A hinged pendulum, like a forearm hinged at the elbow, will have just one DoF, +hence only one driver is needed to drive its motion. The class `AnyKinMotion` with +a polynomial driver function is already inserted in the model as its driver. +Refer to Lesson 5 in the tutorial {ref}`How to Write AnyScript ` +for more information about this driver. + +In the following we will drive the pendulum using motion capture data instead +of using this driver. + +## Driving Using Motion Capture Data + +Now, place the cursor in the editor window just before the {code}`AnyKinMotion` +object, click the Classes tab (on the right side of the screen), unfold the class list, and locate the +{code}`AnyInputC3D` class. Right-click the class and choose “Insert Class +Template”. + +```{literalinclude} Snippets/lesson2/snip.Pendulum.main-1.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 +``` + +As you can see, the class has a lot of settings, but for now we shall +only use two of them, namely `FileName` and `ConstructChartOnOff`. We also +give a name to the object: + +```{literalinclude} Snippets/lesson2/snip.Pendulum.main-2.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 +``` + +`ConstructChartOnOff` instructs the C3D object to not draw 3D +trajectories. + +Now, try loading the model again and run the Kinematics operation. You should get +the following error message: + +```none +Time, 't', has an invalid value for this interpolation +``` + +This is because C3D files contain marker trajectories covering a certain *time span* and +what goes on outside that interval is undefined. Furthermore, the very +beginning and very end of that time span may not be useful for the +motion interpolation due to initial transients. + +If you have a C3D file of unknown duration, you need to determine its start and +end times so that AnyBody can analyze it. In this case, we can already load the +model, which makes this task easy. If you have a model that cannot be loaded, a simple way +to allow AnyBody to load the file is to temporarily disable the study section of +your model. This will eliminate conflicting start and end times in the study. +Simply select the study section and click the “Comment out” tool button above +the editor window (or press {literal}`Ctrl+Shift+k`): + +```{literalinclude} Snippets/lesson2/snip.Pendulum.main-2.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 2 +:end-before: //# END SNIPPET 2 +``` + +Now the model should load with no problems, and you can go to the Model tree +view in the left hand side of the screen, click the Model tab and unfold +MyModel tree down to the C3D object as shown below. + +```{image} _static/lesson2/image1.png +:alt: Model tree +:align: center +:width: 40% +``` + +A bit down in this object you find a folder named "Header". When you unfold it you +get access to a number of basic properties of the C3D file. Each time you +double-click a property, a window will pop up and give you its value. The +important properties in question are these: + +```AnyScriptDoc +FirstFrameNo = 1 +LastFrameNo = 1000 +VideoFrameRate = 100 +``` + +This shows that the file has a total of 1000 frames at a frame rate of +100 frames/sec, i.e. the simulation time spans ten seconds. We can now go to the +editor window and remove the temporary double slashes in front of each line to +uncomment the study section and insert specifications of simulation time: + +```{literalinclude} Snippets/lesson2/snip.Pendulum.main-3.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 +``` + +There is also an automated way to handle the problem. The frame rate +variables we have just processed manually can also be referred to +directly in the study section, such that the `tStart` and `tEnd` parameters +automatically adapt to the C3D file. Try this instead: + +```{literalinclude} Snippets/lesson2/snip.Pendulum.main-4.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 +``` + +Notice that we start the simulation `2*Kinematics.ApproxVelAccPerturb` +after the beginning of the recorded motion and we end it similarly +before the end of the recording. The variable +`Kinematics.ApproxVelAccPerturb` contains information about the +algorithm’s necessary elbow room on each side of the analyzed interval. +This eliminates possible numerical trouble with end points. + +Now the model should load and the Model View window will display a small, grey +dot to the right of the pendulum end. + +```{image} _static/lesson2/image2.jpeg +:alt: small dot +:align: center +``` + +The small dot is in fact the single marker contained in {file}`Pendulum.c3d`. A +typical file from a real motion capture experiment can contain dozens of +markers, but in the interest of simplicity we have just included a single one +here. The `AnyInputC3D` object automatically creates the small dots and the +drivers necessary to move them around as they were recorded. If you run the +Kinematics operation, you will see the pendulum move as before, while the marker +performs an oscillating motion back and forth + +So how do we get the marker to drive the pendulum? This can be done +quite easily with the `AnyKinDriverMarker` object. The steps are: + +1. Remove the existing driver that makes the pendulum rotate. +2. Drive the marker point, `P1`, on the pendulum to follow the data + recorded in the C3D file. + +Start by selecting the existing `AnyKinMotion` driver and comment it out +of the model. That takes care of step 1. + +Then click the Classes tab on the right side of the screen, +insert a new `AnyKinDriverMarker` template, and give it a name: + +```{literalinclude} Snippets/lesson2/snip.Pendulum.main-4.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 2 +:end-before: //# END SNIPPET 2 +``` + +Just as before, the `AnyKinDriverMarker` object needs to know what to +drive and what to drive it with. The “what to drive” part is the +position of `P1` on the pendulum. This is specified with the first +reference frame in the object: + +```{literalinclude} Snippets/lesson2/snip.Pendulum.main-5.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 +``` + +The marker coordinates in the C3D file are recorded in the laboratory +coordinate system, which we shall assume is our global reference frame. +Driving from `GlobalRef` is default in linear measures, so we need not +mention `GlobalRef` explicitly in the `AnyKinDriverMarker` object. + +We are going to drive the point directly by means of the interpolation +function specifying the marker trajectory in the C3D object. First, give +a reasonable name to the `AnyParamFun` and remove the stuff after the +equality sign. + +Then click the Model tab in the tree view on the left hand side of the editor +window, unfold the MyModel branch and subsequently the `C3D` -> +`Points` -> `Markers` -> `L000` and arrive at `PosInterpol` as shown +below. + +```{image} _static/lesson2/image3.png +:alt: Model tree 2 +:align: center +``` + +This is the actual interpolation function of the marker in question. +Place the cursor after the equality sign of the `AnyParamFun` line, +right-click the `PosInterpol` object, and choose “Insert object name”. You +should get this: + +```{literalinclude} Snippets/lesson2/snip.Pendulum.main-6.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 +``` + +Now load the model and run the kinematic analysis. You will get the +following error message: + +```none +ERROR(OBJ.MCH.KIN2): pendulum.any(64): MyStudy.InitialConditions: Model is kinematically over-constrained +``` + +It is time to think of the concept of degrees-of-freedom, DoF. A hinged +pendulum, like a forearm hinged at the elbow, will have just one DoF. But the +marker trajectory has three coordinates and therefore wants to drive `P1` of the +pendulum in $x$, $y$ and $z$, i.e. two DoFs more than we have available. + +There are two possible solutions to this problem. Either we pick only one of the +directions given by the marker and let the revolute joint decide the rest, or we +have to accept that the pendulum cannot follow the marker completely in all +three DoFs, i.e. something has to give. + +Driving just one direction would be fairly simple in this case, but in a +more complicated model with many markers, the selection of a subset of +directions to drive can be a very tedious process. + +Another aspect to +consider is that marker data are measured and therefore always infested +with various types of errors and noise. One of the serious errors in +motion capture technology is the so-called soft tissue artifact or skin +artifact. It comes from the fact that markers are placed on the skin at +some distance from the bone whose motion they are supposed to record. +Between the marker and the bone are layers of skin, fat and muscle, so +the marker never moves exactly with the bone. It is therefore natural in +the model to presume that the connection between the marker and the bone +is not a rigid one, and when that is the case, AnyBody will accept +drivers on more DoFs than the model actually has. + +Resolving the kinematics in the presence of moving markers is somewhat +more complicated numerically, so we have to ask for a specific +kinematics solver that can handle it. This is done in the study section: + +```{literalinclude} Snippets/lesson2/snip.Pendulum.main-6.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 2 +:end-before: //# END SNIPPET 2 +``` + +The two additional lines select a kinematic solver for the +InitialConditions and Kinematics operations that will accept more +kinematic constraints than the system has DoFs. + +:::{note} +See [Andersen MS, Damsgaard M, and Rasmussen J. 2007](https://doi.org/10.1080/10255840802459412) +for detailed information about the algorithm behind the overdeterminate +kinematic analysis. +::: + +Now you can reload and run the kinematic analysis and you should see the +pendulum following the marker movement. You cannot see the marker during the +movement because it is hidden inside the pendulum. In fact, the marker is not +strictly necessary for the analysis and we can get rid of it altogether by an +additional specification in the C3D object: + +```{literalinclude} Snippets/lesson2/snip.Pendulum.main-6.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 3 +:end-before: //# END SNIPPET 3 +``` + +With the unnecessary marker gone from the model, the kinematic analysis +runs faster than before. Each marker adds DoFs and constraints to +the model, and they require solution time. It is therefore more +efficient to leave the markers out unless you really need them. + +Now that there is a driver between pendulum and the marker, it is possible +to simultaneously draw both the point on the pendulum and the marker +from the C3D file. To do this, start by placing the cursor inside the +`AnyKinDriverMarker` object. + +Then click the Classes tab on the right side of screen, insert a new +`AnyDrawKinMeasure` template, remove the properties we will not need and give +it a name: + +```{literalinclude} Snippets/lesson2/snip.Pendulum.main-7.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 +``` + +If you reload the model, you should see something like this: + +```{image} _static/lesson2/image4.jpeg +:alt: Model view AnyKinDriver marker +:align: center +:width: 50% +``` + +The blue dot illustrates the marker from the c3d file and the red line +is drawn to illustrate the difference between the point on the segment +and the measured point. Please notice that there is a small ball hidden +inside yellow sphere from the drawing of the segment. The plot also +shows a label “KDM”, which indicates that it is an `AnyKinDriverMarker` +that is drawn. + +The line between the two points and the label can be removed by changing +the `Label` and `Line` settings to Off. Let us also change the size of the +dots such that we can see both the point on the segment as well as the +measured point. + +```{literalinclude} Snippets/lesson2/snip.Pendulum.main-8.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 +``` + +Reloading the model should show you something like this: + +```{image} _static/lesson2/image5.jpeg +:alt: Model view DrawKinMeasure +:align: center +:width: 50% +``` + +Let us briefly investigate the kinematic constraints of our model. Click +the Model tab in the tree view on the left hand side of the screen and +unfold the `Joint` branch. Inside you find `Constraints`, and after +unfolding that branch you find the property `CType`. If you double-click +it, the popup window shows the following: + +```AnyScriptDoc +CType = {Hard, Hard, Hard, Hard, Hard} +``` + +`CType` appears to be a vector with five components, owing to the fact +that a revolute joint has five constraints, and CType specifies that all +of these are `Hard`. This means that the kinematic solver is not allowed +to violate any of them. + +If you similarly locate and unfold the `C3DMotion` object you again find a +`CType`, and double-clicking it reveals + +```AnyScriptDoc +CType = {Soft, Soft, Soft} +``` + +We have implicitly specified that the joint is a hard constraint while +the marker is a soft constraint. Joints automatically have their +constraint types set to Hard and `AnyKinDriverMarker` objects +automatically have soft constraints, but these rules can be overridden +by the user by explicit specification of `CType` in the respective +objects. + +In {doc}`Lesson 3 ` we investigate how to filter noise out of +the measured data. diff --git a/Making_things_move/lesson3.md b/Motion_Capture_Movement/lesson3.md similarity index 68% rename from Making_things_move/lesson3.md rename to Motion_Capture_Movement/lesson3.md index bd7c3c51..9c3aeada 100644 --- a/Making_things_move/lesson3.md +++ b/Motion_Capture_Movement/lesson3.md @@ -1,13 +1,19 @@ ::: {rst-class} break ::: -# Lesson3: Noise and filters +# Lesson 3: Noise and filters + +In this lesson we will consider noise in the kinematic analysis of the +pendulum and apply a filter to improve the results. Let us run the Kinematics operation and investigate the results. After the operation has completed, please open the Chart View tab and plot the position vector of the pendulum as shown below: -![pendulum.r](_static/lesson3/image1.png) +```{image} _static/lesson3/image1.png +:alt: pendulum.r +:align: center +``` The blue, orange and green curves designate x, y and z locations respectively of the center of mass of the pendulum. We see the expected @@ -18,13 +24,21 @@ it is not. If we plot the velocity, `rDot`, rather than the position, we begin to see the problem: -![pendulum.rdot](_static/lesson3/image2.png) +```{image} _static/lesson3/image2.png +:alt: pendulum.rdot +:align: center +:width: 70% +``` It is obvious that the motion is not as smooth as we would expect from the first set of graphs, and it gets even worse if we plot the accelerations, `rDDot`: -![pendulum.rddot](_static/lesson3/image3.png) +```{image} _static/lesson3/image3.png +:alt: pendulum.rddot +:align: center +:width: 70% +``` Since forces in a mechanical system stem from accelerations, an analysis of the force in this system would lead to a completely different result @@ -41,22 +55,13 @@ a second-order, zero-phase Butterworth filter with a cutoff frequency of going to get. In this case, it is obviously not sufficient, so let’s play a bit with the settings and see whether we can get better results. -The filter section of the `AnyInputC3D` section is currently inactive. -Please remove the `/* */` surrounding the object, and you will have the -following: - -```AnyScriptDoc -Filter = -{ -z0 = ; -AutomaticInitialConditionOnOff = On; -FilterForwardBackwardOnOff = On; -N = 2; -W = ; -Fs = 0.0; -Fc = {10.0}; -Type = LowPass; -}; +Previously, we deleted the filter section of the `AnyInputC3D`. So please insert +the following: + +```{literalinclude} Snippets/lesson3/snip.Pendulum.main-1.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` The first two lines pertain to the filter’s initial condition, and `z0` @@ -68,39 +73,34 @@ in the signal, but it may not always be good enough, and in this case it can be relevant to set the initial conditions. For now, let us keep the automatic setting and therefore remove the incomplete line with `z0`: -```AnyScriptDoc -Filter = { - §// z0 = ;§ - AutomaticInitialConditionOnOff = On; - FilterForwardBackwardOnOff = On; - N = 2; - W = ; - Fs = 0; - Fc = {10}; - Type = LowPass; -}; +```{literalinclude} Snippets/lesson3/snip.Pendulum.main-2.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` -The third line, `FilterForwardBackwardOnOff`, is mostly included for the +The defined parameters have the following meanings: + + - The third line, `FilterForwardBackwardOnOff`, is mostly included for the sake of completeness. When it is set to `On`, zero phase shift in the filter is obtained by filtering twice, i.e. first forward and then backward in the signal, which is the standard approach. Please leave it as it is unless you really know what you are doing. -The property `N` is simply the order of the filter. The default value is 2 + - The property `N` is simply the order of the filter. The default value is 2 and higher values lead to sharper cuts at the specified cutoff frequency. -`W` is the normalized cutoff frequency. Allowed values are between zero + - `W` is the normalized cutoff frequency. Allowed values are between zero and one with one corresponding to half of the sampling frequency. However, it is not allowed to specify `W` when filtering data from a C3D file because the file already contains information about the sampling frequency, so you can safely delete this line. -`Fs` is the sampling frequency, and like `W`, we cannot specify it when + - `Fs` is the sampling frequency, and like `W`, we cannot specify it when reading from a C3D file, so please remove this line. -`Fc` is the cutoff frequency and is set to 10 Hz by default. The dilemma + - `Fc` is the cutoff frequency and is set to 10 Hz by default. The dilemma with filters is always that they can reduce noise and other undesirable elements of the signal, but in the process they also may remove desirable parts of the signal or even introduce artifacts. 10 Hz is a @@ -108,32 +108,36 @@ relatively safe value for experiments with human motion, but it would obviously not be a safe choice if we were modeling insect motion or other phenomena with higher frequency content. -Finally, the last line specifies the type of the filter as low pass, + - Finally, the last line specifies the type of the filter as low pass, which is the relevant value for a signal like this, where the noise is high frequency, but the filters in AnyBody also allow for other types. Please refer to the reference manual for a complete description. -In the graph of `Pendulum.r` above, the red curve seems to have a -frequency of about 0.2 Hz and the green curve about 0.4 Hz. This is +:::{note} +To quickly access the reference manual, simply place your cursor on +the desired word and press `F1`. +::: + +In the graph of `Pendulum.r` above, the blue curve seems to have a +frequency of about 0.2 Hz and the orange curve about 0.4 Hz. This is safely below our present 10 Hz cutoff frequency, so there seems to be -room to eliminate more noise by using a lower value of `Fc`. If we change - -```AnyScriptDoc -Filter = { - // z0 = ; - AutomaticInitialConditionOnOff = On; - FilterForwardBackwardOnOff = On; - N = 2; - Fc = {§2§}; - Type = LowPass; -}; +room to eliminate more noise by using a lower value of `Fc`. If we change, + +```{literalinclude} Snippets/lesson3/snip.Pendulum.main-3.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` -…we can get the following accelerations: +…load and rerun the model, we can get the following accelerations: -![pendulumfilt](_static/lesson3/image4.png) +```{image} _static/lesson3/image4.png +:alt: pendulumfilt +:align: center +:width: 70% +``` -They look much more reasonable, but notice that each end of the curve is +They look much more reasonable, but notice that each end of the curves is influenced by the initial conditions of the filter. Filters remove noise but they are also sources of artifacts in the model and nothing is ever completely perfect. diff --git a/Making_things_move/lesson4.md b/Motion_Capture_Movement/lesson4.md similarity index 51% rename from Making_things_move/lesson4.md rename to Motion_Capture_Movement/lesson4.md index 17031ed5..0aa3484c 100644 --- a/Making_things_move/lesson4.md +++ b/Motion_Capture_Movement/lesson4.md @@ -18,62 +18,22 @@ length of the femur and the location of the hip joint center are always somewhat uncertain. In this section, we are going to see how the data in a C3D file can help us automatically determine these parameters with good accuracy. +## Building the Initial Model + Please download and save the file {download}`multiple.c3d `. -Then close all open windows in AnyBody and create a new Main file by -clicking the ‘M’ tool button in the upper left hand corner of the main -frame. This give you a dialog to create an empty model into which you can insert an -`AnyInputC3D` object, refer to the {file}`multiple.c3d` file and specify the -filter as we did before: - -```AnyScriptDoc -Main = { - - // The actual body model goes in this folder - AnyFolder MyModel = { - // Global Reference Frame - AnyFixedRefFrame GlobalRef = { - // Todo: Add points for grounding of the model here - }; // Global reference frame - - AnyInputC3D §C3D§ = - { - FileName = §"multiple.c3d"§; - //ReadAllDataOnOff = On; - //TruncateExtraCharsInNamesOnOff = On; - //MakeNameUniqueStr = "_"; - //PointsScaleFactor = 1.0; - //ConstructModelOnOff = On; - §ConstructChartOnOff = Off;§ - //ConstructWeightFunUsingResidualOnOff = Off; - //GapFillUsingResidualsOnOff = Off; - //MarkerUseAllPointsOnOff = Off; - //MarkerUseCamMaskOnOff = On; - //MarkerIndices = ; - //MarkerLabels = ; - //MarkerFilterIndex = 0; - //ProcessedDataFilterIndex = 0; - //AnalogFilterIndex = -1; - §Filter = - { - AutomaticInitialConditionOnOff = On; - FilterForwardBackwardOnOff = On; - N = 2; - Fc = {3}; - Type = LowPass; - };§ - //WeightThreshold = 0.0; - //WeightOutput = {{0.0, 1.0}, {0.0, 1.0}, {0.0, 1.0}}; - //WeightTransitionTime = 0.1; - //SearchAndReplace = ; - //WriteMarkerDataToFilesOnOff = Off; - //MarkerScaleXYZ = {0.025, 0.025, 0.025}; - §MarkerRGB = {0, 0, 1};§ - //MarkerDrawOnOff = On; - //MarkerInterPolType = Bspline; - //MarkerBsplineOrder = 4; - }; +Then close all open windows in AnyBody and create a new '*Basic Main*' file by +clicking the ‘M’ tool button ![M](_static/lesson4/image7.png) in the upper left +hand corner of the main frame and save it in the same folder as the +'multiple.c3d' file. This gives you a dialog to create an empty model into which +you can insert an `AnyInputC3D` object, refer to the {file}`multiple.c3d` file +and specify the filter as we did in the previous two lessons: + +```{literalinclude} Snippets/lesson4/snip.Multiple.main-1.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` Notice that we have also colored the markers blue with the `MarkerRGB` @@ -81,23 +41,17 @@ property and disabled the plot of the 3D trajectories with the `ConstructChartOnOff` property. We also set the duration of the movement to automatically fit the C3D file as we have done before: -```AnyScriptDoc -// The study: Operations to be performed on the model -AnyBodyStudy MyStudy = { - AnyFolder &Model = .MyModel; - Gravity = {0.0, -9.81, 0.0}; - §AnyIntVar FirstFrame = Main.MyModel.C3D.Header.FirstFrameNo; - AnyIntVar LastFrame = Main.MyModel.C3D.Header.LastFrameNo; - tStart = FirstFrame/Main.MyModel.C3D.Header.VideoFrameRate+2*Kinematics.ApproxVelAccPerturb; - tEnd = LastFrame/Main.MyModel.C3D.Header.VideoFrameRate-2*Kinematics.ApproxVelAccPerturb;§ -}; +```{literalinclude} Snippets/lesson4/snip.Multiple.main-1.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 2 +:end-before: //# END SNIPPET 2 ``` -Now you should be able to load and run the model and see three blue -markers travel through space in a motion that bears some resemblance to -a football kick. The three markers are located on the same segment, and -we happen to know that this segment is hinged in its upper end just like -the pendulum in the previous lesson, but we do not know exactly where. +Now you should be able to load and run kinematic analysis of the model and see +three blue markers travel through space in a motion that bears some resemblance +to a football kick. The three markers are located on the same segment, and we +happen to know that this segment is hinged in its upper end just like the +pendulum in the previous lesson, but we do not know exactly where. Three markers per segment are typical for many motion capture marker protocols. A segment with no other constraints, i.e. floating freely in @@ -117,99 +71,32 @@ be used to determine other unknown factors in the model. Let us initially define a segment and some guesses of where the three markers may be located on it: -```AnyScriptDoc -Main = { - - // The actual body model goes in this folder - AnyFolder MyModel = { - // Global Reference Frame - AnyFixedRefFrame GlobalRef = { - // Todo: Add points for grounding of the model here - }; // Global reference frame - - §AnySeg Leg = { - Mass = 1; - Jii = {1, 0.01, 1}/15; - AnyRefNode R1 = { - sRel = {0.038, 0.18, 0.022}; - }; - AnyRefNode R2 = { - sRel = {-0.015, -0.104, 0.028}; - }; - AnyRefNode R3 = { - sRel = {-0.022, -0.403, -0.023}; - }; - AnyDrawSeg drw = {}; - };§ - - AnyInputC3D C3D = - { - FileName = "multiple.c3d"; +```{literalinclude} Snippets/lesson4/snip.Multiple.main-2.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` -Now we just need to use AnyKinDriverMarker objects to tie the marker -trajectories to the three points we have defined on the segment and +Now we just need to use `AnyKinDriverMarker` objects to tie the marker +trajectories to the three points we have defined on the segment. Then select the solvers for over-determinate problems exactly as we did in the previous lesson (don’t forget to also select the over-determinate kinematics solver in the study section): -```AnyScriptDoc - §AnyKinDriverMarker C3Dmotion1 = { - AnyRefFrame &Marker = .Leg.R1; - AnyParamFun &Trajectory= - Main.MyModel.C3D.Points.Markers.L000.PosInterpol; - AnyDrawKinMeasure drw = { - Label = Off;Size = 0.03;Line = Off; - }; - }; - AnyKinDriverMarker C3Dmotion2 = { - AnyRefFrame &Marker = .Leg.R2; - AnyParamFun &Trajectory = - Main.MyModel.C3D.Points.Markers.L001.PosInterpol; - AnyDrawKinMeasure drw = { - Label = Off;Size = 0.03;Line = Off; - }; - }; - AnyKinDriverMarker C3Dmotion3 = { - AnyRefFrame &Marker = .Leg.R3; - AnyParamFun &Trajectory = - Main.MyModel.C3D.Points.Markers.L002.PosInterpol; - AnyDrawKinMeasure drw = { - Label = Off;Size = 0.03;Line = Off; - }; - };§ -}; // MyModel - -// The study: Operations to be performed on the model - AnyBodyStudy MyStudy = { - AnyFolder &Model = .MyModel; - Gravity = {0.0, -9.81, 0.0}; - AnyIntVar FirstFrame = Main.MyModel.C3D.Header.FirstFrameNo; - AnyIntVar LastFrame = Main.MyModel.C3D.Header.LastFrameNo; - tStart = FirstFrame/Main.MyModel.C3D.Header.VideoFrameRate+2*Kinematics.ApproxVelAccPerturb; - tEnd = LastFrame/Main.MyModel.C3D.Header.VideoFrameRate-2*Kinematics.ApproxVelAccPerturb; - §InitialConditions.SolverType = KinSolOverDeterminate; - Kinematics.SolverType = KinSolOverDeterminate;§ - }; +```{literalinclude} Snippets/lesson4/snip.Multiple.main-2.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 2 +:end-before: //# END SNIPPET 2 ``` -Now that we have created the AnyDrawKinMeasure objects, it is no longer +Now that we have created the `AnyDrawKinMeasure` objects, it is no longer necessary to have the points drawn in the C3D object. So let us get rid of them: -```AnyScriptDoc -AnyInputC3D C3D = -{ - FileName = "multiple.c3d"; - //ReadAllDataOnOff = On; - //TruncateExtraCharsInNamesOnOff = On; - //MakeNameUniqueStr = "_"; - //PointsScaleFactor = 1.0; - §ConstructModelOnOff = Off;§ - ConstructChartOnOff = Off; - //ConstructWeightFunUsingResidualOnOff = Off; - //GapFillUsingResidualsOnOff = Off; - //MarkerUseAllPointsOnOff = Off; +```{literalinclude} Snippets/lesson4/snip.Multiple.main-2.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 3 +:end-before: //# END SNIPPET 3 ``` It is now possible to run the Kinematics operation and see the leg @@ -217,34 +104,24 @@ segment move with the markers. The actual markers are not visible because they disappear inside the segment, but if we make the segment semi-transparent, they become visible: -```AnyScriptDoc -AnySeg Leg = { - Mass = 1; - Jii = {1, 0.01, 1}/15; - AnyRefNode R1 = { - sRel = {0.038, 0.18, 0.022}; - }; - AnyRefNode R2 = { - sRel = {-0.015, -0.104, 0.028}; - }; - AnyRefNode R3 = { - sRel = {-0.022, -0.403, -0.023}; - }; - AnyDrawSeg drw = { - §Opacity = 0.5;§ - }; -}; +```{literalinclude} Snippets/lesson4/snip.Multiple.main-3.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` We will also add a a drawing for the global reference frame, to better visualize the movement. -```AnyScriptDoc -AnyFixedRefFrame GlobalRef = { - §AnyDrawRefFrame drw = {};§ -}; +```{literalinclude} Snippets/lesson4/snip.Multiple.main-3.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 2 +:end-before: //# END SNIPPET 2 ``` -![pendulum 1](_static/lesson4/image1.jpeg) +```{image} _static/lesson4/image1.jpeg +:alt: pendulum 1 +:align: center +``` The animation reveals that the leg seems to rotate about the origin of the global reference frame, although we have not explicitly defined any @@ -253,24 +130,10 @@ segment, but we do not know exactly where that is. Let us define a joint point at an approximate location on the leg: -```AnyScriptDoc -AnySeg Leg = { - Mass = 1; - Jii = {1, 0.01, 1}/15; - §AnyRefNode Joint = { - sRel = {0, 0.45, 0}; - };§ - AnyRefNode R1 = { - sRel = {0.038, 0.18, 0.022}; - }; - AnyRefNode R2 = { - sRel = {-0.015, -0.104, 0.028}; - }; - AnyRefNode R3 = { - sRel = {-0.022, -0.403, -0.023}; - }; - AnyDrawSeg drw = {Opacity = 0.5;}; -}; +```{literalinclude} Snippets/lesson4/snip.Multiple.main-4.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` If you reload and re-run the model, you will see that the new point is @@ -281,15 +144,10 @@ location for now. The next step is to create a revolute joint between the new point and the origin of the global reference frame: -```AnyScriptDoc -§AnyRevoluteJoint Joint = { - AnyRefFrame &Ground = .GlobalRef; - AnyRefFrame &Pendulum = .Leg.Joint; -};§ - -AnyInputC3D C3D = -{ - FileName = "multiple.c3d"; +```{literalinclude} Snippets/lesson4/snip.Multiple.main-4.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 2 +:end-before: //# END SNIPPET 2 ``` A reload and re-run will reveal that the point is now forced to coincide @@ -299,13 +157,18 @@ constraints that must be exactly fulfilled. The consequence is that the blue marker dots inside the leg segment points now seem to deviate a bit further from the center of the points. -![pendulum 2](_static/lesson4/image2.jpeg) +```{image} _static/lesson4/image2.jpeg +:alt: pendulum 2 +:align: center +``` There seems to be some unknown location of the joint center on the leg and possibly also of the marker points on the segment that we could either find by experimenting manually with the local coordinates of the points on the leg segment or, alternatively, ask AnyBody to find for us. +## Setting Up the Parameter Optimization Study + We are going to do the latter, and we shall employ a special study that AnyBody has implemented for the purpose. Please click on the Classes tab in the Tree View on the right side of the screen, expand the @@ -313,35 +176,10 @@ Class List, and scroll down to find the `AnyOptKinStudy`. Place the cursor after the end brace of the existing AnyBody Study, right-click the `AnyOptKinStudy` in the Class Tree, and insert a template of the class: -```AnyScriptDoc -// The study: Operations to be performed on the model - AnyBodyStudy MyStudy = { - AnyFolder &Model = .MyModel; - Gravity = {0.0, -9.81, 0.0}; - AnyIntVar FirstFrame = Main.MyModel.C3D.Header.FirstFrameNo; - AnyIntVar LastFrame = Main.MyModel.C3D.Header.LastFrameNo; - tStart = FirstFrame/Main.MyModel.C3D.Header.VideoFrameRate+2*Kinematics.ApproxVelAccPerturb; - tEnd = LastFrame/Main.MyModel.C3D.Header.VideoFrameRate-2*Kinematics.ApproxVelAccPerturb; - InitialConditions.SolverType = KinSolOverDeterminate; - Kinematics.SolverType = KinSolOverDeterminate; - }; - §AnyOptKinStudy = - { - //LogFile = ""; - /*Analysis = - { - Settings = - { - Echo = On; - ModelSceneUpdate = On; - }; - //AnyOperation & = ; You can make any number of these objects! - };*/ - //MaxIterationStep = 100; - AnyDesMeasure & = ; - //AnyDesMeasure & = ; You can make any number of these objects! - //AnyDesVar & = ; You can make any number of these objects! - };§ +```{literalinclude} Snippets/lesson4/snip.Multiple.main-4.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 3 +:end-before: //# END SNIPPET 3 ``` The `AnyOptKinStudy`’s structure is very similar to the general optimization @@ -353,15 +191,10 @@ evaluate them. We begin with the latter and make the following changes: -```AnyScriptDoc -AnyOptKinStudy §OptKinStudy§ = -{ - §Analysis = { - AnyOperation &Operation= ..MyStudy.Kinematics; - };§ - //MaxIterationStep = 100; - AnyDesMeasure & = ; -}; +```{literalinclude} Snippets/lesson4/snip.Multiple.main-5.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` Now we have specified that we want to optimize parameters to fit the @@ -392,34 +225,24 @@ of the Joint node on the Leg segment is a variable in the problem. Similarly, we can add the y and z coordinates: -```AnyScriptDoc -AnyOptKinStudy OptKinStudy = -{ - Analysis = { - AnyOperation &Operation= ..MyStudy.Kinematics; - }; - //MaxIterationStep = 100; - AnyDesVar Jointx = { - Val = Main.MyModel.Leg.Joint.sRel[0]; - }; - §AnyDesVar Jointy = { - Val = Main.MyModel.Leg.Joint.sRel[1]; - }; - AnyDesVar Jointz = { - Val = Main.MyModel.Leg.Joint.sRel[2]; - };§ -}; +```{literalinclude} Snippets/lesson4/snip.Multiple.main-6.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` Now we can reload the model and a new set of operations will have appeared: -![image2](_static/lesson4/image3.png) +```{image} _static/lesson4/image3.png +:alt: Operation tree +:align: center +``` -Pick the `ParameterOptimization` and click the *Run* button. +Pick the `ParameterOptimization` and click the *Execute* button. If you have a Model View open, you will see the pendulum starting to move and -messages about the convergence of the process will appear in the Report View at +messages about the convergence of the process will appear in the Output View at the bottom of the screen. Pay close attention to the location of the small blue markers inside the larger @@ -428,12 +251,18 @@ centers of the yellow balls as a consequence of the optimization as shown below, where the left picture is the location of the markers before the joint location optimization, and the right picture shows the situation after optimization. -![before opt](_static/lesson4/image2.jpeg) ![after opt](_static/lesson4/image4.jpeg) +```{image} _static/lesson4/image4.jpeg +:alt: before opt +:align: center +``` -This notion is confirmed by opening opening the chart view and plotting the +This notion is confirmed by opening the chart view and plotting the development of the objective function of the problem: -![opt history](_static/lesson4/image5.png) +```{image} _static/lesson4/image5.png +:alt: opt history +:align: center +``` The graph shows that the norm of the difference between the measured marker positions and the corresponding nodes on the segment over the @@ -451,20 +280,21 @@ you keep the model and specify a name for the new file, for instance If you open the new file you can see the saved values: ```none -Jointx 1.574794116583949e-002 -Jointy 4.907819352974447e-001 -Jointz 6.507036792142549e-004 +Jointx 1.574794116582883e-02 +Jointy 4.907819352974451e-01 +Jointz 6.507036792142557e-04 ``` You can easily load these values into your model from the same context menu every time you have reloaded the model. -Of course, to have the -coordinates of the Joint node permanently updated, you can also simply -copy and paste them into the sRel value directly in the Leg segment -definition in your AnyScript file. Don’t do it yet, though. We are going +Of course, to have the coordinates of the Joint node permanently updated, you +can also simply copy and paste them into the `sRel` value directly in the Leg +segment definition in your AnyScript file. Don’t do it yet, though. We are going to play a little more with the possibilities. +### Including the Marker Positions in the Parameter Optimization + The optimization we have just completed has presumed that we know well where the markers are located on the segment but are in doubt about the location of the joint, such as would often be the case in a gait @@ -475,7 +305,7 @@ protocol that places most markers on well-defined bony landmarks in the model, there may still be doubt about the precise locations of some or all the markers, and the result of the joint location optimization also shows that especially the first marker location deviates somewhat from -its corresponding AnyRefNode. This indicates that there are other +its corresponding `AnyRefNode`. This indicates that there are other sources of error in the model, than the joint location, and indeed the recent relocation of the joint may be influenced by errors that are not associated with the joint location. @@ -489,31 +319,10 @@ locations. The marker node position is included in the optimization in the same way as the Joint node: -```AnyScriptDoc -AnyOptKinStudy OptKinStudy = -{ - Analysis = { - AnyOperation &Operation= ..MyStudy.Kinematics; - }; - //MaxIterationStep = 100; - AnyDesVar Jointx = { - Val = Main.MyModel.Leg.Joint.sRel[0]; - }; - AnyDesVar Jointy = { - Val = Main.MyModel.Leg.Joint.sRel[1]; - }; - AnyDesVar Jointz = { - Val = Main.MyModel.Leg.Joint.sRel[2]; - }; - §AnyDesVar R1x = { - Val = Main.MyModel.Leg.R1.sRel[0]; - }; - AnyDesVar R1y = { - Val = Main.MyModel.Leg.R1.sRel[1]; - }; - AnyDesVar R1z = { - Val = Main.MyModel.Leg.R1.sRel[2]; - };§ +```{literalinclude} Snippets/lesson4/snip.Multiple.main-7.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` Please reload and re-run the `Main.OptKinStudy.ParameterOptimization`. @@ -524,7 +333,10 @@ To speed up the optimization study, try to disable Model View by clicking the "O The convergence should be quite fast in such a small model, and you arrive at the following solution: -![Pendulum final](_static/lesson4/image6.jpeg) +```{image} _static/lesson4/image6.jpeg +:alt: Pendulum final +:align: center +``` The solution appears to be bull’s eye in terms of placing the markers in the center of the yellow nodes. This is confirmed by the optimized value @@ -535,40 +347,10 @@ It appears that we have obtained an almost perfect solution, but why not include all the marker nodes in the optimization? Well, we can try adding another one: -```AnyScriptDoc -AnyOptKinStudy OptKinStudy = -{ - Analysis = { - AnyOperation &Operation= ..MyStudy.Kinematics; - }; - //MaxIterationStep = 100; - AnyDesVar Jointx = { - Val = Main.MyModel.Leg.Joint.sRel[0]; - }; - AnyDesVar Jointy = { - Val = Main.MyModel.Leg.Joint.sRel[1]; - }; - AnyDesVar Jointz = { - Val = Main.MyModel.Leg.Joint.sRel[2]; - }; - AnyDesVar R1x = { - Val = Main.MyModel.Leg.R1.sRel[0]; - }; - AnyDesVar R1y = { - Val = Main.MyModel.Leg.R1.sRel[1]; - }; - AnyDesVar R1z = { - Val = Main.MyModel.Leg.R1.sRel[2]; - }; - §AnyDesVar R2x = { - Val = Main.MyModel.Leg.R2.sRel[0]; - }; - AnyDesVar R2y = { - Val = Main.MyModel.Leg.R2.sRel[1]; - }; - AnyDesVar R2z = { - Val = Main.MyModel.Leg.R2.sRel[2]; - };§ +```{literalinclude} Snippets/lesson4/snip.Multiple.main-8.any +:language: AnyScriptDoc +:start-after: //# BEGIN SNIPPET 1 +:end-before: //# END SNIPPET 1 ``` When you reload the model and re-run the ParameterOptimization, you will @@ -577,7 +359,7 @@ less stable, the segment moves far away from the marker nodes in the process, and eventually the algorithm gives up with the error message: ```none -Optimization failed : Failed to solve position analysis +Failed to resolve kinematic constraints. Newton relaxation too small. ``` You can understand the reason for this behavior if you look at the @@ -608,7 +390,6 @@ technology works. % seealso: `Andersen et al. 2009 `_ % for details on how the parameter identification algorithm works, and the math behind. -Now, let us change our focus to a top-down approach -and see what the technology can do with real motion capture data. That -will be the subject of {doc}`Lesson 5 `. - +Now that you've explored a comprehensive AMMR model using real motion capture +data and created two simple models yourself, let's dive into some common +troubleshooting tips for C3D files in {doc}`Lesson 5 `. diff --git a/Making_things_move/lesson6.md b/Motion_Capture_Movement/lesson5.md similarity index 92% rename from Making_things_move/lesson6.md rename to Motion_Capture_Movement/lesson5.md index 05964e0a..dc37d62a 100644 --- a/Making_things_move/lesson6.md +++ b/Motion_Capture_Movement/lesson5.md @@ -1,7 +1,7 @@ ::: {rst-class} break ::: -# Lesson 6: Troubleshooting C3D files +# Lesson 5: Troubleshooting C3D files Occasionally you may experience problems reading C3D files and some of the common issues are treated below. But before we get to them, let us @@ -23,7 +23,7 @@ about every conceivable computer system means that it has a rather complex structure and that there are rigid and precise rules for the creation of C3D files. An unfortunate consequence of this is that the format is error prone in the sense that not all software systems create -C3D files that live completely up to the standard. The AnyInputC3D class +C3D files that live completely up to the standard. The `AnyInputC3D` class in AnyBody is designed to cope with most of the common deviations from the standard, but occasionally you may run into a problem. Here are some of the common problems and solutions: @@ -40,7 +40,7 @@ will be very far apart, and if you Zoom All in the model view, the markers may be so small compared to the viewed space that you cannot see them. -The remedy is to set the PointScaleFactor in the AnyInputC3D object to +The remedy is to set the `PointScaleFactor` in the `AnyInputC3D` object to 0.001, for instance, in the case of data in millimeters. The second frequent explanation is that a C3D file contains two data @@ -111,3 +111,7 @@ AnyBody passes through a piece of software that truncates the names, then AnyBody will be given a C3D file where all the marker names are truncated to just `MARK`. AnyBody will not accept non-unique marker names and therefore renames them automatically. + +This concludes the tutorials on implementing Motion Capture movement into +AnyBody, building and driving simple models, addressing noise and filtering, +identifying key parameters, and troubleshooting common issues with C3D files. diff --git a/Making_things_move/lesson_weight_deprecated.txt b/Motion_Capture_Movement/lesson_weight_deprecated.txt similarity index 100% rename from Making_things_move/lesson_weight_deprecated.txt rename to Motion_Capture_Movement/lesson_weight_deprecated.txt diff --git a/Making_things_move/material/1test0001.tsv b/Motion_Capture_Movement/material/1test0001.tsv similarity index 100% rename from Making_things_move/material/1test0001.tsv rename to Motion_Capture_Movement/material/1test0001.tsv diff --git a/Making_things_move/material/Interpolation.xlsx b/Motion_Capture_Movement/material/Interpolation.xlsx similarity index 100% rename from Making_things_move/material/Interpolation.xlsx rename to Motion_Capture_Movement/material/Interpolation.xlsx diff --git a/Making_things_move/material/Opt1.txt b/Motion_Capture_Movement/material/Opt1.txt similarity index 100% rename from Making_things_move/material/Opt1.txt rename to Motion_Capture_Movement/material/Opt1.txt diff --git a/Making_things_move/material/PendulumID.any b/Motion_Capture_Movement/material/PendulumID.any similarity index 100% rename from Making_things_move/material/PendulumID.any rename to Motion_Capture_Movement/material/PendulumID.any diff --git a/Making_things_move/material/afteropt.jpg b/Motion_Capture_Movement/material/afteropt.jpg similarity index 100% rename from Making_things_move/material/afteropt.jpg rename to Motion_Capture_Movement/material/afteropt.jpg diff --git a/Making_things_move/material/beforeafter.jpg b/Motion_Capture_Movement/material/beforeafter.jpg similarity index 100% rename from Making_things_move/material/beforeafter.jpg rename to Motion_Capture_Movement/material/beforeafter.jpg diff --git a/Making_things_move/material/kick1.jpg b/Motion_Capture_Movement/material/kick1.jpg similarity index 100% rename from Making_things_move/material/kick1.jpg rename to Motion_Capture_Movement/material/kick1.jpg diff --git a/Making_things_move/material/kick2.jpg b/Motion_Capture_Movement/material/kick2.jpg similarity index 100% rename from Making_things_move/material/kick2.jpg rename to Motion_Capture_Movement/material/kick2.jpg diff --git a/Making_things_move/material/kinematicsrun.png b/Motion_Capture_Movement/material/kinematicsrun.png similarity index 100% rename from Making_things_move/material/kinematicsrun.png rename to Motion_Capture_Movement/material/kinematicsrun.png diff --git a/Making_things_move/material/limbo.jpg b/Motion_Capture_Movement/material/limbo.jpg similarity index 100% rename from Making_things_move/material/limbo.jpg rename to Motion_Capture_Movement/material/limbo.jpg diff --git a/Making_things_move/material/limbo.png b/Motion_Capture_Movement/material/limbo.png similarity index 100% rename from Making_things_move/material/limbo.png rename to Motion_Capture_Movement/material/limbo.png diff --git a/Making_things_move/material/modeltree.gif b/Motion_Capture_Movement/material/modeltree.gif similarity index 100% rename from Making_things_move/material/modeltree.gif rename to Motion_Capture_Movement/material/modeltree.gif diff --git a/Making_things_move/material/modeltree2.gif b/Motion_Capture_Movement/material/modeltree2.gif similarity index 100% rename from Making_things_move/material/modeltree2.gif rename to Motion_Capture_Movement/material/modeltree2.gif diff --git a/Motion_Capture_Movement/material/multiple.c3d b/Motion_Capture_Movement/material/multiple.c3d new file mode 100644 index 00000000..e7844f7e Binary files /dev/null and b/Motion_Capture_Movement/material/multiple.c3d differ diff --git a/Making_things_move/material/multiple.tsv b/Motion_Capture_Movement/material/multiple.tsv similarity index 100% rename from Making_things_move/material/multiple.tsv rename to Motion_Capture_Movement/material/multiple.tsv diff --git a/Making_things_move/material/multiple.xlsx b/Motion_Capture_Movement/material/multiple.xlsx similarity index 100% rename from Making_things_move/material/multiple.xlsx rename to Motion_Capture_Movement/material/multiple.xlsx diff --git a/Making_things_move/material/multiple_with_dropout.c3d b/Motion_Capture_Movement/material/multiple_with_dropout.c3d similarity index 100% rename from Making_things_move/material/multiple_with_dropout.c3d rename to Motion_Capture_Movement/material/multiple_with_dropout.c3d diff --git a/Making_things_move/material/operationstree1.gif b/Motion_Capture_Movement/material/operationstree1.gif similarity index 100% rename from Making_things_move/material/operationstree1.gif rename to Motion_Capture_Movement/material/operationstree1.gif diff --git a/Making_things_move/material/opthistory.gif b/Motion_Capture_Movement/material/opthistory.gif similarity index 100% rename from Making_things_move/material/opthistory.gif rename to Motion_Capture_Movement/material/opthistory.gif diff --git a/Making_things_move/material/pendulum.any b/Motion_Capture_Movement/material/pendulum.any similarity index 100% rename from Making_things_move/material/pendulum.any rename to Motion_Capture_Movement/material/pendulum.any diff --git a/Motion_Capture_Movement/material/pendulum.c3d b/Motion_Capture_Movement/material/pendulum.c3d new file mode 100644 index 00000000..3f448426 Binary files /dev/null and b/Motion_Capture_Movement/material/pendulum.c3d differ diff --git a/Making_things_move/material/pendulum.tsv b/Motion_Capture_Movement/material/pendulum.tsv similarity index 100% rename from Making_things_move/material/pendulum.tsv rename to Motion_Capture_Movement/material/pendulum.tsv diff --git a/Making_things_move/material/pendulum.txt b/Motion_Capture_Movement/material/pendulum.txt similarity index 100% rename from Making_things_move/material/pendulum.txt rename to Motion_Capture_Movement/material/pendulum.txt diff --git a/Making_things_move/material/pendulum.xlsx b/Motion_Capture_Movement/material/pendulum.xlsx similarity index 100% rename from Making_things_move/material/pendulum.xlsx rename to Motion_Capture_Movement/material/pendulum.xlsx diff --git a/Making_things_move/material/pendulumfilt.gif b/Motion_Capture_Movement/material/pendulumfilt.gif similarity index 100% rename from Making_things_move/material/pendulumfilt.gif rename to Motion_Capture_Movement/material/pendulumfilt.gif diff --git a/Making_things_move/material/pendulumr.gif b/Motion_Capture_Movement/material/pendulumr.gif similarity index 100% rename from Making_things_move/material/pendulumr.gif rename to Motion_Capture_Movement/material/pendulumr.gif diff --git a/Making_things_move/material/pendulumrddot.gif b/Motion_Capture_Movement/material/pendulumrddot.gif similarity index 100% rename from Making_things_move/material/pendulumrddot.gif rename to Motion_Capture_Movement/material/pendulumrddot.gif diff --git a/Making_things_move/material/pendulumrdot.gif b/Motion_Capture_Movement/material/pendulumrdot.gif similarity index 100% rename from Making_things_move/material/pendulumrdot.gif rename to Motion_Capture_Movement/material/pendulumrdot.gif diff --git a/Making_things_move/material/pendulumtri.any b/Motion_Capture_Movement/material/pendulumtri.any similarity index 100% rename from Making_things_move/material/pendulumtri.any rename to Motion_Capture_Movement/material/pendulumtri.any diff --git a/Making_things_move/material/savedesign.gif b/Motion_Capture_Movement/material/savedesign.gif similarity index 100% rename from Making_things_move/material/savedesign.gif rename to Motion_Capture_Movement/material/savedesign.gif diff --git a/Making_things_move/material/smalldot.jpg b/Motion_Capture_Movement/material/smalldot.jpg similarity index 100% rename from Making_things_move/material/smalldot.jpg rename to Motion_Capture_Movement/material/smalldot.jpg diff --git a/Tutorials.md b/Tutorials.md index f7f55592..fefe82a3 100644 --- a/Tutorials.md +++ b/Tutorials.md @@ -32,7 +32,7 @@ You can find the available tutorials in the sidebar. The tutorials are ordered i :titlesonly: true A_study_of_studies/index -Making_things_move/index +Motion_Capture_Movement/index MuscleRecruitment/index Muscle_modeling/index The_mechanical_elements/index diff --git a/core-tutorial-descriptions.txt b/core-tutorial-descriptions.txt index fc5a3f2d..6bd0d25a 100644 --- a/core-tutorial-descriptions.txt +++ b/core-tutorial-descriptions.txt @@ -3,7 +3,7 @@ : Explains the sequence of a typical study/simulation from initial conditions, kinematics to the inverse dynamic analysis. -{doc}`Making things move ` +{doc}`Motion Capture Movement ` : Overview of the different possibilities to apply a motion to a body model. From simple drivers to motion caputure data.