איך יוצרים מדריך טיולים במציאות משולבת באמצעות Android XR,‏ Geospatial API ו-Gemini

משך הקריאה: 7 דקות

בכנס Google I/O השנה, הכרזנו על עדכון לחוויות מרחביות: Geospatial API זמין עכשיו כגרסת Preview ב- ARCore for Jetpack XR. פלטפורמת Android XR מאפשרת לעגן תוכן דיגיטלי בעולם הפיזי ברמת דיוק של פחות ממטר אחד ובאוריינטציה מדויקת באזורים נתמכים, באמצעות מערכת מיקום חזותית (VPS) של Google.* כדי להמחיש את האפשרויות ש-Geospatial API פותח, הצוות שלנו יצר הדגמה: סיור גיאוספציאלי ב-XR.

תארו לעצמכם שאתם נכנסים לעיר חדשה, מרכיבים משקפי XR עם חיבור קווי (כמו XREAL Project Aura שעתידים לצאת) ומקבלים מיד מדריך מקומי שמכיר את העיר ומראה לכם את הדרך. לא צריך להסתכל על מפה דו-ממדית – במקום זאת, מודלים תלת-ממדיים מנחים אתכם בעדינות לאורך המסלול, וקול חכם מספר לכם על ציוני הדרך ההיסטוריים שנמצאים ממש לפניכם. שילבנו את ממשקי ה-API של GeospatialGemini API באמצעות Firebase AI LogicGoogle Maps Grounding ו- Jetpack XR SDK כדי ליצור חוויה סוחפת של סיור רגלי ללא ידיים.

 

 

הערה: האפליקציות Video ו-Tour Guide הן לצורכי הדגמה בלבד. חלק מהקטעים קוצרו. יכול להיות שכל החומרה שמוצגת נמצאת בשלבי פיתוח, ופרטי המוצר הסופי עשויים להיות שונים.

במאמר הזה נסביר על פרטי ההטמעה ונדגים איך שילבנו בין ממשקי ה-API האלה כדי ליצור חוויה מרחבית בקנה מידה עולמי.

1. איתור מדויק של המשתמש באמצעות ARCore Geospatial API ‏ (VPS)

כדי לשפר את חוויית הניווט ב-XR, אפשר לשלב בין היכולות של GPS לבין הדיוק של VPS. הדיוק והכיוון המדויק שמתקבלים מ-VPS מאפשרים ליישר נקודות ציון תלת-ממדיות עם העולם הפיזי.

לכן, Geospatial API ב-Android XR יכול לעזור לכם ליצור חוויות בהתאמה אישית. באמצעות ראייה ממוחשבת מתקדמת, מערכת VPS מנסה לספק GeospatialPose (כולל קו רוחב, קו אורך וכיוון) שהוא מדויק יותר מ-GPS.

כך אנחנו מאחזרים את המיקום הגיאוגרפי של המשתמש על ידי מיפוי של האוריינטציה של המכשיר לקואורדינטה גיאוגרפית:

// Retrieve the current geospatial pose from the ARCore session
val result = geospatial.createGeospatialPoseFromPose(arDevice.state.value.devicePose)
if (result is CreateGeospatialPoseFromPoseSuccess) {
    val pose = result.pose
    Log.d("VPS", "Accurate Location: ${pose.latitude}, ${pose.longitude}")
}

הדיוק הזה הוא הבסיס לכל החוויה, ולכן אנחנו עוקבים אחרי horizontalAccuracy וorientationYawAccuracy עד שהם עומדים בסף שלנו. אם המשתמש נמצא בתוך מבנה או באזור לא מזוהה, אנחנו מבקשים ממנו ללכת למרחב ציבורי בחוץ ולהסתכל סביבו.

2. יצירת מסלול נסיעה באמצעות Gemini API ועיגון במפות Google

אחרי שמקבלים מיקום, משתמשים ב-Gemini API באמצעות Firebase AI Logic כדי להנחות את מודל Gemini לפעול כמדריך טיולים מקומי. אנחנו מעבירים למודל את הקואורדינטות של המשתמש ומבקשים ממנו ליצור תשובה מובנית בפורמט JSON שמכילה סיורים רגליים בסביבה:

   val configForTools = ToolConfig(
      functionCallingConfig = null,
      retrievalConfig = retrievalConfig {
        latLng = FirebaseLatLng(pose.latitude, pose.longitude)
        languageCode = "en"
      }
    )

    val responseJsonSchema = Schema.obj(
      mapOf(
        "locationIntro" to Schema.string(),
        "tours" to Schema.array(
          Schema.obj(
            mapOf(
              "title" to Schema.string(),
              "description" to Schema.string(),
              "stops" to Schema.array(
                Schema.obj(
                  mapOf(
                    "name" to Schema.string(),
                    "detailedName" to Schema.string(),
                    "description" to Schema.string()
                  )
                )
              )
            )
          )
        )
      )
    )

    val model = Firebase.ai(backend = GenerativeBackend.googleAI()).generativeModel(
      modelName = "gemini-3.5-flash",
      tools = listOf(Tool.googleMaps()),
      generationConfig = generationConfig {
        responseMimeType = "application/json"
        responseSchema = responseJsonSchema
      }
    )

   val result = model.generateContent("The user is at latitude ${pose.latitude} and longitude ${pose.longitude}. Generate exactly 3 diverse tours near this location (e.g., historical, food, nature). All tour ideas should be walking distance only.")

