From 456c08bfed2c1b28a70a1e5fa16920d168b7c188 Mon Sep 17 00:00:00 2001 From: bke Date: Mon, 24 Mar 2025 12:40:14 +0100 Subject: [PATCH 01/29] add test of muscles included in cal studies --- Body/AAUHuman/Leg/Mus.any | 2 +- .../test_calibration_lowerbody.any | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Body/AAUHuman/Leg/Mus.any b/Body/AAUHuman/Leg/Mus.any index 51cc403db..a6b4fbca8 100644 --- a/Body/AAUHuman/Leg/Mus.any +++ b/Body/AAUHuman/Leg/Mus.any @@ -387,7 +387,7 @@ AnyMuscle &PsoasMajor_PML2T_TM = .TrunkMuscles.PsoasMajor.PML2T_TM;//< Psoas mus AnyMuscle &PsoasMajor_PML3I_TM = .TrunkMuscles.PsoasMajor.PML3I_TM;//< Psoas muscles are created by the Trunk model AnyMuscle &PsoasMajor_PML3T_TM = .TrunkMuscles.PsoasMajor.PML3T_TM;//< Psoas muscles are created by the Trunk model AnyMuscle &PsoasMajor_PML4I_TM = .TrunkMuscles.PsoasMajor.PML4I_TM;//< Psoas muscles are created by the Trunk model -AnyMuscle &PsoasMajor_PML4T_TM = .TrunkMuscles.PsoasMajor.PML4I_TM;//< Psoas muscles are created by the Trunk model +AnyMuscle &PsoasMajor_PML4T_TM = .TrunkMuscles.PsoasMajor.PML4T_TM;//< Psoas muscles are created by the Trunk model AnyMuscle &PsoasMajor_PML5_TM = .TrunkMuscles.PsoasMajor.PML5_TM;//< Psoas muscles are created by the Trunk model AnyMuscle &PsoasMajor_PML5T_TM = .TrunkMuscles.PsoasMajor.PML5T_TM;//< Psoas muscles are created by the Trunk model diff --git a/Tests/Calibration/test_calibration_lowerbody.any b/Tests/Calibration/test_calibration_lowerbody.any index be1ad89c6..eef404758 100644 --- a/Tests/Calibration/test_calibration_lowerbody.any +++ b/Tests/Calibration/test_calibration_lowerbody.any @@ -27,6 +27,7 @@ #define BM_SCALING _SCALING_NONE_ #define BM_LEG_TRUNK_INTERFACE _MORPH_TRUNK_TO_LEG_ #define BM_LEG_MUSCLES_RIGHT _MUSCLES_3E_HILL_ +#define BM_TRUNK_MUSCLES OFF #define BM_LEG_LEFT OFF #define BM_ARM_RIGHT OFF @@ -42,6 +43,24 @@ Main = AnyOperationSequence RunAnalysis = { AnyOperation& Calibration = Main.HumanModel.Calibration.CalibrationSequence; + + // Test to check that all muscles in the model are part of the calibration studies. + // for the leg we find the psoas muscles that belong to the trunk model + // the test is excluded for leg model and calibration combinations that do not make sense / are unimplemented + #if (BM_LEG_MODEL != _LEG_MODEL_LEG_ | BM_LEG_MODEL != _LEG_MODEL_TLEM1_) & BM_CALIBRATION_TYPE != 3 + AnyObjectPtrArray muscles_from_cal_studies = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.Calibration, "MuscleArr"))); + AnyObjectPtrArray muscles_leg = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Right.Leg.Mus, "*", "AnyMuscle"))); + AnyObjectPtrArray muscles_trunk = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Trunk.Muscles.Right, "*", "AnyMuscle"))); + AnyObjectPtrArray muscles_from_model = arrcat(muscles_leg, muscles_trunk); + + AnyInt test_all_mus_in_cal = expect( + eqfun( + NumElemOf(muscles_from_cal_studies), + NumElemOf(muscles_from_model) + ), + "The number of muscles in the calibration studies do not match the number of muscles in the model!" + ); + #endif #if (BM_CALIBRATION_TYPE == 3) & (BM_LEG_MODEL == _LEG_MODEL_TLEM2_) AnyOperation& HipFlexExtRoM = Main.HipFlexExtRoM.InverseDynamics; From dc3cfffa8394e06b659b6654ebd59bbff74b82e9 Mon Sep 17 00:00:00 2001 From: bke Date: Mon, 24 Mar 2025 13:46:04 +0100 Subject: [PATCH 02/29] add test of arm muscles in calibration studies --- Body/AAUHuman/Arm/Calibration/ElbowCal.any | 4 +- Body/AAUHuman/Arm/Calibration/WristCal.any | 113 ++++++++++++++++-- .../test_calibration_upperbody.any | 17 +++ 3 files changed, 121 insertions(+), 13 deletions(-) diff --git a/Body/AAUHuman/Arm/Calibration/ElbowCal.any b/Body/AAUHuman/Arm/Calibration/ElbowCal.any index d24a99f16..301b754ce 100644 --- a/Body/AAUHuman/Arm/Calibration/ElbowCal.any +++ b/Body/AAUHuman/Arm/Calibration/ElbowCal.any @@ -256,11 +256,11 @@ AnyFolder ElbowCal ={ AnyString MusPrefix = CompleteNameOf(&.SideHumanFolderRef.ShoulderArm.Muscles); - AnyObjectPtrArray biceps_brachii_caput_breveMuscles = ObjSearch(MusPrefix+".*.biceps_brachii_caput_breve*", "AnyMuscle"); + AnyObjectPtrArray biceps_brachii_caput_breveMuscles = ObjSearch(MusPrefix+".*.biceps_brachii_caput_br*", "AnyMuscle"); AnyFloat biceps_brachii_caput_breveRmin = repmat(NumElemOf(biceps_brachii_caput_breveMuscles), ..RMin); AnyFloat biceps_brachii_caput_breveRmax = repmat(NumElemOf(biceps_brachii_caput_breveMuscles), ..RMax); - AnyObjectPtrArray biceps_brachii_caput_longumMuscles = ObjSearch(MusPrefix+".*.biceps_brachii_caput_longum*", "AnyMuscle"); + AnyObjectPtrArray biceps_brachii_caput_longumMuscles = ObjSearch(MusPrefix+".*.biceps_brachii_caput_long*", "AnyMuscle"); AnyFloat biceps_brachii_caput_longumRmin = repmat(NumElemOf(biceps_brachii_caput_longumMuscles), ..RMin); AnyFloat biceps_brachii_caput_longumRmax = repmat(NumElemOf(biceps_brachii_caput_longumMuscles), ..RMax); diff --git a/Body/AAUHuman/Arm/Calibration/WristCal.any b/Body/AAUHuman/Arm/Calibration/WristCal.any index cf870cfa6..cdb286444 100644 --- a/Body/AAUHuman/Arm/Calibration/WristCal.any +++ b/Body/AAUHuman/Arm/Calibration/WristCal.any @@ -243,12 +243,64 @@ AnyFolder WristCal ={ #endif AnyString MusPrefix = CompleteNameOf(&.SideHumanFolderRef.ShoulderArm.Muscles); + + AnyObjectPtrArray AbductorPollicisMuscles = ObjSearch(MusPrefix+".AbductorPollicis.*", "AnyMuscle"); + AnyFloat AbductorPollicisRmin = repmat(NumElemOf(AbductorPollicisMuscles), ..RMin); + AnyFloat AbductorPollicisRmax = repmat(NumElemOf(AbductorPollicisMuscles), ..RMax); + + AnyObjectPtrArray ExtensorCarpiRadialisMuscles = ObjSearch(MusPrefix+".ExtensorCarpiRadialis.*", "AnyMuscle"); + AnyFloat ExtensorCarpiRadialisRmin = repmat(NumElemOf(ExtensorCarpiRadialisMuscles), ..RMin); + AnyFloat ExtensorCarpiRadialisRmax = repmat(NumElemOf(ExtensorCarpiRadialisMuscles), ..RMax); + + AnyObjectPtrArray ExtensorCarpiUlnarisMuscles = ObjSearch(MusPrefix+".ExtensorCarpiUlnaris.*", "AnyMuscle"); + AnyFloat ExtensorCarpiUlnarisRmin = repmat(NumElemOf(ExtensorCarpiUlnarisMuscles), ..RMin); + AnyFloat ExtensorCarpiUlnarisRmax = repmat(NumElemOf(ExtensorCarpiUlnarisMuscles), ..RMax); + + AnyObjectPtrArray ExtensorDigitiMinimiMuscles = ObjSearch(MusPrefix+".ExtensorDigitiMinimi.*", "AnyMuscle"); + AnyFloat ExtensorDigitiMinimiRmin = repmat(NumElemOf(ExtensorDigitiMinimiMuscles), ..RMin); + AnyFloat ExtensorDigitiMinimiRmax = repmat(NumElemOf(ExtensorDigitiMinimiMuscles), ..RMax); + + AnyObjectPtrArray ExtensorDigitorumMuscles = ObjSearch(MusPrefix+".ExtensorDigitorum.*", "AnyMuscle"); + AnyFloat ExtensorDigitorumRmin = repmat(NumElemOf(ExtensorDigitorumMuscles), ..RMin); + AnyFloat ExtensorDigitorumRmax = repmat(NumElemOf(ExtensorDigitorumMuscles), ..RMax); + + AnyObjectPtrArray ExtensorIndicisMuscles = ObjSearch(MusPrefix+".ExtensorIndicis.*", "AnyMuscle"); + AnyFloat ExtensorIndicisRmin = repmat(NumElemOf(ExtensorIndicisMuscles), ..RMin); + AnyFloat ExtensorIndicisRmax = repmat(NumElemOf(ExtensorIndicisMuscles), ..RMax); + + AnyObjectPtrArray ExtensorPollicisMuscles = ObjSearch(MusPrefix+".ExtensorPollicis.*", "AnyMuscle"); + AnyFloat ExtensorPollicisRmin = repmat(NumElemOf(ExtensorPollicisMuscles), ..RMin); + AnyFloat ExtensorPollicisRmax = repmat(NumElemOf(ExtensorPollicisMuscles), ..RMax); + + AnyObjectPtrArray FlexorCarpiRadialisMuscles = ObjSearch(MusPrefix+".FlexorCarpiRadialis.*", "AnyMuscle"); + AnyFloat FlexorCarpiRadialisRmin = repmat(NumElemOf(FlexorCarpiRadialisMuscles), ..RMin); + AnyFloat FlexorCarpiRadialisRmax = repmat(NumElemOf(FlexorCarpiRadialisMuscles), ..RMax); + + AnyObjectPtrArray FlexorCarpiUlnarisMuscles = ObjSearch(MusPrefix+".FlexorCarpiUlnaris.*", "AnyMuscle"); + AnyFloat FlexorCarpiUlnarisRmin = repmat(NumElemOf(FlexorCarpiUlnarisMuscles), ..RMin); + AnyFloat FlexorCarpiUlnarisRmax = repmat(NumElemOf(FlexorCarpiUlnarisMuscles), ..RMax); + + AnyObjectPtrArray FlexorDigitorumProfundusMuscles = ObjSearch(MusPrefix+".FlexorDigitorumProfundus.*", "AnyMuscle"); + AnyFloat FlexorDigitorumProfundusRmin = repmat(NumElemOf(FlexorDigitorumProfundusMuscles), ..RMin); + AnyFloat FlexorDigitorumProfundusRmax = repmat(NumElemOf(FlexorDigitorumProfundusMuscles), ..RMax); + + AnyObjectPtrArray FlexorDigitorumSuperficialisMuscles = ObjSearch(MusPrefix+".FlexorDigitorumSuperficialis.*", "AnyMuscle"); + AnyFloat FlexorDigitorumSuperficialisRmin = repmat(NumElemOf(FlexorDigitorumSuperficialisMuscles), ..RMin); + AnyFloat FlexorDigitorumSuperficialisRmax = repmat(NumElemOf(FlexorDigitorumSuperficialisMuscles), ..RMax); + + AnyObjectPtrArray FlexorPollicisLongusMuscles = ObjSearch(MusPrefix+".FlexorPollicisLongus.*", "AnyMuscle"); + AnyFloat FlexorPollicisLongusRmin = repmat(NumElemOf(FlexorPollicisLongusMuscles), ..RMin); + AnyFloat FlexorPollicisLongusRmax = repmat(NumElemOf(FlexorPollicisLongusMuscles), ..RMax); + + AnyObjectPtrArray PalmarisLongusMuscles = ObjSearch(MusPrefix+".PalmarisLongus.*", "AnyMuscle"); + AnyFloat PalmarisLongusRmin = repmat(NumElemOf(PalmarisLongusMuscles), ..RMin); + AnyFloat PalmarisLongusRmax = repmat(NumElemOf(PalmarisLongusMuscles), ..RMax); - AnyObjectPtrArray biceps_brachii_caput_breveMuscles = ObjSearch(MusPrefix+".*.biceps_brachii_caput_breve*", "AnyMuscle"); + AnyObjectPtrArray biceps_brachii_caput_breveMuscles = ObjSearch(MusPrefix+".*.biceps_brachii_caput_br*", "AnyMuscle"); AnyFloat biceps_brachii_caput_breveRmin = repmat(NumElemOf(biceps_brachii_caput_breveMuscles), ..RMin); AnyFloat biceps_brachii_caput_breveRmax = repmat(NumElemOf(biceps_brachii_caput_breveMuscles), ..RMax); - AnyObjectPtrArray biceps_brachii_caput_longumMuscles = ObjSearch(MusPrefix+".*.biceps_brachii_caput_longum*", "AnyMuscle"); + AnyObjectPtrArray biceps_brachii_caput_longumMuscles = ObjSearch(MusPrefix+".*.biceps_brachii_caput_long*", "AnyMuscle"); AnyFloat biceps_brachii_caput_longumRmin = repmat(NumElemOf(biceps_brachii_caput_longumMuscles), ..RMin); AnyFloat biceps_brachii_caput_longumRmax = repmat(NumElemOf(biceps_brachii_caput_longumMuscles), ..RMax); @@ -299,43 +351,82 @@ AnyBodyCalibrationStudy ArmCalibrationStudyWrist = { Kinematics.PosAnalysisOnlyOnOff = On; InitialConditions.PosAnalysisOnlyOnOff = On; - MuscleArr = arrcat(arrcat( + MuscleArr = arrcat(arrcat(arrcat( + ref.AbductorPollicisMuscles, + ref.ExtensorCarpiRadialisMuscles, + ref.ExtensorCarpiUlnarisMuscles, + ref.ExtensorDigitiMinimiMuscles, + ref.ExtensorDigitorumMuscles, + ref.ExtensorIndicisMuscles, + ref.ExtensorPollicisMuscles, + ref.FlexorCarpiRadialisMuscles, + ref.FlexorCarpiUlnarisMuscles), + ref.FlexorDigitorumProfundusMuscles, + ref.FlexorDigitorumSuperficialisMuscles, + ref.FlexorPollicisLongusMuscles, + ref.PalmarisLongusMuscles, ref.biceps_brachii_caput_breveMuscles, ref.biceps_brachii_caput_longumMuscles, ref.BrachialisMuscles, ref.TricepsMuscles, - ref.Brach_radMuscles, + ref.Brach_radMuscles), ref.AnconeusMuscles, ref.Pronator_teres_caput_humeralMuscles, ref.Pronator_teres_caput_ulnareMuscles, ref.Supinator_humerusMuscles, - ref.Supinator_ulnaMuscles), + ref.Supinator_ulnaMuscles, ref.Pron_quadrMuscles ); - RminMuscleFiber = arrcat(arrcat( + RminMuscleFiber = arrcat(arrcat(arrcat( + ref.AbductorPollicisRmin, + ref.ExtensorCarpiRadialisRmin, + ref.ExtensorCarpiUlnarisRmin, + ref.ExtensorDigitiMinimiRmin, + ref.ExtensorDigitorumRmin, + ref.ExtensorIndicisRmin, + ref.ExtensorPollicisRmin, + ref.FlexorCarpiRadialisRmin, + ref.FlexorCarpiUlnarisRmin), + ref.FlexorDigitorumProfundusRmin, + ref.FlexorDigitorumSuperficialisRmin, + ref.FlexorPollicisLongusRmin, + ref.PalmarisLongusRmin, ref.biceps_brachii_caput_breveRmin, ref.biceps_brachii_caput_longumRmin, ref.BrachialisRmin, ref.TricepsRmin, - ref.Brach_radRmin, + ref.Brach_radRmin), ref.AnconeusRmin, ref.Pronator_teres_caput_humeralRmin, ref.Pronator_teres_caput_ulnareRmin, ref.Supinator_humerusRmin, - ref.Supinator_ulnaRmin), + ref.Supinator_ulnaRmin, ref.Pron_quadrRmin ); - RmaxMuscleFiber = arrcat(arrcat( + RmaxMuscleFiber = arrcat(arrcat(arrcat( + ref.AbductorPollicisRmax, + ref.ExtensorCarpiRadialisRmax, + ref.ExtensorCarpiUlnarisRmax, + ref.ExtensorDigitiMinimiRmax, + ref.ExtensorDigitorumRmax, + ref.ExtensorIndicisRmax, + ref.ExtensorPollicisRmax, + ref.FlexorCarpiRadialisRmax, + ref.FlexorCarpiUlnarisRmax), + ref.FlexorDigitorumProfundusRmax, + ref.FlexorDigitorumSuperficialisRmax, + ref.FlexorPollicisLongusRmax, + ref.PalmarisLongusRmax, ref.biceps_brachii_caput_breveRmax, ref.biceps_brachii_caput_longumRmax, ref.BrachialisRmax, ref.TricepsRmax, - ref.Brach_radRmax, + ref.Brach_radRmax), ref.AnconeusRmax, ref.Pronator_teres_caput_humeralRmax, ref.Pronator_teres_caput_ulnareRmax, ref.Supinator_humerusRmax, - ref.Supinator_ulnaRmax), + ref.Supinator_ulnaRmax, ref.Pron_quadrRmax ); diff --git a/Tests/Calibration/test_calibration_upperbody.any b/Tests/Calibration/test_calibration_upperbody.any index c831202fe..0003a4d59 100644 --- a/Tests/Calibration/test_calibration_upperbody.any +++ b/Tests/Calibration/test_calibration_upperbody.any @@ -36,6 +36,23 @@ Main = #include "/HumanModel.any" AnyOperation& RunTest = Main.HumanModel.Calibration.CalibrationSequence; + + // Test to check that all muscles in the model are part of the calibration studies. + // the test is excluded for the calibration combinations that do not make sense / are unimplemented + #if BM_CALIBRATION_TYPE != 3 + AnyObjectPtrArray muscles_from_cal_studies = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.Calibration, "MuscleArr"))); + AnyObjectPtrArray muscles_right = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Right.ShoulderArm.Muscles, "*", "AnyMuscle"))); + AnyObjectPtrArray muscles_left = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Left.ShoulderArm.Muscles, "*", "AnyMuscle"))); + AnyObjectPtrArray muscles_from_model = arrcat(muscles_right, muscles_left); + + AnyInt test_all_mus_in_cal = expect( + eqfun( + NumElemOf(muscles_from_cal_studies), + NumElemOf(muscles_from_model) + ), + "The number of muscles in the calibration studies do not match the number of muscles in the model!" + ); + #endif }; From 1c93ee702aa94c098bc0d18d03b68164b32a24a2 Mon Sep 17 00:00:00 2001 From: bke Date: Mon, 24 Mar 2025 14:23:36 +0100 Subject: [PATCH 03/29] add test of muscles in cal studies for trunk --- .../Calibration/MuscleCalibrationSequence.any | 8 ++++++++ Tests/Calibration/test_calibration_trunk.any | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/Body/AAUHuman/Trunk/Calibration/MuscleCalibrationSequence.any b/Body/AAUHuman/Trunk/Calibration/MuscleCalibrationSequence.any index 9fa4c20e3..271fe3900 100644 --- a/Body/AAUHuman/Trunk/Calibration/MuscleCalibrationSequence.any +++ b/Body/AAUHuman/Trunk/Calibration/MuscleCalibrationSequence.any @@ -80,6 +80,14 @@ AnyFolder ThoraxMuscleCalibration = { Kinematics.SmallStepAssumptionOnOff = Off; Kinematics.PosAnalysisOnlyOnOff = On; InitialConditions.PosAnalysisOnlyOnOff = On; + + /// Array of muscles to calibrate + /// The Pelvic floor muscles are excluded as they cross the Pelvis-Sacrum joint which has no movement. + /// This gives them zero range of motion and thereby no fiberlength [Lf0] when calibrated. + MuscleArr = set_difference( + ObjSearchRecursive(&...BodyModel.Trunk.Muscles, "*", "AnyMuscle", 3), + ObjSearch(&...BodyModel.Trunk.Muscles, "*.PelvicFloor.*") + ); }; }; diff --git a/Tests/Calibration/test_calibration_trunk.any b/Tests/Calibration/test_calibration_trunk.any index e8b9e2a2d..51e697578 100644 --- a/Tests/Calibration/test_calibration_trunk.any +++ b/Tests/Calibration/test_calibration_trunk.any @@ -50,6 +50,25 @@ Main = #include "/HumanModel.any" AnyOperation& RunTest = Main.HumanModel.Calibration.CalibrationSequence; + + // Test to check that all muscles in the model are part of the calibration studies. + // the test is excluded for the calibration combinations that do not make sense / are unimplemented + // The pelvic floor muscles are excluded as they are not 3E muscles! + #if BM_CALIBRATION_TYPE != 3 + AnyObjectPtrArray muscles_from_cal_studies = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.Calibration, "MuscleArr"))); + AnyObjectPtrArray muscles_from_model = set_difference( + ObjSearchRecursive(&Main.HumanModel.BodyModel.Trunk.Muscles, "*", "AnyMuscle", 3), + ObjSearch(&Main.HumanModel.BodyModel.Trunk.Muscles, "*.PelvicFloor.*") + ); + + AnyInt test_all_mus_in_cal = expect( + eqfun( + NumElemOf(muscles_from_cal_studies), + NumElemOf(muscles_from_model) + ), + "The number of muscles in the calibration studies do not match the number of muscles in the model!" + ); + #endif }; From 3cdb65f056cd816ff5f23ed0e78ba9324b7e1697 Mon Sep 17 00:00:00 2001 From: bke Date: Wed, 26 Mar 2025 14:03:14 +0100 Subject: [PATCH 04/29] unique names for operation sequence members --- .../LegTLEM/Calibration/2ParLeftCalStudies.any | 14 +++++++------- .../LegTLEM/Calibration/2ParRightCalStudies.any | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Body/AAUHuman/LegTLEM/Calibration/2ParLeftCalStudies.any b/Body/AAUHuman/LegTLEM/Calibration/2ParLeftCalStudies.any index 849caf1c6..efcbd26fc 100644 --- a/Body/AAUHuman/LegTLEM/Calibration/2ParLeftCalStudies.any +++ b/Body/AAUHuman/LegTLEM/Calibration/2ParLeftCalStudies.any @@ -186,11 +186,11 @@ LegCalibrationStudy LegCalibration7Left( }; CalibrationSequence = { - AnyOperation &Cal1Left = .LegCalibration1Left.FiberAndTendonLengthAdjustment; - AnyOperation &Cal2Left = .LegCalibration2Left.FiberAndTendonLengthAdjustment; - AnyOperation &Cal3Left = .LegCalibration3Left.FiberAndTendonLengthAdjustment; - AnyOperation &Cal4Left = .LegCalibration4Left.FiberAndTendonLengthAdjustment; - AnyOperation &Cal5Left = .LegCalibration5Left.FiberAndTendonLengthAdjustment; - AnyOperation &Cal6Left = .LegCalibration6Left.FiberAndTendonLengthAdjustment; - AnyOperation &Cal7Left = .LegCalibration7Left.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal1Left = .LegCalibration1Left.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal2Left = .LegCalibration2Left.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal3Left = .LegCalibration3Left.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal4Left = .LegCalibration4Left.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal5Left = .LegCalibration5Left.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal6Left = .LegCalibration6Left.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal7Left = .LegCalibration7Left.FiberAndTendonLengthAdjustment; }; \ No newline at end of file diff --git a/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any b/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any index 9c4d2fcd3..605235ca2 100644 --- a/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any +++ b/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any @@ -267,11 +267,11 @@ LegCalibrationStudy LegCalibration7Right( }; CalibrationSequence = { - AnyOperation &Cal1Right = .LegCalibration1Right.FiberAndTendonLengthAdjustment; - AnyOperation &Cal2Right = .LegCalibration2Right.FiberAndTendonLengthAdjustment; - AnyOperation &Cal3Right = .LegCalibration3Right.FiberAndTendonLengthAdjustment; - AnyOperation &Cal4Right = .LegCalibration4Right.FiberAndTendonLengthAdjustment; - AnyOperation &Cal5Right = .LegCalibration5Right.FiberAndTendonLengthAdjustment; - AnyOperation &Cal6Right = .LegCalibration6Right.FiberAndTendonLengthAdjustment; - AnyOperation &Cal7Right = .LegCalibration7Right.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal1Right = .LegCalibration1Right.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal2Right = .LegCalibration2Right.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal3Right = .LegCalibration3Right.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal4Right = .LegCalibration4Right.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal5Right = .LegCalibration5Right.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal6Right = .LegCalibration6Right.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal7Right = .LegCalibration7Right.FiberAndTendonLengthAdjustment; }; \ No newline at end of file From f476ab63c1b89321765b30daa95f5677e77c0f77 Mon Sep 17 00:00:00 2001 From: bke Date: Wed, 26 Mar 2025 14:03:41 +0100 Subject: [PATCH 05/29] extend range of motion data --- Body/AAUHuman/Arm/rangeOfMotion.any | 18 +++++++++++ .../Calibration/RangeOfMotionDefinition.any | 32 +++++++++++++++++++ Body/AAUHuman/Trunk/rangeOfMotion.any | 1 + 3 files changed, 51 insertions(+) diff --git a/Body/AAUHuman/Arm/rangeOfMotion.any b/Body/AAUHuman/Arm/rangeOfMotion.any index a912443ab..749d255df 100644 --- a/Body/AAUHuman/Arm/rangeOfMotion.any +++ b/Body/AAUHuman/Arm/rangeOfMotion.any @@ -12,6 +12,22 @@ AnyFolder RangeOfMotion = { AnyVar MaxScapulaClaviculaDepressionAngle = -5; AnyVar MaxScapulaClaviculaProtractionAngle = 15; AnyVar MaxScapulaClaviculaRetractionAngle = -36; + + // Shoulder positions + AnyFloat Neutral = {0,0,0}; + AnyFloat Flexed = {MaxGlenohumeralFlexionAngle, 0, 0}; + AnyFloat Extended = {MaxGlenohumeralExtensionAngle, 0, 0}; + AnyFloat Abducted = {0, MaxGlenohumeralAbductionAngle, 0}; + AnyFloat Adducted = {0, MaxGlenohumeralAdductionAngle, 0}; + AnyFloat ExternallyRotated = {0, 0, MaxGlenohumeralExternalRotationAngle}; + AnyFloat InternallyRotated = {0, 0, MaxGlenohumeralInternalRotationAngle}; + AnyFloat FlexedAndExternallyRotated = {MaxGlenohumeralFlexionAngle, 0, MaxGlenohumeralExternalRotationAngle}; + AnyFloat FlexedAndInternallyRotated = {MaxGlenohumeralFlexionAngle, 0, MaxGlenohumeralInternalRotationAngle}; + AnyFloat ExtendedAndExternallyRotated = {MaxGlenohumeralExtensionAngle, 0, MaxGlenohumeralExternalRotationAngle}; + AnyFloat ExtendedAndInternallyRotated = {MaxGlenohumeralExtensionAngle, 0, MaxGlenohumeralInternalRotationAngle}; + AnyFloat FlexedAndAdducted = {MaxGlenohumeralFlexionAngle, MaxGlenohumeralAdductionAngle, 0}; + AnyFloat FlexedAndAbducted = {MaxGlenohumeralFlexionAngle, MaxGlenohumeralAbductionAngle, 0}; + }; AnyFolder Elbow = { @@ -19,6 +35,7 @@ AnyFolder RangeOfMotion = { AnyVar MaxExtensionAngle = 0; AnyVar MaxPronationAngle = 90; AnyVar MaxSupinationAngle = -90; + AnyVar Neutral = 0; }; AnyFolder Wrist = { @@ -26,5 +43,6 @@ AnyFolder RangeOfMotion = { AnyVar MaxExtensionAngle = -70; AnyVar MaxAbductionAngle = 20; AnyVar MaxAdductionAngle = -35; + AnyVar Neutral = 0; }; }; \ No newline at end of file diff --git a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any index 67820ef67..67e7c32fe 100644 --- a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any +++ b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any @@ -34,6 +34,21 @@ BodyModelFolderStructure RangeOfMotion() = { AnyVar MaxScapulaClaviculaDepressionAngle ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.MaxScapulaClaviculaDepressionAngle; AnyVar MaxScapulaClaviculaProtractionAngle ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.MaxScapulaClaviculaProtractionAngle; AnyVar MaxScapulaClaviculaRetractionAngle ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.MaxScapulaClaviculaRetractionAngle; + + // Shoulder positions + AnyFloat Neutral ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.Neutral; + AnyFloat Flexed ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.Flexed; + AnyFloat Extended ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.Extended; + AnyFloat Abducted ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.Abducted; + AnyFloat Adducted ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.Adducted; + AnyFloat ExternallyRotated ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.ExternallyRotated; + AnyFloat InternallyRotated ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.InternallyRotated; + AnyFloat FlexedAndExternallyRotated ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.FlexedAndExternallyRotated; + AnyFloat FlexedAndInternallyRotated ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.FlexedAndInternallyRotated; + AnyFloat ExtendedAndExternallyRotated ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.ExtendedAndExternallyRotated; + AnyFloat ExtendedAndInternallyRotated ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.ExtendedAndInternallyRotated; + AnyFloat FlexedAndAdducted ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.FlexedAndAdducted; + AnyFloat FlexedAndAbducted ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.FlexedAndAbducted; }; Right.ShoulderArm.Elbow = { @@ -41,6 +56,7 @@ BodyModelFolderStructure RangeOfMotion() = { AnyVar MaxExtensionAngle ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Elbow.MaxExtensionAngle; AnyVar MaxPronationAngle ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Elbow.MaxPronationAngle; AnyVar MaxSupinationAngle ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Elbow.MaxSupinationAngle; + AnyVar Neutral ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Elbow.Neutral; }; Right.ShoulderArm.Wrist = { @@ -48,6 +64,7 @@ BodyModelFolderStructure RangeOfMotion() = { AnyVar MaxExtensionAngle ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Wrist.MaxExtensionAngle; AnyVar MaxAbductionAngle ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Wrist.MaxAbductionAngle; AnyVar MaxAdductionAngle ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Wrist.MaxAdductionAngle; + AnyVar Neutral ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Wrist.Neutral; }; #endif @@ -105,6 +122,21 @@ BodyModelFolderStructure RangeOfMotion() = { AnyVar MaxScapulaClaviculaDepressionAngle ??= ...Right.ShoulderArm.Shoulder.MaxScapulaClaviculaDepressionAngle; AnyVar MaxScapulaClaviculaProtractionAngle ??= ...Right.ShoulderArm.Shoulder.MaxScapulaClaviculaProtractionAngle; AnyVar MaxScapulaClaviculaRetractionAngle ??= ...Right.ShoulderArm.Shoulder.MaxScapulaClaviculaRetractionAngle; + + // Shoulder positions + AnyFloat Neutral ??= ...Right.ShoulderArm.Shoulder.Neutral; + AnyFloat Flexed ??= ...Right.ShoulderArm.Shoulder.Flexed; + AnyFloat Extended ??= ...Right.ShoulderArm.Shoulder.Extended; + AnyFloat Abducted ??= ...Right.ShoulderArm.Shoulder.Abducted; + AnyFloat Adducted ??= ...Right.ShoulderArm.Shoulder.Adducted; + AnyFloat ExternallyRotated ??= ...Right.ShoulderArm.Shoulder.ExternallyRotated; + AnyFloat InternallyRotated ??= ...Right.ShoulderArm.Shoulder.InternallyRotated; + AnyFloat FlexedAndExternallyRotated ??= ...Right.ShoulderArm.Shoulder.FlexedAndExternallyRotated; + AnyFloat FlexedAndInternallyRotated ??= ...Right.ShoulderArm.Shoulder.FlexedAndInternallyRotated; + AnyFloat ExtendedAndExternallyRotated ??= ...Right.ShoulderArm.Shoulder.ExtendedAndExternallyRotated; + AnyFloat ExtendedAndInternallyRotated ??= ...Right.ShoulderArm.Shoulder.ExtendedAndInternallyRotated; + AnyFloat FlexedAndAdducted ??= ...Right.ShoulderArm.Shoulder.FlexedAndAdducted; + AnyFloat FlexedAndAbducted ??= ...Right.ShoulderArm.Shoulder.FlexedAndAbducted; }; Left.ShoulderArm.Elbow = { diff --git a/Body/AAUHuman/Trunk/rangeOfMotion.any b/Body/AAUHuman/Trunk/rangeOfMotion.any index 3c69ebda4..da17b9500 100644 --- a/Body/AAUHuman/Trunk/rangeOfMotion.any +++ b/Body/AAUHuman/Trunk/rangeOfMotion.any @@ -17,6 +17,7 @@ AnyFolder RangeOfMotion = { AnyVar MaxPelvisSacrumExtensionAngle = -5; AnyVar MaxPelvisSacrumLateralBendingAngle = 5; AnyVar MinPelvisSacrumLateralBendingAngle = -5; + AnyVar Neutral = 0; // AnyFolder Right = {}; // AnyFolder Left = {}; From a49de4804a2628f7814dfd7e09d642f5151e7deb Mon Sep 17 00:00:00 2001 From: bke Date: Wed, 26 Mar 2025 14:50:23 +0100 Subject: [PATCH 06/29] simplify trunk fixing --- .../CalibrationStudy.ClassTemplates.any | 26 +++++++------------ 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any index 920ef34b0..0080ef272 100644 --- a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any +++ b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any @@ -9,28 +9,17 @@ #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 &TrunkSegments = BodyModelRef.Trunk.Segments; + AnyFolder &TrunkJoints = BodyModelRef.Trunk.Joints; 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; + ARel = ..TrunkSegments.PelvisSeg.Axes0; + sRel = ..TrunkSegments.PelvisSeg.r0; }; }; @@ -38,17 +27,20 @@ AnyKinMeasure& PelvisThoraxExtension = BodyModelRef.Interface.Trunk.PelvisThoraxExtension; AnyKinMeasure& PelvisThoraxLateralBending = BodyModelRef.Interface.Trunk.PelvisThoraxLateralBending; AnyKinMeasure& PelvisThoraxRotation = BodyModelRef.Interface.Trunk.PelvisThoraxRotation; + AnyKinMeasure& SkullThoraxFlexion = BodyModelRef.Interface.Trunk.SkullThoraxFlexion; + AnyKinMeasure& SkullThoraxRotation = BodyModelRef.Interface.Trunk.SkullThoraxRotation; + AnyKinMeasure& SkullThoraxLateralBending = BodyModelRef.Interface.Trunk.SkullThoraxLateralBending; }; AnyKinEq PelvisFix = { AnyKinLinear Lin = { AnyRefFrame &ground = ..ground.node; - AnyRefFrame &Pelvis = ..Pelvis; + AnyRefFrame &Pelvis = ..TrunkSegments.PelvisSeg; }; AnyKinRotational Rot = { Type = RotAxesAngles; AnyRefFrame &ground = ..ground.node; - AnyRefFrame &Pelvis = ..Pelvis; + AnyRefFrame &Pelvis = ..TrunkSegments.PelvisSeg; }; }; From eb8fa9d522b0f18ef8bcf87dbcfcd59418a1a573 Mon Sep 17 00:00:00 2001 From: bke Date: Wed, 26 Mar 2025 14:50:43 +0100 Subject: [PATCH 07/29] add arm calibration studies --- .../Arm/Calibration/2ParLeftCalStudies.any | 290 ++++++++++++++ .../Arm/Calibration/2ParRightCalStudies.any | 353 ++++++++++++++++++ .../Arm/Calibration/DetailedHandDrivers.any | 103 +++++ .../CalibrationStudy.ClassTemplates.any | 143 ++++++- .../GenericBodyModel/CalibrationSequence.any | 4 +- 5 files changed, 890 insertions(+), 3 deletions(-) create mode 100644 Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any create mode 100644 Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any create mode 100644 Body/AAUHuman/Arm/Calibration/DetailedHandDrivers.any diff --git a/Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any b/Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any new file mode 100644 index 000000000..654ac105e --- /dev/null +++ b/Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any @@ -0,0 +1,290 @@ +ArmCalibrationStudy ArmCalibration1Left( + BodyModelRef = Main.HumanModel.BodyModel, +Side = Left, +) = { + nStep = .ArmCalibration1Right.nStep; + + MuscleArr = ObjSearch( + &..BodyModel.Left.ShoulderArm.Muscles, + { + "DeltoideusAnterior.*", + "DeltoideusLateral.*", + "DeltoideusPosterior.*", + "Infraspinatus.*", + "LatissimusDorsi.*", + "LevatorScapulae.*", + "PectoralisMajorClavicular.*", + "PectoralisMajorThroacic.*", + "PectoralisMinor.*", + "SerratusAnterior.*", + "Subscapularis.*", + "Supraspinatus.*", + }, + "AnyMuscle" + ); + + RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); + RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); + + AnyObjectPtrArray ShoulderPositions = .ArmCalibration1Right.ShoulderPositions; + AnyObjectPtrArray ElbowFlexionPositions = .ArmCalibration1Right.ElbowFlexionPositions; + AnyObjectPtrArray ElbowPronationPositions = .ArmCalibration1Right.ElbowPronationPositions; + AnyObjectPtrArray WristFlexionPositions = .ArmCalibration1Right.WristFlexionPositions; + AnyObjectPtrArray WristAbductionPositions = .ArmCalibration1Right.WristAbductionPositions; + + #if BM_ARM_DETAILED_HAND + ModelRef = { #include "DetailedHandDrivers.any" }; + #endif + + #if BM_ARM_SHOULDER_RHYTHM + ModelRef = { + // Exclude the shoulder rythm, since the drivers handles all DOFs. + AnyMechObjectExcluder ExcludeShoulderRhythm = + { + Objects = arrcat( + &.Joints.ClaviculaProtractionDriver, + &.Joints.ClaviculaElevationDriver, + ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") + ); + }; + }; + #endif +}; + +ArmCalibrationStudy ArmCalibration2Left( + BodyModelRef = Main.HumanModel.BodyModel, +Side = Left, +) = { + nStep = .ArmCalibration2Right.nStep; + + MuscleArr = ObjSearch( + &..BodyModel.Left.ShoulderArm.Muscles, + { + "Anconeus.*", + "BicepsBrachii.*", + "Brachialis.*", + "Brachioradialis.*", + "Coracobrachialis.*", + "Triceps.*", + }, + "AnyMuscle" + ); + + RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); + RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); + + AnyObjectPtrArray ShoulderPositions = .ArmCalibration2Right.ShoulderPositions; + AnyObjectPtrArray ElbowFlexionPositions = .ArmCalibration2Right.ElbowFlexionPositions; + AnyObjectPtrArray ElbowPronationPositions = .ArmCalibration2Right.ElbowPronationPositions; + AnyObjectPtrArray WristFlexionPositions = .ArmCalibration2Right.WristFlexionPositions; + AnyObjectPtrArray WristAbductionPositions = .ArmCalibration2Right.WristAbductionPositions; + + #if BM_ARM_DETAILED_HAND + ModelRef = { #include "DetailedHandDrivers.any" }; + #endif + + #if BM_ARM_SHOULDER_RHYTHM + ModelRef = { + // Exclude the shoulder rythm, since the drivers handles all DOFs. + AnyMechObjectExcluder ExcludeShoulderRhythm = { + Objects = arrcat( + &.Joints.ClaviculaProtractionDriver, + &.Joints.ClaviculaElevationDriver, + ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") + ); + }; + }; + #endif +}; + +ArmCalibrationStudy ArmCalibration3Left( + BodyModelRef=Main.HumanModel.BodyModel, +Side=Left, +) = { + nStep = .ArmCalibration3Right.nStep; + + MuscleArr = ObjSearch( + &..BodyModel.Left.ShoulderArm.Muscles, + { + "AbductorPollicis.*", + "FlexorPollicisLongus.*", + }, + "AnyMuscle" + ); + + RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); + RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); + + AnyObjectPtrArray ShoulderPositions = .ArmCalibration3Right.ShoulderPositions; + AnyObjectPtrArray ElbowFlexionPositions = .ArmCalibration3Right.ElbowFlexionPositions; + AnyObjectPtrArray ElbowPronationPositions = .ArmCalibration3Right.ElbowPronationPositions; + AnyObjectPtrArray WristFlexionPositions = .ArmCalibration3Right.WristFlexionPositions; + AnyObjectPtrArray WristAbductionPositions = .ArmCalibration3Right.WristAbductionPositions; + + #if BM_ARM_DETAILED_HAND + ModelRef = { #include "DetailedHandDrivers.any" }; + #endif + + #if BM_ARM_SHOULDER_RHYTHM + ModelRef = { + // Exclude the shoulder rythm, since the drivers handles all DOFs. + AnyMechObjectExcluder ExcludeShoulderRhythm = { + Objects = arrcat( + &.Joints.ClaviculaProtractionDriver, + &.Joints.ClaviculaElevationDriver, + ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") + ); + }; + }; + #endif +}; + +ArmCalibrationStudy ArmCalibration4Left( +BodyModelRef=Main.HumanModel.BodyModel, +Side=Left, +) = { + nStep = .ArmCalibration4Right.nStep; + + MuscleArr = ObjSearch( + &..BodyModel.Left.ShoulderArm.Muscles, + { + "Rhomboideus.*", + "Sternocleidomastoid.*", + "TeresMajor.*", + "TeresMinor.*", + "TrapeziusClavicular.*", + "TrapeziusScapular.*", + }, + "AnyMuscle" + ); + + RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); + RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); + + AnyObjectPtrArray ShoulderPositions = .ArmCalibration4Right.ShoulderPositions; + AnyObjectPtrArray ElbowFlexionPositions = .ArmCalibration4Right.ElbowFlexionPositions; + AnyObjectPtrArray ElbowPronationPositions = .ArmCalibration4Right.ElbowPronationPositions; + AnyObjectPtrArray WristFlexionPositions = .ArmCalibration4Right.WristFlexionPositions; + AnyObjectPtrArray WristAbductionPositions = .ArmCalibration4Right.WristAbductionPositions; + + #if BM_ARM_DETAILED_HAND + ModelRef = { #include "DetailedHandDrivers.any" }; + #endif + + #if BM_ARM_SHOULDER_RHYTHM + ModelRef = { + // Exclude the shoulder rythm, since the drivers handles all DOFs. + AnyMechObjectExcluder ExcludeShoulderRhythm = { + Objects = arrcat( + &.Joints.ClaviculaProtractionDriver, + &.Joints.ClaviculaElevationDriver, + ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") + ); + }; + }; + #endif +}; + +ArmCalibrationStudy ArmCalibration5Left( +BodyModelRef=Main.HumanModel.BodyModel, +Side=Left, +) = { + nStep = .ArmCalibration5Right.nStep; + + MuscleArr = ObjSearch( + &..BodyModel.Left.ShoulderArm.Muscles, + { + "PronatorQuadratus.*", + "PronatorTeres.*", + "Supinator.*", + }, + "AnyMuscle" + ); + + RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); + RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); + + AnyObjectPtrArray ShoulderPositions = .ArmCalibration5Right.ShoulderPositions; + AnyObjectPtrArray ElbowFlexionPositions = .ArmCalibration5Right.ElbowFlexionPositions; + AnyObjectPtrArray ElbowPronationPositions = .ArmCalibration5Right.ElbowPronationPositions; + AnyObjectPtrArray WristFlexionPositions = .ArmCalibration5Right.WristFlexionPositions; + AnyObjectPtrArray WristAbductionPositions = .ArmCalibration5Right.WristAbductionPositions; + + #if BM_ARM_DETAILED_HAND + ModelRef = { #include "DetailedHandDrivers.any" }; + #endif + + #if BM_ARM_SHOULDER_RHYTHM + ModelRef = { + // Exclude the shoulder rythm, since the drivers handles all DOFs. + AnyMechObjectExcluder ExcludeShoulderRhythm = { + Objects = arrcat( + &.Joints.ClaviculaProtractionDriver, + &.Joints.ClaviculaElevationDriver, + ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") + ); + }; + }; + #endif +}; + +ArmCalibrationStudy ArmCalibration6Left( +BodyModelRef=Main.HumanModel.BodyModel, +Side=Left, +) = { + nStep = .ArmCalibration6Right.nStep; + + MuscleArr = ObjSearch( + &..BodyModel.Left.ShoulderArm.Muscles, + { + "ExtensorCarpiRadialis.*", + "ExtensorCarpiUlnaris.*", + "ExtensorDigitiMinimi.*", + "ExtensorDigitorum.*", + "ExtensorIndicis.*", + "ExtensorPollicis.*", + "FlexorCarpiRadialis.*", + "FlexorCarpiUlnaris.*", + "FlexorDigitorumProfundus.*", + "FlexorDigitorumSuperficialis.*", + "PalmarisLongus.*", + }, + "AnyMuscle" + ); + + RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); + RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); + + AnyObjectPtrArray ShoulderPositions = .ArmCalibration6Right.ShoulderPositions; + AnyObjectPtrArray ElbowFlexionPositions = .ArmCalibration6Right.ElbowFlexionPositions; + AnyObjectPtrArray ElbowPronationPositions = .ArmCalibration6Right.ElbowPronationPositions; + AnyObjectPtrArray WristFlexionPositions = .ArmCalibration6Right.WristFlexionPositions; + AnyObjectPtrArray WristAbductionPositions = .ArmCalibration6Right.WristAbductionPositions; + + #if BM_ARM_DETAILED_HAND + ModelRef = { #include "DetailedHandDrivers.any" }; + #endif + + #if BM_ARM_SHOULDER_RHYTHM + ModelRef = { + // Exclude the shoulder rythm, since the drivers handles all DOFs. + AnyMechObjectExcluder ExcludeShoulderRhythm = { + Objects = arrcat( + &.Joints.ClaviculaProtractionDriver, + &.Joints.ClaviculaElevationDriver, + ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") + ); + }; + }; + #endif +}; + + +CalibrationSequence = { + AnyOperation &ArmCal1Left = .ArmCalibration1Left.FiberAndTendonLengthAdjustment; + AnyOperation &ArmCal2Left = .ArmCalibration2Left.FiberAndTendonLengthAdjustment; + AnyOperation &ArmCal3Left = .ArmCalibration3Left.FiberAndTendonLengthAdjustment; + AnyOperation &ArmCal4Left = .ArmCalibration4Left.FiberAndTendonLengthAdjustment; + AnyOperation &ArmCal5Left = .ArmCalibration5Left.FiberAndTendonLengthAdjustment; + AnyOperation &ArmCal6Left = .ArmCalibration6Left.FiberAndTendonLengthAdjustment; +}; \ No newline at end of file diff --git a/Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any b/Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any new file mode 100644 index 000000000..00c7a40f4 --- /dev/null +++ b/Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any @@ -0,0 +1,353 @@ +ArmCalibrationStudy ArmCalibration1Right( + BodyModelRef=Main.HumanModel.BodyModel, + Side=Right, +) = { + nStep = nPos; + + MuscleArr = ObjSearch( + &..BodyModel.Right.ShoulderArm.Muscles, + { + "DeltoideusAnterior.*", + "DeltoideusLateral.*", + "DeltoideusPosterior.*", + "Infraspinatus.*", + "LatissimusDorsi.*", + "LevatorScapulae.*", + "PectoralisMajorClavicular.*", + "PectoralisMajorThroacic.*", + "PectoralisMinor.*", + "SerratusAnterior.*", + "Subscapularis.*", + "Supraspinatus.*", + }, + "AnyMuscle" + ); + + RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); + RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); + + AnyInt nPos = NumElemOf(ShoulderPositions); + AnyObjectPtrArray ShoulderPositions = repmat(2,{ + &.RangeOfMotion.Right.ShoulderArm.Shoulder.Flexed, + &.RangeOfMotion.Right.ShoulderArm.Shoulder.Extended, + &.RangeOfMotion.Right.ShoulderArm.Shoulder.Abducted, + &.RangeOfMotion.Right.ShoulderArm.Shoulder.Adducted, + &.RangeOfMotion.Right.ShoulderArm.Shoulder.ExternallyRotated, + &.RangeOfMotion.Right.ShoulderArm.Shoulder.InternallyRotated, + &.RangeOfMotion.Right.ShoulderArm.Shoulder.FlexedAndExternallyRotated, + &.RangeOfMotion.Right.ShoulderArm.Shoulder.FlexedAndInternallyRotated, + &.RangeOfMotion.Right.ShoulderArm.Shoulder.ExtendedAndExternallyRotated, + &.RangeOfMotion.Right.ShoulderArm.Shoulder.ExtendedAndInternallyRotated, + &.RangeOfMotion.Right.ShoulderArm.Shoulder.FlexedAndAdducted, + &.RangeOfMotion.Right.ShoulderArm.Shoulder.FlexedAndAbducted, + }); + + AnyObjectPtrArray ElbowFlexionPositions = flatten({ + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxFlexionAngle), + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxExtensionAngle) + }); + + AnyObjectPtrArray ElbowPronationPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Elbow.Neutral); + AnyObjectPtrArray WristFlexionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); + AnyObjectPtrArray WristAbductionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); + + #if BM_ARM_DETAILED_HAND + ModelRef = { #include "DetailedHandDrivers.any" }; + #endif + + #if BM_ARM_SHOULDER_RHYTHM + ModelRef = { + // Exclude the shoulder rythm, since the drivers handles all DOFs. + AnyMechObjectExcluder ExcludeShoulderRhythm ={ + Objects = arrcat( + &.Joints.ClaviculaProtractionDriver, + &.Joints.ClaviculaElevationDriver, + ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") + ); + }; + }; + #endif +}; + +ArmCalibrationStudy ArmCalibration2Right( + BodyModelRef=Main.HumanModel.BodyModel, + Side=Right, +) = { + nStep = nPos; + + MuscleArr = ObjSearch( + &..BodyModel.Right.ShoulderArm.Muscles, + { + "Anconeus.*", + "BicepsBrachii.*", + "Brachialis.*", + "Brachioradialis.*", + "Coracobrachialis.*", + "Triceps.*", + }, + "AnyMuscle" + ); + + RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); + RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); + + AnyInt nPos = NumElemOf(ShoulderPositions); + AnyObjectPtrArray ShoulderPositions = repmat(2,{ + &.RangeOfMotion.Right.ShoulderArm.Shoulder.Flexed, + &.RangeOfMotion.Right.ShoulderArm.Shoulder.Extended, + }); + + AnyObjectPtrArray ElbowFlexionPositions = flatten({ + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxFlexionAngle), + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxExtensionAngle) + }); + + AnyObjectPtrArray ElbowPronationPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Elbow.Neutral); + AnyObjectPtrArray WristFlexionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); + AnyObjectPtrArray WristAbductionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); + + #if BM_ARM_DETAILED_HAND + ModelRef = { #include "DetailedHandDrivers.any" }; + #endif + + #if BM_ARM_SHOULDER_RHYTHM + ModelRef = { + // Exclude the shoulder rythm, since the drivers handles all DOFs. + AnyMechObjectExcluder ExcludeShoulderRhythm = { + Objects = arrcat( + &.Joints.ClaviculaProtractionDriver, + &.Joints.ClaviculaElevationDriver, + ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") + ); + }; + }; + #endif +}; + +ArmCalibrationStudy ArmCalibration3Right( + BodyModelRef=Main.HumanModel.BodyModel, + Side=Right, +) = { + nStep = nPos; + + MuscleArr = ObjSearch( + &..BodyModel.Right.ShoulderArm.Muscles, + { + "AbductorPollicis.*", + "FlexorPollicisLongus.*", + }, + "AnyMuscle" + ); + + RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); + RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); + + AnyInt nPos = NumElemOf(ShoulderPositions); + AnyObjectPtrArray ShoulderPositions = repmat(2,{ + &.RangeOfMotion.Right.ShoulderArm.Shoulder.Flexed, + &.RangeOfMotion.Right.ShoulderArm.Shoulder.Extended, + }); + + AnyObjectPtrArray ElbowFlexionPositions = flatten({ + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxFlexionAngle), + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxExtensionAngle) + }); + + AnyObjectPtrArray ElbowPronationPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Elbow.Neutral); + AnyObjectPtrArray WristFlexionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); + AnyObjectPtrArray WristAbductionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); + + #if BM_ARM_DETAILED_HAND + ModelRef = { #include "DetailedHandDrivers.any" }; + #endif + + #if BM_ARM_SHOULDER_RHYTHM + ModelRef = { + // Exclude the shoulder rythm, since the drivers handles all DOFs. + AnyMechObjectExcluder ExcludeShoulderRhythm = { + Objects = arrcat( + &.Joints.ClaviculaProtractionDriver, + &.Joints.ClaviculaElevationDriver, + ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") + ); + }; + }; + #endif +}; + +ArmCalibrationStudy ArmCalibration4Right( + BodyModelRef=Main.HumanModel.BodyModel, + Side=Right, +) = { + nStep = nPos; + + MuscleArr = ObjSearch( + &..BodyModel.Right.ShoulderArm.Muscles, + { + "Rhomboideus.*", + "Sternocleidomastoid.*", + "TeresMajor.*", + "TeresMinor.*", + "TrapeziusClavicular.*", + "TrapeziusScapular.*", + }, + "AnyMuscle" + ); + + RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); + RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); + + AnyInt nPos = NumElemOf(ShoulderPositions); + AnyObjectPtrArray ShoulderPositions = repmat(2,{ + &.RangeOfMotion.Right.ShoulderArm.Shoulder.Flexed, + &.RangeOfMotion.Right.ShoulderArm.Shoulder.Extended, + }); + + AnyObjectPtrArray ElbowFlexionPositions = flatten({ + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxFlexionAngle), + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxExtensionAngle) + }); + + AnyObjectPtrArray ElbowPronationPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Elbow.Neutral); + AnyObjectPtrArray WristFlexionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); + AnyObjectPtrArray WristAbductionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); + + #if BM_ARM_DETAILED_HAND + ModelRef = { #include "DetailedHandDrivers.any" }; + #endif + + #if BM_ARM_SHOULDER_RHYTHM + ModelRef = { + // Exclude the shoulder rythm, since the drivers handles all DOFs. + AnyMechObjectExcluder ExcludeShoulderRhythm = { + Objects = arrcat( + &.Joints.ClaviculaProtractionDriver, + &.Joints.ClaviculaElevationDriver, + ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") + ); + }; + }; + #endif +}; + +ArmCalibrationStudy ArmCalibration5Right( + BodyModelRef=Main.HumanModel.BodyModel, + Side=Right, +) = { + nStep = nPos; + + MuscleArr = ObjSearch( + &..BodyModel.Right.ShoulderArm.Muscles, + { + "PronatorQuadratus.*", + "PronatorTeres.*", + "Supinator.*", + }, + "AnyMuscle" + ); + + RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); + RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); + + AnyInt nPos = NumElemOf(ShoulderPositions); + AnyObjectPtrArray ShoulderPositions = repmat(2,{ + &.RangeOfMotion.Right.ShoulderArm.Shoulder.Flexed, + &.RangeOfMotion.Right.ShoulderArm.Shoulder.Extended, + }); + + AnyObjectPtrArray ElbowFlexionPositions = flatten({ + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxFlexionAngle), + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxExtensionAngle) + }); + + AnyObjectPtrArray ElbowPronationPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Elbow.Neutral); + AnyObjectPtrArray WristFlexionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); + AnyObjectPtrArray WristAbductionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); + + #if BM_ARM_DETAILED_HAND + ModelRef = { #include "DetailedHandDrivers.any" }; + #endif + + #if BM_ARM_SHOULDER_RHYTHM + ModelRef = { + // Exclude the shoulder rythm, since the drivers handles all DOFs. + AnyMechObjectExcluder ExcludeShoulderRhythm = { + Objects = arrcat( + &.Joints.ClaviculaProtractionDriver, + &.Joints.ClaviculaElevationDriver, + ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") + ); + }; + }; + #endif +}; + +ArmCalibrationStudy ArmCalibration6Right( + BodyModelRef=Main.HumanModel.BodyModel, + Side=Right, +) = { + nStep = nPos; + + MuscleArr = ObjSearch( + &..BodyModel.Right.ShoulderArm.Muscles, + { + "ExtensorCarpiRadialis.*", + "ExtensorCarpiUlnaris.*", + "ExtensorDigitiMinimi.*", + "ExtensorDigitorum.*", + "ExtensorIndicis.*", + "ExtensorPollicis.*", + "FlexorCarpiRadialis.*", + "FlexorCarpiUlnaris.*", + "FlexorDigitorumProfundus.*", + "FlexorDigitorumSuperficialis.*", + "PalmarisLongus.*", + }, + "AnyMuscle" + ); + + RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); + RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); + + AnyInt nPos = NumElemOf(ShoulderPositions); + AnyObjectPtrArray ShoulderPositions = repmat(2,{ + &.RangeOfMotion.Right.ShoulderArm.Shoulder.Flexed, + &.RangeOfMotion.Right.ShoulderArm.Shoulder.Extended, + }); + + AnyObjectPtrArray ElbowFlexionPositions = flatten({ + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxFlexionAngle), + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxExtensionAngle) + }); + + AnyObjectPtrArray ElbowPronationPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Elbow.Neutral); + AnyObjectPtrArray WristFlexionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); + AnyObjectPtrArray WristAbductionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); + + #if BM_ARM_DETAILED_HAND + ModelRef = { #include "DetailedHandDrivers.any" }; + #endif + + #if BM_ARM_SHOULDER_RHYTHM + ModelRef = { + // Exclude the shoulder rythm, since the drivers handles all DOFs. + AnyMechObjectExcluder ExcludeShoulderRhythm = { + Objects = arrcat( + &.Joints.ClaviculaProtractionDriver, + &.Joints.ClaviculaElevationDriver, + ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") + ); + }; + }; + #endif +}; + + +CalibrationSequence = { + AnyOperation &ArmCal1Right = .ArmCalibration1Right.FiberAndTendonLengthAdjustment; + AnyOperation &ArmCal2Right = .ArmCalibration2Right.FiberAndTendonLengthAdjustment; + AnyOperation &ArmCal3Right = .ArmCalibration3Right.FiberAndTendonLengthAdjustment; + AnyOperation &ArmCal4Right = .ArmCalibration4Right.FiberAndTendonLengthAdjustment; + AnyOperation &ArmCal5Right = .ArmCalibration5Right.FiberAndTendonLengthAdjustment; + AnyOperation &ArmCal6Right = .ArmCalibration6Right.FiberAndTendonLengthAdjustment; +}; \ No newline at end of file diff --git a/Body/AAUHuman/Arm/Calibration/DetailedHandDrivers.any b/Body/AAUHuman/Arm/Calibration/DetailedHandDrivers.any new file mode 100644 index 000000000..c312ce9ce --- /dev/null +++ b/Body/AAUHuman/Arm/Calibration/DetailedHandDrivers.any @@ -0,0 +1,103 @@ +// Finger constraints for the detailed hand model in calibration studies +AnyKinEqSimpleDriver CMC1Flexion = { + AnyRevoluteJoint &ref = .Segments.Hand.Finger1.Jnt.CMCFlexion; + DriverPos = {0}*pi/180; + DriverVel = {0}; +}; + +AnyKinEqSimpleDriver CMC1Abduction = { + AnyRevoluteJoint &ref = .Segments.Hand.Finger1.Jnt.CMCAbduction; + DriverPos = {0}*pi/180; + DriverVel = {0}; +}; + +AnyKinEqSimpleDriver MCP1Flexion = { + AnyRevoluteJoint &ref = .Segments.Hand.Finger1.Jnt.MCPFlexion; + DriverPos = {0}*pi/180; + DriverVel = {0}; +}; + +AnyKinEqSimpleDriver MCP1Abduction= +{ + AnyRevoluteJoint &ref = .Segments.Hand.Finger1.Jnt.MCPAbduction; + DriverPos = {0}*pi/180; + DriverVel = {0}; +}; + +AnyKinEqSimpleDriver DIP1 = { + AnyRevoluteJoint &ref = .Segments.Hand.Finger1.Jnt.DIP; + DriverPos = {0}*pi/180; + DriverVel = {0}; +}; + +AnyKinEqSimpleDriver MCP2= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger2.Jnt.MCP; + DriverPos= {0}*pi/180; + DriverVel= {0}; +}; + +AnyKinEqSimpleDriver PIP2= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger2.Jnt.PIP; + DriverPos= {0}*pi/180; + DriverVel= {0}; +}; + +AnyKinEqSimpleDriver DIP2= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger2.Jnt.DIP; + DriverPos= {0}; + DriverVel= {0}; +}; + +AnyKinEqSimpleDriver MCP3= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger3.Jnt.MCP; + DriverPos= {0}*pi/180; + DriverVel= {0}; +}; + +AnyKinEqSimpleDriver PIP3= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger3.Jnt.PIP; + DriverPos= {0}*pi/180; + DriverVel= {0}; +}; + +AnyKinEqSimpleDriver DIP3= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger3.Jnt.DIP; + DriverPos= {0}; + DriverVel= {0}; +}; + +AnyKinEqSimpleDriver MCP4= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger4.Jnt.MCP; + DriverPos= {0}*pi/180; + DriverVel= {0}; +}; + +AnyKinEqSimpleDriver PIP4= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger4.Jnt.PIP; + DriverPos= {0}*pi/180; + DriverVel= {0}; +}; + +AnyKinEqSimpleDriver DIP4= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger4.Jnt.DIP; + DriverPos= {0}*pi/180; + DriverVel= {0}; +}; + +AnyKinEqSimpleDriver MCP5= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger5.Jnt.MCP; + DriverPos= {0}*pi/180; + DriverVel= {0}; +}; + +AnyKinEqSimpleDriver PIP5= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger5.Jnt.PIP; + DriverPos= {0}*pi/180; + DriverVel= {0}; +}; + +AnyKinEqSimpleDriver DIP5= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger5.Jnt.DIP; + DriverPos= {0}; + DriverVel= {0}; +}; \ No newline at end of file diff --git a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any index 0080ef272..564dd21aa 100644 --- a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any +++ b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any @@ -14,7 +14,7 @@ AnyFolder &LegSegments = BodyModelRef.Side.Leg.Seg; AnyFolder &LegJoints = BodyModelRef.Side.Leg.Jnt; - + // Constraints AnyFixedRefFrame ground = { AnyRefNode node = { @@ -85,6 +85,122 @@ }; }; +/** + Class template for creating a model that can be used to calibrate the arms +*/ +#class_template ArmCalibrationModel(Side, BodyModelRef) { + AnyComponentDefinition CDef = {}; + + #var AnyObjectPtr ShoulderPositions; + #var AnyObjectPtr ElbowFlexionPositions; + #var AnyObjectPtr ElbowPronationPositions; + #var AnyObjectPtr WristFlexionPositions; + #var AnyObjectPtr WristAbductionPositions; + + AnyFolder &TrunkSegments = BodyModelRef.Trunk.Segments; + AnyFolder &TrunkJoints = BodyModelRef.Trunk.Joints; + + AnyFolder &Segments = BodyModelRef.Side.ShoulderArm.Segments; + AnyFolder &Joints = BodyModelRef.Side.ShoulderArm.Joints; + + // The Muscles folder contain segments and constraints for some wrapping muscles + // e.g. Deltoid, Pectoralis Minor, etc. + AnyFolder &Muscles = BodyModelRef.Side.ShoulderArm.Muscles; + + // Constraints + AnyFixedRefFrame ground = { + AnyRefNode node = { + ARel = ..TrunkSegments.PelvisSeg.Axes0; + sRel = ..TrunkSegments.PelvisSeg.r0; + }; + }; + + AnyKinEq ThoraxFix = { + AnyKinMeasure& PelvisThoraxExtension = BodyModelRef.Interface.Trunk.PelvisThoraxExtension; + AnyKinMeasure& PelvisThoraxLateralBending = BodyModelRef.Interface.Trunk.PelvisThoraxLateralBending; + AnyKinMeasure& PelvisThoraxRotation = BodyModelRef.Interface.Trunk.PelvisThoraxRotation; + AnyKinMeasure& SkullThoraxFlexion = BodyModelRef.Interface.Trunk.SkullThoraxFlexion; + AnyKinMeasure& SkullThoraxRotation = BodyModelRef.Interface.Trunk.SkullThoraxRotation; + AnyKinMeasure& SkullThoraxLateralBending = BodyModelRef.Interface.Trunk.SkullThoraxLateralBending; + }; + + AnyKinEq PelvisFix = { + AnyKinLinear Lin = { + AnyRefFrame &ground = ..ground.node; + AnyRefFrame &Pelvis = ..TrunkSegments.PelvisSeg; + }; + AnyKinRotational Rot = { + Type = RotAxesAngles; + AnyRefFrame &ground = ..ground.node; + AnyRefFrame &Pelvis = ..TrunkSegments.PelvisSeg; + }; + }; + + + AnyKinEqInterPolDriver Shoulder = { + AnyKinRotational &Spherical = .BodyModelRef.Interface.Side.GlenohumeralFlexion.GHMeasure; + Type = PiecewiseLinear; + T = linspace(0,1,SizesOf(Data)[1]); + Data = Obj2Num(.ShoulderPositions)' * 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 ScapulaProtraction = { + AnyKinMeasure& Hinge = .BodyModelRef.Interface.Side.ScapulaThoraxProtraction; + Type = PiecewiseLinear; + T = linspace(0,1,SizesOf(Data)[1]); + Data = {Obj2Num(.ElbowFlexionPositions)} * 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 ScapulaElevation = { + AnyKinMeasure& Hinge = .BodyModelRef.Interface.Side.ScapulaThoraxElevation; + Type = PiecewiseLinear; + T = linspace(0,1,SizesOf(Data)[1]); + Data = {Obj2Num(.ElbowFlexionPositions)} * 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 ElbowFlexion = { + AnyKinMeasure& Hinge = .BodyModelRef.Interface.Side.ElbowFlexion; + Type = PiecewiseLinear; + T = linspace(0,1,SizesOf(Data)[1]); + Data = {Obj2Num(.ElbowFlexionPositions)} * 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 ElbowPronation = { + AnyKinMeasure& Hinge = .BodyModelRef.Interface.Side.ElbowPronation; + Type = PiecewiseLinear; + T = linspace(0,1,SizesOf(Data)[1]); + Data = {Obj2Num(.ElbowPronationPositions)} * 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 WristFlexion = { + AnyKinMeasure& Hinge = .BodyModelRef.Interface.Side.WristFlexion; + Type = PiecewiseLinear; + T = linspace(0,1,SizesOf(Data)[1]); + Data = {Obj2Num(.WristFlexionPositions)} * 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 WristAbduction = { + AnyKinMeasure& Hinge = .BodyModelRef.Interface.Side.WristAbduction; + Type = PiecewiseLinear; + T = linspace(0,1,SizesOf(Data)[1]); + Data = {Obj2Num(.WristAbductionPositions)} * 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 @@ -109,3 +225,28 @@ }; }; + +/** + Class template for creating calibrationstudies with same settings +*/ +#class_template ArmCalibrationStudy( + __CLASS__ = AnyBodyCalibrationStudy, + BodyModelRef, + Side, + +) { + // Study settings + FiberAndTendonLengthAdjustment.CalibrateTendonAtMaxForceOnOff = Off; + Kinematics.SmallStepAssumptionOnOff = Off; + InitialConditions.SmallStepAssumptionOnOff = Off; + Kinematics.PosAnalysisOnlyOnOff = On; + InitialConditions.PosAnalysisOnlyOnOff = On; + + ArmCalibrationModel ModelRef(Side=Side, BodyModelRef=BodyModelRef) = { + ShoulderPositions = .ShoulderPositions; + ElbowFlexionPositions = .ElbowFlexionPositions; + ElbowPronationPositions = .ElbowPronationPositions; + WristFlexionPositions = .WristFlexionPositions; + WristAbductionPositions = .WristAbductionPositions; + }; +}; diff --git a/Body/AAUHuman/BodyModels/GenericBodyModel/CalibrationSequence.any b/Body/AAUHuman/BodyModels/GenericBodyModel/CalibrationSequence.any index ed0707343..9a2071652 100644 --- a/Body/AAUHuman/BodyModels/GenericBodyModel/CalibrationSequence.any +++ b/Body/AAUHuman/BodyModels/GenericBodyModel/CalibrationSequence.any @@ -84,7 +84,7 @@ AnyFolder Calibration={ #include "../../Arm/Calibration/CalibrationSequenceRight2Par.any" #endif #if BM_CALIBRATION_TYPE == _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_ - + #include "../../Arm/Calibration/2ParRightCalStudies.any" #endif #if BM_CALIBRATION_TYPE == _CALIBRATION_TYPE_CUSTOM_ // Allow user to implement their own calibration @@ -100,7 +100,7 @@ AnyFolder Calibration={ #include "../../Arm/Calibration/CalibrationSequenceLeft2Par.any" #endif #if BM_CALIBRATION_TYPE == _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_ - + #include "../../Arm/Calibration/2ParLeftCalStudies.any" #endif #if BM_CALIBRATION_TYPE == _CALIBRATION_TYPE_CUSTOM_ // Allow user to implement their own calibration From 8756ffad923a5f87a549a00fdb8c6daf392d0ae3 Mon Sep 17 00:00:00 2001 From: bke Date: Wed, 26 Mar 2025 14:58:16 +0100 Subject: [PATCH 08/29] fix typo in search string and add test to new cal type --- .../Arm/Calibration/2ParLeftCalStudies.any | 2 +- .../Arm/Calibration/2ParRightCalStudies.any | 2 +- .../test_calibration_upperbody.any | 28 +++++++++---------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any b/Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any index 654ac105e..6b3a6fc3e 100644 --- a/Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any +++ b/Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any @@ -14,7 +14,7 @@ Side = Left, "LatissimusDorsi.*", "LevatorScapulae.*", "PectoralisMajorClavicular.*", - "PectoralisMajorThroacic.*", + "PectoralisMajorThoracic.*", "PectoralisMinor.*", "SerratusAnterior.*", "Subscapularis.*", diff --git a/Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any b/Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any index 00c7a40f4..4743e5aaf 100644 --- a/Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any +++ b/Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any @@ -14,7 +14,7 @@ ArmCalibrationStudy ArmCalibration1Right( "LatissimusDorsi.*", "LevatorScapulae.*", "PectoralisMajorClavicular.*", - "PectoralisMajorThroacic.*", + "PectoralisMajorThoracic.*", "PectoralisMinor.*", "SerratusAnterior.*", "Subscapularis.*", diff --git a/Tests/Calibration/test_calibration_upperbody.any b/Tests/Calibration/test_calibration_upperbody.any index 0003a4d59..ba0154e4b 100644 --- a/Tests/Calibration/test_calibration_upperbody.any +++ b/Tests/Calibration/test_calibration_upperbody.any @@ -1,6 +1,8 @@ //ignore_errors = ['Currently, no room for tendon'] //fatal_warnings = [ // "Penetration of surface", +// "too few kinematic constraints to be kinematically determinate", +// "A segment appears to be missing in this study", //] //define = ( // [ @@ -39,20 +41,18 @@ Main = // Test to check that all muscles in the model are part of the calibration studies. // the test is excluded for the calibration combinations that do not make sense / are unimplemented - #if BM_CALIBRATION_TYPE != 3 - AnyObjectPtrArray muscles_from_cal_studies = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.Calibration, "MuscleArr"))); - AnyObjectPtrArray muscles_right = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Right.ShoulderArm.Muscles, "*", "AnyMuscle"))); - AnyObjectPtrArray muscles_left = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Left.ShoulderArm.Muscles, "*", "AnyMuscle"))); - AnyObjectPtrArray muscles_from_model = arrcat(muscles_right, muscles_left); - - AnyInt test_all_mus_in_cal = expect( - eqfun( - NumElemOf(muscles_from_cal_studies), - NumElemOf(muscles_from_model) - ), - "The number of muscles in the calibration studies do not match the number of muscles in the model!" - ); - #endif + AnyObjectPtrArray muscles_from_cal_studies = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.Calibration, "MuscleArr"))); + AnyObjectPtrArray muscles_right = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Right.ShoulderArm.Muscles, "*", "AnyMuscle"))); + AnyObjectPtrArray muscles_left = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Left.ShoulderArm.Muscles, "*", "AnyMuscle"))); + AnyObjectPtrArray muscles_from_model = arrcat(muscles_right, muscles_left); + + AnyInt test_all_mus_in_cal = expect( + eqfun( + NumElemOf(muscles_from_cal_studies), + NumElemOf(muscles_from_model) + ), + "The number of muscles in the calibration studies do not match the number of muscles in the model!" + ); }; From 5cf3cd21a4ca2514ec6aafd9b998ce5fd001d964 Mon Sep 17 00:00:00 2001 From: bke Date: Fri, 28 Mar 2025 13:22:56 +0100 Subject: [PATCH 09/29] add neutral pos --- Body/AAUHuman/Arm/rangeOfMotion.any | 3 ++- Body/AAUHuman/LegTLEM/rangeOfMotion.any | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Body/AAUHuman/Arm/rangeOfMotion.any b/Body/AAUHuman/Arm/rangeOfMotion.any index 749d255df..2f51d8319 100644 --- a/Body/AAUHuman/Arm/rangeOfMotion.any +++ b/Body/AAUHuman/Arm/rangeOfMotion.any @@ -12,9 +12,10 @@ AnyFolder RangeOfMotion = { AnyVar MaxScapulaClaviculaDepressionAngle = -5; AnyVar MaxScapulaClaviculaProtractionAngle = 15; AnyVar MaxScapulaClaviculaRetractionAngle = -36; + AnyVar Neutral = 0; // Shoulder positions - AnyFloat Neutral = {0,0,0}; + AnyFloat Neutral = {Neutral, Neutral, Neutral}; AnyFloat Flexed = {MaxGlenohumeralFlexionAngle, 0, 0}; AnyFloat Extended = {MaxGlenohumeralExtensionAngle, 0, 0}; AnyFloat Abducted = {0, MaxGlenohumeralAbductionAngle, 0}; diff --git a/Body/AAUHuman/LegTLEM/rangeOfMotion.any b/Body/AAUHuman/LegTLEM/rangeOfMotion.any index 1dd2d9ead..3ab2c6698 100644 --- a/Body/AAUHuman/LegTLEM/rangeOfMotion.any +++ b/Body/AAUHuman/LegTLEM/rangeOfMotion.any @@ -12,9 +12,10 @@ AnyFolder RangeOfMotion = { AnyVar MaxExtensionInAdductionAngle = -10; AnyVar MaxFlexionInAbductionAngle = 90; AnyVar MinFlexionInAdduction = 5; + AnyVar Neutral = 0; // Hip positions - AnyFloat Neutral = { 0, 0, 0 }; + AnyFloat Neutral = { Neutral, Neutral, Neutral }; AnyFloat InternallyRotated = { 0, 0, MaxInternalRotationAngle }; AnyFloat ExternallyRotated = { 0, 0, MaxExternalRotationAngle }; AnyFloat Adduction = { MinFlexionInAdduction, MaxAdductionAngle, 0}; From 3c6a79e043e7a67ac03c56e12ef3d0a323b33ffb Mon Sep 17 00:00:00 2001 From: bke Date: Fri, 28 Mar 2025 14:21:15 +0100 Subject: [PATCH 10/29] remove double defined var --- Body/AAUHuman/Arm/rangeOfMotion.any | 3 +-- Body/AAUHuman/LegTLEM/rangeOfMotion.any | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Body/AAUHuman/Arm/rangeOfMotion.any b/Body/AAUHuman/Arm/rangeOfMotion.any index 2f51d8319..40773ad32 100644 --- a/Body/AAUHuman/Arm/rangeOfMotion.any +++ b/Body/AAUHuman/Arm/rangeOfMotion.any @@ -12,10 +12,9 @@ AnyFolder RangeOfMotion = { AnyVar MaxScapulaClaviculaDepressionAngle = -5; AnyVar MaxScapulaClaviculaProtractionAngle = 15; AnyVar MaxScapulaClaviculaRetractionAngle = -36; - AnyVar Neutral = 0; // Shoulder positions - AnyFloat Neutral = {Neutral, Neutral, Neutral}; + AnyFloat Neutral = {0, 0, 0}; AnyFloat Flexed = {MaxGlenohumeralFlexionAngle, 0, 0}; AnyFloat Extended = {MaxGlenohumeralExtensionAngle, 0, 0}; AnyFloat Abducted = {0, MaxGlenohumeralAbductionAngle, 0}; diff --git a/Body/AAUHuman/LegTLEM/rangeOfMotion.any b/Body/AAUHuman/LegTLEM/rangeOfMotion.any index 3ab2c6698..1dd2d9ead 100644 --- a/Body/AAUHuman/LegTLEM/rangeOfMotion.any +++ b/Body/AAUHuman/LegTLEM/rangeOfMotion.any @@ -12,10 +12,9 @@ AnyFolder RangeOfMotion = { AnyVar MaxExtensionInAdductionAngle = -10; AnyVar MaxFlexionInAbductionAngle = 90; AnyVar MinFlexionInAdduction = 5; - AnyVar Neutral = 0; // Hip positions - AnyFloat Neutral = { Neutral, Neutral, Neutral }; + AnyFloat Neutral = { 0, 0, 0 }; AnyFloat InternallyRotated = { 0, 0, MaxInternalRotationAngle }; AnyFloat ExternallyRotated = { 0, 0, MaxExternalRotationAngle }; AnyFloat Adduction = { MinFlexionInAdduction, MaxAdductionAngle, 0}; From 90a1561857e407a3b4d63c34ea77e38daf4649fa Mon Sep 17 00:00:00 2001 From: bke Date: Fri, 28 Mar 2025 14:21:59 +0100 Subject: [PATCH 11/29] add scapula positions --- .../Arm/Calibration/2ParLeftCalStudies.any | 12 +++ .../Arm/Calibration/2ParRightCalStudies.any | 83 ++++++++++++++++++- .../CalibrationStudy.ClassTemplates.any | 8 +- 3 files changed, 97 insertions(+), 6 deletions(-) diff --git a/Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any b/Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any index 6b3a6fc3e..80671a516 100644 --- a/Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any +++ b/Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any @@ -27,6 +27,8 @@ Side = Left, RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); AnyObjectPtrArray ShoulderPositions = .ArmCalibration1Right.ShoulderPositions; + AnyObjectPtrArray ScapulaElevationPositions = .ArmCalibration1Right.ScapulaElevationPositions; + AnyObjectPtrArray ScapulaProtractionPositions = .ArmCalibration1Right.ScapulaProtractionPositions; AnyObjectPtrArray ElbowFlexionPositions = .ArmCalibration1Right.ElbowFlexionPositions; AnyObjectPtrArray ElbowPronationPositions = .ArmCalibration1Right.ElbowPronationPositions; AnyObjectPtrArray WristFlexionPositions = .ArmCalibration1Right.WristFlexionPositions; @@ -74,6 +76,8 @@ Side = Left, RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); AnyObjectPtrArray ShoulderPositions = .ArmCalibration2Right.ShoulderPositions; + AnyObjectPtrArray ScapulaElevationPositions = .ArmCalibration2Right.ScapulaElevationPositions; + AnyObjectPtrArray ScapulaProtractionPositions = .ArmCalibration2Right.ScapulaProtractionPositions; AnyObjectPtrArray ElbowFlexionPositions = .ArmCalibration2Right.ElbowFlexionPositions; AnyObjectPtrArray ElbowPronationPositions = .ArmCalibration2Right.ElbowPronationPositions; AnyObjectPtrArray WristFlexionPositions = .ArmCalibration2Right.WristFlexionPositions; @@ -116,6 +120,8 @@ Side=Left, RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); AnyObjectPtrArray ShoulderPositions = .ArmCalibration3Right.ShoulderPositions; + AnyObjectPtrArray ScapulaElevationPositions = .ArmCalibration3Right.ScapulaElevationPositions; + AnyObjectPtrArray ScapulaProtractionPositions = .ArmCalibration3Right.ScapulaProtractionPositions; AnyObjectPtrArray ElbowFlexionPositions = .ArmCalibration3Right.ElbowFlexionPositions; AnyObjectPtrArray ElbowPronationPositions = .ArmCalibration3Right.ElbowPronationPositions; AnyObjectPtrArray WristFlexionPositions = .ArmCalibration3Right.WristFlexionPositions; @@ -162,6 +168,8 @@ Side=Left, RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); AnyObjectPtrArray ShoulderPositions = .ArmCalibration4Right.ShoulderPositions; + AnyObjectPtrArray ScapulaElevationPositions = .ArmCalibration4Right.ScapulaElevationPositions; + AnyObjectPtrArray ScapulaProtractionPositions = .ArmCalibration4Right.ScapulaProtractionPositions; AnyObjectPtrArray ElbowFlexionPositions = .ArmCalibration4Right.ElbowFlexionPositions; AnyObjectPtrArray ElbowPronationPositions = .ArmCalibration4Right.ElbowPronationPositions; AnyObjectPtrArray WristFlexionPositions = .ArmCalibration4Right.WristFlexionPositions; @@ -205,6 +213,8 @@ Side=Left, RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); AnyObjectPtrArray ShoulderPositions = .ArmCalibration5Right.ShoulderPositions; + AnyObjectPtrArray ScapulaElevationPositions = .ArmCalibration5Right.ScapulaElevationPositions; + AnyObjectPtrArray ScapulaProtractionPositions = .ArmCalibration5Right.ScapulaProtractionPositions; AnyObjectPtrArray ElbowFlexionPositions = .ArmCalibration5Right.ElbowFlexionPositions; AnyObjectPtrArray ElbowPronationPositions = .ArmCalibration5Right.ElbowPronationPositions; AnyObjectPtrArray WristFlexionPositions = .ArmCalibration5Right.WristFlexionPositions; @@ -256,6 +266,8 @@ Side=Left, RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); AnyObjectPtrArray ShoulderPositions = .ArmCalibration6Right.ShoulderPositions; + AnyObjectPtrArray ScapulaElevationPositions = .ArmCalibration6Right.ScapulaElevationPositions; + AnyObjectPtrArray ScapulaProtractionPositions = .ArmCalibration6Right.ScapulaProtractionPositions; AnyObjectPtrArray ElbowFlexionPositions = .ArmCalibration6Right.ElbowFlexionPositions; AnyObjectPtrArray ElbowPronationPositions = .ArmCalibration6Right.ElbowPronationPositions; AnyObjectPtrArray WristFlexionPositions = .ArmCalibration6Right.WristFlexionPositions; diff --git a/Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any b/Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any index 4743e5aaf..5b0a7a20a 100644 --- a/Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any +++ b/Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any @@ -41,6 +41,16 @@ ArmCalibrationStudy ArmCalibration1Right( &.RangeOfMotion.Right.ShoulderArm.Shoulder.FlexedAndAdducted, &.RangeOfMotion.Right.ShoulderArm.Shoulder.FlexedAndAbducted, }); + + AnyObjectPtrArray ScapulaElevationPositions = flatten({ + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaElevationAngle), + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaDepressionAngle) + }); + + AnyObjectPtrArray ScapulaProtractionPositions = flatten({ + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaProtractionAngle), + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaRetractionAngle) + }); AnyObjectPtrArray ElbowFlexionPositions = flatten({ repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxFlexionAngle), @@ -96,13 +106,27 @@ ArmCalibrationStudy ArmCalibration2Right( &.RangeOfMotion.Right.ShoulderArm.Shoulder.Flexed, &.RangeOfMotion.Right.ShoulderArm.Shoulder.Extended, }); + + AnyObjectPtrArray ScapulaElevationPositions = flatten({ + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaElevationAngle), + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaDepressionAngle) + }); + AnyObjectPtrArray ScapulaProtractionPositions = flatten({ + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaProtractionAngle), + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaRetractionAngle) + }); + AnyObjectPtrArray ElbowFlexionPositions = flatten({ repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxFlexionAngle), repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxExtensionAngle) }); - AnyObjectPtrArray ElbowPronationPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Elbow.Neutral); + AnyObjectPtrArray ElbowPronationPositions = flatten({ + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxPronationAngle), + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxSupinationAngle) + }); + AnyObjectPtrArray WristFlexionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); AnyObjectPtrArray WristAbductionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); @@ -148,6 +172,16 @@ ArmCalibrationStudy ArmCalibration3Right( &.RangeOfMotion.Right.ShoulderArm.Shoulder.Extended, }); + AnyObjectPtrArray ScapulaElevationPositions = flatten({ + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaElevationAngle), + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaDepressionAngle) + }); + + AnyObjectPtrArray ScapulaProtractionPositions = flatten({ + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaProtractionAngle), + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaRetractionAngle) + }); + AnyObjectPtrArray ElbowFlexionPositions = flatten({ repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxFlexionAngle), repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxExtensionAngle) @@ -203,6 +237,16 @@ ArmCalibrationStudy ArmCalibration4Right( &.RangeOfMotion.Right.ShoulderArm.Shoulder.Extended, }); + AnyObjectPtrArray ScapulaElevationPositions = flatten({ + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaElevationAngle), + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaDepressionAngle) + }); + + AnyObjectPtrArray ScapulaProtractionPositions = flatten({ + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaProtractionAngle), + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaRetractionAngle) + }); + AnyObjectPtrArray ElbowFlexionPositions = flatten({ repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxFlexionAngle), repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxExtensionAngle) @@ -254,6 +298,16 @@ ArmCalibrationStudy ArmCalibration5Right( &.RangeOfMotion.Right.ShoulderArm.Shoulder.Flexed, &.RangeOfMotion.Right.ShoulderArm.Shoulder.Extended, }); + + AnyObjectPtrArray ScapulaElevationPositions = flatten({ + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaElevationAngle), + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaDepressionAngle) + }); + + AnyObjectPtrArray ScapulaProtractionPositions = flatten({ + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaProtractionAngle), + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaRetractionAngle) + }); AnyObjectPtrArray ElbowFlexionPositions = flatten({ repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxFlexionAngle), @@ -315,14 +369,35 @@ ArmCalibrationStudy ArmCalibration6Right( &.RangeOfMotion.Right.ShoulderArm.Shoulder.Extended, }); + AnyObjectPtrArray ScapulaElevationPositions = flatten({ + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaElevationAngle), + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaDepressionAngle) + }); + + AnyObjectPtrArray ScapulaProtractionPositions = flatten({ + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaProtractionAngle), + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaRetractionAngle) + }); + AnyObjectPtrArray ElbowFlexionPositions = flatten({ repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxFlexionAngle), repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxExtensionAngle) }); - AnyObjectPtrArray ElbowPronationPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Elbow.Neutral); - AnyObjectPtrArray WristFlexionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); - AnyObjectPtrArray WristAbductionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); + AnyObjectPtrArray ElbowPronationPositions = flatten({ + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxPronationAngle), + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxSupinationAngle) + }); + + AnyObjectPtrArray WristFlexionPositions = flatten({ + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Wrist.MaxFlexionAngle), + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Wrist.MaxExtensionAngle) + }); + + AnyObjectPtrArray WristAbductionPositions = flatten({ + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Wrist.MaxAbductionAngle), + repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Wrist.MaxAdductionAngle) + }); #if BM_ARM_DETAILED_HAND ModelRef = { #include "DetailedHandDrivers.any" }; diff --git a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any index 564dd21aa..a4f82e7b5 100644 --- a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any +++ b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any @@ -92,6 +92,8 @@ AnyComponentDefinition CDef = {}; #var AnyObjectPtr ShoulderPositions; + #var AnyObjectPtr ScapulaElevationPositions; + #var AnyObjectPtr ScapulaProtractionPositions; #var AnyObjectPtr ElbowFlexionPositions; #var AnyObjectPtr ElbowPronationPositions; #var AnyObjectPtr WristFlexionPositions; @@ -150,7 +152,7 @@ AnyKinMeasure& Hinge = .BodyModelRef.Interface.Side.ScapulaThoraxProtraction; Type = PiecewiseLinear; T = linspace(0,1,SizesOf(Data)[1]); - Data = {Obj2Num(.ElbowFlexionPositions)} * pi/180; + Data = {Obj2Num(.ScapulaProtractionPositions)} * 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.")); }; @@ -159,7 +161,7 @@ AnyKinMeasure& Hinge = .BodyModelRef.Interface.Side.ScapulaThoraxElevation; Type = PiecewiseLinear; T = linspace(0,1,SizesOf(Data)[1]); - Data = {Obj2Num(.ElbowFlexionPositions)} * pi/180; + Data = {Obj2Num(.ScapulaElevationPositions)} * 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.")); }; @@ -244,6 +246,8 @@ ArmCalibrationModel ModelRef(Side=Side, BodyModelRef=BodyModelRef) = { ShoulderPositions = .ShoulderPositions; + ScapulaElevationPositions = .ScapulaElevationPositions; + ScapulaProtractionPositions = .ScapulaProtractionPositions; ElbowFlexionPositions = .ElbowFlexionPositions; ElbowPronationPositions = .ElbowPronationPositions; WristFlexionPositions = .WristFlexionPositions; From d786e57ed02d0f610563146c27cdda558df63437 Mon Sep 17 00:00:00 2001 From: bke Date: Mon, 31 Mar 2025 14:55:52 +0200 Subject: [PATCH 12/29] update calibration template structure --- .../Arm/Calibration/2ParLeftCalStudies.any | 274 +----------- .../Arm/Calibration/2ParRightCalStudies.any | 389 +----------------- .../Arm/Calibration/DetailedHandDrivers.any | 103 ----- .../Calibration/BMDependentObjects.any | 120 ++++++ .../CalibrationStudy.ClassTemplates.any | 296 +++++-------- .../Calibration/2ParRightCalStudies.any | 253 +----------- 6 files changed, 266 insertions(+), 1169 deletions(-) delete mode 100644 Body/AAUHuman/Arm/Calibration/DetailedHandDrivers.any create mode 100644 Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/BMDependentObjects.any diff --git a/Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any b/Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any index 80671a516..70e71965a 100644 --- a/Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any +++ b/Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any @@ -26,277 +26,17 @@ Side = Left, RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - AnyObjectPtrArray ShoulderPositions = .ArmCalibration1Right.ShoulderPositions; - AnyObjectPtrArray ScapulaElevationPositions = .ArmCalibration1Right.ScapulaElevationPositions; - AnyObjectPtrArray ScapulaProtractionPositions = .ArmCalibration1Right.ScapulaProtractionPositions; - AnyObjectPtrArray ElbowFlexionPositions = .ArmCalibration1Right.ElbowFlexionPositions; - AnyObjectPtrArray ElbowPronationPositions = .ArmCalibration1Right.ElbowPronationPositions; - AnyObjectPtrArray WristFlexionPositions = .ArmCalibration1Right.WristFlexionPositions; - AnyObjectPtrArray WristAbductionPositions = .ArmCalibration1Right.WristAbductionPositions; - - #if BM_ARM_DETAILED_HAND - ModelRef = { #include "DetailedHandDrivers.any" }; - #endif - - #if BM_ARM_SHOULDER_RHYTHM - ModelRef = { - // Exclude the shoulder rythm, since the drivers handles all DOFs. - AnyMechObjectExcluder ExcludeShoulderRhythm = - { - Objects = arrcat( - &.Joints.ClaviculaProtractionDriver, - &.Joints.ClaviculaElevationDriver, - ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") - ); - }; - }; - #endif -}; - -ArmCalibrationStudy ArmCalibration2Left( - BodyModelRef = Main.HumanModel.BodyModel, -Side = Left, -) = { - nStep = .ArmCalibration2Right.nStep; - - MuscleArr = ObjSearch( - &..BodyModel.Left.ShoulderArm.Muscles, - { - "Anconeus.*", - "BicepsBrachii.*", - "Brachialis.*", - "Brachioradialis.*", - "Coracobrachialis.*", - "Triceps.*", - }, - "AnyMuscle" - ); - - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - AnyObjectPtrArray ShoulderPositions = .ArmCalibration2Right.ShoulderPositions; - AnyObjectPtrArray ScapulaElevationPositions = .ArmCalibration2Right.ScapulaElevationPositions; - AnyObjectPtrArray ScapulaProtractionPositions = .ArmCalibration2Right.ScapulaProtractionPositions; - AnyObjectPtrArray ElbowFlexionPositions = .ArmCalibration2Right.ElbowFlexionPositions; - AnyObjectPtrArray ElbowPronationPositions = .ArmCalibration2Right.ElbowPronationPositions; - AnyObjectPtrArray WristFlexionPositions = .ArmCalibration2Right.WristFlexionPositions; - AnyObjectPtrArray WristAbductionPositions = .ArmCalibration2Right.WristAbductionPositions; - - #if BM_ARM_DETAILED_HAND - ModelRef = { #include "DetailedHandDrivers.any" }; - #endif - - #if BM_ARM_SHOULDER_RHYTHM - ModelRef = { - // Exclude the shoulder rythm, since the drivers handles all DOFs. - AnyMechObjectExcluder ExcludeShoulderRhythm = { - Objects = arrcat( - &.Joints.ClaviculaProtractionDriver, - &.Joints.ClaviculaElevationDriver, - ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") - ); - }; - }; - #endif -}; - -ArmCalibrationStudy ArmCalibration3Left( - BodyModelRef=Main.HumanModel.BodyModel, -Side=Left, -) = { - nStep = .ArmCalibration3Right.nStep; - - MuscleArr = ObjSearch( - &..BodyModel.Left.ShoulderArm.Muscles, - { - "AbductorPollicis.*", - "FlexorPollicisLongus.*", - }, - "AnyMuscle" - ); - - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - AnyObjectPtrArray ShoulderPositions = .ArmCalibration3Right.ShoulderPositions; - AnyObjectPtrArray ScapulaElevationPositions = .ArmCalibration3Right.ScapulaElevationPositions; - AnyObjectPtrArray ScapulaProtractionPositions = .ArmCalibration3Right.ScapulaProtractionPositions; - AnyObjectPtrArray ElbowFlexionPositions = .ArmCalibration3Right.ElbowFlexionPositions; - AnyObjectPtrArray ElbowPronationPositions = .ArmCalibration3Right.ElbowPronationPositions; - AnyObjectPtrArray WristFlexionPositions = .ArmCalibration3Right.WristFlexionPositions; - AnyObjectPtrArray WristAbductionPositions = .ArmCalibration3Right.WristAbductionPositions; - - #if BM_ARM_DETAILED_HAND - ModelRef = { #include "DetailedHandDrivers.any" }; - #endif - - #if BM_ARM_SHOULDER_RHYTHM - ModelRef = { - // Exclude the shoulder rythm, since the drivers handles all DOFs. - AnyMechObjectExcluder ExcludeShoulderRhythm = { - Objects = arrcat( - &.Joints.ClaviculaProtractionDriver, - &.Joints.ClaviculaElevationDriver, - ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") - ); - }; - }; - #endif + ShoulderPositions = .ArmCalibration1Right.ShoulderPositions; + ScapulaElevationPositions = .ArmCalibration1Right.ScapulaElevationPositions; + ScapulaProtractionPositions = .ArmCalibration1Right.ScapulaProtractionPositions; + ElbowFlexionPositions = .ArmCalibration1Right.ElbowFlexionPositions; + ElbowPronationPositions = .ArmCalibration1Right.ElbowPronationPositions; + WristFlexionPositions = .ArmCalibration1Right.WristFlexionPositions; + WristAbductionPositions = .ArmCalibration1Right.WristAbductionPositions; }; -ArmCalibrationStudy ArmCalibration4Left( -BodyModelRef=Main.HumanModel.BodyModel, -Side=Left, -) = { - nStep = .ArmCalibration4Right.nStep; - - MuscleArr = ObjSearch( - &..BodyModel.Left.ShoulderArm.Muscles, - { - "Rhomboideus.*", - "Sternocleidomastoid.*", - "TeresMajor.*", - "TeresMinor.*", - "TrapeziusClavicular.*", - "TrapeziusScapular.*", - }, - "AnyMuscle" - ); - - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - AnyObjectPtrArray ShoulderPositions = .ArmCalibration4Right.ShoulderPositions; - AnyObjectPtrArray ScapulaElevationPositions = .ArmCalibration4Right.ScapulaElevationPositions; - AnyObjectPtrArray ScapulaProtractionPositions = .ArmCalibration4Right.ScapulaProtractionPositions; - AnyObjectPtrArray ElbowFlexionPositions = .ArmCalibration4Right.ElbowFlexionPositions; - AnyObjectPtrArray ElbowPronationPositions = .ArmCalibration4Right.ElbowPronationPositions; - AnyObjectPtrArray WristFlexionPositions = .ArmCalibration4Right.WristFlexionPositions; - AnyObjectPtrArray WristAbductionPositions = .ArmCalibration4Right.WristAbductionPositions; - - #if BM_ARM_DETAILED_HAND - ModelRef = { #include "DetailedHandDrivers.any" }; - #endif - - #if BM_ARM_SHOULDER_RHYTHM - ModelRef = { - // Exclude the shoulder rythm, since the drivers handles all DOFs. - AnyMechObjectExcluder ExcludeShoulderRhythm = { - Objects = arrcat( - &.Joints.ClaviculaProtractionDriver, - &.Joints.ClaviculaElevationDriver, - ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") - ); - }; - }; - #endif -}; - -ArmCalibrationStudy ArmCalibration5Left( -BodyModelRef=Main.HumanModel.BodyModel, -Side=Left, -) = { - nStep = .ArmCalibration5Right.nStep; - - MuscleArr = ObjSearch( - &..BodyModel.Left.ShoulderArm.Muscles, - { - "PronatorQuadratus.*", - "PronatorTeres.*", - "Supinator.*", - }, - "AnyMuscle" - ); - - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - AnyObjectPtrArray ShoulderPositions = .ArmCalibration5Right.ShoulderPositions; - AnyObjectPtrArray ScapulaElevationPositions = .ArmCalibration5Right.ScapulaElevationPositions; - AnyObjectPtrArray ScapulaProtractionPositions = .ArmCalibration5Right.ScapulaProtractionPositions; - AnyObjectPtrArray ElbowFlexionPositions = .ArmCalibration5Right.ElbowFlexionPositions; - AnyObjectPtrArray ElbowPronationPositions = .ArmCalibration5Right.ElbowPronationPositions; - AnyObjectPtrArray WristFlexionPositions = .ArmCalibration5Right.WristFlexionPositions; - AnyObjectPtrArray WristAbductionPositions = .ArmCalibration5Right.WristAbductionPositions; - - #if BM_ARM_DETAILED_HAND - ModelRef = { #include "DetailedHandDrivers.any" }; - #endif - - #if BM_ARM_SHOULDER_RHYTHM - ModelRef = { - // Exclude the shoulder rythm, since the drivers handles all DOFs. - AnyMechObjectExcluder ExcludeShoulderRhythm = { - Objects = arrcat( - &.Joints.ClaviculaProtractionDriver, - &.Joints.ClaviculaElevationDriver, - ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") - ); - }; - }; - #endif -}; - -ArmCalibrationStudy ArmCalibration6Left( -BodyModelRef=Main.HumanModel.BodyModel, -Side=Left, -) = { - nStep = .ArmCalibration6Right.nStep; - - MuscleArr = ObjSearch( - &..BodyModel.Left.ShoulderArm.Muscles, - { - "ExtensorCarpiRadialis.*", - "ExtensorCarpiUlnaris.*", - "ExtensorDigitiMinimi.*", - "ExtensorDigitorum.*", - "ExtensorIndicis.*", - "ExtensorPollicis.*", - "FlexorCarpiRadialis.*", - "FlexorCarpiUlnaris.*", - "FlexorDigitorumProfundus.*", - "FlexorDigitorumSuperficialis.*", - "PalmarisLongus.*", - }, - "AnyMuscle" - ); - - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - AnyObjectPtrArray ShoulderPositions = .ArmCalibration6Right.ShoulderPositions; - AnyObjectPtrArray ScapulaElevationPositions = .ArmCalibration6Right.ScapulaElevationPositions; - AnyObjectPtrArray ScapulaProtractionPositions = .ArmCalibration6Right.ScapulaProtractionPositions; - AnyObjectPtrArray ElbowFlexionPositions = .ArmCalibration6Right.ElbowFlexionPositions; - AnyObjectPtrArray ElbowPronationPositions = .ArmCalibration6Right.ElbowPronationPositions; - AnyObjectPtrArray WristFlexionPositions = .ArmCalibration6Right.WristFlexionPositions; - AnyObjectPtrArray WristAbductionPositions = .ArmCalibration6Right.WristAbductionPositions; - - #if BM_ARM_DETAILED_HAND - ModelRef = { #include "DetailedHandDrivers.any" }; - #endif - - #if BM_ARM_SHOULDER_RHYTHM - ModelRef = { - // Exclude the shoulder rythm, since the drivers handles all DOFs. - AnyMechObjectExcluder ExcludeShoulderRhythm = { - Objects = arrcat( - &.Joints.ClaviculaProtractionDriver, - &.Joints.ClaviculaElevationDriver, - ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") - ); - }; - }; - #endif -}; CalibrationSequence = { AnyOperation &ArmCal1Left = .ArmCalibration1Left.FiberAndTendonLengthAdjustment; - AnyOperation &ArmCal2Left = .ArmCalibration2Left.FiberAndTendonLengthAdjustment; - AnyOperation &ArmCal3Left = .ArmCalibration3Left.FiberAndTendonLengthAdjustment; - AnyOperation &ArmCal4Left = .ArmCalibration4Left.FiberAndTendonLengthAdjustment; - AnyOperation &ArmCal5Left = .ArmCalibration5Left.FiberAndTendonLengthAdjustment; - AnyOperation &ArmCal6Left = .ArmCalibration6Left.FiberAndTendonLengthAdjustment; }; \ No newline at end of file diff --git a/Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any b/Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any index 5b0a7a20a..afa5a1589 100644 --- a/Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any +++ b/Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any @@ -2,7 +2,7 @@ ArmCalibrationStudy ArmCalibration1Right( BodyModelRef=Main.HumanModel.BodyModel, Side=Right, ) = { - nStep = nPos; + nStep = NumElemOf(ShoulderPositions); MuscleArr = ObjSearch( &..BodyModel.Right.ShoulderArm.Muscles, @@ -25,9 +25,8 @@ ArmCalibrationStudy ArmCalibration1Right( RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - AnyInt nPos = NumElemOf(ShoulderPositions); - AnyObjectPtrArray ShoulderPositions = repmat(2,{ + + ShoulderPositions = repmat(2,{ &.RangeOfMotion.Right.ShoulderArm.Shoulder.Flexed, &.RangeOfMotion.Right.ShoulderArm.Shoulder.Extended, &.RangeOfMotion.Right.ShoulderArm.Shoulder.Abducted, @@ -42,387 +41,29 @@ ArmCalibrationStudy ArmCalibration1Right( &.RangeOfMotion.Right.ShoulderArm.Shoulder.FlexedAndAbducted, }); - AnyObjectPtrArray ScapulaElevationPositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaElevationAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaDepressionAngle) - }); - - AnyObjectPtrArray ScapulaProtractionPositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaProtractionAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaRetractionAngle) - }); - - AnyObjectPtrArray ElbowFlexionPositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxFlexionAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxExtensionAngle) + ScapulaElevationPositions = flatten({ + repmat(round(nStep/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaElevationAngle), + repmat(round(nStep/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaDepressionAngle) }); - - AnyObjectPtrArray ElbowPronationPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Elbow.Neutral); - AnyObjectPtrArray WristFlexionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); - AnyObjectPtrArray WristAbductionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); - - #if BM_ARM_DETAILED_HAND - ModelRef = { #include "DetailedHandDrivers.any" }; - #endif - - #if BM_ARM_SHOULDER_RHYTHM - ModelRef = { - // Exclude the shoulder rythm, since the drivers handles all DOFs. - AnyMechObjectExcluder ExcludeShoulderRhythm ={ - Objects = arrcat( - &.Joints.ClaviculaProtractionDriver, - &.Joints.ClaviculaElevationDriver, - ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") - ); - }; - }; - #endif -}; - -ArmCalibrationStudy ArmCalibration2Right( - BodyModelRef=Main.HumanModel.BodyModel, - Side=Right, -) = { - nStep = nPos; - - MuscleArr = ObjSearch( - &..BodyModel.Right.ShoulderArm.Muscles, - { - "Anconeus.*", - "BicepsBrachii.*", - "Brachialis.*", - "Brachioradialis.*", - "Coracobrachialis.*", - "Triceps.*", - }, - "AnyMuscle" - ); - - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - AnyInt nPos = NumElemOf(ShoulderPositions); - AnyObjectPtrArray ShoulderPositions = repmat(2,{ - &.RangeOfMotion.Right.ShoulderArm.Shoulder.Flexed, - &.RangeOfMotion.Right.ShoulderArm.Shoulder.Extended, - }); - - AnyObjectPtrArray ScapulaElevationPositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaElevationAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaDepressionAngle) + ScapulaProtractionPositions = flatten({ + repmat(round(nStep/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaProtractionAngle), + repmat(round(nStep/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaRetractionAngle) }); - AnyObjectPtrArray ScapulaProtractionPositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaProtractionAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaRetractionAngle) + ElbowFlexionPositions = flatten({ + repmat(round(nStep/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxFlexionAngle), + repmat(round(nStep/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxExtensionAngle) }); - AnyObjectPtrArray ElbowFlexionPositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxFlexionAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxExtensionAngle) - }); + ElbowPronationPositions = repmat(nStep, &.RangeOfMotion.Right.ShoulderArm.Elbow.Neutral); + WristFlexionPositions = repmat(nStep, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); + WristAbductionPositions = repmat(nStep, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); - AnyObjectPtrArray ElbowPronationPositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxPronationAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxSupinationAngle) - }); - - AnyObjectPtrArray WristFlexionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); - AnyObjectPtrArray WristAbductionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); - - #if BM_ARM_DETAILED_HAND - ModelRef = { #include "DetailedHandDrivers.any" }; - #endif - - #if BM_ARM_SHOULDER_RHYTHM - ModelRef = { - // Exclude the shoulder rythm, since the drivers handles all DOFs. - AnyMechObjectExcluder ExcludeShoulderRhythm = { - Objects = arrcat( - &.Joints.ClaviculaProtractionDriver, - &.Joints.ClaviculaElevationDriver, - ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") - ); - }; - }; - #endif }; -ArmCalibrationStudy ArmCalibration3Right( - BodyModelRef=Main.HumanModel.BodyModel, - Side=Right, -) = { - nStep = nPos; - - MuscleArr = ObjSearch( - &..BodyModel.Right.ShoulderArm.Muscles, - { - "AbductorPollicis.*", - "FlexorPollicisLongus.*", - }, - "AnyMuscle" - ); - - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - AnyInt nPos = NumElemOf(ShoulderPositions); - AnyObjectPtrArray ShoulderPositions = repmat(2,{ - &.RangeOfMotion.Right.ShoulderArm.Shoulder.Flexed, - &.RangeOfMotion.Right.ShoulderArm.Shoulder.Extended, - }); - - AnyObjectPtrArray ScapulaElevationPositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaElevationAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaDepressionAngle) - }); - - AnyObjectPtrArray ScapulaProtractionPositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaProtractionAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaRetractionAngle) - }); - - AnyObjectPtrArray ElbowFlexionPositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxFlexionAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxExtensionAngle) - }); - - AnyObjectPtrArray ElbowPronationPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Elbow.Neutral); - AnyObjectPtrArray WristFlexionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); - AnyObjectPtrArray WristAbductionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); - - #if BM_ARM_DETAILED_HAND - ModelRef = { #include "DetailedHandDrivers.any" }; - #endif - - #if BM_ARM_SHOULDER_RHYTHM - ModelRef = { - // Exclude the shoulder rythm, since the drivers handles all DOFs. - AnyMechObjectExcluder ExcludeShoulderRhythm = { - Objects = arrcat( - &.Joints.ClaviculaProtractionDriver, - &.Joints.ClaviculaElevationDriver, - ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") - ); - }; - }; - #endif -}; - -ArmCalibrationStudy ArmCalibration4Right( - BodyModelRef=Main.HumanModel.BodyModel, - Side=Right, -) = { - nStep = nPos; - - MuscleArr = ObjSearch( - &..BodyModel.Right.ShoulderArm.Muscles, - { - "Rhomboideus.*", - "Sternocleidomastoid.*", - "TeresMajor.*", - "TeresMinor.*", - "TrapeziusClavicular.*", - "TrapeziusScapular.*", - }, - "AnyMuscle" - ); - - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - AnyInt nPos = NumElemOf(ShoulderPositions); - AnyObjectPtrArray ShoulderPositions = repmat(2,{ - &.RangeOfMotion.Right.ShoulderArm.Shoulder.Flexed, - &.RangeOfMotion.Right.ShoulderArm.Shoulder.Extended, - }); - - AnyObjectPtrArray ScapulaElevationPositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaElevationAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaDepressionAngle) - }); - - AnyObjectPtrArray ScapulaProtractionPositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaProtractionAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaRetractionAngle) - }); - - AnyObjectPtrArray ElbowFlexionPositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxFlexionAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxExtensionAngle) - }); - - AnyObjectPtrArray ElbowPronationPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Elbow.Neutral); - AnyObjectPtrArray WristFlexionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); - AnyObjectPtrArray WristAbductionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); - - #if BM_ARM_DETAILED_HAND - ModelRef = { #include "DetailedHandDrivers.any" }; - #endif - - #if BM_ARM_SHOULDER_RHYTHM - ModelRef = { - // Exclude the shoulder rythm, since the drivers handles all DOFs. - AnyMechObjectExcluder ExcludeShoulderRhythm = { - Objects = arrcat( - &.Joints.ClaviculaProtractionDriver, - &.Joints.ClaviculaElevationDriver, - ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") - ); - }; - }; - #endif -}; - -ArmCalibrationStudy ArmCalibration5Right( - BodyModelRef=Main.HumanModel.BodyModel, - Side=Right, -) = { - nStep = nPos; - - MuscleArr = ObjSearch( - &..BodyModel.Right.ShoulderArm.Muscles, - { - "PronatorQuadratus.*", - "PronatorTeres.*", - "Supinator.*", - }, - "AnyMuscle" - ); - - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - AnyInt nPos = NumElemOf(ShoulderPositions); - AnyObjectPtrArray ShoulderPositions = repmat(2,{ - &.RangeOfMotion.Right.ShoulderArm.Shoulder.Flexed, - &.RangeOfMotion.Right.ShoulderArm.Shoulder.Extended, - }); - - AnyObjectPtrArray ScapulaElevationPositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaElevationAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaDepressionAngle) - }); - - AnyObjectPtrArray ScapulaProtractionPositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaProtractionAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaRetractionAngle) - }); - - AnyObjectPtrArray ElbowFlexionPositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxFlexionAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxExtensionAngle) - }); - - AnyObjectPtrArray ElbowPronationPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Elbow.Neutral); - AnyObjectPtrArray WristFlexionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); - AnyObjectPtrArray WristAbductionPositions = repmat(nPos, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); - - #if BM_ARM_DETAILED_HAND - ModelRef = { #include "DetailedHandDrivers.any" }; - #endif - - #if BM_ARM_SHOULDER_RHYTHM - ModelRef = { - // Exclude the shoulder rythm, since the drivers handles all DOFs. - AnyMechObjectExcluder ExcludeShoulderRhythm = { - Objects = arrcat( - &.Joints.ClaviculaProtractionDriver, - &.Joints.ClaviculaElevationDriver, - ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") - ); - }; - }; - #endif -}; - -ArmCalibrationStudy ArmCalibration6Right( - BodyModelRef=Main.HumanModel.BodyModel, - Side=Right, -) = { - nStep = nPos; - - MuscleArr = ObjSearch( - &..BodyModel.Right.ShoulderArm.Muscles, - { - "ExtensorCarpiRadialis.*", - "ExtensorCarpiUlnaris.*", - "ExtensorDigitiMinimi.*", - "ExtensorDigitorum.*", - "ExtensorIndicis.*", - "ExtensorPollicis.*", - "FlexorCarpiRadialis.*", - "FlexorCarpiUlnaris.*", - "FlexorDigitorumProfundus.*", - "FlexorDigitorumSuperficialis.*", - "PalmarisLongus.*", - }, - "AnyMuscle" - ); - - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - AnyInt nPos = NumElemOf(ShoulderPositions); - AnyObjectPtrArray ShoulderPositions = repmat(2,{ - &.RangeOfMotion.Right.ShoulderArm.Shoulder.Flexed, - &.RangeOfMotion.Right.ShoulderArm.Shoulder.Extended, - }); - - AnyObjectPtrArray ScapulaElevationPositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaElevationAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaDepressionAngle) - }); - - AnyObjectPtrArray ScapulaProtractionPositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaProtractionAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaRetractionAngle) - }); - - AnyObjectPtrArray ElbowFlexionPositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxFlexionAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxExtensionAngle) - }); - - AnyObjectPtrArray ElbowPronationPositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxPronationAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxSupinationAngle) - }); - - AnyObjectPtrArray WristFlexionPositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Wrist.MaxFlexionAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Wrist.MaxExtensionAngle) - }); - - AnyObjectPtrArray WristAbductionPositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Wrist.MaxAbductionAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.ShoulderArm.Wrist.MaxAdductionAngle) - }); - - #if BM_ARM_DETAILED_HAND - ModelRef = { #include "DetailedHandDrivers.any" }; - #endif - - #if BM_ARM_SHOULDER_RHYTHM - ModelRef = { - // Exclude the shoulder rythm, since the drivers handles all DOFs. - AnyMechObjectExcluder ExcludeShoulderRhythm = { - Objects = arrcat( - &.Joints.ClaviculaProtractionDriver, - &.Joints.ClaviculaElevationDriver, - ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") - ); - }; - }; - #endif -}; CalibrationSequence = { AnyOperation &ArmCal1Right = .ArmCalibration1Right.FiberAndTendonLengthAdjustment; - AnyOperation &ArmCal2Right = .ArmCalibration2Right.FiberAndTendonLengthAdjustment; - AnyOperation &ArmCal3Right = .ArmCalibration3Right.FiberAndTendonLengthAdjustment; - AnyOperation &ArmCal4Right = .ArmCalibration4Right.FiberAndTendonLengthAdjustment; - AnyOperation &ArmCal5Right = .ArmCalibration5Right.FiberAndTendonLengthAdjustment; - AnyOperation &ArmCal6Right = .ArmCalibration6Right.FiberAndTendonLengthAdjustment; }; \ No newline at end of file diff --git a/Body/AAUHuman/Arm/Calibration/DetailedHandDrivers.any b/Body/AAUHuman/Arm/Calibration/DetailedHandDrivers.any deleted file mode 100644 index c312ce9ce..000000000 --- a/Body/AAUHuman/Arm/Calibration/DetailedHandDrivers.any +++ /dev/null @@ -1,103 +0,0 @@ -// Finger constraints for the detailed hand model in calibration studies -AnyKinEqSimpleDriver CMC1Flexion = { - AnyRevoluteJoint &ref = .Segments.Hand.Finger1.Jnt.CMCFlexion; - DriverPos = {0}*pi/180; - DriverVel = {0}; -}; - -AnyKinEqSimpleDriver CMC1Abduction = { - AnyRevoluteJoint &ref = .Segments.Hand.Finger1.Jnt.CMCAbduction; - DriverPos = {0}*pi/180; - DriverVel = {0}; -}; - -AnyKinEqSimpleDriver MCP1Flexion = { - AnyRevoluteJoint &ref = .Segments.Hand.Finger1.Jnt.MCPFlexion; - DriverPos = {0}*pi/180; - DriverVel = {0}; -}; - -AnyKinEqSimpleDriver MCP1Abduction= -{ - AnyRevoluteJoint &ref = .Segments.Hand.Finger1.Jnt.MCPAbduction; - DriverPos = {0}*pi/180; - DriverVel = {0}; -}; - -AnyKinEqSimpleDriver DIP1 = { - AnyRevoluteJoint &ref = .Segments.Hand.Finger1.Jnt.DIP; - DriverPos = {0}*pi/180; - DriverVel = {0}; -}; - -AnyKinEqSimpleDriver MCP2= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger2.Jnt.MCP; - DriverPos= {0}*pi/180; - DriverVel= {0}; -}; - -AnyKinEqSimpleDriver PIP2= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger2.Jnt.PIP; - DriverPos= {0}*pi/180; - DriverVel= {0}; -}; - -AnyKinEqSimpleDriver DIP2= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger2.Jnt.DIP; - DriverPos= {0}; - DriverVel= {0}; -}; - -AnyKinEqSimpleDriver MCP3= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger3.Jnt.MCP; - DriverPos= {0}*pi/180; - DriverVel= {0}; -}; - -AnyKinEqSimpleDriver PIP3= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger3.Jnt.PIP; - DriverPos= {0}*pi/180; - DriverVel= {0}; -}; - -AnyKinEqSimpleDriver DIP3= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger3.Jnt.DIP; - DriverPos= {0}; - DriverVel= {0}; -}; - -AnyKinEqSimpleDriver MCP4= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger4.Jnt.MCP; - DriverPos= {0}*pi/180; - DriverVel= {0}; -}; - -AnyKinEqSimpleDriver PIP4= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger4.Jnt.PIP; - DriverPos= {0}*pi/180; - DriverVel= {0}; -}; - -AnyKinEqSimpleDriver DIP4= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger4.Jnt.DIP; - DriverPos= {0}*pi/180; - DriverVel= {0}; -}; - -AnyKinEqSimpleDriver MCP5= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger5.Jnt.MCP; - DriverPos= {0}*pi/180; - DriverVel= {0}; -}; - -AnyKinEqSimpleDriver PIP5= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger5.Jnt.PIP; - DriverPos= {0}*pi/180; - DriverVel= {0}; -}; - -AnyKinEqSimpleDriver DIP5= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger5.Jnt.DIP; - DriverPos= {0}; - DriverVel= {0}; -}; \ No newline at end of file diff --git a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/BMDependentObjects.any b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/BMDependentObjects.any new file mode 100644 index 000000000..faaf6e304 --- /dev/null +++ b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/BMDependentObjects.any @@ -0,0 +1,120 @@ +/* + File containing the BM dependent objects for the calibration studies. +*/ + +/// Mech Objects for the shoulder rythm. +/// These are excluded from the calibration (if found) +/// since the calibration drivers handles all DOFs. +AnyMechObjectExcluder ExcludeShoulderRhythm = { + Objects = arrcat( + ObjSearch(&.Joints, "ClaviculaProtractionDriver"), + ObjSearch(&.Joints, "ClaviculaElevationDriver"), + ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") + ); +}; + +#if BM_ARM_DETAILED_HAND + // Finger constraints for the detailed hand model in calibration studies + AnyKinEqSimpleDriver CMC1Flexion = { + AnyRevoluteJoint &ref = .Segments.Hand.Finger1.Jnt.CMCFlexion; + DriverPos = {0}*pi/180; + DriverVel = {0}; + }; + + AnyKinEqSimpleDriver CMC1Abduction = { + AnyRevoluteJoint &ref = .Segments.Hand.Finger1.Jnt.CMCAbduction; + DriverPos = {0}*pi/180; + DriverVel = {0}; + }; + + AnyKinEqSimpleDriver MCP1Flexion = { + AnyRevoluteJoint &ref = .Segments.Hand.Finger1.Jnt.MCPFlexion; + DriverPos = {0}*pi/180; + DriverVel = {0}; + }; + + AnyKinEqSimpleDriver MCP1Abduction= + { + AnyRevoluteJoint &ref = .Segments.Hand.Finger1.Jnt.MCPAbduction; + DriverPos = {0}*pi/180; + DriverVel = {0}; + }; + + AnyKinEqSimpleDriver DIP1 = { + AnyRevoluteJoint &ref = .Segments.Hand.Finger1.Jnt.DIP; + DriverPos = {0}*pi/180; + DriverVel = {0}; + }; + + AnyKinEqSimpleDriver MCP2= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger2.Jnt.MCP; + DriverPos= {0}*pi/180; + DriverVel= {0}; + }; + + AnyKinEqSimpleDriver PIP2= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger2.Jnt.PIP; + DriverPos= {0}*pi/180; + DriverVel= {0}; + }; + + AnyKinEqSimpleDriver DIP2= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger2.Jnt.DIP; + DriverPos= {0}; + DriverVel= {0}; + }; + + AnyKinEqSimpleDriver MCP3= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger3.Jnt.MCP; + DriverPos= {0}*pi/180; + DriverVel= {0}; + }; + + AnyKinEqSimpleDriver PIP3= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger3.Jnt.PIP; + DriverPos= {0}*pi/180; + DriverVel= {0}; + }; + + AnyKinEqSimpleDriver DIP3= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger3.Jnt.DIP; + DriverPos= {0}; + DriverVel= {0}; + }; + + AnyKinEqSimpleDriver MCP4= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger4.Jnt.MCP; + DriverPos= {0}*pi/180; + DriverVel= {0}; + }; + + AnyKinEqSimpleDriver PIP4= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger4.Jnt.PIP; + DriverPos= {0}*pi/180; + DriverVel= {0}; + }; + + AnyKinEqSimpleDriver DIP4= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger4.Jnt.DIP; + DriverPos= {0}*pi/180; + DriverVel= {0}; + }; + + AnyKinEqSimpleDriver MCP5= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger5.Jnt.MCP; + DriverPos= {0}*pi/180; + DriverVel= {0}; + }; + + AnyKinEqSimpleDriver PIP5= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger5.Jnt.PIP; + DriverPos= {0}*pi/180; + DriverVel= {0}; + }; + + AnyKinEqSimpleDriver DIP5= { + AnyRevoluteJoint &ref = .Segments.Hand.Finger5.Jnt.DIP; + DriverPos= {0}; + DriverVel= {0}; + }; +#endif \ No newline at end of file diff --git a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any index a4f82e7b5..3e287b1eb 100644 --- a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any +++ b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any @@ -1,20 +1,9 @@ -/** - 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; + +#class_template TrunkCalibrationModel(Side, BodyModelRef) { AnyFolder &TrunkSegments = BodyModelRef.Trunk.Segments; AnyFolder &TrunkJoints = BodyModelRef.Trunk.Joints; - AnyFolder &LegSegments = BodyModelRef.Side.Leg.Seg; - AnyFolder &LegJoints = BodyModelRef.Side.Leg.Jnt; - // Constraints AnyFixedRefFrame ground = { AnyRefNode node = { @@ -43,167 +32,43 @@ AnyRefFrame &Pelvis = ..TrunkSegments.PelvisSeg; }; }; - - 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 a model that can be used to calibrate the arms -*/ -#class_template ArmCalibrationModel(Side, BodyModelRef) { - AnyComponentDefinition CDef = {}; - - #var AnyObjectPtr ShoulderPositions; - #var AnyObjectPtr ScapulaElevationPositions; - #var AnyObjectPtr ScapulaProtractionPositions; - #var AnyObjectPtr ElbowFlexionPositions; - #var AnyObjectPtr ElbowPronationPositions; - #var AnyObjectPtr WristFlexionPositions; - #var AnyObjectPtr WristAbductionPositions; - - AnyFolder &TrunkSegments = BodyModelRef.Trunk.Segments; - AnyFolder &TrunkJoints = BodyModelRef.Trunk.Joints; - - AnyFolder &Segments = BodyModelRef.Side.ShoulderArm.Segments; - AnyFolder &Joints = BodyModelRef.Side.ShoulderArm.Joints; - // The Muscles folder contain segments and constraints for some wrapping muscles - // e.g. Deltoid, Pectoralis Minor, etc. - AnyFolder &Muscles = BodyModelRef.Side.ShoulderArm.Muscles; - - // Constraints - AnyFixedRefFrame ground = { - AnyRefNode node = { - ARel = ..TrunkSegments.PelvisSeg.Axes0; - sRel = ..TrunkSegments.PelvisSeg.r0; - }; - }; - - AnyKinEq ThoraxFix = { - AnyKinMeasure& PelvisThoraxExtension = BodyModelRef.Interface.Trunk.PelvisThoraxExtension; - AnyKinMeasure& PelvisThoraxLateralBending = BodyModelRef.Interface.Trunk.PelvisThoraxLateralBending; - AnyKinMeasure& PelvisThoraxRotation = BodyModelRef.Interface.Trunk.PelvisThoraxRotation; - AnyKinMeasure& SkullThoraxFlexion = BodyModelRef.Interface.Trunk.SkullThoraxFlexion; - AnyKinMeasure& SkullThoraxRotation = BodyModelRef.Interface.Trunk.SkullThoraxRotation; - AnyKinMeasure& SkullThoraxLateralBending = BodyModelRef.Interface.Trunk.SkullThoraxLateralBending; - }; - - AnyKinEq PelvisFix = { - AnyKinLinear Lin = { - AnyRefFrame &ground = ..ground.node; - AnyRefFrame &Pelvis = ..TrunkSegments.PelvisSeg; - }; - AnyKinRotational Rot = { - Type = RotAxesAngles; - AnyRefFrame &ground = ..ground.node; - AnyRefFrame &Pelvis = ..TrunkSegments.PelvisSeg; - }; - }; - - - AnyKinEqInterPolDriver Shoulder = { - AnyKinRotational &Spherical = .BodyModelRef.Interface.Side.GlenohumeralFlexion.GHMeasure; - Type = PiecewiseLinear; - T = linspace(0,1,SizesOf(Data)[1]); - Data = Obj2Num(.ShoulderPositions)' * 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 ScapulaProtraction = { - AnyKinMeasure& Hinge = .BodyModelRef.Interface.Side.ScapulaThoraxProtraction; - Type = PiecewiseLinear; - T = linspace(0,1,SizesOf(Data)[1]); - Data = {Obj2Num(.ScapulaProtractionPositions)} * 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 ScapulaElevation = { - AnyKinMeasure& Hinge = .BodyModelRef.Interface.Side.ScapulaThoraxElevation; - Type = PiecewiseLinear; - T = linspace(0,1,SizesOf(Data)[1]); - Data = {Obj2Num(.ScapulaElevationPositions)} * 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 to create a driver for a single-DoF measure in a calibration study. +*/ +#class_template SingleDoFCalDriver( + __CLASS__ = AnyKinEqInterPolDriver, + Measure, + DriverData +) { + Type = PiecewiseLinear; + T = linspace(0,1,SizesOf(Data)[1]); + Reaction.Type = repmat(nDim, Off); + Data = {Obj2Num(DriverData)} * pi/180; + AnyKinMeasure& MeasureRef = Measure; + 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 ElbowFlexion = { - AnyKinMeasure& Hinge = .BodyModelRef.Interface.Side.ElbowFlexion; - Type = PiecewiseLinear; - T = linspace(0,1,SizesOf(Data)[1]); - Data = {Obj2Num(.ElbowFlexionPositions)} * 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 ElbowPronation = { - AnyKinMeasure& Hinge = .BodyModelRef.Interface.Side.ElbowPronation; - Type = PiecewiseLinear; - T = linspace(0,1,SizesOf(Data)[1]); - Data = {Obj2Num(.ElbowPronationPositions)} * 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 WristFlexion = { - AnyKinMeasure& Hinge = .BodyModelRef.Interface.Side.WristFlexion; - Type = PiecewiseLinear; - T = linspace(0,1,SizesOf(Data)[1]); - Data = {Obj2Num(.WristFlexionPositions)} * 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 WristAbduction = { - AnyKinMeasure& Hinge = .BodyModelRef.Interface.Side.WristAbduction; - Type = PiecewiseLinear; - T = linspace(0,1,SizesOf(Data)[1]); - Data = {Obj2Num(.WristAbductionPositions)} * 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 to create a driver for a multi-DoF measure in a calibration study. +*/ +#class_template MultiDoFCalDriver( + __CLASS__ = AnyKinEqInterPolDriver, + Measure, + DriverData +) { + Type = PiecewiseLinear; + T = linspace(0,1,SizesOf(Data)[1]); + Reaction.Type = repmat(nDim, Off); + Data = Obj2Num(DriverData)' * pi/180; ///< TODO: Refactor the data structure to join the template with the single-DoF version! + AnyKinMeasure& MeasureRef = Measure; + 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 */ @@ -219,12 +84,35 @@ Kinematics.PosAnalysisOnlyOnOff = On; InitialConditions.PosAnalysisOnlyOnOff = On; - LegCalibrationModel ModelRef(Side=Side, BodyModelRef=BodyModelRef) = { - HipPositions = .HipPositions; - KneePositions = .KneePositions; - AnklePositions = .AnklePositions; - SubTalarPositions = .SubTalarPositions; - }; + #var AnyObjectPtr HipPositions; + #var AnyObjectPtr KneePositions; + #var AnyObjectPtr AnklePositions; + #var AnyObjectPtr SubTalarPositions; + + AnyFolder &Segments = BodyModelRef.Side.Leg.Seg; + AnyFolder &Joints = BodyModelRef.Side.Leg.Jnt; + + TrunkCalibrationModel TrunkModel(Side = Side, BodyModelRef = BodyModelRef) = {}; + + MultiDoFCalDriver Hip( + Measure = BodyModelRef.Interface.Side.HipFlexion.HipMeasure, + DriverData = .HipPositions + ) ={}; + + SingleDoFCalDriver Knee( + Measure = BodyModelRef.Interface.Side.KneeFlexion, + DriverData = .KneePositions + ) ={}; + + SingleDoFCalDriver Ankle( + Measure = BodyModelRef.Interface.Side.AnklePlantarFlexion, + DriverData = .AnklePositions + ) ={}; + + SingleDoFCalDriver SubTalar( + Measure = BodyModelRef.Interface.Side.SubTalarEversion, + DriverData = .SubTalarPositions + ) ={}; }; @@ -244,13 +132,57 @@ Kinematics.PosAnalysisOnlyOnOff = On; InitialConditions.PosAnalysisOnlyOnOff = On; - ArmCalibrationModel ModelRef(Side=Side, BodyModelRef=BodyModelRef) = { - ShoulderPositions = .ShoulderPositions; - ScapulaElevationPositions = .ScapulaElevationPositions; - ScapulaProtractionPositions = .ScapulaProtractionPositions; - ElbowFlexionPositions = .ElbowFlexionPositions; - ElbowPronationPositions = .ElbowPronationPositions; - WristFlexionPositions = .WristFlexionPositions; - WristAbductionPositions = .WristAbductionPositions; - }; + #var AnyObjectPtr ShoulderPositions; + #var AnyObjectPtr ScapulaElevationPositions; + #var AnyObjectPtr ScapulaProtractionPositions; + #var AnyObjectPtr ElbowFlexionPositions; + #var AnyObjectPtr ElbowPronationPositions; + #var AnyObjectPtr WristFlexionPositions; + #var AnyObjectPtr WristAbductionPositions; + + AnyFolder &Segments = BodyModelRef.Side.ShoulderArm.Segments; + AnyFolder &Joints = BodyModelRef.Side.ShoulderArm.Joints; + + // The Muscles folder contain segments and constraints for some wrapping muscles + // e.g. Deltoid, Pectoralis Minor, etc. + AnyFolder &Muscles = BodyModelRef.Side.ShoulderArm.Muscles; + + TrunkCalibrationModel TrunkModel(Side = Side, BodyModelRef = BodyModelRef) = {}; + + MultiDoFCalDriver Shoulder( + Measure = BodyModelRef.Interface.Side.GlenohumeralFlexion.GHMeasure, + DriverData = .ShoulderPositions + ) ={}; + + SingleDoFCalDriver ScapulaProtraction( + Measure = BodyModelRef.Interface.Side.ScapulaThoraxProtraction, + DriverData = .ScapulaProtractionPositions + ) ={}; + + SingleDoFCalDriver ScapulaElevation( + Measure = BodyModelRef.Interface.Side.ScapulaThoraxElevation, + DriverData = .ScapulaElevationPositions + ) ={}; + + SingleDoFCalDriver ElbowFlexion( + Measure = BodyModelRef.Interface.Side.ElbowFlexion, + DriverData = .ElbowFlexionPositions + ) ={}; + + SingleDoFCalDriver ElbowPronation( + Measure = BodyModelRef.Interface.Side.ElbowPronation, + DriverData = .ElbowPronationPositions + ) ={}; + + SingleDoFCalDriver WristFlexion( + Measure = BodyModelRef.Interface.Side.WristFlexion, + DriverData = .WristFlexionPositions + ) ={}; + + SingleDoFCalDriver WristAbduction( + Measure = BodyModelRef.Interface.Side.WristAbduction, + DriverData = .WristAbductionPositions + ) ={}; + + #include "BMDependentObjects.any" }; diff --git a/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any b/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any index 605235ca2..6f9d0e451 100644 --- a/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any +++ b/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any @@ -1,8 +1,8 @@ -LegCalibrationStudy LegCalibration1Right( +LegCalibrationStudy RightCal1Hip( BodyModelRef=Main.HumanModel.BodyModel, Side=Right, ) = { - nStep = nPos; + nStep = NumElemOf(HipPositions); MuscleArr = ObjSearch( &..BodyModel.Right.Leg.Mus, @@ -19,9 +19,8 @@ LegCalibrationStudy LegCalibration1Right( RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - AnyInt nPos = NumElemOf(HipPositions); - AnyObjectPtrArray HipPositions = repmat(2,{ + + HipPositions = repmat(2,{ &.RangeOfMotion.Right.Leg.Hip.InternallyRotated, &.RangeOfMotion.Right.Leg.Hip.Adduction, &.RangeOfMotion.Right.Leg.Hip.Abduction, @@ -31,247 +30,15 @@ LegCalibrationStudy LegCalibration1Right( &.RangeOfMotion.Right.Leg.Hip.ExtendedAndAdducted, }); - AnyObjectPtrArray KneePositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.Leg.Knee.MaxFlexionAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.Leg.Knee.MaxExtensionAngle) - }); - AnyObjectPtrArray AnklePositions = repmat(nPos, &.RangeOfMotion.Right.Leg.Ankle.Neutral); - AnyObjectPtrArray SubTalarPositions = repmat(nPos, &.RangeOfMotion.Right.Leg.Ankle.Neutral); -}; - -LegCalibrationStudy LegCalibration2Right( - BodyModelRef=Main.HumanModel.BodyModel, - Side=Right, -) = { - nStep = nPos; - - MuscleArr = ObjSearch( - &..BodyModel.Right.Leg.Mus, - { - "Gluteus*.*", - "Piriformis.*", - "Gemellus.*", - "Obturator*.*", - "QuadratusFem*.*", - }, - "AnyMuscle" - ); - - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - AnyInt nPos = NumElemOf(HipPositions); - AnyObjectPtrArray HipPositions = repmat(2,{ - &.RangeOfMotion.Right.Leg.Hip.InternallyRotated, - &.RangeOfMotion.Right.Leg.Hip.Adduction, - &.RangeOfMotion.Right.Leg.Hip.FlexedAndAdducted, - &.RangeOfMotion.Right.Leg.Hip.Flexed, - &.RangeOfMotion.Right.Leg.Hip.FlexedAndAbducted, - &.RangeOfMotion.Right.Leg.Hip.AbductedAndExternallyRotated, - &.RangeOfMotion.Right.Leg.Hip.Extended, - &.RangeOfMotion.Right.Leg.Hip.ExtendedAndAdducted, - &.RangeOfMotion.Right.Leg.Hip.ExternallyRotated, + KneePositions = flatten({ + repmat(round(nStep/2), &.RangeOfMotion.Right.Leg.Knee.MaxFlexionAngle), + repmat(round(nStep/2), &.RangeOfMotion.Right.Leg.Knee.MaxExtensionAngle) }); - AnyObjectPtrArray KneePositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.Leg.Knee.MaxFlexionAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.Leg.Knee.MaxExtensionAngle) - }); - AnyObjectPtrArray AnklePositions = repmat(nPos, &.RangeOfMotion.Right.Leg.Ankle.Neutral); - AnyObjectPtrArray SubTalarPositions = repmat(nPos, &.RangeOfMotion.Right.Leg.Ankle.Neutral); + AnklePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); + SubTalarPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); }; -LegCalibrationStudy LegCalibration3Right( - BodyModelRef=Main.HumanModel.BodyModel, - Side=Right, -) = { - nStep = nPos; - - MuscleArr = ObjSearch( - {&..BodyModel.Right.Leg.Mus, &..BodyModel.Trunk.Muscles.Right,}, - { - "Iliacus*.*", - "Psoas*.*", - }, - "AnyMuscle" - ); - - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - AnyInt nPos = NumElemOf(HipPositions); - AnyObjectPtrArray HipPositions = repmat(2,{ - &.RangeOfMotion.Right.Leg.Hip.FlexedAndAdducted, - &.RangeOfMotion.Right.Leg.Hip.Flexed, - &.RangeOfMotion.Right.Leg.Hip.Extended, - &.RangeOfMotion.Right.Leg.Hip.ExtendedAndAdducted, - }); - AnyObjectPtrArray KneePositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.Leg.Knee.MaxFlexionAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.Leg.Knee.MaxExtensionAngle) - }); - AnyObjectPtrArray AnklePositions = repmat(nPos, &.RangeOfMotion.Right.Leg.Ankle.Neutral); - AnyObjectPtrArray SubTalarPositions = repmat(nPos, &.RangeOfMotion.Right.Leg.Ankle.Neutral); -}; - -LegCalibrationStudy LegCalibration4Right( - BodyModelRef=Main.HumanModel.BodyModel, - Side=Right, -) = { - nStep = nPos; - - MuscleArr = ObjSearch( - &..BodyModel.Right.Leg.Mus, - { - "RectusFem*.*", - "BicepsFem*.*", - "Semitend*.*", - "Semimem*.*", - "Sartorius.*", - }, - "AnyMuscle" - ); - - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - AnyInt nPos = NumElemOf(HipPositions); - AnyObjectPtrArray HipPositions = repmat(2,{ - &.RangeOfMotion.Right.Leg.Hip.FlexedAndAdducted, - &.RangeOfMotion.Right.Leg.Hip.FlexedAndAbducted, - &.RangeOfMotion.Right.Leg.Hip.AbductedAndExternallyRotated, - &.RangeOfMotion.Right.Leg.Hip.Extended, - &.RangeOfMotion.Right.Leg.Hip.ExtendedAndAdducted, - &.RangeOfMotion.Right.Leg.Hip.ExternallyRotated, - }); - AnyObjectPtrArray KneePositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.Leg.Knee.MaxFlexionAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.Leg.Knee.MaxExtensionAngle) - }); - AnyObjectPtrArray AnklePositions = repmat(nPos, &.RangeOfMotion.Right.Leg.Ankle.Neutral); - AnyObjectPtrArray SubTalarPositions = repmat(nPos, &.RangeOfMotion.Right.Leg.Ankle.Neutral); -}; - -LegCalibrationStudy LegCalibration5Right( - BodyModelRef=Main.HumanModel.BodyModel, - Side=Right, -) = { - nStep = nPos; - - MuscleArr = ObjSearch( - &..BodyModel.Right.Leg.Mus, - { - "Vastus*.*", - "Popliteus.*", - }, - "AnyMuscle" - ); - - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - AnyInt nPos = NumElemOf(HipPositions); - AnyObjectPtrArray HipPositions = repmat(2,{ - &.RangeOfMotion.Right.Leg.Hip.Neutral, - &.RangeOfMotion.Right.Leg.Hip.FlexedAndAdducted, - &.RangeOfMotion.Right.Leg.Hip.Extended, - }); - AnyObjectPtrArray KneePositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.Leg.Knee.MaxFlexionAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.Leg.Knee.MaxExtensionAngle) - }); - AnyObjectPtrArray AnklePositions = repmat(nPos, &.RangeOfMotion.Right.Leg.Ankle.Neutral); - AnyObjectPtrArray SubTalarPositions = repmat(nPos, &.RangeOfMotion.Right.Leg.Ankle.Neutral); -}; - -LegCalibrationStudy LegCalibration6Right( - BodyModelRef=Main.HumanModel.BodyModel, - Side=Right, -) = { - nStep = nPos; - - MuscleArr = ObjSearch( - &..BodyModel.Right.Leg.Mus, - { - "TibialisAnt*.*", - "TibialisPosteriorMed*.*", - "ExtensorDigi*.*", - "ExtensorHall*.*", - "FlexorDigi*.*", - "FlexorHall*.*", - "Peroneus*.*", - "Plantaris.*", - "Gastroc*.*", - }, - "AnyMuscle" - ); - - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - AnyInt nPos = NumElemOf(AnklePositions); - AnyObjectPtrArray HipPositions = repmat(nPos, &.RangeOfMotion.Right.Leg.Hip.Neutral); - AnyObjectPtrArray KneePositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.Leg.Knee.MaxFlexionAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.Leg.Knee.MaxExtensionAngle) - }); - AnyObjectPtrArray AnklePositions = flatten(repmat(2, { - &.RangeOfMotion.Right.Leg.Ankle.MaxPlantarFlexionAngle, - &.RangeOfMotion.Right.Leg.Ankle.Neutral, - &.RangeOfMotion.Right.Leg.Ankle.MaxDorsiFlexionAngle, - &.RangeOfMotion.Right.Leg.Ankle.Neutral, - })); - AnyObjectPtrArray SubTalarPositions = flatten(repmat(2, { - &.RangeOfMotion.Right.Leg.Ankle.Neutral, - &.RangeOfMotion.Right.Leg.Ankle.MaxInversionAngle, - &.RangeOfMotion.Right.Leg.Ankle.Neutral, - &.RangeOfMotion.Right.Leg.Ankle.MaxEversionAngle, - })); -}; - -LegCalibrationStudy LegCalibration7Right( - BodyModelRef=Main.HumanModel.BodyModel, - Side=Right, -) = { - nStep = nPos; - - MuscleArr = ObjSearch( - &..BodyModel.Right.Leg.Mus, - { - "TibialisPosteriorLat*.*", - "Soleus*.*", - }, - "AnyMuscle" - ); - - RminMuscleFiber = repmat(NumElemOf(MuscleArr), 1.0); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), 1.2); - - AnyInt nPos = NumElemOf(AnklePositions); - AnyObjectPtrArray HipPositions = repmat(nPos, &.RangeOfMotion.Right.Leg.Hip.Neutral); - AnyObjectPtrArray KneePositions = flatten({ - repmat(round(nPos/2), &.RangeOfMotion.Right.Leg.Knee.MaxFlexionAngle), - repmat(round(nPos/2), &.RangeOfMotion.Right.Leg.Knee.MaxExtensionAngle) - }); - AnyObjectPtrArray AnklePositions = flatten(repmat(2, { - &.RangeOfMotion.Right.Leg.Ankle.MaxPlantarFlexionAngle, - &.RangeOfMotion.Right.Leg.Ankle.Neutral, - &.RangeOfMotion.Right.Leg.Ankle.MaxDorsiFlexionAngle, - &.RangeOfMotion.Right.Leg.Ankle.Neutral, - })); - AnyObjectPtrArray SubTalarPositions = flatten(repmat(2, { - &.RangeOfMotion.Right.Leg.Ankle.Neutral, - &.RangeOfMotion.Right.Leg.Ankle.MaxInversionAngle, - &.RangeOfMotion.Right.Leg.Ankle.Neutral, - &.RangeOfMotion.Right.Leg.Ankle.MaxEversionAngle, - })); -}; CalibrationSequence = { - AnyOperation &LegCal1Right = .LegCalibration1Right.FiberAndTendonLengthAdjustment; - AnyOperation &LegCal2Right = .LegCalibration2Right.FiberAndTendonLengthAdjustment; - AnyOperation &LegCal3Right = .LegCalibration3Right.FiberAndTendonLengthAdjustment; - AnyOperation &LegCal4Right = .LegCalibration4Right.FiberAndTendonLengthAdjustment; - AnyOperation &LegCal5Right = .LegCalibration5Right.FiberAndTendonLengthAdjustment; - AnyOperation &LegCal6Right = .LegCalibration6Right.FiberAndTendonLengthAdjustment; - AnyOperation &LegCal7Right = .LegCalibration7Right.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal1Right = .RightCal1Hip.FiberAndTendonLengthAdjustment; }; \ No newline at end of file From ac13ff16b7ea618ca98f0494e4fb9c01a7fe5db7 Mon Sep 17 00:00:00 2001 From: bke Date: Mon, 7 Apr 2025 14:56:16 +0200 Subject: [PATCH 13/29] refactor leg studies --- .../Calibration/RangeOfMotionDefinition.any | 13 ++ .../Calibration/2ParRightCalStudies.any | 156 ++++++++++++++++-- Body/AAUHuman/LegTLEM/rangeOfMotion.any | 28 ++++ 3 files changed, 181 insertions(+), 16 deletions(-) diff --git a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any index 67e7c32fe..0bff1cab6 100644 --- a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any +++ b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any @@ -93,12 +93,16 @@ BodyModelFolderStructure RangeOfMotion() = { AnyFloat Extended ??= .....BodyModel.Right.Leg.Data.RangeOfMotion.Hip.Extended; AnyFloat ExtendedAndAdducted ??= .....BodyModel.Right.Leg.Data.RangeOfMotion.Hip.ExtendedAndAdducted; AnyFloat AbductedAndExternallyRotated ??= .....BodyModel.Right.Leg.Data.RangeOfMotion.Hip.AbductedAndExternallyRotated; + + AnyObjectPtr ActiveRoM ??= .....BodyModel.Right.Leg.Data.RangeOfMotion.Hip.ActiveRoM; }; Right.Leg.Knee = { AnyVar Neutral ??= .....BodyModel.Right.Leg.Data.RangeOfMotion.Knee.Neutral; AnyVar MaxFlexionAngle ??= .....BodyModel.Right.Leg.Data.RangeOfMotion.Knee.MaxFlexionAngle; AnyVar MaxExtensionAngle ??= .....BodyModel.Right.Leg.Data.RangeOfMotion.Knee.MaxExtensionAngle; + + AnyObjectPtr ActiveRoM ??= .....BodyModel.Right.Leg.Data.RangeOfMotion.Knee.ActiveRoM; }; Right.Leg.Ankle = { @@ -107,6 +111,8 @@ BodyModelFolderStructure RangeOfMotion() = { AnyVar MaxDorsiFlexionAngle ??= .....BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.MaxDorsiFlexionAngle; AnyVar MaxInversionAngle ??= .....BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.MaxInversionAngle; AnyVar MaxEversionAngle ??= .....BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.MaxEversionAngle; + + AnyObjectPtr ActiveRoM ??= .....BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.ActiveRoM; }; #endif @@ -173,18 +179,23 @@ BodyModelFolderStructure RangeOfMotion() = { AnyFloat InternallyRotated ??= ...Right.Leg.Hip.InternallyRotated; AnyFloat ExternallyRotated ??= ...Right.Leg.Hip.ExternallyRotated; AnyFloat Adduction ??= ...Right.Leg.Hip.Adduction; + AnyFloat Abduction ??= ...Right.Leg.Hip.Abduction; 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; + + AnyObjectPtr ActiveRoM ??= ...Right.Leg.Hip.ActiveRoM; }; Left.Leg.Knee = { AnyVar Neutral ??= ...Right.Leg.Knee.Neutral; AnyVar MaxFlexionAngle ??= ...Right.Leg.Knee.MaxFlexionAngle; AnyVar MaxExtensionAngle ??= ...Right.Leg.Knee.MaxExtensionAngle; + + AnyObjectPtr ActiveRoM ??= ...Right.Leg.Knee.ActiveRoM; }; Left.Leg.Ankle = { @@ -193,6 +204,8 @@ BodyModelFolderStructure RangeOfMotion() = { AnyVar MaxDorsiFlexionAngle ??= ...Right.Leg.Ankle.MaxDorsiFlexionAngle; AnyVar MaxInversionAngle ??= ...Right.Leg.Ankle.MaxInversionAngle; AnyVar MaxEversionAngle ??= ...Right.Leg.Ankle.MaxEversionAngle; + + AnyObjectPtr ActiveRoM ??= ...Right.Leg.Ankle.ActiveRoM; }; #endif }; \ No newline at end of file diff --git a/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any b/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any index 6f9d0e451..b53a622d0 100644 --- a/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any +++ b/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any @@ -7,11 +7,67 @@ LegCalibrationStudy RightCal1Hip( MuscleArr = ObjSearch( &..BodyModel.Right.Leg.Mus, { - "AdductorMagnus*.*", - "AdductorLong*.*", "AdductorBrevis*.*", + "AdductorLong*.*", + "AdductorMagnus*.*", + "Gemellus.*", + "Gluteus*.*", + "Iliacus*.*", + "Obturator*.*", "Pectineus.*", + "Piriformis.*", + "QuadratusFemoris.*", + }, + "AnyMuscle" + ); + + RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); + RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); + + HipPositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Hip.ActiveRoM)); + KneePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Knee.Neutral); + AnklePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); + SubTalarPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); +}; + +LegCalibrationStudy RightCal2HipSpine( + BodyModelRef=Main.HumanModel.BodyModel, + Side=Right, +) = { + nStep = NumElemOf(HipPositions); + + MuscleArr = ObjSearch( + &..BodyModel.Trunk.Muscles.Right, + { + "Psoas*.*", + }, + "AnyMuscle" + ); + + RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); + RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); + + HipPositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Hip.ActiveRoM)); + KneePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Knee.Neutral); + AnklePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); + SubTalarPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); +}; + +LegCalibrationStudy RightCal3HipKnee( + BodyModelRef=Main.HumanModel.BodyModel, + Side=Right, +) = { + nStep = NumElemOf(HipPositions); + + MuscleArr = ObjSearch( + &..BodyModel.Right.Leg.Mus, + { + "BicepsFemorisCaputLongum.*", "Gracilis.*", + "RectusFem*.*", + "Sartorius.*", + "Semimembranosus.*", + "Semitendinosus.*", "TensorFasciaeLatae.*", }, "AnyMuscle" @@ -20,25 +76,93 @@ LegCalibrationStudy RightCal1Hip( RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - HipPositions = repmat(2,{ - &.RangeOfMotion.Right.Leg.Hip.InternallyRotated, - &.RangeOfMotion.Right.Leg.Hip.Adduction, - &.RangeOfMotion.Right.Leg.Hip.Abduction, - &.RangeOfMotion.Right.Leg.Hip.AbductedAndExternallyRotated, - &.RangeOfMotion.Right.Leg.Hip.FlexedAndAdducted, - &.RangeOfMotion.Right.Leg.Hip.FlexedAndAbducted, - &.RangeOfMotion.Right.Leg.Hip.ExtendedAndAdducted, - }); - - KneePositions = flatten({ - repmat(round(nStep/2), &.RangeOfMotion.Right.Leg.Knee.MaxFlexionAngle), - repmat(round(nStep/2), &.RangeOfMotion.Right.Leg.Knee.MaxExtensionAngle) - }); + HipPositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Hip.ActiveRoM)); + KneePositions = repmat(10, flattenptr(&.RangeOfMotion.Right.Leg.Knee.ActiveRoM)); + AnklePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); + SubTalarPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); +}; + +LegCalibrationStudy RightCal4Knee( + BodyModelRef=Main.HumanModel.BodyModel, + Side=Right, +) = { + nStep = NumElemOf(KneePositions); + + MuscleArr = ObjSearch( + &..BodyModel.Right.Leg.Mus, + { + "BicepsFemorisCaputBreve.*", + "Popliteus.*", + "Vastus*.*", + }, + "AnyMuscle" + ); + + RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); + RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); + + HipPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Hip.Neutral); + KneePositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Knee.ActiveRoM)); AnklePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); SubTalarPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); }; +LegCalibrationStudy RightCal5AnkleKnee( + BodyModelRef=Main.HumanModel.BodyModel, + Side=Right, +) = { + nStep = NumElemOf(AnklePositions); + + MuscleArr = ObjSearch( + &..BodyModel.Right.Leg.Mus, + { + "Gastroc*.*", + "Peroneus*.*", + "Plantaris.*", + }, + "AnyMuscle" + ); + + RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); + RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); + + HipPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Hip.Neutral); + KneePositions = repmat(4, flattenptr(&.RangeOfMotion.Right.Leg.Knee.ActiveRoM)); + AnklePositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Ankle.ActiveRoM)); + SubTalarPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); +}; + +LegCalibrationStudy RightCal6Ankle( + BodyModelRef=Main.HumanModel.BodyModel, + Side=Right, +) = { + nStep = NumElemOf(AnklePositions); + MuscleArr = ObjSearch( + &..BodyModel.Right.Leg.Mus, + { + "Extensor*.*", + "Flexor*.*", + "Soleus*.*", + "Tibialis*.*", + }, + "AnyMuscle" + ); + + RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); + RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); + + HipPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Hip.Neutral); + KneePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Knee.Neutral); + AnklePositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Ankle.ActiveRoM)); + SubTalarPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); +}; + CalibrationSequence = { AnyOperation &LegCal1Right = .RightCal1Hip.FiberAndTendonLengthAdjustment; + // AnyOperation &LegCal2Right = .RightCal2HipSpine.FiberAndTendonLengthAdjustment; + // AnyOperation &LegCal3Right = .RightCal3HipKnee.FiberAndTendonLengthAdjustment; + // AnyOperation &LegCal4Right = .RightCal4Knee.FiberAndTendonLengthAdjustment; + // AnyOperation &LegCal5Right = .RightCal5AnkleKnee.FiberAndTendonLengthAdjustment; + // AnyOperation &LegCal6Right = .RightCal6Ankle.FiberAndTendonLengthAdjustment; }; \ No newline at end of file diff --git a/Body/AAUHuman/LegTLEM/rangeOfMotion.any b/Body/AAUHuman/LegTLEM/rangeOfMotion.any index 1dd2d9ead..5f1e0b4c3 100644 --- a/Body/AAUHuman/LegTLEM/rangeOfMotion.any +++ b/Body/AAUHuman/LegTLEM/rangeOfMotion.any @@ -25,12 +25,33 @@ AnyFolder RangeOfMotion = { AnyFloat Extended = { MaxExtensionAngle, 0, 0}; AnyFloat ExtendedAndAdducted = { MaxExtensionInAdductionAngle, MaxAdductionInExtensionAngle, 0}; AnyFloat AbductedAndExternallyRotated = {0, MaxAbductionAngle, MaxExternalRotationAngle}; + + /// Positions defining the active range of motion for the hip joint + /// The active range of motion is defined as the range of motion that can be achieved by the muscles + AnyObjectPtrArray ActiveRoM = { + &InternallyRotated, + &ExternallyRotated, + &Adduction, + &Abduction, + &Flexed, + &FlexedAndAdducted, + &FlexedAndAbducted, + &Extended, + &ExtendedAndAdducted, + &AbductedAndExternallyRotated, + }; + }; AnyFolder Knee = { AnyVar Neutral = 0; AnyVar MaxFlexionAngle = 130; AnyVar MaxExtensionAngle = -3; + + AnyObjectPtrArray ActiveRoM = { + &MaxFlexionAngle, + &MaxExtensionAngle, + }; }; AnyFolder Ankle = { @@ -39,5 +60,12 @@ AnyFolder RangeOfMotion = { AnyVar MaxDorsiFlexionAngle = -20; AnyVar MaxInversionAngle = 15; AnyVar MaxEversionAngle = -20; + + AnyObjectPtrArray ActiveRoM = { + &MaxPlantarFlexionAngle, + &MaxDorsiFlexionAngle, + &MaxInversionAngle, + &MaxEversionAngle, + }; }; }; \ No newline at end of file From 03ac6b31499e5388dbf65e1a6583860a8e2a8701 Mon Sep 17 00:00:00 2001 From: bke Date: Tue, 8 Apr 2025 13:38:51 +0200 Subject: [PATCH 14/29] refactor trunk DoFs --- .../Calibration/BMDependentObjects.any | 40 +-- .../CalibrationStudy.ClassTemplates.any | 101 +++++--- .../Calibration/RangeOfMotionDefinition.any | 2 + .../Calibration/2ParLeftCalStudies.any | 244 ++++++++---------- 4 files changed, 194 insertions(+), 193 deletions(-) diff --git a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/BMDependentObjects.any b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/BMDependentObjects.any index faaf6e304..330bb61ba 100644 --- a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/BMDependentObjects.any +++ b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/BMDependentObjects.any @@ -7,113 +7,113 @@ /// since the calibration drivers handles all DOFs. AnyMechObjectExcluder ExcludeShoulderRhythm = { Objects = arrcat( - ObjSearch(&.Joints, "ClaviculaProtractionDriver"), - ObjSearch(&.Joints, "ClaviculaElevationDriver"), - ObjSearch(&.Joints, "ClaviculaAxialRotationDriver") + ObjSearch(&.ArmJoints, "ClaviculaProtractionDriver"), + ObjSearch(&.ArmJoints, "ClaviculaElevationDriver"), + ObjSearch(&.ArmJoints, "ClaviculaAxialRotationDriver") ); }; #if BM_ARM_DETAILED_HAND // Finger constraints for the detailed hand model in calibration studies AnyKinEqSimpleDriver CMC1Flexion = { - AnyRevoluteJoint &ref = .Segments.Hand.Finger1.Jnt.CMCFlexion; + AnyRevoluteJoint &ref = .ArmSegments.Hand.Finger1.Jnt.CMCFlexion; DriverPos = {0}*pi/180; DriverVel = {0}; }; AnyKinEqSimpleDriver CMC1Abduction = { - AnyRevoluteJoint &ref = .Segments.Hand.Finger1.Jnt.CMCAbduction; + AnyRevoluteJoint &ref = .ArmSegments.Hand.Finger1.Jnt.CMCAbduction; DriverPos = {0}*pi/180; DriverVel = {0}; }; AnyKinEqSimpleDriver MCP1Flexion = { - AnyRevoluteJoint &ref = .Segments.Hand.Finger1.Jnt.MCPFlexion; + AnyRevoluteJoint &ref = .ArmSegments.Hand.Finger1.Jnt.MCPFlexion; DriverPos = {0}*pi/180; DriverVel = {0}; }; AnyKinEqSimpleDriver MCP1Abduction= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger1.Jnt.MCPAbduction; + AnyRevoluteJoint &ref = .ArmSegments.Hand.Finger1.Jnt.MCPAbduction; DriverPos = {0}*pi/180; DriverVel = {0}; }; AnyKinEqSimpleDriver DIP1 = { - AnyRevoluteJoint &ref = .Segments.Hand.Finger1.Jnt.DIP; + AnyRevoluteJoint &ref = .ArmSegments.Hand.Finger1.Jnt.DIP; DriverPos = {0}*pi/180; DriverVel = {0}; }; AnyKinEqSimpleDriver MCP2= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger2.Jnt.MCP; + AnyRevoluteJoint &ref = .ArmSegments.Hand.Finger2.Jnt.MCP; DriverPos= {0}*pi/180; DriverVel= {0}; }; AnyKinEqSimpleDriver PIP2= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger2.Jnt.PIP; + AnyRevoluteJoint &ref = .ArmSegments.Hand.Finger2.Jnt.PIP; DriverPos= {0}*pi/180; DriverVel= {0}; }; AnyKinEqSimpleDriver DIP2= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger2.Jnt.DIP; + AnyRevoluteJoint &ref = .ArmSegments.Hand.Finger2.Jnt.DIP; DriverPos= {0}; DriverVel= {0}; }; AnyKinEqSimpleDriver MCP3= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger3.Jnt.MCP; + AnyRevoluteJoint &ref = .ArmSegments.Hand.Finger3.Jnt.MCP; DriverPos= {0}*pi/180; DriverVel= {0}; }; AnyKinEqSimpleDriver PIP3= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger3.Jnt.PIP; + AnyRevoluteJoint &ref = .ArmSegments.Hand.Finger3.Jnt.PIP; DriverPos= {0}*pi/180; DriverVel= {0}; }; AnyKinEqSimpleDriver DIP3= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger3.Jnt.DIP; + AnyRevoluteJoint &ref = .ArmSegments.Hand.Finger3.Jnt.DIP; DriverPos= {0}; DriverVel= {0}; }; AnyKinEqSimpleDriver MCP4= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger4.Jnt.MCP; + AnyRevoluteJoint &ref = .ArmSegments.Hand.Finger4.Jnt.MCP; DriverPos= {0}*pi/180; DriverVel= {0}; }; AnyKinEqSimpleDriver PIP4= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger4.Jnt.PIP; + AnyRevoluteJoint &ref = .ArmSegments.Hand.Finger4.Jnt.PIP; DriverPos= {0}*pi/180; DriverVel= {0}; }; AnyKinEqSimpleDriver DIP4= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger4.Jnt.DIP; + AnyRevoluteJoint &ref = .ArmSegments.Hand.Finger4.Jnt.DIP; DriverPos= {0}*pi/180; DriverVel= {0}; }; AnyKinEqSimpleDriver MCP5= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger5.Jnt.MCP; + AnyRevoluteJoint &ref = .ArmSegments.Hand.Finger5.Jnt.MCP; DriverPos= {0}*pi/180; DriverVel= {0}; }; AnyKinEqSimpleDriver PIP5= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger5.Jnt.PIP; + AnyRevoluteJoint &ref = .ArmSegments.Hand.Finger5.Jnt.PIP; DriverPos= {0}*pi/180; DriverVel= {0}; }; AnyKinEqSimpleDriver DIP5= { - AnyRevoluteJoint &ref = .Segments.Hand.Finger5.Jnt.DIP; + AnyRevoluteJoint &ref = .ArmSegments.Hand.Finger5.Jnt.DIP; DriverPos= {0}; DriverVel= {0}; }; diff --git a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any index 3e287b1eb..97b98b6ed 100644 --- a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any +++ b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any @@ -1,40 +1,4 @@ -#class_template TrunkCalibrationModel(Side, BodyModelRef) { - - AnyFolder &TrunkSegments = BodyModelRef.Trunk.Segments; - AnyFolder &TrunkJoints = BodyModelRef.Trunk.Joints; - - // Constraints - AnyFixedRefFrame ground = { - AnyRefNode node = { - ARel = ..TrunkSegments.PelvisSeg.Axes0; - sRel = ..TrunkSegments.PelvisSeg.r0; - }; - }; - - AnyKinEq ThoraxFix = { - AnyKinMeasure& PelvisThoraxExtension = BodyModelRef.Interface.Trunk.PelvisThoraxExtension; - AnyKinMeasure& PelvisThoraxLateralBending = BodyModelRef.Interface.Trunk.PelvisThoraxLateralBending; - AnyKinMeasure& PelvisThoraxRotation = BodyModelRef.Interface.Trunk.PelvisThoraxRotation; - AnyKinMeasure& SkullThoraxFlexion = BodyModelRef.Interface.Trunk.SkullThoraxFlexion; - AnyKinMeasure& SkullThoraxRotation = BodyModelRef.Interface.Trunk.SkullThoraxRotation; - AnyKinMeasure& SkullThoraxLateralBending = BodyModelRef.Interface.Trunk.SkullThoraxLateralBending; - }; - - AnyKinEq PelvisFix = { - AnyKinLinear Lin = { - AnyRefFrame &ground = ..ground.node; - AnyRefFrame &Pelvis = ..TrunkSegments.PelvisSeg; - }; - AnyKinRotational Rot = { - Type = RotAxesAngles; - AnyRefFrame &ground = ..ground.node; - AnyRefFrame &Pelvis = ..TrunkSegments.PelvisSeg; - }; - }; -}; - - /** Class template to create a driver for a single-DoF measure in a calibration study. */ @@ -67,6 +31,70 @@ 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 TrunkCalibrationModel(Side, BodyModelRef) { + + AnyVar nStep = .nStep; + + #var AnyObjectPtr TrunkFlexionPositions = repmat(.nStep, &..RangeOfMotion.Trunk.Neutral); + #var AnyObjectPtr TrunkLateralBendingPositions = repmat(.nStep, &..RangeOfMotion.Trunk.Neutral); + #var AnyObjectPtr TrunkRotationPositions = repmat(.nStep, &..RangeOfMotion.Trunk.Neutral); + #var AnyObjectPtr SkullFlexionPositions = repmat(.nStep, &..RangeOfMotion.Trunk.Neutral); + #var AnyObjectPtr SkullLateralBendingPositions = repmat(.nStep, &..RangeOfMotion.Trunk.Neutral); + #var AnyObjectPtr SkullRotationPositions = repmat(.nStep, &..RangeOfMotion.Trunk.Neutral); + + AnyFolder &TrunkSegments = BodyModelRef.Trunk.Segments; + AnyFolder &TrunkJoints = BodyModelRef.Trunk.Joints; + + // Constraints + AnyFixedRefFrame ground = { + AnyRefNode node = { + ARel = ..TrunkSegments.PelvisSeg.Axes0; + sRel = ..TrunkSegments.PelvisSeg.r0; + }; + }; + + SingleDoFCalDriver TrunkFlexion( + Measure = BodyModelRef.Interface.Trunk.PelvisThoraxExtension, + DriverData = .TrunkFlexionPositions + ) ={}; + + SingleDoFCalDriver TrunkLateralBending( + Measure = BodyModelRef.Interface.Trunk.PelvisThoraxLateralBending, + DriverData = .TrunkLateralBendingPositions + ) ={}; + + SingleDoFCalDriver TrunkRotation( + Measure = BodyModelRef.Interface.Trunk.PelvisThoraxRotation, + DriverData = .TrunkRotationPositions + ) ={}; + + SingleDoFCalDriver SkullFlexion( + Measure = BodyModelRef.Interface.Trunk.SkullThoraxFlexion, + DriverData = .SkullFlexionPositions + ) ={}; + + SingleDoFCalDriver SkullLateralBending( + Measure = BodyModelRef.Interface.Trunk.SkullThoraxLateralBending, + DriverData = .SkullLateralBendingPositions + ) ={}; + + SingleDoFCalDriver SkullRotation( + Measure = BodyModelRef.Interface.Trunk.SkullThoraxRotation, + DriverData = .SkullRotationPositions + ) ={}; + + AnyKinEq PelvisFix = { + AnyKinLinear Lin = { + AnyRefFrame &ground = ..ground.node; + AnyRefFrame &Pelvis = ..TrunkSegments.PelvisSeg; + }; + AnyKinRotational Rot = { + Type = RotAxesAngles; + AnyRefFrame &ground = ..ground.node; + AnyRefFrame &Pelvis = ..TrunkSegments.PelvisSeg; + }; + }; +}; /** @@ -123,7 +151,6 @@ __CLASS__ = AnyBodyCalibrationStudy, BodyModelRef, Side, - ) { // Study settings FiberAndTendonLengthAdjustment.CalibrateTendonAtMaxForceOnOff = Off; diff --git a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any index 0bff1cab6..32edf08f2 100644 --- a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any +++ b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any @@ -20,6 +20,8 @@ BodyModelFolderStructure RangeOfMotion() = { AnyVar MaxPelvisSacrumExtensionAngle ??= ...BodyModel.Trunk.Data.RangeOfMotion.MaxPelvisSacrumExtensionAngle; AnyVar MaxPelvisSacrumLateralBendingAngle ??= ...BodyModel.Trunk.Data.RangeOfMotion.MaxPelvisSacrumLateralBendingAngle; AnyVar MinPelvisSacrumLateralBendingAngle ??= ...BodyModel.Trunk.Data.RangeOfMotion.MinPelvisSacrumLateralBendingAngle; + AnyVar Neutral ??= ...BodyModel.Trunk.Data.RangeOfMotion.Neutral; + }; #if BM_ARM_RIGHT diff --git a/Body/AAUHuman/LegTLEM/Calibration/2ParLeftCalStudies.any b/Body/AAUHuman/LegTLEM/Calibration/2ParLeftCalStudies.any index efcbd26fc..feb6c2d22 100644 --- a/Body/AAUHuman/LegTLEM/Calibration/2ParLeftCalStudies.any +++ b/Body/AAUHuman/LegTLEM/Calibration/2ParLeftCalStudies.any @@ -1,196 +1,168 @@ -LegCalibrationStudy LegCalibration1Left( - BodyModelRef=Main.HumanModel.BodyModel, - Side=Left, +LegCalibrationStudy LeftCal1Hip( +BodyModelRef = Main.HumanModel.BodyModel, +Side = Left, ) = { - nStep = .LegCalibration1Right.nStep; + nStep = .RightCal1Hip.nStep; MuscleArr = ObjSearch( - &..BodyModel.Left.Leg.Mus, - { - "AdductorMagnus*.*", - "AdductorLong*.*", - "AdductorBrevis*.*", - "Pectineus.*", - "Gracilis.*", - "TensorFasciaeLatae.*", - }, - "AnyMuscle" + &..BodyModel.Left.Leg.Mus, + { + "AdductorBrevis*.*", + "AdductorLong*.*", + "AdductorMagnus*.*", + "Gemellus.*", + "Gluteus*.*", + "Iliacus*.*", + "Obturator*.*", + "Pectineus.*", + "Piriformis.*", + "QuadratusFemoris.*", + }, + "AnyMuscle" ); - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); + RminMuscleFiber = .RightCal1Hip.RminMuscleFiber; + RmaxMuscleFiber = .RightCal1Hip.RmaxMuscleFiber; - AnyObjectPtrArray HipPositions = .LegCalibration1Right.HipPositions; - AnyObjectPtrArray KneePositions = .LegCalibration1Right.KneePositions; - AnyObjectPtrArray AnklePositions = .LegCalibration1Right.AnklePositions; - AnyObjectPtrArray SubTalarPositions = .LegCalibration1Right.SubTalarPositions; + HipPositions = .RightCal1Hip.HipPositions; + KneePositions = .RightCal1Hip.KneePositions; + AnklePositions = .RightCal1Hip.AnklePositions; + SubTalarPositions = .RightCal1Hip.SubTalarPositions; }; - -LegCalibrationStudy LegCalibration2Left( - BodyModelRef=Main.HumanModel.BodyModel, - Side=Left, +LegCalibrationStudy LeftCal2HipSpine( +BodyModelRef = Main.HumanModel.BodyModel, +Side = Left, ) = { - nStep = .LegCalibration2Right.nStep; + nStep = NumElemOf(HipPositions); MuscleArr = ObjSearch( - &..BodyModel.Left.Leg.Mus, - { - "Gluteus*.*", - "Piriformis.*", - "Gemellus.*", - "Obturator*.*", - "QuadratusFem*.*", - }, - "AnyMuscle" + &..BodyModel.Trunk.Muscles.Left, + { + "Psoas*.*", + }, + "AnyMuscle" ); RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - AnyObjectPtrArray HipPositions = .LegCalibration2Right.HipPositions; - AnyObjectPtrArray KneePositions = .LegCalibration2Right.KneePositions; - AnyObjectPtrArray AnklePositions = .LegCalibration2Right.AnklePositions; - AnyObjectPtrArray SubTalarPositions = .LegCalibration2Right.SubTalarPositions; + HipPositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Hip.ActiveRoM)); + KneePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Knee.Neutral); + AnklePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); + SubTalarPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); }; -LegCalibrationStudy LegCalibration3Left( - BodyModelRef=Main.HumanModel.BodyModel, - Side=Left, +LegCalibrationStudy LeftCal3HipKnee( +BodyModelRef = Main.HumanModel.BodyModel, +Side = Left, ) = { - nStep = .LegCalibration3Right.nStep; + nStep = NumElemOf(HipPositions); MuscleArr = ObjSearch( - {&..BodyModel.Left.Leg.Mus, &..BodyModel.Trunk.Muscles.Left,}, - { - "Iliacus*.*", - "PsoasMajor*.*", - }, - "AnyMuscle" + &..BodyModel.Left.Leg.Mus, + { + "BicepsFemorisCaputLongum.*", + "Gracilis.*", + "RectusFem*.*", + "Sartorius.*", + "Semimembranosus.*", + "Semitendinosus.*", + "TensorFasciaeLatae.*", + }, + "AnyMuscle" ); RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - AnyObjectPtrArray HipPositions = .LegCalibration3Right.HipPositions; - AnyObjectPtrArray KneePositions = .LegCalibration3Right.KneePositions; - AnyObjectPtrArray AnklePositions = .LegCalibration3Right.AnklePositions; - AnyObjectPtrArray SubTalarPositions = .LegCalibration3Right.SubTalarPositions; + HipPositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Hip.ActiveRoM)); + KneePositions = repmat(10, flattenptr(&.RangeOfMotion.Right.Leg.Knee.ActiveRoM)); + AnklePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); + SubTalarPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); }; - -LegCalibrationStudy LegCalibration4Left( - BodyModelRef=Main.HumanModel.BodyModel, - Side=Left, +LegCalibrationStudy LeftCal4Knee( +BodyModelRef = Main.HumanModel.BodyModel, +Side = Left, ) = { - nStep = .LegCalibration4Right.nStep; + nStep = NumElemOf(KneePositions); MuscleArr = ObjSearch( - &..BodyModel.Left.Leg.Mus, - { - "RectusFem*.*", - "BicepsFem*.*", - "Semitend*.*", - "Semimem*.*", - "Sartorius.*", - }, - "AnyMuscle" + &..BodyModel.Left.Leg.Mus, + { + "BicepsFemorisCaputBreve.*", + "Popliteus.*", + "Vastus*.*", + }, + "AnyMuscle" ); RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - AnyObjectPtrArray HipPositions = .LegCalibration4Right.HipPositions; - AnyObjectPtrArray KneePositions = .LegCalibration4Right.KneePositions; - AnyObjectPtrArray AnklePositions = .LegCalibration4Right.AnklePositions; - AnyObjectPtrArray SubTalarPositions = .LegCalibration4Right.SubTalarPositions; + HipPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Hip.Neutral); + KneePositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Knee.ActiveRoM)); + AnklePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); + SubTalarPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); }; -LegCalibrationStudy LegCalibration5Left( - BodyModelRef=Main.HumanModel.BodyModel, - Side=Left, +LegCalibrationStudy LeftCal5AnkleKnee( +BodyModelRef = Main.HumanModel.BodyModel, +Side = Left, ) = { - nStep = .LegCalibration6Right.nStep; + nStep = NumElemOf(AnklePositions); MuscleArr = ObjSearch( - &..BodyModel.Left.Leg.Mus, - { - "Vastus*.*", - "Popliteus.*", - }, - "AnyMuscle" + &..BodyModel.Left.Leg.Mus, + { + "Gastroc*.*", + "Peroneus*.*", + "Plantaris.*", + }, + "AnyMuscle" ); RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - AnyObjectPtrArray HipPositions = .LegCalibration6Right.HipPositions; - AnyObjectPtrArray KneePositions = .LegCalibration6Right.KneePositions; - AnyObjectPtrArray AnklePositions = .LegCalibration6Right.AnklePositions; - AnyObjectPtrArray SubTalarPositions = .LegCalibration6Right.SubTalarPositions; + HipPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Hip.Neutral); + KneePositions = repmat(4, flattenptr(&.RangeOfMotion.Right.Leg.Knee.ActiveRoM)); + AnklePositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Ankle.ActiveRoM)); + SubTalarPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); }; -LegCalibrationStudy LegCalibration6Left( - BodyModelRef=Main.HumanModel.BodyModel, - Side=Left, +LegCalibrationStudy LeftCal6Ankle( +BodyModelRef = Main.HumanModel.BodyModel, +Side = Left, ) = { - nStep = .LegCalibration7Right.nStep; - + nStep = NumElemOf(AnklePositions); MuscleArr = ObjSearch( - &..BodyModel.Left.Leg.Mus, - { - "TibialisAnt*.*", - "TibialisPosteriorMed*.*", - "ExtensorDigi*.*", - "ExtensorHall*.*", - "FlexorDigi*.*", - "FlexorHall*.*", - "Peroneus*.*", - "Plantaris.*", - "Gastroc*.*", - }, - "AnyMuscle" + &..BodyModel.Left.Leg.Mus, + { + "Extensor*.*", + "Flexor*.*", + "Soleus*.*", + "Tibialis*.*", + }, + "AnyMuscle" ); RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - AnyObjectPtrArray HipPositions = .LegCalibration7Right.HipPositions; - AnyObjectPtrArray KneePositions = .LegCalibration7Right.KneePositions; - AnyObjectPtrArray AnklePositions = .LegCalibration7Right.AnklePositions; - AnyObjectPtrArray SubTalarPositions = .LegCalibration7Right.SubTalarPositions; + HipPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Hip.Neutral); + KneePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Knee.Neutral); + AnklePositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Ankle.ActiveRoM)); + SubTalarPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); }; -LegCalibrationStudy LegCalibration7Left( - BodyModelRef = Main.HumanModel.BodyModel, - Side = Left, -) = { - nStep = .LegCalibration7Right.nStep; - - MuscleArr = ObjSearch( - &..BodyModel.Left.Leg.Mus, - { - "TibialisPosteriorLat*.*", - "Soleus*.*", - }, - "AnyMuscle" - ); - - RminMuscleFiber = repmat(NumElemOf(MuscleArr), 1.0); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), 1.2); - - AnyObjectPtrArray HipPositions = .LegCalibration7Right.HipPositions; - AnyObjectPtrArray KneePositions = .LegCalibration7Right.KneePositions; - AnyObjectPtrArray AnklePositions = .LegCalibration7Right.AnklePositions; - AnyObjectPtrArray SubTalarPositions = .LegCalibration7Right.SubTalarPositions; -}; CalibrationSequence = { - AnyOperation &LegCal1Left = .LegCalibration1Left.FiberAndTendonLengthAdjustment; - AnyOperation &LegCal2Left = .LegCalibration2Left.FiberAndTendonLengthAdjustment; - AnyOperation &LegCal3Left = .LegCalibration3Left.FiberAndTendonLengthAdjustment; - AnyOperation &LegCal4Left = .LegCalibration4Left.FiberAndTendonLengthAdjustment; - AnyOperation &LegCal5Left = .LegCalibration5Left.FiberAndTendonLengthAdjustment; - AnyOperation &LegCal6Left = .LegCalibration6Left.FiberAndTendonLengthAdjustment; - AnyOperation &LegCal7Left = .LegCalibration7Left.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal1Left = .LeftCal1Hip.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal2Left = .LeftCal2HipSpine.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal3Left = .LeftCal3HipKnee.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal4Left = .LeftCal4Knee.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal5Left = .LeftCal5AnkleKnee.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal6Left = .LeftCal6Ankle.FiberAndTendonLengthAdjustment; }; \ No newline at end of file From 4f5048d290d9a80a4a67a0195eaf42b884db23fe Mon Sep 17 00:00:00 2001 From: bke Date: Tue, 8 Apr 2025 13:56:17 +0200 Subject: [PATCH 15/29] refactor to one template --- .../CalibrationStudy.ClassTemplates.any | 319 ++++++++++++++++-- .../Calibration/RangeOfMotionDefinition.any | 126 +++---- .../Calibration/2ParLeftCalStudies.any | 78 ++--- .../Calibration/2ParRightCalStudies.any | 72 ++-- 4 files changed, 409 insertions(+), 186 deletions(-) diff --git a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any index 97b98b6ed..4908d89ca 100644 --- a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any +++ b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any @@ -3,14 +3,14 @@ Class template to create a driver for a single-DoF measure in a calibration study. */ #class_template SingleDoFCalDriver( - __CLASS__ = AnyKinEqInterPolDriver, +__CLASS__ = AnyKinEqInterPolDriver, Measure, DriverData ) { Type = PiecewiseLinear; T = linspace(0,1,SizesOf(Data)[1]); - Reaction.Type = repmat(nDim, Off); - Data = {Obj2Num(DriverData)} * pi/180; + Reaction.Type = repmat(nDim, Off); + Data = {Obj2Num(DriverData)} * pi/180; AnyKinMeasure& MeasureRef = Measure; 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.")); }; @@ -19,14 +19,14 @@ Class template to create a driver for a multi-DoF measure in a calibration study. */ #class_template MultiDoFCalDriver( - __CLASS__ = AnyKinEqInterPolDriver, +__CLASS__ = AnyKinEqInterPolDriver, Measure, DriverData ) { Type = PiecewiseLinear; T = linspace(0,1,SizesOf(Data)[1]); - Reaction.Type = repmat(nDim, Off); - Data = Obj2Num(DriverData)' * pi/180; ///< TODO: Refactor the data structure to join the template with the single-DoF version! + Reaction.Type = repmat(nDim, Off); + Data = Obj2Num(DriverData)' * pi/180; ///< TODO: Refactor the data structure to join the template with the single-DoF version! AnyKinMeasure& MeasureRef = Measure; 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.")); }; @@ -123,23 +123,23 @@ TrunkCalibrationModel TrunkModel(Side = Side, BodyModelRef = BodyModelRef) = {}; MultiDoFCalDriver Hip( - Measure = BodyModelRef.Interface.Side.HipFlexion.HipMeasure, - DriverData = .HipPositions + Measure = BodyModelRef.Interface.Side.HipFlexion.HipMeasure, + DriverData = .HipPositions ) ={}; SingleDoFCalDriver Knee( - Measure = BodyModelRef.Interface.Side.KneeFlexion, - DriverData = .KneePositions + Measure = BodyModelRef.Interface.Side.KneeFlexion, + DriverData = .KneePositions ) ={}; SingleDoFCalDriver Ankle( - Measure = BodyModelRef.Interface.Side.AnklePlantarFlexion, - DriverData = .AnklePositions + Measure = BodyModelRef.Interface.Side.AnklePlantarFlexion, + DriverData = .AnklePositions ) ={}; SingleDoFCalDriver SubTalar( - Measure = BodyModelRef.Interface.Side.SubTalarEversion, - DriverData = .SubTalarPositions + Measure = BodyModelRef.Interface.Side.SubTalarEversion, + DriverData = .SubTalarPositions ) ={}; }; @@ -177,39 +177,302 @@ TrunkCalibrationModel TrunkModel(Side = Side, BodyModelRef = BodyModelRef) = {}; MultiDoFCalDriver Shoulder( - Measure = BodyModelRef.Interface.Side.GlenohumeralFlexion.GHMeasure, - DriverData = .ShoulderPositions + Measure = BodyModelRef.Interface.Side.GlenohumeralFlexion.GHMeasure, + DriverData = .ShoulderPositions ) ={}; SingleDoFCalDriver ScapulaProtraction( - Measure = BodyModelRef.Interface.Side.ScapulaThoraxProtraction, - DriverData = .ScapulaProtractionPositions + Measure = BodyModelRef.Interface.Side.ScapulaThoraxProtraction, + DriverData = .ScapulaProtractionPositions ) ={}; SingleDoFCalDriver ScapulaElevation( - Measure = BodyModelRef.Interface.Side.ScapulaThoraxElevation, - DriverData = .ScapulaElevationPositions + Measure = BodyModelRef.Interface.Side.ScapulaThoraxElevation, + DriverData = .ScapulaElevationPositions ) ={}; SingleDoFCalDriver ElbowFlexion( - Measure = BodyModelRef.Interface.Side.ElbowFlexion, - DriverData = .ElbowFlexionPositions + Measure = BodyModelRef.Interface.Side.ElbowFlexion, + DriverData = .ElbowFlexionPositions ) ={}; SingleDoFCalDriver ElbowPronation( - Measure = BodyModelRef.Interface.Side.ElbowPronation, - DriverData = .ElbowPronationPositions + Measure = BodyModelRef.Interface.Side.ElbowPronation, + DriverData = .ElbowPronationPositions ) ={}; SingleDoFCalDriver WristFlexion( - Measure = BodyModelRef.Interface.Side.WristFlexion, - DriverData = .WristFlexionPositions + Measure = BodyModelRef.Interface.Side.WristFlexion, + DriverData = .WristFlexionPositions ) ={}; SingleDoFCalDriver WristAbduction( - Measure = BodyModelRef.Interface.Side.WristAbduction, - DriverData = .WristAbductionPositions + Measure = BodyModelRef.Interface.Side.WristAbduction, + DriverData = .WristAbductionPositions ) ={}; #include "BMDependentObjects.any" }; + +#class_template TwoParCalibrationStudy( + __CLASS__ = AnyBodyCalibrationStudy, + BodyModelRef, + Side, + TRUNKFLEXION = Off, + TRUNKLATERALBENDING = Off, + TRUNKROTATION = Off, + SKULLFLEXION = Off, + SKULLLATERALBENDING = Off, + SKULLROTATION = Off, + SHOULDER = Off, + SCAPULAELEVATION = Off, + SCAPULAPROTRACTION = Off, + ELBOWFLEXION = Off, + ELBOWPRONATION = Off, + WRISTFLEXION = Off, + WRISTABDUCTION = Off, + HIP = Off, + KNEE = Off, + ANKLE = Off, + SUBTALAR = Off, +) { + // Study settings + FiberAndTendonLengthAdjustment.CalibrateTendonAtMaxForceOnOff = Off; + Kinematics.SmallStepAssumptionOnOff = Off; + InitialConditions.SmallStepAssumptionOnOff = Off; + Kinematics.PosAnalysisOnlyOnOff = On; + InitialConditions.PosAnalysisOnlyOnOff = On; + + #var RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); + #var RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); + + // Constraint to ground + AnyFixedRefFrame Ground = { + AnyRefNode node = { + ARel = ..TrunkSegments.PelvisSeg.Axes0; + sRel = ..TrunkSegments.PelvisSeg.r0; + }; + }; + + AnyKinEq PelvisToGroundFix = { + AnyKinLinear Lin = { + AnyRefFrame &ground = ..Ground.node; + AnyRefFrame &Pelvis = ..TrunkSegments.PelvisSeg; + }; + AnyKinRotational Rot = { + Type = RotAxesAngles; + AnyRefFrame &ground = ..Ground.node; + AnyRefFrame &Pelvis = ..TrunkSegments.PelvisSeg; + }; + }; + + // The Trunk is always needed to fixate the model to the world + // Users can still activate the DoF and overwrite the positions in the calibration study + AnyFolder &TrunkSegments = BodyModelRef.Trunk.Segments; + AnyFolder &TrunkJoints = BodyModelRef.Trunk.Joints; + + SingleDoFCalDriver TrunkFlexion( + Measure = BodyModelRef.Interface.Trunk.PelvisThoraxExtension, + DriverData = .TrunkFlexionPositions + ) ={}; + + SingleDoFCalDriver TrunkLateralBending( + Measure = BodyModelRef.Interface.Trunk.PelvisThoraxLateralBending, + DriverData = .TrunkLateralBendingPositions + ) ={}; + + SingleDoFCalDriver TrunkRotation( + Measure = BodyModelRef.Interface.Trunk.PelvisThoraxRotation, + DriverData = .TrunkRotationPositions + ) ={}; + + SingleDoFCalDriver SkullFlexion( + Measure = BodyModelRef.Interface.Trunk.SkullThoraxFlexion, + DriverData = .SkullFlexionPositions + ) ={}; + + SingleDoFCalDriver SkullLateralBending( + Measure = BodyModelRef.Interface.Trunk.SkullThoraxLateralBending, + DriverData = .SkullLateralBendingPositions + ) ={}; + + SingleDoFCalDriver SkullRotation( + Measure = BodyModelRef.Interface.Trunk.SkullThoraxRotation, + DriverData = .SkullRotationPositions + ) ={}; + + #if TRUNKFLEXION == On + #var AnyObjectPtr TrunkFlexionPositions; + #else + AnyObjectPtr TrunkFlexionPositions = repmat(nStep, &.RangeOfMotion.Trunk.Neutral); + #endif + + #if TRUNKLATERALBENDING == On + #var AnyObjectPtr TrunkLateralBendingPositions; + #else + AnyObjectPtr TrunkLateralBendingPositions = repmat(nStep, &.RangeOfMotion.Trunk.Neutral); + #endif + + #if TRUNKROTATION == On + #var AnyObjectPtr TrunkRotationPositions; + #else + AnyObjectPtr TrunkRotationPositions = repmat(nStep, &.RangeOfMotion.Trunk.Neutral); + #endif + + #if SKULLFLEXION == On + #var AnyObjectPtr SkullFlexionPositions; + #else + AnyObjectPtr SkullFlexionPositions = repmat(nStep, &.RangeOfMotion.Trunk.Neutral); + #endif + + #if SKULLLATERALBENDING == On + #var AnyObjectPtr SkullLateralBendingPositions; + #else + AnyObjectPtr SkullLateralBendingPositions = repmat(nStep, &.RangeOfMotion.Trunk.Neutral); + #endif + + #if SKULLROTATION == On + #var AnyObjectPtr SkullRotationPositions; + #else + AnyObjectPtr SkullRotationPositions = repmat(nStep, &.RangeOfMotion.Trunk.Neutral); + #endif + + + #if (SHOULDER == On) | (SCAPULAELEVATION == On) | (SCAPULAPROTRACTION == On) | (ELBOWFLEXION == On) | (ELBOWPRONATION == On) | (WRISTFLEXION == On) | (WRISTABDUCTION == On) + AnyFolder &ArmSegments = BodyModelRef.Side.ShoulderArm.Segments; + AnyFolder &ArmJoints = BodyModelRef.Side.ShoulderArm.Joints; + + // The Muscles folder contain segments and constraints for some wrapping muscles + // e.g. Deltoid, Pectoralis Minor, etc. + AnyFolder &ArmMuscles = BodyModelRef.Side.ShoulderArm.Muscles; + + #include "BMDependentObjects.any" + + MultiDoFCalDriver Shoulder( + Measure = BodyModelRef.Interface.Side.GlenohumeralFlexion.GHMeasure, + DriverData = .ShoulderPositions + ) ={}; + + SingleDoFCalDriver ScapulaElevation( + Measure = BodyModelRef.Interface.Side.ScapulaThoraxElevation, + DriverData = .ScapulaElevationPositions + ) ={}; + + SingleDoFCalDriver ScapulaProtraction( + Measure = BodyModelRef.Interface.Side.ScapulaThoraxProtraction, + DriverData = .ScapulaProtractionPositions + ) ={}; + + SingleDoFCalDriver ElbowFlexion( + Measure = BodyModelRef.Interface.Side.ElbowFlexion, + DriverData = .ElbowFlexionPositions + ) ={}; + + SingleDoFCalDriver ElbowPronation( + Measure = BodyModelRef.Interface.Side.ElbowPronation, + DriverData = .ElbowPronationPositions + ) ={}; + + SingleDoFCalDriver WristFlexion( + Measure = BodyModelRef.Interface.Side.WristFlexion, + DriverData = .WristFlexionPositions + ) ={}; + + SingleDoFCalDriver WristAbduction( + Measure = BodyModelRef.Interface.Side.WristAbduction, + DriverData = .WristAbductionPositions + ) ={}; + + #if SHOULDER == On + #var AnyObjectPtr ShoulderPositions; + #else + AnyObjectPtr ShoulderPositions = repmat(nStep, &.RangeOfMotion.Side.ShoulderArm.Shoulder.Neutral); + #endif + + #if SCAPULAELEVATION == On + #var AnyObjectPtr ScapulaElevationPositions; + #else + AnyObjectPtr ScapulaElevationPositions = repmat(nStep, &.RangeOfMotion.Side.ShoulderArm.Shoulder.Neutral); + #endif + + #if SCAPULAPROTRACTION == On + #var AnyObjectPtr ScapulaProtractionPositions; + #else + AnyObjectPtr ScapulaProtractionPositions = repmat(nStep, &.RangeOfMotion.Side.ShoulderArm.Shoulder.Neutral); + #endif + + #if ELBOWFLEXION == On + #var AnyObjectPtr ElbowFlexionPositions; + #else + AnyObjectPtr ElbowFlexionPositions = repmat(nStep, &.RangeOfMotion.Side.ShoulderArm.Elbow.Neutral); + #endif + + #if ELBOWPRONATION == On + #var AnyObjectPtr ElbowPronationPositions; + #else + AnyObjectPtr ElbowPronationPositions = repmat(nStep, &.RangeOfMotion.Side.ShoulderArm.Elbow.Neutral); + #endif + + #if WRISTFLEXION == On + #var AnyObjectPtr WristFlexionPositions; + #else + AnyObjectPtr WristFlexionPositions = repmat(nStep, &.RangeOfMotion.Side.ShoulderArm.Wrist.Neutral); + #endif + + #if WRISTABDUCTION == On + #var AnyObjectPtr WristAbductionPositions; + #else + AnyObjectPtr WristAbductionPositions = repmat(nStep, &.RangeOfMotion.Side.ShoulderArm.Wrist.Neutral); + #endif + #endif + + // Leg + #if (HIP == On) | (KNEE == On) | (ANKLE == On) | (SUBTALAR == On) + AnyFolder &LegSegments = BodyModelRef.Side.Leg.Seg; + AnyFolder &LegJoints = BodyModelRef.Side.Leg.Jnt; + + MultiDoFCalDriver Hip( + Measure = BodyModelRef.Interface.Side.HipFlexion.HipMeasure, + DriverData = .HipPositions + ) ={}; + + SingleDoFCalDriver Knee( + Measure = BodyModelRef.Interface.Side.KneeFlexion, + DriverData = .KneePositions + ) ={}; + + SingleDoFCalDriver Ankle( + Measure = BodyModelRef.Interface.Side.AnklePlantarFlexion, + DriverData = .AnklePositions + ) ={}; + + SingleDoFCalDriver SubTalar( + Measure = BodyModelRef.Interface.Side.SubTalarEversion, + DriverData = .SubTalarPositions + ) ={}; + + #if HIP == On + #var AnyObjectPtr HipPositions; + #else + AnyObjectPtr HipPositions = repmat(nStep, &.RangeOfMotion.Side.Leg.Hip.Neutral); + #endif + + #if KNEE == On + #var AnyObjectPtr KneePositions; + #else + AnyObjectPtr KneePositions = repmat(nStep, &.RangeOfMotion.Side.Leg.Knee.Neutral); + #endif + + #if ANKLE == On + #var AnyObjectPtr AnklePositions; + #else + AnyObjectPtr AnklePositions = repmat(nStep, &.RangeOfMotion.Side.Leg.Ankle.Neutral); + #endif + + #if SUBTALAR == On + #var AnyObjectPtr SubTalarPositions; + #else + AnyObjectPtr SubTalarPositions = repmat(nStep, &.RangeOfMotion.Side.Leg.Ankle.Neutral); + #endif + #endif +}; \ No newline at end of file diff --git a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any index 32edf08f2..d7c587400 100644 --- a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any +++ b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any @@ -120,94 +120,94 @@ BodyModelFolderStructure RangeOfMotion() = { #if BM_ARM_LEFT Left.ShoulderArm.Shoulder = { - AnyVar MaxGlenohumeralFlexionAngle ??= ...Right.ShoulderArm.Shoulder.MaxGlenohumeralFlexionAngle; - AnyVar MaxGlenohumeralExtensionAngle ??= ...Right.ShoulderArm.Shoulder.MaxGlenohumeralExtensionAngle; - AnyVar MaxGlenohumeralAbductionAngle ??= ...Right.ShoulderArm.Shoulder.MaxGlenohumeralAbductionAngle; - AnyVar MaxGlenohumeralAdductionAngle ??= ...Right.ShoulderArm.Shoulder.MaxGlenohumeralAdductionAngle; - AnyVar MaxGlenohumeralExternalRotationAngle ??= ...Right.ShoulderArm.Shoulder.MaxGlenohumeralExternalRotationAngle; - AnyVar MaxGlenohumeralInternalRotationAngle ??= ...Right.ShoulderArm.Shoulder.MaxGlenohumeralInternalRotationAngle; - AnyVar MaxScapulaClaviculaElevationAngle ??= ...Right.ShoulderArm.Shoulder.MaxScapulaClaviculaElevationAngle; - AnyVar MaxScapulaClaviculaDepressionAngle ??= ...Right.ShoulderArm.Shoulder.MaxScapulaClaviculaDepressionAngle; - AnyVar MaxScapulaClaviculaProtractionAngle ??= ...Right.ShoulderArm.Shoulder.MaxScapulaClaviculaProtractionAngle; - AnyVar MaxScapulaClaviculaRetractionAngle ??= ...Right.ShoulderArm.Shoulder.MaxScapulaClaviculaRetractionAngle; + AnyVar MaxGlenohumeralFlexionAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.MaxGlenohumeralFlexionAngle; + AnyVar MaxGlenohumeralExtensionAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.MaxGlenohumeralExtensionAngle; + AnyVar MaxGlenohumeralAbductionAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.MaxGlenohumeralAbductionAngle; + AnyVar MaxGlenohumeralAdductionAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.MaxGlenohumeralAdductionAngle; + AnyVar MaxGlenohumeralExternalRotationAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.MaxGlenohumeralExternalRotationAngle; + AnyVar MaxGlenohumeralInternalRotationAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.MaxGlenohumeralInternalRotationAngle; + AnyVar MaxScapulaClaviculaElevationAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.MaxScapulaClaviculaElevationAngle; + AnyVar MaxScapulaClaviculaDepressionAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.MaxScapulaClaviculaDepressionAngle; + AnyVar MaxScapulaClaviculaProtractionAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.MaxScapulaClaviculaProtractionAngle; + AnyVar MaxScapulaClaviculaRetractionAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.MaxScapulaClaviculaRetractionAngle; // Shoulder positions - AnyFloat Neutral ??= ...Right.ShoulderArm.Shoulder.Neutral; - AnyFloat Flexed ??= ...Right.ShoulderArm.Shoulder.Flexed; - AnyFloat Extended ??= ...Right.ShoulderArm.Shoulder.Extended; - AnyFloat Abducted ??= ...Right.ShoulderArm.Shoulder.Abducted; - AnyFloat Adducted ??= ...Right.ShoulderArm.Shoulder.Adducted; - AnyFloat ExternallyRotated ??= ...Right.ShoulderArm.Shoulder.ExternallyRotated; - AnyFloat InternallyRotated ??= ...Right.ShoulderArm.Shoulder.InternallyRotated; - AnyFloat FlexedAndExternallyRotated ??= ...Right.ShoulderArm.Shoulder.FlexedAndExternallyRotated; - AnyFloat FlexedAndInternallyRotated ??= ...Right.ShoulderArm.Shoulder.FlexedAndInternallyRotated; - AnyFloat ExtendedAndExternallyRotated ??= ...Right.ShoulderArm.Shoulder.ExtendedAndExternallyRotated; - AnyFloat ExtendedAndInternallyRotated ??= ...Right.ShoulderArm.Shoulder.ExtendedAndInternallyRotated; - AnyFloat FlexedAndAdducted ??= ...Right.ShoulderArm.Shoulder.FlexedAndAdducted; - AnyFloat FlexedAndAbducted ??= ...Right.ShoulderArm.Shoulder.FlexedAndAbducted; + AnyFloat Neutral ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.Neutral; + AnyFloat Flexed ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.Flexed; + AnyFloat Extended ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.Extended; + AnyFloat Abducted ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.Abducted; + AnyFloat Adducted ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.Adducted; + AnyFloat ExternallyRotated ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.ExternallyRotated; + AnyFloat InternallyRotated ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.InternallyRotated; + AnyFloat FlexedAndExternallyRotated ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.FlexedAndExternallyRotated; + AnyFloat FlexedAndInternallyRotated ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.FlexedAndInternallyRotated; + AnyFloat ExtendedAndExternallyRotated ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.ExtendedAndExternallyRotated; + AnyFloat ExtendedAndInternallyRotated ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.ExtendedAndInternallyRotated; + AnyFloat FlexedAndAdducted ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.FlexedAndAdducted; + AnyFloat FlexedAndAbducted ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.FlexedAndAbducted; }; Left.ShoulderArm.Elbow = { - AnyVar MaxFlexionAngle ??= ...Right.ShoulderArm.Elbow.MaxFlexionAngle; - AnyVar MaxExtensionAngle ??= ...Right.ShoulderArm.Elbow.MaxExtensionAngle; - AnyVar MaxPronationAngle ??= ...Right.ShoulderArm.Elbow.MaxPronationAngle; - AnyVar MaxSupinationAngle ??= ...Right.ShoulderArm.Elbow.MaxSupinationAngle; + AnyVar MaxFlexionAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Elbow.MaxFlexionAngle; + AnyVar MaxExtensionAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Elbow.MaxExtensionAngle; + AnyVar MaxPronationAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Elbow.MaxPronationAngle; + AnyVar MaxSupinationAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Elbow.MaxSupinationAngle; }; Left.ShoulderArm.Wrist = { - AnyVar MaxFlexionAngle ??= ...Right.ShoulderArm.Wrist.MaxFlexionAngle; - AnyVar MaxExtensionAngle ??= ...Right.ShoulderArm.Wrist.MaxExtensionAngle; - AnyVar MaxAbductionAngle ??= ...Right.ShoulderArm.Wrist.MaxAbductionAngle; - AnyVar MaxAdductionAngle ??= ...Right.ShoulderArm.Wrist.MaxAdductionAngle; + AnyVar MaxFlexionAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Wrist.MaxFlexionAngle; + AnyVar MaxExtensionAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Wrist.MaxExtensionAngle; + AnyVar MaxAbductionAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Wrist.MaxAbductionAngle; + AnyVar MaxAdductionAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Wrist.MaxAdductionAngle; }; #endif #if BM_LEG_LEFT & (BM_LEG_MODEL == _LEG_MODEL_TLEM2_) // 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; + AnyVar MaxExternalRotationAngle ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Hip.MaxExternalRotationAngle; + AnyVar MaxInternalRotationAngle ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Hip.MaxInternalRotationAngle; + AnyVar MaxAdductionAngle ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Hip.MaxAdductionAngle; + AnyVar MaxAdductionInExtensionAngle ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Hip.MaxAdductionInExtensionAngle; + AnyVar MaxAbductionAngle ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Hip.MaxAbductionAngle; + AnyVar MaxFlexionAngle ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Hip.MaxFlexionAngle; + AnyVar MaxExtensionAngle ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Hip.MaxExtensionAngle; + AnyVar MaxExtensionInAdductionAngle ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Hip.MaxExtensionInAdductionAngle; + AnyVar MaxFlexionInAbductionAngle ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Hip.MaxFlexionInAbductionAngle; + AnyVar MinFlexionInAdduction ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.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 Abduction ??= ...Right.Leg.Hip.Abduction; - 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; + AnyFloat Neutral ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Hip.Neutral; + AnyFloat InternallyRotated ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Hip.InternallyRotated; + AnyFloat ExternallyRotated ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Hip.ExternallyRotated; + AnyFloat Adduction ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Hip.Adduction; + AnyFloat Abduction ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Hip.Abduction; + AnyFloat Flexed ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Hip.Flexed; + AnyFloat FlexedAndAdducted ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Hip.FlexedAndAdducted; + AnyFloat FlexedAndAbducted ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Hip.FlexedAndAbducted; + AnyFloat Extended ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Hip.Extended; + AnyFloat ExtendedAndAdducted ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Hip.ExtendedAndAdducted; + AnyFloat AbductedAndExternallyRotated ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Hip.AbductedAndExternallyRotated; - AnyObjectPtr ActiveRoM ??= ...Right.Leg.Hip.ActiveRoM; + AnyObjectPtr ActiveRoM ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Hip.ActiveRoM; }; Left.Leg.Knee = { - AnyVar Neutral ??= ...Right.Leg.Knee.Neutral; - AnyVar MaxFlexionAngle ??= ...Right.Leg.Knee.MaxFlexionAngle; - AnyVar MaxExtensionAngle ??= ...Right.Leg.Knee.MaxExtensionAngle; + AnyVar Neutral ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Knee.Neutral; + AnyVar MaxFlexionAngle ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Knee.MaxFlexionAngle; + AnyVar MaxExtensionAngle ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Knee.MaxExtensionAngle; - AnyObjectPtr ActiveRoM ??= ...Right.Leg.Knee.ActiveRoM; + AnyObjectPtr ActiveRoM ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Knee.ActiveRoM; }; 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; + AnyVar Neutral ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Ankle.Neutral; + AnyVar MaxPlantarFlexionAngle ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Ankle.MaxPlantarFlexionAngle; + AnyVar MaxDorsiFlexionAngle ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Ankle.MaxDorsiFlexionAngle; + AnyVar MaxInversionAngle ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Ankle.MaxInversionAngle; + AnyVar MaxEversionAngle ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Ankle.MaxEversionAngle; - AnyObjectPtr ActiveRoM ??= ...Right.Leg.Ankle.ActiveRoM; + AnyObjectPtr ActiveRoM ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Ankle.ActiveRoM; }; #endif }; \ No newline at end of file diff --git a/Body/AAUHuman/LegTLEM/Calibration/2ParLeftCalStudies.any b/Body/AAUHuman/LegTLEM/Calibration/2ParLeftCalStudies.any index feb6c2d22..ce71c9e69 100644 --- a/Body/AAUHuman/LegTLEM/Calibration/2ParLeftCalStudies.any +++ b/Body/AAUHuman/LegTLEM/Calibration/2ParLeftCalStudies.any @@ -1,8 +1,9 @@ -LegCalibrationStudy LeftCal1Hip( +TwoParCalibrationStudy LeftCal1Hip( BodyModelRef = Main.HumanModel.BodyModel, Side = Left, +HIP = On ) = { - nStep = .RightCal1Hip.nStep; + nStep = NumElemOf(HipPositions); MuscleArr = ObjSearch( &..BodyModel.Left.Leg.Mus, @@ -21,18 +22,16 @@ Side = Left, "AnyMuscle" ); - RminMuscleFiber = .RightCal1Hip.RminMuscleFiber; - RmaxMuscleFiber = .RightCal1Hip.RmaxMuscleFiber; - - HipPositions = .RightCal1Hip.HipPositions; - KneePositions = .RightCal1Hip.KneePositions; - AnklePositions = .RightCal1Hip.AnklePositions; - SubTalarPositions = .RightCal1Hip.SubTalarPositions; + HipPositions = repmat(2, flattenptr(&.RangeOfMotion.Left.Leg.Hip.ActiveRoM)); }; -LegCalibrationStudy LeftCal2HipSpine( +TwoParCalibrationStudy LeftCal2HipSpine( BodyModelRef = Main.HumanModel.BodyModel, Side = Left, +HIP = On, +TRUNKFLEXION = On, +TRUNKLATERALBENDING = On, +TRUNKROTATION = On, ) = { nStep = NumElemOf(HipPositions); @@ -44,18 +43,17 @@ Side = Left, "AnyMuscle" ); - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - HipPositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Hip.ActiveRoM)); - KneePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Knee.Neutral); - AnklePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); - SubTalarPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); + HipPositions = repmat(2, flattenptr(&.RangeOfMotion.Left.Leg.Hip.Neutral)); + TrunkFlexionPositions = repmat(2, flattenptr(&.RangeOfMotion.Trunk.Neutral)); + TrunkLateralBendingPositions = repmat(2, flattenptr(&.RangeOfMotion.Trunk.Neutral)); + TrunkRotationPositions = repmat(2, flattenptr(&.RangeOfMotion.Trunk.Neutral)); }; -LegCalibrationStudy LeftCal3HipKnee( +TwoParCalibrationStudy LeftCal3HipKnee( BodyModelRef = Main.HumanModel.BodyModel, Side = Left, +HIP = On, +KNEE = On, ) = { nStep = NumElemOf(HipPositions); @@ -73,18 +71,14 @@ Side = Left, "AnyMuscle" ); - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - HipPositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Hip.ActiveRoM)); - KneePositions = repmat(10, flattenptr(&.RangeOfMotion.Right.Leg.Knee.ActiveRoM)); - AnklePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); - SubTalarPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); + HipPositions = repmat(2, flattenptr(&.RangeOfMotion.Left.Leg.Hip.ActiveRoM)); + KneePositions = repmat(10, flattenptr(&.RangeOfMotion.Left.Leg.Knee.ActiveRoM)); }; -LegCalibrationStudy LeftCal4Knee( +TwoParCalibrationStudy LeftCal4Knee( BodyModelRef = Main.HumanModel.BodyModel, Side = Left, +KNEE = On, ) = { nStep = NumElemOf(KneePositions); @@ -98,18 +92,14 @@ Side = Left, "AnyMuscle" ); - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - HipPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Hip.Neutral); - KneePositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Knee.ActiveRoM)); - AnklePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); - SubTalarPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); + KneePositions = repmat(2, flattenptr(&.RangeOfMotion.Left.Leg.Knee.ActiveRoM)); }; -LegCalibrationStudy LeftCal5AnkleKnee( +TwoParCalibrationStudy LeftCal5AnkleKnee( BodyModelRef = Main.HumanModel.BodyModel, Side = Left, +KNEE = On, +ANKLE = On, ) = { nStep = NumElemOf(AnklePositions); @@ -123,18 +113,14 @@ Side = Left, "AnyMuscle" ); - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - HipPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Hip.Neutral); - KneePositions = repmat(4, flattenptr(&.RangeOfMotion.Right.Leg.Knee.ActiveRoM)); - AnklePositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Ankle.ActiveRoM)); - SubTalarPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); + KneePositions = repmat(4, flattenptr(&.RangeOfMotion.Left.Leg.Knee.ActiveRoM)); + AnklePositions = repmat(2, flattenptr(&.RangeOfMotion.Left.Leg.Ankle.ActiveRoM)); }; -LegCalibrationStudy LeftCal6Ankle( +TwoParCalibrationStudy LeftCal6Ankle( BodyModelRef = Main.HumanModel.BodyModel, Side = Left, +ANKLE = On, ) = { nStep = NumElemOf(AnklePositions); MuscleArr = ObjSearch( @@ -148,13 +134,7 @@ Side = Left, "AnyMuscle" ); - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - HipPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Hip.Neutral); - KneePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Knee.Neutral); - AnklePositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Ankle.ActiveRoM)); - SubTalarPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); + AnklePositions = repmat(2, flattenptr(&.RangeOfMotion.Left.Leg.Ankle.ActiveRoM)); }; diff --git a/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any b/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any index b53a622d0..3f67a26e2 100644 --- a/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any +++ b/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any @@ -1,6 +1,7 @@ -LegCalibrationStudy RightCal1Hip( +TwoParCalibrationStudy RightCal1Hip( BodyModelRef=Main.HumanModel.BodyModel, Side=Right, + HIP = On ) = { nStep = NumElemOf(HipPositions); @@ -20,19 +21,17 @@ LegCalibrationStudy RightCal1Hip( }, "AnyMuscle" ); - - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); HipPositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Hip.ActiveRoM)); - KneePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Knee.Neutral); - AnklePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); - SubTalarPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); }; -LegCalibrationStudy RightCal2HipSpine( +TwoParCalibrationStudy RightCal2HipSpine( BodyModelRef=Main.HumanModel.BodyModel, Side=Right, + HIP = On, + TRUNKFLEXION = On, + TRUNKLATERALBENDING = On, + TRUNKROTATION = On, ) = { nStep = NumElemOf(HipPositions); @@ -43,19 +42,18 @@ LegCalibrationStudy RightCal2HipSpine( }, "AnyMuscle" ); - - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - HipPositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Hip.ActiveRoM)); - KneePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Knee.Neutral); - AnklePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); - SubTalarPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); + HipPositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Hip.Neutral)); + TrunkFlexionPositions = repmat(2, flattenptr(&.RangeOfMotion.Trunk.Neutral)); + TrunkLateralBendingPositions = repmat(2, flattenptr(&.RangeOfMotion.Trunk.Neutral)); + TrunkRotationPositions = repmat(2, flattenptr(&.RangeOfMotion.Trunk.Neutral)); }; -LegCalibrationStudy RightCal3HipKnee( +TwoParCalibrationStudy RightCal3HipKnee( BodyModelRef=Main.HumanModel.BodyModel, Side=Right, + HIP = On, + KNEE = On, ) = { nStep = NumElemOf(HipPositions); @@ -72,19 +70,15 @@ LegCalibrationStudy RightCal3HipKnee( }, "AnyMuscle" ); - - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); HipPositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Hip.ActiveRoM)); KneePositions = repmat(10, flattenptr(&.RangeOfMotion.Right.Leg.Knee.ActiveRoM)); - AnklePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); - SubTalarPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); }; -LegCalibrationStudy RightCal4Knee( +TwoParCalibrationStudy RightCal4Knee( BodyModelRef=Main.HumanModel.BodyModel, Side=Right, + KNEE = On, ) = { nStep = NumElemOf(KneePositions); @@ -97,19 +91,15 @@ LegCalibrationStudy RightCal4Knee( }, "AnyMuscle" ); - - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - HipPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Hip.Neutral); KneePositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Knee.ActiveRoM)); - AnklePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); - SubTalarPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); }; -LegCalibrationStudy RightCal5AnkleKnee( +TwoParCalibrationStudy RightCal5AnkleKnee( BodyModelRef=Main.HumanModel.BodyModel, Side=Right, + KNEE = On, + ANKLE = On, ) = { nStep = NumElemOf(AnklePositions); @@ -122,19 +112,15 @@ LegCalibrationStudy RightCal5AnkleKnee( }, "AnyMuscle" ); - - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - HipPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Hip.Neutral); KneePositions = repmat(4, flattenptr(&.RangeOfMotion.Right.Leg.Knee.ActiveRoM)); AnklePositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Ankle.ActiveRoM)); - SubTalarPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); }; -LegCalibrationStudy RightCal6Ankle( +TwoParCalibrationStudy RightCal6Ankle( BodyModelRef=Main.HumanModel.BodyModel, Side=Right, + ANKLE = On, ) = { nStep = NumElemOf(AnklePositions); MuscleArr = ObjSearch( @@ -148,21 +134,15 @@ LegCalibrationStudy RightCal6Ankle( "AnyMuscle" ); - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - HipPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Hip.Neutral); - KneePositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Knee.Neutral); AnklePositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Ankle.ActiveRoM)); - SubTalarPositions = repmat(nStep, &.RangeOfMotion.Right.Leg.Ankle.Neutral); }; CalibrationSequence = { AnyOperation &LegCal1Right = .RightCal1Hip.FiberAndTendonLengthAdjustment; - // AnyOperation &LegCal2Right = .RightCal2HipSpine.FiberAndTendonLengthAdjustment; - // AnyOperation &LegCal3Right = .RightCal3HipKnee.FiberAndTendonLengthAdjustment; - // AnyOperation &LegCal4Right = .RightCal4Knee.FiberAndTendonLengthAdjustment; - // AnyOperation &LegCal5Right = .RightCal5AnkleKnee.FiberAndTendonLengthAdjustment; - // AnyOperation &LegCal6Right = .RightCal6Ankle.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal2Right = .RightCal2HipSpine.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal3Right = .RightCal3HipKnee.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal4Right = .RightCal4Knee.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal5Right = .RightCal5AnkleKnee.FiberAndTendonLengthAdjustment; + AnyOperation &LegCal6Right = .RightCal6Ankle.FiberAndTendonLengthAdjustment; }; \ No newline at end of file From 91512f737345f439022d728064c9bfa63487e407 Mon Sep 17 00:00:00 2001 From: bke Date: Tue, 8 Apr 2025 14:45:48 +0200 Subject: [PATCH 16/29] update w. spine ActiveRoM --- .../Calibration/RangeOfMotionDefinition.any | 8 ++++- .../Calibration/2ParRightCalStudies.any | 8 ++--- Body/AAUHuman/Trunk/rangeOfMotion.any | 30 +++++++++++++++++++ 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any index d7c587400..41dbb7497 100644 --- a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any +++ b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any @@ -21,7 +21,13 @@ BodyModelFolderStructure RangeOfMotion() = { AnyVar MaxPelvisSacrumLateralBendingAngle ??= ...BodyModel.Trunk.Data.RangeOfMotion.MaxPelvisSacrumLateralBendingAngle; AnyVar MinPelvisSacrumLateralBendingAngle ??= ...BodyModel.Trunk.Data.RangeOfMotion.MinPelvisSacrumLateralBendingAngle; AnyVar Neutral ??= ...BodyModel.Trunk.Data.RangeOfMotion.Neutral; - + + AnyObjectPtr ActiveRoMThoraxFlexion ??= ...BodyModel.Trunk.Data.RangeOfMotion.ActiveRoMThoraxFlexion; + AnyObjectPtr ActiveRoMThoraxLateralBending ??= ...BodyModel.Trunk.Data.RangeOfMotion.ActiveRoMThoraxLateralBending; + AnyObjectPtr ActiveRoMThoraxAxialRotation ??= ...BodyModel.Trunk.Data.RangeOfMotion.ActiveRoMThoraxAxialRotation; + AnyObjectPtr ActiveRoMSkullFlexion ??= ...BodyModel.Trunk.Data.RangeOfMotion.ActiveRoMSkullFlexion; + AnyObjectPtr ActiveRoMSkullLateralBending ??= ...BodyModel.Trunk.Data.RangeOfMotion.ActiveRoMSkullLateralBending; + AnyObjectPtr ActiveRoMSkullAxialRotation ??= ...BodyModel.Trunk.Data.RangeOfMotion.ActiveRoMSkullAxialRotation; }; #if BM_ARM_RIGHT diff --git a/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any b/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any index 3f67a26e2..5550b219f 100644 --- a/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any +++ b/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any @@ -43,10 +43,10 @@ TwoParCalibrationStudy RightCal2HipSpine( "AnyMuscle" ); - HipPositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Hip.Neutral)); - TrunkFlexionPositions = repmat(2, flattenptr(&.RangeOfMotion.Trunk.Neutral)); - TrunkLateralBendingPositions = repmat(2, flattenptr(&.RangeOfMotion.Trunk.Neutral)); - TrunkRotationPositions = repmat(2, flattenptr(&.RangeOfMotion.Trunk.Neutral)); + HipPositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Hip.ActiveRoM)); + TrunkFlexionPositions = repmat(10, flattenptr(&.RangeOfMotion.Trunk.ActiveRoMThoraxFlexion)); + TrunkLateralBendingPositions = repmat(10, flattenptr(&.RangeOfMotion.Trunk.ActiveRoMThoraxLateralBending)); + TrunkRotationPositions = repmat(10, flattenptr(&.RangeOfMotion.Trunk.ActiveRoMThoraxAxialRotation)); }; TwoParCalibrationStudy RightCal3HipKnee( diff --git a/Body/AAUHuman/Trunk/rangeOfMotion.any b/Body/AAUHuman/Trunk/rangeOfMotion.any index da17b9500..d41dc38b0 100644 --- a/Body/AAUHuman/Trunk/rangeOfMotion.any +++ b/Body/AAUHuman/Trunk/rangeOfMotion.any @@ -18,7 +18,37 @@ AnyFolder RangeOfMotion = { AnyVar MaxPelvisSacrumLateralBendingAngle = 5; AnyVar MinPelvisSacrumLateralBendingAngle = -5; AnyVar Neutral = 0; + + AnyObjectPtrArray ActiveRoMThoraxFlexion = { + &MaxPelvisThoraxFlexionAngle, + &MaxPelvisThoraxExtensionAngle, + }; + + AnyObjectPtrArray ActiveRoMThoraxLateralBending = { + &MaxPelvisThoraxLateralBendingAngle, + &MinPelvisThoraxLateralBendingAngle, + }; + + AnyObjectPtrArray ActiveRoMThoraxAxialRotation = { + &MaxPelvisThoraxAxialRotationAngle, + &MinPelvisThoraxAxialRotationAngle, + }; + AnyObjectPtrArray ActiveRoMSkullFlexion = { + &MaxSkullThoraxFlexionAngle, + &MaxSkullThoraxExtensionAngle, + }; + + AnyObjectPtrArray ActiveRoMSkullLateralBending = { + &MaxSkullThoraxLateralBendingAngle, + &MinSkullThoraxLateralBendingAngle, + }; + + AnyObjectPtrArray ActiveRoMSkullAxialRotation = { + &MaxSkullThoraxAxialRotationAngle, + &MinSkullThoraxAxialRotationAngle, + }; + // AnyFolder Right = {}; // AnyFolder Left = {}; }; \ No newline at end of file From b616fd700c3588f0897174751ede995ebda353d1 Mon Sep 17 00:00:00 2001 From: bke Date: Tue, 8 Apr 2025 15:18:02 +0200 Subject: [PATCH 17/29] start refactor arm studies --- .../Arm/Calibration/2ParLeftCalStudies.any | 41 ++-- .../Arm/Calibration/2ParRightCalStudies.any | 47 +---- Body/AAUHuman/Arm/rangeOfMotion.any | 29 +++ .../CalibrationStudy.ClassTemplates.any | 191 +----------------- .../Calibration/RangeOfMotionDefinition.any | 18 +- 5 files changed, 84 insertions(+), 242 deletions(-) diff --git a/Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any b/Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any index 70e71965a..4ae6afd76 100644 --- a/Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any +++ b/Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any @@ -1,8 +1,9 @@ -ArmCalibrationStudy ArmCalibration1Left( +TwoParCalibrationStudy LeftCal1Shoulder( BodyModelRef = Main.HumanModel.BodyModel, Side = Left, +SHOULDER = On ) = { - nStep = .ArmCalibration1Right.nStep; + nStep = NumElemOf(ShoulderPositions); MuscleArr = ObjSearch( &..BodyModel.Left.ShoulderArm.Muscles, @@ -23,20 +24,30 @@ Side = Left, "AnyMuscle" ); - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - ShoulderPositions = .ArmCalibration1Right.ShoulderPositions; - ScapulaElevationPositions = .ArmCalibration1Right.ScapulaElevationPositions; - ScapulaProtractionPositions = .ArmCalibration1Right.ScapulaProtractionPositions; - ElbowFlexionPositions = .ArmCalibration1Right.ElbowFlexionPositions; - ElbowPronationPositions = .ArmCalibration1Right.ElbowPronationPositions; - WristFlexionPositions = .ArmCalibration1Right.WristFlexionPositions; - WristAbductionPositions = .ArmCalibration1Right.WristAbductionPositions; + ShoulderPositions = flattenptr(&.RangeOfMotion.Left.ShoulderArm.Shoulder.ActiveRoM); }; +TwoParCalibrationStudy LeftCal2Elbow( + BodyModelRef = Main.HumanModel.BodyModel, + Side = Left, + ELBOWFLEXION = On +) = { + nStep = NumElemOf(ElbowFlexionPositions); + + MuscleArr = ObjSearch( + &..BodyModel.Left.ShoulderArm.Muscles, + { + "Anoconeus.*", + "BicepsBrachii.*", + "Brachialis.*", + "Brachioradialis.*", + "Coracobrachialis.*", + "Triceps.*", + }, + "AnyMuscle" + ); + + ElbowFlexionPositions = flattenptr(&.RangeOfMotion.Left.ShoulderArm.Elbow.ActiveRoM); +}; -CalibrationSequence = { - AnyOperation &ArmCal1Left = .ArmCalibration1Left.FiberAndTendonLengthAdjustment; -}; \ No newline at end of file diff --git a/Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any b/Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any index afa5a1589..b4cca9846 100644 --- a/Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any +++ b/Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any @@ -1,6 +1,7 @@ -ArmCalibrationStudy ArmCalibration1Right( +TwoParCalibrationStudy RightCal1Shoulder( BodyModelRef=Main.HumanModel.BodyModel, Side=Right, + SHOULDER = On, ) = { nStep = NumElemOf(ShoulderPositions); @@ -23,47 +24,5 @@ ArmCalibrationStudy ArmCalibration1Right( "AnyMuscle" ); - RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); - RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); - - ShoulderPositions = repmat(2,{ - &.RangeOfMotion.Right.ShoulderArm.Shoulder.Flexed, - &.RangeOfMotion.Right.ShoulderArm.Shoulder.Extended, - &.RangeOfMotion.Right.ShoulderArm.Shoulder.Abducted, - &.RangeOfMotion.Right.ShoulderArm.Shoulder.Adducted, - &.RangeOfMotion.Right.ShoulderArm.Shoulder.ExternallyRotated, - &.RangeOfMotion.Right.ShoulderArm.Shoulder.InternallyRotated, - &.RangeOfMotion.Right.ShoulderArm.Shoulder.FlexedAndExternallyRotated, - &.RangeOfMotion.Right.ShoulderArm.Shoulder.FlexedAndInternallyRotated, - &.RangeOfMotion.Right.ShoulderArm.Shoulder.ExtendedAndExternallyRotated, - &.RangeOfMotion.Right.ShoulderArm.Shoulder.ExtendedAndInternallyRotated, - &.RangeOfMotion.Right.ShoulderArm.Shoulder.FlexedAndAdducted, - &.RangeOfMotion.Right.ShoulderArm.Shoulder.FlexedAndAbducted, - }); - - ScapulaElevationPositions = flatten({ - repmat(round(nStep/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaElevationAngle), - repmat(round(nStep/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaDepressionAngle) - }); - - ScapulaProtractionPositions = flatten({ - repmat(round(nStep/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaProtractionAngle), - repmat(round(nStep/2), &.RangeOfMotion.Right.ShoulderArm.Shoulder.MaxScapulaClaviculaRetractionAngle) - }); - - ElbowFlexionPositions = flatten({ - repmat(round(nStep/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxFlexionAngle), - repmat(round(nStep/2), &.RangeOfMotion.Right.ShoulderArm.Elbow.MaxExtensionAngle) - }); - - ElbowPronationPositions = repmat(nStep, &.RangeOfMotion.Right.ShoulderArm.Elbow.Neutral); - WristFlexionPositions = repmat(nStep, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); - WristAbductionPositions = repmat(nStep, &.RangeOfMotion.Right.ShoulderArm.Wrist.Neutral); - -}; - - - -CalibrationSequence = { - AnyOperation &ArmCal1Right = .ArmCalibration1Right.FiberAndTendonLengthAdjustment; + ShoulderPositions = flattenptr(&.RangeOfMotion.Right.ShoulderArm.Shoulder.ActiveRoM); }; \ No newline at end of file diff --git a/Body/AAUHuman/Arm/rangeOfMotion.any b/Body/AAUHuman/Arm/rangeOfMotion.any index 40773ad32..963c450b7 100644 --- a/Body/AAUHuman/Arm/rangeOfMotion.any +++ b/Body/AAUHuman/Arm/rangeOfMotion.any @@ -12,6 +12,7 @@ AnyFolder RangeOfMotion = { AnyVar MaxScapulaClaviculaDepressionAngle = -5; AnyVar MaxScapulaClaviculaProtractionAngle = 15; AnyVar MaxScapulaClaviculaRetractionAngle = -36; + AnyVar ScapulaNeutral = 0; // Shoulder positions AnyFloat Neutral = {0, 0, 0}; @@ -28,6 +29,20 @@ AnyFolder RangeOfMotion = { AnyFloat FlexedAndAdducted = {MaxGlenohumeralFlexionAngle, MaxGlenohumeralAdductionAngle, 0}; AnyFloat FlexedAndAbducted = {MaxGlenohumeralFlexionAngle, MaxGlenohumeralAbductionAngle, 0}; + AnyObjectPtr ActiveRoM = { + &Flexed, + &Extended, + &Abducted, + &Adducted, + &ExternallyRotated, + &InternallyRotated, + &FlexedAndExternallyRotated, + &FlexedAndInternallyRotated, + &ExtendedAndExternallyRotated, + &ExtendedAndInternallyRotated, + &FlexedAndAdducted, + &FlexedAndAbducted, + }; }; AnyFolder Elbow = { @@ -36,6 +51,13 @@ AnyFolder RangeOfMotion = { AnyVar MaxPronationAngle = 90; AnyVar MaxSupinationAngle = -90; AnyVar Neutral = 0; + + AnyObjectPtrArray ActiveRoM = { + &MaxFlexionAngle, + &MaxExtensionAngle, + &MaxPronationAngle, + &MaxSupinationAngle, + }; }; AnyFolder Wrist = { @@ -44,5 +66,12 @@ AnyFolder RangeOfMotion = { AnyVar MaxAbductionAngle = 20; AnyVar MaxAdductionAngle = -35; AnyVar Neutral = 0; + + AnyObjectPtrArray ActiveRoM = { + &MaxFlexionAngle, + &MaxExtensionAngle, + &MaxAbductionAngle, + &MaxAdductionAngle, + }; }; }; \ No newline at end of file diff --git a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any index 4908d89ca..579b72314 100644 --- a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any +++ b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any @@ -31,189 +31,15 @@ __CLASS__ = AnyKinEqInterPolDriver, 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 TrunkCalibrationModel(Side, BodyModelRef) { - - AnyVar nStep = .nStep; - - #var AnyObjectPtr TrunkFlexionPositions = repmat(.nStep, &..RangeOfMotion.Trunk.Neutral); - #var AnyObjectPtr TrunkLateralBendingPositions = repmat(.nStep, &..RangeOfMotion.Trunk.Neutral); - #var AnyObjectPtr TrunkRotationPositions = repmat(.nStep, &..RangeOfMotion.Trunk.Neutral); - #var AnyObjectPtr SkullFlexionPositions = repmat(.nStep, &..RangeOfMotion.Trunk.Neutral); - #var AnyObjectPtr SkullLateralBendingPositions = repmat(.nStep, &..RangeOfMotion.Trunk.Neutral); - #var AnyObjectPtr SkullRotationPositions = repmat(.nStep, &..RangeOfMotion.Trunk.Neutral); - - AnyFolder &TrunkSegments = BodyModelRef.Trunk.Segments; - AnyFolder &TrunkJoints = BodyModelRef.Trunk.Joints; - - // Constraints - AnyFixedRefFrame ground = { - AnyRefNode node = { - ARel = ..TrunkSegments.PelvisSeg.Axes0; - sRel = ..TrunkSegments.PelvisSeg.r0; - }; - }; - - SingleDoFCalDriver TrunkFlexion( - Measure = BodyModelRef.Interface.Trunk.PelvisThoraxExtension, - DriverData = .TrunkFlexionPositions - ) ={}; - - SingleDoFCalDriver TrunkLateralBending( - Measure = BodyModelRef.Interface.Trunk.PelvisThoraxLateralBending, - DriverData = .TrunkLateralBendingPositions - ) ={}; - - SingleDoFCalDriver TrunkRotation( - Measure = BodyModelRef.Interface.Trunk.PelvisThoraxRotation, - DriverData = .TrunkRotationPositions - ) ={}; - - SingleDoFCalDriver SkullFlexion( - Measure = BodyModelRef.Interface.Trunk.SkullThoraxFlexion, - DriverData = .SkullFlexionPositions - ) ={}; - - SingleDoFCalDriver SkullLateralBending( - Measure = BodyModelRef.Interface.Trunk.SkullThoraxLateralBending, - DriverData = .SkullLateralBendingPositions - ) ={}; - - SingleDoFCalDriver SkullRotation( - Measure = BodyModelRef.Interface.Trunk.SkullThoraxRotation, - DriverData = .SkullRotationPositions - ) ={}; - - AnyKinEq PelvisFix = { - AnyKinLinear Lin = { - AnyRefFrame &ground = ..ground.node; - AnyRefFrame &Pelvis = ..TrunkSegments.PelvisSeg; - }; - AnyKinRotational Rot = { - Type = RotAxesAngles; - AnyRefFrame &ground = ..ground.node; - AnyRefFrame &Pelvis = ..TrunkSegments.PelvisSeg; - }; - }; -}; - /** - 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; - - #var AnyObjectPtr HipPositions; - #var AnyObjectPtr KneePositions; - #var AnyObjectPtr AnklePositions; - #var AnyObjectPtr SubTalarPositions; - - AnyFolder &Segments = BodyModelRef.Side.Leg.Seg; - AnyFolder &Joints = BodyModelRef.Side.Leg.Jnt; - - TrunkCalibrationModel TrunkModel(Side = Side, BodyModelRef = BodyModelRef) = {}; - - MultiDoFCalDriver Hip( - Measure = BodyModelRef.Interface.Side.HipFlexion.HipMeasure, - DriverData = .HipPositions - ) ={}; - - SingleDoFCalDriver Knee( - Measure = BodyModelRef.Interface.Side.KneeFlexion, - DriverData = .KneePositions - ) ={}; - - SingleDoFCalDriver Ankle( - Measure = BodyModelRef.Interface.Side.AnklePlantarFlexion, - DriverData = .AnklePositions - ) ={}; - - SingleDoFCalDriver SubTalar( - Measure = BodyModelRef.Interface.Side.SubTalarEversion, - DriverData = .SubTalarPositions - ) ={}; -}; - + Class template for creating calibration studies for the bodymodel. -/** - Class template for creating calibrationstudies with same settings + The template accepts arguments that define which DoF to include in the calibration study. + Enabling a DoF will create a driver for the DoF and add it to the calibration study. + The user will be required to provide an array of positions for each DoF that is enabled. + The positions are defined in degrees and will be converted to radians in the driver. */ -#class_template ArmCalibrationStudy( - __CLASS__ = AnyBodyCalibrationStudy, - BodyModelRef, - Side, -) { - // Study settings - FiberAndTendonLengthAdjustment.CalibrateTendonAtMaxForceOnOff = Off; - Kinematics.SmallStepAssumptionOnOff = Off; - InitialConditions.SmallStepAssumptionOnOff = Off; - Kinematics.PosAnalysisOnlyOnOff = On; - InitialConditions.PosAnalysisOnlyOnOff = On; - - #var AnyObjectPtr ShoulderPositions; - #var AnyObjectPtr ScapulaElevationPositions; - #var AnyObjectPtr ScapulaProtractionPositions; - #var AnyObjectPtr ElbowFlexionPositions; - #var AnyObjectPtr ElbowPronationPositions; - #var AnyObjectPtr WristFlexionPositions; - #var AnyObjectPtr WristAbductionPositions; - - AnyFolder &Segments = BodyModelRef.Side.ShoulderArm.Segments; - AnyFolder &Joints = BodyModelRef.Side.ShoulderArm.Joints; - - // The Muscles folder contain segments and constraints for some wrapping muscles - // e.g. Deltoid, Pectoralis Minor, etc. - AnyFolder &Muscles = BodyModelRef.Side.ShoulderArm.Muscles; - - TrunkCalibrationModel TrunkModel(Side = Side, BodyModelRef = BodyModelRef) = {}; - - MultiDoFCalDriver Shoulder( - Measure = BodyModelRef.Interface.Side.GlenohumeralFlexion.GHMeasure, - DriverData = .ShoulderPositions - ) ={}; - - SingleDoFCalDriver ScapulaProtraction( - Measure = BodyModelRef.Interface.Side.ScapulaThoraxProtraction, - DriverData = .ScapulaProtractionPositions - ) ={}; - - SingleDoFCalDriver ScapulaElevation( - Measure = BodyModelRef.Interface.Side.ScapulaThoraxElevation, - DriverData = .ScapulaElevationPositions - ) ={}; - - SingleDoFCalDriver ElbowFlexion( - Measure = BodyModelRef.Interface.Side.ElbowFlexion, - DriverData = .ElbowFlexionPositions - ) ={}; - - SingleDoFCalDriver ElbowPronation( - Measure = BodyModelRef.Interface.Side.ElbowPronation, - DriverData = .ElbowPronationPositions - ) ={}; - - SingleDoFCalDriver WristFlexion( - Measure = BodyModelRef.Interface.Side.WristFlexion, - DriverData = .WristFlexionPositions - ) ={}; - - SingleDoFCalDriver WristAbduction( - Measure = BodyModelRef.Interface.Side.WristAbduction, - DriverData = .WristAbductionPositions - ) ={}; - - #include "BMDependentObjects.any" -}; - #class_template TwoParCalibrationStudy( __CLASS__ = AnyBodyCalibrationStudy, BodyModelRef, @@ -243,6 +69,7 @@ __CLASS__ = AnyKinEqInterPolDriver, Kinematics.PosAnalysisOnlyOnOff = On; InitialConditions.PosAnalysisOnlyOnOff = On; + // Default values for Rmin and Rmax #var RminMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMinDefault); #var RmaxMuscleFiber = repmat(NumElemOf(MuscleArr), .RValues.RMaxDefault); @@ -337,7 +164,7 @@ __CLASS__ = AnyKinEqInterPolDriver, AnyObjectPtr SkullRotationPositions = repmat(nStep, &.RangeOfMotion.Trunk.Neutral); #endif - + // Arm #if (SHOULDER == On) | (SCAPULAELEVATION == On) | (SCAPULAPROTRACTION == On) | (ELBOWFLEXION == On) | (ELBOWPRONATION == On) | (WRISTFLEXION == On) | (WRISTABDUCTION == On) AnyFolder &ArmSegments = BodyModelRef.Side.ShoulderArm.Segments; AnyFolder &ArmJoints = BodyModelRef.Side.ShoulderArm.Joints; @@ -392,13 +219,13 @@ __CLASS__ = AnyKinEqInterPolDriver, #if SCAPULAELEVATION == On #var AnyObjectPtr ScapulaElevationPositions; #else - AnyObjectPtr ScapulaElevationPositions = repmat(nStep, &.RangeOfMotion.Side.ShoulderArm.Shoulder.Neutral); + AnyObjectPtr ScapulaElevationPositions = repmat(nStep, &.RangeOfMotion.Side.ShoulderArm.Shoulder.ScapulaNeutral); #endif #if SCAPULAPROTRACTION == On #var AnyObjectPtr ScapulaProtractionPositions; #else - AnyObjectPtr ScapulaProtractionPositions = repmat(nStep, &.RangeOfMotion.Side.ShoulderArm.Shoulder.Neutral); + AnyObjectPtr ScapulaProtractionPositions = repmat(nStep, &.RangeOfMotion.Side.ShoulderArm.Shoulder.ScapulaNeutral); #endif #if ELBOWFLEXION == On diff --git a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any index 41dbb7497..4372ed250 100644 --- a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any +++ b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any @@ -42,7 +42,8 @@ BodyModelFolderStructure RangeOfMotion() = { AnyVar MaxScapulaClaviculaDepressionAngle ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.MaxScapulaClaviculaDepressionAngle; AnyVar MaxScapulaClaviculaProtractionAngle ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.MaxScapulaClaviculaProtractionAngle; AnyVar MaxScapulaClaviculaRetractionAngle ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.MaxScapulaClaviculaRetractionAngle; - + AnyVar ScapulaNeutral ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.ScapulaNeutral; + // Shoulder positions AnyFloat Neutral ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.Neutral; AnyFloat Flexed ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.Flexed; @@ -57,6 +58,8 @@ BodyModelFolderStructure RangeOfMotion() = { AnyFloat ExtendedAndInternallyRotated ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.ExtendedAndInternallyRotated; AnyFloat FlexedAndAdducted ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.FlexedAndAdducted; AnyFloat FlexedAndAbducted ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.FlexedAndAbducted; + + AnyObjectPtr ActiveRoM ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.ActiveRoM; }; Right.ShoulderArm.Elbow = { @@ -65,6 +68,8 @@ BodyModelFolderStructure RangeOfMotion() = { AnyVar MaxPronationAngle ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Elbow.MaxPronationAngle; AnyVar MaxSupinationAngle ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Elbow.MaxSupinationAngle; AnyVar Neutral ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Elbow.Neutral; + + AnyObjectPtr ActiveRoM ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Elbow.ActiveRoM; }; Right.ShoulderArm.Wrist = { @@ -73,6 +78,8 @@ BodyModelFolderStructure RangeOfMotion() = { AnyVar MaxAbductionAngle ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Wrist.MaxAbductionAngle; AnyVar MaxAdductionAngle ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Wrist.MaxAdductionAngle; AnyVar Neutral ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Wrist.Neutral; + + AnyObjectPtr ActiveRoM ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Wrist.ActiveRoM; }; #endif @@ -136,6 +143,7 @@ BodyModelFolderStructure RangeOfMotion() = { AnyVar MaxScapulaClaviculaDepressionAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.MaxScapulaClaviculaDepressionAngle; AnyVar MaxScapulaClaviculaProtractionAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.MaxScapulaClaviculaProtractionAngle; AnyVar MaxScapulaClaviculaRetractionAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.MaxScapulaClaviculaRetractionAngle; + AnyVar ScapulaNeutral ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.ScapulaNeutral; // Shoulder positions AnyFloat Neutral ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.Neutral; @@ -151,6 +159,8 @@ BodyModelFolderStructure RangeOfMotion() = { AnyFloat ExtendedAndInternallyRotated ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.ExtendedAndInternallyRotated; AnyFloat FlexedAndAdducted ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.FlexedAndAdducted; AnyFloat FlexedAndAbducted ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.FlexedAndAbducted; + + AnyObjectPtr ActiveRoM ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.ActiveRoM; }; Left.ShoulderArm.Elbow = { @@ -158,6 +168,9 @@ BodyModelFolderStructure RangeOfMotion() = { AnyVar MaxExtensionAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Elbow.MaxExtensionAngle; AnyVar MaxPronationAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Elbow.MaxPronationAngle; AnyVar MaxSupinationAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Elbow.MaxSupinationAngle; + AnyVar Neutral ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Elbow.Neutral; + + AnyObjectPtr ActiveRoM ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Elbow.ActiveRoM; }; Left.ShoulderArm.Wrist = { @@ -165,6 +178,9 @@ BodyModelFolderStructure RangeOfMotion() = { AnyVar MaxExtensionAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Wrist.MaxExtensionAngle; AnyVar MaxAbductionAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Wrist.MaxAbductionAngle; AnyVar MaxAdductionAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Wrist.MaxAdductionAngle; + AnyVar Neutral ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Wrist.Neutral; + + AnyObjectPtr ActiveRoM ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Wrist.ActiveRoM; }; #endif From 05728f026a8a61c6c4d1b7fd81673365d95060cc Mon Sep 17 00:00:00 2001 From: bke Date: Wed, 9 Apr 2025 11:26:10 +0200 Subject: [PATCH 18/29] add studies for arms --- .../Arm/Calibration/2ParLeftCalStudies.any | 151 ++++++++++++++---- .../Arm/Calibration/2ParRightCalStudies.any | 126 ++++++++++++++- Body/AAUHuman/Arm/rangeOfMotion.any | 22 ++- .../Calibration/RangeOfMotionDefinition.any | 20 ++- .../test_calibration_lowerbody.any | 43 ++--- .../test_calibration_upperbody.any | 3 +- 6 files changed, 301 insertions(+), 64 deletions(-) diff --git a/Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any b/Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any index 4ae6afd76..a89ab82f7 100644 --- a/Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any +++ b/Body/AAUHuman/Arm/Calibration/2ParLeftCalStudies.any @@ -1,30 +1,30 @@ TwoParCalibrationStudy LeftCal1Shoulder( BodyModelRef = Main.HumanModel.BodyModel, -Side = Left, -SHOULDER = On + Side = Left, + SHOULDER = On ) = { nStep = NumElemOf(ShoulderPositions); MuscleArr = ObjSearch( - &..BodyModel.Left.ShoulderArm.Muscles, - { - "DeltoideusAnterior.*", - "DeltoideusLateral.*", - "DeltoideusPosterior.*", - "Infraspinatus.*", - "LatissimusDorsi.*", - "LevatorScapulae.*", - "PectoralisMajorClavicular.*", - "PectoralisMajorThoracic.*", - "PectoralisMinor.*", - "SerratusAnterior.*", - "Subscapularis.*", - "Supraspinatus.*", - }, - "AnyMuscle" + &..BodyModel.Left.ShoulderArm.Muscles, + { + "DeltoideusAnterior.*", + "DeltoideusLateral.*", + "DeltoideusPosterior.*", + "Infraspinatus.*", + "LatissimusDorsi.*", + "LevatorScapulae.*", + "PectoralisMajorClavicular.*", + "PectoralisMajorThoracic.*", + "PectoralisMinor.*", + "SerratusAnterior.*", + "Subscapularis.*", + "Supraspinatus.*", + }, + "AnyMuscle" ); - ShoulderPositions = flattenptr(&.RangeOfMotion.Left.ShoulderArm.Shoulder.ActiveRoM); + ShoulderPositions = flattenptr(&.RangeOfMotion.Left.ShoulderArm.Shoulder.ActiveRoMShoulder); }; TwoParCalibrationStudy LeftCal2Elbow( @@ -35,19 +35,110 @@ TwoParCalibrationStudy LeftCal2Elbow( nStep = NumElemOf(ElbowFlexionPositions); MuscleArr = ObjSearch( - &..BodyModel.Left.ShoulderArm.Muscles, - { - "Anoconeus.*", - "BicepsBrachii.*", - "Brachialis.*", - "Brachioradialis.*", - "Coracobrachialis.*", - "Triceps.*", - }, - "AnyMuscle" + &..BodyModel.Left.ShoulderArm.Muscles, + { + "Anconeus.*", + "BicepsBrachii.*", + "Brachialis.*", + "Brachioradialis.*", + "Coracobrachialis.*", + "Triceps.*", + }, + "AnyMuscle" ); - ElbowFlexionPositions = flattenptr(&.RangeOfMotion.Left.ShoulderArm.Elbow.ActiveRoM); + ElbowFlexionPositions = flattenptr(&.RangeOfMotion.Left.ShoulderArm.Elbow.ActiveRoMFlexion); }; +TwoParCalibrationStudy LeftCal3ElbowWrist( + BodyModelRef = Main.HumanModel.BodyModel, + Side = Left, + ELBOWFLEXION = On, + WRISTFLEXION = On +) = { + nStep = NumElemOf(ElbowFlexionPositions); + + MuscleArr = ObjSearch( + &..BodyModel.Left.ShoulderArm.Muscles, + { + "Extensor*.*", + "FlexorCarpi*.*", + "FlexorDigi*.*", + "PalmarisLongus.*", + }, + "AnyMuscle" + ); + + ElbowFlexionPositions = repmat(4, flattenptr(&.RangeOfMotion.Left.ShoulderArm.Elbow.ActiveRoMFlexion)); + WristFlexionPositions = repmat(4, flattenptr(&.RangeOfMotion.Left.ShoulderArm.Wrist.ActiveRoMFlexion)); +}; + +TwoParCalibrationStudy LeftCal4Wrist( + BodyModelRef = Main.HumanModel.BodyModel, + Side = Left, + WRISTFLEXION = On +) = { + nStep = NumElemOf(WristFlexionPositions); + + MuscleArr = ObjSearch( + &..BodyModel.Left.ShoulderArm.Muscles, + { + "AbductorPollicis.*", + "FlexorPollicis*.*", + }, + "AnyMuscle" + ); + + WristFlexionPositions = flattenptr(&.RangeOfMotion.Left.ShoulderArm.Wrist.ActiveRoMFlexion); +}; + +TwoParCalibrationStudy LeftCal5ScapulaClavicula( + BodyModelRef = Main.HumanModel.BodyModel, + Side = Left, + SCAPULAELEVATION = On, + SCAPULAPROTRACTION = On, +) = { + nStep = NumElemOf(ScapulaElevationPositions); + + MuscleArr = ObjSearch( + &..BodyModel.Left.ShoulderArm.Muscles, + { + "Rhomboideus.*", + "Sternocleidomastoid.*", + "Teres*.*", + "Trapezius*.*", + }, + "AnyMuscle" + ); + + ScapulaElevationPositions = repmat(2, flattenptr(&.RangeOfMotion.Left.ShoulderArm.Shoulder.ActiveRoMScapulaElevation)); + ScapulaProtractionPositions = repmat(2, flattenptr(&.RangeOfMotion.Left.ShoulderArm.Shoulder.ActiveRoMScapulaProtraction)); +}; + +TwoParCalibrationStudy LeftCal6ForearmPronationSupination( + BodyModelRef = Main.HumanModel.BodyModel, + Side = Left, + ELBOWPRONATION = On, +) = { + nStep = NumElemOf(ElbowPronationPositions); + + MuscleArr = ObjSearch( + &..BodyModel.Left.ShoulderArm.Muscles, + { + "Pronator*.*", + "Supinator.*", + }, + "AnyMuscle" + ); + + ElbowPronationPositions = flattenptr(&.RangeOfMotion.Left.ShoulderArm.Elbow.ActiveRoMPronation); +}; +CalibrationSequence = { + AnyOperation& LeftCal1Shoulder = .LeftCal1Shoulder.FiberAndTendonLengthAdjustment; + AnyOperation& LeftCal2Elbow = .LeftCal2Elbow.FiberAndTendonLengthAdjustment; + AnyOperation& LeftCal3ElbowWrist = .LeftCal3ElbowWrist.FiberAndTendonLengthAdjustment; + AnyOperation& LeftCal4Wrist = .LeftCal4Wrist.FiberAndTendonLengthAdjustment; + AnyOperation& LeftCal5ScapulaClavicula = .LeftCal5ScapulaClavicula.FiberAndTendonLengthAdjustment; + AnyOperation& LeftCal6ForearmPronationSupination = .LeftCal6ForearmPronationSupination.FiberAndTendonLengthAdjustment; +}; \ No newline at end of file diff --git a/Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any b/Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any index b4cca9846..d0b8cbc61 100644 --- a/Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any +++ b/Body/AAUHuman/Arm/Calibration/2ParRightCalStudies.any @@ -1,7 +1,7 @@ TwoParCalibrationStudy RightCal1Shoulder( - BodyModelRef=Main.HumanModel.BodyModel, - Side=Right, - SHOULDER = On, + BodyModelRef = Main.HumanModel.BodyModel, + Side = Right, + SHOULDER = On ) = { nStep = NumElemOf(ShoulderPositions); @@ -20,9 +20,125 @@ TwoParCalibrationStudy RightCal1Shoulder( "SerratusAnterior.*", "Subscapularis.*", "Supraspinatus.*", - }, + }, "AnyMuscle" ); - ShoulderPositions = flattenptr(&.RangeOfMotion.Right.ShoulderArm.Shoulder.ActiveRoM); + ShoulderPositions = flattenptr(&.RangeOfMotion.Right.ShoulderArm.Shoulder.ActiveRoMShoulder); +}; + +TwoParCalibrationStudy RightCal2Elbow( + BodyModelRef = Main.HumanModel.BodyModel, + Side = Right, + ELBOWFLEXION = On +) = { + nStep = NumElemOf(ElbowFlexionPositions); + + MuscleArr = ObjSearch( + &..BodyModel.Right.ShoulderArm.Muscles, + { + "Anconeus.*", + "BicepsBrachii.*", + "Brachialis.*", + "Brachioradialis.*", + "Coracobrachialis.*", + "Triceps.*", + }, + "AnyMuscle" + ); + + ElbowFlexionPositions = flattenptr(&.RangeOfMotion.Right.ShoulderArm.Elbow.ActiveRoMFlexion); +}; + +TwoParCalibrationStudy RightCal3ElbowWrist( + BodyModelRef = Main.HumanModel.BodyModel, + Side = Right, + ELBOWFLEXION = On, + WRISTFLEXION = On +) = { + nStep = NumElemOf(ElbowFlexionPositions); + + MuscleArr = ObjSearch( + &..BodyModel.Right.ShoulderArm.Muscles, + { + "Extensor*.*", + "FlexorCarpi*.*", + "FlexorDigi*.*", + "PalmarisLongus.*", + }, + "AnyMuscle" + ); + + ElbowFlexionPositions = repmat(4, flattenptr(&.RangeOfMotion.Right.ShoulderArm.Elbow.ActiveRoMFlexion)); + WristFlexionPositions = repmat(4, flattenptr(&.RangeOfMotion.Right.ShoulderArm.Wrist.ActiveRoMFlexion)); +}; + +TwoParCalibrationStudy RightCal4Wrist( + BodyModelRef = Main.HumanModel.BodyModel, + Side = Right, + WRISTFLEXION = On +) = { + nStep = NumElemOf(WristFlexionPositions); + + MuscleArr = ObjSearch( + &..BodyModel.Right.ShoulderArm.Muscles, + { + "AbductorPollicis.*", + "FlexorPollicis*.*", + }, + "AnyMuscle" + ); + + WristFlexionPositions = flattenptr(&.RangeOfMotion.Right.ShoulderArm.Wrist.ActiveRoMFlexion); +}; + +TwoParCalibrationStudy RightCal5ScapulaClavicula( + BodyModelRef = Main.HumanModel.BodyModel, + Side = Right, + SCAPULAELEVATION = On, + SCAPULAPROTRACTION = On, +) = { + nStep = NumElemOf(ScapulaElevationPositions); + + MuscleArr = ObjSearch( + &..BodyModel.Right.ShoulderArm.Muscles, + { + "Rhomboideus.*", + "Sternocleidomastoid.*", + "Teres*.*", + "Trapezius*.*", + }, + "AnyMuscle" + ); + + ScapulaElevationPositions = repmat(2, flattenptr(&.RangeOfMotion.Right.ShoulderArm.Shoulder.ActiveRoMScapulaElevation)); + ScapulaProtractionPositions = repmat(2, flattenptr(&.RangeOfMotion.Right.ShoulderArm.Shoulder.ActiveRoMScapulaProtraction)); +}; + +TwoParCalibrationStudy RightCal6ForearmPronationSupination( + BodyModelRef = Main.HumanModel.BodyModel, + Side = Right, + ELBOWPRONATION = On, +) = { + nStep = NumElemOf(ElbowPronationPositions); + + MuscleArr = ObjSearch( + &..BodyModel.Right.ShoulderArm.Muscles, + { + "Pronator*.*", + "Supinator.*", + }, + "AnyMuscle" + ); + + ElbowPronationPositions = flattenptr(&.RangeOfMotion.Right.ShoulderArm.Elbow.ActiveRoMPronation); +}; + +CalibrationSequence = { + AnyOperation& Cal1Shoulder = .RightCal1Shoulder.FiberAndTendonLengthAdjustment; + AnyOperation& Cal2Elbow = .RightCal2Elbow.FiberAndTendonLengthAdjustment; + AnyOperation& Cal3ElbowWrist = .RightCal3ElbowWrist.FiberAndTendonLengthAdjustment; + AnyOperation& Cal4Wrist = .RightCal4Wrist.FiberAndTendonLengthAdjustment; + AnyOperation& Cal5ScapulaClavicula = .RightCal5ScapulaClavicula.FiberAndTendonLengthAdjustment; + AnyOperation& Cal6ForearmPronationSupination = .RightCal6ForearmPronationSupination.FiberAndTendonLengthAdjustment; }; \ No newline at end of file diff --git a/Body/AAUHuman/Arm/rangeOfMotion.any b/Body/AAUHuman/Arm/rangeOfMotion.any index 963c450b7..ee6090915 100644 --- a/Body/AAUHuman/Arm/rangeOfMotion.any +++ b/Body/AAUHuman/Arm/rangeOfMotion.any @@ -29,7 +29,7 @@ AnyFolder RangeOfMotion = { AnyFloat FlexedAndAdducted = {MaxGlenohumeralFlexionAngle, MaxGlenohumeralAdductionAngle, 0}; AnyFloat FlexedAndAbducted = {MaxGlenohumeralFlexionAngle, MaxGlenohumeralAbductionAngle, 0}; - AnyObjectPtr ActiveRoM = { + AnyObjectPtrArray ActiveRoMShoulder = { &Flexed, &Extended, &Abducted, @@ -43,6 +43,16 @@ AnyFolder RangeOfMotion = { &FlexedAndAdducted, &FlexedAndAbducted, }; + + AnyObjectPtrArray ActiveRoMScapulaElevation = { + &MaxScapulaClaviculaElevationAngle, + &MaxScapulaClaviculaDepressionAngle, + }; + + AnyObjectPtrArray ActiveRoMScapulaProtraction = { + &MaxScapulaClaviculaProtractionAngle, + &MaxScapulaClaviculaRetractionAngle, + }; }; AnyFolder Elbow = { @@ -52,9 +62,12 @@ AnyFolder RangeOfMotion = { AnyVar MaxSupinationAngle = -90; AnyVar Neutral = 0; - AnyObjectPtrArray ActiveRoM = { + AnyObjectPtrArray ActiveRoMFlexion = { &MaxFlexionAngle, &MaxExtensionAngle, + }; + + AnyObjectPtrArray ActiveRoMPronation = { &MaxPronationAngle, &MaxSupinationAngle, }; @@ -67,9 +80,12 @@ AnyFolder RangeOfMotion = { AnyVar MaxAdductionAngle = -35; AnyVar Neutral = 0; - AnyObjectPtrArray ActiveRoM = { + AnyObjectPtrArray ActiveRoMFlexion = { &MaxFlexionAngle, &MaxExtensionAngle, + }; + + AnyObjectPtrArray ActiveRoMAbduction = { &MaxAbductionAngle, &MaxAdductionAngle, }; diff --git a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any index 4372ed250..a43c2bdea 100644 --- a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any +++ b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any @@ -59,7 +59,9 @@ BodyModelFolderStructure RangeOfMotion() = { AnyFloat FlexedAndAdducted ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.FlexedAndAdducted; AnyFloat FlexedAndAbducted ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.FlexedAndAbducted; - AnyObjectPtr ActiveRoM ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.ActiveRoM; + AnyObjectPtr ActiveRoMShoulder ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.ActiveRoMShoulder; + AnyObjectPtr ActiveRoMScapulaElevation ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.ActiveRoMScapulaElevation; + AnyObjectPtr ActiveRoMScapulaProtraction ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Shoulder.ActiveRoMScapulaProtraction; }; Right.ShoulderArm.Elbow = { @@ -69,7 +71,8 @@ BodyModelFolderStructure RangeOfMotion() = { AnyVar MaxSupinationAngle ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Elbow.MaxSupinationAngle; AnyVar Neutral ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Elbow.Neutral; - AnyObjectPtr ActiveRoM ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Elbow.ActiveRoM; + AnyObjectPtr ActiveRoMFlexion ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Elbow.ActiveRoMFlexion; + AnyObjectPtr ActiveRoMPronation ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Elbow.ActiveRoMPronation; }; Right.ShoulderArm.Wrist = { @@ -79,7 +82,8 @@ BodyModelFolderStructure RangeOfMotion() = { AnyVar MaxAdductionAngle ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Wrist.MaxAdductionAngle; AnyVar Neutral ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Wrist.Neutral; - AnyObjectPtr ActiveRoM ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Wrist.ActiveRoM; + AnyObjectPtr ActiveRoMFlexion ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Wrist.ActiveRoMFlexion; + AnyObjectPtr ActiveRoMAbduction ??= .....BodyModel.Right.ShoulderArm.Data.RangeOfMotion.Wrist.ActiveRoMAbduction; }; #endif @@ -160,7 +164,9 @@ BodyModelFolderStructure RangeOfMotion() = { AnyFloat FlexedAndAdducted ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.FlexedAndAdducted; AnyFloat FlexedAndAbducted ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.FlexedAndAbducted; - AnyObjectPtr ActiveRoM ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.ActiveRoM; + AnyObjectPtr ActiveRoMShoulder ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.ActiveRoMShoulder; + AnyObjectPtr ActiveRoMScapulaElevation ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.ActiveRoMScapulaElevation; + AnyObjectPtr ActiveRoMScapulaProtraction ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Shoulder.ActiveRoMScapulaProtraction; }; Left.ShoulderArm.Elbow = { @@ -170,7 +176,8 @@ BodyModelFolderStructure RangeOfMotion() = { AnyVar MaxSupinationAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Elbow.MaxSupinationAngle; AnyVar Neutral ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Elbow.Neutral; - AnyObjectPtr ActiveRoM ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Elbow.ActiveRoM; + AnyObjectPtr ActiveRoMFlexion ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Elbow.ActiveRoMFlexion; + AnyObjectPtr ActiveRoMPronation ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Elbow.ActiveRoMPronation; }; Left.ShoulderArm.Wrist = { @@ -180,7 +187,8 @@ BodyModelFolderStructure RangeOfMotion() = { AnyVar MaxAdductionAngle ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Wrist.MaxAdductionAngle; AnyVar Neutral ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Wrist.Neutral; - AnyObjectPtr ActiveRoM ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Wrist.ActiveRoM; + AnyObjectPtr ActiveRoMFlexion ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Wrist.ActiveRoMFlexion; + AnyObjectPtr ActiveRoMAbduction ??= .....BodyModel.Left.ShoulderArm.Data.RangeOfMotion.Wrist.ActiveRoMAbduction; }; #endif diff --git a/Tests/Calibration/test_calibration_lowerbody.any b/Tests/Calibration/test_calibration_lowerbody.any index eef404758..75018d113 100644 --- a/Tests/Calibration/test_calibration_lowerbody.any +++ b/Tests/Calibration/test_calibration_lowerbody.any @@ -26,7 +26,7 @@ #define BM_SCALING _SCALING_NONE_ #define BM_LEG_TRUNK_INTERFACE _MORPH_TRUNK_TO_LEG_ -#define BM_LEG_MUSCLES_RIGHT _MUSCLES_3E_HILL_ +#define BM_LEG_MUSCLES_BOTH _MUSCLES_3E_HILL_ #define BM_TRUNK_MUSCLES OFF #define BM_LEG_LEFT OFF @@ -47,21 +47,19 @@ Main = // Test to check that all muscles in the model are part of the calibration studies. // for the leg we find the psoas muscles that belong to the trunk model // the test is excluded for leg model and calibration combinations that do not make sense / are unimplemented - #if (BM_LEG_MODEL != _LEG_MODEL_LEG_ | BM_LEG_MODEL != _LEG_MODEL_TLEM1_) & BM_CALIBRATION_TYPE != 3 - AnyObjectPtrArray muscles_from_cal_studies = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.Calibration, "MuscleArr"))); - AnyObjectPtrArray muscles_leg = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Right.Leg.Mus, "*", "AnyMuscle"))); - AnyObjectPtrArray muscles_trunk = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Trunk.Muscles.Right, "*", "AnyMuscle"))); - AnyObjectPtrArray muscles_from_model = arrcat(muscles_leg, muscles_trunk); - - AnyInt test_all_mus_in_cal = expect( - eqfun( - NumElemOf(muscles_from_cal_studies), - NumElemOf(muscles_from_model) - ), - "The number of muscles in the calibration studies do not match the number of muscles in the model!" - ); - #endif - + AnyObjectPtrArray muscles_from_cal_studies = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.Calibration, "MuscleArr"))); + AnyObjectPtrArray muscles_leg = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Right.Leg.Mus, "*", "AnyMuscle"))); + AnyObjectPtrArray muscles_trunk = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Trunk.Muscles.Right, "*", "AnyMuscle"))); + AnyObjectPtrArray muscles_from_model = arrcat(muscles_leg, muscles_trunk); + + AnyInt test_all_mus_in_cal = expect( + eqfun( + NumElemOf(muscles_from_cal_studies), + NumElemOf(muscles_from_model) + ), + "The number of muscles in the calibration studies do not match the number of muscles in the model!" + ); + #if (BM_CALIBRATION_TYPE == 3) & (BM_LEG_MODEL == _LEG_MODEL_TLEM2_) AnyOperation& HipFlexExtRoM = Main.HipFlexExtRoM.InverseDynamics; AnyOperation& HipAddAbdRoM = Main.HipAddAbdRoM.InverseDynamics; @@ -113,9 +111,9 @@ Main = AnyFloat passive_forces_vals = Obj2Num(passive_forces); AnyObjectPtrArray strengths = ObjGetMember(.muscles_from_cal_studies, "Strength"); AnyFloat strengths_vals = Obj2Num(strengths); - AnyObjectPtrArray cal_rmax = ObjSearchRecursive(&Main.HumanModel.Calibration, "RmaxMuscleFiber"); - AnyFloat cal_rmax_vals = Obj2NumFlatten(cal_rmax); - AnyFloat passive_force_thresholds = mult(strengths_vals, (cal_rmax_vals-1)); + AnyObjectPtrArray rmax = ObjSearchRecursive(&Main.HumanModel.Calibration, "RmaxMuscleFiber"); + AnyFloat rmax_vals = Obj2NumFlatten(rmax); + AnyFloat passive_force_thresholds = mult(strengths_vals, (rmax_vals-1)); AnyString passive_force_paired_look_up = transpose({CompleteNameOf(.muscles_from_cal_studies), strval(passive_forces_vals), strval(passive_force_thresholds), strval(.test_passive_forces)}); }; @@ -125,6 +123,13 @@ Main = ), "Muscles have to large passive forces!" ); + + AnyInt test_max_mus_act = expect(orfun( + not(Main.TestTrigger), + lteqfun(MaxMuscleActivity, 1.0), + ), + "Muscles Not strong enough inside active range of motion!" + ); InverseDynamics.PreOperation = { AnyOperation &EnableTests = Main.SetTestTrigger; diff --git a/Tests/Calibration/test_calibration_upperbody.any b/Tests/Calibration/test_calibration_upperbody.any index ba0154e4b..faed5d1a4 100644 --- a/Tests/Calibration/test_calibration_upperbody.any +++ b/Tests/Calibration/test_calibration_upperbody.any @@ -45,7 +45,8 @@ Main = AnyObjectPtrArray muscles_right = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Right.ShoulderArm.Muscles, "*", "AnyMuscle"))); AnyObjectPtrArray muscles_left = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Left.ShoulderArm.Muscles, "*", "AnyMuscle"))); AnyObjectPtrArray muscles_from_model = arrcat(muscles_right, muscles_left); - + AnyObjectPtr diff = set_difference(muscles_from_model, muscles_from_cal_studies); + AnyInt test_all_mus_in_cal = expect( eqfun( NumElemOf(muscles_from_cal_studies), From aec4dcec3309112da9c92986e237db6374ae5976 Mon Sep 17 00:00:00 2001 From: bke Date: Wed, 9 Apr 2025 15:07:54 +0200 Subject: [PATCH 19/29] update --- .../CalibrationStudy.ClassTemplates.any | 2 +- .../GenericBodyModel/Calibration/RValues.any | 2 +- .../Calibration/RangeOfMotionDefinition.any | 7 ++- .../Calibration/2ParLeftCalStudies.any | 8 ++-- .../Calibration/2ParRightCalStudies.any | 16 ++++--- Body/AAUHuman/LegTLEM/rangeOfMotion.any | 7 ++- .../test_calibration_lowerbody.any | 44 ++++++++++--------- 7 files changed, 51 insertions(+), 35 deletions(-) diff --git a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any index 579b72314..07b650ac5 100644 --- a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any +++ b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/CalibrationStudy.ClassTemplates.any @@ -63,7 +63,7 @@ __CLASS__ = AnyKinEqInterPolDriver, SUBTALAR = Off, ) { // Study settings - FiberAndTendonLengthAdjustment.CalibrateTendonAtMaxForceOnOff = Off; + FiberAndTendonLengthAdjustment.CalibrateTendonAtMaxForceOnOff = On; Kinematics.SmallStepAssumptionOnOff = Off; InitialConditions.SmallStepAssumptionOnOff = Off; Kinematics.PosAnalysisOnlyOnOff = On; diff --git a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RValues.any b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RValues.any index 4e499262c..768a73861 100644 --- a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RValues.any +++ b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RValues.any @@ -4,7 +4,7 @@ */ AnyFolder RValues = { AnyFloat RMinNoMuscleForce = 0.5; - AnyFloat RMinDefault = 0.6; + AnyFloat RMinDefault = 0.7; AnyFloat RMaxDefault = 1.2; AnyFloat RMaxActiveStretching = 1.3; diff --git a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any index a43c2bdea..64917f2fb 100644 --- a/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any +++ b/Body/AAUHuman/BodyModels/GenericBodyModel/Calibration/RangeOfMotionDefinition.any @@ -131,7 +131,8 @@ BodyModelFolderStructure RangeOfMotion() = { AnyVar MaxInversionAngle ??= .....BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.MaxInversionAngle; AnyVar MaxEversionAngle ??= .....BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.MaxEversionAngle; - AnyObjectPtr ActiveRoM ??= .....BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.ActiveRoM; + AnyObjectPtr ActiveRoMFlexion ??= .....BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.ActiveRoMFlexion; + AnyObjectPtr ActiveRoMEversion ??= .....BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.ActiveRoMEversion; }; #endif @@ -237,7 +238,9 @@ BodyModelFolderStructure RangeOfMotion() = { AnyVar MaxInversionAngle ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Ankle.MaxInversionAngle; AnyVar MaxEversionAngle ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Ankle.MaxEversionAngle; - AnyObjectPtr ActiveRoM ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Ankle.ActiveRoM; + AnyObjectPtr ActiveRoMFlexion ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Ankle.ActiveRoMFlexion; + AnyObjectPtr ActiveRoMEversion ??= .....BodyModel.Left.Leg.Data.RangeOfMotion.Ankle.ActiveRoMEversion; + }; #endif }; \ No newline at end of file diff --git a/Body/AAUHuman/LegTLEM/Calibration/2ParLeftCalStudies.any b/Body/AAUHuman/LegTLEM/Calibration/2ParLeftCalStudies.any index ce71c9e69..f93c69e68 100644 --- a/Body/AAUHuman/LegTLEM/Calibration/2ParLeftCalStudies.any +++ b/Body/AAUHuman/LegTLEM/Calibration/2ParLeftCalStudies.any @@ -113,14 +113,15 @@ ANKLE = On, "AnyMuscle" ); - KneePositions = repmat(4, flattenptr(&.RangeOfMotion.Left.Leg.Knee.ActiveRoM)); - AnklePositions = repmat(2, flattenptr(&.RangeOfMotion.Left.Leg.Ankle.ActiveRoM)); + KneePositions = repmat(3, flattenptr(&.RangeOfMotion.Left.Leg.Knee.ActiveRoM)); + AnklePositions = repmat(2, flattenptr(&.RangeOfMotion.Left.Leg.Ankle.ActiveRoMFlexion)); }; TwoParCalibrationStudy LeftCal6Ankle( BodyModelRef = Main.HumanModel.BodyModel, Side = Left, ANKLE = On, +SUBTALAR = On, ) = { nStep = NumElemOf(AnklePositions); MuscleArr = ObjSearch( @@ -134,7 +135,8 @@ ANKLE = On, "AnyMuscle" ); - AnklePositions = repmat(2, flattenptr(&.RangeOfMotion.Left.Leg.Ankle.ActiveRoM)); + AnklePositions = repmat(3, flattenptr(&.RangeOfMotion.Left.Leg.Ankle.ActiveRoMFlexion)); + SubTalarPositions = repmat(3, flattenptr(&.RangeOfMotion.Left.Leg.Ankle.ActiveRoMEversion)); }; diff --git a/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any b/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any index 5550b219f..5a5d42838 100644 --- a/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any +++ b/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any @@ -44,9 +44,9 @@ TwoParCalibrationStudy RightCal2HipSpine( ); HipPositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Hip.ActiveRoM)); - TrunkFlexionPositions = repmat(10, flattenptr(&.RangeOfMotion.Trunk.ActiveRoMThoraxFlexion)); - TrunkLateralBendingPositions = repmat(10, flattenptr(&.RangeOfMotion.Trunk.ActiveRoMThoraxLateralBending)); - TrunkRotationPositions = repmat(10, flattenptr(&.RangeOfMotion.Trunk.ActiveRoMThoraxAxialRotation)); + TrunkFlexionPositions = flatten(transpose(reshape(repmat(10, flattenptr(&.RangeOfMotion.Trunk.ActiveRoMThoraxFlexion)), {10,2}))); + TrunkLateralBendingPositions = flatten(transpose(reshape(repmat(10, flattenptr(&.RangeOfMotion.Trunk.ActiveRoMThoraxLateralBending)), {10,2}))); + TrunkRotationPositions = flatten(transpose(reshape(repmat(10, flattenptr(&.RangeOfMotion.Trunk.ActiveRoMThoraxAxialRotation)), {10,2}))); }; TwoParCalibrationStudy RightCal3HipKnee( @@ -72,7 +72,7 @@ TwoParCalibrationStudy RightCal3HipKnee( ); HipPositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Hip.ActiveRoM)); - KneePositions = repmat(10, flattenptr(&.RangeOfMotion.Right.Leg.Knee.ActiveRoM)); + KneePositions = flatten(transpose(reshape(repmat(10, flattenptr(&.RangeOfMotion.Right.Leg.Knee.ActiveRoM)), {10,2}))); }; TwoParCalibrationStudy RightCal4Knee( @@ -113,14 +113,15 @@ TwoParCalibrationStudy RightCal5AnkleKnee( "AnyMuscle" ); - KneePositions = repmat(4, flattenptr(&.RangeOfMotion.Right.Leg.Knee.ActiveRoM)); - AnklePositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Ankle.ActiveRoM)); + KneePositions = flatten(transpose(reshape(repmat(3, flattenptr(&.RangeOfMotion.Right.Leg.Knee.ActiveRoM)), {3,2}))); + AnklePositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Ankle.ActiveRoMFlexion)); }; TwoParCalibrationStudy RightCal6Ankle( BodyModelRef=Main.HumanModel.BodyModel, Side=Right, ANKLE = On, + SUBTALAR = On, ) = { nStep = NumElemOf(AnklePositions); MuscleArr = ObjSearch( @@ -134,7 +135,8 @@ TwoParCalibrationStudy RightCal6Ankle( "AnyMuscle" ); - AnklePositions = repmat(2, flattenptr(&.RangeOfMotion.Right.Leg.Ankle.ActiveRoM)); + AnklePositions = repmat(3, flattenptr(&.RangeOfMotion.Right.Leg.Ankle.ActiveRoMFlexion)); + SubTalarPositions = flatten(transpose(reshape(repmat(3, flattenptr(&.RangeOfMotion.Right.Leg.Ankle.ActiveRoMEversion)),{3,3}))); }; diff --git a/Body/AAUHuman/LegTLEM/rangeOfMotion.any b/Body/AAUHuman/LegTLEM/rangeOfMotion.any index 5f1e0b4c3..9fae3a464 100644 --- a/Body/AAUHuman/LegTLEM/rangeOfMotion.any +++ b/Body/AAUHuman/LegTLEM/rangeOfMotion.any @@ -61,10 +61,15 @@ AnyFolder RangeOfMotion = { AnyVar MaxInversionAngle = 15; AnyVar MaxEversionAngle = -20; - AnyObjectPtrArray ActiveRoM = { + AnyObjectPtrArray ActiveRoMFlexion = { &MaxPlantarFlexionAngle, + &Neutral, &MaxDorsiFlexionAngle, + }; + + AnyObjectPtrArray ActiveRoMEversion = { &MaxInversionAngle, + &Neutral, &MaxEversionAngle, }; }; diff --git a/Tests/Calibration/test_calibration_lowerbody.any b/Tests/Calibration/test_calibration_lowerbody.any index 75018d113..1367e8167 100644 --- a/Tests/Calibration/test_calibration_lowerbody.any +++ b/Tests/Calibration/test_calibration_lowerbody.any @@ -23,7 +23,7 @@ #define TEST_NAME "test_calibration_lowerbody.any_1" #endif - +#define EVALUATE_JOINT_STRENGTH 1 #define BM_SCALING _SCALING_NONE_ #define BM_LEG_TRUNK_INTERFACE _MORPH_TRUNK_TO_LEG_ #define BM_LEG_MUSCLES_BOTH _MUSCLES_3E_HILL_ @@ -39,27 +39,12 @@ Main = #include "/HumanModel.any" + AnyOperation& RunTest = RunAnalysis; AnyOperationSequence RunAnalysis = { AnyOperation& Calibration = Main.HumanModel.Calibration.CalibrationSequence; - - // Test to check that all muscles in the model are part of the calibration studies. - // for the leg we find the psoas muscles that belong to the trunk model - // the test is excluded for leg model and calibration combinations that do not make sense / are unimplemented - AnyObjectPtrArray muscles_from_cal_studies = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.Calibration, "MuscleArr"))); - AnyObjectPtrArray muscles_leg = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Right.Leg.Mus, "*", "AnyMuscle"))); - AnyObjectPtrArray muscles_trunk = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Trunk.Muscles.Right, "*", "AnyMuscle"))); - AnyObjectPtrArray muscles_from_model = arrcat(muscles_leg, muscles_trunk); - AnyInt test_all_mus_in_cal = expect( - eqfun( - NumElemOf(muscles_from_cal_studies), - NumElemOf(muscles_from_model) - ), - "The number of muscles in the calibration studies do not match the number of muscles in the model!" - ); - #if (BM_CALIBRATION_TYPE == 3) & (BM_LEG_MODEL == _LEG_MODEL_TLEM2_) AnyOperation& HipFlexExtRoM = Main.HipFlexExtRoM.InverseDynamics; AnyOperation& HipAddAbdRoM = Main.HipAddAbdRoM.InverseDynamics; @@ -68,7 +53,26 @@ Main = AnyOperation& AnkleFlexRoM = Main.AnkleFlexRoM.InverseDynamics; AnyOperation& AnkleEverInverRoM = Main.AnkleEverInverRoM.InverseDynamics; #endif - }; + }; + + // Test to check that all muscles in the model are part of the calibration studies. + // for the leg we find the psoas muscles that belong to the trunk model + // the test is excluded for leg model and calibration combinations that do not make sense / are unimplemented + AnyObjectPtrArray muscles_from_cal_studies = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.Calibration, "MuscleArr", 3))); + AnyObjectPtrArray muscles_leg = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Right.Leg.Mus, "*", "AnyMuscle"))); + AnyObjectPtrArray muscles_trunk = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Trunk.Muscles.Right, "*", "AnyMuscle"))); + AnyObjectPtrArray muscles_from_model = arrcat(muscles_leg, muscles_trunk); + + AnyInt test_all_mus_in_cal = expect( + eqfun( + NumElemOf(muscles_from_cal_studies), + NumElemOf(muscles_from_model) + ), + "The number of muscles in the calibration studies do not match the number of muscles in the model!" + ); + + // Collect calibration rundurations + AnyObjectPtr RunDurations = ObjSearch(&Main.HumanModel.Calibration, "*.FiberAndTendonLengthAdjustment.RunDuration"); /// Template to create a study for the leg - user must provide a driver. #class_template RoMTestStudy(__CLASS__ = AnyBodyStudy) { @@ -105,13 +109,13 @@ Main = }; // tests - AnyObjectPtrArray muscles_from_cal_studies = flattenptr(ObjSearchRecursive(&Main.HumanModel.Calibration, "MuscleArr")); + AnyObjectPtrArray muscles_from_cal_studies = flattenptr(ObjSearchRecursive(&Main.HumanModel.Calibration, "MuscleArr", 2)); AnyFolder Calculations = { AnyObjectPtrArray passive_forces = ObjGetMember(.muscles_from_cal_studies, "Fp"); AnyFloat passive_forces_vals = Obj2Num(passive_forces); AnyObjectPtrArray strengths = ObjGetMember(.muscles_from_cal_studies, "Strength"); AnyFloat strengths_vals = Obj2Num(strengths); - AnyObjectPtrArray rmax = ObjSearchRecursive(&Main.HumanModel.Calibration, "RmaxMuscleFiber"); + AnyObjectPtrArray rmax = ObjSearchRecursive(&Main.HumanModel.Calibration, "RmaxMuscleFiber", 2); AnyFloat rmax_vals = Obj2NumFlatten(rmax); AnyFloat passive_force_thresholds = mult(strengths_vals, (rmax_vals-1)); AnyString passive_force_paired_look_up = transpose({CompleteNameOf(.muscles_from_cal_studies), strval(passive_forces_vals), strval(passive_force_thresholds), strval(.test_passive_forces)}); From 2addd0ab75e23a1678b75cc4700f845aa8377d14 Mon Sep 17 00:00:00 2001 From: bke Date: Wed, 21 May 2025 10:30:08 +0200 Subject: [PATCH 20/29] use define instead of value --- Tests/Calibration/test_calibration_lowerbody.any | 6 +++--- Tests/Calibration/test_calibration_trunk.any | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Tests/Calibration/test_calibration_lowerbody.any b/Tests/Calibration/test_calibration_lowerbody.any index f789dc6de..52428c7ed 100644 --- a/Tests/Calibration/test_calibration_lowerbody.any +++ b/Tests/Calibration/test_calibration_lowerbody.any @@ -47,7 +47,7 @@ Main = // Test to check that all muscles in the model are part of the calibration studies. // for the leg we find the psoas muscles that belong to the trunk model // the test is excluded for leg model and calibration combinations that do not make sense / are unimplemented - #if BM_LEG_MODEL != _LEG_MODEL_LEG_ & BM_CALIBRATION_TYPE != 3 + #if BM_LEG_MODEL != _LEG_MODEL_LEG_ & BM_CALIBRATION_TYPE != _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_ AnyObjectPtrArray muscles_from_cal_studies = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.Calibration, "MuscleArr"))); AnyObjectPtrArray muscles_leg = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Right.Leg.Mus, "*", "AnyMuscle"))); AnyObjectPtrArray muscles_trunk = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Trunk.Muscles.Right, "*", "AnyMuscle"))); @@ -62,7 +62,7 @@ Main = ); #endif - #if (BM_CALIBRATION_TYPE == 3) & (BM_LEG_MODEL == _LEG_MODEL_TLEM_) + #if (BM_CALIBRATION_TYPE == _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_) & (BM_LEG_MODEL == _LEG_MODEL_TLEM_) AnyOperation& HipFlexExtRoM = Main.HipFlexExtRoM.InverseDynamics; AnyOperation& HipAddAbdRoM = Main.HipAddAbdRoM.InverseDynamics; AnyOperation& HipRotRoM = Main.HipRotRoM.InverseDynamics; @@ -161,7 +161,7 @@ Main = }; - #if (BM_CALIBRATION_TYPE == 3) & (BM_LEG_MODEL == _LEG_MODEL_TLEM_) + #if (BM_CALIBRATION_TYPE == _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_) & (BM_LEG_MODEL == _LEG_MODEL_TLEM_) AnyInt TestTrigger = DesignVar(0); AnyOperationMacro UpdateValues = { MacroStr = {"classoperation Main " + strquote("Update Values")}; diff --git a/Tests/Calibration/test_calibration_trunk.any b/Tests/Calibration/test_calibration_trunk.any index 51e697578..2ccedc72d 100644 --- a/Tests/Calibration/test_calibration_trunk.any +++ b/Tests/Calibration/test_calibration_trunk.any @@ -54,7 +54,7 @@ Main = // Test to check that all muscles in the model are part of the calibration studies. // the test is excluded for the calibration combinations that do not make sense / are unimplemented // The pelvic floor muscles are excluded as they are not 3E muscles! - #if BM_CALIBRATION_TYPE != 3 + #if BM_CALIBRATION_TYPE != _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_ AnyObjectPtrArray muscles_from_cal_studies = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.Calibration, "MuscleArr"))); AnyObjectPtrArray muscles_from_model = set_difference( ObjSearchRecursive(&Main.HumanModel.BodyModel.Trunk.Muscles, "*", "AnyMuscle", 3), From cd21c7486f79f4f3a026a77d079ed12c841b933e Mon Sep 17 00:00:00 2001 From: bke Date: Fri, 23 May 2025 08:23:51 +0200 Subject: [PATCH 21/29] set default in test --- .../Calibration/2ParLeftCalStudies.any | 48 +++++++++---------- .../test_calibration_lowerbody.any | 2 +- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/Body/AAUHuman/LegTLEM/Calibration/2ParLeftCalStudies.any b/Body/AAUHuman/LegTLEM/Calibration/2ParLeftCalStudies.any index f93c69e68..c6d69a692 100644 --- a/Body/AAUHuman/LegTLEM/Calibration/2ParLeftCalStudies.any +++ b/Body/AAUHuman/LegTLEM/Calibration/2ParLeftCalStudies.any @@ -1,7 +1,7 @@ TwoParCalibrationStudy LeftCal1Hip( -BodyModelRef = Main.HumanModel.BodyModel, -Side = Left, -HIP = On + BodyModelRef = Main.HumanModel.BodyModel, + Side = Left, + HIP = On ) = { nStep = NumElemOf(HipPositions); @@ -26,12 +26,12 @@ HIP = On }; TwoParCalibrationStudy LeftCal2HipSpine( -BodyModelRef = Main.HumanModel.BodyModel, -Side = Left, -HIP = On, -TRUNKFLEXION = On, -TRUNKLATERALBENDING = On, -TRUNKROTATION = On, + BodyModelRef = Main.HumanModel.BodyModel, + Side = Left, + HIP = On, + TRUNKFLEXION = On, + TRUNKLATERALBENDING = On, + TRUNKROTATION = On, ) = { nStep = NumElemOf(HipPositions); @@ -50,10 +50,10 @@ TRUNKROTATION = On, }; TwoParCalibrationStudy LeftCal3HipKnee( -BodyModelRef = Main.HumanModel.BodyModel, -Side = Left, -HIP = On, -KNEE = On, + BodyModelRef = Main.HumanModel.BodyModel, + Side = Left, + HIP = On, + KNEE = On, ) = { nStep = NumElemOf(HipPositions); @@ -76,9 +76,9 @@ KNEE = On, }; TwoParCalibrationStudy LeftCal4Knee( -BodyModelRef = Main.HumanModel.BodyModel, -Side = Left, -KNEE = On, + BodyModelRef = Main.HumanModel.BodyModel, + Side = Left, + KNEE = On, ) = { nStep = NumElemOf(KneePositions); @@ -96,10 +96,10 @@ KNEE = On, }; TwoParCalibrationStudy LeftCal5AnkleKnee( -BodyModelRef = Main.HumanModel.BodyModel, -Side = Left, -KNEE = On, -ANKLE = On, + BodyModelRef = Main.HumanModel.BodyModel, + Side = Left, + KNEE = On, + ANKLE = On, ) = { nStep = NumElemOf(AnklePositions); @@ -118,10 +118,10 @@ ANKLE = On, }; TwoParCalibrationStudy LeftCal6Ankle( -BodyModelRef = Main.HumanModel.BodyModel, -Side = Left, -ANKLE = On, -SUBTALAR = On, + BodyModelRef = Main.HumanModel.BodyModel, + Side = Left, + ANKLE = On, + SUBTALAR = On, ) = { nStep = NumElemOf(AnklePositions); MuscleArr = ObjSearch( diff --git a/Tests/Calibration/test_calibration_lowerbody.any b/Tests/Calibration/test_calibration_lowerbody.any index 52428c7ed..0f71502d3 100644 --- a/Tests/Calibration/test_calibration_lowerbody.any +++ b/Tests/Calibration/test_calibration_lowerbody.any @@ -17,7 +17,7 @@ #include "libdef.any" #ifndef TEST_NAME - #define BM_LEG_MODEL 2 + #define BM_LEG_MODEL 1 #define BM_CALIBRATION_TYPE 3 #define TEST_NAME "test_calibration_lowerbody.any_1" #endif From 05b876f0109626c115d60e0080c40da958f899e5 Mon Sep 17 00:00:00 2001 From: bke Date: Mon, 2 Jun 2025 09:39:56 +0200 Subject: [PATCH 22/29] add simple muscle option to cal test --- .../test_calibration_lowerbody.any | 414 +++++++++--------- 1 file changed, 208 insertions(+), 206 deletions(-) diff --git a/Tests/Calibration/test_calibration_lowerbody.any b/Tests/Calibration/test_calibration_lowerbody.any index 0f71502d3..d98763e7b 100644 --- a/Tests/Calibration/test_calibration_lowerbody.any +++ b/Tests/Calibration/test_calibration_lowerbody.any @@ -17,15 +17,16 @@ #include "libdef.any" #ifndef TEST_NAME - #define BM_LEG_MODEL 1 - #define BM_CALIBRATION_TYPE 3 + #define BM_LEG_MODEL _LEG_MODEL_TLEM_ + #define BM_CALIBRATION_TYPE _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_ #define TEST_NAME "test_calibration_lowerbody.any_1" + #define BM_LEG_MUSCLES_BOTH _MUSCLES_3E_HILL_ +// #define BM_LEG_MUSCLES_BOTH _MUSCLES_SIMPLE_ #endif #define EVALUATE_JOINT_STRENGTH 1 #define BM_SCALING _SCALING_NONE_ #define BM_LEG_TRUNK_INTERFACE _MORPH_TRUNK_TO_LEG_ -#define BM_LEG_MUSCLES_BOTH _MUSCLES_3E_HILL_ #define BM_TRUNK_MUSCLES OFF #define BM_LEG_LEFT OFF @@ -38,236 +39,237 @@ Main = #include "/HumanModel.any" - - AnyOperation& RunTest = RunAnalysis; - AnyOperationSequence RunAnalysis = { + #if BM_LEG_MUSCLES_BOTH == _MUSCLES_3E_HILL_ + AnyOperation& RunTest = RunAnalysis; + AnyOperationSequence RunAnalysis = { - AnyOperation& Calibration = Main.HumanModel.Calibration.CalibrationSequence; - + AnyOperation& Calibration = Main.HumanModel.Calibration.CalibrationSequence; + + // Test to check that all muscles in the model are part of the calibration studies. + // for the leg we find the psoas muscles that belong to the trunk model + // the test is excluded for leg model and calibration combinations that do not make sense / are unimplemented + #if BM_LEG_MODEL != _LEG_MODEL_LEG_ & BM_CALIBRATION_TYPE != _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_ + AnyObjectPtrArray muscles_from_cal_studies = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.Calibration, "MuscleArr"))); + AnyObjectPtrArray muscles_leg = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Right.Leg.Mus, "*", "AnyMuscle"))); + AnyObjectPtrArray muscles_trunk = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Trunk.Muscles.Right, "*", "AnyMuscle"))); + AnyObjectPtrArray muscles_from_model = arrcat(muscles_leg, muscles_trunk); + + AnyInt test_all_mus_in_cal = expect( + eqfun( + NumElemOf(muscles_from_cal_studies), + NumElemOf(muscles_from_model) + ), + "The number of muscles in the calibration studies do not match the number of muscles in the model!" + ); + #endif + + #if (BM_CALIBRATION_TYPE == _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_) & (BM_LEG_MODEL == _LEG_MODEL_TLEM_) + AnyOperation& HipFlexExtRoM = Main.HipFlexExtRoM.InverseDynamics; + AnyOperation& HipAddAbdRoM = Main.HipAddAbdRoM.InverseDynamics; + AnyOperation& HipRotRoM = Main.HipRotRoM.InverseDynamics; + AnyOperation& KneeFlexExtRoM = Main.KneeFlexExtRoM.InverseDynamics; + AnyOperation& AnkleFlexRoM = Main.AnkleFlexRoM.InverseDynamics; + AnyOperation& AnkleEverInverRoM = Main.AnkleEverInverRoM.InverseDynamics; + #endif + }; + // Test to check that all muscles in the model are part of the calibration studies. // for the leg we find the psoas muscles that belong to the trunk model // the test is excluded for leg model and calibration combinations that do not make sense / are unimplemented - #if BM_LEG_MODEL != _LEG_MODEL_LEG_ & BM_CALIBRATION_TYPE != _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_ - AnyObjectPtrArray muscles_from_cal_studies = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.Calibration, "MuscleArr"))); - AnyObjectPtrArray muscles_leg = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Right.Leg.Mus, "*", "AnyMuscle"))); - AnyObjectPtrArray muscles_trunk = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Trunk.Muscles.Right, "*", "AnyMuscle"))); - AnyObjectPtrArray muscles_from_model = arrcat(muscles_leg, muscles_trunk); + AnyObjectPtrArray muscles_from_cal_studies = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.Calibration, "MuscleArr", 3))); + AnyObjectPtrArray muscles_leg = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Right.Leg.Mus, "*", "AnyMuscle"))); + AnyObjectPtrArray muscles_trunk = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Trunk.Muscles.Right, "*", "AnyMuscle"))); + AnyObjectPtrArray muscles_from_model = arrcat(muscles_leg, muscles_trunk); + + AnyInt test_all_mus_in_cal = expect( + eqfun( + NumElemOf(muscles_from_cal_studies), + NumElemOf(muscles_from_model) + ), + "The number of muscles in the calibration studies do not match the number of muscles in the model!" + ); - AnyInt test_all_mus_in_cal = expect( - eqfun( - NumElemOf(muscles_from_cal_studies), - NumElemOf(muscles_from_model) - ), - "The number of muscles in the calibration studies do not match the number of muscles in the model!" - ); - #endif + // Collect calibration rundurations + AnyObjectPtr RunDurations = ObjSearch(&Main.HumanModel.Calibration, "*.FiberAndTendonLengthAdjustment.RunDuration"); - #if (BM_CALIBRATION_TYPE == _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_) & (BM_LEG_MODEL == _LEG_MODEL_TLEM_) - AnyOperation& HipFlexExtRoM = Main.HipFlexExtRoM.InverseDynamics; - AnyOperation& HipAddAbdRoM = Main.HipAddAbdRoM.InverseDynamics; - AnyOperation& HipRotRoM = Main.HipRotRoM.InverseDynamics; - AnyOperation& KneeFlexExtRoM = Main.KneeFlexExtRoM.InverseDynamics; - AnyOperation& AnkleFlexRoM = Main.AnkleFlexRoM.InverseDynamics; - AnyOperation& AnkleEverInverRoM = Main.AnkleEverInverRoM.InverseDynamics; - #endif - }; - - // Test to check that all muscles in the model are part of the calibration studies. - // for the leg we find the psoas muscles that belong to the trunk model - // the test is excluded for leg model and calibration combinations that do not make sense / are unimplemented - AnyObjectPtrArray muscles_from_cal_studies = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.Calibration, "MuscleArr", 3))); - AnyObjectPtrArray muscles_leg = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Right.Leg.Mus, "*", "AnyMuscle"))); - AnyObjectPtrArray muscles_trunk = unique(flattenptr(ObjSearchRecursive(&Main.HumanModel.BodyModel.Trunk.Muscles.Right, "*", "AnyMuscle"))); - AnyObjectPtrArray muscles_from_model = arrcat(muscles_leg, muscles_trunk); - - AnyInt test_all_mus_in_cal = expect( - eqfun( - NumElemOf(muscles_from_cal_studies), - NumElemOf(muscles_from_model) - ), - "The number of muscles in the calibration studies do not match the number of muscles in the model!" - ); - - // Collect calibration rundurations - AnyObjectPtr RunDurations = ObjSearch(&Main.HumanModel.Calibration, "*.FiberAndTendonLengthAdjustment.RunDuration"); - - /// Template to create a study for the leg - user must provide a driver. - #class_template RoMTestStudy(__CLASS__ = AnyBodyStudy) { - Kinematics.SolverType = KinSolOverDeterminate; - InitialConditions.SolverType = Kinematics.SolverType; - nStep = 5; - Gravity = {0, 0, 0}; - InverseDynamics.Criterion.UpperBoundOnOff = Off; - AnyFolder &Model = Main.HumanModel.BodyModelWithDefaultDrivers; + /// Template to create a study for the leg - user must provide a driver. + #class_template RoMTestStudy(__CLASS__ = AnyBodyStudy) { + Kinematics.SolverType = KinSolOverDeterminate; + InitialConditions.SolverType = Kinematics.SolverType; + nStep = 5; + Gravity = {0, 0, 0}; + InverseDynamics.Criterion.UpperBoundOnOff = Off; + AnyFolder &Model = Main.HumanModel.BodyModelWithDefaultDrivers; + + AnyFixedRefFrame ground = { + AnyRefNode node = { + ARel = Main.HumanModel.BodyModel.Trunk.Segments.PelvisSeg.Axes0; + sRel = Main.HumanModel.BodyModel.Trunk.Segments.PelvisSeg.r0; + }; + }; + + AnyKinEq ThoraxFix = { + AnyKinMeasure& PelvisThoraxExtension = Main.HumanModel.BodyModel.Interface.Trunk.PelvisThoraxExtension; + AnyKinMeasure& PelvisThoraxLateralBending = Main.HumanModel.BodyModel.Interface.Trunk.PelvisThoraxLateralBending; + AnyKinMeasure& PelvisThoraxRotation = Main.HumanModel.BodyModel.Interface.Trunk.PelvisThoraxRotation; + }; + + AnyKinEq PelvisFix = { + AnyKinLinear Lin = { + AnyRefFrame &ground = ..ground.node; + AnyRefFrame &Pelvis = Main.HumanModel.BodyModel.Trunk.Segments.PelvisSeg; + }; + AnyKinRotational Rot = { + Type = RotAxesAngles; + AnyRefFrame &ground = ..ground.node; + AnyRefFrame &Pelvis = Main.HumanModel.BodyModel.Trunk.Segments.PelvisSeg; + }; + }; + + // tests + AnyObjectPtrArray muscles_from_cal_studies = flattenptr(ObjSearchRecursive(&Main.HumanModel.Calibration, "MuscleArr", 2)); + AnyFolder Calculations = { + AnyObjectPtrArray passive_forces = ObjGetMember(.muscles_from_cal_studies, "Fp"); + AnyFloat passive_forces_vals = Obj2Num(passive_forces); + AnyObjectPtrArray strengths = ObjGetMember(.muscles_from_cal_studies, "Strength"); + AnyFloat strengths_vals = Obj2Num(strengths); + AnyObjectPtrArray rmax = ObjSearchRecursive(&Main.HumanModel.Calibration, "RmaxMuscleFiber", 2); + AnyFloat rmax_vals = Obj2NumFlatten(rmax); + AnyFloat passive_force_thresholds = mult(strengths_vals, (rmax_vals-1)); + AnyString passive_force_paired_look_up = transpose({CompleteNameOf(.muscles_from_cal_studies), strval(passive_forces_vals), strval(passive_force_thresholds), strval(.test_passive_forces)}); + }; - AnyFixedRefFrame ground = { - AnyRefNode node = { - ARel = Main.HumanModel.BodyModel.Trunk.Segments.PelvisSeg.Axes0; - sRel = Main.HumanModel.BodyModel.Trunk.Segments.PelvisSeg.r0; + AnyInt test_passive_forces = expect(orfun( + not(Main.TestTrigger), + lteqfun(Calculations.passive_forces_vals, Calculations.passive_force_thresholds), + ), + "Muscles have to large passive forces!" + ); + + AnyInt test_max_mus_act = expect(orfun( + not(Main.TestTrigger), + lteqfun(MaxMuscleActivity, 1.0), + ), + "Muscles Not strong enough inside active range of motion!" + ); + + InverseDynamics.PreOperation = { + AnyOperation &EnableTests = Main.SetTestTrigger; + AnyOperation &UpdateValues = Main.UpdateValues; }; + + InverseDynamics.PostOperation = { AnyOperation &ResetTestTrigger = Main.ResetTestTrigger;}; }; - AnyKinEq ThoraxFix = { - AnyKinMeasure& PelvisThoraxExtension = Main.HumanModel.BodyModel.Interface.Trunk.PelvisThoraxExtension; - AnyKinMeasure& PelvisThoraxLateralBending = Main.HumanModel.BodyModel.Interface.Trunk.PelvisThoraxLateralBending; - AnyKinMeasure& PelvisThoraxRotation = Main.HumanModel.BodyModel.Interface.Trunk.PelvisThoraxRotation; - }; - AnyKinEq PelvisFix = { - AnyKinLinear Lin = { - AnyRefFrame &ground = ..ground.node; - AnyRefFrame &Pelvis = Main.HumanModel.BodyModel.Trunk.Segments.PelvisSeg; + #if (BM_CALIBRATION_TYPE == _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_) & (BM_LEG_MODEL == _LEG_MODEL_TLEM_) + AnyInt TestTrigger = DesignVar(0); + AnyOperationMacro UpdateValues = { + MacroStr = {"classoperation Main " + strquote("Update Values")}; }; - AnyKinRotational Rot = { - Type = RotAxesAngles; - AnyRefFrame &ground = ..ground.node; - AnyRefFrame &Pelvis = Main.HumanModel.BodyModel.Trunk.Segments.PelvisSeg; + AnyOperationSetValue SetTestTrigger = { + AnyInt dummy = 1; + Source = {&dummy}; + Target = {&.TestTrigger}; + }; + AnyOperationSetValue ResetTestTrigger = { + AnyInt dummy = 0; + Source = {&dummy}; + Target = {&.TestTrigger}; }; - }; - - // tests - AnyObjectPtrArray muscles_from_cal_studies = flattenptr(ObjSearchRecursive(&Main.HumanModel.Calibration, "MuscleArr", 2)); - AnyFolder Calculations = { - AnyObjectPtrArray passive_forces = ObjGetMember(.muscles_from_cal_studies, "Fp"); - AnyFloat passive_forces_vals = Obj2Num(passive_forces); - AnyObjectPtrArray strengths = ObjGetMember(.muscles_from_cal_studies, "Strength"); - AnyFloat strengths_vals = Obj2Num(strengths); - AnyObjectPtrArray rmax = ObjSearchRecursive(&Main.HumanModel.Calibration, "RmaxMuscleFiber", 2); - AnyFloat rmax_vals = Obj2NumFlatten(rmax); - AnyFloat passive_force_thresholds = mult(strengths_vals, (rmax_vals-1)); - AnyString passive_force_paired_look_up = transpose({CompleteNameOf(.muscles_from_cal_studies), strval(passive_forces_vals), strval(passive_force_thresholds), strval(.test_passive_forces)}); - }; - - AnyInt test_passive_forces = expect(orfun( - not(Main.TestTrigger), - lteqfun(Calculations.passive_forces_vals, Calculations.passive_force_thresholds), - ), - "Muscles have to large passive forces!" - ); - AnyInt test_max_mus_act = expect(orfun( - not(Main.TestTrigger), - lteqfun(MaxMuscleActivity, 1.0), - ), - "Muscles Not strong enough inside active range of motion!" - ); - InverseDynamics.PreOperation = { - AnyOperation &EnableTests = Main.SetTestTrigger; - AnyOperation &UpdateValues = Main.UpdateValues; - }; - - InverseDynamics.PostOperation = { AnyOperation &ResetTestTrigger = Main.ResetTestTrigger;}; - }; - - - #if (BM_CALIBRATION_TYPE == _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_) & (BM_LEG_MODEL == _LEG_MODEL_TLEM_) - AnyInt TestTrigger = DesignVar(0); - AnyOperationMacro UpdateValues = { - MacroStr = {"classoperation Main " + strquote("Update Values")}; - }; - AnyOperationSetValue SetTestTrigger = { - AnyInt dummy = 1; - Source = {&dummy}; - Target = {&.TestTrigger}; - }; - AnyOperationSetValue ResetTestTrigger = { - AnyInt dummy = 0; - Source = {&dummy}; - Target = {&.TestTrigger}; - }; - - - RoMTestStudy HipFlexExtRoM() = { - AnyKinEqInterPolDriver Hip = { - AnyKinMeasure &measure = Main.HumanModel.BodyModel.Interface.Right.HipFlexion; - Type = PiecewiseLinear; - T = linspace(0,1,.nStep); - Data = { - linspace( - Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Hip.MaxExtensionAngle, - Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Hip.MaxFlexionAngle, - .nStep - ) * pi/180 + RoMTestStudy HipFlexExtRoM() = { + AnyKinEqInterPolDriver Hip = { + AnyKinMeasure &measure = Main.HumanModel.BodyModel.Interface.Right.HipFlexion; + Type = PiecewiseLinear; + T = linspace(0,1,.nStep); + Data = { + linspace( + Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Hip.MaxExtensionAngle, + Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Hip.MaxFlexionAngle, + .nStep + ) * pi/180 + }; + Reaction.Type = {Off}; }; - Reaction.Type = {Off}; }; - }; - RoMTestStudy HipAddAbdRoM() = { - AnyKinEqInterPolDriver Hip = { - AnyKinMeasure &measure = Main.HumanModel.BodyModel.Interface.Right.HipAbduction; - Type = PiecewiseLinear; - T = linspace(0,1,.nStep); - Data = { - linspace( - Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Hip.MaxAdductionAngle, - Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Hip.MaxAbductionAngle, - .nStep - ) * pi/180 + RoMTestStudy HipAddAbdRoM() = { + AnyKinEqInterPolDriver Hip = { + AnyKinMeasure &measure = Main.HumanModel.BodyModel.Interface.Right.HipAbduction; + Type = PiecewiseLinear; + T = linspace(0,1,.nStep); + Data = { + linspace( + Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Hip.MaxAdductionAngle, + Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Hip.MaxAbductionAngle, + .nStep + ) * pi/180 + }; + Reaction.Type = {Off}; }; - Reaction.Type = {Off}; }; - }; - RoMTestStudy HipRotRoM() = { - AnyKinEqInterPolDriver Hip = { - AnyKinMeasure &measure = Main.HumanModel.BodyModel.Interface.Right.HipExternalRotation; - Type = PiecewiseLinear; - T = linspace(0,1,.nStep); - Data = { - linspace( - Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Hip.MaxExternalRotationAngle, - Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Hip.MaxInternalRotationAngle, - .nStep - ) * pi/180 + RoMTestStudy HipRotRoM() = { + AnyKinEqInterPolDriver Hip = { + AnyKinMeasure &measure = Main.HumanModel.BodyModel.Interface.Right.HipExternalRotation; + Type = PiecewiseLinear; + T = linspace(0,1,.nStep); + Data = { + linspace( + Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Hip.MaxExternalRotationAngle, + Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Hip.MaxInternalRotationAngle, + .nStep + ) * pi/180 + }; + Reaction.Type = {Off}; }; - Reaction.Type = {Off}; }; - }; - RoMTestStudy KneeFlexExtRoM() = { - AnyKinEqInterPolDriver Knee = { - AnyKinMeasure &measure = Main.HumanModel.BodyModel.Interface.Right.KneeFlexion; - Type = PiecewiseLinear; - T = linspace(0,1,.nStep); - Data = { - linspace( - Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Knee.MaxExtensionAngle, - Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Knee.MaxFlexionAngle, - .nStep - ) * pi/180 + RoMTestStudy KneeFlexExtRoM() = { + AnyKinEqInterPolDriver Knee = { + AnyKinMeasure &measure = Main.HumanModel.BodyModel.Interface.Right.KneeFlexion; + Type = PiecewiseLinear; + T = linspace(0,1,.nStep); + Data = { + linspace( + Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Knee.MaxExtensionAngle, + Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Knee.MaxFlexionAngle, + .nStep + ) * pi/180 + }; + Reaction.Type = {Off}; }; - Reaction.Type = {Off}; }; - }; - RoMTestStudy AnkleFlexRoM() = { - AnyKinEqInterPolDriver Ankle = { - AnyKinMeasure &measure = Main.HumanModel.BodyModel.Interface.Right.AnklePlantarFlexion; - Type = PiecewiseLinear; - T = linspace(0,1,.nStep); - Data = { - linspace( - Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.MaxPlantarFlexionAngle, - Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.MaxDorsiFlexionAngle, - .nStep - ) * pi/180 + RoMTestStudy AnkleFlexRoM() = { + AnyKinEqInterPolDriver Ankle = { + AnyKinMeasure &measure = Main.HumanModel.BodyModel.Interface.Right.AnklePlantarFlexion; + Type = PiecewiseLinear; + T = linspace(0,1,.nStep); + Data = { + linspace( + Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.MaxPlantarFlexionAngle, + Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.MaxDorsiFlexionAngle, + .nStep + ) * pi/180 + }; + Reaction.Type = {Off}; }; - Reaction.Type = {Off}; }; - }; - RoMTestStudy AnkleEverInverRoM() = { - AnyKinEqInterPolDriver Ankle = { - AnyKinMeasure &measure = Main.HumanModel.BodyModel.Interface.Right.SubTalarEversion; - Type = PiecewiseLinear; - T = linspace(0,1,.nStep); - Data = { - linspace( - Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.MaxEversionAngle, - Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.MaxInversionAngle, - .nStep - ) * pi/180 + RoMTestStudy AnkleEverInverRoM() = { + AnyKinEqInterPolDriver Ankle = { + AnyKinMeasure &measure = Main.HumanModel.BodyModel.Interface.Right.SubTalarEversion; + Type = PiecewiseLinear; + T = linspace(0,1,.nStep); + Data = { + linspace( + Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.MaxEversionAngle, + Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.MaxInversionAngle, + .nStep + ) * pi/180 + }; + Reaction.Type = {Off}; }; - Reaction.Type = {Off}; }; - }; + #endif #endif }; From bb30410f137d0fbf8c9f0a0dcbec157ff2ccef1c Mon Sep 17 00:00:00 2001 From: bke Date: Mon, 2 Jun 2025 09:40:03 +0200 Subject: [PATCH 23/29] add joint stregnth test --- Tests/Calibration/test_joint_strength.py | 104 +++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 Tests/Calibration/test_joint_strength.py diff --git a/Tests/Calibration/test_joint_strength.py b/Tests/Calibration/test_joint_strength.py new file mode 100644 index 000000000..1a33c99f7 --- /dev/null +++ b/Tests/Calibration/test_joint_strength.py @@ -0,0 +1,104 @@ +from pathlib import Path +from itertools import product, groupby +from collections import ChainMap +from anypytools import AnyPyProcess, macro_commands as mc +from anypytools.abcutils import AnyPyProcessOutputList +from anypytools.tools import winepath, ON_WINDOWS + +import pytest + +ABS_TOL = 3 +MODEL_FILE = "test_calibration_lowerbody.any" +OPERATION = "Main.HumanModel.EvalulateJointStrength.Run_all_studies" +AMS_VARIABLES = [ + "Main.HumanModel.EvalulateJointStrength.Right.Leg.HipFlexion.Study.Output.JointStrength.JointStrength", + "Main.HumanModel.EvalulateJointStrength.Right.Leg.HipExtension.Study.Output.JointStrength.JointStrength", + "Main.HumanModel.EvalulateJointStrength.Right.Leg.KneeFlexion.Study.Output.JointStrength.JointStrength", + "Main.HumanModel.EvalulateJointStrength.Right.Leg.KneeExtension.Study.Output.JointStrength.JointStrength", + "Main.HumanModel.EvalulateJointStrength.Right.Leg.AnklePlantarFlexion.Study.Output.JointStrength.JointStrength", + "Main.HumanModel.EvalulateJointStrength.Right.Leg.AnkleDorsiFlexion.Study.Output.JointStrength.JointStrength", + "Main.HumanModel.EvalulateJointStrength.Right.Leg.HipAdduction.Study.Output.JointStrength.JointStrength", + "Main.HumanModel.EvalulateJointStrength.Right.Leg.HipAbduction.Study.Output.JointStrength.JointStrength", + "Main.HumanModel.EvalulateJointStrength.Right.Leg.HipInternalRotation.Study.Output.JointStrength.JointStrength", + "Main.HumanModel.EvalulateJointStrength.Right.Leg.HipExternalRotation.Study.Output.JointStrength.JointStrength", + "Main.HumanModel.EvalulateJointStrength.Right.Leg.SubTalarEversion.Study.Output.JointStrength.JointStrength", + "Main.HumanModel.EvalulateJointStrength.Right.Leg.SubTalarInversion.Study.Output.JointStrength.JointStrength", +] + +DEFINES_COMBINATIONS = product( + [ + {'BM_LEG_MODEL':'_LEG_MODEL_TLEM_'} + + ], + [ + {'BM_CALIBRATION_TYPE':'_EXPERIMENTAL_CALIBRATION_TYPE_2PAR_'} + ], + [ + {'BM_LEG_MUSCLES_BOTH': '_MUSCLES_3E_HILL_'}, + {'BM_LEG_MUSCLES_BOTH': '_MUSCLES_SIMPLE_'} + ], + [ + {"TEST_NAME":"test_cal_joint_strength_0"}, # set to indicate running from test framework + ], +) + +DEFINES = [dict(**ChainMap(*defs)) for defs in DEFINES_COMBINATIONS] + + +def all_equal(iterable) -> bool: + "Returns True if all the elements are equal to each other" + g = groupby(iterable) + return next(g, True) and not next(g, False) + + +def extract_output(output: AnyPyProcessOutputList) -> dict[str,list]: + """ extract output variables from the model into a dict""" + formatted = {} + for result in output: + for var in AMS_VARIABLES: + formatted.setdefault(var.split(".")[-1], []).append(result[var]) + + return formatted + + +def make_dump_commands(variables: list[str]) -> list[mc.MacroCommand]: + return [mc.Dump(var) for var in variables] + + +@pytest.fixture(scope="module") +def model_output() -> dict: + """ run the models and provide the test output""" + + model = next(Path().rglob(MODEL_FILE)).resolve() + + if not ON_WINDOWS: + model = winepath(model, "-w") + + macros = [] + for defs in DEFINES: + macros.append( + [ + mc.Load(model, defs=defs), + # mc.OperationRun(OPERATION), + # *make_dump_commands(AMS_VARIABLES), + ] + ) + + app = AnyPyProcess( + num_processes=2, + anybodycon_path= pytest.anytest.ams_path + ) + + results = app.start_macro(macros) + for result, defs in zip(results, DEFINES): + if 'ERROR' in result: + pytest.fail(f"Model had erros:\n{result['ERROR']}\n, defs: {defs}") + + return extract_output(results) + + +def test_joint_strength(model_output: AnyPyProcessOutputList): + """ test the trunk region mass""" + output = model_output["JointStrength"] + + rounded_vals = [round(val, ABS_TOL) for val in output] From 57c05adf95a595935550b173b11838897d0afc74 Mon Sep 17 00:00:00 2001 From: bke Date: Mon, 18 Aug 2025 11:54:03 +0200 Subject: [PATCH 24/29] add circular sweep code --- .../Calibration/2ParRightCalStudies.any | 13 ++++- Body/AAUHuman/LegTLEM/rangeOfMotion.any | 56 ++++++++++++++++++- 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any b/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any index 5a5d42838..be6004a21 100644 --- a/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any +++ b/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any @@ -123,7 +123,8 @@ TwoParCalibrationStudy RightCal6Ankle( ANKLE = On, SUBTALAR = On, ) = { - nStep = NumElemOf(AnklePositions); +// nStep = NumElemOf(AnklePositions); + nStep = NumElemOf(Obj2Num(AnklePositions)); MuscleArr = ObjSearch( &..BodyModel.Right.Leg.Mus, { @@ -135,8 +136,14 @@ TwoParCalibrationStudy RightCal6Ankle( "AnyMuscle" ); - AnklePositions = repmat(3, flattenptr(&.RangeOfMotion.Right.Leg.Ankle.ActiveRoMFlexion)); - SubTalarPositions = flatten(transpose(reshape(repmat(3, flattenptr(&.RangeOfMotion.Right.Leg.Ankle.ActiveRoMEversion)),{3,3}))); +// AnklePositions = repmat(3, flattenptr(&.RangeOfMotion.Right.Leg.Ankle.ActiveRoMFlexion)); +// SubTalarPositions = flatten(transpose(reshape(repmat(3, flattenptr(&.RangeOfMotion.Right.Leg.Ankle.ActiveRoMEversion)),{3,3}))); + +// AnklePositions = Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.SweepActiveRoMFlexion; +// SubTalarPositions = Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.SweepActiveRoMEversion; + + AnklePositions = &Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.circularSweep.v1Samples; + SubTalarPositions = &Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.circularSweep.v2Samples; }; diff --git a/Body/AAUHuman/LegTLEM/rangeOfMotion.any b/Body/AAUHuman/LegTLEM/rangeOfMotion.any index 9fae3a464..100324a0f 100644 --- a/Body/AAUHuman/LegTLEM/rangeOfMotion.any +++ b/Body/AAUHuman/LegTLEM/rangeOfMotion.any @@ -60,17 +60,71 @@ AnyFolder RangeOfMotion = { AnyVar MaxDorsiFlexionAngle = -20; AnyVar MaxInversionAngle = 15; AnyVar MaxEversionAngle = -20; - + AnyObjectPtrArray ActiveRoMFlexion = { &MaxPlantarFlexionAngle, &Neutral, &MaxDorsiFlexionAngle, }; + AnyObjectPtrArray ActiveRoMEversion = { &MaxInversionAngle, &Neutral, &MaxEversionAngle, }; + + + // Square grid without center + AnyInt NumOfPoints = 10; + AnyFloat FlexionAngles = linspace(MaxPlantarFlexionAngle, MaxDorsiFlexionAngle, NumOfPoints); + AnyFloat InversionAngles = linspace(MaxInversionAngle, MaxEversionAngle, NumOfPoints); + AnyFloat v1 = flatten(transpose(repmat(1, NumOfPoints, FlexionAngles))); + AnyFloat v2 = flatten(repmat(1, NumOfPoints, InversionAngles)); + AnyFloat values = {v1, v2}; + AnyObjectPtr SweepActiveRoMFlexion = &v1; + AnyObjectPtr SweepActiveRoMEversion = &v2; + + + // circular sweep + AnyInt m = 10; + AnyInt n = 10; + AnyFloat center = zeros(2,m*m); + AnyMatrix arr0 = {flatten(arr0x'), flatten(arr0y)}; +// AnyFloat array = center + (arr0 - center) * (1/repmat(2,m,rm)); + AnyFloat rm = im / m; + AnyIntArray im = iarr(1,m); + AnyFloat arr0x = repmat(1, m, FlexionAngles) * diag(rm); + AnyFloat arr0y = diag(rm) * repmat(1, m, InversionAngles) ;//* diag(rm); + + /** + Class template to sample a circular grid of points from start -> end for a 2d space. + m is the number of samples + */ + #class_template SampleRoM( + m, + v1_start, + v1_end, + v2_start, + v2_end, + ) { + AnyFolder calculations = { + AnyFloat v1_i = linspace(.v1_start, .v1_end, .m); + AnyFloat v2_i = linspace(.v2_start, .v2_end, .m); + AnyIntArray im = iarr(1,.m); + AnyFloat rm = im / .m; + }; + AnyFloat v1Samples = flatten(repmat(1, m, calculations.v1_i) * diag(calculations.rm)); + AnyFloat v2Samples = flatten(repmat(1, m, calculations.v2_i) * diag(calculations.rm)); + }; + + SampleRoM circularSweep( + m=.m, + v1_start=.MaxPlantarFlexionAngle, + v1_end=.MaxDorsiFlexionAngle, + v2_start=.MaxInversionAngle, + v2_end=.MaxEversionAngle + )={}; + }; }; \ No newline at end of file From 7d7288868953d1bc7c836a3c59bf5f1c438a8f99 Mon Sep 17 00:00:00 2001 From: bke Date: Mon, 18 Aug 2025 11:54:43 +0200 Subject: [PATCH 25/29] update joint strength test --- Tests/Calibration/test_joint_strength.py | 62 +++++++++++++++++++----- 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/Tests/Calibration/test_joint_strength.py b/Tests/Calibration/test_joint_strength.py index 1a33c99f7..9bad9f0d8 100644 --- a/Tests/Calibration/test_joint_strength.py +++ b/Tests/Calibration/test_joint_strength.py @@ -4,6 +4,7 @@ from anypytools import AnyPyProcess, macro_commands as mc from anypytools.abcutils import AnyPyProcessOutputList from anypytools.tools import winepath, ON_WINDOWS +import matplotlib.pyplot as plt import pytest @@ -27,15 +28,15 @@ DEFINES_COMBINATIONS = product( [ - {'BM_LEG_MODEL':'_LEG_MODEL_TLEM_'} + {'BM_LEG_MODEL': 1} # _LEG_MODEL_TLEM_ ], [ - {'BM_CALIBRATION_TYPE':'_EXPERIMENTAL_CALIBRATION_TYPE_2PAR_'} + {'BM_CALIBRATION_TYPE': 3} # _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_ ], [ - {'BM_LEG_MUSCLES_BOTH': '_MUSCLES_3E_HILL_'}, - {'BM_LEG_MUSCLES_BOTH': '_MUSCLES_SIMPLE_'} + {'BM_LEG_MUSCLES_BOTH': 2}, # _MUSCLES_3E_HILL_ + {'BM_LEG_MUSCLES_BOTH': 1} # _MUSCLES_SIMPLE_ ], [ {"TEST_NAME":"test_cal_joint_strength_0"}, # set to indicate running from test framework @@ -55,12 +56,24 @@ def extract_output(output: AnyPyProcessOutputList) -> dict[str,list]: """ extract output variables from the model into a dict""" formatted = {} for result in output: + muscle_config = get_muscle_config(result["task_macro"][0]) + for var in AMS_VARIABLES: - formatted.setdefault(var.split(".")[-1], []).append(result[var]) + formatted.setdefault(f"{muscle_config}_{var.split(".")[-5]}", result[var]) return formatted +def get_muscle_config(load_string: str) -> str: + """ get the muscle configuration from the load string""" + if 'BM_LEG_MUSCLES_BOTH="2"' in load_string: + return "3E" + elif 'BM_LEG_MUSCLES_BOTH="1"' in load_string: + return "SIMPLE" + else: + raise ValueError(f"Unknown muscle configuration in {load_string}") + + def make_dump_commands(variables: list[str]) -> list[mc.MacroCommand]: return [mc.Dump(var) for var in variables] @@ -79,8 +92,8 @@ def model_output() -> dict: macros.append( [ mc.Load(model, defs=defs), - # mc.OperationRun(OPERATION), - # *make_dump_commands(AMS_VARIABLES), + mc.OperationRun(OPERATION), + *make_dump_commands(AMS_VARIABLES), ] ) @@ -97,8 +110,35 @@ def model_output() -> dict: return extract_output(results) -def test_joint_strength(model_output: AnyPyProcessOutputList): - """ test the trunk region mass""" - output = model_output["JointStrength"] +def test_joint_strength(model_output: AnyPyProcessOutputList) -> None: + + # plot the same joint strength for each variable across different muscle configurations + joints = [ + "HipFlexion", + "HipExtension", + "KneeFlexion", + "KneeExtension", + "AnklePlantarFlexion", + "AnkleDorsiFlexion", + "HipAdduction", + "HipAbduction", + "HipInternalRotation", + "HipExternalRotation", + "SubTalarEversion", + "SubTalarInversion", + ] + for var in joints: + output: dict[str, list[float]] = {key: value for key, value in model_output.items() if var in key} + # plt.figure(figsize=(10, 6)) + for key, values in output.items(): + plt.plot(values, label=key) + plt.title(f"Joint Strength for {var}") + plt.xlabel("Study") + plt.ylabel("Joint Strength") + plt.legend() + plt.grid() + plt.savefig(f"Tests/Calibration/joint_strength_{var}.png") + plt.close() + - rounded_vals = [round(val, ABS_TOL) for val in output] + \ No newline at end of file From 99f07aff53cdde835618816a5bda0880d8b57050 Mon Sep 17 00:00:00 2001 From: bke Date: Mon, 18 Aug 2025 11:55:12 +0200 Subject: [PATCH 26/29] add matplotlib and pandas to env --- pixi.lock | 2285 ++++++++++++++++++++++++++++++++++++++++++++++++++++- pixi.toml | 2 + 2 files changed, 2267 insertions(+), 20 deletions(-) diff --git a/pixi.lock b/pixi.lock index 8f2460a59..d9d09e106 100644 --- a/pixi.lock +++ b/pixi.lock @@ -10,78 +10,149 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/anypytools-1.16.0-py312he424501_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-1.1.0-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.1.0-hb9d3cd8_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.1.0-py312h2ec8cdc_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.5-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.1.31-hbd8a1cb_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.4.26-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-1.17.1-py312h06ac9bb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py312h68727a3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.27-h54b06d7_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/dbus-1.13.6-h5008d03_3.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.14-py312h2ec8cdc_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.3.1-h5888daf_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.7.0-h5888daf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.58.1-py312h178313f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/freetype-2.13.3-ha770c72_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.13-h59595ed_1003.conda - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.2.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/h5py-3.13.0-nompi_py312hedeef09_100.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-11.2.1-h3beb420_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/hdf5-1.14.3-nompi_h2d575fe_109.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.10-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.1-h166bdaf_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.8-py312h84d6215_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.43-h712a8e2_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.3-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-31_h59b9bed_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.1.0-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.1.0-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.1.0-hb9d3cd8_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-31_he106b2a_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.6-default_h1df26ce_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang13-20.1.6-default_he06ed0a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h4637d8d_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.13.0-h332b0f4_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.24-h86f0d12_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.124-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.0-h5888daf_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.13.3-ha770c72_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.13.3-h48d6fc4_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-14.2.0-h767d61c_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.2.0-h69a702a_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-14.2.0-h69a702a_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-14.2.0-hf1ad2bd_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.1-h2ff4ddf_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.2.0-h767d61c_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h4ce23a2_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.0-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-31_h7ac8fdf_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.6-he9d0ab4_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.64.0-h161d5f1_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.29-pthreads_h94d23a6_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hd590300_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.47-h943b412_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libpq-17.5-h27ae623_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.49.1-hee588c1_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hf672d98_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-14.2.0-h8f9b012_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-14.2.0-h4852527_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hf01ce69_5.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.5.0-h851e524_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.10.0-h65c71a3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.8-h4bc477f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.39-h76b75d6_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.2-py312h178313f_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.3-py312h7900ff3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.3-py312hd3ec401_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nomkl-1.0-h5ca1d4c_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.5-py312h72c5963_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h5fbd93e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.0-h7b32b05_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.0-py312hf9745cd_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.44-hc749103_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-11.2.1-py312h80c1187_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.0-h29eaf8c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydoe-0.3.8-py_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments_anyscript-1.4.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.0-py312h91f0f75_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.12.10-h9e4cc4f_0_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.12-7_cp312.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.0-h8d00660_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.0.0-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/roman-numerals-py-3.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/scipy-1.15.2-py312ha707e6e_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-79.0.1-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-2.2.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-8.2.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-2.0.0-pyhd8ed1ab_1.conda @@ -92,69 +163,152 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.10-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-video-0.4.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.1-py312h66e93f0_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.13.2-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-16.0.0-py312h66e93f0_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/wayland-1.23.1-h3e06ad9_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-hb711507_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.5-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.44-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.6-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.1-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.4-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.23.0-py312h66e93f0_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda win-64: + - conda: https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-2_gnu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/anybody/win-64/anybodycon-8.1.1-20202.44880_12656.conda - conda: https://conda.anaconda.org/conda-forge/win-64/anypytools-1.16.0-py312h3de42fe_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-1.1.0-h2466b09_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-bin-1.1.0-h2466b09_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.1.0-py312h275cf98_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h2466b09_7.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.1.31-h4c7d964_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h5782bbf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.4.26-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-1.17.1-py312h4389bb4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.2-py312hd5eb7cc_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.14-py312h275cf98_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/double-conversion-3.3.1-he0c23c2_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.15.0-h765892d_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.58.1-py312h31fea79_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/freetype-2.13.3-h57928b3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.13-h63175ca_1003.conda - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.2.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/h5py-3.13.0-nompi_py312ha036244_100.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/harfbuzz-11.2.1-h8796e6f_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/hdf5-1.14.3-nompi_hb2c4d47_109.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/icu-75.1-he0c23c2_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.10-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.4.8-py312hc790b64_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.21.3-hdf4eb48_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/lcms2-2.17-hbcf6048_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/lerc-4.0.0-h6470a55_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libaec-1.1.3-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.9.0-31_h11dc60a_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.1.0-h2466b09_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.1.0-h2466b09_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.1.0-h2466b09_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.9.0-31_h9bd4c3b_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libclang13-20.1.6-default_h6e92b77_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.13.0-h88aaa65_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.24-h76ddb4d_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.0-he0c23c2_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.4.6-h537db12_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.13.3-h57928b3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.13.3-h0b5ce68_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgcc-15.1.0-h1383e82_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.84.1-h7025463_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgomp-15.1.0-h1383e82_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-h135ad9c_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.0-h2466b09_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.9.0-31_h2526c6b_openblas.conda - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libopenblas-0.3.29-pthreads_head3c61_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.47-h7a4582a_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.49.1-h67fdade_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.1-he619c9f_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.0-h05922d8_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.5.0-h3b0e114_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_9.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.13.8-h442d1da_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.39-h3df6e99_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.2-py312h31fea79_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.10.3-py312h2e8e312_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.3-py312h90004f6_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/nomkl-1.0-h5ca1d4c_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.2.5-py312h3150e54_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.3-h4d64b90_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.5.0-ha4e3fda_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pandas-2.3.0-py312h72972c8_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.44-h99c9b8b_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pillow-11.2.1-py312h078707f_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.0-had0cd8c_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-h0e40799_1002.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydoe-0.3.8-py_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments_anyscript-1.4.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyside6-6.9.0-py312h520aab8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.12.10-h3f84c4b_0_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.12-7_cp312.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-307-py312h275cf98_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/qhull-2020.2-hc790b64_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.9.0-h1ab902a_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.0.0-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/roman-numerals-py-3.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/scipy-1.15.2-py312h451d5c4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-79.0.1-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-2.2.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-8.2.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-2.0.0-pyhd8ed1ab_1.conda @@ -165,14 +319,19 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.10-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-video-0.4.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h5226925_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.1-py312h4389bb4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.13.2-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/unicodedata2-16.0.0-py312h4389bb4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h2b53caa_26.conda - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.42.34438-hfd919c2_26.conda - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-h0e40799_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-h0e40799_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstandard-0.23.0-py312h4389bb4_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-hbeecb71_2.conda default: channels: - url: https://conda.anaconda.org/conda-forge/ @@ -183,47 +342,129 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-1.1.0-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.1.0-hb9d3cd8_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.1.0-py313h46c70d0_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.1.31-hbd8a1cb_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.4.26-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-1.17.1-py313hfab6e84_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py313h33d0bda_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.27-h54b06d7_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/dbus-1.13.6-h5008d03_3.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.14-py313h46c70d0_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.3.1-h5888daf_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.7.0-h5888daf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.58.1-py313h8060acc_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/freetype-2.13.3-ha770c72_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.13-h59595ed_1003.conda - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.2.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-11.2.1-h3beb420_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.10-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.1-h166bdaf_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.7-py313h33d0bda_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.43-h712a8e2_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-31_h59b9bed_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.1.0-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.1.0-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.1.0-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-31_he106b2a_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.6-default_h1df26ce_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang13-20.1.6-default_he06ed0a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h4637d8d_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.24-h86f0d12_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.124-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.0-h5888daf_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.13.3-ha770c72_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.13.3-h48d6fc4_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-14.2.0-h767d61c_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.2.0-h69a702a_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-14.2.0-h69a702a_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-14.2.0-hf1ad2bd_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.1-h2ff4ddf_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.2.0-h767d61c_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h4ce23a2_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.0-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-31_h7ac8fdf_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.6-he9d0ab4_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-h4bc722e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.29-pthreads_h94d23a6_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hd590300_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.47-h943b412_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libpq-17.5-h27ae623_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.49.1-hee588c1_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-14.2.0-h8f9b012_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-14.2.0-h4852527_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hf01ce69_5.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.5.0-h851e524_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.10.0-h65c71a3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.8-h4bc477f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.39-h76b75d6_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.2-py313h8060acc_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.3-py313h78bf25f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.3-py313h129903b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.6-py313h17eae1a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h5fbd93e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.0-h7b32b05_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.0-py313ha87cce1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.44-hc749103_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-11.2.1-py313h8db990d_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.0-h29eaf8c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.0-py313h5f61773_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.3-hf636f53_101_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-7_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.0-h8d00660_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/roman-numerals-py-3.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-2.2.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-8.2.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-2.0.0-pyhd8ed1ab_1.conda @@ -234,44 +475,135 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.10-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-video-0.4.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.1-py313h536fd9c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/wayland-1.23.1-h3e06ad9_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-hb711507_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.5-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.44-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.6-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.1-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.4-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.23.0-py313h536fd9c_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda win-64: + - conda: https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-2_gnu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-1.1.0-h2466b09_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-bin-1.1.0-h2466b09_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.1.0-py313h5813708_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h2466b09_7.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.1.31-h4c7d964_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h5782bbf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.4.26-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-1.17.1-py313ha7868ed_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.2-py313h1ec8472_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.14-py313h5813708_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/double-conversion-3.3.1-he0c23c2_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.15.0-h765892d_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.58.1-py313hb4c8b1a_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/freetype-2.13.3-h57928b3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.13-h63175ca_1003.conda - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.2.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/harfbuzz-11.2.1-h8796e6f_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/icu-75.1-he0c23c2_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.10-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/intel-openmp-2024.2.1-h57928b3_1083.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.4.7-py313h1ec8472_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.21.3-hdf4eb48_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/lcms2-2.17-hbcf6048_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/lerc-4.0.0-h6470a55_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.9.0-31_h641d27c_mkl.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.1.0-h2466b09_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.1.0-h2466b09_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.1.0-h2466b09_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.9.0-31_h5e41251_mkl.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libclang13-20.1.6-default_h6e92b77_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.24-h76ddb4d_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.0-he0c23c2_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.4.6-h537db12_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.13.3-h57928b3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.13.3-h0b5ce68_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgcc-15.1.0-h1383e82_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.84.1-h7025463_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgomp-15.1.0-h1383e82_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.11.2-default_ha69328c_1001.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-h135ad9c_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.0-h2466b09_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.9.0-31_h1aa476e_mkl.conda - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-h2466b09_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.47-h7a4582a_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.49.1-h67fdade_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.0-h05922d8_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.5.0-h3b0e114_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_9.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.13.8-h442d1da_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.39-h3df6e99_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.2-py313hb4c8b1a_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.10.3-py313hfa70ccb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.3-py313h81b4f16_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2024.2.2-h66d3029_15.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.2.6-py313hefb8edb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.3-h4d64b90_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.5.0-ha4e3fda_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pandas-2.3.0-py313hf91d08e_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.44-h99c9b8b_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pillow-11.2.1-py313hda88b71_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.0-had0cd8c_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-h0e40799_1002.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyside6-6.9.0-py313hb43cee3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.3-h261c0b1_101_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-7_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/qhull-2020.2-hc790b64_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.9.0-h1ab902a_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/roman-numerals-py-3.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-2.2.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-8.2.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-2.0.0-pyhd8ed1ab_1.conda @@ -281,14 +613,19 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-2.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.10-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-video-0.4.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2021.13.0-h62715c5_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h5226925_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.1-py313ha7868ed_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h2b53caa_26.conda - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.42.34438-hfd919c2_26.conda - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-h0e40799_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-h0e40799_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstandard-0.23.0-py313ha7868ed_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-hbeecb71_2.conda docs: channels: - url: https://conda.anaconda.org/conda-forge/ @@ -568,47 +905,77 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/anypytools-1.16.0-py312he424501_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/azure-core-1.33.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/azure-storage-blob-12.25.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-1.1.0-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.1.0-hb9d3cd8_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.1.0-py312h2ec8cdc_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.5-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.1.31-hbd8a1cb_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.1.31-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-1.17.1-py312h06ac9bb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py312h68727a3_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-44.0.2-py312hda17c39_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.27-h54b06d7_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/dbus-1.13.6-h5008d03_3.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.14-py312h2ec8cdc_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.3.1-h5888daf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.7.0-h5888daf_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.58.1-py312h178313f_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/freetype-2.13.3-ha770c72_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.13-h59595ed_1003.conda - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.2.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/h5py-3.13.0-nompi_py312hedeef09_100.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-11.2.1-h3beb420_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/hdf5-1.14.3-nompi_h2d575fe_109.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.10-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/isodate-0.7.2-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.1-h166bdaf_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.8-py312h84d6215_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.43-h712a8e2_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.3-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-31_h59b9bed_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.1.0-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.1.0-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.1.0-hb9d3cd8_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-31_he106b2a_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.6-default_h1df26ce_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang13-20.1.6-default_he06ed0a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h4637d8d_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.13.0-h332b0f4_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.23-h86f0d12_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.124-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.0-h5888daf_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda @@ -618,14 +985,24 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.2.0-h69a702a_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-14.2.0-h69a702a_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-14.2.0-hf1ad2bd_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.1-h2ff4ddf_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.2.0-h767d61c_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h4ce23a2_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.0-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-31_h7ac8fdf_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.6-he9d0ab4_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.64.0-h161d5f1_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.29-pthreads_h94d23a6_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.47-h943b412_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libpq-17.5-h27ae623_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.49.1-hee588c1_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hf672d98_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-14.2.0-h8f9b012_2.conda @@ -635,30 +1012,46 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.5.0-h851e524_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.10.0-h65c71a3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.8-h4bc477f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.39-h76b75d6_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.2-py312h178313f_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.3-py312h7900ff3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.3-py312hd3ec401_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nomkl-1.0-h5ca1d4c_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.5-py312h72c5963_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h5fbd93e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.0-h7b32b05_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.0-py312hf9745cd_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.44-hc749103_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-11.1.0-py312h80c1187_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.0-h29eaf8c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydoe-0.3.8-py_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments_anyscript-1.4.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.0-py312h91f0f75_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-split-0.10.0-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.12.10-h9e4cc4f_0_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.12-7_cp312.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.0-h8d00660_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.0.0-pyh29332c3_0.conda @@ -677,12 +1070,35 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-video-0.4.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.1-py312h66e93f0_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.13.2-h0e9735f_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.13.2-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-16.0.0-py312h66e93f0_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/wayland-1.23.1-h3e06ad9_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-hb711507_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.5-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.44-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.6-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.1-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.4-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.23.0-py312h66e93f0_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda win-64: @@ -693,37 +1109,59 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/azure-core-1.33.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/azure-storage-blob-12.25.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-1.1.0-h2466b09_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-bin-1.1.0-h2466b09_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/brotli-python-1.1.0-py312h275cf98_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h2466b09_7.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.1.31-h4c7d964_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h5782bbf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.1.31-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-1.17.1-py312h4389bb4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.2-py312hd5eb7cc_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/cryptography-44.0.2-py312h9500af3_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/debugpy-1.8.14-py312h275cf98_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/double-conversion-3.3.1-he0c23c2_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.15.0-h765892d_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.58.1-py312h31fea79_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/freetype-2.13.3-h57928b3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.13-h63175ca_1003.conda - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.2.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/h5py-3.13.0-nompi_py312ha036244_100.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/harfbuzz-11.2.1-h8796e6f_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/hdf5-1.14.3-nompi_hb2c4d47_109.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/icu-75.1-he0c23c2_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.10-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/isodate-0.7.2-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.4.8-py312hc790b64_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.21.3-hdf4eb48_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/lcms2-2.17-hbcf6048_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/lerc-4.0.0-h6470a55_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libaec-1.1.3-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.9.0-31_h11dc60a_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.1.0-h2466b09_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.1.0-h2466b09_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.1.0-h2466b09_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.9.0-31_h9bd4c3b_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libclang13-20.1.6-default_h6e92b77_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.13.0-h88aaa65_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.23-h76ddb4d_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.0-he0c23c2_0.conda @@ -731,7 +1169,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.13.3-h57928b3_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.13.3-h0b5ce68_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libgcc-14.2.0-h1383e82_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.84.1-h7025463_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libgomp-14.2.0-h1383e82_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-h135ad9c_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.0-h2466b09_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.9.0-31_h2526c6b_openblas.conda - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_0.conda @@ -743,30 +1184,44 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.5.0-h3b0e114_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_9.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.13.8-h442d1da_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.39-h3df6e99_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-3.0.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/markupsafe-3.0.2-py312h31fea79_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.10.3-py312h2e8e312_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.3-py312h90004f6_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/nomkl-1.0-h5ca1d4c_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.2.5-py312h3150e54_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.3-h4d64b90_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.5.0-ha4e3fda_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pandas-2.3.0-py312h72972c8_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.44-h99c9b8b_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/pillow-11.1.0-py312h078707f_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.0-had0cd8c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-h0e40799_1002.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydoe-0.3.8-py_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments_anyscript-1.4.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyside6-6.9.0-py312h520aab8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-split-0.10.0-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.12.10-h3f84c4b_0_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.12-7_cp312.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-307-py312h275cf98_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/qhull-2020.2-hc790b64_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.9.0-h1ab902a_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rich-14.0.0-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/roman-numerals-py-3.1.0-pyhd8ed1ab_0.conda @@ -784,10 +1239,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-video-0.4.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h5226925_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.1-py312h4389bb4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.13.2-h0e9735f_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.13.2-pyh29332c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/unicodedata2-16.0.0-py312h4389bb4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h2b53caa_26.conda - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.42.34438-hfd919c2_26.conda @@ -849,6 +1306,16 @@ packages: license_family: BSD size: 18684 timestamp: 1733750512696 +- conda: https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda + sha256: b9214bc17e89bf2b691fad50d952b7f029f6148f4ac4fe7c60c08f093efdf745 + md5: 76df83c2a9035c54df5d04ff81bcc02d + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: LGPL-2.1-or-later + license_family: GPL + size: 566531 + timestamp: 1744668655747 - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda sha256: e0ea1ba78fbb64f17062601edda82097fcf815012cf52bb704150a2668110d48 md5: 2934f256a8acfe48f6ebb4fce6cde29c @@ -1126,6 +1593,50 @@ packages: license_family: BSD size: 11065 timestamp: 1615209567874 +- conda: https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda + sha256: 3bd6a391ad60e471de76c0e9db34986c4b5058587fbf2efa5a7f54645e28c2c7 + md5: 09262e66b19567aff4f592fb53b28760 + depends: + - __glibc >=2.17,<3.0.a0 + - fontconfig >=2.15.0,<3.0a0 + - fonts-conda-ecosystem + - freetype >=2.12.1,<3.0a0 + - icu >=75.1,<76.0a0 + - libexpat >=2.6.4,<3.0a0 + - libgcc >=13 + - libglib >=2.82.2,<3.0a0 + - libpng >=1.6.47,<1.7.0a0 + - libstdcxx >=13 + - libxcb >=1.17.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - pixman >=0.44.2,<1.0a0 + - xorg-libice >=1.1.2,<2.0a0 + - xorg-libsm >=1.2.5,<2.0a0 + - xorg-libx11 >=1.8.11,<2.0a0 + - xorg-libxext >=1.3.6,<2.0a0 + - xorg-libxrender >=0.9.12,<0.10.0a0 + license: LGPL-2.1-only or MPL-1.1 + size: 978114 + timestamp: 1741554591855 +- conda: https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h5782bbf_0.conda + sha256: b9f577bddb033dba4533e851853924bfe7b7c1623d0697df382eef177308a917 + md5: 20e32ced54300292aff690a69c5e7b97 + depends: + - fontconfig >=2.15.0,<3.0a0 + - fonts-conda-ecosystem + - freetype >=2.12.1,<3.0a0 + - icu >=75.1,<76.0a0 + - libexpat >=2.6.4,<3.0a0 + - libglib >=2.82.2,<3.0a0 + - libpng >=1.6.47,<1.7.0a0 + - libzlib >=1.3.1,<2.0a0 + - pixman >=0.44.2,<1.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: LGPL-2.1-only or MPL-1.1 + size: 1524254 + timestamp: 1741555212198 - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2025.1.31-pyhd8ed1ab_0.conda sha256: 42a78446da06a2568cb13e69be3355169fbd0ea424b00fc80b7d840f5baaacf3 md5: c207fa5ac7ea99b149344385a9c0880d @@ -1225,6 +1736,20 @@ packages: license_family: BSD size: 27011 timestamp: 1733218222191 +- conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py312h68727a3_0.conda + sha256: 4c8f2aa34aa031229e6f8aa18f146bce7987e26eae9c6503053722a8695ebf0c + md5: e688276449452cdfe9f8f5d3e74c23f6 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libstdcxx >=13 + - numpy >=1.23 + - python >=3.12,<3.13.0a0 + - python_abi 3.12.* *_cp312 + license: BSD-3-Clause + license_family: BSD + size: 276533 + timestamp: 1744743235779 - conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py313h33d0bda_0.conda sha256: 8e6e7c9644fa4841909f46b8136b6fad540c9c7b2688bfc15e8f9ce5eef0aabe md5: 5dc81fffe102f63045225007a33d6199 @@ -1239,6 +1764,20 @@ packages: license_family: BSD size: 278576 timestamp: 1744743243839 +- conda: https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.2-py312hd5eb7cc_0.conda + sha256: 9b552bcab6c1e3a364cbc010bdef3d26831c90984b7d0852a1dd70659d9cf84a + md5: bfcbb98aff376f62298f0801ca9bcfc3 + depends: + - numpy >=1.23 + - python >=3.12,<3.13.0a0 + - python_abi 3.12.* *_cp312 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-3-Clause + license_family: BSD + size: 217491 + timestamp: 1744743749434 - conda: https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.2-py313h1ec8472_0.conda sha256: e791b7cce4c7e1382140e7c542d0436ce78a605504b23f6f33c6c0f0cd01e9f2 md5: 5cc68b7c893d2e3b9d838ef3b8716862 @@ -1293,6 +1832,30 @@ packages: license_family: BSD size: 13399 timestamp: 1733332563512 +- conda: https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.27-h54b06d7_7.conda + sha256: d2ea5e52da745c4249e1a818095a28f9c57bd4df22cbfc645352defa468e86c2 + md5: dce22f70b4e5a407ce88f2be046f4ceb + depends: + - krb5 >=1.21.1,<1.22.0a0 + - libgcc-ng >=12 + - libntlm + - libstdcxx-ng >=12 + - openssl >=3.1.1,<4.0a0 + license: BSD-3-Clause-Attribution + license_family: BSD + size: 219527 + timestamp: 1690061203707 +- conda: https://conda.anaconda.org/conda-forge/linux-64/dbus-1.13.6-h5008d03_3.tar.bz2 + sha256: 8f5f995699a2d9dbdd62c61385bfeeb57c82a681a7c8c5313c395aa0ccab68a5 + md5: ecfff944ba3960ecb334b9a2663d708d + depends: + - expat >=2.4.2,<3.0a0 + - libgcc-ng >=9.4.0 + - libglib >=2.70.2,<3.0a0 + license: GPL-2.0-or-later + license_family: GPL + size: 618596 + timestamp: 1640112124844 - conda: https://conda.anaconda.org/conda-forge/linux-64/debugpy-1.8.14-py312h2ec8cdc_0.conda sha256: 8f0b338687f79ea87324f067bedddd2168f07b8eec234f0fe63b522344c6a919 md5: 089cf3a3becf0e2f403feaf16e921678 @@ -1353,6 +1916,28 @@ packages: license: CC-PDDC AND BSD-3-Clause AND BSD-2-Clause AND ZPL-2.1 size: 402700 timestamp: 1733217860944 +- conda: https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.3.1-h5888daf_0.conda + sha256: 1bcc132fbcc13f9ad69da7aa87f60ea41de7ed4d09f3a00ff6e0e70e1c690bc2 + md5: bfd56492d8346d669010eccafe0ba058 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libstdcxx >=13 + license: BSD-3-Clause + license_family: BSD + size: 69544 + timestamp: 1739569648873 +- conda: https://conda.anaconda.org/conda-forge/win-64/double-conversion-3.3.1-he0c23c2_0.conda + sha256: b1fee32ef36a98159f0a2a96c4e734dfc9adff73acd444940831b22c1fb6d5c0 + md5: e9a1402439c18a4e3c7a52e4246e9e1c + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-3-Clause + license_family: BSD + size: 71355 + timestamp: 1739570178995 - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_1.conda sha256: cbde2c64ec317118fc06b223c5fd87c8a680255e7348dd60e7b292d2e103e701 md5: a16662747cdeb9abbac74d0057cc976e @@ -1370,6 +1955,95 @@ packages: license_family: MIT size: 38835 timestamp: 1733231086305 +- conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.7.0-h5888daf_0.conda + sha256: dd5530ddddca93b17318838b97a2c9d7694fa4d57fc676cf0d06da649085e57a + md5: d6845ae4dea52a2f90178bf1829a21f8 + depends: + - __glibc >=2.17,<3.0.a0 + - libexpat 2.7.0 h5888daf_0 + - libgcc >=13 + license: MIT + license_family: MIT + size: 140050 + timestamp: 1743431809745 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + sha256: 58d7f40d2940dd0a8aa28651239adbf5613254df0f75789919c4e6762054403b + md5: 0c96522c6bdaed4b1566d11387caaf45 + license: BSD-3-Clause + license_family: BSD + size: 397370 + timestamp: 1566932522327 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + sha256: c52a29fdac682c20d252facc50f01e7c2e7ceac52aa9817aaf0bb83f7559ec5c + md5: 34893075a5c9e55cdafac56607368fc6 + license: OFL-1.1 + license_family: Other + size: 96530 + timestamp: 1620479909603 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + sha256: 00925c8c055a2275614b4d983e1df637245e19058d79fc7dd1a93b8d9fb4b139 + md5: 4d59c254e01d9cde7957100457e2d5fb + license: OFL-1.1 + license_family: Other + size: 700814 + timestamp: 1620479612257 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda + sha256: 2821ec1dc454bd8b9a31d0ed22a7ce22422c0aef163c59f49dfdf915d0f0ca14 + md5: 49023d73832ef61042f6a237cb2687e7 + license: LicenseRef-Ubuntu-Font-Licence-Version-1.0 + license_family: Other + size: 1620504 + timestamp: 1727511233259 +- conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda + sha256: 7093aa19d6df5ccb6ca50329ef8510c6acb6b0d8001191909397368b65b02113 + md5: 8f5b0b297b59e1ac160ad4beec99dbee + depends: + - __glibc >=2.17,<3.0.a0 + - freetype >=2.12.1,<3.0a0 + - libexpat >=2.6.3,<3.0a0 + - libgcc >=13 + - libuuid >=2.38.1,<3.0a0 + - libzlib >=1.3.1,<2.0a0 + license: MIT + license_family: MIT + size: 265599 + timestamp: 1730283881107 +- conda: https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.15.0-h765892d_1.conda + sha256: ed122fc858fb95768ca9ca77e73c8d9ddc21d4b2e13aaab5281e27593e840691 + md5: 9bb0026a2131b09404c59c4290c697cd + depends: + - freetype >=2.12.1,<3.0a0 + - libexpat >=2.6.3,<3.0a0 + - libiconv >=1.17,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + size: 192355 + timestamp: 1730284147944 +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + sha256: a997f2f1921bb9c9d76e6fa2f6b408b7fa549edd349a77639c9fe7a23ea93e61 + md5: fee5683a3f04bd15cbd8318b096a27ab + depends: + - fonts-conda-forge + license: BSD-3-Clause + license_family: BSD + size: 3667 + timestamp: 1566974674465 +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 + sha256: 53f23a3319466053818540bcdf2091f253cbdbab1e0e9ae7b9e509dcaa2a5e38 + md5: f766549260d6815b0c52253f1fb1bb29 + depends: + - font-ttf-dejavu-sans-mono + - font-ttf-inconsolata + - font-ttf-source-code-pro + - font-ttf-ubuntu + license: BSD-3-Clause + license_family: BSD + size: 4102 + timestamp: 1566932280397 - conda: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.57.0-py313h8060acc_0.conda sha256: 069c91292b986dd1ceeaf186908ccd312aba9e461022949edfa6828f04d47abf md5: 76b3a3367ac578a7cc43f4b7814e7e87 @@ -1384,6 +2058,35 @@ packages: license_family: MIT size: 2847860 timestamp: 1743732656559 +- conda: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.58.1-py312h178313f_0.conda + sha256: e393557ad5ca31f71ec59da7035eea0d8d9a87ef1807fda832d2953112e71588 + md5: 59ac6c124428928a1a41691eedf2b3bd + depends: + - __glibc >=2.17,<3.0.a0 + - brotli + - libgcc >=13 + - munkres + - python >=3.12,<3.13.0a0 + - python_abi 3.12.* *_cp312 + - unicodedata2 >=15.1.0 + license: MIT + license_family: MIT + size: 2862750 + timestamp: 1748465641381 +- conda: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.58.1-py313h8060acc_0.conda + sha256: c510622fc0e9adfd0756e94fa8a017633664e80bc98d5e209766aaf1bb1f9c10 + md5: f03a1dc39346922cb5cf2ee190ac9b95 + depends: + - __glibc >=2.17,<3.0.a0 + - brotli + - libgcc >=13 + - munkres + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + license: MIT + license_family: MIT + size: 2865585 + timestamp: 1748465743413 - conda: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.57.0-py313hb4c8b1a_0.conda sha256: 750a7d94f1ab8f9452204f2f468b4bb50cc47e70c15296c4e89ba20241ba7471 md5: a7cb72059cad745b6c193d7d8d922b82 @@ -1399,12 +2102,43 @@ packages: license_family: MIT size: 2449299 timestamp: 1743732768155 -- conda: https://conda.anaconda.org/conda-forge/linux-64/freetype-2.13.3-ha770c72_1.conda - sha256: 7ef7d477c43c12a5b4cddcf048a83277414512d1116aba62ebadfa7056a7d84f - md5: 9ccd736d31e0c6e41f54e704e5312811 +- conda: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.58.1-py312h31fea79_0.conda + sha256: 67721282cc0cad4b9d2fb1a6a9987b3090cd6c5a516ffef293e4f8181556c20a + md5: fbe3cbbe4fc661f033725bd9a958bb52 depends: - - libfreetype 2.13.3 ha770c72_1 - - libfreetype6 2.13.3 h48d6fc4_1 + - brotli + - munkres + - python >=3.12,<3.13.0a0 + - python_abi 3.12.* *_cp312 + - ucrt >=10.0.20348.0 + - unicodedata2 >=15.1.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + size: 2421825 + timestamp: 1748465991875 +- conda: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.58.1-py313hb4c8b1a_0.conda + sha256: 12a7530950212556e6e873bd80cf705359f2eb23cd367d18437d0054c3eb94d5 + md5: b6768271381091c86a03696fdeb60d97 + depends: + - brotli + - munkres + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + size: 2455592 + timestamp: 1748466107179 +- conda: https://conda.anaconda.org/conda-forge/linux-64/freetype-2.13.3-ha770c72_1.conda + sha256: 7ef7d477c43c12a5b4cddcf048a83277414512d1116aba62ebadfa7056a7d84f + md5: 9ccd736d31e0c6e41f54e704e5312811 + depends: + - libfreetype 2.13.3 ha770c72_1 + - libfreetype6 2.13.3 h48d6fc4_1 license: GPL-2.0-only OR FTL size: 172450 timestamp: 1745369996765 @@ -1417,6 +2151,27 @@ packages: license: GPL-2.0-only OR FTL size: 184162 timestamp: 1745370242683 +- conda: https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.13-h59595ed_1003.conda + sha256: 0595b009f20f8f60f13a6398e7cdcbd2acea5f986633adcf85f5a2283c992add + md5: f87c7b7c2cb45f323ffbce941c78ab7c + depends: + - libgcc-ng >=12 + - libstdcxx-ng >=12 + license: LGPL-2.0-or-later + license_family: LGPL + size: 96855 + timestamp: 1711634169756 +- conda: https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.13-h63175ca_1003.conda + sha256: 25040a4f371b9b51663f546bac620122c237fa1d5d32968e21b0751af9b7f56f + md5: 3194499ee7d1a67404a87d0eefdd92c6 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: LGPL-2.0-or-later + license_family: LGPL + size: 95406 + timestamp: 1711634622644 - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.2.0-pyhd8ed1ab_0.conda sha256: 0aa1cdc67a9fe75ea95b5644b734a756200d6ec9d0dff66530aec3d1c1e9df75 md5: b4754fb1bdcb70c8fd54f918301582c6 @@ -1459,6 +2214,46 @@ packages: license_family: BSD size: 1100814 timestamp: 1739952768979 +- conda: https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-11.2.1-h3beb420_0.conda + sha256: 5bd0f3674808862838d6e2efc0b3075e561c34309c5c2f4c976f7f1f57c91112 + md5: 0e6e192d4b3d95708ad192d957cf3163 + depends: + - __glibc >=2.17,<3.0.a0 + - cairo >=1.18.4,<2.0a0 + - freetype + - graphite2 + - icu >=75.1,<76.0a0 + - libexpat >=2.7.0,<3.0a0 + - libfreetype >=2.13.3 + - libfreetype6 >=2.13.3 + - libgcc >=13 + - libglib >=2.84.1,<3.0a0 + - libstdcxx >=13 + - libzlib >=1.3.1,<2.0a0 + license: MIT + license_family: MIT + size: 1730226 + timestamp: 1747091044218 +- conda: https://conda.anaconda.org/conda-forge/win-64/harfbuzz-11.2.1-h8796e6f_0.conda + sha256: 26e09e2b43d498523c08c58ea485c883478b74e2fb664c0321089e5c10318d32 + md5: bccea58fbf7910ce868b084f27ffe8bd + depends: + - cairo >=1.18.4,<2.0a0 + - freetype + - graphite2 + - icu >=75.1,<76.0a0 + - libexpat >=2.7.0,<3.0a0 + - libfreetype >=2.13.3 + - libfreetype6 >=2.13.3 + - libglib >=2.84.1,<3.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + size: 1126103 + timestamp: 1747093237683 - conda: https://conda.anaconda.org/conda-forge/linux-64/hdf5-1.14.3-nompi_h2d575fe_109.conda sha256: e8669a6d76d415f4fdbe682507ac3a3b39e8f493d2f2bdc520817f80b7cc0753 md5: e7a7a6e6f70553a31e6e79c65768d089 @@ -1509,6 +2304,28 @@ packages: license_family: MIT size: 17397 timestamp: 1737618427549 +- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda + sha256: 71e750d509f5fa3421087ba88ef9a7b9be11c53174af3aa4d06aff4c18b38e8e + md5: 8b189310083baabfb622af68fd9d3ae3 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc-ng >=12 + - libstdcxx-ng >=12 + license: MIT + license_family: MIT + size: 12129203 + timestamp: 1720853576813 +- conda: https://conda.anaconda.org/conda-forge/win-64/icu-75.1-he0c23c2_0.conda + sha256: 1d04369a1860a1e9e371b9fc82dd0092b616adcf057d6c88371856669280e920 + md5: 8579b6bb8d18be7c0b27fb08adeeeb40 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + size: 14544252 + timestamp: 1720853966338 - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.10-pyhd8ed1ab_1.conda sha256: d7a472c9fd479e2e8dcb83fb8d433fce971ea369d704ece380e876f9c3494e87 md5: 39a4f67be3286c86d696df570b1201b7 @@ -1593,6 +2410,19 @@ packages: license_family: BSD size: 70982 timestamp: 1725459393722 +- conda: https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.8-py312h84d6215_0.conda + sha256: 3ce99d721c1543f6f8f5155e53eef11be47b2f5942a8d1060de6854f9d51f246 + md5: 6713467dc95509683bfa3aca08524e8a + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libstdcxx >=13 + - python >=3.12,<3.13.0a0 + - python_abi 3.12.* *_cp312 + license: BSD-3-Clause + license_family: BSD + size: 71649 + timestamp: 1736908364705 - conda: https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.4.7-py313h1ec8472_0.conda sha256: 7ac87046ee34efbd99282f62a4f33214085f999294e3ba7f8a1b5cb3fa00d8e4 md5: 9239895dcd4116c6042ffe0a4e81706a @@ -1606,6 +2436,19 @@ packages: license_family: BSD size: 55591 timestamp: 1725459960401 +- conda: https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.4.8-py312hc790b64_0.conda + sha256: 2cce3d9bcc95c68069e3032cda25b732f69be7b025f94685ee4783d7b54588dd + md5: 7ef59428fc0dcb8a78a5e23dc4f50aa3 + depends: + - python >=3.12,<3.13.0a0 + - python_abi 3.12.* *_cp312 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-3-Clause + license_family: BSD + size: 71318 + timestamp: 1736908754898 - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda sha256: 99df692f7a8a5c27cd14b5fb1374ee55e756631b9c3d659ed3ee60830249b238 md5: 3f43953b7d3fb3aaa1d0d0723d91e368 @@ -1883,6 +2726,55 @@ packages: license_family: BSD size: 3946225 timestamp: 1740088645546 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.6-default_h1df26ce_0.conda + sha256: c2194ccfd8e6ef422a7fcf21b9b72efd8859f84d3792f54ff6be87574751b913 + md5: 99ead3b974685e44df8b1e3953503cfc + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libllvm20 >=20.1.6,<20.2.0a0 + - libstdcxx >=13 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 20859825 + timestamp: 1748541570131 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libclang13-20.1.6-default_he06ed0a_0.conda + sha256: 5d40dc0cf929532ba4337bf1c7dbe1abb5f7c19ceb76397406006e9946a73fd4 + md5: cc6c469d9d7fc0ac106cef5f45d973a9 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libllvm20 >=20.1.6,<20.2.0a0 + - libstdcxx >=13 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 12111337 + timestamp: 1748541871797 +- conda: https://conda.anaconda.org/conda-forge/win-64/libclang13-20.1.6-default_h6e92b77_0.conda + sha256: 6ac6dc226a2fe5af61730224d89cd32f88123623bf35995a2c42d53a077e0427 + md5: 3920536319b052a9a49639e02fda2db7 + depends: + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 28337445 + timestamp: 1748541917495 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h4637d8d_4.conda + sha256: bc67b9b21078c99c6bd8595fe7e1ed6da1f721007726e717f0449de7032798c4 + md5: d4529f4dff3057982a7617c7ac58fde3 + depends: + - krb5 >=1.21.1,<1.22.0a0 + - libgcc-ng >=12 + - libstdcxx-ng >=12 + - libzlib >=1.2.13,<2.0.0a0 + license: Apache-2.0 + license_family: Apache + size: 4519402 + timestamp: 1689195353551 - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.13.0-h332b0f4_0.conda sha256: 38e528acfaa0276b7052f4de44271ff9293fdb84579650601a8c49dac171482a md5: cbdc92ac0d93fe3c796e36ad65c7905c @@ -1922,6 +2814,16 @@ packages: license: MIT size: 72783 timestamp: 1745260463421 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.24-h86f0d12_0.conda + sha256: 8420748ea1cc5f18ecc5068b4f24c7a023cc9b20971c99c824ba10641fb95ddf + md5: 64f0c503da58ec25ebd359e4d990afa8 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: MIT + license_family: MIT + size: 72573 + timestamp: 1747040452262 - conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.23-h76ddb4d_0.conda sha256: 881244050587dc658078ee45dfc792ecb458bbb1fdc861da67948d747b117dc2 md5: 34f03138e46543944d4d7f8538048842 @@ -1932,6 +2834,28 @@ packages: license: MIT size: 155548 timestamp: 1745260818985 +- conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.24-h76ddb4d_0.conda + sha256: 65347475c0009078887ede77efe60db679ea06f2b56f7853b9310787fe5ad035 + md5: 08d988e266c6ae77e03d164b83786dc4 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + size: 156292 + timestamp: 1747040812624 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.124-hb9d3cd8_0.conda + sha256: f0d5ffbdf3903a7840184d14c14154b503e1a96767c328f61d99ad24b6963e52 + md5: 8bc89311041d7fcb510238cf0848ccae + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libpciaccess >=0.18,<0.19.0a0 + license: MIT + license_family: MIT + size: 242533 + timestamp: 1733424409299 - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda sha256: d789471216e7aba3c184cd054ed61ce3f6dac6f87a50ec69291b9297f8c18724 md5: c277e0a4d549b03ac1e9d6cbbe3d017b @@ -1944,6 +2868,15 @@ packages: license_family: BSD size: 134676 timestamp: 1738479519902 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda + sha256: 7fd5408d359d05a969133e47af580183fbf38e2235b562193d427bb9dad79723 + md5: c151d5eb730e9b7480e6d48c0fc44048 + depends: + - __glibc >=2.17,<3.0.a0 + - libglvnd 1.7.0 ha4b6fd6_2 + license: LicenseRef-libglvnd + size: 44840 + timestamp: 1731330973553 - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda sha256: 1cd6048169fa0395af74ed5d8f1716e22c19a81a8a36f934c110ca3ad4dd27b4 md5: 172bf1cd1ff8629f2b1179945ed45055 @@ -2069,6 +3002,20 @@ packages: license_family: GPL size: 666343 timestamp: 1740240717807 +- conda: https://conda.anaconda.org/conda-forge/win-64/libgcc-15.1.0-h1383e82_2.conda + sha256: c0288596ac58366d96a56c57e4088fe1c6dd4194fdcaeacf5862f47fb1e1e5be + md5: 9bedb24480136bfeb81ebc81d4285e70 + depends: + - _openmp_mutex >=4.5 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + constrains: + - msys2-conda-epoch <0.0a0 + - libgcc-ng ==15.1.0=*_2 + - libgomp 15.1.0 h1383e82_2 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 673459 + timestamp: 1746656621653 - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.2.0-h69a702a_2.conda sha256: fb7558c328b38b2f9d2e412c48da7890e7721ba018d733ebdfea57280df01904 md5: a2222a6ada71fb478682efe483ce0f92 @@ -2101,6 +3048,66 @@ packages: license_family: GPL size: 1461978 timestamp: 1740240671964 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda + sha256: dc2752241fa3d9e40ce552c1942d0a4b5eeb93740c9723873f6fcf8d39ef8d2d + md5: 928b8be80851f5d8ffb016f9c81dae7a + depends: + - __glibc >=2.17,<3.0.a0 + - libglvnd 1.7.0 ha4b6fd6_2 + - libglx 1.7.0 ha4b6fd6_2 + license: LicenseRef-libglvnd + size: 134712 + timestamp: 1731330998354 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.1-h2ff4ddf_0.conda + sha256: 18e354d30a60441b0bf5fcbb125b6b22fd0df179620ae834e2533d44d1598211 + md5: 0305434da649d4fb48a425e588b79ea6 + depends: + - __glibc >=2.17,<3.0.a0 + - libffi >=3.4.6,<3.5.0a0 + - libgcc >=13 + - libiconv >=1.18,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - pcre2 >=10.44,<10.45.0a0 + constrains: + - glib 2.84.1 *_0 + license: LGPL-2.1-or-later + size: 3947789 + timestamp: 1743773764878 +- conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.84.1-h7025463_0.conda + sha256: 75a35a0134c7b2f3f41dbf24faa417be6a98a70db23dc1225b0c74ea45c0ce61 + md5: 6cbaea9075a4f007eb7d0a90bb9a2a09 + depends: + - libffi >=3.4.6,<3.5.0a0 + - libiconv >=1.18,<2.0a0 + - libintl >=0.22.5,<1.0a0 + - libzlib >=1.3.1,<2.0a0 + - pcre2 >=10.44,<10.45.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + constrains: + - glib 2.84.1 *_0 + license: LGPL-2.1-or-later + size: 3806534 + timestamp: 1743774256525 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda + sha256: 1175f8a7a0c68b7f81962699751bb6574e6f07db4c9f72825f978e3016f46850 + md5: 434ca7e50e40f4918ab701e3facd59a0 + depends: + - __glibc >=2.17,<3.0.a0 + license: LicenseRef-libglvnd + size: 132463 + timestamp: 1731330968309 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda + sha256: 2d35a679624a93ce5b3e9dd301fff92343db609b79f0363e6d0ceb3a6478bfa7 + md5: c8013e438185f33b13814c5c488acd5c + depends: + - __glibc >=2.17,<3.0.a0 + - libglvnd 1.7.0 ha4b6fd6_2 + - xorg-libx11 >=1.8.10,<2.0a0 + license: LicenseRef-libglvnd + size: 75504 + timestamp: 1731330988898 - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.2.0-h767d61c_2.conda sha256: 1a3130e0b9267e781b89399580f3163632d59fe5b0142900d63052ab1a53490e md5: 06d02030237f4d5b3d9a7e7d348fe3c6 @@ -2121,6 +3128,17 @@ packages: license_family: GPL size: 524548 timestamp: 1740240660967 +- conda: https://conda.anaconda.org/conda-forge/win-64/libgomp-15.1.0-h1383e82_2.conda + sha256: 4316316097ce5fde2608b6fccd18709cf647dce52e230f5ac66f5c524dfad791 + md5: 5fbacaa9b41e294a6966602205b99747 + depends: + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + constrains: + - msys2-conda-epoch <0.0a0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 540903 + timestamp: 1746656563815 - conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.11.2-default_ha69328c_1001.conda sha256: 850e255997f538d5fb6ed651321141155a33bb781d43d326fc4ff62114dd2842 md5: b87a0ac5ab6495d8225db5dc72dd21cd @@ -2134,6 +3152,15 @@ packages: license_family: BSD size: 2390021 timestamp: 1731375651179 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h4ce23a2_1.conda + sha256: 18a4afe14f731bfb9cf388659994263904d20111e42f841e9eea1bb6f91f4ab4 + md5: e796ff8ddc598affdf7c173d6145f087 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: LGPL-2.1-only + size: 713084 + timestamp: 1740128065462 - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-h135ad9c_1.conda sha256: ea5ed2b362b6dbc4ba7188eb4eaf576146e3dfc6f4395e9f0db76ad77465f786 md5: 21fc5dba2cbcd8e5e26ff976a312122c @@ -2144,6 +3171,14 @@ packages: license: LGPL-2.1-only size: 638142 timestamp: 1740128665984 +- conda: https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_3.conda + sha256: c7e4600f28bcada8ea81456a6530c2329312519efcf0c886030ada38976b0511 + md5: 2cf0cf76cc15d360dfa2f17fd6cf9772 + depends: + - libiconv >=1.17,<2.0a0 + license: LGPL-2.1-or-later + size: 95568 + timestamp: 1723629479451 - conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.0-hb9d3cd8_0.conda sha256: 98b399287e27768bf79d48faba8a99a2289748c65cd342ca21033fab1860d4a4 md5: 9fa334557db9f63da6c9285fd2a48638 @@ -2212,6 +3247,20 @@ packages: license_family: BSD size: 3944766 timestamp: 1740088686444 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.6-he9d0ab4_0.conda + sha256: 1f446c261c98794c4f4430513065637dfaaacaf00b6d5d41b3f90e9d9f8cb631 + md5: bf8ccdd2c1c1a54a3fa25bb61f26460e + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libstdcxx >=13 + - libxml2 >=2.13.8,<2.14.0a0 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 43023023 + timestamp: 1748507316454 - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_0.conda sha256: f4f21dfc54b08d462f707b771ecce3fa9bc702a2a05b55654f64154f48b141ef md5: 0e87378639676987af32fee53ba32258 @@ -2277,6 +3326,15 @@ packages: license_family: GPL size: 33408 timestamp: 1697359010159 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda + sha256: 3b3f19ced060013c2dd99d9d46403be6d319d4601814c772a3472fe2955612b0 + md5: 7c7927b404672409d9917d49bff5f2d6 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: LGPL-2.1-or-later + size: 33418 + timestamp: 1734670021371 - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.29-pthreads_h94d23a6_0.conda sha256: cc5389ea254f111ef17a53df75e8e5209ef2ea6117e3f8aced88b5a8e51f11c4 md5: 0a4d0252248ef9a0f88f2ba8b8a08e12 @@ -2304,6 +3362,24 @@ packages: license_family: BSD size: 3938876 timestamp: 1739829020535 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda + sha256: 215086c108d80349e96051ad14131b751d17af3ed2cb5a34edd62fa89bfe8ead + md5: 7df50d44d4a14d6c31a2c54f2cd92157 + depends: + - __glibc >=2.17,<3.0.a0 + - libglvnd 1.7.0 ha4b6fd6_2 + license: LicenseRef-libglvnd + size: 50757 + timestamp: 1731330993524 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hd590300_0.conda + sha256: c0a30ac74eba66ea76a4f0a39acc7833f5ed783a632ca3bb6665b2d81aabd2fb + md5: 48f4330bfcd959c3cfb704d424903c82 + depends: + - libgcc-ng >=12 + license: MIT + license_family: MIT + size: 28361 + timestamp: 1707101388552 - conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.47-h943b412_0.conda sha256: 23367d71da58c9a61c8cbd963fcffb92768d4ae5ffbef9a47cdf1f54f98c5c36 md5: 55199e2ae2c3651f6f9b2a447b47bdc9 @@ -2314,6 +3390,17 @@ packages: license: zlib-acknowledgement size: 288701 timestamp: 1739952993639 +- conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.47-h7a4582a_0.conda + sha256: e12c46ca882080d901392ae45e0e5a1c96fc3e5acd5cd1a23c2632eb7f024f26 + md5: ad620e92b82d2948bc019e029c574ebb + depends: + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: zlib-acknowledgement + size: 346511 + timestamp: 1745771984515 - conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.47-had7236b_0.conda sha256: cf8a594b697de103025dcae2c917ec9c100609caf7c917a94c64a683cb1db1ac md5: 7d717163d9dab337c65f2bf21a676b8f @@ -2325,6 +3412,19 @@ packages: license: zlib-acknowledgement size: 346101 timestamp: 1739953426806 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libpq-17.5-h27ae623_0.conda + sha256: 2dbcef0db82e0e7b6895b6c0dadd3d36c607044c40290c7ca10656f3fca3166f + md5: 6458be24f09e1b034902ab44fe9de908 + depends: + - __glibc >=2.17,<3.0.a0 + - icu >=75.1,<76.0a0 + - krb5 >=1.21.3,<1.22.0a0 + - libgcc >=13 + - openldap >=2.6.9,<2.7.0a0 + - openssl >=3.5.0,<4.0a0 + license: PostgreSQL + size: 2680582 + timestamp: 1746743259857 - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.49.1-hee588c1_2.conda sha256: a086289bf75c33adc1daed3f1422024504ffb5c3c8b3285c49f025c29708ed16 md5: 962d6ac93c30b1dfc54c9cccafd1003e @@ -2406,6 +3506,39 @@ packages: license: HPND size: 429381 timestamp: 1745372713285 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hf01ce69_5.conda + sha256: 7fa6ddac72e0d803bb08e55090a8f2e71769f1eb7adbd5711bdd7789561601b1 + md5: e79a094918988bb1807462cd42c83962 + depends: + - __glibc >=2.17,<3.0.a0 + - lerc >=4.0.0,<5.0a0 + - libdeflate >=1.24,<1.25.0a0 + - libgcc >=13 + - libjpeg-turbo >=3.1.0,<4.0a0 + - liblzma >=5.8.1,<6.0a0 + - libstdcxx >=13 + - libwebp-base >=1.5.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: HPND + size: 429575 + timestamp: 1747067001268 +- conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.0-h05922d8_5.conda + sha256: 1bb0b2e7d076fecc2f8147336bc22e7e6f9a4e0505e0e4ab2be1f56023a4a458 + md5: 75370aba951b47ec3b5bfe689f1bcf7f + depends: + - lerc >=4.0.0,<5.0a0 + - libdeflate >=1.24,<1.25.0a0 + - libjpeg-turbo >=3.1.0,<4.0a0 + - liblzma >=5.8.1,<6.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - zstd >=1.5.7,<1.6.0a0 + license: HPND + size: 979074 + timestamp: 1747067408877 - conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.0-h797046b_4.conda sha256: 3456e2a6dfe6c00fd0cda316f0cbb47caddf77f83d3ed4040b6ad17ec1610d2a md5: 7d938ca70c64c5516767b4eae0a56172 @@ -2502,6 +3635,35 @@ packages: license: LGPL-2.1-or-later size: 100393 timestamp: 1702724383534 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.10.0-h65c71a3_0.conda + sha256: a8043a46157511b3ceb6573a99952b5c0232313283f2d6a066cec7c8dcaed7d0 + md5: fedf6bfe5d21d21d2b1785ec00a8889a + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libstdcxx >=13 + - libxcb >=1.17.0,<2.0a0 + - libxml2 >=2.13.8,<2.14.0a0 + - xkeyboard-config + - xorg-libxau >=1.0.12,<2.0a0 + license: MIT/X11 Derivative + license_family: MIT + size: 707156 + timestamp: 1747911059945 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.8-h4bc477f_0.conda + sha256: b0b3a96791fa8bb4ec030295e8c8bf2d3278f33c0f9ad540e73b5e538e6268e7 + md5: 14dbe05b929e329dbaa6f2d0aa19466d + depends: + - __glibc >=2.17,<3.0.a0 + - icu >=75.1,<76.0a0 + - libgcc >=13 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libzlib >=1.3.1,<2.0a0 + license: MIT + license_family: MIT + size: 690864 + timestamp: 1746634244154 - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.13.7-h442d1da_1.conda sha256: 0a013527f784f4702dc18460070d8ec79d1ebb5087dd9e678d6afbeaca68d2ac md5: c14ff7f05e57489df9244917d2b55763 @@ -2515,6 +3677,41 @@ packages: license_family: MIT size: 1513740 timestamp: 1743795035107 +- conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.13.8-h442d1da_0.conda + sha256: 473b8a53c8df714d676ab41711551c8d250f8d799f2db5cb7cb2b177a0ce13f6 + md5: 833c2dbc1a5020007b520b044c713ed3 + depends: + - libiconv >=1.18,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + size: 1513627 + timestamp: 1746634633560 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.39-h76b75d6_0.conda + sha256: 684e9b67ef7b9ca0ca993762eeb39705ec58e2e7f958555c758da7ef416db9f3 + md5: e71f31f8cfb0a91439f2086fc8aa0461 + depends: + - libgcc-ng >=12 + - libxml2 >=2.12.1,<2.14.0a0 + license: MIT + license_family: MIT + size: 254297 + timestamp: 1701628814990 +- conda: https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.39-h3df6e99_0.conda + sha256: 6e3d99466d2076c35e7ac8dcdfe604da3d593f55b74a5b8e96c2b2ff63c247aa + md5: 279ee338c9b34871d578cb3c7aa68f70 + depends: + - libxml2 >=2.12.1,<2.14.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + size: 418542 + timestamp: 1701629338549 - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda sha256: d4bfe88d7cb447768e31650f06257995601f89076080e76df55e3112d4e47dc4 md5: edb0dca6bc32e4f4789199455a1dbeb8 @@ -2608,22 +3805,74 @@ packages: license_family: BSD size: 27930 timestamp: 1733220059655 -- conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.1-py313h129903b_0.conda - sha256: de574f3fc34486df489f58586b90371882209225ab4d6c46fef64c7855e35196 - md5: 4e23b3fabf434b418e0d9c6975a6453f +- conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.3-py312h7900ff3_0.conda + sha256: 2255888d215fb1438b968bd7e5fd89580c25eb90f4010aad38dda8aac7b642c8 + md5: 40e02247b1467ce6fff28cad870dc833 depends: - - __glibc >=2.17,<3.0.a0 - - contourpy >=1.0.1 - - cycler >=0.10 - - fonttools >=4.22.0 - - freetype >=2.12.1,<3.0a0 - - kiwisolver >=1.3.1 - - libgcc >=13 - - libstdcxx >=13 - - numpy >=1.21,<3 - - numpy >=1.23 - - packaging >=20.0 - - pillow >=8 + - matplotlib-base >=3.10.3,<3.10.4.0a0 + - pyside6 >=6.7.2 + - python >=3.12,<3.13.0a0 + - python_abi 3.12.* *_cp312 + - tornado >=5 + license: PSF-2.0 + license_family: PSF + size: 17376 + timestamp: 1746820703075 +- conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.3-py313h78bf25f_0.conda + sha256: 384337a8553f9e5dec80e4d1c46460207d96b0e2b6e73aa1c0de04a52d90917b + md5: cc9324e614a297fdf23439d887d3513d + depends: + - matplotlib-base >=3.10.3,<3.10.4.0a0 + - pyside6 >=6.7.2 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - tornado >=5 + license: PSF-2.0 + license_family: PSF + size: 17426 + timestamp: 1746820711137 +- conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.10.3-py312h2e8e312_0.conda + sha256: 9bca2f50f6a00a9e1f6d07a7c447a02e7067ef0924bfa63da45e1362bae922b9 + md5: 914c15eac59e9bd477e94b0103e47f63 + depends: + - matplotlib-base >=3.10.3,<3.10.4.0a0 + - pyside6 >=6.7.2 + - python >=3.12,<3.13.0a0 + - python_abi 3.12.* *_cp312 + - tornado >=5 + license: PSF-2.0 + license_family: PSF + size: 17794 + timestamp: 1746821737107 +- conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.10.3-py313hfa70ccb_0.conda + sha256: 3ccae11c5e6fe5c929f92e72c2d90a85eb3f3517579beb7ca77ba6e7d14ddb48 + md5: 9b98ebdc5283235268e84abf5d76773d + depends: + - matplotlib-base >=3.10.3,<3.10.4.0a0 + - pyside6 >=6.7.2 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - tornado >=5 + license: PSF-2.0 + license_family: PSF + size: 17719 + timestamp: 1746821359509 +- conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.1-py313h129903b_0.conda + sha256: de574f3fc34486df489f58586b90371882209225ab4d6c46fef64c7855e35196 + md5: 4e23b3fabf434b418e0d9c6975a6453f + depends: + - __glibc >=2.17,<3.0.a0 + - contourpy >=1.0.1 + - cycler >=0.10 + - fonttools >=4.22.0 + - freetype >=2.12.1,<3.0a0 + - kiwisolver >=1.3.1 + - libgcc >=13 + - libstdcxx >=13 + - numpy >=1.21,<3 + - numpy >=1.23 + - packaging >=20.0 + - pillow >=8 - pyparsing >=2.3.1 - python >=3.13,<3.14.0a0 - python-dateutil >=2.7 @@ -2634,6 +3883,62 @@ packages: license_family: PSF size: 8247223 timestamp: 1740781100259 +- conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.3-py312hd3ec401_0.conda + sha256: 3b5be100ddfcd5697140dbb8d4126e3afd0147d4033defd6c6eeac78fe089bd2 + md5: 2d69618b52d70970c81cc598e4b51118 + depends: + - __glibc >=2.17,<3.0.a0 + - contourpy >=1.0.1 + - cycler >=0.10 + - fonttools >=4.22.0 + - freetype + - kiwisolver >=1.3.1 + - libfreetype >=2.13.3 + - libfreetype6 >=2.13.3 + - libgcc >=13 + - libstdcxx >=13 + - numpy >=1.19,<3 + - numpy >=1.23 + - packaging >=20.0 + - pillow >=8 + - pyparsing >=2.3.1 + - python >=3.12,<3.13.0a0 + - python-dateutil >=2.7 + - python_abi 3.12.* *_cp312 + - qhull >=2020.2,<2020.3.0a0 + - tk >=8.6.13,<8.7.0a0 + license: PSF-2.0 + license_family: PSF + size: 8188885 + timestamp: 1746820680864 +- conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.3-py313h129903b_0.conda + sha256: eb23d6945d34836b62add0ca454f287cadb74b4b771cdd7196a1f51def425014 + md5: 4f8816d006b1c155ec416bcf7ff6cee2 + depends: + - __glibc >=2.17,<3.0.a0 + - contourpy >=1.0.1 + - cycler >=0.10 + - fonttools >=4.22.0 + - freetype + - kiwisolver >=1.3.1 + - libfreetype >=2.13.3 + - libfreetype6 >=2.13.3 + - libgcc >=13 + - libstdcxx >=13 + - numpy >=1.21,<3 + - numpy >=1.23 + - packaging >=20.0 + - pillow >=8 + - pyparsing >=2.3.1 + - python >=3.13,<3.14.0a0 + - python-dateutil >=2.7 + - python_abi 3.13.* *_cp313 + - qhull >=2020.2,<2020.3.0a0 + - tk >=8.6.13,<8.7.0a0 + license: PSF-2.0 + license_family: PSF + size: 8479847 + timestamp: 1746820689093 - conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.1-py313h81b4f16_0.conda sha256: 7708dca849a2bbcba2917a2789273b5714eac9cd1ad75030389cdcdedba9ff93 md5: 3258ce4dcc660f45dfbbe27709c4d8ba @@ -2659,6 +3964,60 @@ packages: license_family: PSF size: 7936179 timestamp: 1740782043413 +- conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.3-py312h90004f6_0.conda + sha256: dd41282ac388887227a37122c8ec5822ad3121896e5b27e8360e6f2bd38b352d + md5: 8d3097febb52bfe3d0e33112c327c180 + depends: + - contourpy >=1.0.1 + - cycler >=0.10 + - fonttools >=4.22.0 + - freetype + - kiwisolver >=1.3.1 + - libfreetype >=2.13.3 + - libfreetype6 >=2.13.3 + - numpy >=1.19,<3 + - numpy >=1.23 + - packaging >=20.0 + - pillow >=8 + - pyparsing >=2.3.1 + - python >=3.12,<3.13.0a0 + - python-dateutil >=2.7 + - python_abi 3.12.* *_cp312 + - qhull >=2020.2,<2020.3.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: PSF-2.0 + license_family: PSF + size: 8035551 + timestamp: 1746821698674 +- conda: https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.3-py313h81b4f16_0.conda + sha256: 0072d66eb173b7d011864499da204daa0d413efc7b0e3e992b3c4e6239595e3a + md5: 26fe68da572921413fa9200c61da844d + depends: + - contourpy >=1.0.1 + - cycler >=0.10 + - fonttools >=4.22.0 + - freetype + - kiwisolver >=1.3.1 + - libfreetype >=2.13.3 + - libfreetype6 >=2.13.3 + - numpy >=1.21,<3 + - numpy >=1.23 + - packaging >=20.0 + - pillow >=8 + - pyparsing >=2.3.1 + - python >=3.13,<3.14.0a0 + - python-dateutil >=2.7 + - python_abi 3.13.* *_cp313 + - qhull >=2020.2,<2020.3.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: PSF-2.0 + license_family: PSF + size: 8043799 + timestamp: 1746821318371 - conda: https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.4.2-pyhd8ed1ab_1.conda sha256: c63ed79d9745109c0a70397713b0c07f06e7d3561abcb122cfc80a141ab3b449 md5: af2060041d4f3250a7eb6ab3ec0e549b @@ -2764,6 +4123,24 @@ packages: license: BSD-3-Clause size: 8528362 timestamp: 1745119324280 +- conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.6-py313h17eae1a_0.conda + sha256: 7da9ebd80a7311e0482c4c6393be0eddf0012b3846df528e375037409b3d2b3d + md5: 7a2d2f9adecd86ed5c29c2115354f615 + depends: + - __glibc >=2.17,<3.0.a0 + - libblas >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + - libgcc >=13 + - liblapack >=3.9.0,<4.0a0 + - libstdcxx >=13 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + constrains: + - numpy-base <0a0 + license: BSD-3-Clause + license_family: BSD + size: 8517250 + timestamp: 1747545080496 - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.2.5-py312h3150e54_0.conda sha256: c497607b3e7e0946b8a2566b6587152c7cb376625559addbf606494f5bbe41dd md5: 00c3b00c9091b7f76faba85795350c7e @@ -2798,6 +4175,24 @@ packages: license: BSD-3-Clause size: 7108203 timestamp: 1745120126721 +- conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.2.6-py313hefb8edb_0.conda + sha256: ee193d2cfbf6bc06fb99312ee2555c40b68402cae44cf101f452acb2f1490f98 + md5: ae9a9741b830bbb42f22f80ef4e6a074 + depends: + - libblas >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + - liblapack >=3.9.0,<4.0a0 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + constrains: + - numpy-base <0a0 + license: BSD-3-Clause + license_family: BSD + size: 7097859 + timestamp: 1747545350386 - conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h5fbd93e_0.conda sha256: 5bee706ea5ba453ed7fd9da7da8380dd88b865c8d30b5aaec14d2b6dd32dbc39 md5: 9e5816bc95d285c115a3ebc2f8563564 @@ -2826,6 +4221,20 @@ packages: license_family: BSD size: 240148 timestamp: 1733817010335 +- conda: https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda + sha256: cb0b07db15e303e6f0a19646807715d28f1264c6350309a559702f4f34f37892 + md5: 2e5bf4f1da39c0b32778561c3c4e5878 + depends: + - __glibc >=2.17,<3.0.a0 + - cyrus-sasl >=2.1.27,<3.0a0 + - krb5 >=1.21.3,<1.22.0a0 + - libgcc >=13 + - libstdcxx >=13 + - openssl >=3.5.0,<4.0a0 + license: OLDAP-2.8 + license_family: BSD + size: 780253 + timestamp: 1748010165522 - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.0-h7b32b05_0.conda sha256: 38285d280f84f1755b7c54baf17eccf2e3e696287954ce0adca16546b85ee62c md5: bb539841f2a3fde210f387d00ed4bb9d @@ -2859,6 +4268,239 @@ packages: license_family: APACHE size: 62477 timestamp: 1745345660407 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.0-py312hf9745cd_0.conda + sha256: 44f5587c1e1a9f0257387dd18735bcf65a67a6089e723302dc7947be09d9affe + md5: ac82ac336dbe61106e21fb2e11704459 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libstdcxx >=13 + - numpy >=1.19,<3 + - numpy >=1.22.4 + - python >=3.12,<3.13.0a0 + - python-dateutil >=2.8.2 + - python-tzdata >=2022.7 + - python_abi 3.12.* *_cp312 + - pytz >=2020.1 + constrains: + - bottleneck >=1.3.6 + - blosc >=1.21.3 + - numba >=0.56.4 + - pyqt5 >=5.15.9 + - pyarrow >=10.0.1 + - gcsfs >=2022.11.0 + - xlsxwriter >=3.0.5 + - scipy >=1.10.0 + - beautifulsoup4 >=4.11.2 + - numexpr >=2.8.4 + - fastparquet >=2022.12.0 + - lxml >=4.9.2 + - xlrd >=2.0.1 + - openpyxl >=3.1.0 + - qtpy >=2.3.0 + - s3fs >=2022.11.0 + - pandas-gbq >=0.19.0 + - pytables >=3.8.0 + - python-calamine >=0.1.7 + - fsspec >=2022.11.0 + - psycopg2 >=2.9.6 + - xarray >=2022.12.0 + - matplotlib >=3.6.3 + - pyxlsb >=1.0.10 + - tabulate >=0.9.0 + - odfpy >=1.4.1 + - pyreadstat >=1.2.0 + - html5lib >=1.1 + - zstandard >=0.19.0 + - sqlalchemy >=2.0.0 + - tzdata >=2022.7 + arch: x86_64 + platform: linux + license: BSD-3-Clause + license_family: BSD + size: 14958450 + timestamp: 1749100123120 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.0-py313ha87cce1_0.conda + sha256: c4a6e9bc13454c5afd17600c2ee2b6b07fee8b2629cb1c193c22c048faa9bdcc + md5: 8664b4fa9b5b23b0d1cdc55c7195fcfe + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libstdcxx >=13 + - numpy >=1.21,<3 + - numpy >=1.22.4 + - python >=3.13,<3.14.0a0 + - python-dateutil >=2.8.2 + - python-tzdata >=2022.7 + - python_abi 3.13.* *_cp313 + - pytz >=2020.1 + constrains: + - zstandard >=0.19.0 + - sqlalchemy >=2.0.0 + - pyqt5 >=5.15.9 + - pyxlsb >=1.0.10 + - qtpy >=2.3.0 + - odfpy >=1.4.1 + - python-calamine >=0.1.7 + - pytables >=3.8.0 + - numexpr >=2.8.4 + - s3fs >=2022.11.0 + - html5lib >=1.1 + - pyarrow >=10.0.1 + - xarray >=2022.12.0 + - lxml >=4.9.2 + - openpyxl >=3.1.0 + - fastparquet >=2022.12.0 + - fsspec >=2022.11.0 + - matplotlib >=3.6.3 + - scipy >=1.10.0 + - pandas-gbq >=0.19.0 + - xlsxwriter >=3.0.5 + - blosc >=1.21.3 + - xlrd >=2.0.1 + - bottleneck >=1.3.6 + - numba >=0.56.4 + - beautifulsoup4 >=4.11.2 + - pyreadstat >=1.2.0 + - tabulate >=0.9.0 + - tzdata >=2022.7 + - gcsfs >=2022.11.0 + - psycopg2 >=2.9.6 + arch: x86_64 + platform: linux + license: BSD-3-Clause + license_family: BSD + size: 14991000 + timestamp: 1749100101435 +- conda: https://conda.anaconda.org/conda-forge/win-64/pandas-2.3.0-py312h72972c8_0.conda + sha256: e4c8a685cfa1334a566b642523c9584d79ba78ed05888c7b7809d9116b6e9e25 + md5: e2ab2d8cc52281c9ebe19451936802eb + depends: + - numpy >=1.19,<3 + - numpy >=1.22.4 + - python >=3.12,<3.13.0a0 + - python-dateutil >=2.8.2 + - python-tzdata >=2022.7 + - python_abi 3.12.* *_cp312 + - pytz >=2020.1 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + constrains: + - pyarrow >=10.0.1 + - gcsfs >=2022.11.0 + - fsspec >=2022.11.0 + - lxml >=4.9.2 + - tabulate >=0.9.0 + - openpyxl >=3.1.0 + - pyreadstat >=1.2.0 + - xlrd >=2.0.1 + - pyqt5 >=5.15.9 + - pyxlsb >=1.0.10 + - s3fs >=2022.11.0 + - zstandard >=0.19.0 + - numexpr >=2.8.4 + - python-calamine >=0.1.7 + - beautifulsoup4 >=4.11.2 + - fastparquet >=2022.12.0 + - bottleneck >=1.3.6 + - xarray >=2022.12.0 + - xlsxwriter >=3.0.5 + - sqlalchemy >=2.0.0 + - psycopg2 >=2.9.6 + - matplotlib >=3.6.3 + - blosc >=1.21.3 + - pytables >=3.8.0 + - html5lib >=1.1 + - numba >=0.56.4 + - tzdata >=2022.7 + - pandas-gbq >=0.19.0 + - qtpy >=2.3.0 + - scipy >=1.10.0 + - odfpy >=1.4.1 + arch: x86_64 + platform: win + license: BSD-3-Clause + license_family: BSD + size: 13859642 + timestamp: 1749100498003 +- conda: https://conda.anaconda.org/conda-forge/win-64/pandas-2.3.0-py313hf91d08e_0.conda + sha256: 2dac0e788df070dfb12e7f3630386973b0bb9730d04b7f774c519e3f3f1db21f + md5: 06f537fc2102679d5c1567cf2d38391d + depends: + - numpy >=1.21,<3 + - numpy >=1.22.4 + - python >=3.13,<3.14.0a0 + - python-dateutil >=2.8.2 + - python-tzdata >=2022.7 + - python_abi 3.13.* *_cp313 + - pytz >=2020.1 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + constrains: + - pytables >=3.8.0 + - scipy >=1.10.0 + - xlsxwriter >=3.0.5 + - sqlalchemy >=2.0.0 + - tzdata >=2022.7 + - python-calamine >=0.1.7 + - pyqt5 >=5.15.9 + - s3fs >=2022.11.0 + - zstandard >=0.19.0 + - qtpy >=2.3.0 + - matplotlib >=3.6.3 + - xlrd >=2.0.1 + - odfpy >=1.4.1 + - pyxlsb >=1.0.10 + - pandas-gbq >=0.19.0 + - fastparquet >=2022.12.0 + - openpyxl >=3.1.0 + - tabulate >=0.9.0 + - gcsfs >=2022.11.0 + - bottleneck >=1.3.6 + - numexpr >=2.8.4 + - pyarrow >=10.0.1 + - beautifulsoup4 >=4.11.2 + - pyreadstat >=1.2.0 + - lxml >=4.9.2 + - xarray >=2022.12.0 + - html5lib >=1.1 + - numba >=0.56.4 + - fsspec >=2022.11.0 + - psycopg2 >=2.9.6 + - blosc >=1.21.3 + arch: x86_64 + platform: win + license: BSD-3-Clause + license_family: BSD + size: 13929307 + timestamp: 1749100343118 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.44-hc749103_2.conda + sha256: 09717569649d89caafbf32f6cda1e65aef86e5a86c053d30e4ce77fca8d27b68 + md5: 31614c73d7b103ef76faa4d83d261d34 + depends: + - __glibc >=2.17,<3.0.a0 + - bzip2 >=1.0.8,<2.0a0 + - libgcc >=13 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + size: 956207 + timestamp: 1745931215744 +- conda: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.44-h99c9b8b_2.conda + sha256: 15dffc9a2d6bb6b8ccaa7cbd26b229d24f1a0a1c4f5685b308a63929c56b381f + md5: a912b2c4ff0f03101c751aa79a331831 + depends: + - bzip2 >=1.0.8,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-3-Clause + license_family: BSD + size: 816653 + timestamp: 1745931851696 - conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-11.1.0-py312h80c1187_0.conda sha256: 5c347962202b55ae4d8a463e0555c5c6ca33396266a08284bf1384399894e541 md5: d3894405f05b2c0f351d5de3ae26fa9c @@ -2899,6 +4541,48 @@ packages: license: HPND size: 41774632 timestamp: 1735929847800 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-11.2.1-py312h80c1187_0.conda + sha256: 15f32ec89f3a7104fcb190546a2bc0fc279372d9073e5ec08a8d61a1c79af4c0 + md5: ca438bf57e4f2423d261987fe423a0dd + depends: + - __glibc >=2.17,<3.0.a0 + - lcms2 >=2.17,<3.0a0 + - libfreetype >=2.13.3 + - libfreetype6 >=2.13.3 + - libgcc >=13 + - libjpeg-turbo >=3.1.0,<4.0a0 + - libtiff >=4.7.0,<4.8.0a0 + - libwebp-base >=1.5.0,<2.0a0 + - libxcb >=1.17.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - openjpeg >=2.5.3,<3.0a0 + - python >=3.12,<3.13.0a0 + - python_abi 3.12.* *_cp312 + - tk >=8.6.13,<8.7.0a0 + license: HPND + size: 42506161 + timestamp: 1746646366556 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-11.2.1-py313h8db990d_0.conda + sha256: f35e9bef2dd00361b871deb015cd50c3ff2847b957af16ab98651443eab1010c + md5: 91b00afee98d72d29dc3d1c1ab0008d7 + depends: + - __glibc >=2.17,<3.0.a0 + - lcms2 >=2.17,<3.0a0 + - libfreetype >=2.13.3 + - libfreetype6 >=2.13.3 + - libgcc >=13 + - libjpeg-turbo >=3.1.0,<4.0a0 + - libtiff >=4.7.0,<4.8.0a0 + - libwebp-base >=1.5.0,<2.0a0 + - libxcb >=1.17.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - openjpeg >=2.5.3,<3.0a0 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - tk >=8.6.13,<8.7.0a0 + license: HPND + size: 42836283 + timestamp: 1746646372487 - conda: https://conda.anaconda.org/conda-forge/win-64/pillow-11.1.0-py312h078707f_0.conda sha256: 1047f68dce73ae88369ee323b64b9a67c28f4fb3d15215344eb478a1454438bb md5: e609a6cb41a83f7b67c326e51f008a79 @@ -2941,6 +4625,72 @@ packages: license: HPND size: 41811177 timestamp: 1735930330180 +- conda: https://conda.anaconda.org/conda-forge/win-64/pillow-11.2.1-py312h078707f_0.conda + sha256: e2e06c41da68943242c0c7181400781890fbc92fe0705ba312592b8cb1489c65 + md5: 08d84254d64ef99ca6b718e6dae1c25d + depends: + - lcms2 >=2.17,<3.0a0 + - libfreetype >=2.13.3 + - libfreetype6 >=2.13.3 + - libjpeg-turbo >=3.1.0,<4.0a0 + - libtiff >=4.7.0,<4.8.0a0 + - libwebp-base >=1.5.0,<2.0a0 + - libxcb >=1.17.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - openjpeg >=2.5.3,<3.0a0 + - python >=3.12,<3.13.0a0 + - python_abi 3.12.* *_cp312 + - tk >=8.6.13,<8.7.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: HPND + size: 42728944 + timestamp: 1746646804195 +- conda: https://conda.anaconda.org/conda-forge/win-64/pillow-11.2.1-py313hda88b71_0.conda + sha256: b5b0074dae2c2064e124c94cfea0029dd04122a7bb90552e739900867061eb31 + md5: 04f15a89396af43b697fd583fe37863a + depends: + - lcms2 >=2.17,<3.0a0 + - libfreetype >=2.13.3 + - libfreetype6 >=2.13.3 + - libjpeg-turbo >=3.1.0,<4.0a0 + - libtiff >=4.7.0,<4.8.0a0 + - libwebp-base >=1.5.0,<2.0a0 + - libxcb >=1.17.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - openjpeg >=2.5.3,<3.0a0 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - tk >=8.6.13,<8.7.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: HPND + size: 41899294 + timestamp: 1746646850330 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.0-h29eaf8c_0.conda + sha256: 1330c3fd424fa2deec6a30678f235049c0ed1b0fad8d2d81ef995c9322d5e49a + md5: d2f1c87d4416d1e7344cf92b1aaee1c4 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libstdcxx >=13 + license: MIT + license_family: MIT + size: 398664 + timestamp: 1746011575217 +- conda: https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.0-had0cd8c_0.conda + sha256: d41f4d9faf6aefa138c609b64fe2a22cf252d88e8c393b25847e909d02870491 + md5: 01617534ef71b5385ebba940a6d6150d + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + size: 472718 + timestamp: 1746016414502 - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_1.conda sha256: 122433fc5318816b8c69283aaf267c73d87aa2d09ce39f64c9805c9a3b264819 md5: e9dcbce5f45f9ee500e728ae58b605b6 @@ -3121,6 +4871,84 @@ packages: license_family: MIT size: 95988 timestamp: 1743089832359 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.0-py312h91f0f75_0.conda + sha256: 4db931dccd8347140e79236378096d9a1b97b98bbd206d54cebd42491ad12535 + md5: e3a335c7530a1d0c4db621914f00f9f7 + depends: + - __glibc >=2.17,<3.0.a0 + - libclang13 >=20.1.2 + - libegl >=1.7.0,<2.0a0 + - libgcc >=13 + - libgl >=1.7.0,<2.0a0 + - libopengl >=1.7.0,<2.0a0 + - libstdcxx >=13 + - libxml2 >=2.13.7,<2.14.0a0 + - libxslt >=1.1.39,<2.0a0 + - python >=3.12,<3.13.0a0 + - python_abi 3.12.* *_cp312 + - qt6-main 6.9.0.* + - qt6-main >=6.9.0,<6.10.0a0 + license: LGPL-3.0-only + license_family: LGPL + size: 10119296 + timestamp: 1743760712824 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.0-py313h5f61773_0.conda + sha256: bd452d15edc3999aa33de9b408be51454950dd47eb4f5635dbde7a6f329276ed + md5: f51f25ec8fcbf777f8b186bb5deeed40 + depends: + - __glibc >=2.17,<3.0.a0 + - libclang13 >=20.1.2 + - libegl >=1.7.0,<2.0a0 + - libgcc >=13 + - libgl >=1.7.0,<2.0a0 + - libopengl >=1.7.0,<2.0a0 + - libstdcxx >=13 + - libxml2 >=2.13.7,<2.14.0a0 + - libxslt >=1.1.39,<2.0a0 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - qt6-main 6.9.0.* + - qt6-main >=6.9.0,<6.10.0a0 + license: LGPL-3.0-only + license_family: LGPL + size: 10148785 + timestamp: 1743760705831 +- conda: https://conda.anaconda.org/conda-forge/win-64/pyside6-6.9.0-py312h520aab8_0.conda + sha256: 808204eb911e20f4e58b0b6a90e424410a66668a57c08e2e6466b23137cb4f90 + md5: 52a05ba3f802633cb2234bb3edc45888 + depends: + - libclang13 >=20.1.2 + - libxml2 >=2.13.7,<2.14.0a0 + - libxslt >=1.1.39,<2.0a0 + - python >=3.12,<3.13.0a0 + - python_abi 3.12.* *_cp312 + - qt6-main 6.9.0.* + - qt6-main >=6.9.0,<6.10.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.42.34438 + license: LGPL-3.0-only + license_family: LGPL + size: 8918147 + timestamp: 1743761403797 +- conda: https://conda.anaconda.org/conda-forge/win-64/pyside6-6.9.0-py313hb43cee3_0.conda + sha256: c931b0fe146c724159129bdecef994df28bd154b0b90316fcc8c01c64a7c6e52 + md5: 198016daffa07c9844fc9598cf08db9f + depends: + - libclang13 >=20.1.2 + - libxml2 >=2.13.7,<2.14.0a0 + - libxslt >=1.1.39,<2.0a0 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - qt6-main 6.9.0.* + - qt6-main >=6.9.0,<6.10.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.42.34438 + license: LGPL-3.0-only + license_family: LGPL + size: 8901835 + timestamp: 1743761158270 - conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyh09c184e_7.conda sha256: d016e04b0e12063fbee4a2d5fbb9b39a8d191b5a0042f0b8459188aedeabb0ca md5: e2fd202833c4a981ce8a65974fe4abd1 @@ -3298,6 +5126,15 @@ packages: license_family: MIT size: 14824 timestamp: 1705448707407 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda + sha256: e8392a8044d56ad017c08fec2b0eb10ae3d1235ac967d0aab8bd7b41c4a5eaf0 + md5: 88476ae6ebd24f39261e0854ac244f33 + depends: + - python >=3.9 + license: Apache-2.0 + license_family: APACHE + size: 144160 + timestamp: 1742745254292 - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.12-7_cp312.conda build_number: 7 sha256: a1bbced35e0df66cc713105344263570e835625c28d1bdee8f748f482b2d7793 @@ -3387,6 +5224,95 @@ packages: license: LicenseRef-Qhull size: 1377020 timestamp: 1720814433486 +- conda: https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.0-h8d00660_2.conda + sha256: d52a7d4a26f5cb3d335067a1d4140f7f2b0b53ad8d78b2c766e88906863c33aa + md5: ac0eb548e24a2cb3c2c8ba060aef7db2 + depends: + - __glibc >=2.17,<3.0.a0 + - alsa-lib >=1.2.14,<1.3.0a0 + - dbus >=1.13.6,<2.0a0 + - double-conversion >=3.3.1,<3.4.0a0 + - fontconfig >=2.15.0,<3.0a0 + - fonts-conda-ecosystem + - harfbuzz >=11.0.1 + - icu >=75.1,<76.0a0 + - krb5 >=1.21.3,<1.22.0a0 + - libclang-cpp20.1 >=20.1.4,<20.2.0a0 + - libclang13 >=20.1.4 + - libcups >=2.3.3,<2.4.0a0 + - libdrm >=2.4.124,<2.5.0a0 + - libegl >=1.7.0,<2.0a0 + - libfreetype >=2.13.3 + - libfreetype6 >=2.13.3 + - libgcc >=13 + - libgl >=1.7.0,<2.0a0 + - libglib >=2.84.1,<3.0a0 + - libjpeg-turbo >=3.1.0,<4.0a0 + - libllvm20 >=20.1.4,<20.2.0a0 + - libpng >=1.6.47,<1.7.0a0 + - libpq >=17.4,<18.0a0 + - libsqlite >=3.49.1,<4.0a0 + - libstdcxx >=13 + - libtiff >=4.7.0,<4.8.0a0 + - libwebp-base >=1.5.0,<2.0a0 + - libxcb >=1.17.0,<2.0a0 + - libxkbcommon >=1.9.2,<2.0a0 + - libxml2 >=2.13.7,<2.14.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.0,<4.0a0 + - pcre2 >=10.44,<10.45.0a0 + - wayland >=1.23.1,<2.0a0 + - xcb-util >=0.4.1,<0.5.0a0 + - xcb-util-cursor >=0.1.5,<0.2.0a0 + - xcb-util-image >=0.4.0,<0.5.0a0 + - xcb-util-keysyms >=0.4.1,<0.5.0a0 + - xcb-util-renderutil >=0.3.10,<0.4.0a0 + - xcb-util-wm >=0.4.2,<0.5.0a0 + - xorg-libice >=1.1.2,<2.0a0 + - xorg-libsm >=1.2.6,<2.0a0 + - xorg-libx11 >=1.8.12,<2.0a0 + - xorg-libxcomposite >=0.4.6,<1.0a0 + - xorg-libxcursor >=1.2.3,<2.0a0 + - xorg-libxdamage >=1.1.6,<2.0a0 + - xorg-libxext >=1.3.6,<2.0a0 + - xorg-libxrandr >=1.5.4,<2.0a0 + - xorg-libxtst >=1.2.5,<2.0a0 + - xorg-libxxf86vm >=1.1.6,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + constrains: + - qt 6.9.0 + license: LGPL-3.0-only + license_family: LGPL + size: 51745422 + timestamp: 1746636875150 +- conda: https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.9.0-h1ab902a_2.conda + sha256: 16ec8355befadfbd5799a05db2b1879c6c28ded890adb5659b32aae082d41ada + md5: 99a8af7791ea42b4994cea09dd858ca8 + depends: + - double-conversion >=3.3.1,<3.4.0a0 + - harfbuzz >=11.0.1 + - icu >=75.1,<76.0a0 + - krb5 >=1.21.3,<1.22.0a0 + - libclang13 >=20.1.4 + - libglib >=2.84.1,<3.0a0 + - libjpeg-turbo >=3.1.0,<4.0a0 + - libpng >=1.6.47,<1.7.0a0 + - libsqlite >=3.49.1,<4.0a0 + - libtiff >=4.7.0,<4.8.0a0 + - libwebp-base >=1.5.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.0,<4.0a0 + - pcre2 >=10.44,<10.45.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.42.34438 + - zstd >=1.5.7,<1.6.0a0 + constrains: + - qt 6.9.0 + license: LGPL-3.0-only + license_family: LGPL + size: 93587777 + timestamp: 1746640460607 - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda sha256: 2d6d0c026902561ed77cd646b5021aef2d4db22e57a5b0178dfc669231e06d2c md5: 283b96675859b20a825f8fa30f311446 @@ -3748,6 +5674,56 @@ packages: license_family: MIT size: 19167 timestamp: 1733256819729 +- conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.1-py312h66e93f0_0.conda + sha256: c96be4c8bca2431d7ad7379bad94ed6d4d25cd725ae345540a531d9e26e148c9 + md5: c532a6ee766bed75c4fa0c39e959d132 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - python >=3.12,<3.13.0a0 + - python_abi 3.12.* *_cp312 + license: Apache-2.0 + license_family: Apache + size: 850902 + timestamp: 1748003427956 +- conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.1-py313h536fd9c_0.conda + sha256: 282c9c3380217119c779fc4c432b0e4e1e42e9a6265bfe36b6f17f6b5d4e6614 + md5: e9434a5155db25c38ade26f71a2f5a48 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + license: Apache-2.0 + license_family: Apache + size: 873269 + timestamp: 1748003477089 +- conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.1-py312h4389bb4_0.conda + sha256: cec4ab331788122f7f01dd02f57f8e21d9ae14553dedd6389d7dfeceb3592399 + md5: 06b156bbbe1597eb5ea30b931cadaa32 + depends: + - python >=3.12,<3.13.0a0 + - python_abi 3.12.* *_cp312 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: Apache-2.0 + license_family: Apache + size: 853357 + timestamp: 1748003925528 +- conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.1-py313ha7868ed_0.conda + sha256: 4d5511a98b3450157f40479eb3d00bbf3c4741c97149e2914258f71715c5cb47 + md5: a6a7c54e5dfc3bfad645e714cc14854c + depends: + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: Apache-2.0 + license_family: Apache + size: 878044 + timestamp: 1748003914685 - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.1-pyhd8ed1ab_1.conda sha256: 11e2c85468ae9902d24a27137b6b39b4a78099806e551d390e394a8c34b48e40 md5: 9efbfdc37242619130ea42b1cc4ed861 @@ -3800,6 +5776,31 @@ packages: license: LicenseRef-MicrosoftWindowsSDK10 size: 559710 timestamp: 1728377334097 +- conda: https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-16.0.0-py312h66e93f0_0.conda + sha256: 638916105a836973593547ba5cf4891d1f2cb82d1cf14354fcef93fd5b941cdc + md5: 617f5d608ff8c28ad546e5d9671cbb95 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - python >=3.12,<3.13.0a0 + - python_abi 3.12.* *_cp312 + license: Apache-2.0 + license_family: Apache + size: 404401 + timestamp: 1736692621599 +- conda: https://conda.anaconda.org/conda-forge/win-64/unicodedata2-16.0.0-py312h4389bb4_0.conda + sha256: 0889ccb541d0b63cbf42ea5b1f1686b772e872bfcddd3a18787dc4437ebbd7c6 + md5: 3b124c38c7852704ba6a42a170c152a1 + depends: + - python >=3.12,<3.13.0a0 + - python_abi 3.12.* *_cp312 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: Apache-2.0 + license_family: Apache + size: 400974 + timestamp: 1736693037551 - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.4.0-pyhd8ed1ab_0.conda sha256: a25403b76f7f03ca1a906e1ef0f88521edded991b9897e7fed56a3e334b3db8c md5: c1e349028e0052c4eea844e94f773065 @@ -3844,6 +5845,19 @@ packages: license_family: BSD size: 17873 timestamp: 1743195097269 +- conda: https://conda.anaconda.org/conda-forge/linux-64/wayland-1.23.1-h3e06ad9_1.conda + sha256: 73d809ec8056c2f08e077f9d779d7f4e4c2b625881cad6af303c33dc1562ea01 + md5: a37843723437ba75f42c9270ffe800b1 + depends: + - __glibc >=2.17,<3.0.a0 + - libexpat >=2.7.0,<3.0a0 + - libffi >=3.4.6,<3.5.0a0 + - libgcc >=13 + - libstdcxx >=13 + license: MIT + license_family: MIT + size: 321099 + timestamp: 1745806602179 - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyh7428d3b_8.conda sha256: 93807369ab91f230cf9e6e2a237eaa812492fe00face5b38068735858fba954f md5: 46e441ba871f524e2b067929da3051c2 @@ -3853,6 +5867,115 @@ packages: license: LicenseRef-Public-Domain size: 9555 timestamp: 1733130678956 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-hb711507_2.conda + sha256: 416aa55d946ce4ab173ab338796564893a2f820e80e04e098ff00c25fb981263 + md5: 8637c3e5821654d0edf97e2b0404b443 + depends: + - libgcc-ng >=12 + - libxcb >=1.16,<2.0.0a0 + license: MIT + license_family: MIT + size: 19965 + timestamp: 1718843348208 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.5-hb9d3cd8_0.conda + sha256: c7b35db96f6e32a9e5346f97adc968ef2f33948e3d7084295baebc0e33abdd5b + md5: eb44b3b6deb1cab08d72cb61686fe64c + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libxcb >=1.13 + - libxcb >=1.16,<2.0.0a0 + - xcb-util-image >=0.4.0,<0.5.0a0 + - xcb-util-renderutil >=0.3.10,<0.4.0a0 + license: MIT + license_family: MIT + size: 20296 + timestamp: 1726125844850 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda + sha256: 94b12ff8b30260d9de4fd7a28cca12e028e572cbc504fd42aa2646ec4a5bded7 + md5: a0901183f08b6c7107aab109733a3c91 + depends: + - libgcc-ng >=12 + - libxcb >=1.16,<2.0.0a0 + - xcb-util >=0.4.1,<0.5.0a0 + license: MIT + license_family: MIT + size: 24551 + timestamp: 1718880534789 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda + sha256: 546e3ee01e95a4c884b6401284bb22da449a2f4daf508d038fdfa0712fe4cc69 + md5: ad748ccca349aec3e91743e08b5e2b50 + depends: + - libgcc-ng >=12 + - libxcb >=1.16,<2.0.0a0 + license: MIT + license_family: MIT + size: 14314 + timestamp: 1718846569232 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda + sha256: 2d401dadc43855971ce008344a4b5bd804aca9487d8ebd83328592217daca3df + md5: 0e0cbe0564d03a99afd5fd7b362feecd + depends: + - libgcc-ng >=12 + - libxcb >=1.16,<2.0.0a0 + license: MIT + license_family: MIT + size: 16978 + timestamp: 1718848865819 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda + sha256: 31d44f297ad87a1e6510895740325a635dd204556aa7e079194a0034cdd7e66a + md5: 608e0ef8256b81d04456e8d211eee3e8 + depends: + - libgcc-ng >=12 + - libxcb >=1.16,<2.0.0a0 + license: MIT + license_family: MIT + size: 51689 + timestamp: 1718844051451 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.44-hb9d3cd8_0.conda + sha256: 83ad2be5eb1d359b4cd7d7a93a6b25cdbfdce9d27b37508e2a4efe90d3a4ed80 + md5: 7c91bfc90672888259675ad2ad28af9c + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - xorg-libx11 >=1.8.12,<2.0a0 + license: MIT + license_family: MIT + size: 392870 + timestamp: 1745806998840 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda + sha256: c12396aabb21244c212e488bbdc4abcdef0b7404b15761d9329f5a4a39113c4b + md5: fb901ff28063514abb6046c9ec2c4a45 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: MIT + license_family: MIT + size: 58628 + timestamp: 1734227592886 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda + sha256: 277841c43a39f738927145930ff963c5ce4c4dacf66637a3d95d802a64173250 + md5: 1c74ff8c35dcadf952a16f752ca5aa49 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libuuid >=2.38.1,<3.0a0 + - xorg-libice >=1.1.2,<2.0a0 + license: MIT + license_family: MIT + size: 27590 + timestamp: 1741896361728 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda + sha256: 51909270b1a6c5474ed3978628b341b4d4472cd22610e5f22b506855a5e20f67 + md5: db038ce880f100acc74dba10302b5630 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libxcb >=1.17.0,<2.0a0 + license: MIT + license_family: MIT + size: 835896 + timestamp: 1741901112627 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb9d3cd8_0.conda sha256: ed10c9283974d311855ae08a16dfd7e56241fac632aec3b92e3cfe73cff31038 md5: f6ebe2cb3f82ba6c057dde5d9debe4f7 @@ -3874,6 +5997,44 @@ packages: license_family: MIT size: 108013 timestamp: 1734229474049 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda + sha256: 753f73e990c33366a91fd42cc17a3d19bb9444b9ca5ff983605fa9e953baf57f + md5: d3c295b50f092ab525ffe3c2aa4b7413 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - xorg-libx11 >=1.8.10,<2.0a0 + - xorg-libxfixes >=6.0.1,<7.0a0 + license: MIT + license_family: MIT + size: 13603 + timestamp: 1727884600744 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda + sha256: 832f538ade441b1eee863c8c91af9e69b356cd3e9e1350fff4fe36cc573fc91a + md5: 2ccd714aa2242315acaf0a67faea780b + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - xorg-libx11 >=1.8.10,<2.0a0 + - xorg-libxfixes >=6.0.1,<7.0a0 + - xorg-libxrender >=0.9.11,<0.10.0a0 + license: MIT + license_family: MIT + size: 32533 + timestamp: 1730908305254 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda + sha256: 43b9772fd6582bf401846642c4635c47a9b0e36ca08116b3ec3df36ab96e0ec0 + md5: b5fcc7172d22516e1f965490e65e33a4 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - xorg-libx11 >=1.8.10,<2.0a0 + - xorg-libxext >=1.3.6,<2.0a0 + - xorg-libxfixes >=6.0.1,<7.0a0 + license: MIT + license_family: MIT + size: 13217 + timestamp: 1727891438799 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb9d3cd8_0.conda sha256: 6b250f3e59db07c2514057944a3ea2044d6a8cdde8a47b6497c254520fade1ee md5: 8035c64cb77ed555e3f150b7b3972480 @@ -3895,6 +6056,90 @@ packages: license_family: MIT size: 69920 timestamp: 1727795651979 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.6-hb9d3cd8_0.conda + sha256: da5dc921c017c05f38a38bd75245017463104457b63a1ce633ed41f214159c14 + md5: febbab7d15033c913d53c7a2c102309d + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - xorg-libx11 >=1.8.10,<2.0a0 + license: MIT + license_family: MIT + size: 50060 + timestamp: 1727752228921 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.1-hb9d3cd8_0.conda + sha256: 2fef37e660985794617716eb915865ce157004a4d567ed35ec16514960ae9271 + md5: 4bdb303603e9821baf5fe5fdff1dc8f8 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - xorg-libx11 >=1.8.10,<2.0a0 + license: MIT + license_family: MIT + size: 19575 + timestamp: 1727794961233 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda + sha256: 1a724b47d98d7880f26da40e45f01728e7638e6ec69f35a3e11f92acd05f9e7a + md5: 17dcc85db3c7886650b8908b183d6876 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - xorg-libx11 >=1.8.10,<2.0a0 + - xorg-libxext >=1.3.6,<2.0a0 + - xorg-libxfixes >=6.0.1,<7.0a0 + license: MIT + license_family: MIT + size: 47179 + timestamp: 1727799254088 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.4-hb9d3cd8_0.conda + sha256: ac0f037e0791a620a69980914a77cb6bb40308e26db11698029d6708f5aa8e0d + md5: 2de7f99d6581a4a7adbff607b5c278ca + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - xorg-libx11 >=1.8.10,<2.0a0 + - xorg-libxext >=1.3.6,<2.0a0 + - xorg-libxrender >=0.9.11,<0.10.0a0 + license: MIT + license_family: MIT + size: 29599 + timestamp: 1727794874300 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda + sha256: 044c7b3153c224c6cedd4484dd91b389d2d7fd9c776ad0f4a34f099b3389f4a1 + md5: 96d57aba173e878a2089d5638016dc5e + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - xorg-libx11 >=1.8.10,<2.0a0 + license: MIT + license_family: MIT + size: 33005 + timestamp: 1734229037766 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda + sha256: 752fdaac5d58ed863bbf685bb6f98092fe1a488ea8ebb7ed7b606ccfce08637a + md5: 7bbe9a0cc0df0ac5f5a8ad6d6a11af2f + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - xorg-libx11 >=1.8.10,<2.0a0 + - xorg-libxext >=1.3.6,<2.0a0 + - xorg-libxi >=1.7.10,<2.0a0 + license: MIT + license_family: MIT + size: 32808 + timestamp: 1727964811275 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda + sha256: 8a4e2ee642f884e6b78c20c0892b85dd9b2a6e64a6044e903297e616be6ca35b + md5: 5efa5fa6243a622445fdfd72aee15efa + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - xorg-libx11 >=1.8.10,<2.0a0 + - xorg-libxext >=1.3.6,<2.0a0 + license: MIT + license_family: MIT + size: 17819 + timestamp: 1734214575628 - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h7f98852_2.tar.bz2 sha256: a4e34c710eeb26945bdbdaba82d3d74f60a78f54a874ec10d373811a5d217535 md5: 4cb3ad778ec2d5a7acbdf254eb1c42ae diff --git a/pixi.toml b/pixi.toml index 2aefe2c9c..e753318c6 100644 --- a/pixi.toml +++ b/pixi.toml @@ -9,6 +9,8 @@ python = ">=3.12.8,<3.14" jinja2 = ">=3.1.4" debugpy = ">=1.8.11" sphinxcontrib-video = ">=0.4.1,<0.5" +matplotlib = ">=3.10.3,<4" +pandas = ">=2.3.0,<3" [feature.anybodycon.dependencies] From cfe3480d0ddc02e00eca3067d69439841ac64178 Mon Sep 17 00:00:00 2001 From: bke Date: Mon, 18 Aug 2025 11:56:33 +0200 Subject: [PATCH 27/29] add sweep test script --- Tests/Calibration/test_lf0_sweep.py | 126 ++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 Tests/Calibration/test_lf0_sweep.py diff --git a/Tests/Calibration/test_lf0_sweep.py b/Tests/Calibration/test_lf0_sweep.py new file mode 100644 index 000000000..8e53fdc9c --- /dev/null +++ b/Tests/Calibration/test_lf0_sweep.py @@ -0,0 +1,126 @@ +from pathlib import Path +from itertools import product +from collections import ChainMap +from anypytools import AnyPyProcess, macro_commands as mc +from anypytools.abcutils import AnyPyProcessOutputList +from anypytools.tools import winepath, ON_WINDOWS +import matplotlib.pyplot as plt +from mpl_toolkits.mplot3d import Axes3D +import numpy as np +import pandas as pd + +import pytest + +MODEL_FILE = "test_calibration_lowerbody.any" +OPERATION = "Main.HumanModel.Calibration.CalibrationSequence" +AMS_VARIABLES = [ + # "Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.MaxPlantarFlexionAngle", + # "Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.MaxDorsiFlexionAngle", + # "Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.MaxEversionAngle", + # "Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.MaxInversionAngle", + # "Main.HumanModel.BodyModel.Right.Leg.Data.RangeOfMotion.Ankle.NumOfPoints", + "Main.HumanModel.Calibration.RightCal6Ankle.Ankle.Data", + "Main.HumanModel.Calibration.RightCal6Ankle.SubTalar.Data", + "Main.HumanModel.Calibration.RightCal6Ankle.MuscleArr", + "Main.HumanModel.Calibration.RightCal6Ankle.Output.Lmt" +] + +DEFINES_COMBINATIONS = product( + [ + {'BM_LEG_MODEL': 1} # _LEG_MODEL_TLEM_ + ], + [ + {'BM_CALIBRATION_TYPE': 3} # _EXPERIMENTAL_CALIBRATION_TYPE_2PAR_ + ], + [ + {'BM_LEG_MUSCLES_BOTH': 2}, # _MUSCLES_3E_HILL_ + ], + [ + {"TEST_NAME":"test_cal_joint_strength_0"}, # set to indicate running from test framework + ], +) + +DEFINES = [dict(**ChainMap(*defs)) for defs in DEFINES_COMBINATIONS] + +def make_dump_commands(variables: list[str]) -> list[mc.MacroCommand]: + return [mc.Dump(var) for var in variables] + + +@pytest.fixture(scope="module") +def model_output() -> dict: + """ run the models and provide the test output""" + + model = next(Path().rglob(MODEL_FILE)).resolve() + + if not ON_WINDOWS: + model = winepath(model, "-w") + + macros = [] + for defs in DEFINES: + macros.append( + [ + mc.Load(model, defs=defs), + mc.OperationRun(OPERATION), + *make_dump_commands(AMS_VARIABLES), + ] + ) + + app = AnyPyProcess( + num_processes=2, + anybodycon_path= pytest.anytest.ams_path + ) + + results = app.start_macro(macros) + for result, defs in zip(results, DEFINES): + if 'ERROR' in result: + pytest.fail(f"Model had erros:\n{result['ERROR']}\n, defs: {defs}") + + return results + +# def plot_lf0_sweep(muscleArr: list, lmt: list, ankleData: list, subTalarData: list) -> None: + + + +def test_lf0_sweep(model_output: AnyPyProcessOutputList) -> None: + """ + Test to check the lf0 when sweeping the posture space for joint. + """ + muscleArr = model_output["MuscleArr"].flatten().tolist() + lmt = model_output["Lmt"].squeeze() + ankleData = model_output["Ankle.Data"] + subTalarData = model_output["SubTalar.Data"] + + df = pd.DataFrame(lmt, columns=muscleArr) + df.insert(0, "Ankle (deg)", ankleData.flatten() * 180 / np.pi) + df.insert(1, "SubTalar (deg)", subTalarData.flatten() * 180 / np.pi) + df.to_csv("lf0_sweep.csv", index=False) + + +def test_plot_lf0_sweep(): + + df = pd.read_csv("lf0_sweep.csv") + x_vals = df["Ankle (deg)"] + y_vals = df["SubTalar (deg)"] + # Create a 3D plot for each column that starts with "Main" in the DataFrame + for col in df.columns[2:]: + + name = col.split('.')[-1] + # plot setup + fig = plt.figure() + ax = fig.add_subplot(111, projection='3d') + ax.set_title(f" {name} Lf0 Sweep") + plt.xlabel("Plantar Flexion(X axis)") + plt.ylabel("Inversion (Y axis)") + ax.grid(True) + z_vals = df[col] + + ax.plot(x_vals, y_vals, z_vals, 'bo') + + + fig.savefig(f"{name}_Lf0_sweep.png", dpi=300, bbox_inches='tight') + if "FlexorHall" in name: + plt.show() + else: + plt.close(fig) + + \ No newline at end of file From 548dcd047d7d6ab3c459fe67c4005860684f88f6 Mon Sep 17 00:00:00 2001 From: bke Date: Mon, 18 Aug 2025 11:58:41 +0200 Subject: [PATCH 28/29] ignore images from tests --- .gitignore | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index a0e951d64..6ebb8ffda 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,25 @@ -**.cache/*.* -*.pyc -**/Output/* -!**/Output/.gitkeep -!Application/MocapExamples/Plug-in-gait_Simple_GMFoot/Output/LowerExtremity_BareFootWalk.anyset -Docs/_build/* -Docs/auto_examples/* -Documentation/* -.pytest_cache/* -Tests/anytest-output/* -Tests/_anytest-output/* -.mypy_cache -.pytest_cache -Application/MocapExamples/Rehazenter-adult-walking-model/Output/* -*_[0-9][0-9][0-9][0-9].png -*.mp4 -*_Preview.png -*).anymcr -*).txt - -ffmpeg2pass-*.log -# pixi environments -.pixi +**.cache/*.* +*.pyc +**/Output/* +!**/Output/.gitkeep +!Application/MocapExamples/Plug-in-gait_Simple_GMFoot/Output/LowerExtremity_BareFootWalk.anyset +Docs/_build/* +Docs/auto_examples/* +Documentation/* +.pytest_cache/* +Tests/anytest-output/* +Tests/_anytest-output/* +.mypy_cache +.pytest_cache +Application/MocapExamples/Rehazenter-adult-walking-model/Output/* +*_[0-9][0-9][0-9][0-9].png +*.mp4 +*_Preview.png +*).anymcr +*).txt + +ffmpeg2pass-*.log +# pixi environments +.pixi + +Tests/Calibration/**/*.png \ No newline at end of file From abfc4dd299c169419bc90188daa90f5c745a57ac Mon Sep 17 00:00:00 2001 From: bke Date: Mon, 18 Aug 2025 12:01:50 +0200 Subject: [PATCH 29/29] fix bad merge --- .../Calibration/2ParRightCalStudies.any | 3 -- Body/AAUHuman/LegTLEM/rangeOfMotion.any | 51 +++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any b/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any index a504a39bb..3a5a05d7f 100644 --- a/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any +++ b/Body/AAUHuman/LegTLEM/Calibration/2ParRightCalStudies.any @@ -136,9 +136,6 @@ TwoParCalibrationStudy RightCal6Ankle( "AnyMuscle" ); - AnklePositions = repmat(3, flattenptr(&.RangeOfMotion.Right.Leg.Ankle.ActiveRoMFlexion)); - SubTalarPositions = flatten(transpose(reshape(repmat(3, flattenptr(&.RangeOfMotion.Right.Leg.Ankle.ActiveRoMEversion)),{3,3}))); - // AnklePositions = repmat(3, flattenptr(&.RangeOfMotion.Right.Leg.Ankle.ActiveRoMFlexion)); // SubTalarPositions = flatten(transpose(reshape(repmat(3, flattenptr(&.RangeOfMotion.Right.Leg.Ankle.ActiveRoMEversion)),{3,3}))); diff --git a/Body/AAUHuman/LegTLEM/rangeOfMotion.any b/Body/AAUHuman/LegTLEM/rangeOfMotion.any index 1168c011e..ddc5e1ddf 100644 --- a/Body/AAUHuman/LegTLEM/rangeOfMotion.any +++ b/Body/AAUHuman/LegTLEM/rangeOfMotion.any @@ -73,5 +73,56 @@ AnyFolder RangeOfMotion = { &Neutral, &MaxEversionAngle, }; + + // Square grid without center + AnyInt NumOfPoints = 10; + AnyFloat FlexionAngles = linspace(MaxPlantarFlexionAngle, MaxDorsiFlexionAngle, NumOfPoints); + AnyFloat InversionAngles = linspace(MaxInversionAngle, MaxEversionAngle, NumOfPoints); + AnyFloat v1 = flatten(transpose(repmat(1, NumOfPoints, FlexionAngles))); + AnyFloat v2 = flatten(repmat(1, NumOfPoints, InversionAngles)); + AnyFloat values = {v1, v2}; + AnyObjectPtr SweepActiveRoMFlexion = &v1; + AnyObjectPtr SweepActiveRoMEversion = &v2; + + + // circular sweep + AnyInt m = 10; + AnyInt n = 10; + AnyFloat center = zeros(2,m*m); + AnyMatrix arr0 = {flatten(arr0x'), flatten(arr0y)}; + // AnyFloat array = center + (arr0 - center) * (1/repmat(2,m,rm)); + AnyFloat rm = im / m; + AnyIntArray im = iarr(1,m); + AnyFloat arr0x = repmat(1, m, FlexionAngles) * diag(rm); + AnyFloat arr0y = diag(rm) * repmat(1, m, InversionAngles) ;//* diag(rm); + + /** + Class template to sample a circular grid of points from start -> end for a 2d space. + m is the number of samples + */ + #class_template SampleRoM( + m, + v1_start, + v1_end, + v2_start, + v2_end, + ) { + AnyFolder calculations = { + AnyFloat v1_i = linspace(.v1_start, .v1_end, .m); + AnyFloat v2_i = linspace(.v2_start, .v2_end, .m); + AnyIntArray im = iarr(1,.m); + AnyFloat rm = im / .m; + }; + AnyFloat v1Samples = flatten(repmat(1, m, calculations.v1_i) * diag(calculations.rm)); + AnyFloat v2Samples = flatten(repmat(1, m, calculations.v2_i) * diag(calculations.rm)); + }; + + SampleRoM circularSweep( + m=.m, + v1_start=.MaxPlantarFlexionAngle, + v1_end=.MaxDorsiFlexionAngle, + v2_start=.MaxInversionAngle, + v2_end=.MaxEversionAngle + )={}; }; };