How to handle physical orientation of ICM20948 when calculating Roll and Pitch used for leveling

We are creating a device based on a ESP32 and an ICM20948, using 4 actuators to physically level out platforms.

The actuators are activated based on the Roll and Pitch that is calculated from the output of the ICM20948.

For the calculation of the Roll and Pitch, we “borrowed” code from the internet (https://en.wikipedia.org/w/index.php?ti … rce_code_2 ), incoorporated in the examples by @PaulZC as I understand)

We are technically schooled but no mathematicians and do not really understand what it’s doing … but its working :slight_smile:

The actuators are on a well known location on the platform, so we know that if i.e. Roll = 10 that we need to extend the forward and backward actuators on the right of the platform to get the Roll to become smaller.

The problem now arrises that the way that our device is mounted on the platform can vary between installations, the ICM will not always be mounted parallel to the top surface of the platform, but can be mounted in any orientation (we can assume that it will only be 90 degree rotations, so the Roll or Pitch axis can point forward, left, backwrd, right, up or down in regards to the platform.)

Our question is how can we add a configuration specifying the mounted orientation, and (more importantly) use that configuration to get the right Roll and Pitch angles of the platform to steer the correct actuators.

Any help or reference to other sources would be welcome.

Thanks!

I posted this question as an issue on the ICM_20948 github and PaulZC was kind enough to point out de direction of the solution, but I still need some more help in implementing this. (See https://github.com/sparkfun/SparkFun_IC … /issues/66)

So i could get a quaternion describing the physical mounting of the ICM but im still not sure how to apply this quaternion on the quaternion that comes from the ICM (before converting it to Euler angles). Can somebody help me with that?

Also, would mounting the ICM differently have any effect on the accuracy of the retrieved values? I can i.e. imagine that the magnetometer will be working differently if its set at a 90 degree angle… ?

When the sensor is not moving, roll and pitch are determined entirely by the accelerometer, as described here: https://wiki.dfrobot.com/How_to_Use_a_T … lt_Sensing

If you can’t install sensors on platforms in a known orientation, then you will somehow have to calibrate each platform individually. The easiest way to do that is to measure the roll and pitch values when the platform is level, and use those values as the final target of the leveling mechanism.

We do store the actual values as part of a one time calibration process, but the problem is that if the device is mounted other then with the X axis in the North direction and the Y axis in the Eeast direction then we don;t know fi we need to look at roll and pitch, or maybe yaw and pitch or … etc etc.

As PaulZC already pointed out to me, a BNO080 chip has the possibility include to specify the mounted orientation, and it will correct the resulting quaternions. Bus alas the ICM does not have that capability.

Determining which axis is approximately vertical when the platform is level is a trivial programming exercise. That will be the one with showing the maximum positive value of acceleration when the accelerometer is not moving.

Call that axis “Z” and assign the other two as “X” and “Y” according to the right hand rule for coordinate systems. Proceed from that to calculate pitch and roll according to

  roll = atan2(Y , Z) * 57.3;
  pitch = atan2(- X , sqrt(Y *Y + Z *Z)) * 57.3;

Ok that is true, but i still dont know which is in the North/South indicating pitch and which in the East/West indicating Roll.

That doesn’t matter. If the sensor is fixed to the platform, so are the actuators, right? If all you care about is level, then that is determined by the up/down direction, and has nothing to do with N, E, S, W.

My approach would be to calibrate each setup by recording the accelerometer (ax, ay, az) values when the platform is level, and in a new situation, move whichever actuators are required to re-establish those values. Actuator identification can automatically be determined by the leveling program.

To elaborate, this is a standard optimization problem. Suppose you have three actuators X1, X2, X3 to adjust the platform orientation, and that the setup is calibrated so that the accelerometer reads (ax0, ay0, az0) when the platform is level.

Most people would use the Least Squares Method and adjust the X values to minimize the sum of squares S = (ax - ax0)^2 + (ay - ay0)^2 + (az - az0)^2. This can be done even without knowing the relationship between (X1, X2, X3) and (ax, ay, az), for example, by using numerical derivatives and gradient descent. You don’t need to calculate tilt angles, either.

jremington, Thanks for you help so far

I think I know where you are going with this … but not quite there yet …

We have 4 actuators, one on each corner of the platform. The platform is a very sizable weight, so I have to be carefull and gentle in the movements of the actuators

What I do not understand is how I can determine which actuators to move based on the differences between (ax0, ay0, az0) and (ax, ay, az)? Like I said before … i’m no mathematician

Also, do you mean by “accelerometer values” the values determined by just the accelerometer, or by the full IMU including gyroscooop and magnetometer, 9 DOF

The gyroscope and magnetometer are of no use whatsoever for your problem.

how I can determine which actuators

Very simply. Move an actuator a tiny bit. If the sum of squares S (defined in post #226106) increases, that is the wrong direction, so move in the other direction.

One mindless, programmatic approach is to cycle around the actuators in random order, applying the above idea, until S is at some minimum value. But there are much better approaches.

You might consider collaborating with someone who is familiar with the mathematics, or at the very least, post the details of your gizmo so people would have a better idea what you are talking about.

I understand what you mean, but given the size of the platform we don;t want to make any movements that are not needed, so we dont want to do this by trial and error.

Also because of the load, we are only allowed to always move two adjacent actuators at the same time (so leftfront and rightfront or leftfront and leftrear etc).

That is why we were looking at roll and pitch, so we can i.e. decrease pitch by lengthening the left and right rear actuators