AR.jsのロケーションベースで方位が取れない？

## はじめに
最近、ずっと気になっていたAR.jsのロケーションベースARを触ってみました。
そこで躓いた部分があるので、ここに共有しておきます。

※今現在も原因がわかっていません。
　ご存じの方がいらっしゃいましたら、教えていただけますと嬉しいです。

ちなみに、私のテスト環境はiPhone12mini＋Safari/Chromeです。
OSバージョンは16.1.1、Safari/Chromeとも最新です。

## AR.jsとは
https://ar-js-org.github.io/AR.js-Docs/
Web AR用の軽量ライブラリです。
イメージトラッキング、ロケーションベースAR、マーカートラッキングの機能が提供されています。
高速、Webベース、オープンソースで、無料で利用できます。​

## WebARとは
WebARはブラウザで開くだけでAR体験ができるシステム（サービス）の総称です。
ユーザーの端末にアプリケーションをインストールすることなく手軽にARを体験できますが、
その分、ネイティブアプリより制限があり、コンテンツのリッチさでは劣る面もあります。
でも、幅広い層に、気軽に体験を与えることができるのは大変魅力的ですね。

## ロケーションベースのARとは
ロケーションベースのARでは、現実世界の場所（ロケーション）、主に緯度と経度を利用します。

* 使われるセンサ　GPS、加速度、磁気センサ など
* 使われる情報　　緯度経度、高度、方位 など

上記の情報を利用するので、ARマーカーは不要ですが、
端末の各種センサを利用するので、精度は端末に依存します。
GPSは障害物に弱いのでビル群などでは配置がズレやすいですし、屋内での利用も推奨されていません。

でも、ランドマークに３Dモデルを表示したり、ナビゲーションに利用したり…
って魅力的です！やってみたいですよね～

## 早速、試してみよう
AR.jsのライブラリには、イメージトラッキング、ロケーションベースAR、マーカートラッキングのそれぞれに、
描画に**A-Frame**を利用するものと**Three.js**を利用するものの２つのバージョンが用意されています。
まずはAR.jsを試してみたいという動機であればA-Frameの方が簡単に実装できる…くらいの認識でよいのかな？

ロケーションベース A-FrameバージョンのライブラリはA-Frameのコンポーネントを用意しているのですが、
現在、このコンポーネントは**new-location-based**、**projected**、**classic**３つのバリアントが用意されています。
公式ドキュメントによると

>* new-location-basedコンポーネント：
AR.js 3.4.0 以降で利用可能。さまざまなバグ修正が組み込まれ、より単純なコードが使用されます。
three.js APIのthin wrapperが提供されます。
ほとんどの用途に推奨されますが、内部実装が異なるため、古いコンポーネントのすべてのイベントをサポートしているわけではありません。
このバリアントは今後も開発される可能性が高く、古いバリアントはバグ修正以外の作業が行われる可能性は低いです。
>
>* projectedコンポーネント：
AR.js 3.3.1 以降で利用可能。classicコンポーネントとほぼ同じ内部実装を使用している。
「球状メルカトル図法への緯度/経度の投影」を提供する最初のもの。
>
>:::note info
>球状メルカトル図法は地球を平面とみなして投影する、Googleマップで使用されているものと同じ投影法です。
緯度と経度は球状メルカトルの東座標と北座標に投影されます。
球状メルカトル図法を使う理由は、道路などのより複雑な地理データを簡単に追加できるようにするためです。
また、球状メルカトル単位はメートルに近いため座標をWebGL/A-Frameワールド座標として直接使用できます。
>:::
>
>* classicコンポーネント：
AR.js 3.3.1 より前で利用可能。projectedコンポーネントに似ていますが、
緯度/経度と拡張現実に使用される投影座標との間を変換する機能を提供しません。

図にしてみるとこんな感じですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/913784/aad9fc54-90ab-a547-e9ef-388e865baea7.png)

ここは素直に、チュートリアルでも使用されていて、
公式のドキュメントでも推奨されている**new-location-based**コンポーネントを使用することにします。

## 問題発生
[公式のチュートリアル](https://ar-js-org.github.io/AR.js-Docs/location-based-aframe/)を素直に進めていったのですが…
問題が発生したのはココ。
**Introducing JavaScript with AR.js**の**Things to try**を実装し終わったところ。
Things to tryの内容は、
サンプルで実装した「現在地より0.001度北に箱を表示」するプログラムに
* 0.001度東に黄色の球
* 0.001度南にオレンジの円柱
* 0.001度西にマゼンダの円錐
 
を追加するというもの。

実装して動かしたものがこちら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/913784/d5debd35-f85a-8e7d-8480-afbe7295d17c.png) ⇒左に90度![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/913784/b7526b8a-3ad7-ace1-110c-356423138ff6.png)⇒左に90度![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/913784/c535f22e-6ecf-e497-6da9-913598237979.png)⇒左に90度![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/913784/1795076c-8fef-c1f0-4112-925710aa9b9b.png)

一見うまくいっていそうですよね。
何がおかしいかと言うと…

コレ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/913784/d5debd35-f85a-8e7d-8480-afbe7295d17c.png)
私は、**西(やや南）を向いてる**んです。

何度か試してみたのですが、
ブラウザを開いて初回読み込みされる時の向きを「北」と認識して処理しているようです…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/913784/b2865f49-853a-3bb7-2ef4-1d5ce1cdc252.png)
どこを向いても、初期方向は北。オカシイ…

## 結局どうしたのか？

Geolocation APIで方位を取得してみたり（いまいちでした…8割nullで返ってくる）
磁気センサで方位を取得できる方法を調べてみたり（調査期間が限られていたので、途中でやめました）

で、結局どうしたのかと言うと。

**過去のバリアントで実装しました。**

**classic**コンポーネントの場合
**projected**コンポーネントの場合
どちらも、方位がちゃんと取れていました（なぜ？）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/913784/81cb8235-0cc0-6852-860f-04138ef4d902.png)
西にマゼンダの円錐が出たよー

## ただし、次は別の問題が
classicでしか確認していませんが、今度は、イベントが来ません。

```Javascript:basic.js
el.addEventListener("gps-camera-update-position", e =>{
```
ココですね。

他の全イベントを試してみましたが
**何も発火しませんでした。**

↓これ試しました。[公式ページ](https://ar-js-org.github.io/AR.js-Docs/ui-events/)より
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/913784/e0dd1308-a567-6d7f-3f0c-8451ce908e38.png)

つまり、動的に現在地の緯度経度を用いて付近に拡張オブジェクトを表示！
が出来なくなりました。（HTML側から静的に配置するのは大丈夫。）

**gps-camera-update-position**イベントしか確認していませんが、
**projected**コンポーネントでもイベントは発火しませんでした。

## おわりに
今回はAR.jsのロケーションベースを試してみることが目的だったのでここまでの調査で終了しましたが、
なんとなく微妙な結果になってしまいました。

Three.jsのバージョンだと初期位置の設定が出来たりするのかなぁ、と思ったりしているので、
必要になればそのあたりも調査していけるといいのかなと思います。

執筆後のメモ：
調査当時思いつかなかったんですが、
AR.jsのバージョンを下げたらイベント発火するかもしれないですね。
時間が出来たら試してみたいと思います。