バナーナナブログ

宮城県仙台市より、日々思ったことを綴っていくウェブログです。

RaspberryPi4でSwitchをBluetooth制御してイイ感じに自動操作する

はじめに

どうも。

昨年の年明け早々にArduinoの存在を知り疑似コントローラーでの自作プログラムで色々なことを自動化させていましたが、こんな記事が出てたんですね。

qiita.com

筆者さんの名前みたことあるなーと思ったらそれもそのはず、私がArduinogithubリポジトリをフォークさせて頂いた方でした。控えめに言って神だと思う。
Bluetooth使ってPCで疑似コントローラー作る勢が盛り上がってるぜ、と。
記事の中で動画をつかってデモしてくださっています。

これをみて私は思いました。

 「そういえば最近やっすいビデオキャプチャでも普通に使えると聞いたな。やってみよ。」
すぐに私は買い物をしました。
f:id:smdbanana:20210113223657j:image

 Bluetoothアダプタとビデオキャプチャ、それとhdmiスプリッターです。

 Bluetoothアダプタは、私のPC(ASUSのUX430U)だと仮想ubuntuで内蔵BTアダプタをフィルタ利用すると、Switchのjoycon接続の途中でエラーを吐いて中断してしまったから購入しました。 

コイツを使ったところ、Switchに問題なく繋がりました。ELECOMだしいいだろ、くらいの感覚で買いましたが繋がってくれてよかった。

ビデオキャプチャは以下を選択。

もっと安いやつはありましたが、なんとなくケーブル部がある方が取り回しいいしレビューも(ほぼサクラだろうが)多いのでこれにしました。

結論から言うと、私のVirtualBox経由のubuntu環境では信号が正しく得られない現象が発生し、うまく動作しませんでした。ただ、ホストPC(Windows)とかRaspberryPiでは問題なく動作したのでまあ良しとします。

最後はスプリッター。

1入力2出力が意外と種類少なくかつ海外製ばっかりだったので悩みましたがこれもレビュー数が多かったのでコレにしました。Switch→コレ→キャプチャ&モニターに使う想定で買いましたが、これも特に問題なし。

途中に書いた通り、仮想のUbuntuにキャプチャのUSBのフィルタがうまいこと設定できず、全てを仮想Ubuntuでクローズすることは出来ない状況でした。

そこで、タイトルにある通り仮想マシンではなく、RaspberryPi4を活用しようと思ったのです。

ラズパイOSの書き込み

OSの書き込みには公式のimagerを使います。

Raspberry Pi OS – Raspberry Pi

私が利用したのはv1.5です。

f:id:smdbanana:20210113231021p:plain

ubuntu desktop 20.10 を選択しました。
書き込みが完了したら再度SDを挿入し、boot領域からconfig.txtをいじっておきます。

hdmi_force_hotplug=1
hdmi_group=1
hdmi_mode=16

https://raspberrypi.stackexchange.com/questions/107044/how-do-you-make-the-hdmi-hot-pluggable-on-a-pi

ここに書いているものを参考にしました。
ラズパイにモニター繋ぐのは初回だけで、あとはssh or リモート接続にしたかったからです。上記対応をしておかないと、ラズパイ起動時にhdmi出力先が見つからないとVNCで接続ができません。

SDをPCから外してラズパイに装着。起動します。

Ubuntuのセットアップ 共通編

ほぼ全てデフォルトとスキップでデスクトップ画面表示まで飛びます。
唯一気を付けておくのは、ユーザ登録時に「自動ログイン」にしておくこと。
(あとから変更できるけど)

f:id:smdbanana:20210113233319p:plain

ゴリラです。
ということでとりあえずトップ画面表示までは省略。

次はツール群の更新。

// 起動後に更新関係を実施
$ sudo apt update
$ sudo apt upgrade
// 再起動
$ sudo shutdown -r now

ssh接続できるようにする。

// sshできるようにする
$ sudo apt install openssh-server
$ sudo systemctl start ssh

GUI接続環境も欲しいので設定しておく。

f:id:smdbanana:20210113234445p:plain

Settings→Sharing画面で上部unlockしたらScreen Sharingをオンにする。
設定できたらターミナルから以下対応。

// IP確認してリモート用ポートチェック、あと暗号化無効
$ ip a
$ sudo lsof -i:5900
$ gsettings set org.gnome.Vino require-encryption false

これでMACから

