AR Indoor Wayfinding: When Pixels Beat Paper (and Pixels)
The first time a user got lost using our AR wayfinding system, it wasn't because of a GPS drift issue. It was because the ARKit 1.0 camera feed lagged by half a second, and the user, trying to follow an arrow that pointed to a wall, walked straight into a kiosk.
Why this matters in 2026
By 2026, indoor positioning is no longer a novelty; it's an expectation. For large, complex venues – think a 200,000 sqft hospital or a mid-sized airport terminal – relying solely on 2D overhead maps is a failure of imagination. Users have become accustomed to contextual, real-time information. AR offers a way to overlay that information directly onto their physical environment, reducing cognitive load and increasing accuracy, provided the underlying tech is sound.
Three things I learned shipping this in production
The Illusion of Precision: UWB vs. BLE for AR Anchors
We were building an AR wayfinding system for a 40-floor commercial tower. The initial plan was to use Bluetooth Low Energy (BLE) beacons from Kontakt.io, specifically their iBeacon protocol, for positioning. Our goal was sub-meter accuracy to place AR arrows precisely in front of doors or specific conference rooms.
The problem? BLE, even with dense beacon placement (we deployed 300 beacons across two floors), offers an average accuracy of 2-5 meters. This is fine for general zone identification ("you are in the West Wing"), but useless for pinpointing an AR arrow. When a user's phone reported them as being 3 meters away from a door, the AR arrow would appear in the middle of the hallway, or worse, pointing to the wrong side of the room. This led to confusion, frustration, and a significant drop-off in usage.
We switched to Ultra-Wideband (UWB) with a vendor-agnostic RTLS system. UWB, when properly deployed with at least four anchors per zone and a robust trilateration algorithm, can achieve centimeter-level accuracy. This allowed us to anchor AR elements to specific physical locations with confidence. For example, when a user entered a specific office suite, the AR overlay would accurately place the "Conference Room A" arrow directly in front of its physical door, not 5 meters down the corridor. The UWB system cost us an additional $100,000 for the initial hardware and installation for the two floors, but the user experience improvement was night and day. We saw a 70% increase in successful wayfinding sessions after the UWB rollout.
AR Anchors: The Foundation of Trust
ARKit (iOS 13+) and ARCore (Android 10+) provide powerful tools for anchoring virtual content to the real world. However, the quality of these anchors is paramount. We learned this the hard way in a sprawling convention center. Our initial AR placement logic relied heavily on the ARKit ARWorldTrackingConfiguration and ARCore's ARCoreWorldTracking.TrackingMode.POSITIONAL_TRACKING.
The issue arose when the venue's lighting changed dramatically, or when users walked past large reflective surfaces like glass walls. ARKit and ARCore use visual features in the environment to track the device's position and orientation. When these features are scarce, inconsistent, or change rapidly, the tracking can become unstable, causing AR anchors to "drift" or jitter. In the convention center, this meant AR arrows would swim around, sometimes jumping several feet. This made following them feel like a guessing game, not a reliable navigation tool.
Our solution was to fuse UWB positioning data with the AR tracking. We used the UWB system to provide a highly accurate, absolute positional reference. This UWB coordinate was then used to "correct" or "snap" the AR anchor to its intended real-world location, even if the visual tracking momentarily faltered. We implemented a Kalman filter in our backend service that took both UWB and ARKit/ARCore pose estimates, weighting them based on their respective confidences.
Here's a simplified pseudocode example of how we fused the data:
class ARFusionFilter:
def __init__(self, initial_pose, uwb_pose):
self.last_uwb_pose = uwb_pose
self.last_ar_pose = initial_pose
self.fusion_weight = 0.8 # UWB gets more weight def update(self, new_ar_pose, new_uwb_pose):
# Simple weighted average for demonstration
# A real implementation would use a Kalman filter
fused_x = (self.fusion_weight new_uwb_pose.x) + ((1 - self.fusion_weight) new_ar_pose.x)
fused_y = (self.fusion_weight new_uwb_pose.y) + ((1 - self.fusion_weight) new_ar_pose.y)
fused_z = (self.fusion_weight new_uwb_pose.z) + ((1 - self.fusion_weight) new_ar_pose.z)
fused_pose = Pose(fused_x, fused_y, fused_z, new_ar_pose.orientation) # Orientation from AR
self.last_ar_pose = new_ar_pose
self.last_uwb_pose = new_uwb_pose
return fused_pose
This approach significantly stabilized the AR experience, drastically reducing anchor jitter and making the virtual arrows feel "stuck" to their intended locations.
The "Cold Start" Problem: Initializing AR Tracking
Getting ARKit or ARCore to initialize tracking reliably is crucial. We experienced this acutely in a large, open-plan office space that had minimal distinct visual features. When a user first opened the AR wayfinding app, the system would struggle to establish a stable world map. This "cold start" problem meant the initial AR anchors would appear in arbitrary locations or the system wouldn't track at all for several seconds.
In one instance, a user was trying to find a meeting room on their first day at a new job. The AR app failed to initialize for 15 seconds, showing a spinning loader. By the time the AR tracking kicked in, they had already walked past the correct turn. The app then placed an arrow pointing to a wall. The cost of this failure wasn't just a lost navigation session; it was a negative first impression and a potential delay in their workday.
Our solution involved providing a better initial "hint" to the AR tracking system. We combined the initial UWB position with a known average floor plan orientation. This gave ARKit/ARCore a much better starting point. Instead of trying to guess its position from scratch, it could begin refining its understanding of the environment from a more informed estimate. We also implemented a grace period where we would continue to show a simplified 2D map or a "searching for location" message for up to 5 seconds, rather than immediately presenting a potentially unstable AR view. Once the AR tracking achieved a certain confidence level (e.g., ARTrackingState.tracking in ARKit or TrackingState.TRACKING in ARCore), we would transition to the AR overlay.
What I would do differently if I started today
If I were starting an AR indoor wayfinding project today, I would prioritize a hybrid approach from day one, even if it meant a higher upfront cost. I would insist on UWB as the primary positional technology, using BLE or Wi-Fi triangulation as a fallback or for broader zone detection. The stability and accuracy of UWB are, in my experience, non-negotiable for a truly usable AR navigation system. Relying solely on visual-inertial odometry (VIO) from ARKit/ARCore, while impressive, introduces too many failure modes in real-world, dynamic environments. The $50,000 to $150,000 (depending on venue size and complexity) for a robust UWB infrastructure is an investment that pays dividends in user satisfaction and system reliability.
What this looks like for your team
1. Audit your current positioning technology: If you're using BLE or Wi-Fi for indoor location, measure its actual accuracy in your target venue. Take 100 sample readings in a known location and calculate the standard deviation. If it's over 3 meters, it's likely not precise enough for AR anchoring. 2. Prototype AR anchoring with real-world sensor fusion: Don't just rely on ARKit or ARCore's raw pose data. Integrate it with any existing positional data you have (even if it's just Wi-Fi RTT) and experiment with simple filtering techniques like a weighted average. See how much it stabilizes your AR anchors. 3. Plan for environmental challenges: Identify areas in your venue that might challenge AR tracking: low light, reflective surfaces, long corridors with few visual features. Think about how you'll provide fallback mechanisms or supplementary data to ensure a consistent experience.
I write about engineering decisions and production systems at devwithzach.com — drop me a line if any of this rings true.
John from California
just requested a quote
2 minutes ago