Skip to content

Commit c4249ac

Browse files
SylvainBertrandrjgriffin42
authored andcommitted
Tool to differentiate orientation
Some doc and cleanup Adding 4x4 Qdot to omega transform. work-in-progress... Initial version of 4x4 Qdot -> omega transform Add important clarifying comment.
1 parent 02d8f30 commit c4249ac

File tree

1 file changed

+84
-12
lines changed

1 file changed

+84
-12
lines changed

ihmc-robotics-toolkit/src/main/java/us/ihmc/robotics/EuclidCoreMissingTools.java

Lines changed: 84 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import static us.ihmc.euclid.geometry.tools.EuclidGeometryTools.ONE_TRILLIONTH;
55
import static us.ihmc.euclid.tools.EuclidCoreTools.normSquared;
66

7+
import org.ejml.data.DMatrixRMaj;
8+
79
import us.ihmc.commons.MathTools;
810
import us.ihmc.euclid.Axis3D;
911
import us.ihmc.euclid.geometry.tools.EuclidGeometryTools;
@@ -21,9 +23,13 @@
2123
import us.ihmc.euclid.tuple2D.Point2D;
2224
import us.ihmc.euclid.tuple2D.interfaces.Point2DBasics;
2325
import us.ihmc.euclid.tuple2D.interfaces.Point2DReadOnly;
24-
import us.ihmc.euclid.tuple2D.interfaces.Tuple2DReadOnly;
2526
import us.ihmc.euclid.tuple2D.interfaces.Vector2DReadOnly;
26-
import us.ihmc.euclid.tuple3D.interfaces.*;
27+
import us.ihmc.euclid.tuple3D.interfaces.Point3DBasics;
28+
import us.ihmc.euclid.tuple3D.interfaces.Tuple3DBasics;
29+
import us.ihmc.euclid.tuple3D.interfaces.Tuple3DReadOnly;
30+
import us.ihmc.euclid.tuple3D.interfaces.UnitVector3DReadOnly;
31+
import us.ihmc.euclid.tuple3D.interfaces.Vector3DBasics;
32+
import us.ihmc.euclid.tuple3D.interfaces.Vector3DReadOnly;
2733
import us.ihmc.euclid.tuple4D.interfaces.QuaternionBasics;
2834
import us.ihmc.euclid.tuple4D.interfaces.QuaternionReadOnly;
2935

