BITalinoで筋電位センサー

Image from Gyazo

筋電位センサー

今回はBITalinoの 筋電位センサー(EMG) を利用してみましょう. 筋電位センサーの電極ケーブルは3極で構成され,中央が基準電極(REF),左右が正極(+)と負極(-)を表しています. このように,2極の信号の差分を増幅して取得する方法は 作動増幅 と呼ばれ,生体センシングではよく用いられる方法です.

Image from Gyazo

筋電位センサーを腕に取り付けます. 基準となる基準電極は肘の骨がある部分に配置します. また,正極と負極は筋繊維に沿って配置します.

Image from Gyazo

OpenSignalsでデータを取得してみましょう. まずは,BITalinoの設定を変更します. 今回はA1に筋電位センサー(EMG)を接続しているため,EMG を指定しています.

Image from Gyazo

計測を開始すると,0を平均として小さなスパイク状の波形が発生している. ここで,腕に力をいれると,波の振幅は大きくなることがわかります.

Image from Gyazo

Python APIを利用した筋電位の取得

それでは,Python APIを利用して筋電位のデータを取得してみましょう. データの取得方法は光センサーのときと全く同じです. しかし,取得されるデータはBITalino独自の単位となっているため, 一般的なミリボルト(mV)を単位とするには下記の式を用いて変換が必要です (詳細は公式ドキュメント参照).

$$ EMG(mV) = \frac{ (x / 2^n - 1 / 2) \cdot VCC \cdot 1000 }{ GAIN } $$

上記の式において,$n$は信号のビット幅であり10ビット,$VCC$は電源電圧であり3.3ボルト,$GAIN$はセンサーゲインであり1009を指定します. この変換したデータ(mV)の 平均標準偏差最大値 を求めてみることにします.

BITS = 10 # 信号のビット幅
VCC = 3.3 # 電源電圧
GAIN = 1009 # センサーゲイン

emg = (((((data[:,5] / 2**BITS) - 1/2) * VCC) / GAIN) * 1000) # 単位変換(mV)
emg = np.abs(emg) # 絶対値

print(emg)
print("Average:" + str(np.average(emg)))
print("Standard Deviation:" + str(np.std(emg)))
print("Maximum:" + str(np.max(emg)))

下記は腕に力を入れていないときと,力をいれたときの比較です. 平均,標準偏差,最大値のいずれも,力を入れたときの方が大きな値となっています. これは,力をいれると波形の振幅が大きくなることが理由です. このため,適当な 閾値 を定めれば,どちらの状態かを判定することができそうです(後述では閾値を 0.3 に設定).

【力を入れていないとき】

Average:0.02015357872893954 # 平均
Standard Deviation:0.01117134026621993 # 標準偏差
Maximum:0.04152084365708622 # 最大値

【力を入れたとき】

Average:0.06394209923191277 # 平均
Standard Deviation:0.05738557855750504 # 標準偏差
Maximum:0.35133021555996036 # 最大値

コミュニケーション・ボードの実装

それでは,筋電位を利用したコミュニケーション・ボードを制作してみましょう. コミュニケーションボードは,発話に障がいを抱える人が,文字やイラストを選択することで意思を伝える仕組みのことです. ここでは,Pythonのゲーム甩のライブラリである PyGame を利用しますが,詳細は割愛します.

下記が閾値を利用して,力の有無を判定する関数です. この関数は,閾値(THRESHOLD)を 0.3 とし, 取得した値が閾値を超えればTrue,越えなければFalseを返します.

def selected():
    BITS = 10 # 信号のビット幅
    VCC = 3.3 # 操作電圧
    GAIN = 1009 # センサーゲイン
    THRESHOLD = 0.3 # 閾値

    data = device.read(nSamples)
    emg = (((((data[:,5] / 2**BITS) - 1/2) * VCC) / GAIN) * 1000) # 単位変換(mV)
    emg = np.abs(emg) # 絶対値
    max_value = np.max(emg) # 最大値

    if max_value > THRESHOLD:
        return True
    else:
        return False

1秒ごとにフォーカスが移動するコミュニケーション・ボードを作成し, 上記の関数でタイミングよく選択することで合成音声を発話します. 下記の動画がデモとなります.

スポンサーリンク