M5StickCの傾きに応じて画面上のボールを転がしてバウンドさせる

M5StickCには6軸センサが搭載されており、M5StickC本体の傾きなどを検知することができます。
また、LCDも搭載されており、画面上に図形を描画することもできます。


先日、これらの機能を利用して、「M5StickC本体を傾けると、それに応じて、LCDに表示されているボールが転がる」というスケッチ(記事は こちら)と、「M5StickC本体のLCDに表示されているボールが自由落下し、地面についたらバウンドする」というスケッチ(記事は こちら)を作成しました。

今回はこれらふたつのスケッチを組み合わせ、

  • M5StickC本体を傾けると、それに応じて、LCDに表示されているボールが転がる
  • ボールが画面の左右端についたら、そこでバウンドする

というスケッチを作ってみます。

先日のスケッチと同様、6軸センサで、Y軸の加速度情報「accY」を採取します。
前回は、この加速度情報から、そのままボールの速度「v」を求めていましたが、今回は、ボールの跳ね返りを考慮するため、一旦、加速度から力「f」を求めます。
その上で、弾性力(F = kx)、粘性抵抗(F = cv)というふたつの力も考慮して、「f」を補正します。
こうして求めた補正後の「f」から、ボールの加速度「a」、ボールの速度「v」、ボールの位置情報「x」を求めます。

スケッチは以下のようになります。「k」、「c」の値は、ボールの跳ね返り具合が自然になるように調整しました。

#include <M5StickC.h>

float accX = 0.0f;
float accY = 0.0f;
float accZ = 0.0f;
float x = 80.0f;
float v = 0.0f;
float m = 1.0f;
float k = 1.0f;
float c = 0.3f;

void setup() {
  M5.begin();
  M5.IMU.Init();
  M5.Lcd.setRotation(1);
}

void loop() {
  M5.update();
  M5.IMU.getAccelData(&accX, &accY, &accZ);
  float f = m * accY;
  if(x > 150.0) {
    float f2 = k * (x-150.0);
    float f3 = c * v;
    f = f - f2 - f3;
  }
  if(x < 10.0) {
    float f2 = k * (x-10.0);
    float f3 = c * v;
    f = f - f2 - f3;
  }
  float a = f / m;
  v += a;
  x += v;
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.fillCircle((int)x, 40, 10, YELLOW);
  delay(20);
}

結果は以下のとおりです。結構いい感じに、ボールの動きを表現できていると思います。

座標計算のための特別なライブラリも使わず、わずか数十行のスケッチで、おもしろい動きを表現することができました。
応用すると、より複雑な動きも表現できそうです。

なお、私がM5Stack、M5StickCの使い方を習得するのにあたっては、以下の書籍を参考にさせていただきました。


ごく基本的なところから、かなり複雑なスケッチや、ネットワーク接続など、比較的高度なものまで、つまづかずに読み進めていけるような構成になっており、大変わかりやすい本です。


このサイトで書いている、M5Stackシリーズ(M5Stack、M5StickCなど)に関するブログ記事を、「さとやまノート」という別のブログページに、あらためて整理してまとめました。

他のM5Stackシリーズの記事にも興味のある方は「さとやまノート」をご覧ください。