LoginSignup
20
7

More than 1 year has passed since last update.

Niantic Lightship ARDKの機能調査

Last updated at Posted at 2021-12-04

まずARDKの概要情報です

Lightship ARDKとは、「Pokemon Go」で知られるNianticが2021年11月8日から正式に提供を開始したUnityベースのARアプリ開発キットです。この記事ではその機能や実装してみて気づいたことなどをまとめています。

基本的には下記のドキュメントに乗っている情報を基に書いております。
https://lightship.dev/docs/

ARDKの機能要約

1. Mapping

  • ARアンカー
  • 深度推定

    • カラー画像入力から、カメラと映ったモノの距離を深層学習で推定。LiDAR深度データは使用されない
  • リアルタイム・メッシュ

    • 画像, カメラの向き, (LiDAR深度データ)からニューラルネットワークにより3Dジオメトリを生成
      • LiDAR搭載デバイスとそれ以外の場合の違い
        • IARWorldTrackingConfiguration.IsDepthEnabledの真否を変えると、下記表のような違いが生まれる
  • オクリュージョン
    深度を基に障害物があったら、3Dモデルを隠す

    • ARDepthManagerのOcclusionModeで調整可能

2. Understanding

index Channel名 メモ
0 sky 雲が含まれています。霧は含まれていません。
1 ground 人工地盤(下)のすべてのものと、土、草、砂、およびその他の自然地盤タイプが含まれます。
植生や葉が多い地面は地面として検出されず、代わりに葉として検出されます。
2 artificial_ground 道路、歩道、線路、カーペット、敷物、フローリング、小道、砂利、およびいくつかの競技場が含まれます。
3 water 川、海、池、湖、プール、滝、いくつかの水たまりが含まれています。飲料水、カップ、ボウル、シンク、バスの水は含まれません。
反射の強い水は水として検出されない場合があります。
4 building 近代的および伝統的な住宅および商業ビルが含まれます。
壁と同義と見なされるべきではありません。
5 foliage 茂み、低木、木の緑豊かな部分、鉢植えの植物、花が含まれています。
6 grass 背の高い草ではなく、芝生などの芝生の地面。

3. Sharing

  • マルチプレイ
  • 空間データの共有
    • セッション開始時は、その時点のデバイスの位置を原点とした各自の座標系を作成
    • Stable以降はホストの座標系に合わせて、デバイスや物の位置を補正する。

4. 開発ツール

Virtual Studio
アプリのビルド・デプロイに時間を費やさないようにテストするための環境

  1. Mock Mode
    仮想で部屋を作り、その部屋で開発したARのテストを行う

  2. Remote Mode
    スマホとPCを接続し、スマホのカメラで得た映像や深度を用いて、ARのテストを行う

リリース予定

料金体系

実装例

次は実装してみて重要そうだなと思ったことの羅列です

Virtual StudioのRemote Mode構築手順

Remote Feed Appのインストール

  1. ARDKExamples/VirtualStudio/ARDK Remote Feed App.Sceneだけをビルド
    • Build SettingsでAutoconnectProfiler, Develop Buildをチェック
  2. Remote Feed Appをインストール

Remote Feed AppとテストしたいSceneを開いたUnity Editorの接続

  1. PCとスマホを接続
  2. ARSessionを開始しているテストすべきSceneを開く
  3. Profilerでデバイスを選択
  4. Virtual StudioでRemote → USBを選択
  5. スマホでRemote Feed Appを開き、USBを選択する
    • 接続に成功すれば[Connected!]と表示される
  6. Unity Editorでテストしたい挙動を行う

MeshとSemantic Segmentation

Mesh

実装例
1. ARSessionManagerのあるシーンでARMeshプレハブを追加する

Semantic Segmentation

実装例
1. AR Semantic Segmentation ManagerをARSceneCameraプレハブに追加
2. 下記のようなスクリプトを記述

CheckSemantic.cs
        // Update is called once per frame
        void Update()
        {
            if (PlatformAgnosticInput.touchCount <= 0) { return; }

            var touch = PlatformAgnosticInput.GetTouch(0);
            if (touch.phase == TouchPhase.Began)
            {
                int x = (int)touch.position.x;
                int y = (int)touch.position.y;
                DebugLogSemanticsAt(x, y);
            }
        }

        //examples of all the functions you can use to interogate the procider/biffers
        void DebugLogSemanticsAt(int x, int y)
        {
            string[] channelsNamesInPixel = semanticManager.SemanticBufferProcessor.GetChannelNamesAt(x, y);
            foreach (var i in channelsNamesInPixel)
            {
                Debug.Log($"{i}");
            }
        }
    }
}

HLAPIとLocalization

メンバー同士での空間データの重ね合わせ

生成

位置同期

