-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathKinematicMath.cs
More file actions
149 lines (122 loc) · 6.15 KB
/
Copy pathKinematicMath.cs
File metadata and controls
149 lines (122 loc) · 6.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
using MathNet.Numerics.LinearAlgebra.Double;
namespace GFunctions.Mathnet
{
/// <summary>
/// Contains various calculation methods for kinematics
/// </summary>
public class KinematicMath
{
/// <summary>
/// Gets a rotation matrix from pitch roll yaw angles
/// </summary>
/// <param name="rotation">Pitch, roll, yaw in degrees</param>
/// <returns>Equivalent rotation matrix</returns>
public static DenseMatrix RotationMatrixFromPRY(double[] rotation)
{
if (rotation.Length != 3)
throw new ArgumentException("Cannot calculate rotation matrix. Invalid number of arguments provided in array.");
double Pitch = rotation[0] * Math.PI / 180.0;
double Roll = rotation[1] * Math.PI / 180.0;
double Yaw = rotation[2] * Math.PI / 180.0;
//Math: http://planning.cs.uiuc.edu/node102.html
//------------ Pitch Matrix -----------------------
DenseMatrix PitchMat = new DenseMatrix(3, 3);
PitchMat[0, 0] = Math.Cos(Pitch);
PitchMat[1, 0] = 0;
PitchMat[2, 0] = -1 * Math.Sin(Pitch);
PitchMat[0, 1] = 0;
PitchMat[1, 1] = 1;
PitchMat[2, 1] = 0;
PitchMat[0, 2] = Math.Sin(Pitch);
PitchMat[1, 2] = 0;
PitchMat[2, 2] = Math.Cos(Pitch);
//------------ Roll Matrix -----------------------
var RollMat = new DenseMatrix(3, 3);
RollMat[0, 0] = 1;
RollMat[1, 0] = 0;
RollMat[2, 0] = 0;
RollMat[0, 1] = 0;
RollMat[1, 1] = Math.Cos(Roll);
RollMat[2, 1] = Math.Sin(Roll);
RollMat[0, 2] = 0;
RollMat[1, 2] = -1 * Math.Sin(Roll);
RollMat[2, 2] = Math.Cos(Roll);
//------------ Yaw Matrix -----------------------
var YawMat = new DenseMatrix(3, 3);
YawMat[0, 0] = Math.Cos(Yaw);
YawMat[1, 0] = Math.Sin(Yaw);
YawMat[2, 0] = 0;
YawMat[0, 1] = -1 * Math.Sin(Yaw);
YawMat[1, 1] = Math.Cos(Yaw);
YawMat[2, 1] = 0;
YawMat[0, 2] = 0;
YawMat[1, 2] = 0;
YawMat[2, 2] = 1;
DenseMatrix output = YawMat * PitchMat * RollMat;
return output;
}
/// <summary>
/// Gets the length between two Nd vectors of the same order
/// </summary>
/// <param name="pos1">Position 1 (x,y,....)</param>
/// <param name="pos2">Position 2 (x,y,....)</param>
/// <returns>Distance between the two positions</returns>
public static double VectorLength(double[] pos1, double[] pos2)
{
double output = 0;
for (int i = 0; i < pos1.Length; i++)
{
output += (pos2[i] - pos1[i]) * (pos2[i] - pos1[i]);
}
return Math.Sqrt(output);
}
/// <summary>
/// Rotates a vector by the given pitch roll yaw angles
/// </summary>
/// <param name="vector">The vector to rotate</param>
/// <param name="rotationPRY">Pitch, roll, yaw rotation in degrees</param>
/// <returns>The rotated vector (x,y,z)</returns>
public static Vector3 RotateVector(Vector3 vector, RotationPRY rotationPRY)
{
DenseVector vectorObj = new(vector.ToArray()); // Local vector without rotation;
DenseMatrix rotation = rotationPRY.ToRotationMatrix();
DenseVector rotatedVector = rotation * vectorObj; // Apply rotation
return new(rotatedVector[0], rotatedVector[1], rotatedVector[2]);
}
/// <summary>
/// Calculates a coordinates with the applied translations and rotation
/// </summary>
/// <param name="localCoord">The local coordinate (x,y,z)</param>
/// <param name="trans1">First translation distance (x,y,z)</param>
/// <param name="trans2">Second translation distance (x,y,z)</param>
/// <param name="rotation">Pitch, roll, yaw rotation in degrees</param>
/// <returns>Transformed coordinates (x,y,z)</returns>
public static Vector3 CalcGlobalCoord(Vector3 localCoord, Vector3 trans1, Vector3 trans2, RotationPRY rotation)
{
DenseMatrix LocalCoords = localCoord.ToColumnMatrix();
DenseMatrix TranslationMat = trans1.ToColumnMatrix();
DenseMatrix StartingMat = trans2.ToColumnMatrix();
DenseMatrix GlobalCoords = (rotation.ToRotationMatrix() * LocalCoords) + TranslationMat + StartingMat;
return new(GlobalCoords[0, 0], GlobalCoords[1, 0], GlobalCoords[2, 0]);
}
/// <summary>
/// Calculates a coordinates with the applied translations and rotation
/// </summary>
/// <param name="localCoord">The local coordinate (x,y,z)</param>
/// <param name="trans1">Translation distance (x,y,z) before rotation</param>
/// <param name="trans2">Translation distance (x,y,z) after rotation</param>
/// <param name="rotation">Pitch, roll, yaw rotation in degrees</param>
/// <param name="relativeRotCenter">Coordinates of the rotation center (x,y,z) relative to the local coordinate</param>
/// <returns>Transformed coordinates (x,y,z)</returns>
public static Vector3 CalcGlobalCoord2(Vector3 localCoord, Vector3 trans1, Vector3 trans2, RotationPRY rotation, Vector3? relativeRotCenter = null)
{
// If no relative center, set the rotation center to (0, 0, 0)
DenseMatrix RotCenter = (relativeRotCenter ?? new Vector3(0, 0, 0)).ToColumnMatrix();
DenseMatrix LocalCoords = localCoord.ToColumnMatrix();
DenseMatrix TranslationMat = trans1.ToColumnMatrix();
DenseMatrix TranslationMat2 = trans2.ToColumnMatrix();
DenseMatrix GlobalCoords = (rotation.ToRotationMatrix() * (LocalCoords - RotCenter + TranslationMat)) + TranslationMat2 + RotCenter; //Rotcenter needs to be added before rotation, then removed after
return new(GlobalCoords[0, 0], GlobalCoords[1, 0], GlobalCoords[2, 0]);
}
}
}