Magic Leap で GPS 情報を疑似的に取得する!?

- Magic Leap Advent Calendar 2020 3日目 -

Nisho Matsushita
Cyber Brain Glasses

--

皆さんご存じのように、 Magic Leap デバイスには現状 GPS 情報を取得できるセンサーは搭載されていません。そんな Magic Leap で疑似的に GPS 情報を取得する方法を紹介します。

ただ実用するにはまだ問題があるので、今後解決すべき課題についても述べて、読者の皆さんのお知恵を借りられたらと思います。

追記

Magic Leap には WiFi 経由で GPS 情報を取得する Location API が存在します。筆者の確認不足でした。モバイル WiFi でも動作するかはわかりませんが、もし動作するならリアルタイムの GPS 情報取得が可能となるので、これから紹介する方法は必要なくなるかもしれません。

必要なもの

Immersal です。

どのように Immersal を Magic Leap のプロジェクトに組み込むかは、以下のエントリーで紹介しています。

実は Immersal では、スキャンした空間マップに GPS 情報が紐づけられていて、それを取得するための API が提供されています。今回はこれを利用して、疑似的に取得します。

GPS 情報とは?

一口で GPS 情報と言っても、実は色々な表現方法があるらしいです。ここでは Immersal が扱っている2つの方式について軽く紹介します。

  • WGS84 (World Geodetic System 1984)
    GPS と言われてぱっとイメージであろう緯度、経度、高度の3つの値によって表現されます。
  • ECEF (Earth-Centered Earth-Fixed)
    地球重心を原点として、xy 面を赤道面 にとり、x 軸正方向をグリニッジ子午線上の経度 0 度、y 軸正方向を東経 90 度、z 軸正方 向を xy 面に垂直な幾何学的北極点方向にとるような座標系によって表現されます。
WGS-84 準拠 ECEF 座標系

参考文献1 参考文献2 参考文献3

できること

Immersal SDK には2種類の API があります。

Unity Plugin として提供されいる Core Plugin API では Visual GPS functions が用意されており、自己位置を逐次 GPS 情報に変換する関数があります。

一方で、 Immersal Cloud Service を利用するための REST API では Map ECEF (GPS) が用意されていますが、対象の空間マップに紐付けられた ECEF 値しか取得できず、自分が動いたとしても更新されません。

Magic Leap では、現状後者の REST API にしか対応していないため、限定的にしか GPS が取得できないということになります。

REST API を使った ECEF 取得方法

以下に Map ECEF(GPS) の HTTP リクエストをするためのコルーチンスクリプト例を示します。

まずは SDKEcefRequest オブジェクトを作成し、ECEF をサーバに問い合わせる際必要な POST 情報を設定します。 token には自身の developer token で、 map には Immersal に保存しているスキャン済みの map ID を指定してください。どちらも Developer Portal にログインすると表示されます。 token を正しく記入しないと、データにアクセスできないので気を付けてください。

SDKEcefRequest を json 形式にコンバートしてから、 UnityWebRequest に渡します。URL には Immersal が事前に定義している string format に従って、ECEF 取得用の Endpoint.SERVER_ECEF を設定します。

最後には結果の json が返ってくるのを待ち、受け取ります。 SDKEcefResult にデコードすると、中に double の配列に ECEF 座標系の x, y, z 値が順に格納されていることを確認できます。

ECEF から WGS84 への変換(今後情報アップデートあり)

ECEF のままでも地球上での位置を表現できますが、やはり緯度経度情報を持つ WGS84 に変換したほうが何かと便利だったりもします。例えば Google Maps Platform Gaming Solution で現在位置のマップを表示したい!となったときには緯度経度を指定する必要があります。

Immersal の Core Plugin API では ECEF から WGS84 への変換関数 PoseEcefToWgs84 が用意されていますが、 Magic Leap では利用できません。

そのため無料で提供されている地理座標系変換ライブラリの CoordinateSharp の dll をプロジェクトに追加し、 ECEF.ECEFToLatLong 関数を利用し変換を試みました。

結果としては経度は本来の値と完全一致しましたが、緯度が日本付近の座標だと大体0.20°程度のずれが生じました。これは距離にすると 30-40km 程のずれで、とても正確な値とは呼べません。ちなみに本来の値としているのは、 Developer portal でマップに紐づいて表示されている緯度経度のことです。

Magic Leap でビルドせず、 Unity Editor 上で Core Plugin API のPoseEcefToWgs84 で変換した結果、緯度も正しく出力されたので、Immersal の変換方式が少し特殊なのではないかと思い至り、 Immersal に問い合わせた結果、後日変換部分の C# コードを提供してくれることになりました。公開もしてよいとのことだったので、いただき次第この項目を更新させていただきます。

今回は Immersal の REST API を使って、事前にスキャンしたマップを読み込んだときに、その ECEF 値をリクエストすることで、疑似的に Magic Leap でも GPS 情報を取得できることを紹介しました。

ただ、本来の GPS のように、自己位置に応じて逐次値が更新されるわけではないので、まだまだ実用は現実的ではありません。リアルタイムに値を更新したい場合は、「Unity 空間での相対移動値を WGS84 値に反映させる」ような関数が必要になります。読者の中でその方法に心当たりがある方は、ぜひコメントを残していただけるとありがたいです。

宣伝

2020年12月17日にMagic Leap Meetup vol.2 in Japan が オンラインで開催されます。参加費は無料ですので、興味がある場合はお気軽にお越しいただければと思います。詳細については以下をご覧ください。

--

--

Nisho Matsushita
Cyber Brain Glasses

AR/MR Developer of HoloLab Inc., AR/MR enthusiast, believing AR/MR will change the world. Interest in AR glasses like MagicLeap, HoloLens, etc.