Switch to unified view

a b/Tools/AnyMocap/RotationAxisAngles.any
1
#ifndef _ANYMOCAP_ROTATION_AXIS_ANGLES_ANY_
2
#define _ANYMOCAP_ROTATION_AXIS_ANGLES_ANY_
3
/*
4
---
5
group: Utilities
6
topic: Angles
7
descr: |
8
  Class template to calculate Bryant (euler) angles for the z-y-x rotation
9
  sequence given a a rotation matrix.
10
---
11
12
To use these drivers import the file:
13
#include "<AMMR_TOOLS>/AnyMoCap/RotationAxisAngles.any"
14
15
See the individual classes for more information.
16
17
*/
18
19
20
//
21
//  Calculates the Bryant (euler) angles for the z-y-x rotation sequence given a 
22
//  rotation matrix
23
//
24
// :::{rubric} Example
25
// :::
26
// Here is an example of how to use the class.
27
//
28
// ```{code-block} AnyScriptDoc
29
//
30
//  RotAxisAnglesZYX Angles(ROT = .SomeSeg.Axes0) = {};
31
//
32
//  // Results are in radians
33
//  AnyVar zRot = Angles.zRot;
34
//  AnyVar yRot = Angles.yRot;
35
//  AnyVar xRot = Angles.xRot;
36
//
37
// ```
38
//
39
//  The class can also calculate the relative 
40
//  rotation angles between two segments. 
41
//
42
// ```{code-block} AnyScriptDoc
43
//
44
// RotAxisAnglesZYX Angles(ROT = .SomeSeg.Axes0) = {
45
//   ROT_rel = .SomeOtherSeg.Axes0;
46
// };
47
//
48
// ```
49
//
50
#class_template RotAxisAnglesZYX (ROT){
51
  // Arguments
52
  // -----------
53
  //  RotAxisAnglesZYX#ROT
54
  //   The rotation matrix to calculate the angles from
55
56
57
    // RotAxisAnglesZYX
58
    ///   A relative rotation matrix so the angles are calculated
59
    ///   between these two rotation matrices.
60
    #var AnyMat33 ROT_rel = eye(3);
61
  
62
    AnyFolder Calculations = {
63
64
  
65
      AnyMat33 Rot = .ROT_rel'*.ROT;
66
  
67
      AnyVar yRot1 = asin(-Rot[2][0]);
68
      AnyVar yRot2 = pi - yRot1;
69
      
70
      AnyVar zRot1 = atan2(Rot[1][0]/cos(yRot1), Rot[0][0]/cos(yRot1));
71
      AnyVar zRot2 = atan2(Rot[1][0]/cos(yRot2), Rot[0][0]/cos(yRot2));
72
      
73
      AnyVar xRot1 = atan2(Rot[2][1]/cos(yRot1),Rot[2][2]/cos(yRot1));
74
      AnyVar xRot2 = atan2(Rot[2][1]/cos(yRot2),Rot[2][2]/cos(yRot2));
75
      AnyVar abs1 = abs(zRot1)+abs(yRot1)+abs(zRot1);
76
      AnyVar abs2 = abs(zRot2)+abs(yRot2)+abs(zRot2);
77
    };
78
    
79
    AnyVar zRot = iffun(gtfun(Calculations.abs1,Calculations.abs2), Calculations.zRot2,Calculations.zRot1);
80
    AnyVar yRot = iffun(gtfun(Calculations.abs1,Calculations.abs2), Calculations.yRot2,Calculations.yRot1);
81
    AnyVar xRot = iffun(gtfun(Calculations.abs1,Calculations.abs2), Calculations.xRot2,Calculations.xRot1) ;
82
}; 
83
84
85
86
/* 
87
  Class to bind two segments together with drivers based on their load time positions. The
88
  driver constraint type can be controlled by the `_CTYPE` arg
89
90
  The class adds a node on Seg1 with position and velocity set to 0. This helps certain
91
  situations where gimbal lock might occur. 
92
93
  The class can also add add the forces between the segments using strong recruited
94
  actuators. (Recruited actuators are used to avoid statically indeterminate systems,
95
  which could easily occur with normal reaction forces.)
96
97
98
    DriverBasedOnLoadPos driver1(Seg1=..Mass1,Seg2=..Mass2, NodeName = Node1) ={};
99
100
101
102
*/ 
103
104
#class_template DriverBasedOnLoadPos(AnySeg &Seg1,AnySeg &Seg2, NodeName, RECRUITMENT_CONSTRAINTS = 1, _CTYPE = Soft){
105
      
106
  RotAxisAnglesZYX  RotPos (ROT=.Seg2.Axes0)= {ROT_rel=.Seg1.Axes0;};
107
108
109
  Seg1= {
110
    //        AnyDrawSeg drw2 ={};
111
    AnyRefNode NodeName ={
112
      sRel=(..Seg2.r0-.r0)*.Axes0;
113
      ARel= RotMat(..RotPos.zRot,z)*RotMat(..RotPos.yRot,y)*RotMat(..RotPos.xRot,x);
114
    };
115
  };
116
117
  AnyKinEqSimpleDriver driver ={
118
    AnyKinLinear lin ={
119
      AnyRefFrame &ref1=..Seg1.NodeName;
120
      AnyRefFrame &ref2=..Seg2;
121
    };
122
    AnyKinRotational rot ={
123
      AnyRefFrame &ref1=..Seg1.NodeName;
124
      AnyRefFrame &ref2=..Seg2;
125
      Type=RotVector;
126
    };
127
    
128
    DriverPos={0,0,0,0,0,0};
129
    DriverVel={0,0,0,0,0,0};
130
    Reaction.Type={Off,Off,Off,Off,Off,Off};
131
    CType={_CTYPE,_CTYPE,_CTYPE,_CTYPE,_CTYPE,_CTYPE};
132
  };
133
134
  #if RECRUITMENT_CONSTRAINTS
135
  AnyRecruitedActuator RecruitedReactions_1 = {
136
    AnyKinMeasure &lin=.driver.lin;
137
    AnyKinMeasure &rot=.driver.rot;
138
    Type = NonNegative;
139
    Strength = {2000,2000,2000,2000,2000,2000};
140
    SET_DEFAULT_ACTUATOR_VOLUME;
141
  };
142
  AnyRecruitedActuator RecruitedReactions_2 = {
143
    AnyKinMeasure &lin=.driver.lin;
144
    AnyKinMeasure &rot=.driver.rot;
145
    Type = NonPositive;
146
    Strength = {2000,2000,2000,2000,2000,2000};
147
    SET_DEFAULT_ACTUATOR_VOLUME;
148
  };
149
  #endif
150
};
151
152
  
153
154
#endif