M5StickCの6軸IMU(SH200Q)検証

謎の動きをしています。。。ジャイロと加速度の数値が逆な気がしますし、軸もおかしいような?

情報

IMUは英語のページと、データシートがあるので良かったです。

データシートでの軸

IMUは使ったことがないのですが、図を見る限り普通の座標系な気がします。

実験

机の上に、横に置いて、上から見た図の写真です。この方向からいろいろな方向に動かして、加速度とジャイロの反応を調べました。

表示されているのが上から、ジャイロの現在値、最大値、最小値。加速度の現在地、最大値、最小値です。ボタンを押すと数値をリセットするので、調べ終わったらリセットして、他の方向を調べています。

傾けて停止した場合、ジャイロの数値は変化した状態で安定し、加速度は0に近くなるはずが、逆に見えます。以下上が加速度、下がジャイロとして検証しています。データシート上は正しい数値を読み出している気がしますが、なんでだろう?

加速度(acc)

X軸加速度

左右に動かしても反応しなかったのですが、なんと右側を持ち上げるとプラスに反応。左側を持ち上げるとマイナスの加速度でした。

Y軸加速度

Y軸は手前に傾けるとプラス、手前を持ち上げるとマイナスでした。

Z軸加速度

Z軸は左に回転するとプラス、右に回転するとマイナスでした。

ジャイロ(Gyro)

X軸ジャイロ

元の状態が0で、手前を持ち上げるとプラスで、写真の状態で0.5になり、奥を持ち上げるとマイナスになります。

Y軸ジャイロ

元の状態が0で、右側を持ち上げるとプラスで、写真の状態で0.5になり、左側を持ち上げるとマイナスになります。

Z軸ジャイロ

元の状態が0.5で、どの方向にでも90度傾けると0.0になっていたように思えます。

実験プログラム

#include <M5StickC.h>

int16_t accX = 0;
int16_t accY = 0;
int16_t accZ = 0;

int16_t gyroX = 0;
int16_t gyroY = 0;
int16_t gyroZ = 0;

void setup() {
  // put your setup code here, to run once:
  M5.begin();
  M5.IMU.Init();
  M5.Lcd.setRotation(3);
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setTextSize(1);
  M5.Lcd.setCursor(40, 0);
  M5.Lcd.println("SH200I TEST");
  M5.Lcd.setCursor(0, 15);
  M5.Lcd.println("  X       Y       Z");
  pinMode(M5_BUTTON_HOME, INPUT);
  pinMode(M5_BUTTON_RST, INPUT);
}

float max_gyroX = 0;
float min_gyroX = 0;
float max_gyroY = 0;
float min_gyroY = 0;
float max_gyroZ = 0;
float min_gyroZ = 0;

float max_accX = 0;
float min_accX = 0;
float max_accY = 0;
float min_accY = 0;
float max_accZ = 0;
float min_accZ = 0;

