Why the 3D building drifts as you walk, what we can do about it, the decisions we need from you, and what each option costs.
The 3D building must appear locked at its exact real-world position and scale, and stay put as the viewer walks around it. Today the app uses the phone's GPS + camera/IMU tracking. This drifts: GPS is off by several meters, and camera tracking accumulates error as you move — so the building slowly slides out of place. We need a drift-free, "stuck-to-the-ground" anchor.
The two best markerless, no-extra-hardware methods are both blocked at this site:
That leaves two honest choices:
These answers decide which path we take and how many devices we buy:
| Option | Works at this site? | Markerless | Drift-free |
|---|---|---|---|
| Match camera to the splat | ❌ building not built | ✅ | ✅ |
| ARCore Geospatial (Google VPS) | ❌ no Street View | ✅ | ✅ |
| Apple ARGeoAnchor | ❌ not covered | ✅ | ✅ |
| Physical markers | ⚠ can't cover 200 m | ❌ | ✅ near marker |
| RTK GNSS | ✅ yes | ✅ | ✅ |
| UWB beacons | ⚠ needs install | ✅ | ✅ |
| Bluetooth / WiFi | ❌ 2–8 m | ✅ | ❌ |
| GPS + VIO (current) | ⚠ drifts | ✅ | ❌ |
RTK ("Real-Time Kinematic") is survey-grade GPS. A fixed base on a known point measures the live satellite error and streams a correction to a rover mounted on the phone, which subtracts it → 1–2 cm position, continuously, anywhere outdoors. No real building or Street View needed.
Interactive 3D (Three.js — needs internet to load). Toggle Emlid / SparkFun Facet below the scene to swap the actual device models and per-part prices. Toggling also changes the rig: Emlid & Facet ride a short pole (receiver on top, phone clamped below — too bulky to clip on the phone), while DIY-small clips onto the phone (no pole). Either way it's one rigid unit (fixed antenna↔camera offset). One base broadcasts corrections to all rovers at once; each phone in use at the same time needs its own rover (see the price panel).
3D device models: Emlid Reach RX by Strumenti Topografici & Reach RS2 by INGEN Innovations (Sketchfab, CC-BY). The Facet is a stylized SparkFun RTK Facet look-alike (its real model is view-only).
Emlid's Reach RX is Apple MFi-certified — once paired, iOS reports centimeter position to any app, so our app needs almost no code change. Tidy, wireless, reliable.
| Item | ~ USD |
|---|---|
| Reach RX (rover, MFi) | $2,000 |
| Reach RS3 / RS2+ (base) | $2,000–3,800 |
| Tripod + phone bracket | $150 |
| Nassau (base + rover) | ~$4,150–6,000 |
The SparkFun RTK Facet is a complete, enclosed all-in-one: a surveyor-grade antenna, a 6 Ah all-day battery and Bluetooth inside an IP53 dome. No assembly, no 3D-printing — it streams centimeter NMEA to the phone over Bluetooth, far cheaper than Emlid.
| Item | ~ USD |
|---|---|
| SparkFun RTK Facet (base) | $740 |
| SparkFun RTK Facet (rover) | $740 |
| Short pole + phone clamp (rig — Facet on top, phone below) | $50 |
| Tripod (base) + power bank | $45 |
| Nassau hardware (Facet path) | ~$1,575 |
A Facet as the base + a self-built tiny rover (a small ZED-F9P board + a small antenna) that clips onto the phone — no pole. The only way to get a small, cheap, phone-clipped rover — but we design + 3D-print the bracket, assemble it, and parse NMEA. Full build steps in “Rover form factor” below.
| Item | Qty | Buy / Build | ~ USD |
|---|---|---|---|
| SparkFun RTK Facet (base) | 1 | buy | $740 |
| ZED-F9P board + small antenna + battery (rover) | 1 | buy + build | $375 |
| Printed phone bracket | 1 | incl. | |
| Tripod (base) | 1 | buy | $30 |
| Nassau (base + 1 rover) · + build / print / code | ~$1,150 | ||
The base is always a Facet on a tripod; only the rover that goes with the phone changes shape. The Facet is a bulky dome — it can't clip onto a phone — so there are three ways to carry the rover:
| Direction | Size / how you carry it | Build (assemble · print · code) | Accuracy | Rover ~$ |
|---|---|---|---|---|
| 1 · Emlid Reach RX | small puck — clips right on top of the phone | none (MFi, plug-and-play) | high | $2,000 |
| 2 · SparkFun Facet on a short pole | bulky dome — Facet on top of a ~30–50 cm rod, phone clamped below it | none (just configure) | high | $740 |
| 3 · DIY small rover | small — a board + small antenna on the back of the phone | YES — we build it | a bit lower (small antenna → more multipath) | $300–400 |
Rule of thumb: small + cheap + accurate — pick two. Reach RX = small + accurate (pricey). Facet-on-pole = cheap + accurate (bulky). DIY-small = small + cheap (we build it, antenna a bit weaker).
Compact enough to sit on the phone, but it is a full in-house build. The steps:
| Stage | What | ~ Effort / $ |
|---|---|---|
| Buy | ZED-F9P board (credit-card size, e.g. a SparkFun breakout) · small multiband antenna (patch / helical) + small ground plane · SMA cable · small LiPo or mini power bank · filament | ~$300–400 |
| Design & 3D-print | a slim enclosure for the board + battery, and a bracket that clips to the iPhone and holds the antenna above the camera at a fixed offset (print + iterate the fit) | ~2–4 days |
| Assemble | connect the antenna (SMA) + battery, fit into the printed case, mount it on the phone bracket | ~1 day |
| Configure | u-center: enable the NMEA messages + rate, set rover mode + correction input (NTRIP via the phone, or radio from the base) | ~0.5 day |
| Code the app | BLE transport + NMEA parser + position integration + (single-rover) NTRIP client + status UI + QA — the same parsing work the Facet needs | ~4–6 days |
Why DIY-small can clip on the phone while the others ride a pole: it's the device + antenna size. (Approximate — verify on the datasheet before ordering.)
| Board / module | Size ~ | Note |
|---|---|---|
| u-blox ZED-F9P chip (module) | 17 × 22 mm | tiny |
| SparkFun GPS-RTK2 board | ~41 × 38 mm | credit-card-ish |
| ArduSimple simpleRTK2B | ~51 × 53 mm | |
| Unicore UM980 / UM982 (module) | ~30 × 40 mm | UM982 = built-in heading |
| Antenna | Size ~ | Trade-off |
|---|---|---|
| Helical multi-band | ~Ø18 × 45 mm | compact — best for phone-mount |
| Patch + ground plane | ~35–60 mm + base | better multipath, too big for phone |
| u-blox ANN-MB puck | Ø60 mm | too big for phone-mount |
| Whole rover unit | Size ~ | Mounting |
|---|---|---|
| DIY small (board + helical) | ~matchbox | clips on the phone — no pole |
| Emlid Reach RX | Ø64 × 95 mm | short pole |
| SparkFun Facet | dome ~Ø115 mm | pole (bulky) |
Emlid & Facet ride a short pole (receiver on top, iPhone clamped below); DIY-small clips onto the iPhone (no pole). Same scale throughout — the Facet dome is huge, the Reach RX a chunky puck, the DIY board + helical antenna tiny.
iPhone model: iPhone X low-poly by Fred Drabble (Sketchfab, CC-BY).
There are two separate streams — we only touch one:
| Stream | What it carries | Who handles it |
|---|---|---|
| base ↔ rover | RTK corrections (RTCM) | the receivers themselves — not our code |
| rover → iPhone | the cm position (NMEA text, over Bluetooth) | parsed on the iPhone — this is the only work |
Who parses the rover → iPhone NMEA: Emlid (MFi) → iOS does it automatically (zero code). Facet / DIY (not MFi) → our app does it (see the table below).
With Emlid (MFi) iOS reports the centimeter position automatically — zero parsing. The Facet instead streams raw NMEA text over Bluetooth that the app has to ingest itself:
| Code piece | What it does | Effort |
|---|---|---|
| BLE transport (CoreBluetooth) | scan, connect & subscribe to the receiver's serial data service | ~1 day |
| NMEA parser (open-source) | use a Swift library — NMEAParser — to read $GNGGA (lat/lon/alt + RTK fix quality) & $GNGST (accuracy) → decimal degrees. Mostly wiring, not writing a parser | ~0.5 day |
| Position-source integration | inject the cm fixes into the app's anchor pipeline (replacing the GPS origin); trust only quality = RTK-fixed | ~1 day |
| NTRIP client (single-rover only) | pull RTCM3 corrections from a caster & forward to the receiver — not needed with our own base + radio, or if the device firmware does NTRIP | ~1–2 days |
| Fix-status UI | show fix type (none / float / fixed), satellite count, accuracy | ~0.5 day |
| Self-test, QA & hardening | auto-reconnect on dropout, parse edge-cases, on-device integration testing + bug-fix iteration | ~2–3 days |
| Facet total (incl. self-test, open-source parser) | ~4–6 days | |
With Emlid this whole block collapses to ~2–3 days (incl. self-test): iOS CoreLocation already delivers cm — we just trust it, show status, and QA it.
The Facet is a finished device — nothing to build. The only setup is a one-time firmware configuration via its on-device menu: base mode (survey-in or fixed coordinates) on one unit, rover mode + NTRIP/radio correction input on the other. The Facet is too bulky to clip on the phone, so the rover rides on a short pole (Facet on top, phone clamped below — see "Rover form factor"). After that, daily use is just power-on → wait for "Fix".
| Viewing model | Does RTK work? |
|---|---|
| Agent-led (customer just watches) | ✅ Yes — staff handles everything; customer needs zero skill |
| Customer self-service, own phone, nobody assisting | ❌ No hardware fits → accept drift (GPS+VIO) |
This is exactly why Q1 (§3) is the deciding question.
| Component | How many | Why |
|---|---|---|
| Base | 1 per site | One base serves unlimited rovers; set up once, leave running |
| Rover | 1 per phone used at the same time | The rover measures its own position and must travel with that phone — it can't be shared over Bluetooth from afar |
| Simultaneous viewers | Base | Rovers | ~ Cost (Emlid) | ~ Cost (Facet) |
|---|---|---|---|---|
| 1 at a time (pass the rig) | 1 | 1 | ~$4,000 | ~$1,575 |
| 2 at once | 1 | 2 | ~$6,000 | ~$2,355 |
| 3 at once | 1 | 3 | ~$8,500 | ~$3,135 |
For sales demos, one viewer at a time (1 base + 1 rover) is usually enough — pass the same rig to each guest.
Rough plan once hardware is in hand. Emlid is faster (MFi feeds the app directly); the Facet adds time to parse the position feed (not MFi).
Development after hardware arrives, including self-test/QA: ~3–4 weeks (Emlid) or ~4–5 weeks (Facet), excluding shipping and on-site travel.
The developer needs a physical device to build and test. Two models:
| Approach | Hardware | Pros | Cons |
|---|---|---|---|
| Ship one set back & forth | 1 base + 1 rover | cheapest hardware | slow; customs each way; no dev rig afterward; single point of failure |
| Buy 2 rovers + 1 base (recommended) | +1 rover | no shipping ping-pong; developer keeps a permanent test/support rig; spare/backup | +1 rover cost |
| Leg | Via | ~ Time |
|---|---|---|
| China → Vietnam | cross-border express (SF / J&T) · AliExpress Choice | ~2–5 days |
| Hong Kong → Vietnam | Emlid HK store | ~3–7 days |
| US → Nassau | FedEx Intl Priority / DHL Express | ~1–3 days |
| Vietnam → Nassau | DHL/FedEx express + Bahamas customs | ~3–7 days |
| EU (ArduSimple) → either | — | ~1–2 weeks |
Bahamas customs for electronics: register Click 2 Clear + file a C44 form so the courier clears it for you.
| Route | The Nassau unit | Ship to Nassau |
|---|---|---|
| Emlid / Facet (finished) | buy from a US source, plug-and-play | US → Nassau ~1–3 days ✅ |
| DIY (we build it) | built in Vietnam (board + antenna + print + assemble + config) | VN → Nassau ~3–7 days + customs ⚠️ |
| Route | Dev unit → Vietnam | Nassau unit → Nassau |
|---|---|---|
| Emlid | Emlid HK store (~3–7 d) | US Emlid dealer → FedEx (~1–3 d) |
| SparkFun Facet | SparkFun / Mouser (slower to VN) | SparkFun US → FedEx (~1–3 d) |
| DIY (ZED-F9P) | AliExpress board (~2–5 d) | built in VN → ship VN→Nassau |