מודלים גדולים של שפה (LLM) מצוינים ביצירת תיאורים עשירים, אבל לפעמים הם יכולים להמציא קואורדינטות מדויקות של קו רוחב/אורך. כדי לפתור את הבעיה הזו, השתמשנו ב-Google Maps Grounding כדי להקנות ל-AI יכולת Grounding.

3. קול שינחה אתכם: Gemini 2.5 TTS

כדי שהמדריך ירגיש נוכח באמת, הטמענו קריינות דינמית.

באמצעות gemini-2.5-flash-tts model, אנחנו יכולים להגדיר את ההגדרה של יצירת המודל כך שתחזיר נתוני אודיו באופן מקורי במקום טקסט בלבד. כדי לבקש את ResponseModality.AUDIO:

val ttsModel = Firebase.ai(backend = GenerativeBackend.googleAI())
    .generativeModel(
        modelName = "gemini-2.5-flash-tts",
        generationConfig = generationConfig {
            // Instruct the model to return Audio
            responseModalities = listOf(ResponseModality.AUDIO)
        }
    )

val response = ttsModel.generateContent("Say in a neutral but positive voice:\n$prompt")

// Extract the raw audio bytes from the response
val audioBytes = response.candidates.firstOrNull()?.content?.parts
    ?.filterIsInstance<InlineDataPart>()
    ?.firstOrNull { it.mimeType.contains("audio") }?.inlineData

4. הפיכת הרעיון למציאות בתלת-ממד באמצעות Jetpack XR

החלק האחרון בפאזל הוא רינדור הנתונים האלה בשדה הראייה של המשתמש. ערכת ה-SDK של Jetpack XR מאפשרת מעבר אינטואיטיבי מממשק משתמש דו-ממדי של Android למחשוב מרחבי.

השתמשנו ב-Jetpack Compose for XR כדי ליצור רכיבים מרחביים. כדי לייצג נקודות עניין לאורך הסיור, יצרנו רכיב שניתן להרכבה בשם InfoSphere, שמכיל GltfModel של כדור תלת-ממדי שצף בחלל ושאפשר לקיים איתו אינטראקציה כדי לחשוף מידע.

באמצעות Jetpack XR SDK, אפשר למקם מודלים תלת-ממדיים לצד ממשק המשתמש של Compose באמצעות SpatialBox ו- SceneCoreEntity. השתמשנו גם ב-InteractableComponent כדי להגיב להקשות של המשתמשים.

על ידי שילוב AnimatedSpatialVisibility לממשקי משתמש מסורתיים של Compose עם רכיבי תלת-ממד של SceneCoreEntity, אנחנו יכולים לשלב נתונים בצורה חלקה בעולם הפיזי.

@Composable
fun InfoSphere(
    content: InfoBubbleContent,
    session: Session,
    sphereModel: GltfModel,
    isSelected: Boolean,
    onClick: () -> Unit
) {
    // SpatialBox lets us arrange 3D components and SpatialPanels together
    SpatialBox(
        SubspaceModifier
            .offset(x = 2.dp, y = 1.dp, z = (-3).dp) // Positioned in 3D space
    ) {
        // Smoothly animate the visibility of our 2D Compose UI Panel
        AnimatedSpatialVisibility(visible = isSelected) {
            SpatialPanel {
                InfoBubble(content) // Regular 2D Compose UI
            }
        }
        // Render our interactive 3D sphere
        SceneCoreEntity(
            factory = {
                GltfModelEntity.create(session, sphereModel).also { entity ->
                    // Make the 3D model respond to user taps
                    entity.addComponent(InteractableComponent.create(session) { inputEvent ->
                        if (inputEvent.action == InputEvent.Action.UP) {
                            onClick()
                        }
                    })
                }
            }
        )
    }
}

מה אפשר לעשות היום עם Android XR

בניית אפליקציית XR Geospatial Tour הראתה לנו שהמחסום לכניסה ליצירת חוויות מרחביות בקנה מידה עולמי נמוך מאי פעם למפתחי Android. ה-Geospatial API זמין עכשיו בגרסת טרום-השקה ב-Android XR, כך שהאפליקציות שלכם יכולות להבין בצורה חלקה את העולם הפיזי שסביבן. שילוב של ממשקי Compose for XR API עם נתוני מיקום ברמת דיוק גבוהה מ-VPS והיכולות הגנרטיביות של Gemini מאפשר ליצור חוויות שמבינות גם איפה המשתמש נמצא וגם מה הוא רואה.

כדי לעזור לכם להתנסות ב-Android XR, אנחנו שמחים לפתוח את ההרשמה לתוכנית Android XR Developer Catalyst, שכוללת את XREAL Project Aura. החל מהיום, תוכלו להגיש בקשה לקבלת גישה לערכת פיתוח של XREAL Project Aura או לערכת פיתוח של משקפיים עם תצוגה פנימית בחודשים הקרובים.

*הערה: התכונה זמינה רק במכשירים נבחרים. נדרש חיבור לאינטרנט. התכונה פועלת באפליקציות ובפלטפורמות תואמות. יכולות להתקבל תוצאות שונות. 

להמשך הקריאה