void loop() {
  if (digitalRead(M5_BUTTON_HOME) == LOW || digitalRead(M5_BUTTON_RST) == LOW ) {
    max_gyroX = 0;
    min_gyroX = 0;
    max_gyroY = 0;
    min_gyroY = 0;
    max_gyroZ = 0;
    min_gyroZ = 0;

    max_accX = 0;
    min_accX = 0;
    max_accY = 0;
    min_accY = 0;
    max_accZ = 0;
    min_accZ = 0;
    delay(1000);
  }

  // put your main code here, to run repeatedly:
  M5.IMU.getGyroData(&amp;gyroX, &amp;gyroY, &amp;gyroZ);
  M5.IMU.getAccelData(&amp;accX, &amp;accY, &amp;accZ);

  if ( max_gyroX < ((float) gyroX) * M5.IMU.gRes ) {
    max_gyroX = ((float) gyroX) * M5.IMU.gRes;
  }
  if ( ((float) gyroX) * M5.IMU.gRes < min_gyroX ) {
    min_gyroX = ((float) gyroX) * M5.IMU.gRes;
  }

  if ( max_gyroY < ((float) gyroY) * M5.IMU.gRes ) {
    max_gyroY = ((float) gyroY) * M5.IMU.gRes;
  }
  if ( ((float) gyroY) * M5.IMU.gRes < min_gyroY ) {
    min_gyroY = ((float) gyroY) * M5.IMU.gRes;
  }

  if ( max_gyroZ < ((float) gyroZ) * M5.IMU.gRes ) {
    max_gyroZ = ((float) gyroZ) * M5.IMU.gRes;
  }
  if ( ((float) gyroZ) * M5.IMU.gRes < min_gyroZ ) {
    min_gyroZ = ((float) gyroZ) * M5.IMU.gRes;
  }

  if ( max_accX < ((float) accX) * M5.IMU.aRes ) {
    max_accX = ((float) accX) * M5.IMU.aRes;
  }
  if ( ((float) accX) * M5.IMU.aRes < min_accX ) {
    min_accX = ((float) accX) * M5.IMU.aRes;
  }

  if ( max_accY < ((float) accY) * M5.IMU.aRes ) {
    max_accY = ((float) accY) * M5.IMU.aRes;
  }
  if ( ((float) accY) * M5.IMU.aRes < min_accY ) {
    min_accY = ((float) accY) * M5.IMU.aRes;
  }

  if ( max_accZ < ((float) accZ) * M5.IMU.aRes ) {
    max_accZ = ((float) accZ) * M5.IMU.aRes;
  }
  if ( ((float) accZ) * M5.IMU.aRes < min_accZ ) {
    min_accZ = ((float) accZ) * M5.IMU.aRes;
  }

  M5.Lcd.setCursor(0, 24);
  M5.Lcd.printf("%+7.2f %+7.2f %+7.2f\n", ((float) gyroX) * M5.IMU.gRes, ((float) gyroY) * M5.IMU.gRes, ((float) gyroZ) * M5.IMU.gRes);
  M5.Lcd.printf("%+7.2f %+7.2f %+7.2f\n", max_gyroX, max_gyroY, max_gyroZ);
  M5.Lcd.printf("%+7.2f %+7.2f %+7.2f\n", min_gyroX, min_gyroY, min_gyroZ);

  M5.Lcd.setCursor(0, 50);
  M5.Lcd.printf("%+7.2f %+7.2f %+7.2f\n", ((float) accX) * M5.IMU.aRes, ((float) accY) * M5.IMU.aRes, ((float) accZ) * M5.IMU.aRes);
  M5.Lcd.printf("%+7.2f %+7.2f %+7.2f\n", max_accX, max_accY, max_accZ);
  M5.Lcd.printf("%+7.2f %+7.2f %+7.2f\n", min_accX, min_accY, min_accZ);
}

サンプルスケッチのSH200Iに最小値と最大値を保存するようにした物になります。温度計は表示上邪魔なので消してしまいました。

まとめ

サンプルスケッチを動かしてみて、数値の動きが意図していたのと違っていたので実験してみましたが、予想と違う結果になりました。

加速度は純粋な座標軸じゃなくて、座標軸に対する回転方向の加速度な気がします。ただ、加速度とジャイロで軸の方向が違う気がするので謎が深まります。

ジャイロはおそらく重力を基準としているので、チップの付いている向きと重力の向きが違うのかもしれません。

ちょっと腑に落ちないところがあるので、他の人も検証してもらいたいです。私の端末がおかしいのか、そもそもデータシートから間違っているのかが知りたいです。。。

5件のコメント

    1. 図でおかしいのは,軸は左手座標系なのに回転方向が反時計回りになっているところですかね.一般的に左手座標系の場合,時計回りがプラス方向かと思います.

      1. そもそも加速度とジャイロの数字が逆と思えるので、何が正しいのかがわからない状態です、、、
        データシートとソースコード上、正しいはずなんですけれどね

    1. データシートと実際の動きが違う気がしますよね
      全部この動きであれば、この動き前提のプログラムを作ればいいんですけれど、ちょっともやっとします

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)