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 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 = session.config.copy(
// Set the GeospatialMode to VPS_AND_GPS.
geospatial = Config.GeospatialMode.VPS_AND_GPS
// Set the DeviceTrackingMode to LAST_KNOWN.
deviceTracking = Config.DeviceTrackingMode.LAST_KNOWN
)
// Apply the configuration to the session.
try {
when (val configResult = session.configure(newConfig)) {
is SessionConfigureGooglePlayServicesLocationLibraryNotLinked -> {
// This case generally indicates a missing library dependency.
}
is SessionConfigureSuccess -> {
// The session is now configured to use the Geospatial API.
}
else -> {
// Catch-all for other configuration errors returned using the result class.
}
}
} catch (e: UnsupportedOperationException) {
// Handle configuration failure. For example, if the specific mode is not supported on the current device or API version.
}
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
var 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 度の回転精度を提供します。位置情報に VPS カバレッジがあるかどうかは、suspend 関数 Geospatial.checkVpsAvailability(latitude, longitude) を使用して確認できます。この呼び出しは非同期オペレーションであり、セッションを GeospatialMode.VPS_AND_GPS モードで構成する必要はありません。
次のコードは、指定された緯度と経度から VPS の可用性を確認する方法を示しています。
// You can query the GPS to get the current device's location and check if it has VPS
val latitude = getLatitudeFromGPS()
val longitude = getLongitudeFromGPS()
// Must be called from a coroutine.
val result = geospatial.checkVpsAvailability(latitude, longitude)
if (result is VpsAvailabilityAvailable) {
// VPS is available
} else if (result is VpsAvailabilityUnavailable) {
// VPS is not available
}
アプリが Google Cloud の ARCore API と通信するように正しく設定されている必要があります。そうでない場合、アプリは VpsAvailabilityNotAuthorized の結果を受け取ります。
デバイスのポーズを地理空間のポーズに変換する
デバイスのポーズを地理空間ポーズに変換して、AI グラスが位置情報を認識したデータを操作、生成できるようにします。このパイプラインは、デバイスのローカル座標系における現在の位置と向き(デバイスポーズ)を、グローバルに認識される座標に変換します。
これにより、次のことが可能になります。
- ユーザーが配置した仮想オブジェクトが後で取得できるように、グローバルな場所に正確にアンカーされる永続的な AR コンテンツを作成します。
- 地図上でユーザーの位置を継続的に更新して、リアルタイムのナビゲーションやジオフェンシングされたゲームプレイを可能にすることで、位置情報に基づくエクスペリエンスをトリガーします。
- 位置情報に関連するアプリのロジックをトリガーするユーザーの正確な現実世界のコンテキストを特定します。
Geospatial.createGeospatialPoseFromPose() を使用してデバイスのポーズを地理空間のポーズに変換するには:
// Get the current device Pose from the AR Session's state
// This is the device's position and orientation relative to the AR tracking origin.
val devicePose = ArDevice.getInstance(session).state.value.devicePose
// Convert the device Pose into a GeospatialPose
when (val geospatialPoseResult = geospatial.createGeospatialPoseFromPose(devicePose)) {
is CreateGeospatialPoseFromPoseSuccess -> {
val currentGeospatialPose = geospatialPoseResult.pose
val horizontalAccuracy = geospatialPoseResult.horizontalAccuracy
// ... use pose and accuracy
val latitude = currentGeospatialPose.latitude
val longitude = currentGeospatialPose.longitude
// The orientation is stored as a Quaternion in the EUS (East-Up-South) system. The EUS coordinate system has X+ pointing east, Y+ pointing up, and Z+ pointing south. True North is aligned with the -Z axis.
val eusQuaternion = currentGeospatialPose.eastUpSouthQuaternion
}
is CreateGeospatialPoseFromPoseNotTracking -> {
// Geospatial is not currently tracking
}
}
地理空間のポーズをデバイスのポーズに変換する
地理空間ポーズをデバイスポーズに変換して、AI グラスでコンテキスト認識型の位置情報認識エクスペリエンスを提供できます。この変換では、現実世界の座標で定義された情報(ランドマークの位置、ナビゲーション パス、永続的な AR コンテンツなど)を取得し、ユーザーのメガネの正確な視覚空間に変換します。
Geospatial.createPoseFromGeospatialPose() を使用して地理空間のポーズをデバイスのポーズに変換するには:
when (val poseResult = geospatial.createPoseFromGeospatialPose(geospatialPose)) {
is CreatePoseFromGeospatialPoseSuccess -> {
val devicePose = poseResult.pose
// devicePose is now ready to be used
}
is CreatePoseFromGeospatialPoseNotTracking -> {
// Geospatial is not currently tracking
}
}