3

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
Slicc
  • 133
  • 4
  • 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? – fibonatic Feb 09 '21 at 07: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 – Slicc Feb 09 '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)? – fibonatic Feb 09 '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. – Slicc Feb 10 '21 at 06: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. – Slicc Feb 10 '21 at 06:48
  • As stated before, this doesn't uniquely define the rotation. Namely, any rotation around the z-axis you can't detect. One could assume that there is no rotation around the z-axis, in which case there would be a unique solution. – fibonatic Feb 10 '21 at 08:36
  • Ahh yes, see what you are saying, yes I am not concerned with rotation around the z-axis, at some point I may, but can use the gyros/compass if I do. – Slicc Feb 10 '21 at 08:52

1 Answers1

3

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.

Alex
  • 449
  • 2
  • 7
  • 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. – Slicc 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. – Slicc 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 RPb to get to work corner coordinates? I.e. why is the rotation matrix transposed in your second step? – Slicc Feb 11 '21 at 07: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
  • Ah right, I was seeing 0,0,1 as a body coordinate and the accelerometer as the world coordinate, but think I follow it your way round. – Slicc Feb 11 '21 at 13:12