WWDC Quick Look 💓 By SwiftGGTeam
visionOS のオブジェクトトラッキング強化を探る

visionOS のオブジェクトトラッキング強化を探る

元の動画を見る

ハイライト

visionOS 27 のオブジェクトトラッキングは、動的な手持ち物体の高フレームレート追跡、メートル法空間の座標、iOS でのクロスプラットフォーム実行に対応します。さらに LED、IMU、Bluetooth を使うサードパーティ製空間アクセサリ標準が公開され、開発者はボタンや触覚フィードバックを備えた物理入力デバイスを自作できます。

主要内容

静的な置物から手持ちツールへ

visionOS 2.0 のオブジェクトトラッキングには大きな弱点がありました。机の上に置かれた静的な物体しか追跡できなかったのです。手に取ったり、物体を素早く動かしたりすると、すぐに追跡が失われました。

(02:22) visionOS 27 では High Frame Rate Tracking が追加されました。Create ML の Extended Training Mode と組み合わせることで、システムは手持ち物体の動きをより安定して追跡できます。

セッションでは医療用プローブの例が紹介されました。医師が手持ちプローブを脊柱モデル上で動かすと、システムが椎骨間の距離をリアルタイムで計算します。このような場面は以前は実現できませんでした。手が物体の一部を隠し、静的トラッキングではすぐに対象を失っていたからです。

メートル法空間の座標:「見た目の整合」から「正確な測定」へ

(05:04) visionOS 2.0 のオブジェクトトラッキングには隠れた問題がありました。返される座標に表示補正が含まれていたことです。Apple は、ヘッドセット内で仮想コンテンツが物理物体と見た目上そろうように、座標へ微調整を加えていました。この補正は UI をレンダリングするには問題ありませんが、物理測定には致命的です。

visionOS 27 では Coordinate Space Correction API が追加されました。開発者は 2 種類の座標を選べます。

  • .rendered:表示補正を含み、仮想コンテンツのレンダリングに適しています
  • .none:純粋なメートル法空間の座標で、物理測定に適しています

この区別によって、オブジェクトトラッキングは「見た目を合わせるツール」から「精密測定ツール」へ変わります。

オブジェクトトラッキングが iOS に来る

(05:53) 今年、オブジェクトトラッキング API は正式に iOS に登場しました。トレーニング済みの .referenceobject ファイルは iOS と visionOS の間で共通に使えるため、同じモデルをクロスプラットフォームで再利用できます。

iOS の API は visionOS とほぼ同じです。参照オブジェクトを読み込み、ARWorldTrackingConfiguration を設定し、ARObjectAnchor のライフサイクルコールバックを処理します。

サードパーティ製空間アクセサリ:消費から創造へ

(07:25) visionOS 26 では、Logitech Muse や PSVR2 Sense コントローラのような公式認証済み空間アクセサリだけがサポートされていました。visionOS 27 では、この標準が完全に開かれます。

次の 3 つの条件を満たす電子機器なら、どれでも空間アクセサリになれます。

  • Vision Pro のカメラが追跡するための LED コンステレーション配列
  • 向きと加速度を提供する IMU
  • Vision Pro と通信する Bluetooth チップ

空間アクセサリは表示リフレッシュレートと同等の頻度で追跡でき、遅延も非常に低く、手で短時間隠れても追跡が続きます。アクセサリには物理ボタンや触覚モーターも搭載でき、インタラクションをより本物らしくできます。

セッションではステアリングホイールのアクセサリが示されました。物理的なステアリングホイールの内部に空間アクセサリを組み込むと、デジタル車両がホイールと正確にそろいます。ユーザーがホイールを握ると、本当に車に座っているように感じられます。

詳細

高フレームレートトラッキングを有効にする

(03:50) 高フレームレートトラッキングは、グローバルスイッチではなく、参照オブジェクトごとに設定します。

// 参照オブジェクト設定を作成
var configuration = ReferenceObject.Configuration()
configuration.highFrameRateTrackingEnabled = true

// 参照オブジェクトを読み込むときに設定を渡す
let refObjURL = Bundle.main.url(forResource: "flashlight", withExtension: ".referenceobject")!
let refObject = try? await ReferenceObject(from: refObjURL, configuration: configuration)

