Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: New 2par calibration interface #39

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Body/AAUHuman/Arm/ArmData1.1/ArmModelMuscleParameters.any
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
#define _TENDON_LENGTH_DESIGNVAR(x) (x)
#define _FIBER_LENGTH_DESIGNVAR(x) DesignVar(x)
#endif
#if BM_CALIBRATION_TYPE == _CALIBRATION_TYPE_2PAR_
#if (BM_CALIBRATION_TYPE == _CALIBRATION_TYPE_2PAR_) | (BM_CALIBRATION_TYPE == _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_)
#define _TENDON_LENGTH_DESIGNVAR(x) (x)
#define _FIBER_LENGTH_DESIGNVAR(x) (x)
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
//
// Muscle Calibration related logic
//
#if BM_CALIBRATION_TYPE == _CALIBRATION_TYPE_2PAR_ & BM_TRUNK_CERVICAL_RHYTHM == OFF
#if (BM_CALIBRATION_TYPE == _CALIBRATION_TYPE_2PAR_) | (BM_CALIBRATION_TYPE == _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_) & BM_TRUNK_CERVICAL_RHYTHM == OFF

AnyInt bm_cervical_rhythm_notice1= notice(0, strformat("\n"+
"------------------------------------------------------------------------------------------------------\n"+
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
Class Template for providing the folder structure of the body model
*/
#class_template BodyModelFolderStructure() {
AnyFolder Trunk = {
AnyFolder Right = {};
AnyFolder Left = {};
};
AnyFolder Right = {
AnyFolder ShoulderArm = {};
AnyFolder Leg = {
AnyFolder Hip = {};
AnyFolder Knee = {};
AnyFolder Ankle = {};
AnyFolder SubTalar = {};
};
};
AnyFolder Left = {
AnyFolder ShoulderArm = {};
AnyFolder Leg = {
AnyFolder Hip = {};
AnyFolder Knee = {};
AnyFolder Ankle = {};
AnyFolder SubTalar = {};
};
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@

#define _CALIBRATION_TYPE_2PAR_ 2

#define _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_ 3

#define _CALIBRATION_TYPE_CUSTOM_ 0

#define CONST_MUSCLES_NONE 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,22 @@
"------------------------------------------------------------------------------------------------------------------------ "));
#endif


#ifdef BM_CALIBRATION_TYPE
#if BM_CALIBRATION_TYPE == _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_
#ifdef BM_LEG_MODEL
#if BM_LEG_MODEL == _LEG_MODEL_TLEM1_
AnyInt not_implemented_calibration_for_TLEM1 = warn(0, strformat("\n"+
"------------------------------------------------------------------------------------------------------\n"+
" The Experimental 2-parameter calibration routine (BM_CALIBRATION_TYPE == _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_ \n"+
" is not compatible with The Twente Lower Extremity Model v.1 (TLEM1). \n"+
" Please use the TLEM 2 (which is default or set: #define BM_LEG_MODEL _LEG_MODEL_TLEM2_) \n"+
"-------------------------------------------------------------------------------------------------------"));
#endif
#endif
#endif
#endif

#ifndef ANYBODY_PYTHON_SUPPRESS_NOTICE
#if ANYBODY_PYTHON_AVAILABLE == 0
AnyMessage PythonMissing =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/**
Class template for creating a model that can be used to calibrate the legs
*/
#class_template LegCalibrationModel(Side, BodyModelRef) {
AnyComponentDefinition CDef = {};

#var AnyObjectPtr HipPositions;
#var AnyObjectPtr KneePositions;
#var AnyObjectPtr AnklePositions;
#var AnyObjectPtr SubTalarPositions;

AnyFolder &Pelvis = BodyModelRef.Trunk.Segments.PelvisSeg;
AnyFolder &Sacrum = BodyModelRef.Trunk.Segments.SacrumSeg;
AnyFolder &Thorax = BodyModelRef.Trunk.Segments.ThoraxSeg;

AnySeg &L1 = BodyModelRef.Trunk.Segments.L1Seg;
AnySeg &L2 = BodyModelRef.Trunk.Segments.L2Seg;
AnySeg &L3 = BodyModelRef.Trunk.Segments.L3Seg;
AnySeg &L4 = BodyModelRef.Trunk.Segments.L4Seg;
AnySeg &L5 = BodyModelRef.Trunk.Segments.L5Seg;

AnyFolder &LumbarJoints = BodyModelRef.Trunk.Joints.Lumbar;

AnyFolder &LegSegments = BodyModelRef.Side.Leg.Seg;
AnyFolder &LegJoints = BodyModelRef.Side.Leg.Jnt;

AnyFolder &Muscles = BodyModelRef.Side.Leg.Mus;

// Constraints
AnyFixedRefFrame ground = {
AnyRefNode node = {
ARel = ..Pelvis.Axes0;
sRel = ..Pelvis.r0;
};
};

AnyKinEq ThoraxFix = {
AnyKinMeasure& PelvisThoraxExtension = BodyModelRef.Interface.Trunk.PelvisThoraxExtension;
AnyKinMeasure& PelvisThoraxLateralBending = BodyModelRef.Interface.Trunk.PelvisThoraxLateralBending;
AnyKinMeasure& PelvisThoraxRotation = BodyModelRef.Interface.Trunk.PelvisThoraxRotation;
};

AnyKinEq PelvisFix = {
AnyKinLinear Lin = {
AnyRefFrame &ground = ..ground.node;
AnyRefFrame &Pelvis = ..Pelvis;
};
AnyKinRotational Rot = {
Type = RotAxesAngles;
AnyRefFrame &ground = ..ground.node;
AnyRefFrame &Pelvis = ..Pelvis;
};
};

AnyKinEqInterPolDriver Hip = {
AnyKinRotational &Spherical = .BodyModelRef.Interface.Side.HipFlexion.HipMeasure;
Type = PiecewiseLinear;
T = linspace(0,1,SizesOf(Data)[1]);
Data = Obj2Num(.HipPositions)' * pi/180;
Reaction.Type = {Off, Off, Off};
AnyInt expect_nPos_to_match_nStep = warn(eqfun(NumElemOf(T), ..nStep), strformat("The number of calibration positions (Data) in the: " + NameOf(ObjGetParent(0)) + " driver does not match the number of positions (nStep) in the study."));

};

AnyKinEqInterPolDriver Knee = {
AnyKinMeasure& Hinge = .BodyModelRef.Interface.Side.KneeFlexion;
Type = PiecewiseLinear;
T = linspace(0,1,SizesOf(Data)[1]);
Data = {Obj2Num(.KneePositions)} * pi/180;
Reaction.Type = {Off};
AnyInt expect_nPos_to_match_nStep = warn(eqfun(NumElemOf(T), ..nStep), strformat("The number of calibration positions (Data) in the: " + NameOf(ObjGetParent(0)) + " driver does not match the number of positions (nStep) in the study."));

};

AnyKinEqInterPolDriver Ankle = {
AnyKinMeasure& Hinge = .BodyModelRef.Interface.Side.AnklePlantarFlexion;
Type = PiecewiseLinear;
T = linspace(0,1,SizesOf(Data)[1]);
Data = {Obj2Num(.AnklePositions)} * pi/180;
Reaction.Type = {Off};
AnyInt expect_nPos_to_match_nStep = warn(eqfun(NumElemOf(T), ..nStep), strformat("The number of calibration positions (Data) in the: " + NameOf(ObjGetParent(0)) + " driver does not match the number of positions (nStep) in the study."));

};

AnyKinEqInterPolDriver SubTalar = {
AnyKinMeasure& Hinge = .BodyModelRef.Interface.Side.SubTalarEversion;
Type = PiecewiseLinear;
T = linspace(0,1,SizesOf(Data)[1]);
Data = {Obj2Num(.SubTalarPositions)} * pi/180;
Reaction.Type = {Off};
AnyInt expect_nPos_to_match_nStep = warn(eqfun(NumElemOf(T), ..nStep), strformat("The number of calibration positions (Data) in the: " + NameOf(ObjGetParent(0)) + " driver does not match the number of positions (nStep) in the study."));

};
};


