はつねの日記

Kinect, Windows 10 UWP, Windows Azure, IoT, 電子工作

Nreal Airを買ったので空中の立方体がくるくる回るアプリを作ろう

前回:
hatsune.hatenablog.jp

準備

開発環境

  • Unity 2021.3.14f1
  • Visual Studio 2022 (Community 2019なども可)
  • NRSDK 1.9.5

環境整備:詳細は前回参照

  1. NRSDKのインポート
  2. NRSDKのTipsのFix
  3. GraphicsAPI is not OpenGLES3の対応

新規プロジェクト作成

Unity Hubからプロジェクトの新規作成を行います。

オブジェクト配置:詳細は前回参照

  1. Hierarchyへのプレハブ(NRCameraRig、NRInput)の追加
  2. HierarchyからのMainCameraの削除
  3. HierarchyへのCubeの追加、位置や大きさの調整

C#エディタの設定

[Edit]-[Perferences]メニューから[External Tools]の[External Script Editor]で使用するVisual Studioを選択します。
VSCodeなども選べますが、今回は愛用している「Microsoft Visual Studio 2022」を選択しました。

アプリ作成

今回は、前回配置した立方体をくるくる回すアプリなので、くるくる回すためのスクリプトC#コード)を作成して、それを立方体に割り当てて動くようにしていきます。

スクリプトの作成