重要な点:

  • ReferenceObject.Configuration() は visionOS に追加された ARKit の新しい API です
  • highFrameRateTrackingEnabled はオブジェクトごとの設定であり、物体ごとに異なる追跡戦略を使えます
  • この設定は実行時に決まり、モデルを再トレーニングする必要はありません

Extended Training Mode

(04:50) Create ML には Extended Training Mode が追加され、手持ち物体の追跡精度と堅牢性を高められます。

コマンドラインでのトレーニング:

% xrun createml objecttracker \
    --source flashlight.usdz \
    --output flashlight.referenceobject \
    --training-mode extended \
    --all-angles

重要な点:

  • --training-mode extended は拡張トレーニングを有効にし、標準モードよりかなり時間がかかります
  • Extended Training Mode は高フレームレートトラッキングと組み合わせて使うことが推奨されます
  • コマンドライン方式はリモートマシンでのトレーニングにも対応します
  • --all-angles はすべての角度からトレーニングすることを意味します

メートル法空間の座標

(05:25) coordinateSpace(correction:) API により、開発者は座標精度の方針を選べます。

// 仮想コンテンツのレンダリング用に、表示補正済み座標を取得
let renderingPose = myObjectAnchor.coordinateSpace(correction: .rendered)

// 物理測定用に、純粋なメートル法空間の座標を取得
let metricPose = myObjectAnchor.coordinateSpace(correction: .none)

重要な点:

  • .rendered は表示補正後の座標を返し、仮想コンテンツは物理物体と見た目上そろいます
  • .none は物理世界の絶対座標を返し、いかなる表示補正の影響も受けません
  • 医療用プローブ測定、工業検査などの場面では必ず .none を使う必要があります
  • .none の座標をそのままレンダリングに使ってはいけません。見た目のずれが発生します

iOS 上のオブジェクトトラッキング

(06:22) iOS 27 の ARKit はオブジェクトトラッキングを完全にサポートします。

import ARKit
import RealityKit

class ObjectTrackingARSessionDelegate: NSObject, ARSessionDelegate {
    let arView = ARView(frame: .zero)
    var entities: [UUID: AnchorEntity] = [:]

    func start() throws {
        let stationaryObject = try ARReferenceObject(archiveURL:
            Bundle.main.url(forResource: "stationary", withExtension: "referenceobject")!)
        let movingObject = try ARReferenceObject(archiveURL:
            Bundle.main.url(forResource: "moving", withExtension: "referenceobject")!)

        let configuration = ARWorldTrackingConfiguration()
        configuration.detectionObjects = [stationaryObject]   // 低フレームレート、静的な物体
        configuration.trackingObjects = [movingObject]        // 高フレームレート、動的な物体

        arView.session.delegate = self
        arView.session.run(configuration)
    }

    func session(_ session: ARSession, didAdd anchors: [ARAnchor]) {
        for case let anchor as ARObjectAnchor in anchors {
            let entity = AnchorEntity(anchor: anchor)
            entities[anchor.identifier] = entity
            arView.scene.addAnchor(entity)
        }
    }

    func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
        for case let anchor as ARObjectAnchor in anchors {
            entities[anchor.identifier]?.isEnabled = anchor.isTracked
        }
    }

    func session(_ session: ARSession, didRemove anchors: [ARAnchor]) {
        for case let anchor as ARObjectAnchor in anchors {
            if let entity = entities.removeValue(forKey: anchor.identifier) {
                arView.scene.removeAnchor(entity)
            }
        }
    }
}

重要な点:

  • ARReferenceObject と visionOS の ReferenceObject は同じ .referenceobject ファイルを使います
  • detectionObjects は mostly stationary な物体に使い、追跡頻度は低めです
  • trackingObjects は移動する物体に使い、高フレームレートトラッキングを有効にします
  • didAdd / didUpdate / didRemove の 3 つのコールバックでアンカーの完全なライフサイクルを管理します
  • anchor.isTracked はエンティティを表示するかどうかを制御し、追跡が失われると自動的に非表示にします

空間アクセサリを発見して接続する

(12:26) 空間アクセサリは GameController フレームワークを通じて発見・接続します。