/**
Class template for creating calibrationstudies with same settings
*/
#class_template LegCalibrationStudy(
__CLASS__ = AnyBodyCalibrationStudy,
BodyModelRef,
Side,
) {
// Study settings
FiberAndTendonLengthAdjustment.CalibrateTendonAtMaxForceOnOff = Off;
Kinematics.SmallStepAssumptionOnOff = Off;
InitialConditions.SmallStepAssumptionOnOff = Off;
Kinematics.PosAnalysisOnlyOnOff = On;
InitialConditions.PosAnalysisOnlyOnOff = On;

LegCalibrationModel ModelRef(Side=Side, BodyModelRef=BodyModelRef) = {
HipPositions = .HipPositions;
KneePositions = .KneePositions;
AnklePositions = .AnklePositions;
SubTalarPositions = .SubTalarPositions;
};
};

12 changes: 12 additions & 0 deletions Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RValues.any
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
Folder containing different R values (ratios of muscle fiber length to optimal fiber
length) for different purposes.
*/
AnyFolder RValues = {
AnyFloat RMinNoMuscleForce = 0.5;
AnyFloat RMinDefault = 0.6;

AnyFloat RMaxDefault = 1.2;
AnyFloat RMaxActiveStretching = 1.3;
AnyFloat RMaxPassiveForceEqualToFMax = 1.5;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/**
Folder containing the range of motion for the joints in the body model. The folder
also contains Predefined Positions for each joint. Can be used by calibration
studies. Hip positions are {Flexion/Extension, Abduction/Adduction,
Internal/External Rotation} angles Knee positions are {Flexion/Extension} angles
Ankle positions are {Plantar/Dorsi flexion, Inversion/Eversion} angles
*/
BodyModelFolderStructure RangeOfMotion() = {
Right.Leg.Hip = {
// TODO: bke - TBC DO we want more levels for the degree of freedom?
// Hip.ExternalRotation = {AnyFloat Min, AnyFloat Max}; ??
AnyVar MaxExternalRotationAngle ??= 30;
AnyVar MaxInternalRotationAngle ??= -30;
AnyVar MaxAdductionAngle ??= -15;
AnyVar MaxAdductionInExtensionAngle ??= -10;
AnyVar MaxAbductionAngle ??= 40;
AnyVar MaxFlexionAngle ??= 120;
AnyVar MaxExtensionAngle ??= -20;
AnyVar MaxExtensionInAdductionAngle ??= -10;
AnyVar MaxFlexionInAbductionAngle ??= 90;
AnyVar MinFlexionInAdduction ??= 5;

// Hip positions
AnyFloat Neutral ??= { 0, 0, 0 };
AnyFloat InternallyRotated ??= { 0, 0, MaxInternalRotationAngle };
AnyFloat ExternallyRotated ??= { 0, 0, MaxExternalRotationAngle };
AnyFloat Adduction ??= { MinFlexionInAdduction, MaxAdductionAngle, 0};
AnyFloat Abduction ??= { 0, MaxAbductionAngle, 0};
AnyFloat Flexed ??= { MaxFlexionAngle, 0, 0};
AnyFloat FlexedAndAdducted ??= { MaxFlexionAngle, MaxAdductionAngle, 0};
AnyFloat FlexedAndAbducted ??= { MaxFlexionInAbductionAngle, MaxAbductionAngle, 0};
AnyFloat Extended ??= { MaxExtensionAngle, 0, 0};
AnyFloat ExtendedAndAdducted ??= { MaxExtensionInAdductionAngle, MaxAdductionInExtensionAngle, 0};
AnyFloat AbductedAndExternallyRotated ??= {0, MaxAbductionAngle, MaxExternalRotationAngle};
};

Right.Leg.Knee = {
AnyVar Neutral ??= 0;
AnyVar MaxFlexionAngle ??= 130;
AnyVar MaxExtensionAngle ??= -3;
};

Right.Leg.Ankle = {
AnyVar Neutral ??= 0;
AnyVar MaxPlantarFlexionAngle ??= 45;
AnyVar MaxDorsiFlexionAngle ??= -20;
AnyVar MaxInversionAngle ??= 15;
AnyVar MaxEversionAngle ??= -20;
};

// Left side is by default a mirror of the right side
Left.Leg.Hip = {
AnyVar MaxExternalRotationAngle ??= ...Right.Leg.Hip.MaxExternalRotationAngle;
AnyVar MaxInternalRotationAngle ??= ...Right.Leg.Hip.MaxInternalRotationAngle;
AnyVar MaxAdductionAngle ??= ...Right.Leg.Hip.MaxAdductionAngle;
AnyVar MaxAdductionInExtensionAngle ??= ...Right.Leg.Hip.MaxAdductionInExtensionAngle;
AnyVar MaxAbductionAngle ??= ...Right.Leg.Hip.MaxAbductionAngle;
AnyVar MaxFlexionAngle ??= ...Right.Leg.Hip.MaxFlexionAngle;
AnyVar MaxExtensionAngle ??= ...Right.Leg.Hip.MaxExtensionAngle;
AnyVar MaxExtensionInAdductionAngle ??= ...Right.Leg.Hip.MaxExtensionInAdductionAngle;
AnyVar MaxFlexionInAbductionAngle ??= ...Right.Leg.Hip.MaxFlexionInAbductionAngle;
AnyVar MinFlexionInAdduction ??= ...Right.Leg.Hip.MinFlexionInAdduction;

// Hip positions
AnyFloat Neutral ??= ...Right.Leg.Hip.Neutral;
AnyFloat InternallyRotated ??= ...Right.Leg.Hip.InternallyRotated;
AnyFloat ExternallyRotated ??= ...Right.Leg.Hip.ExternallyRotated;
AnyFloat Adduction ??= ...Right.Leg.Hip.Adduction;
AnyFloat Flexed ??= ...Right.Leg.Hip.Flexed;
AnyFloat FlexedAndAdducted ??= ...Right.Leg.Hip.FlexedAndAdducted;
AnyFloat FlexedAndAbducted ??= ...Right.Leg.Hip.FlexedAndAbducted;
AnyFloat Extended ??= ...Right.Leg.Hip.Extended;
AnyFloat ExtendedAndAdducted ??= ...Right.Leg.Hip.ExtendedAndAdducted;
AnyFloat AbductedAndExternallyRotated ??= ...Right.Leg.Hip.AbductedAndExternallyRotated;
};

Left.Leg.Knee = {
AnyVar Neutral ??= ...Right.Leg.Knee.Neutral;
AnyVar MaxFlexionAngle ??= ...Right.Leg.Knee.MaxFlexionAngle;
AnyVar MaxExtensionAngle ??= ...Right.Leg.Knee.MaxExtensionAngle;
};

Left.Leg.Ankle = {
AnyVar Neutral ??= ...Right.Leg.Ankle.Neutral;
AnyVar MaxPlantarFlexionAngle ??= ...Right.Leg.Ankle.MaxPlantarFlexionAngle;
AnyVar MaxDorsiFlexionAngle ??= ...Right.Leg.Ankle.MaxDorsiFlexionAngle;
AnyVar MaxInversionAngle ??= ...Right.Leg.Ankle.MaxInversionAngle;
AnyVar MaxEversionAngle ??= ...Right.Leg.Ankle.MaxEversionAngle;
};
};
39 changes: 33 additions & 6 deletions Body/AAUHuman/BodyModels/GenericBodyModel/CalibrationSequence.any
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@

//This file controls which calibrations to be made on the model
//This file controls which calibrations to be made on the model
#include "Calibration/CalibrationStudy.ClassTemplates.any"
#include "BodyModel.ClassTemplates.any"

AnyFolder Calibration={
AnyComponentDefinition obj = {};
#if BM_CALIBRATION_TYPE == _CALIBRATION_TYPE_2PAR_
AnyFloat RMin = DesignVar(0.5); ///< Muscle fiber length's ratio to the optimal fiber length at the lower extreme for the given range of motion.
AnyFloat RMax = DesignVar(1.0); ///< Muscle fiber length's ratio to the optimal fiber length at the upper extreme for the given range of motion.
AnyFloat RMin = DesignVar(0.5); ///< Muscle fiber length's ratio to the optimal fiber length at the lower extreme for the given range of motion.
AnyFloat RMax = DesignVar(1.0); ///< Muscle fiber length's ratio to the optimal fiber length at the upper extreme for the given range of motion.
#endif

#if BM_CALIBRATION_TYPE ==_EXPERIMENTAL_CALIBRATION_TYPE_2PAR_


#include "Calibration/RValues.any"
#include "Calibration/RangeOfMotionDefinition.any"


#endif

#if BM_LEG_RIGHT & BM_LEG_MODEL_IS_TLEM & (BM_LEG_MUSCLES_RIGHT == _MUSCLES_3E_HILL_)
Expand All @@ -18,6 +30,9 @@ AnyFolder Calibration={
};
#include "<BM_LEG_TLEM_PATH>/Calibration/CalibrationSequenceRight2Par.any"
#endif
#if (BM_CALIBRATION_TYPE == _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_) & (BM_LEG_MODEL != _LEG_MODEL_TLEM1_)
#include "<BM_LEG_TLEM_PATH>/Calibration/2ParRightCalStudies.any"
#endif
#if BM_CALIBRATION_TYPE == _CALIBRATION_TYPE_CUSTOM_
// Allow user to implement their own calibration
#endif
Expand All @@ -34,6 +49,9 @@ AnyFolder Calibration={
};
#include "<BM_LEG_TLEM_PATH>/Calibration/CalibrationSequenceLeft2Par.any"
#endif
#if (BM_CALIBRATION_TYPE == _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_) & (BM_LEG_MODEL != _LEG_MODEL_TLEM1_)
#include "<BM_LEG_TLEM_PATH>/Calibration/2ParLeftCalStudies.any"
#endif
#if BM_CALIBRATION_TYPE == _CALIBRATION_TYPE_CUSTOM_
// Allow user to implement their own calibration
#endif
Expand Down Expand Up @@ -65,6 +83,10 @@ AnyFolder Calibration={
// 2Par PEFactor will be set here
#include "../../Arm/Calibration/CalibrationSequenceRight2Par.any"
#endif
#if BM_CALIBRATION_TYPE == _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_
// 2Par PEFactor will be set here
#include "../../Arm/Calibration/CalibrationSequenceRight2Par.any"
#endif
#if BM_CALIBRATION_TYPE == _CALIBRATION_TYPE_CUSTOM_
// Allow user to implement their own calibration
#endif
Expand All @@ -78,6 +100,10 @@ AnyFolder Calibration={
// 2Par PEFactor will be set here
#include "../../Arm/Calibration/CalibrationSequenceLeft2Par.any"
#endif
#if BM_CALIBRATION_TYPE == _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_
// 2Par PEFactor will be set here
#include "../../Arm/Calibration/CalibrationSequenceLeft2Par.any"
#endif
#if BM_CALIBRATION_TYPE == _CALIBRATION_TYPE_CUSTOM_
// Allow user to implement their own calibration
#endif
Expand All @@ -91,6 +117,10 @@ AnyFolder Calibration={
// 2Par PEFactor will be set here
#include "../../Trunk/Calibration/MuscleCalibrationSequence2Par.any"
#endif
#if BM_CALIBRATION_TYPE == _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_
// 2Par PEFactor will be set here
#include "../../Trunk/Calibration/MuscleCalibrationSequence2Par.any"
#endif
#if BM_CALIBRATION_TYPE == _CALIBRATION_TYPE_CUSTOM_
// Allow user to implement their own calibration
#endif
Expand All @@ -104,10 +134,7 @@ AnyFolder Calibration={
#endif
#endif


AnyOperationSequence CalibrationSequence ={
AnyOperationDummy PlaceHolderOpr = {};
};


};
Loading
Loading