Skip to content

mit112/log-pose

Repository files navigation

Log Pose

A real-life Log Pose from One Piece. A wrist-worn compass that always points toward home — built as a birthday gift for Kashish.

Three components work together:

  1. iPhone app — calculates bearing-to-home from GPS and sends it over BLE
  2. Apple Watch app — standalone digital Log Pose compass on your wrist
  3. Arduino prop — a 3D-printed wrist-worn Log Pose with a physical needle driven by an ESP32

The iPhone is the brain. It computes the geographic bearing from your current location to a saved "home" location, subtracts its own heading, and sends the resulting needle angle to the ESP32 over Bluetooth Low Energy. The ESP32 drives a servo to that angle — just like the anime. The Apple Watch runs an independent compass with its own magnetometer, and can also take direct BLE control of the prop.


Demo

Screenshots and demo video coming soon — needle tracking bearing as the phone moves, Watch compass in action, and the physical prop spinning.

Tech Stack

CI Swift SwiftUI watchOS CoreBluetooth Firebase XCTest


Architecture

iPhone (GPS + heading)
  │
  ├──► BLE (direct) ──► ESP32 + servo (physical needle)   ◄──┐
  │       Servo Angle characteristic →                        │
  │                                                           │
  └──► WatchConnectivity ──► Apple Watch (digital compass) ──┘
                                  BLE (when watch takes control)

The prop can only hold one BLE connection at a time. Phone holds it by default; the Watch can take control via a manual handoff (tap the antenna button on Watch → phone disconnects → Watch connects and drives the prop with its own heading). When the Watch releases, the phone reconnects automatically.

No WiFi or cloud required for the prop — BLE only, ~10–30m range. Prop holds its last needle angle when BLE disconnects.


BLE Service Contract

The ESP32 runs a BLE GATT server. The iPhone is the BLE central — it scans, connects, and writes servo angles over one characteristic.

Device name: ESP32C3-Servo
Service UUID: 4FAFC201-1FB5-459E-8FCC-C5C9C331914B

Characteristic UUID Direction Payload
Servo Angle BEB5483E-36E1-4688-B7F5-EA07361B26A8 Phone → ESP32 UTF-8 text string, integer 0180. Heading-compensated by the phone before sending.

Full Arduino integration doc: docs/arduino-handover.md — covers hardware, BLE sketch, encoding, and testing notes.


Where the math lives

The iPhone computes a heading-compensated needle angle (displayBearing = geographicBearing − deviceHeading) and encodes it for the servo: servo = 90 − signed(displayBearing), clamped to [0, 180]. Centering at 90° means servo 90° = home directly ahead; the sign accounts for the servo being reverse-mounted (increasing angle = CCW from front). The ESP32 has no orientation sensors — all heading compensation happens on the phone.


Firebase

Firebase is used by the iPhone for:

  • Anonymous Auth — generates a UID stored in Keychain, used to gate RTDB writes
  • RTDB — writes /bearing, /home, /trigger (legacy; the prop uses BLE directly)

Project ID: log-pose-3851e

The ESP32 does not need to connect to Firebase. All prop communication is over BLE.

Bootstrapping auth on a new device

  1. Run the iPhone app once
  2. Check the Xcode console for: Firebase UID: <uid>
  3. In Firebase Console → Realtime Database, set /ownerUID to that UID string
  4. Rerun. Firebase writes will start succeeding.

Deploying security rules

GOOGLE_CLOUD_QUOTA_PROJECT=log-pose-3851e \
  firebase deploy --only database --project log-pose-3851e

Building the iOS/watchOS App

Prerequisites

  • Xcode 16+
  • xcodegen (brew install xcodegen)
  • GoogleService-Info.plist at LogPose/GoogleService-Info.plist (gitignored — ask Mit)
  • Apple Developer account for device deployment

Build

# Generate the Xcode project from project.yml
/opt/homebrew/bin/xcodegen generate

# Open in Xcode
open LogPose.xcodeproj

Build the LogPose scheme for iPhone or LogPose WatchKit App for Apple Watch.

Targets

Target Platform Description
LogPose iOS 17+ Main iPhone app
LogPose WatchKit App watchOS 10+ Standalone watch compass
LogPose Complication watchOS 10+ Watch face widget showing direction

Running on device

  • iPhone: select LogPose scheme, plug in phone, ▶️
  • Watch: the watch app embeds inside the iPhone app. On first install, open the Watch app on iPhone → My Watch → scroll to Log Pose → Install. Then run LogPose WatchKit App from Xcode.

Tests

⌘U with the LogPose scheme selected. Tests cover BearingCalculator math, HomeLocation persistence, and BLE encoding/decoding.


How Bearing Updates Flow

  1. CLLocationManager fires a GPS update on the iPhone
  2. AppViewModel computes bearing using the great-circle forward azimuth formula
  3. If bearing changed by ≥2° (circular distance, handles 359°→1° correctly):
    • Writes to BLEBearingManager → prop over BLE
    • Sends to Watch via WatchConnectivity
  4. On the iPhone, the compass needle is heading-compensated: displayBearing = geographicBearing − deviceHeading using shortest-path rotation (continuous angle accumulation) so the needle never does a 360° spin at the 0°/360° boundary
  5. The Watch runs the same heading-compensation algorithm locally using its own magnetometer

Questions?

Reach out to Mit for Firebase credentials, GoogleService-Info.plist, or integration questions. For the hardware prop, start with docs/arduino-handover.md.

About

A real-life Log Pose from One Piece — wrist-worn compass that always points home. iOS + watchOS app with BLE-driven physical servo prop. Built as a birthday gift.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages