Jetpack XR 向け ARCore の Geospatial API を使用すると、アプリで Google ストリートビューがカバーする任意のエリアにコンテンツをリモートで添付し、グローバル規模で AR エクスペリエンスを作成できます。Geospatial API は、デバイスのセンサーと GPS のデータを使用してデバイスの環境を検出し、その環境の認識可能な部分を Google の Visual Positioning System(VPS)が提供するローカライズ モデルと照合して、ユーザーのデバイスの正確な位置を特定します。また、API はユーザーのローカル座標と VPS の地理座標を統合して、単一の座標系で作業できるようにします。
ARCore API を有効にする
アプリで Visual Positioning System(VPS)を使用する前に、新規または既存の Google Cloud プロジェクトで ARCore API を有効にする必要があります。このサービスは、Geospatial アンカーのホスティング、保存、解決を行います。
追加のライブラリの依存関係を追加する
Geospatial API を使用するには、追加のライブラリ依存関係が必要です。アプリの build.gradle.kts ファイルに次の行を追加します。
Groovy
dependencies { // ... Other required dependencies for the Jetpack XR SDK implementation "com.google.android.gms:play-services-location:21.3.0" }
Kotlin
dependencies { // ... Other required dependencies for the Jetpack XR SDK implementation("com.google.android.gms:play-services-location:21.3.0") }
必要な権限をリクエストする
Jetpack XR で ARCore の Geospatial API を使用するには、アプリで次のランタイム権限をリクエストする必要があります。
ACCESS_INTERNET: ARCore Geospatial API クラウド サービスに接続するために必要です。ACCESS_COARSE_LOCATION: ユーザーのおおよその位置情報を特定するために必要です。ACCESS_FINE_LOCATION: ユーザーの正確な位置情報を特定するために必要です。
アプリの権限を宣言する
実行時にこれらの権限をリクエストするには、アプリのマニフェストで宣言する必要があります。
<manifest ... >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
</manifest>
権限をリクエストする
必要な権限を宣言したら、アプリは実行時にそれらの権限をリクエストする必要があります。アプリに権限が必要な理由を説明するようにしてください。
Geospatial API は、ユーザーの正確な位置を特定できないと機能しません。そのため、アプリに ACCESS_FINE_LOCATION 権限と ACCESS_COARSE_LOCATION 権限の両方を付与できるように、実行時に位置情報権限をリクエストするためのガイダンスに沿ってください。
セッションにアクセスする
Jetpack XR Runtime Session を通じて地理空間情報にアクセスします。アプリで作成する必要があります。
セッションを構成する
XR セッションでは、デバイスのポーズ情報はデフォルトで有効になっていません。アプリがデバイスのポーズ情報を取得できるようにするには、セッションを構成し、GeospatialMode.VPS_AND_GPS モードと DeviceTrackingMode.LAST_KNOWN モードの両方を設定します。
// Define the configuration object to enable Geospatial features. val newConfig = Config( // Set the GeospatialMode to VPS_AND_GPS. geospatial = GeospatialMode.VPS_AND_GPS, // Set the DeviceTrackingMode to LAST_KNOWN. deviceTracking = DeviceTrackingMode.LAST_KNOWN ) // Apply the configuration to the session. try { when (val configResult = session.configure(newConfig)) { is SessionConfigureSuccess -> { // The session is now configured to use the Geospatial API. } else -> { // Handle other configuration errors (e.g., missing library dependencies). } } } catch (e: UnsupportedOperationException) { // Handle configuration failure if the mode is not supported. }
GeospatialMode.VPS_AND_GPS モードでは、視覚測位システム(VPS)と全地球測位システム(GPS)の両方のデータを活用して、デバイスの地理空間位置を正確に特定します。
すべての XR デバイスが GeospatialMode.VPS_AND_GPS モードと DeviceTrackingMode.LAST_KNOWN モードをサポートしているわけではありません。Session.configure() が成功した場合、デバイスはこれらのモードをサポートします。
デバイスデータの使用を許可するようユーザーに求める
Jetpack XR 向け ARCore で Geospatial API を使用するアプリは、デバイスのデータの使用を承認して許可するよう求めるプロンプトをユーザーに表示する必要があります。詳しくは、ユーザーのプライバシーに関する要件をご覧ください。
Geospatial オブジェクトを取得する
セッションを構成したら、Geospatial.getInstance(session) を使用して Geospatial オブジェクトを取得します。
// Get the Geospatial instance for the current session. val geospatial = Geospatial.getInstance(session)
Geospatial オブジェクトは、状態が State.RUNNING の場合にのみ使用する必要があります。Geospatial.state StateFlow<Geospatial.State> を使用して状態をモニタリングできます。
VPS の可用性を確認する
Geospatial API は VPS と GPS を組み合わせて Geospatial ポーズを特定するため、デバイスが位置を特定できる場合はいつでも API を利用できます。屋内や密集した都市環境など、GPS の精度が低いエリアでは、API は VPS カバレッジを利用して高精度のポーズを生成します。
一般的な条件下では、VPS は約 5 メートルの位置精度と 5 度の回転精度を提供します。Geospatial.checkVpsAvailability(latitude, longitude) の suspend 関数を使用して、VPS の対象地域かどうかを確認できます。この呼び出しは非同期オペレーションであり、セッションを GeospatialMode.VPS_AND_GPS モードで構成する必要はありません。
次のコードは、指定された緯度と経度から VPS の可用性を確認する方法を示しています。
// You can query the GPS to get the current device's location. val latitude = 37.422 val longitude = -122.084 // Use the geospatial instance to check VPS availability for a specific location. val result = geospatial.checkVpsAvailability(latitude, longitude) when (result) { is VpsAvailabilityAvailable -> { // VPS is available at this location. } is VpsAvailabilityErrorInternal -> { // VPS availability check failed with an internal error. } is VpsAvailabilityNetworkError -> { // VPS availability check failed due to a network error. } is VpsAvailabilityNotAuthorized -> { // VPS availability check failed due to an authorization error. } is VpsAvailabilityResourceExhausted -> { // VPS availability check failed due to resource exhaustion. } is VpsAvailabilityUnavailable -> { // VPS is not available at this location. } }
アプリが Google Cloud の ARCore API と通信するように正しく設定されている必要があります。そうでない場合、アプリは VpsAvailabilityNotAuthorized 結果を受け取ります。
デバイスのポーズを地理空間のポーズに変換する
デバイスのポーズを地理空間ポーズに変換して、AI グラスが位置情報を認識したデータを操作、生成できるようにします。このパイプラインは、デバイスのローカル座標系における現在の位置と向き(デバイスポーズ)を、グローバルに認識される座標に変換します。
これにより、次のことが可能になります。
- ユーザーが配置した仮想オブジェクトがグローバルな場所に正確にアンカーされ、後で取得できるように、永続的な AR コンテンツを作成します。
- 地図上でユーザーの位置を継続的に更新して、リアルタイムのナビゲーションやジオフェンシングされたゲームプレイを可能にすることで、位置情報に基づくエクスペリエンスをトリガーします。
- 位置情報に関連するアプリのロジックをトリガーするユーザーの正確な現実世界のコンテキストを特定します。
Geospatial.createGeospatialPoseFromPose() を使用してデバイスのポーズを地理空間のポーズに変換するには:
// Get the current device Pose from the AR Session's state. val devicePose = ArDevice.getInstance(session).state.value.devicePose // Convert the device Pose into a GeospatialPose. when (val result = geospatial.createGeospatialPoseFromPose(devicePose)) { is CreateGeospatialPoseFromPoseSuccess -> { val geoPose = result.pose val lat = geoPose.latitude val lon = geoPose.longitude val alt = geoPose.altitude // Orientation is in the EUS (East-Up-South) coordinate system. val orientation = geoPose.eastUpSouthQuaternion } is CreateGeospatialPoseFromPoseNotTracking -> { // Geospatial is not currently tracking. } }
地理空間のポーズをデバイスのポーズに変換する
地理空間ポーズをデバイスポーズに変換して、AI グラスでコンテキスト認識型の位置情報認識エクスペリエンスを提供できます。この変換では、現実世界の座標で定義された情報(ランドマークの位置、ナビゲーション パス、永続的な AR コンテンツなど)を取得し、ユーザーのメガネの正確な視覚空間に変換します。
Geospatial.createPoseFromGeospatialPose() を使用して地理空間のポーズをデバイスのポーズに変換するには:
// Convert a GeospatialPose (lat/long/alt) back to a device-space Pose. when (val result = geospatial.createPoseFromGeospatialPose(geoPose)) { is CreatePoseFromGeospatialPoseSuccess -> { val devicePose: Pose = result.pose // devicePose is now ready to be used relative to the tracking origin. } is CreatePoseFromGeospatialPoseNotTracking -> { // Geospatial is not currently tracking. } }