memorandums

日々の生活で問題解決したこと、知ってよかったことなどを自分が思い出すために記録しています。

Quest3とArduinoでシリアル通信したかったんメモ(通信できず)

ゼミ生が卒研でVR流鏑馬システムを開発中です。

弓コントローラの製作にやっと入ったところで、弓コントローラに取り付け予定のマイコン(Arduino想定)とQuest3をシリアル通信させる話になりまして、そういえばやったことなかったなぁと思ったわけです。

昔、森山くんが作った以下のシステムもQuest2とハンドルコントローラを接続したのですが、このときはPCに接続して映像をOculus Linkで飛ばすというちょっと逃げの技を使っていました。プロトタイプとしては全然十分と思いますがやはり流鏑馬となると単体で動作した方がいいということで調査してもらっています。

www.youtube.com

僕も一緒にやっているので少し調べてみようと昨日夕方からごにょごにょ調べていました。なかなか難しかったです。。。Quest3を研究室に置いてきてしまっているので実働確認は取れていませんがとりあえず手順を忘れないうちにメモしておこうと書き出しています。

Questでシリアル通信するAssetはあるにはあるようですが有料なので試していません。UnityのアセットストアなのでQuestに対応(少なくともAndroidに対応)していないとダメと思いますが。。。仕事じゃないので有料使ってもなぁ。。。最悪、上記のOculus Linkでいいしとは学生さんとも話していたので。

Questでシリアル通信について言及した記事は以下くらいかと思います。大元のライブラリは別の方が開発されているのですが日本語で、かつ、扱いやすいラッパーまで考えている記事はこれだけだと思います。素晴らしい。。。ただ、既に3年前の記事です。そのまま動くか。。。というかそもそもAndroid Studioなにそれという学生さんにはこの記事を見ただけで再現するのは難しそうでした。

qiita.com

とりあえず色々と試行錯誤したメモを書いていきます。できあがったコードは上記の記事の著者の方のリポジトリをフォークしたリポジトリに置きました。

github.com

まず、情報源の整理をします。

もともとのライブラリの作者は@mik3y氏で、その方が開発したusb-serial-for-androidのリポがあり、そのリポをもとに上記のQiitaの解説記事を書かれたのが@hiro-han氏で、その方が記事に書いたことを反映したリポがusb-serial-for-androidです。

この2つのリポをもとに試行錯誤を始めました。Qiitaの記事では@mik3y氏のリポに、記事に書かれたことを変更しながら進めるという流れで書かれているのですが、コードが長くなるため省略されています。そのため、適宜、@hiro-han氏のリポを参照する必要があります。

最初、記事の通り、@mik3y氏のリポベースで作業を進めてみたのですが、途中でラッパークラスの追加が出てきてそのあたりが十分に説明されていませんでした。どこにどう追加すればいいのだろう?

じゃ、記事は参考程度に読んで@hiro-han氏のリポをクローンしてそれで自分用に書き換えればいいじゃん。。。と思ったのですが、@hiro-han氏のリポは3年前のためかgradleで色々とエラーが出ます。Android Studioの自動修正機能?を試しましたがうまくいかず。。。一方、@mik3y氏のリポはビルドが通るんですね。。。

そもそもAndroidプロジェクトの構成も忘れていたので、とりあえず試行錯誤的に調べて、@mik3y氏のリポベースに進めて、@hiro-han氏が追加したファイルを設定すればいいじゃん。。。ということで落ち着きました。@mik3y氏のリポは6ヶ月くらい前に更新されていました(build.gradleなど)ので、恐らく、新しいSDKに対応させて改訂したのではないかと思います。

では、行きましょう。上の記事を補間する感じで見てもらえたらと思います。つまり手順の完全性は保証しません(あくまで個人メモなので、いいわけです💦)。

Android Studioをインストールする

Android Studio とアプリツールのダウンロード - Android デベロッパー  |  Android Developers

@mik3y氏のusb-serial-for-androidをダウンロードする

git clone https://github.com/mik3y/usb-serial-for-android.git

ダウンロードしたディレクトリ名を変えておく(何でもいい、ここではm)

あとで@hiro-han氏のリポもダウンロードするため同名だと都合が悪いためです。

mv usb-serial-for-android m

Android Studio を起動して、mを開く

Android Studio が起動するとメニューが出てくるので、Openを選択し、そこで、ダウンロードしたmのトップディレクトリにたどり着いてボタンを押すだけ。

@hiro-han氏のリポをダウンロードする

git clone https://github.com/hiro-han/usb-serial-for-android.git

ダウンロードしたディレクトリ名を変えておく(何でもいい、ここではh)

mv usb-serial-for-android h

@hiro-han氏のUsbSerialWrapper.javaが欲しいので、mにコピペする

FinderとかエクスプローラでファイルをコピペするとAndroid Studioが認識しないみたい(ファイル名が赤く表示される、Eclipseみたいだな。。。)ので、Android Studioの左ペインのフォルダツリー上の当該位置にドラッグ&ドロップします。

コピペするものはusbSerialForAndroid/src/main/java/com/hoho/android/usbserial/wrapper 以下です。mの方にはwrapper以下はありませんのでwrapperごとusbSerialForAndroid/src/main/java/com/hoho/android/usbserial/にドラッグ&ドロップするとコピペできます。

