姿勢推定
機械学習に興味があり、Seeed StudioのXiao nRF52840 Senseを入手したので、今更ながらチュートリアルがてら機械学習(Edge Impulse)を試してみることにしました。
基本、こちら のチュートリアルをなぞっています。
1. ハードウェアについて
今回はとりあえず触ってみようということで、チュートリアルにあるケースやバッテリー、ディスプレイは接続していません。
正真正銘、Xiao nRF52840だけで行っています。
電源もPCから繋がったUSB-C経由です。
使用するソフトウェアのインストール
ライブラリは
- Seeed_Arduino_LSM6DS3-master
-
U8g2
をインストールします
またEdge Inpulseが使えるように
- Node.js v12以上
-
Arduino CLI
- The Edge Impulse CLI
も必要です。
Edge Impulse CLIは
npm install -g edge-impulse-cli
でインストールします。
Edge Impulseと接続
Edge ImpulseとXiao nRF52840を接続します。
USB-CでPCとXiao nRF52840を接続した後、
Edge Impulseにログインして、
プロジェクトを作成します。
(チュートリアルではこの後にどういうタイプのデータを扱うのか聞かれるのですが、そのステップはありませんでした)
ライブラリとサンプルスケッチを取得
データのトレーニングをおこなうため、
Download Seeed_Arduino_LSM6DS3 LibraryのライブラリをZIP形式でダウンロードし、
その後Arduino IEDで
スケッチ>ライブラリをインクルード>.zip形式のライブラリをインストール
でダウンロードしたZIPファイルをインストールします。
その後、下記のコードを入力します。
// XIAO BLE Sense LSM6DS3 Accelerometer Raw Data
#include "LSM6DS3.h"
#include "Wire.h"
//Create a instance of class LSM6DS3
LSM6DS3 myIMU(I2C_MODE, 0x6A); //I2C device address 0x6A
#define CONVERT_G_TO_MS2 9.80665f
#define FREQUENCY_HZ 50
#define INTERVAL_MS (1000 / (FREQUENCY_HZ + 1))
static unsigned long last_interval_ms = 0;
void setup() {
Serial.begin(115200);
while (!Serial)
;
if (myIMU.begin() != 0) {
Serial.println("Device error");
} else {
Serial.println("Device OK!");
}
}
void loop() {
if (millis() > last_interval_ms + INTERVAL_MS) {
last_interval_ms = millis();
Serial.print(myIMU.readFloatAccelX() * CONVERT_G_TO_MS2, 4);
Serial.print('\t');
Serial.print(myIMU.readFloatAccelY() * CONVERT_G_TO_MS2, 4);
Serial.print('\t');
Serial.println(myIMU.readFloatAccelZ() * CONVERT_G_TO_MS2, 4);
}
}
このスケッチを実行することで、シリアルモニターで加速度のロウデータを取得できます。
edge impulseに接続するため、ターミナルで下記コードを実行します。
edge-impulse-data-forwarder
するとターミナル上でログインを促されるため、
Edge Impulseのアカウントでログインを行います。
ちなみにこの際、Arduino側は一度切っておきましょう。
画像でFaied to connectしているのはそのせいです。
またnrf52のライブラリを使おうとしたところ、権限の問題でCompilation errorが出ており、
そちらは adafruit-nrfutil
の権限を変更すると動くようになりました。
その後、3軸センサーのそれぞれの値の呼び名、デバイス名の入力を求められるのでそちらも適宜入力します。
これでEdge ImpulseとXiaoを接続できました。
挙動のサンプリング開始
Edge ImpulseのData acquisition
ページへ行きデバイスとの接続が正常に出来てるか確認します。
ページ右側にデバイス名が出ていれば成功です。
ページ右側で取得するセンサーを選択した後、
これからサンプリングする挙動の名前をつけます。
上下運動から設定するため up and down
と入力します。
Sample lengthはチュートリアルと揃えて20000msとしました。
Start sapling
ボタンをクリック後、サンプリングが開始されるので、
20秒間、Xiaoを上下に振り続けます。
20秒経過すると、取得したデータのグラフが右下に表示されます。
このデータを適切な単位で分割するため、グラフ右上の3点リーダから Split sample
を選択します。
サンプルの分割は、一回ずつの挙動を適切な範囲で選択して上げる必要があります。
(僕はここで適当にやりすぎてサンプル入力を何回もするハメになりました)
最終的には20秒間に1秒1回ずつ上下運動を取得し、1秒ずつ分割することで精度もよくなりました。
その後、同じように
- 左右運動(
left and right
) - 時計回り(
clockwise
) - 反時計回り(
unticlockwise
)
も入力し、分割していきます。
機械学習モデルを構築
ダッシュボードに戻り、画面下部の Perform train / test split
をクリックします。
確認がでるのでConfirmします。
サイドバーからCreate impulse
をクリックし、
Add a processing block
-> Spectral Analysis
-> Add a learning block
-> Classification
-> Save Impulse
の順番で選択していきます。
サイドバーのSpectral features
から Save parameters
をクリック
ページ上部の Generate features
からページ下部のGenerate features
ボタンをクリックします。
するとこんな感じで、各データの分布図が表示されると思います。
サイドバーの Classifier
から Start training
をクリックします。
処理が終わると、画面右下にAccuracy
が表示されるはずです。
この値が65%より低いと精度がかなり悪くなるので、サンプル回数を増やしてみてください。
Arduino用のSketchをデプロイ
サイドバーの Model testing
から Classify all
をクリック
ここでもAccuracyが低い場合はサンプル回数を増やしてみましょう(画像はAccuracyが低い例)
問題なければ
サイドバーの Deployment
から SELECTED DEPLOYMENT
でArduino Library
を選択し。
Build
ボタンをクリックします。
ZIPファイルがDLされるのでそのファイルを
スケッチ
>ライブラリをインクルード
>.zip形式のライブラリをインストール
でインストールします。
こちらのファイルをダウンロードし、Arduino IDEで開いたあと、
冒頭にある
#include <XIAO-BLE-gestures-inferencing.h>
のライブラリ名部分を先程インストールしたライブラリ名に置き換えます。
成功
プログラムを実行後、XIAO nRF52840 Senseを動かしながらシリアルモニターを確認しましょう。
画像のように姿勢が推定されていれば成功です!
(left and rgith、up and downの確度が高まっている状態)
感想
機械学習、よくわからなすぎて手を付けられていなかったのですが、Edge Inpulseは簡単に触ることができてよかったです!
他のデバイスでも試してみようと思います。