Dual Quaternion¶
A dual quaternion is a pair of quaternions, one for rotation and the other for translation. It is used to represent rigid transformations in 3D space. The dual quaternion is defined as
where \(q_r\) is the real, \(q_d\) is the dual quaternion, and \(\epsilon\) is the dual unit. The dual unit \(\epsilon\) satisfies the following equation:
Conjugate & Norm¶
There's three conjugate for dual quaternion. The primary conjugate, dual conjugate, and full conjugate.
I will use the Primary conjugate most of the time, with the notation \(\bar{d}\). The dual conjugate is not used in robotics, and the full conjugate is used for the action of unit dual quaternion.
Primary Conjugate¶
The primary conjugate of a dual quaternion is defined as the conjugate of each quaternion.
The norm with the primary conjugate is defined as the square of the self with the primary conjugate.
Unit Dual Quaternion is defined using this Conjugate and Norm
Dual Conjugate¶
The dual conjugate of a dual quaternion is defined as the sign of the dual part flipped.
This conjugate has no meaning in perspective of robotics.
Full Conjugate¶
The full conjugate of a dual quaternion is defined as the conjugate of each quaternion and the sign of the dual part flipped.
This conjugate is used for action of unit dual quaternion just like SE(3) group.
Addition & Subtraction¶
Dual quaternion addition & subtraction are defined as follows:
Multiplication¶
Dual quaternion multiplication is defined as follows:
Inverse & Division¶
The inverse of a dual quaternion is defined as the conjugate of the dual quaternion divided by the norm of the dual quaternion.
Divison is defined as multiplication with the inverse.
Dual Quaternion Class¶
// initializer, (1+2i+3j+4k) + epsilon(5+6i+7j+8k)
DualQuaternion<float> dq1{Quaternion<float>{1.f, 2.f, 3.f, 4.f},
Quaternion<float>{5.f, 6.f, 7.f, 8.f}}; // Re, Du
DualQuaternion<float> dq2{{1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f}};
// type alias
DualQuaternionf dq3 = dq1;
// access
Quaternionf q_r = dq1.Re();
Quaternionf q_d = dq1.Du();
dq1.Re() = q_r;
dq1.Du() = q_d;
float r_w = dq1.rw();
float r_x = dq1.rx();
float r_y = dq1.ry();
float r_z = dq1.rz();
float d_w = dq1.dw();
float d_x = dq1.dx();
float d_y = dq1.dy();
float d_z = dq1.dz();
dq1.rw() = r_w;
dq1.rx() = r_x;
dq1.ry() = r_y;
dq1.rz() = r_z;
dq1.dw() = d_w;
dq1.dx() = d_x;
dq1.dy() = d_y;
dq1.dz() = d_z;
// cast to other object (8 x 1)
Vectorf<8> vec81 = dq1.cast2Vector();
Matrixf<8,1> mat81 = dq1.cast2Matrix();
// conjugates
DualQuaternionf dq4 = dq1.conjugatedPrimary();
DualQuaternionf dq5 = dq1.conjugatedDual();
DualQuaternionf dq6 = dq1.conjugatedFull();
// norm
DualNumberf norm = dq1.normDualNum();
DualNumberf norm2 = dq1.normDualNumSqared();
float norm3 = dq1.normScalar();
norm3 = dq1.normDualNum().norm();
// inverse
DualQuaternionf dq7 = dq1.inversed(); // using Primary conjugate and Norm
// operators
DualQuaternionf dq8 = dq1 + dq2;
DualQuaternionf dq9 = dq1 - dq2;
DualQuaternionf dq10 = dq1 * dq2; // dual quaternion multiplication
DualQuaternionf dq11 = dq1 / dq2; // dual quaternion division
// result type casting
Vectorf<8> vec81 = SquareMatrixf<8>{} * dq1; // matrix multiplication
// to multiplication matrix
SquareMatrixf<8> mat8 = dq1.toMulMatrix();