dual_quaternions
dual_quaternions copied to clipboard
is_normalized() not working
I have tested the is_normalized() function with two normalized dual quaternions, dq1 and dq2, but it only returns False. The two dual quaternions:
dq1 = DualQuaternion(-0.19846574648301676, -0.003727645110356892, 0.019714514040105935, 0.9799024390575996) + (-0.26885821157532125, 20.377681310377717, -3.2778468461642998, 0.0890116940545257)e>
dq2 = DualQuaternion(-0.19815311910261352, -0.004011949502977785, 0.019765922709431866, 0.9799635472559859) + (-0.2819718824973357, 20.36564434954993, -3.2589343810704126, 0.09209339883505874)e>
dq1 and dq2 are normalized, if we use the function below in dq1 and dq2, it returns: 'Rotation part is normalized' 'The dual part is normalized'
def is_dual_quaternion_normalized(dual_quaternion):
tolerance = 1e-15
# Check the rotation part
if abs(dual_quaternion.q_r.norm - 1) > tolerance:
print("Rotation part is not normalized")
else:
print("Rotation part is normalized")
# Check the dual part
part1 = dual_quaternion.q_r * dual_quaternion.q_d.conjugate
part2 = dual_quaternion.q_d*dual_quaternion.q_r.conjugate
if abs(sum(part1 + part2)) > tolerance:
print("Dual part is not normalized")
else:
print("Dual part is normalized")
Thanks for reporting this!
I just tested this in #10 where the is_normalized function works as follows:
return np.isclose(self.q_r.norm, 1.0) and np.isclose(self.q_r.w * self.q_d.w + np.dot(self.q_r.vector, self.q_d.vector), 0)
The function docstrings describe why this works.
Testing it on your dual quaternions:
from dual_quaternions import DualQuaternion as DQ
import numpy as np
dq1 = DQ.from_dq_array(np.array([-0.19846574648301676, -0.003727645110356892, 0.019714514040105935, 0.9799024390575996, -0.26885821157532125, 20.377681310377717, -3.2778468461642998, 0.0890116940545257]))
dq2 = DQ.from_dq_array(np.array([-0.19815311910261352, -0.004011949502977785, 0.019765922709431866, 0.9799635472559859, -0.2819718824973357, 20.36564434954993, -3.2589343810704126, 0.09209339883505874]))
print(dq1.is_normalized)
print(dq2.is_normalized)
yields
True
True
I will revisit that PR and make sure the fix gets in.
In the dual_quaternions/src/dual_quaternions/dual_quaternions.py
def is_normalized(self):
"""
Check if the dual quaternion is normalized, aka 'unit'
Since a rigid body transformation requires 6 parameters and a DQ has 8, there are two constraints
to achieve a uniq dual quaternion, from
||dq|| = 1 := sqrt(dq*dq.quaternion_conjugate()) # raise both sides to power 2 to drop sqrt
= q_r *q_r.conjugate + eps * (q_r * q_d.conjugate + q_d * q_r.conjugate)
= 1 + eps * 0
"""
return np.isclose(self.q_r.norm, 0) and \
all(np.isclose(self.q_r * self.q_d.conjugate + self.q_d * self.q_r.conjugate), [0,]*4)
Maybe the "np.isclose(self.q_r.norm, 0)" should be changed to "np.isclose(self.q_r.norm, 1)".
closed by #10