0
0

More than 1 year has passed since last update.

クラシックマウス 作ってみた その4 Gyro

Last updated at Posted at 2023-02-05

はじめに

  • 作成したクラシックマウスの各パーツの解説。
  • 今回は「Gyroセンサー MPU6050」。
  • 機体写真、動画などは「その1」をご参照。

Gyroセンサー MPU6050

ステッピングモーターを使っていても、進むにつれて車体は斜めになっていき、いずれ壁に激突してしまう。距離センサーは精度が足りず、なかなか機体を制御するのが難しかった。
Gyroセンサーは、安価なのに精度が高く、機体の向きの制御が格段に容易になりました。

  • BNO055との比較
    • BNO055も試してみましたが、MPU6050の方が精度が高い気がしました。
    • BNO055は9軸なので、向き(yaw)の絶対値が求まります。一方MPU6050は6軸なので、相対的な向きが出てきます。迷路探索においては、相対的な向きで十分なので、MPU6050を使っています。
  • 取付位置
    • 機体の写真で上に飛び出しているのがMPU6050です。マイコンやモーターからのノイズを減らす目的で離して取り付けています。ミニブレボ上に取り付けるより良くなった気がします。
  • 使い方
    • スタート時に向きを測定し、その測定数字をもとに機体の向きを修正しています。
    • 90度回転 → 向き測定 → ずれた分を微調整 のような感じで利用しています。 
  • "yaw" 4元数?
    • 本モジュールはマイコン(DMP)を内蔵していて、いろいろな数字を出力してくれますが、ここでは"yaw"しか使っていません。Sampleスケッチによると、"yaw"は4元数から計算されているようなので、精度は十分と考えました。
    • 正直、4元数は難しすぎます。ドローン制御には必須なのでしょうか…
  • 精度、調整
    • 精度はかなり高いように思います。いろいろ回転させてみても、1~2°程度の誤差に収まっているようなので、機体制御には十分です。
    • 自作の4×4迷路では、移動を繰り返した後でも、十分な精度を保っているように見えます。16x16ではどうなるでしょうか。
    • 電源を入れてから、しばらく数字が安定しません。10秒程度(?)経つと安定するので、それから利用しています。
  • ライブラリ
    • ElectronicCatsのMPU6050を使いました。
    • MPU6050_DMP6_using_DMP_V6v12.ino を適宜修正、削除して、"yaw"を利用しています。
    • このSampleスケッチは割込みピンを利用する形になっていますが、ここでは利用していません。計測頻度が高くないので大丈夫なのでしょう。
    • Calibrationは良くわからないので、Sampleスケッチにおまかせです。間違いがあるかもしれません。
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps612.h"
MPU6050 mpu;
#define OUTPUT_READABLE_YAWPITCHROLL

// MPU control/status vars
uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;     // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer

// orientation/motion vars
Quaternion q;           // [w, x, y, z]         quaternion container
VectorFloat gravity;    // [x, y, z]            gravity vector
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

/////  以下SETUP内  ////////////
//6050初期化
// initialize device
  mpu.initialize();
  // load and configure the DMP
  devStatus = mpu.dmpInitialize();
  // supply your own gyro offsets here, scaled for min sensitivity
  mpu.setXGyroOffset(51);
  mpu.setYGyroOffset(8);
  mpu.setZGyroOffset(21);
  mpu.setXAccelOffset(1150);
  mpu.setYAccelOffset(-50);
  mpu.setZAccelOffset(1060);
  // make sure it worked (returns 0 if so)
  if (devStatus == 0) {
    // Calibration Time: generate offsets and calibrate our MPU6050
    mpu.CalibrateAccel(6);
    mpu.CalibrateGyro(6);
    mpu.PrintActiveOffsets();
    // turn on the DMP, now that it's ready
    mpu.setDMPEnabled(true);
    // get expected DMP packet size for later comparison
    packetSize = mpu.dmpGetFIFOPacketSize();
  } else {
    // ERROR!
    // 1 = initial memory load failed
    // 2 = DMP configuration updates failed
    // (if it's going to break, usually the code will be 1)
    oled.print(F("DMP Initialization failed (code "));
    oled.print(devStatus);
  }

/////  以下yaw取得のための関数  ////////////

float get_y_6050(){
    // read a packet from FIFO
    mpu.dmpGetCurrentFIFOPacket(fifoBuffer);
    // display Euler angles in degrees
    mpu.dmpGetQuaternion(&q, fifoBuffer);
    mpu.dmpGetGravity(&gravity, &q);
    mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);

    return ypr[0] * 180 / M_PI;
}

以上

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0