@@ -93,7 +99,7 @@ public static void projectRotationOnAxis(QuaternionReadOnly rotation, Vector3DRe
9399
{
94100
double dotProduct = rotation.getX() * axis.getX() + rotation.getY() * axis.getY() + rotation.getZ() * axis.getZ();
95101

96-
double scale = dotProduct / axis.lengthSquared();
102+
double scale = dotProduct / axis.normSquared();
97103
double projectedX = scale * axis.getX();
98104
double projectedY = scale * axis.getY();
99105
double projectedZ = scale * axis.getZ();
@@ -1088,14 +1094,14 @@ public static boolean intersectionBetweenRay2DAndLine2D(Point2DReadOnly rayOrigi
10881094
* Just a more thorough version
10891095
*/
10901096
public static boolean intersectionBetweenRay2DAndLine2D(double rayOriginX,
1091-
double rayOriginY,
1092-
double rayDirectionX,
1093-
double rayDirectionY,
1094-
double lineOriginX,
1095-
double lineOriginY,
1096-
double lineDirectionX,
1097-
double lineDirectionY,
1098-
Point2DBasics intersectionToPack)
1097+
double rayOriginY,
1098+
double rayDirectionX,
1099+
double rayDirectionY,
1100+
double lineOriginX,
1101+
double lineOriginY,
1102+
double lineDirectionX,
1103+
double lineDirectionY,
1104+
Point2DBasics intersectionToPack)
10991105
{
11001106
double start1x = rayOriginX;
11011107
double start1y = rayOriginY;
@@ -1138,7 +1144,7 @@ private static boolean intersectionBetweenTwoLine2DsImpl(double start1x,
11381144

11391145
if (Math.abs(determinant) < epsilon)
11401146
{ // The lines are parallel
1141-
// Check if they are collinear
1147+
// Check if they are collinear
11421148
double dx = start2x - start1x;
11431149
double dy = start2y - start1y;
11441150
double cross = dx * direction1y - dy * direction1x;
@@ -1266,4 +1272,70 @@ private static boolean intersectionBetweenTwoLine2DsImpl(double start1x,
12661272

12671273
return areIntersecting;
12681274
}
1275+
1276+
/**
1277+
* Calculate the angular velocity by differentiating orientation.
1278+
*
1279+
* @param qStart the initial orientation at time t.
1280+
* @param qEnd the final orientation at time t + duration.
1281+
* @param duration the time interval between the 2 orientations.
1282+
* @param angularVelocityToPack the angular velocity.
1283+
*/
1284+
public static void differentiateOrientation(QuaternionReadOnly qStart, QuaternionReadOnly qEnd, double duration, Vector3DBasics angularVelocityToPack)
1285+
{
1286+
double q1x = qStart.getX();
1287+
double q1y = qStart.getY();
1288+
double q1z = qStart.getZ();
1289+
double q1s = qStart.getS();
1290+
1291+
double q2x = qEnd.getX();
1292+
double q2y = qEnd.getY();
1293+
double q2z = qEnd.getZ();
1294+
double q2s = qEnd.getS();
1295+
1296+
double diffx = q1s * q2x - q1x * q2s - q1y * q2z + q1z * q2y;
1297+
double diffy = q1s * q2y + q1x * q2z - q1y * q2s - q1z * q2x;
1298+
double diffz = q1s * q2z - q1x * q2y + q1y * q2x - q1z * q2s;
1299+
double diffs = q1s * q2s + q1x * q2x + q1y * q2y + q1z * q2z;
1300+
1301+
if (diffs < 0.0)
1302+
{
1303+
diffx = -diffx;
1304+
diffy = -diffy;
1305+
diffz = -diffz;
1306+
diffs = -diffs;
1307+
}
1308+
1309+
double sinHalfTheta = EuclidCoreTools.norm(diffx, diffy, diffz);
1310+
1311+
double angle;
1312+
if (EuclidCoreTools.epsilonEquals(1.0, diffs, 1.0e-12))
1313+
angle = 2.0 * sinHalfTheta / diffs;
1314+
else
1315+
angle = 2.0 * EuclidCoreTools.atan2(sinHalfTheta, diffs);
1316+
angularVelocityToPack.set(diffx, diffy, diffz);
1317+
angularVelocityToPack.scale(angle / (sinHalfTheta * duration));
1318+
}
1319+
1320+
// *** NOTE ***: The 4x4 output matrix produced by this method assumes a Quaternion component ordering of:
1321+
// Quat = [ Qs
1322+
// Qx
1323+
// Qy
1324+
// Qz ]
1325+
public static DMatrixRMaj quaternionDotToOmegaTransform(QuaternionReadOnly rotatingFrameQuaternion)
1326+
{
1327+
double qs = rotatingFrameQuaternion.getS();
1328+
double qx = rotatingFrameQuaternion.getX();
1329+
double qy = rotatingFrameQuaternion.getY();
1330+
double qz = rotatingFrameQuaternion.getZ();
1331+
1332+
DMatrixRMaj E = new DMatrixRMaj(4,4);
1333+
1334+
E.set(0,0, qs); E.set(0,1, qx); E.set(0,2, qy); E.set(0,3, qz);
1335+
E.set(1,0,-qx); E.set(1,1, qs); E.set(1,2, qz); E.set(1,3,-qy);
1336+
E.set(2,0,-qy); E.set(2,1,-qz); E.set(2,2, qs); E.set(2,3, qx);
1337+
E.set(3,0,-qz); E.set(3,1, qy); E.set(3,2,-qx); E.set(3,3, qs);
1338+
1339+
return E;
1340+
}
12691341
}

0 commit comments

Comments
 (0)