ひとしれずひっそり

主にソフトに関することをメモしていきます。過程をそのまま書いていたりするので間違いが含まれます。鵜呑みしない様に。

倒立振子に挑戦 (1)

前回書いた様に倒立振子に挑戦してみる。

まず振子の姿勢を知るためにIMUを使用するので、M5AtomS3を制御に使用する。
姿勢を知るにはroll、pitch、yawを計算すれば良い。

M5AtomライブラリーではM5. MPU6886.getAhrsData()で得られるが、M5AtomS3ライブラリーにはない様だ。ただMahonyAHRS関連の関数はあるようなのでそれを使えば良さそう。

M5AtomS3/MahonyAHRS.h at main · m5stack/M5AtomS3 · GitHub

M5UnifiedにはMahonyAHRS関連は用意されてない様なのでMadgwickライブラリーを読み込んで使用する。

lib_deps = 
    M5Unified
    arduino-libraries/Madgwick@^1.2.0

周期的に計算される事を前提としている様なので、最初タイマーを使用したがスタックを結構使用する様でスタックオーバーフローになってしまった。
タイマーに割り当てるスタックサイズを変更できることも書いてあったが、これからToioの制御もあるのでタスクを使用する事にした。(厳密には計算時間分遅れちゃうんだけど)

static void imu_task(void*)
{
  int freq = 100;
  madgwick.begin(freq);
  while(true) {
    float val[6];
    M5.Imu.getGyro(&val[0], &val[1], &val[2]);
    M5.Imu.getAccel(&val[3], &val[4], &val[5]);
    madgwick.updateIMU(val[0], val[1], val[2], val[3], val[4], val[5]);
    roll = madgwick.getRoll();
    pitch = madgwick.getPitch();
    yaw = madgwick.getYaw();
    delay(1000 / freq);
    Serial.printf("roll: %f, pitch: %f, yaw: %f\r\n", roll, pitch, yaw);
  }
}

表示はM5Unifiedのサンプルを流用した。

M5Unified/HowToUse.ino at master · m5stack/M5Unified · GitHub

表示の判定にあるこの部分が最初理解できなかった。

    if ((xpos[i] < 0) != (px < 0))

結果として左の条件と右の条件のXORを取っている事になっていた。
左は現在の値が負の値で、右は前回の値が負の値を判定している。
負の値負の値 の場合は成立しない。
判定に直接出てこないが 正の値正の値 の場合も成立しない。(0の場合も含まれる)
正と負 、または 負と正符号が違う場合 に条件が成立する。

つまり前回と符号か変わったかを判定している。

この書き方は馴染みがなかったが、XOR判定するときに今度使ってみよう。
というか != はXOR演算子なのか。長い事ソフトをやっているが驚きの発見だ。

上からroll(赤)、pitch(緑)、yaw(青)を表していて、今回はrollを使えば良さそうだ。

ここまで M5AtomS3とToioで倒立振子に挑戦 · GitHub