130 lines (91 with data), 4.1 kB
//************ Shoulder Rhythm **********************
// Based on the concepts from
// De Groot, J. H. The shoulder: a kinematic and dynamic analysis of motion and loading. (1998)
AnyFunInterpol Gear ={
//This allows for a non linear gearing of the Elevation measure,
//The gearing can be made so the Elevation is zero in the beginning and it will then ramp up to a gearing of one
//The idea is to keep the rhythm unchanged for high elevation but ensure the SC joints stays almost unchanged until
//elevation reach a certain magnitude
//Data = {{400, 150, 90, 50*0.5, 25*0.25 , 0, 25*0.25, 50*0.5, 90, 150, 400}}*pi/180;
T ??= {-400, -150, -90, -50, -25, 0, 25, 50, 90, 150, 400}*pi/180;
Data ??= {{400, 150, 90, 50, 25 , 0, 25, 50, 90, 150, 400}}*pi/180;
Type = Bspline;
};
AnyKinMeasureFunComb1 Elevation_Gear = {
AnyKinMeasure& SternoClavicularElevation = ..InterfaceFolder.ThoraxHumerus.Elevation;
Functions = {&.Gear};
};
AnyKinEqSimpleDriver ClaviculaProtractionDriver =
{
AnyKinMeasureLinComb ClaviculaProtractionRhythm =
{
AnyKinMeasure& ClaviculaProtraction = ...InterfaceFolder.SternoClavicularProtraction;
AnyKinMeasure& HumerusElevation = ..Elevation_Gear;
AnyKinMeasure& HumerusElevationPlane = ...InterfaceFolder.ThoraxHumerus.PlaneOfElevation;
OutDim = 1;
// These coefficients are tweaked compared to De Groot et al (1998) to achive a behaviour
// where the shoulder also works when the arm is lifted in negative elevation planes (not part
// of the paper), as well as a neutral shoulder position similar to models without the shoulder rhythm.
// Coef = {{1, 0.242, -0.12}};
// Const = -1*{(-4.983*pi/180)};
Coef = {{1, 0.14, -0.15}};
Const = -1*{(-23*pi/180)};
};
// Use a template to create the weight function, so
// the weight values can be overridden by the user.
Template_AnyFunConst Weights (NUMBER_OF_ELEMENTS=..nDim) = {};
// CType= repmat(nDim,Soft);
WeightFun ={&Weights.Fun};
#if BM_ARM_SHOULDER_RHYTHM == _RHYTHM_SOFT_
CType= repmat(nDim,Soft);
#endif
DriverPos = {0};
DriverVel = {0};
Reaction.Type = {Off};
};
AnyKinEqSimpleDriver ClaviculaElevationDriver =
{
AnyKinMeasureLinComb ClaviculaElevationRhythm =
{
AnyKinMeasure& ClaviculaElevation = ...InterfaceFolder.SternoClavicularElevation;
// AnyKinMeasure& HumerusElevation = ...InterfaceFolder.ThoraxHumerus.Elevation;
AnyKinMeasure& HumerusElevation = ..Elevation_Gear;
AnyKinMeasure& HumerusElevationPlane = ...InterfaceFolder.ThoraxHumerus.PlaneOfElevation;
OutDim = 1;
Coef = {{1, -0.123, 0.046}};
Const = -1*{(3.917*pi/180)};
};
// Use a template to create the weight function, so
// the weight values can be overridden by the user.
Template_AnyFunConst Weights (NUMBER_OF_ELEMENTS=..nDim) = {};
WeightFun ={&Weights.Fun};
#if BM_ARM_SHOULDER_RHYTHM == _RHYTHM_SOFT_
CType= repmat(nDim,Soft);
#endif
DriverPos = {0};
DriverVel = {0};
Reaction.Type = {Off};
};
#if BM_ARM_CLAVICULA_ROTATION_RHYTHM == OFF
AnyKinEqSimpleDriver ClaviculaAxialRotationDriver =
{
AnyKinMeasureLinComb ClaviculaAxialRotationRhythm =
{
AnyKinMeasure& ClaviculaAxialRotation = ...InterfaceFolder.SternoClavicularAxialRotation;
AnyKinMeasure& HumerusElevation = ...InterfaceFolder.GlenohumeralAbduction;
OutDim = 1;
Coef = {{1, -0.422}};
Const = -1*{-0.423}; // initial position -0.349 rad, constant found by iteration (data non available)
};
// Use a template to create the weight function, so
// the weight values can be overridden by the user.
Template_AnyFunConst Weights (NUMBER_OF_ELEMENTS=..nDim) = {};
WeightFun ={&Weights.Fun};
#if BM_ARM_SHOULDER_RHYTHM == _RHYTHM_SOFT_
CType= repmat(nDim,Soft);
#endif
DriverPos = {0};
DriverVel = {0};
Reaction.Type = {Off};
};
#endif