vnc://ラズパイのIP:5900

 にアクセスできるようになるはず。
(MACなら暗号化無効はいらない、みたいな記事みたけど私の環境ではそうはいかなかった。)

次は日本語化。

f:id:smdbanana:20210113234542p:plain

Settings→Region&Language画面を開き、下部にある「Manage Installed Languages」を押下する。すると
「言語サポートが完全にはインストールされていません」とダイアログでてくるのでインストールを実行。その後再起動すれば日本語化してるはず。
右上の言語選択から日本語(Mozc)を選べば日本語入力もできる。

以上

Ubuntuのセットアップ Joycon操作編

といっても、先程紹介の記事にあるコマンドを打つだけ。

$ wget -O - https://bit.ly/3geP7Gv | sh
$ cd joycontrol-pluginloader/
$ sudo joycontrol-pluginloader plugins/tests/PairingController.py

問題なく接続できることを確認。
接続成功していれば、実行ログからでなくともMACアドレスは確認できます。

$ sudo bluetoothctl
[bluetooth]# paired-devices
Device XX:XX:XX:XX:XX:XX Nintendo Switch
[bluetooth]# exit

ということで、あとはプログラムのお作法を理解すれば自分好みの自動制御ができます。けど、せっかくビデオキャプチャもあるんだし、もうちょっとリッチに自動操作したいと思ったのです。

そうだ、画像処理させよう。

OpenCVを使えば、ある程度のことは割と簡単にできます。
インストールは以下手順で実施しました。

$ sudo apt install python3-dev python3-pip python3-setuptools
$ sudo apt install libopencv-dev opencv-data
$ sudo python3 -m pip install opencv-python

卵孵化のプログラムを見ると、孵化サイクルを指定してサイクル分時間経過させています。
ここの部分をサイクル消費を時間で計算するのではなく、自転車を走らせている中で画像をチェックし続けて

f:id:smdbanana:20210114010915j:plain

これが出てきたら卵が孵化する合図だぜ、と判定してやればいいよな。
ということでサンプルコードはこんな感じ。

OpenCVを使ってビデオキャプチャの画像が指定の画像と類似するか

たとえば自転車を走らせて「おや……?」のメッセージが出たとき

f:id:smdbanana:20210114011411j:plain

$ python3 HatchMsgCheck.py
Hatched !!!! ret is 4799

こんな感じで結果が出ます。
40x120=4800が完全一致ですがそうなっていないのはjpgだからでしょう。
ちなみに孵化後の画像とかであれば

f:id:smdbanana:20210114011711j:plain

$ python3 HatchMsgCheck.py
Not Hatched. ret is 2675

みたいに既定値を下回ったものになります。

他にも色々マッチング方法はあるでしょうが、私はこれで十分でした。

そうだ、文字認識させよう。

ついでですが、せっかく画像処理するんだったら文字認識もさせてしまおうかと思います。

$ sudo apt install tesseract-ocr libtesseract-dev libleptonica-dev pkg-config
$ sudo python3 -m pip install tesserocr
$ sudo wget https://github.com/tesseract-ocr/tessdata_best/raw/master/jpn.traineddata -O /usr/share/tesseract-ocr/4.00/tessdata/jpn.traineddata
$ sudo wget https://github.com/tesseract-ocr/tessdata_best/raw/master/jpn_vert.traineddata -O /usr/share/tesseract-ocr/4.00/tessdata/jpn_vert.traineddata

bestを選択しているのは何となくです。何となくではありますが精度は高まっていると思います。
ラッパーライブラリは何となくでtesserocrにしました。
ではこっちもサンプルを。

OpenCVとTesseractを使ってポケモンの特性を文字認識する

とりあえず思いついたのが、特性を指定しておいて一致してるかの判定をする、というもの。他はV位置チェックとかでしょうか。

f:id:smdbanana:20210114021247j:plain

このキャプチャ画像に対して特性部分

f:id:smdbanana:20210114021323j:plain

これですね。切り取った画像をOCRかけてやります。
で、結果はこんな感じ。

$ python3 AbilityOcrCheck.py
ほのおのからだ

うん。思惑どおり。いい感じです。

 

さいごに

3月にモンハン新作がやってくるので、それに向けて色々準備をしておきたかったのでした。
今回色々やってみて、改めてポケモンって色々と勉強するのにとてもいい教材だと思いました。 

では。また。