-
Notifications
You must be signed in to change notification settings - Fork 0
ARCore Module Reference
samples/augins-arcore-headpose/ provides 6DoF head pose via
Google ARCore. The module spawns an ArSession in the runtime
service process and exports an OpenXR-shaped function the
runtime dispatches into.
-
aug_on_module_loadcaptures JVM and Context from the host API, spawns a worker thread, and starts anArSessionagainst the device's camera. - The worker calls
arcore_min_tickin a ~60 Hz loop and stashes each new pose into a mutex-guarded global. -
aug_LocateDeviceInSpace(see Service-Side-Dispatch) overwrites theXrSpaceLocationwith the latest ARCore pose. Non-head devices never reach this function; the adapter filters them out. -
aug_on_module_unloadsignals the worker to stop, joins it, releases theArSession, and detaches the JNI thread.
OpenXR clients on this runtime receive ARCore-tracked 6DoF head
pose in XrView.pose returned by xrLocateViews.
-
T_xdev_headoverride. The module only adaptsspace_locate_device(the T_base_xdev half ofxrLocateViews). The T_xdev_head half stays whatever Monado's gyro+accel fusion produces. The T_base_xdev transform dominates so the resulting view pose is correct; v0.2.x can add adevice_get_tracked_poseadapter if a downstream consumer needs ARCore on that half too. See Roadmap. -
LOCAL_FLOORheight offset. Reference-space-type-aware offsets are not applied; head pose renders at headset height regardless of whether the app requestedLOCAL,LOCAL_FLOOR,STAGE, orUNBOUNDED. - Camera frame publishing. v0.1 published the YUV camera frame's Y plane to a host-API broker for the Mercury hand-tracking module. Host API v1 has no broker entry; Mercury is also not yet rewritten on the v0.2 ABI. The broker entry returns with the Mercury rewrite.
-
arcore_module.cpp-- module entry points and the worker thread. ~200 lines. -
vendor/arcore_c_api.h,vendor/arcore_instance.{cpp,h},vendor/xrt/xrt_handles.h-- vendored ARCore SDK C API plus a thin wrapper (arcore_min) overArSession_*calls, written for the earlier in-tree ARCore xdev experiments. -
vendor/arm64-v8a/libarcore_sdk_c.so-- prebuilt ARCore SDK, shipped underLICENSE-arcore. -
metadata.json-- manifest (Manifest_Version 1). -
CMakeLists.txt-- standalone NDK build. -
build.gradle-- packaging + adb push.
- Google Play Services for AR. The ARCore SDK is a wrapper over
an out-of-process service Google ships;
ArSession_createfails without it. - ARCore-compatible phone. See Google's compatibility list.
- CAMERA permission, granted to the runtime APK (declared in
AndroidManifest.xml). Prompted on first runtime activity launch.
-
src/xrt/augins/module_abi.h. - OpenXR headers (
src/external/openxr_includes/). - Vendored ARCore SDK headers (
vendor/). - Android NDK 26.3.x and CMake 3.22.x.
aug_on_module_load(host)
- validate host->struct_version >= 1
- cache host
- GetEnv on main thread (do NOT Attach/Detach here)
- NewGlobalRef the Application Context
- spawn worker(vm, ctx_global)
- return 0
worker(vm, ctx_global)
- AttachCurrentThread (worker is a new thread)
- arcore_min_start_ex(...)
- loop {
arcore_min_tick(...)
stash pose into g_cached_pose (mutex)
sleep ~16 ms
} while (!g_stop)
- arcore_min_stop()
- DeleteGlobalRef(ctx_global)
- DetachCurrentThread (worker is responsible for its own detach)
aug_LocateDeviceInSpace(baseSpace, time, &location)
- snapshot g_cached_pose under mutex
- if not tracking: clear POSITION_TRACKED bit, return XR_SUCCESS
- else: write pose into location, set tracked flags, return XR_SUCCESS
aug_on_module_unload()
- signal g_stop
- join worker
- return
The pose snapshot uses std::mutex. The critical section is a
half-dozen float copies and a bool.
No per-module settings file in v0.2. ARCore configuration
(autofocus, camera HZ mode) is set in arcore_min_config at
session-start time. Current defaults:
focus_mode = AUTO_FOCUS_ENABLEDcamera_hz_mode = MAX_ARCAMERA_HZ-
texture_update_mode-- default (OES) - Plane detection, depth, augmented faces -- disabled
Change by editing arcore_module.cpp and rebuilding. A per-module
settings UI is [Planned] for v0.2.2.
The module emits a rate-limited info line every 240 calls:
adb logcat -s "Aug-Ins.ARCore:V"
Output during a running XR app:
I Aug-Ins.ARCore: aug_on_module_load: host API v1 accepted
I Aug-Ins.ARCore: aug_on_module_load: ARCore worker spawned
I Aug-Ins.ARCore: ARCore session started
I Aug-Ins.ARCore: aug_LocateDeviceInSpace call #240 (rate-limited 1/240)
I Aug-Ins.ARCore: aug_LocateDeviceInSpace call #480 (rate-limited 1/240)
...
The dispatch fires twice per frame (one per view); a 90 Hz client produces ~180 calls/sec, roughly one log line per 1.3 seconds.
| Item | Status | Note |
|---|---|---|
T_xdev_head is gyro+accel, not ARCore |
[Working] |
T_base_xdev dominates so the view pose is correct, but the device's own-frame pose inside the service is not ARCore-driven. v0.2.x can add a second adapter. |
| Initial ~1 second ARCore convergence | [Working] |
During convergence the module returns XR_SUCCESS with the POSITION_TRACKED bit cleared. |
One ArSession per service process |
By design | XR clients share the same ARCore stream. Camera is not re-opened per-client. |
No LOCAL_FLOOR Y offset |
[WIP] |
Reference-space-type-aware Y offsets are not applied. |
| Eager ARCore start at module load | [WIP] |
The worker runs even when no XR client is connected. v0.2.x will lazy-start on first dispatch. |
The ARCore SDK and Google Play Services for AR are Google
products. See Acknowledgements. The
prebuilt libarcore_sdk_c.so in this module's zip is
redistributed under Google's ARCore SDK license (file
LICENSE-arcore in the sample directory).
The arcore_min C wrapper was written for the earlier in-tree
ARCore xdev experiments and preserved under vendor/.