電子工作
3Dジェスチャーモジュールを試す
公開日:
2020/04/13
3Dジェスチャーモジュールを試す

はじめに

OBのUMEです。

部活公式Vtuberができたりランダムのサイトがいつのまにやら新しくなったりブログリレーをやったりとアクティブに活動しているのを見てすげーという気持ちになっていたところ、 活発な部員のペンギンから

老害OB枠として新歓ブログリレー参加して貰えません?(原文ママ)

というメッセージを受け取ったので、適当に何か記事を書いてみます。
新入生を意識してかふわっとした楽しげな記事が多いですが、自分は少しお堅い記事を書いてみます。

記事の内容に直接関係ないですが、ブログ執筆用のページ普通に高機能ですごい。

やること

この3Dジェスチャーを認識するモジュールを使ってみます。電子工作のモジュールを扱うスイッチサイエンスというところに新商品として並んでいたものです。
(良い感じの短い名前が付いていなさそうなので、この記事内では Seeed_mgc3130 と呼ぶことにします)
磁場の変化をもとに手の動きを読み取るモジュールのようです。

関連商品として Skywriter HAT というものも並んでいます。
これもSeeed_mgc3130と似たようなモジュールで、こちら の記事でラズパイ版Minecraftを指で動かすところまで行われています。
Seeed_mgc3130はまだそのような使用体験を書いたものが無さそうだったので、上記記事と同様にMinecraftの操作ができるところまでやってみます。

電子工作は1年もやってない初心者ですががんばります。

マイコンの話

おそらくマイコンのことをあまり知らない人が多いと思うので、ざっくりと説明しておきます。

ArduinoやRaspberryPiなどのマイコンは、基板上のピンに電圧をかけたり、かかっている電圧を読み取ったりできます。
基本的に機能はこれだけですが、これができるといろんなことができます。

例えば、気温によって出力電圧が変わる温度センサーをアナログピンにつないで、電圧を読み取ることで温度を得ることができます。

もっと汎用的な使い方として、電圧のHIGH/LOWの高速な切り替えでデジタルな信号を表現することで、異なるマイコンやモジュール間で通信ができます。 小型液晶のモジュールなどはこういった通信で受け取った値を元にして表示するようになっています。

今回はRaspberryPiというマイコンを使います。このマイコンは上記のようなマイコンとしての基本機能に加えてLinuxというOSが動くという特徴があります。
その特徴を生かすことで、センサモジュールで読み取った値を元にtwitterとかslackとかに投稿するbotなんかも作れたりします。

warning
Raspberry Piにはアナログ値の入力機能はないので注意

ただ、高機能な分だけ値段も高めで、別途microSDカードやminiHDMI⇔HDMIケーブルも必要です。
熱も出るので放熱用のケースやファン、ヒートシンクなども必要です。
操作もLinuxなので初めて触る人には少し敷居が高いかもしれません。

info
Raspberry Pi Zeroという安価な種類もあるが品薄で入手難易度が高い

今回は使いませんが、ArduinoというマイコンだとTypeBやmicroUSBケーブル一本でPCと接続して操作でき、プログラムを書く環境もソフト一個インストールするだけで終わるので非常にらくちんです。
最近だと無線や小型液晶モジュールなどが標準搭載されたM5stackという種類もあり、Arduinoの開発環境を使えたりします。

使うもの

セットアップ

ラズパイのセットアップはこの記事のメインテーマではないので、詳細な操作は省きます。 Linuxの操作や設定について何か分からないことがあれば活発な部員のペンギンを頼りにしましょう。

基本的なセットアップが終わったら、I2C通信を有効にしておきます

Seeed_mgc3130を使えるようにする

まずはモジュールをラズパイに接続します。
今回使うSeeed_mgc3130はHATシールドと呼ばれるタイプで、ピンが並んだところに差し込むだけでOKです。

次に公式ページやライブラリのReadmeに書かれている通りに設定します。
(記述を省いていますが、一通りコマンドを打ち込むごとに cd でhomeに戻るようにしましょう)

# ncursesのインストール
wget https://invisible-mirror.net/archives/ncurses/ncurses-6.1.tar.gz
tar -xvf ncurses-6.1.tar.gz
cd ncurses-6.1/
./configure
make
sudo make install
ncurses6-config --version
# WiringPiのインストール
git clone https://github.com/WiringPi/WiringPi.git
cd wiringPi
./build

一通り設定が済んで、サンプルプログラムを動かすと以下のような感じで読み取った値が表示されます。

# Seeed_mgc3x30のサンプルプログラム
git clone https://github.com/Seeed-Studio/Seeed_mgc3x30.git
cd Seeed_mgc3x30
make clean && make

./mgc3130

 ************************************************************
 *                                                          *
 * Position X : 28306                                       *
 * Position Y : 0                                           *
 * Position Z : 34198                                       *
 *                                                          *
 * Gesture : North to South                                 *
 *                                                          *
 * Airwheel angle : 2272                                    *
 *                                                          *
 * Touch electrode : Center
 * Tap electrode :                                                                                                       *
 * Double Tap electrode :                                                                                                *                                                          *
 *                                                          *
 *                                                          *
 *                                                          *
 *                                                          *
 *                                                          *
 ************************************************************