[Project]領域で[Assets]フォルダを選択してから、[Assets]-[Create]-[C# Script]メニューをクリックすると、[Assets]フォルダに「NewBehaviourScript」というファイル名でC#のコードを書くためのファイルが生成されます。
今回は、名前を「Interaction」とリネームして使います。

gist.github.com

くるくる回すコードを書く

Unityでオブジェクトをくるくる回す方法はいくつかありますが、今回は、Rigidbodyを追加してポインタが当たっている間だけangularVelocityに加速度を設定してあげることで回転させてみたいと思います。
gist.github.com

RigidBodyの追加

StartメソッドでRigidBodyをgameObject = スクリプトを割り当てたオブジェクトを追加しています。

this.Body = gameObject.AddComponent();
this.Body.useGravity = false;
this.Body.angularDrag = 0f;

これはオブジェクトに物理法則を割り当てることになるため、デフォルトのままだと重力が働いてオブジェクトが自由落下を始めてしまうため、useGravity = falseを設定しています。
また、angularDrag = 0fとすることで空気抵抗をなくして回転し始めたらずっと同じ速度で回転するようにします。

ポインタがあたっているときは回転する

Interactionクラスに「IPointerEnterHandler」インターフェースを追加して「OnPointerEnter」イベントがキャッチできるようにします。そのイベントが発生したときに呼び出される「OnPointerEnter」メソッドの中では、angularVelocityに対して、y軸に2の加速度を設定することで、くるくる回します。

this.Body.angularVelocity = new Vector3(0, 2f, 0);

ポインタがはずれたときは停止する

Interactionクラスに「IPointerExitHandler」インターフェースを追加して「OnPointerExit」イベントがキャッチできるようにします。そのイベントが発生したときに呼び出される「OnPointerExit」メソッドの中では、angularVelocityに対して、Vector3.zeroで加速度を0にすることで回転を停止します。

this.Body.angularVelocity = Vector3.zero;

くるくる回すコードをCubeに割り当てる

[Hierarchy]で「Cube」を選択して、「Cube」の[Inspector]を表示したら、そこに「Interaction」をドラッグ&ドロップします。
そうすると、「Cube」の[Inspector]に「Interacton(Script)」という項目が追加され、OnPointEnterとOnPointExitのイベントで「Interaction」クラスのコードが呼びされるようになります。

Unity Editor上での確認

プログラムが完成したら、Unity上で実行して動作を確認します。
ポインタの移動は、Shiftキーを押しながらのマウス操作で可能です。
ポインタがCubeに当たると回転し、外れると回転が止まります。

実機動作

一通り動作が確認できたら、実機をUSBで接続後に[Build Settings]で[Run Device]に実機を指定して[Build And Run]で実機転送します。
転送が完了したら、PCとのUSB接続ケーブルを外して、Nreal Airを繋いで起動します。
youtube.com
手元のAndroid端末を動かせばポインタも動くのでCubeに当てたり外したりして回転させてみましょう。

Nreal Airを買ったのでアプリを作る準備しよう

Nreal Airは、適合するAndroid端末に繋いで使用するARグラスです。
Amazon.co.jp: Nreal Air /ARグラス/スマートグラス/どこにでも持ち歩ける最大201インチ大画面/TUV認証取得(目に優しい)/ステレオサウンドのデュアルスピーカー/ノイズキャンセリングマイク/3DoF対応/EIS電子式アンチシェイク/専用アプリNebula対応/Type-C (DP ALT MODE)接続 : 家電&カメラ

最近、iPhoneやPCにも接続できるアダプターも販売が開始されました。
Amazon.co.jp: Nreal Adapter/NR-7100AGL / ARグラス/スマートグラス Nreal Air 専用/有線でデータ転送・変換 動画サービスやゲームの視聴をサポート/HDMI接続/iOS対応-Lightning端子はApple社純正Adapter別売 必要 : 家電&カメラ

iPhoneやPCでできるのはミラーリング表示と呼ばれるもので、画面表示そのままがNreal Airに表示されます。
このとき黒は透過されるので背景黒のアプリだと必要な情報が空中に浮かんでいるように見えます。
もちろんAndroid端末でもミラーリング表示は可能です。
この表示方式であれば、Nreal Air用にアプリを作成しなくて、既存のスマホアプリで色味を調整するだけでAR表示なアプリ動作が可能になります。

しかし!!
Nreal Airの実力を100%活用したアプリにするには、Nreal AirSDK(NRSDK)を組み込んだ専用アプリとして仕立て上げたほうがいいでしょう。

準備

Unityの準備

NRSDKはUnityやunrealから使用するので、まずは、Unityの環境を整えます。

Unity Hub

UnityのダウンロードサイトからUnity Hubをダウンロードします。
unity3d.com
ダウンロードしたUnityHub.exeを起動して、Unity Hubをインストールします。

Unityのインストール

Unity Hubを起動すると、まだUnity自体はインストールしていないので、Unityがないと表示されます。

そこでインストールボタンをクリックしてUnityのバージョンとして、2022/11/19現在の最新LTSである「Unity 2021.3.14f1」をインストールします。

必要なモジュールとしては「Android Build Support」となります。

もし、Visual Studioをインストールしていないのであれば、同時にインストールしましょう。すでにインストール済の場合は「Microsoft Visual Studio Community 2019」のチェックは不要です。

NRSDKの準備

入手

2022/11/19現在のNRSDKの最新は、Unity SDK 1.9.5「NRSDKForUnity_Release_1.9.5.unitypackage」となります。
developer.nreal.ai

はじめてのNreal Airアプリ開発

共通の準備

Nreal Airアプリ開発開始時に必要な手順をまず実施します。

新規作成

Unity Hubを起動して[プロジェクト]→[新規作成]をクリックします。

テンプレートの指定

テンプレートとして「3D」を選択して、プロジェクト名「NrealAirHelloWorld」として[作成]をクリックします。

プラットフォームの変更

Unityを起動してUnityの新規プロジェクトが作成されたら、[File]-[Build Settings]メニューから設定画面を開きます。

プラットフォームを「Android」に変更して[Switch Platform]をクリックします。

NRSDKのインポート

[Assets]-[Import Package]-[Custom Package]メニューからダウンロードした「NRSDKForUnity_Release_1.9.5.unitypackage」をインポートします。

インポートするものを選択するダイアログが表示されるので、[All]をクリックしてすべてを選択してから[Import]でプロジェクトにNRSDKを追加します。

インポートに成功していれば、[Project]領域の[Assets]に「NRSDK」が追加されます。

NRSDK実行環境を整える (TipsをFix)

[NRSDK]-[Project Tips]メニューをクリックして、NRSDKを使ったAndroidアプリ作成用の設定を実施します。

表示されたTipsはすべてFixします。

NRSDK実行環境を整える (手動設定)

ただし、今回のバージョン構成だとどうしても1つだけTipsがFixできません。
それが「OpneGLES3」を有効にするTipsです。
このTipsは、[Build Settings]の中の[Player Settings]の[Android]-[Other Settings]の項目への設定なので、[Auto Graphics API」チェックを外して、「ES3.1」「ES3.1+AEP」「ES3.2」のチェックを付けると、「OpneGLES3」のTipsもリストから消えます。

これをやっておかないと実機でオブジェクトが表示されないので確実にやっておきましょう。

プレハブ追加

[Project]からAssets > NRSDK > Prefabsを開きます。

「NRCameraRig」と「NRInput」を「Hierarchy」にドラッグ&ドロップします。

「MainCamera」は不要なので削除します。

Cubeを表示する

共通設定が完了したら、ARグラスアプリのHello Worldともいえる空中に浮かんだCubeを表示するアプリを作ります。

Cubeを追加

「Hierarchy」を右クリックして、[3D Object]-[Cube]メニューをクリックしてCubeを追加します。

Cubeの位置と大きさを調整

初期位置ではカメラと重なってしまうので、「Hierarchy」で「Cube」を選択して、その「Inspector」でPositionを(0, 0, 3)=3m先の位置、Rotationを(30, 30, 0)、Scaleを(0.5, 0.5, 0.5)にして配置します。

これでNreal Airを付けた時に目の前の空中に立方体が浮かぶことになります。

実機デバッグ

実機準備

Android実機側では、まずは「開発者モード(Developer mode)」に変更して、さらに「USBデバッグ」ができるようにしておきます。

実機接続

Android実機側の準備ができたらUSBにて接続します。
準備がうまくできていると、ここで「USBデバッグを開始する」のようなダイアログが表示されるので、かならず「OK」をクリックします。

Unity側設定

[Run Device]には接続した実機を選択します。
[Development Build]と[Script Debugging]にもチェックをいれておきます。

実機実行

[Build And Run]をクリックして、ビルドと実機転送、そして実行を行います。
ただし、転送まで成功してもそのままデバッグ実行にはならず、Android端末には「Nebulaを利用するには、Nrealグラスと接続してください」と表示されます。

Nreal Airを付けての実行

そこで、PCと接続されているUSBケーブルを外してNreal Airに繋ぎ変えて実行するとUnityの[Game]で表示されていた表示とそっくりな表示が空中に浮かびあがります。

次回はポインタ操作など操作にチャレンジする予定です。
hatsune.hatenablog.jp

Microsoftの製品ドキュメントはdocsからlearnへ

Microsoftの製品ドキュメントは、docs.microsoft.com~というサイトで参照できましたが、learn.microsoft.comと先頭がlearnに変わっています。

learnといえば今までは学習コンテンツが充実していて、認定試験対策などでよく使っていて、以前は、docsのなかにlearnがあったと思うのですが、これからはlearnの中にdocs(というカテゴリ自体なくなっていますが)という形になりますね。

ほんの些細なことかもしれませんが、学習体験というものを重視するという心意気の現れなのかもしれませんね。
learn.microsoft.com

いよいよMicrosoft Ignite 2022が来週に迫ってきました。

北米現地時間で10/12~13、日本時間で10/13~10/14にMicrosoft Ignite 2022が開催されます。
ignite.microsoft.com
シアトル現地とオンラインのハイブリット開催となっています。
現地開催は、本当に久しぶりですね。
まずは、日本時間の10/13 01:00からの基調講演が楽しみです!
日本時間での再放送もあるようなので、オンラインでもぜひ皆さん情報収集を!

M5StickC Plusで.NET nanoFrameworkからGROVE端子を使ってみた

前回

hatsune.hatenablog.jp
前回はNTPを使った時刻合わせと表示の方法について紹介しました。
今回は、HY2.0-4P(GROVE端子)を.NET nanoFrameworkから使う方法について紹介します。

事前準備

センサーについて

この記事で使用するセンサーは、M5StackユニットのENV-IIIを使います。
GROVE規格なのでM5StickC PlusのHY2.0-4P端子に接続できます。
ENV-IIIは、気圧センサーとしてQMP6988、気温と湿度のセンサーとしてSHT30を内蔵したユニットとなります。
ENV-IIIとM5StickC Plusを接続し、更にM5StickC PlusをUSBでPCに接続して、準備完了です。

Install the nanoFramework firmware

M5StickC PlusにはnanoFrameworkは標準インストールされていないので、nanoFrameworkをインストールします。

接続ポート番号の確認

USBでM5StickC PlusをPCに接続したら、USB Serial Portのポート番号を確認します。今回の環境では「COM6」が該当しました。

Flasherアプリケーションのインストール

OSの[スタート]メニューから「Developer PowerShell for VS2022」を起動します。

dotnet tool install --global nanoff

nanoFrameworkfファームウェアをインストール

M5StickC Plusをターゲットにして「COM6」経由でnanoFrameworkをアップロードします。

nanoff --target M5StickCPlus --update --serialport COM6

Visual Studioの準備

Visual Studioを機能拡張する

Visual Studioには.NET nanoFramework Extensionをインストールして機能拡張しておきます。
この機能拡張によりnanoFrameworkアプリのテンプレートが追加されます。
このテンプレートで作成したプロジェクトには、NuGetから自動的に「nanoFramework.CoreLibrary」ライブラリが追加されています。

「nanoFramework.M5StickCPlus」ライブラリを追加する

M5StickC Plusの画面などハードウェアにアクセスするために、M5StickC Plus用のライブラリを追加します。

ここまでが、M5StickC Plusを使うアプリ開発を行う上での共通の事前準備となります。

M5StickC Plusで気温と湿度の表示(SHT30)

ライブラリの追加

.NET nanoFrameworkにはSHT30用のライブラリである「nanoFramework.Iot.Device.Sht3x」がNuGetで提供されています。
.NET nanoFramrworkアプリケーションテンプレートで新規プロジェクトを作成したら、NuGetでSht3xライブラリを追加します。

SHT30から気温と湿度を取得して画面に表示するC#コード

ENV-IIIのI2Cアドレスを調べる

I2Cシリアル通信では、端子につながっている機器から特定のセンサーを指定するために「アドレス」を指定します。
ENV-IIIの中のSHT30と接続するためにアドレスに指定する値は、ENV-IIIの仕様書をみると書かれています。
ENV III Unit with Temperature Humidity Air Pressure Sensor (SHT30+QMP6988) | m5stack-store

I2C interface (SHT30:0x44 , QMP6988:0x70)

このアドレスを指定してI2C通信を行うことでSHT30より気圧値を取得できます。
Grove端子との通信では次のようなコードでI2C通信経路を確立できます。
gist.github.com

センサー値を取得する

センサー値を取得するためには次のようなコードになります。

WriteLine($"Temperature:{Sht.Temperature.DegreesCelsius:F} C");
WriteLine($"Humidity:{Sht.Humidity.Percent:F} %");

単位ごとのメソッドが用意されているので、℃で気温を得たいときは「Temperature.DegreesCelsius」メソッド、湿度を%で多いときは「Humidity.Percent」メソッドを使います。

M5StickC Plusで気圧表示(QMP6988)

SHT30から温と湿度を無事取得できたので、次は、QMP6988から気圧を取得します。

ENV-IIIのライブラリを調べる

SHT30については「nanoFramework.Iot.Device.Sht3x」ライブラリが使えますが、QMP6988を使うためのライブラリは2022年8月現時点ではNuGetに公開されていません。
そこで自作でQMP6988用のクラスを作成しました。
IoT.Devices.Qmp6988.cs · GitHub
詳しくは、以前の記事を参照してください。
hatsune.hatenablog.jp

ENV-IIIのI2Cアドレスを調べる

ENV-IIIのQMP6988のアドレスは仕様書から「0x70」なのでそれを指定して通信を確立します。

Qmp = new(M5StickCPlus.GetGrove(0x70))

センサー値を取得する

全体的なコードは次のようになります。
gist.github.com
センサー値の取得部分は次のところです

Console.WriteLine($"DateTime:{DateTime.UtcNow:yyyyMMdd HHmmss}");
Console.WriteLine($"Pressure:{Qmp.CalcPressureHectopascals():F} hPa");
Console.WriteLine($"Temperature:{Sht.Temperature.DegreesCelsius:F} C");
Console.WriteLine($"Humidity:{Sht.Humidity.Percent:F} %");

M5StickC Plusでの動作

ENV-IIIから気圧、気温、湿度を取得するコードが完成したので、Visual Studioで[デバッグ]-[デバッグの開始]メニューでM5StickC Plusへの転送と実行を行います。
時間とセンサー値が1秒ごとに更新表示されます。

.NET nanoFramework ExtensionとVisual Studio 2022をすぐに更新して最新にしよう!

北米8/16(日本時間で8/17)に「Visual Studio 2022 version 17.3.1」がリリースされました。
同時に.NET nanoFramework Extensionも「.NET nanoFramework VS Extension v2022.2.0.33」に更新されました。
ここ数日、実は.NET nanoFrameworkのプロジェクトをVisual Studioで読み込むと、予期しないエラーが発生するようになりました。
gist.github.com
一応はビルドやデプロイもできるのですが、インテリセンスなどが効かないなど不具合は発生していました。

Visual Studio側を17.3に上げたのが原因だとは思っていたのですが、アンインストールして意図的に1つ前のバージョンをいれてとか少々面倒に感じでインテリセンスなしでコードをかいていました。
でも、インテリセンス……ないとすんごく不便ですね。

そんな悩みを抱えていたのですが「Visual Studio 2022 version 17.3.1」が本日
リリースされました。
docs.microsoft.com
こちらを提供して更に「.NET nanoFramework VS Extension v2022.2.0.33」に更新すれば、プロジェクトファイル読み込み時の予期せぬエラーも解消されて、インテリセンスが戻ってきました。

よかった~。