3
$\begingroup$

I have two motion capturing sensors that are worn above and below the knee as shown in the image below:

Image showing sensor placement and coordinates

Each sensor can stream its own rotation as a body-to-world frame rotation matrix and/or body-to-world frame quaternion. Can anyone advise how I calculate the angle $\Theta$ as shown in the drawing below:

Drawing showing required angle

I think I need the relative rotation in the $y$ coordinate but I'm not sure where to start. I've tried using the relative orientation like so:

relativeOrientation = upperSensorQuaternion * inverse(lowerSensorQuaternion)

Extracting the Euler value of $y$ from the resultant quaternion seems to work when a person is standing up but not when lying down because there is additional rotation about the $x$ and $z$ as well. Could anyone advise on how to correctly calculate $\Theta$? Many thanks.

$\endgroup$
0
$\begingroup$

It seems like you want the angle between the second columns of the two body-to-world rotation matrices. The second column is the image of a unit vector in the direction of the $y$-axis. The dot product of the two columns is the cosine of the angle between the vectors (we would normally divide the dot product by the lengths of the vectors, but they are unit vectors). So you want the arccosine of the dot product of those two columns.

The only twist is that the angle you drew is the supplement the angle of rotation. With the knee extended, the rotation from one sensor's $y$-axis to the other is zero, but the $\theta$ you drew is a straight angle of 180 degrees. So just subtract the angle returned by the arccosine from 180.

| cite | improve this answer | |
$\endgroup$
  • $\begingroup$ Thanks for this. I've tried this method and it works perfectly when standing but again when lying down instead of theta being roughly 90 degrees it comes out at about 67 degrees. The Javascript code I'm using is in the following Gist: gist.github.com/chrisdukey/73ca8211c33f305981cd7000a6b2c62d $\endgroup$ – apeman Mar 15 '17 at 17:20
  • $\begingroup$ Forgot to say I'm using the Threejs library: threejs.org/docs/index.html#Manual/Introduction/… Have to head off now but will be back later and will translate what I'm doing in javascript into mathematical language as best I can $\endgroup$ – apeman Mar 15 '17 at 17:21
0
$\begingroup$

You started out well: $$ Q_\mathrm{hinge} = Q_\mathrm{upper} Q_\mathrm{lower}^{-1}. $$

This is because if you hold your leg perfectly straight, both the upper sensor's quaternion $Q_\mathrm{upper}$ and the lower sensor's quaternion $Q_\mathrm{lower}$ will give the same rotation value no matter which way you move your leg. If you then bend your knee while keeping your upper leg still, the additional rotation around the hinge joint will further rotate the lower leg, with the result $$ Q_\mathrm{lower} = Q_\mathrm{upper} Q_\mathrm{hinge}. $$

The secret to getting the correct angle out is that $Q_\mathrm{hinge}$ represents an axis (which could be in any direction, depending on how you positioned your upper leg) and an angle. You want the angle, not the axis. So forget any urge to extract different "coordinates" of the rotation or to look for individual Euler angles of some sort. Just decompose the quaternion $Q_\mathrm{hinge}$ in the standard way into the "angle" and "axis" parts and ignore the "axis." The angle $\alpha$ by which the lower leg rotated relative to the upper leg is given by the formula $$ \cos\frac\alpha2 = r $$ where $r$ is the real part of $Q_\mathrm{hinge}.$ The angle you drew in the figures is $\theta = \pi - \alpha,$ measuring in radians.

| cite | improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.