Posted at

M5StickCで歩数計を作る


はじめに

LINE Thingsで歩数計Botを作ろうの補足記事です。前回はM5StackのPedometerライブラリを使って歩数計を作成しましたが、ここではM5StickCで歩数計を作成します。

M5StackCには歩数計のライブラリがなかったので自分で実装する必要がありました。ちなみに書いたコードはこちらで公開しています。

また、M5StickCに搭載されているモーションセンサーは旧デバイスではSH200Qで新デバイスではMPU6886になります。ライブラリの記述にも違いが少しあるので注意が必要です。


参考


とりあえず歩数計を作ってみる

まずは下の図のような方針を考えてみました。

歩数計.jpg

各ブロックの具体的な実装に上記のサイトを参考にしました。センサーデータは単純にセンサー値を取ってきただけなので省略して、そこから先の


  1. ノルム(ベクトルの長さ)の算出

  2. フィルタリングによるセンサーノイズの除去

  3. 信号波形からの歩数算出

について書いていきます。


ノルムの算出

デバイスからはx,y,z軸の加速度がとれるわけですが、歩いているときに変化するのはどこか一方の軸になることが想像できますが、デバイスを固定しない限りどこの軸が変化するのかわからないので今回は3軸のベクトルから長さを算出してそれをセンサー値としました。

ノルムを算出するにあたり通常なら以下のユークリッド距離を使うのが通常ですが、

L=\sqrt{x^2+y^2+z^2} \\

別に正確なノルムを計算する必要がないことと、マイコンで平方根の計算をするのもいかがなものかと思ったので今回は下の式のようなマンハッタン距離を使いました。

L=|x|+|y|+|z|

これだと単純に絶対値を足すだけでいいので計算が軽くなるのと、センサー値を大きくとることができるので良いかなと思いました。


フィルタリングによるノイズ除去

これに関しては定石どおりにデジタルローパスフィルタをかけることにしました。

y_i = a \times y_{i-1} + (1-a) \times x_i

今回はaの値を0.8としました。


波形を見てみる

歩数算出のために一旦ここでセンサー値を見てみることにしました。計測のためにポケットにM5StickCを入れてそこら辺をグルグルと歩きながら、デバイスからセンサー値をwifiでローカルサーバ送って、ローカルサーバからそれをcsvファイルに変換してグラフを求めました。

data0.png

ローパスフィルタをかけたのにあまりノイズが除去できてなかったのが悲しかったですが、とりあえず閾値からの立ち上がりor立ち下がりを求めたら歩数が算出できそうな気がしました。しかしこの閾値は常に一定にはならなさそうな波形でもあったので算出方法に工夫がいりそうです。

ここで先述した参考サイトを見ながら動的に閾値を求める方法を実装してみました。


動的に閾値を求める

ざっくりしたイメージが下図です。

閾値の求め方.jpg

n回分センサー値を求めてその最大値と最小値を足したものを2分して平均値を求めるというシンプルなやり方です。とりあえず今回はnの値を10,20,30,40,50に変えながら閾値の算出のようすを計測してみてグラフを出してみました。


n=10

data1.png

青い線がセンサー値で、赤い線が動的に求めた閾値です。ちゃんと追従はしてくれますが、よけいなノイズとかも拾ってしまっている気もします。


n=20

data2.png

さきほどより落ち着きは感じますが、いまいち。


n=30

data3.png

あまり違いがない。


n=40

data4.png

落ち着きがでてきた。もう少し!!


n=50

data5.png

安定して閾値を算出しているように感じる。欠点としては最初に多くのサンプルを取る必要があるので立ち上がりが遅いことですね。参考サイトでは50がいいと言っていたのでこの数値あたりが妥当だと思います。これ以上上げると立ち上がりが遅くなってしまうので。。。


さいごに

この後は前回の記事と同じなので省略します。とりあえず今回の考察は以下です。


  • 加速度の取得の間隔が短すぎるとMPU6886からちゃんと値が取れなかったので今回は100msの間隔を置いていたが、歩数計では人間の歩行のペース感覚に合わせれば良いのでもう少し遅延を置いても良かったのかもしれない

  • 歩行の波形の周波数はある程度の帯域みたいなものが存在する気もするのでバンドパスフィルタをかけることも効果がありそう

  • 今回は併設されてるジャイロセンサーは不使用だったが、それを用いてセンサー値の補正などを行えるかもしれない

  • センサー値を計測するときに今回は前後の小さな値の変化のときは前の値をそのまま渡すことで、デバイスの僅かな動きでも歩数が加算されることを避けたが、ここでは50という値のみで固定していたので、適切な値を設定すれば歩行以外の動作を切り捨てられるかもしれない

作ったはいいものの、精度があまりよろしくないので今後の改良の余地がありそうです。ちなみにスライド版も公開しています。どちらかというと記事の方が結構後に書かれたものです。

こういった数パターンのグラフを貼る作業は学生の時以来だったので懐かしさを感じました。