Project: Motorcycle Body-Position IMU Logger — iOS V0 Build a small native Swift/SwiftUI iOS application for experimentally measuring motorcycle rider body-position movements using the iPhone's motion sensors. This is a research/prototyping tool, not yet a polished consumer app. The immediate use case is an iPhone mounted rigidly to the rider's torso while the rider sits on a stationary motorcycle on front/rear stands in a garage and repeatedly practices left/right body-position transitions. The very next version will be a watchOS companion/port using an Apple Watch Ultra 2 mounted rigidly to the torso. Architect the motion-data model, session format, analysis code, and metrics so that iPhone and Watch recordings can eventually be compared using the same pipeline. Do not unnecessarily couple the analysis layer to UIKit/iPhone-specific concepts. Primary research questions We ultimately want to determine: 1. How far does the rider move/tilt relative to a calibrated neutral riding position? 2. How smoothly does the rider transition between positions? 3. How repeatable are repeated left and right transitions? 4. Are there meaningful left/right asymmetries? 5. How long does each transition take? 6. Can we identify the start, peak movement, settling, hold, and return portions of a transition? 7. Later, can the Apple Watch capture these same features with sufficient sample rate, latency, sensitivity, noise level, and repeatability compared with the iPhone? Do not optimize prematurely around a single "smoothness score." Preserve the raw data needed to experiment with different metrics offline. Core Motion capture Use Apple's Core Motion framework and one shared CMMotionManager. Record processed CMDeviceMotion data at the highest sensible supported/requestable rate for this experiment. Initially request 100 Hz, but do not assume that 100 Hz is actually delivered. For every sample record: - Core Motion timestamp - host/monotonic timestamp if useful for cross-checking - attitude roll, pitch, yaw - attitude quaternion x/y/z/w - attitude rotation matrix if inexpensive/useful - rotationRate x/y/z - gravity x/y/z - userAcceleration x/y/z - magnetic-field data and calibration accuracy if available - heading/heading accuracy if available Also investigate whether recording raw accelerometer and raw gyroscope streams simultaneously provides useful additional information beyond CMDeviceMotion. If Core Motion permits this cleanly without compromising sampling behavior, record: - raw accelerometer x/y/z + timestamp - raw gyroscope x/y/z + timestamp Keep these as separate timestamped streams rather than pretending samples occurred simultaneously. Never manufacture samples to create an artificial fixed-rate stream. Preserve the actual sensor timestamps. Calculate and report the actual achieved sampling characteristics after each recording: - sample count - duration - mean Hz - median Hz - min/max inter-sample interval - standard deviation of interval - p95 and p99 interval - number/percentage of unusually large gaps or dropped/late samples This instrumentation is important because we will later run essentially the same experiment on Apple Watch Ultra 2 and compare the hardware/platforms. Calibration Provide a large Calibrate Neutral button. The rider sits centered on the stationary motorcycle in normal neutral riding posture and remains still for approximately 2–3 seconds. Collect multiple samples during calibration rather than relying on one instantaneous reading. Establish a neutral reference orientation from those samples. Prefer quaternion/reference-frame math internally rather than simply subtracting Euler angles where that can introduce wrapping/gimbal issues. After calibration, express subsequent orientation as relative orientation from the rider's own neutral position. The physical phone orientation should therefore not need to be perfectly vertical or perfectly aligned with the motorcycle. It only needs to remain rigidly mounted after calibration. Show the user simple derived values such as: - relative left/right angle - relative forward/back angle - axial rotation if meaningful Clearly document exactly how device axes map into these derived rider axes. Recording UI Keep V0 intentionally simple. Main screen: - sensor availability/status - requested sample rate - current measured sample rate - Calibrate Neutral - Start Recording - Stop Recording - elapsed recording time - sample count - current relative orientation values - obvious recording indicator Prevent accidental loss of a completed recording. Do not build accounts, cloud sync, subscriptions, social features, GPS, maps, track databases, Bluetooth helmet feedback, or elaborate visual design. Event markers During recording provide large buttons for: - LEFT - CENTER - RIGHT - GOOD - BAD Each simply writes a timestamped marker into the session. Also provide an optional audible cue/test mode that can generate a simple sequence such as: CENTER → LEFT → CENTER → RIGHT → CENTER Record the exact timestamp at which each cue was issued so we can later calculate cue-to-movement timing. Do not attempt to judge the rider in real time yet. Data storage/export Save each recording as a self-contained session with metadata including: - session UUID - device model - OS version - app version - requested update intervals - achieved sampling statistics - calibration information - recording start/end information - all raw/fused sensor samples - event/cue markers Choose a straightforward versioned schema that can later represent both platform: iphone and platform: apple_watch. Prefer a lossless machine-readable master format such as JSON/JSONL or an appropriately simple structured format. Also provide CSV export suitable for Python/pandas analysis. Use the iOS share sheet so the recording can easily be exported to Files/AirDrop/etc. Do not throw away precision to make the files pretty. Initial post-session analysis Implement a separate analysis layer that operates on the recorded session model rather than directly on Core Motion. Initially calculate/visualize: - relative orientation vs time - angular velocity vs time - angular acceleration vs time - user acceleration vs time - approximate transition start/end - peak relative angle - transition duration - settling time - overshoot - number/magnitude of secondary corrections Investigate angular jerk / change in angular acceleration, but don't assume that one mathematical definition of jerk is automatically our desired smoothness metric. Experiment with several candidate smoothness measurements, for example: - integrated squared jerk - peak jerk - RMS jerk - normalized jerk - spectral/high-frequency energy - number and amplitude of reversals/corrections - shape of angular-velocity profile Explain in code/comments what each metric represents and its limitations. A visually smooth deliberate body transition should ideally produce a relatively simple angular-velocity profile—acceleration into the movement, peak velocity, deceleration, then a stable settled position—rather than repeated corrections or high-frequency spikes. But do not bake that assumption into the data collection layer. Simple results screen After recording, provide a basic session review showing: - timeline plots for relative angle - angular velocity - acceleration - markers/cues - detected transitions For each detected transition show: - direction - starting angle - ending/peak angle - range of movement - duration - settling time - candidate smoothness metrics Also calculate session-level: - left/right range distributions - repeatability/variance - left/right asymmetry - transition-duration distribution - smoothness distributions Do not reduce everything to a single score yet. Architecture for upcoming Apple Watch experiment Design around a platform-neutral structure conceptually similar to: MotionSample MotionStream Calibration MotionSession EventMarker Transition MotionAnalyzer The analysis code should consume these common models and ideally be reusable by the future watchOS target. The next experiment will run equivalent body-position drills with: 1. iPhone mounted rigidly at the sternum 2. Apple Watch Ultra 2 mounted rigidly at approximately the same torso location Eventually we may record both simultaneously. Therefore ensure the format preserves sufficient timing information to compare: - achieved sample frequency - timing jitter - apparent latency - sensor noise while stationary - sensitivity to slow movement - sensitivity to rapid movement - orientation drift - transition onset timing - peak angular velocity - calculated range - calculated smoothness - repeatability Include a small Sensor Diagnostics mode specifically for this purpose. It should record approximately 30 seconds of stationary data followed by controlled movements and produce basic noise/sampling statistics. Important engineering principles - Preserve raw measurements. - Derived metrics must be reproducible from saved data. - Timestamp everything. - Never assume requested sample rate equals delivered sample rate. - Keep sensor acquisition separate from analysis. - Keep analysis platform-independent wherever practical. - Prefer correctness and inspectability over abstraction. - Document coordinate systems and units explicitly. - Avoid premature filtering. Save unfiltered data and perform filtering as a derived analysis operation. - When filtering is introduced, make parameters explicit and preserve the original stream. - Don't invent unsupported sensor capabilities. If an API/platform limitation is encountered, document it. V0 definition of done I should be able to install the app on my iPhone 16 Pro, rigidly strap the phone to the center of my torso, put my motorcycle securely on stands, sit on it, press Calibrate Neutral, press Record, perform roughly 50 deliberate left/right/center body-position transitions, stop recording, and inspect/export a dataset from which we can objectively answer: Can an iPhone IMU reliably distinguish the range, timing, repeatability, and smoothness of my motorcycle body-position transitions? The implementation should also leave us in a position where the next development task is adding a watchOS target for Apple Watch Ultra 2 and running the same protocol to answer: What measurable information, if anything, do we lose by replacing the torso-mounted iPhone with the much smaller torso-mounted Apple Watch? Before implementing, inspect the current Apple documentation for the relevant Core Motion APIs and current iOS/watchOS constraints. Briefly state any design decisions that depend on those APIs. Then implement the smallest functional version meeting this experiment rather than expanding scope.