Is their a package for quaternions that works well with symbolic equations? We wrote now our own functions, but I think this should be done either in a new package, or added to one of the existing packages like Rotations.jl . Any comments?
function rotate_by_quaternion(q, v)
p = [0, v...]
return quaternion_multiply(q, quaternion_multiply(p, quaternion_conjugate(q)))[2:4]
end
function quaternion_conjugate(q)
return [q[1], -q[2], -q[3], -q[4]]
end
function quaternion_multiply(q1, q2)
w1, x1, y1, z1 = q1
w2, x2, y2, z2 = q2
w = w1*w2 - x1*x2 - y1*y2 - z1*z2
x = w1*x2 + x1*w2 + y1*z2 - z1*y2
y = w1*y2 - x1*z2 + y1*w2 + z1*x2
z = w1*z2 + x1*y2 - y1*x2 + z1*w2
return [w, x, y, z]
end
function quaternion_to_rotation_matrix(q)
w, x, y, z = q[1], q[2], q[3], q[4]
return [
1 - 2*(y*y + z*z) 2*(x*y - z*w) 2*(x*z + y*w);
2*(x*y + z*w) 1 - 2*(x*x + z*z) 2*(y*z - x*w);
2*(x*z - y*w) 2*(y*z + x*w) 1 - 2*(x*x + y*y)
]
end
function rotation_matrix_to_quaternion(R)
tr_ = tr(R)
if tr_ > 0
S = sqrt(tr_ + 1.0) * 2
w = 0.25 * S
x = (R[3,2] - R[2,3]) / S
y = (R[1,3] - R[3,1]) / S
z = (R[2,1] - R[1,2]) / S
elseif (R[1,1] > R[2,2]) && (R[1,1] > R[3,3])
S = sqrt(1.0 + R[1,1] - R[2,2] - R[3,3]) * 2
w = (R[3,2] - R[2,3]) / S
x = 0.25 * S
y = (R[1,2] + R[2,1]) / S
z = (R[1,3] + R[3,1]) / S
elseif R[2,2] > R[3,3]
S = sqrt(1.0 + R[2,2] - R[1,1] - R[3,3]) * 2
w = (R[1,3] - R[3,1]) / S
x = (R[1,2] + R[2,1]) / S
y = 0.25 * S
z = (R[2,3] + R[3,2]) / S
else
S = sqrt(1.0 + R[3,3] - R[1,1] - R[2,2]) * 2
w = (R[2,1] - R[1,2]) / S
x = (R[1,3] + R[3,1]) / S
y = (R[2,3] + R[3,2]) / S
z = 0.25 * S
end
return [w, x, y, z]
end
What would be important for us is to be able to write equations like this:
[D(Q_b_w[i]) ~ Q_vel[i] for i in 1:4]
[Q_vel[i] ~ 0.5 * sum(Ω[i, j] * Q_b_w[j] for j in 1:4) for i in 1:4]