Switch to side-by-side view

--- a
+++ b/Tools/AnyMocap/CreateConstraintClass.any
@@ -0,0 +1,216 @@
+#ifndef _ANYMOCAP_CREATE_CONSTRAINT_CLASS_ANY_
+#define _ANYMOCAP_CREATE_CONSTRAINT_CLASS_ANY_
+/*
+---
+group: MoCap
+topic: Parameter Identification
+descr: |
+  Collection of class templates for adding constraints between 
+  design variables in Parameter optimization studies.
+---
+
+To use these drivers import the file:
+#include "<AMMR_TOOLS>/AnyMoCap/CreateConstraintClass.any"
+
+See the individual classes for more information.
+
+*/
+
+
+
+// Add a constraint to AnyMoCap models between two design variables 
+// in the parameter identification study.
+// By default the Design variables are linked to be equal by adding a constraint 
+// `Coef1*DesVar1 - Coef2*DesVar2 = 0`
+//
+// It is also possible change the link by setting `Coef1` and `Coef2`, and the
+// `Constraint_Type` argument. 
+// 
+// :::{rubric} Example:
+// :::
+// ```{code-block} AnyScriptDoc
+//  LinkDesignVars EqualThighLength (
+//    Desvar1=RightThighLength,
+//    Desvar2=LeftThighLength,
+//  ) = {};
+//```
+// The constraint can be changed by changing the `Constraint_Type` argument.
+//
+#class_template LinkDesignVars (
+    DesVar1,
+    DesVar2,
+    Constraint_Type = EqualToZero,
+    Coef1 = 1,
+    Coef2= 1,
+    PARAMETER_OPT_STUDY = Main.Studies.ParameterIdentification
+)
+{
+    // Arguments
+    // ------------
+    // LinkDesignVars#DesVar1
+    //   The first design variable to link.
+    // LinkDesignVars#DesVar2
+    //   The second design variable to link.
+    // LinkDesignVars#Constraint_Type
+    //   The type of constraint to add between the design variables.
+    //   Possible values are: EqualToZero, LessThanZero, GreaterThanZero
+    // LinkDesignVars#Coef1
+    //   The coefficient of the first design variable in the constraint equation.
+    // LinkDesignVars#Coef2
+    //   The coefficient of the second design variable in the constraint equation.
+    // LinkDesignVars#PARAMETER_OPT_STUDY
+    //   The parameter optimization study to add the constraint to.
+
+    Main.ModelSetup.ParameterIdentification = {
+       AnyDesMeasure LinkedDesignVars_##DesVar1##_##DesVar2 = {
+           Type = Constraint_Type;
+           Val = (Coef1) *.DesVar1.Val - (Coef2)*.DesVar2.Val;
+       }; 
+    };
+    
+    PARAMETER_OPT_STUDY = {
+        AnyDesMeasure &LinkedDesignVars_##DesVar1##_##DesVar2 = Main.ModelSetup.ParameterIdentification.LinkedDesignVars_##DesVar1##_##DesVar2 ;  
+    };  
+}; 
+
+
+// Small convenience class to quickly add an `AnyDesMeasure` constraint to 
+// the `Main.ModelSetup.ParameterIdentification` folder and link it 
+// to the parameter optimization study.
+//
+// :::{rubric} Example:
+// :::
+// Here is an example of adding a constraints which forces the pelvis width
+// to follow the overall body scale.
+// 
+// :::{note} The following assumes the pelvis width is a design variable, and a model which 
+//        uses the `ScaleXYZ` scaling law. 
+// :::
+//
+// ```{code-block} AnyScriptDoc
+// CreateConstraint ScaleHeadWithBody(
+//   Constraint_Type = EqualToZero,
+// ) = 
+//{
+//   Value = Main.HumanModel.Anthropometrics.SegmentScaleFactors.BodyScale 
+//          - Main.HumanModel.Anthropometrics.SegmentScaleFactors.Pelvis.WidthScale;
+// };
+//```
+//
+#class_template CreateConstraint (
+   NAME=__NOT_DEFINED__,
+   Constraint_Type = EqualToZero, 
+   PARAMETER_OPT_STUDY = Main.Studies.ParameterIdentification)
+{
+    // Arguments
+    // CreateConstraint#Constraint_Type
+    //  The type of constraint to add between the design variables.
+    //  Possible values are: EqualToZero, LessThanZero, GreaterThanZero
+    // CreateConstraint#PARAMETER_OPT_STUDY
+    // The parameter optimization study to add the constraint to.
+
+
+    // CreateConstraint
+    /// The value used in constraint. This is usually set to some expression between 
+    /// other variables. 
+    #var AnyFloat Value;
+  
+    Main.ModelSetup.ParameterIdentification = {
+    #if NAME == __NOT_DEFINED__
+        AnyDesMeasure __NAME__##Constraint_Type =
+    #else
+        AnyDesMeasure NAME##Constraint_Type =
+    #endif
+        {
+            Type = Constraint_Type;
+            Val = ....Value;
+        };  
+  };
+  
+  PARAMETER_OPT_STUDY = {
+    #if NAME == __NOT_DEFINED__
+        AnyDesMeasure &__NAME__##Constraint_Type = Main.ModelSetup.ParameterIdentification.__NAME__##Constraint_Type ;
+    #else
+        AnyDesMeasure &NAME##Constraint_Type = Main.ModelSetup.ParameterIdentification.NAME##Constraint_Type ;  
+    #endif
+   };
+    
+}; 
+
+
+// Convenience class to quickly add an constraints to markers in a cluster.
+// The constraints ensures the markers remain in a rectangular shape.
+//
+// :::{note} Adding such a constraint is often not be necessary and may 
+//     make it more difficult for the optimizer.
+// :::
+// 
+// :::{rubric} Example:
+// :::
+//
+// ```{code-block} AnyScriptDoc
+// Create4clusterRectangleConstraint ThighClusterConstraint(
+//   marker1 = RThigh1,
+//   marker2 = RThigh2,
+//   marker3 = RThigh3,
+//   marker4 = RThigh4,
+// ) = {};
+//
+//```
+//
+#class_template Create4clusterRectangleConstraint (
+    marker1,
+    marker2,
+    marker3,
+    marker4,
+    PARAMETER_OPT_STUDY = Main.Studies.ParameterIdentification,
+){
+    // Arguments
+    // ------------
+    // Create4clusterRectangleConstraint#marker1
+    //   The first marker in the cluster.
+    // Create4clusterRectangleConstraint#marker2
+    //   The second marker in the cluster.
+    // Create4clusterRectangleConstraint#marker3
+    //   The third marker in the cluster.
+    // Create4clusterRectangleConstraint#marker4
+    //   The fourth marker in the cluster.
+    // Create4clusterRectangleConstraint#PARAMETER_OPT_STUDY
+    //   The parameter optimization study to add the constraint to.
+
+
+  PARAMETER_OPT_STUDY = {
+     // equal opposing sides in the rectangular cluster
+    AnyDesMeasure __NAME__##_SideConstraint1 = {
+         Type = EqualToZero;
+         Val = vnorm(marker1.sRelOptEdit-marker2.sRelOptEdit) - vnorm(marker3.sRelOptEdit-marker4.sRelOptEdit);
+     };
+     // equal opposing sides in the rectangular cluster
+     AnyDesMeasure __NAME__##_SideConstraint2= {
+         Type = EqualToZero;
+         Val = vnorm(marker2.sRelOptEdit-marker3.sRelOptEdit) - vnorm(marker4.sRelOptEdit-marker1.sRelOptEdit);
+     };
+     // equal diagonals in the cluster
+     AnyDesMeasure __NAME__##_DiagonalConstraint= {
+         Type = EqualToZero;
+         Val = vnorm(marker1.sRelOptEdit-marker3.sRelOptEdit) - vnorm(marker2.sRelOptEdit-marker4.sRelOptEdit);
+     };
+  };
+  
+  
+};
+
+#class_template Create4clusterParallelogramConstraint (name, marker1, marker2, marker3, marker4,
+PARAMETER_OPT_STUDY = Main.Studies.ParameterIdentification){
+  PARAMETER_OPT_STUDY = {
+     // equal opposing sides in the rectangular cluster
+    AnyDesMeasure name##_ParallelogramConstraint = {
+         Type = EqualToZero;
+         Val = vnorm(marker4.sRelOptEdit+ marker2.sRelOptEdit - marker1.sRelOptEdit - marker3.sRelOptEdit);
+     };
+  };
+  
+  
+};
+
+#endif
\ No newline at end of file