# Calculating rotation matrix efficiently

I'm trying to efficiently calculate the vertical offset of each corner of a rectangular base. I have an accelerometer mounted in the middle of the base, ADXL345. The steps I have taken, and seems to work are below. Can anyone advise if this is the most efficient way of doing this. I'm using the raspberry pi pico, with MicroPython:

1. convert the accelerometer into a unit vector
2. use the dot product and cross products ( between X =0, y= 0, z= 1 and the accelerometer unit vector) to calculate the quaternion
3. calculate the quaternion rotation matrix
4. calculate the rotation of the four corners using the rotation matrix, but only for the z component, as I'm only interested in vertical offset of the corners
• One vector pair (each in different reference frames) aren't enough to define a unique rotation. Or are you interested in the rotation with the smallest angle? Feb 9 '21 at 7:38
• I might be misunderstanding, here, but I am assuming they are in the same reference frame, i.e. the 0,0,0 of both vectors is the same point in space. All new to me here, so not sure what I am saying is correct Feb 9 '21 at 14:46
• So you are not looking for the rotation matrix that maps (0,0,1) to the accelerometer unit vector (or vise versa)? Feb 9 '21 at 21:54
• No, there are three vectors here, 0,0,1 (the start position of the accelerometer), the accelerometer reading unit vector, and the vector of the corner of the plane. I'm looking to see how the corner of the plane has moved in z as a consequence of 0,0,1 moving to the new accelerometer vector. Hope that makes sense. Feb 10 '21 at 6:40
• So I'm currently using 0,0,1 and the accelerometer to calculate a rotation matrix, then applying that to the corner of the plane. Everything is centred about the accelerometer. Feb 10 '21 at 6:48

The accelerometer measures the gravity vector in the body frame, call it $$a$$. If you normalize that, say $$\hat a$$, it's the third row of the rotation matrix $$R$$ that represents the rotation of the body. i.e. $$R^\top \begin{pmatrix}0 \\ 0 \\ 1\end{pmatrix} = \frac{a}{||a||} = \hat a = z_{\mathcal{W}}^{\mathcal{B}}$$

So $$R = \begin{pmatrix} ? \\ ? \\ \hat a \end{pmatrix}$$

Now to get the world coordinates of a corner point $$p^{\mathcal{B}}$$ expressed in the body frame, $$p^{\mathcal{W}} = R p^{\mathcal{B}} = \begin{pmatrix} ? \\ ? \\ \hat a \end{pmatrix} p^{\mathcal{B}} = \begin{pmatrix} ? \\ ? \\ \hat a ^\top p^{\mathcal{B}} \end{pmatrix}$$

Thus the world $$z$$ coordinate of the corner point is the dot product between the normalized accelerometer vector and the corner point expressed in the body frame.

If you just need the $$z$$ coordinate, you do not need to construct the rotation matrix.

• Looks good thanks, so if I follow, I just calculate the third row and apply that on it's own, without worrying about the other two. Feb 10 '21 at 13:25
• In fact you seem to have got to the final row in fewer steps than my approach above! Will give it a try thanks. Feb 10 '21 at 13:30
• Yes, just normalize the accelerometer data, then dot product with the body points to get the z coordinates. If you have the points in an Nx3 matrix, a matrix multiplication with the unit vector acceleration will get you the N z coordinates.
– Alex
Feb 10 '21 at 23:56
• Probably a silly question, but why is it Rt*(0,0,1) to get to the world accelerometer coordinates, but R*Pb to get to work corner coordinates? I.e. why is the rotation matrix transposed in your second step? Feb 11 '21 at 7:39
• Multiplying by R.T takes a vector expressed in world coordinates and expresses it in body coordinates. Since the gravity vector is along the world z-axis (straight up or down), to express it in body coordinates, we multiply by R.T. Since the accelerometer measures gravity in body coordinates, we know it's the third row of R (or third column of R.T). To convert corner points expressed in body coordinates to world coordinates, we multiply by R. In this case, we can only compute the z coordinate. Let me know if something sounds wrong or is unclear!
– Alex
Feb 11 '21 at 12:30