CosmosBehaviour.cs
//NetworkBehaviourを継承しているクラスでの関数です
protected override void SetupSession(out Action initializer, out int order)
{
    initializer = () =>
    {
        var auth = Owner.Auth;
        var descriptor = auth.AuthorityToObserverDescriptor(TransportType.UnreliableUnordered);

        // UnreliableBroadcastTransformPackerを作成するだけで、
        // Transform同期のためのブロードキャスト/受信が設定されます
        new UnreliableBroadcastTransformPacker
        (
           "netTransform",
            transform,
            descriptor,
            TransformPiece.Position,
            Owner.Group
         );
    };

    order = 0;
}
  • TransformType
    • Relieable → 99.95%の信頼性を保証, UnRelieable → 99%で受け取らなかったメッセージはドロップ
    • UnreliableUnorderedとUnreliableOrdered, ReliableUnordered とReliableOrderedがある

メッセージの送受信

  • 実装例
タグ付きでメッセージ
void PerformActionForAllPeers(IMultipeerNetworking networking, byte[] gameData)
{
  networking.BroadcastData(GameActionMessageTags.PerformSomeGameAction, gameData, TransportType.UnreliableUnordered);
}

void SubscribeToPeerDataReceived(IMultipeerNetworking networking)
{
  networking.PeerDataReceived += OnPeerDataReceived;
}

// Since the Hlapi also uses byte messages, this will be fired each time an object is NetworkSpawned as well
void OnPeerDataReceived(PeerDataReceivedArgs args)
{
  // Check that it is a message we care about, rather than an Hlapi message
  if(args.Tag != GameActionMessageTags.PerformSomeGameAction)
  {
    return;
  }

  // We now know this is the message that this class cares about, so use the data to perform some update
}

※タグはイベントデータであるPeerDataRecievedArgsの中で指定できるuint

タグ無しでメッセージ
private void OnDidConnect(ConnectedArgs connectedArgs)
{
  // ...
  // Continuing method from second code snippet...

  _hitStreamReplicator =
    new MessageStreamReplicator<Vector3>
    (
      "hitMessageStream",
      _arNetworking.Networking.AnyToAnyDescriptor(TransportType.ReliableOrdered),
      group
    );

  _hitStreamReplicator.MessageReceived += 
    (args) =>
    {
      Debug.Log("Ball was hit");

      if (_auth.LocalRole != Role.Authority)
        return;

      _ballBehaviour.Hit(args.Message);
    };
}

HLAPIの詳細(データの送受信の際に起きていることなど)

  1. FAQ
  2. NetworkFieldなどの実装例

その他注意点

  1. 精度

    • 下記動画のスマホのように位置のずれはあった
  2. 通信

    • サーバーメッセージの遅延は数百ms ~ 数千msになるが、ピアツーピアメッセージの遅延は数十msになる場合がある(デバイスの近さによって異なる)。
    • 下記の間にピアAからピアBにメッセージを送信した場合、ピアBはピアAをまだ有効なピアとしておらず、メッセージをドロップする。そのためPeerAddedイベントの度、数フレーム後に初期化メッセージが発生するようにするべき。
      • ピアA ← ピアBからPeerAddedイベントを受信 ピアB ← ピアAからPeerAddedイベントをまだ受信していない
    • 現在、同じピアとしてセッションに再参加することはサポートされていない。再参加した場合、デバイスは完全に新しいピアと見なされる。
      • ホストがセッションを離れる場合、新ホストは選択されない。ただし、ホストが検出したマップはセッションのタイムアウトまで残り、新しいピアは残ったマップに対してローカライズできる。
    • 全ピアが退出した後、30秒後にタイムアウトする。この時セッションに再参加しようとすると、意図しない動作が発生する可能性がある。

おまけ①: 2021年11月30日現在、難しかったこと

※ドキュメントでの記述がないことなので、真偽不明です

  • WindowsのUnityでビルド + XCodeでiPhoneにインストールしようとするとエラー
    →MacのUnityでビルド + XCodeでインストールすると大丈夫だった

  • Virtual Studioはどちらのモードでもリアルタイム・メッシュ機能が使えなかった
    →Depth機能とSemantic Segmentation, ネットワーク機能は使えた

  • URPのままVirtual Studio・Mock Modeにすると、仮想環境と認識させるためにARDK_MockWorldレイヤーを設定しているGameObject全てが見えなくなってしまった
    →その他ピンクシェーダーになる部分が多く、やはりまだ使うべきではなさそう

おまけ②: その他

  • Q. マルチプレイのメッセージ容量100MBで大きい。どう実装しているか。
    • A.
      • メッセージ
        • byte[] 10MB
      • 永続的なKey,Value
        • Key → string 4KB, Value → byte[] 100MB
        • セッションがアクティブな限り、サーバーに保存されるデータ
        • 更新されると各デバイスでイベントが発火する
        • セッション開始時に全員が得るべきデータを保存するなどの目的で使う
        • 実装例
      • ※データ制限について
20
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
7