import ARKit
import GameController

// ペアリング済みの空間アクセサリを発見
if let device = GCSpatialAccessory.spatialAccessories.first {

    // ARKit が .referenceaccessory bundle を自動的に解析
    let accessory = try await Accessory(device: device)
    let provider = AccessoryTrackingProvider(accessories: [accessory])
    try await arkitSession.run([provider])
}

// 実行時にホットスワップ。session の再起動は不要
try await provider.updateAccessories([newAccessory])

重要な点:

  • GCSpatialAccessory.spatialAccessories はペアリング済みのすべての空間アクセサリを返します
  • Accessory(device:) はデバイス内の .referenceaccessory ファイルを自動的に解析します
  • AccessoryTrackingProvider はオブジェクトトラッキングの provider と似た使い方です
  • updateAccessories は実行時のアクセサリ切り替えに対応し、追跡 Session を中断しません
  • アクセサリメーカーは Info.plist.referenceaccessory を exported UTType として宣言する必要があります
  • サードパーティ開発者はアクセサリファイルを imported UTType として宣言し、App を独立して動かせます

重要な発想

1. 手持ち医療測定ツール

作るもの:医師がトラッキングされた手持ちプローブを使い、骨格モデル上でドリル位置を練習できる整形外科手術トレーニング App を作ります。

作る価値:高フレームレートトラッキングとメートル法空間の座標により、手持ちツールのミリメートル単位の位置特定が可能になります。以前は固定台上の手術ナビゲーションでしかこの精度を実現できませんでした。

始め方:Create ML の extended モードでプローブの reference object をトレーニングし、highFrameRateTrackingEnabled を有効にし、coordinateSpace(correction: .none) で実際の物理座標を取得して距離を計算します。

2. イマーシブなレーシングシミュレータ

作るもの:実物のステアリングホイールに空間アクセサリを組み込み、デジタルのレーシングカーと物理ホイールを完全に同期して回転させます。

作る価値:空間アクセサリは表示リフレッシュレートで追跡でき、遅延が非常に低く、物理ボタンと触覚フィードバックもサポートします。純粋な視覚トラッキングよりもはるかに良いステアリング体験になります。

始め方:DFRobot や MIKROE の既製ハードウェアキットで最初のプロトタイプを組み立て、GCSpatialAccessory で発見・接続し、AccessoryTrackingProvider で位置を追跡します。

3. 工業組み立てガイドシステム

作るもの:工場ライン上でオブジェクトトラッキングを使って部品を識別し、組み立て手順のガイドを重ねて表示します。

作る価値:オブジェクトトラッキングが iOS に来たことで、同じ reference object を iPad(現場指導)と Vision Pro(イマーシブトレーニング)の間で再利用できます。

始め方:USDZ モデルで部品の reference object をトレーニングします。iOS では detectionObjects を設定して静的認識を行い、visionOS では高フレームレートトラッキングを有効にして動的ガイドに使います。

4. 3D プリントしたマーカーで任意の物体を追跡する

作るもの:3D モデルを持たない日用品(手術器具や工具など)に 3D プリントした追跡マーカーを取り付け、低コストで追跡できるようにします。

作る価値:フォトリアルな USDZ モデルは不要です。物体に取り付けるマーカー部品を印刷するだけで追跡できます。これによりオブジェクトトラッキングの導入ハードルが大きく下がります。

始め方:独自のテクスチャを持つ 3D プリントマーカーを設計し、Create ML でマーカーの reference object をトレーニングし、追跡したい物体に固定します。

5. 複数アクセサリが協調する複合現実ゲーム

作るもの:複数の空間アクセサリを同時に追跡する MR ゲームを作ります。たとえば片手に銃、もう片手に盾を持つような体験です。

作る価値updateAccessories は実行時にアクセサリを動的に追加・削除できます。プレイヤーはゲームを再起動せずに持ち替えたり新しいデバイスを追加したりできます。

始め方:初期化時に主アクセサリへ接続して Session を開始します。プレイヤーが 2 つ目のアクセサリを手に取ったら、updateAccessories を呼んで追跡リストに追加し、アクセサリのボタンイベントでゲームアクションを発火します。

関連 Session

コメント

GitHub Issues · utterances