ちなみにAndroid Studioでは左ペインの見え方を選択できるようで(開発に慣れたら不要な構造とか見たくないためなんでしょうね)、下図のようにProject Filesを選択するとFinderなどと同じようにツリー構造が見えるので安心かと思います。こんなこと知ってて当然でしょうね。。。開発者の方は。

あとは、ほぼ手順通りですが補間しながらメモ進めます。

device_filter.xmlを作成する

Android Studio上でusbSerialForAndroid/src/main以下でresというディレクトリを作成し、その下にさらにxmlというディレクトリを作成します。作成の仕方は、例えば、左ペインでusbSerialForAndroid/src/mainのmainアイコンを選択し右クリックしNewかな?を押してディレクトリを選択します。あとは名前をつけるだけですね。xmlディレクトリの下で同様に右クリでNewを選択して空ファイルだっけかな?を選択し名前をdevice_filter.xmlにして内容を貼り付けます。内容は元記事を読んでください。

ここで問題になるのがQuest3に接続するマイコンのUSBのベンダIDとプロダクトIDです。これはググればWindowsとMacの方法が見つかりますのでそれで頑張って見つけてください。それほど難しくないです。

私は中華のAndroid NanoなのでCH340になると思います。ここでなぜだという方はAIに聞いて下さい。以下がそれになるようです。16進数なので一応10進数になおしておきました。これら2つの値をxmlの該当箇所を修正しました。

ベンダーID:1A86 プロダクトID:7523

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <usb-device vendor-id="6790" product-id="29987" />
</resources>

Unityのclass.jarを追加

これは記事通りでいいですかね。。。ポイントはAndroid Studio上のファイルツリーにドラッグ&ドロップしてAndroid Studioに認識させることですね。Android Studioが警告を2つ出してきますがとりあえずYesという感じだったと思います。

usbSerialForAndroid/build.gradleの編集

元記事では30にするようですが、私の環境では35か36でした。36のSDKが入っていましたが36にするとワーニングがでるのでcompileSdkVersionは36に、targetSdkVersionは35にしました(→これでもワーニングがでますが)。あと、minSdkVersionを21にしないと怒られるようでした。あと、以下は重要です。これをつけないと元記事の通り、Unityのusingのところでエラーが出ます。

compileOnly fileTree(dir: 'libs', include: ['*.jar'])

どこにいれるかイメージがわからないと思いますのでとりあえず図を示しておきます。dependenciesの中では順番は関係ないと思いますが一番下に入れています。これを入れると、UsbSerialWrapper内のimport com.unity3d.player.UnityPlayer;がグレー化してコンパイル対象から外される様子でした。

ビルド設定

で、いよいよaarファイル(jarならぬaarですね)の生成ですね。これがね。。。元記事では「ライブラリをビルドします。成功すると.aarファイルが以下ディレクトリに出力されます。」とさらっと書かれています。へ?どうやってやるの?という感じになります。Android Studioでの開発に慣れていていると当然のことなのでしょう。

答えは(正しいかはわかりませんが)、下図のような感じになると思います。私はできました。①を押すとgradleのペインが右側に表示されるので、その中の②を押すとgradleコマンドを入力できる画面が出てきます。そこで③で「gradlew assembleRelease」と入力してエンターキーを押すとビルドが開始されます。成功すれば元記事の通り「usbSerialForAndroid/build/outputs/aar/usbSerialForAndroid-release.aar」が生成されます。

なお、UsbSerialWrapper.javaでエラーがいくつか出るはずです。私は3つくらい出たような記憶があります。API(SDK)が変わったため記述方法が変わったようです。Android Studioの修正ヒントが出るのでそれでいけそうですがなかなか全部は消えませんでした。もともとラッパークラスを作ったときに@hiro-han氏がやったように、usbSerialExamplesの中にあるコードを読んで近づけていくしかないと思います。ただ、具体的に処理内容がはっきりとわからないのでこのパラメタでいいのか?微妙なところはありますが。

一応、私の修正結果が以下にありますので参考にしていただければと思います。

github.com

しかたがなく、うまく行きませんでした。

Unityアプリの実装

あとは特別迷うところはなかったように思います。aarファイルをUnityプロジェクト内にコピペし、マニフェストファイル(Assets/Plugins/Android/AndroidManifest.xml)を作成して置きました。

Arduinoとの通信

ダメでした。。。なぜかダメです。元記事によるとマイコンをQuest3に接続すると接続するか?ダイアログが表示されるとありますが。。。出ません。Unityアプリはビルド成功しましたが起動してもすぐに落ちます。落ちる理由が知りたい。。。でもlogcatが使えない。USBケーブルがArduinoと繋がっていますから。。。どうやってデバッグすればいいんだろう?ログが見れればなぁ。。。とりあえず2日使いました。時間切れかなぁ。時間があったらまたやります。とりあえずこの辺で終えておきます。これだけやっているわけにはいかないので。。。

OTGケーブルかなぁ?でもPixelとArduinoはこのアダプタで繋がるからなぁ。。。Arduino Nano(CH340)がそもそも対応していないという話もあります。うーん。こまった。