モジュールの上10cmくらいで指を動かすとxyzが変化します。
また、タッチすると大まかなタッチ位置(中心と東西南北)、ダブルタップかどうか等が表示されます。

ボード上を良い感じの速度で横切った時は(South To North)みたいに出ます。判定されるにはちょっとコツが要ります。
ボード上でボードと平行な面上で指を良い感じの速度で回すと回転角が変化します。これも判定されるにはちょっとコツが要ります。

Seeed_mgc3130をPythonで使う

Python用のライブラリをgithubからcloneしてきて、説明の通りにインストールします。

git clone https://github.com/open-electronics/GestIC.git
cd GestIC/AppRaspberry/Librerie/MGC3130_Lib/V1_1_0_0/MGC3130
sudo python setup.py install

このライブラリをimportして使うのですが、 getX() みたいな値を取得する関数は用意されていないみたいなので、 モジュールから読み取ったbyte列から良い感じでxyzの値を取ってくるようにします。
ライブラリの実装を雰囲気で見た感じ、以下のような感じで値が取れるみたいです。

import sys
sys.path.insert(0, "/usr/local/lib/python2.7/dist-packages/MGC3130")
import MGC3130
from MGC3130 import *
import RPi.GPIO as GPIO
import time

# 初期設定
# なくてもいけるっぽい
MGC3130_SetAdd("/dev/i2c-1")
GPIO.setmode(GPIO.BCM)
MGC3130_Begin(GPIO, 8, 11)
# 礼儀正しく終わるときは呼び出す
# GPIO.cleanup()

while(True):
	# 読み取り
	MGC3130_GetEvent()
	# 生データから2byteずつ読み出し
	x = MGC3130._xyz.xyzArray[1] * 256 + MGC3130._xyz.xyzArray[0]
	y = MGC3130._xyz.xyzArray[3] * 256 + MGC3130._xyz.xyzArray[2]
	z = MGC3130._xyz.xyzArray[5] * 256 + MGC3130._xyz.xyzArray[4]
	print("{:>5},{:>5},{:>5}".format(x,y,z))
	time.sleep(0.01)

最初にSeeed_mgc3130との通信に使うピンの指定などをします。引数は回路図を見たりしつつ雰囲気で入れておきます。

GetEventを呼び出すとモジュールからbyte列を読みだしてなんやかんやしているようですが、このあたりに書いてあるように、取得した生のbyte列の20~25番目に(x,y,z)が2byteずつ入っているようです。
この6byte分は別途 MGC3130._xyz.xyzArray に格納されているのでそれを参照しています。

GetEventの実装上、検出した動きがないときはTelegram not managedがコンソールに出力されます。
このあたりは適宜ライブラリの該当箇所をコメントアウトするなどした方がよさそうです。

Seeed_mgc3130をMinecraftで使う

x,y,zの値が取れたので、この値をMinecraftの主人公の位置として反映させるようにします。

import sys
sys.path.insert(0, "/usr/local/lib/python2.7/dist-packages/MGC3130")
import MGC3130
from MGC3130 import *
import time
from mcpi.minecraft import Minecraft

mc = Minecraft.create()

while(True):
	MGC3130_GetEvent()
	x = MGC3130._xyz.xyzArray[1] * 256 + MGC3130._xyz.xyzArray[0]
	y = MGC3130._xyz.xyzArray[3] * 256 + MGC3130._xyz.xyzArray[2]
	z = MGC3130._xyz.xyzArray[5] * 256 + MGC3130._xyz.xyzArray[4]
	x = int(x/1024) - 32.5
	y = int(y/1024) - 32.5
	z = int(z/1024) + 0.5
	mc.camera.setPos(y,z,x)
	print("{:>5},{:>5},{:>5}".format(x,y,z))
	time.sleep(0.01)

Minecraftを起動してワールドに入った状態でこれを呼び出すと、指の動きに合わせて動くようになります。
(スペースキー2回押しで空中浮遊モードになっておかないと、位置更新の間に重力で下に移動してしまうので上下にガタガタ動いてしまいます)

反応が遅延しているような気がしますが、シビアな入力を要求されるものを操作してみないとどの程度遅延しているか判断しにくいです。
多少の遅延を誤魔化せるように慣性で移動するようにしてみたら、ちょっとは遊べそうな操作感になりました。

info
ラズパイ版Minecraftは機能縮小版なので敵とかは出てこない

今後の予定

RaspberryPiでとりあえず使えることは分かったので、今度はArduinoでやってみたい。
ArduinoのLeonardoという種類を使えばマウスになりきることができるので、擬似トラックパッドみたいなデバイスを作れそうな気がしている。 (実用性があるかどうかは一旦おいといて)

さいごに

プログラムが書けるとゲームやら解の探索やらbotの稼働やら何でもできるように思えますが、現実世界の物に干渉するためには電子工作は必須です。
今回のようにモジュールを繋ぐだけでも現実世界の情報を読み取れるようになります。モーターの制御とかやれば物を動かすこともできます。

電子工作は基本パーツ・ケーブル・マイコン・モジュール・用具といろいろ揃える必要があってお金がかかりがちなので、部活などでシェアできるとらくちんです。
部活内の競プロ熱がここ数年で盛り上がったように、電子工作も盛り上がったりしないかな...とこっそり思っています。

loading...