API Reference
Complete reference of all public types, methods, and properties in RepMotion.
RepMotionCore
MotionSample
A single sensor reading from the device.
public struct MotionSample: Sendable {
public let timestamp: TimeInterval
public let ax: Double, ay: Double, az: Double // accelerometer (g-force)
public let gx: Double, gy: Double, gz: Double // gyroscope (rad/s)
public init(
timestamp: TimeInterval,
ax: Double, ay: Double, az: Double,
gx: Double = 0, gy: Double = 0, gz: Double = 0
)
public func toDictionary() -> [String: Any]
public static func from(dictionary: [String: Any]) -> MotionSample?
}
RepEvent
Emitted when a rep is detected.
public struct RepEvent: Sendable {
public let timestamp: Date
public let confidence: Double // 0.0 to 1.0
public let peakAcceleration: Double // filtered peak value
}
RepCalibration
Configuration for the detection algorithm.
public struct RepCalibration: Sendable {
public var alpha: Double // EMA smoothing (default: 0.2)
public var thresholdMultiplier: Double // stddev multiplier (default: 1.5)
public var refractoryPeriod: Double // min seconds between reps (default: 0.4)
public var detectionAxis: DetectionAxis // .x, .y, or .z (default: .y)
public var peakPolarity: PeakPolarity // .positive or .negative (default: .positive)
public var warmupDuration: TimeInterval // seconds before detection starts (default: 5.0)
public var cooldownDuration: TimeInterval // seconds after exercise ends (default: 3.0)
public static let `default` = RepCalibration()
}
DetectionAxis
public enum DetectionAxis: String, CaseIterable, Identifiable, Sendable {
case x = "X"
case y = "Y"
case z = "Z"
}
PeakPolarity
public enum PeakPolarity: String, CaseIterable, Identifiable, Sendable {
case positive = "Positive (+)"
case negative = "Negative (-)"
public var multiplier: Double // 1.0 or -1.0
}
RepMarker
Marks a rep position in a sample buffer. Identifiable for SwiftUI list rendering.
public struct RepMarker: Identifiable, Sendable {
public let id: UUID
public var bufferIndex: Int
public let confidence: Double
}
DetectionDiagnostic
Per-sample diagnostic data from the detection pipeline.
public struct DetectionDiagnostic: Sendable {
public let sampleIndex: Int
public let rawValue: Double // axis value * polarity, before filtering
public let filteredValue: Double // after EMA smoothing
public let threshold: Double // dynamic threshold
public let mean: Double // rolling 100-sample mean
public let stddev: Double // rolling 100-sample stddev
}
PowerReading
Power metrics for a single rep.
public struct PowerReading: Sendable {
public let relativePower: Double // rep peak / session peak (0.0-1.0)
public let rollingAvgPower: Double // rep peak / rolling 5-rep avg
public let rollingMaxPower: Double // rep peak / rolling 5-rep max
public let peakAcceleration: Double // raw peak this rep (g)
public let repAvgAcceleration: Double // rolling 5-rep avg (g)
public func value(for mode: PowerMode) -> Double
}
PowerMode
public enum PowerMode: String, CaseIterable, Identifiable, Sendable {
case rollingAvg // "Rolling Avg"
case rollingMax // "Rolling Max"
case absolute // "Absolute (g)"
public var displayName: String
}
RepMotionDetection
RepDetectionService
The main detection engine. Processes motion samples and emits rep events.
public final class RepDetectionService {
public var calibration: RepCalibration
// Publishers
public var repPublisher: AnyPublisher<RepEvent, Never>
public var rpmPublisher: AnyPublisher<Double, Never>
public var diagnosticPublisher: AnyPublisher<DetectionDiagnostic, Never>
public var warmupPublisher: AnyPublisher<TimeInterval, Never>
public init()
public func processBatch(_ samples: [MotionSample])
public func reset()
}
CalibrationEngine
Optimizes detection parameters by replaying recorded sessions.
public struct CalibrationEngine: Sendable {
public init()
public func calibrate(
samples: [MotionSample],
target: Int,
current: RepCalibration
) -> CalibrationResult?
}
CalibrationResult
public struct CalibrationResult: Sendable {
public let calibration: RepCalibration
public let detectedReps: Int
public let previousReps: Int
public let targetReps: Int
public let combinationsTested: Int
public let perfectMatches: Int
public var improvement: Int
public var isAlreadyOptimal: Bool
}
PowerEstimationService
Tracks acceleration magnitude across reps for power metrics.
public final class PowerEstimationService {
public var powerPublisher: AnyPublisher<PowerReading, Never>
public init()
public func processBatch(_ samples: [MotionSample])
public func consumeRepEvent(_ event: RepEvent)
public func reset()
}
DistanceEstimationService
Accumulates estimated distance from rep power.
public final class DistanceEstimationService {
public static let defaultBaseMeters: Double // 8.0
public var distancePublisher: AnyPublisher<Double, Never>
public private(set) var totalDistance: Double
public init()
public func addRep(power: Double)
public func reset()
}
RepMotionCapture
MotionProvider
Protocol for motion data sources.
public protocol MotionProvider {
var samplePublisher: AnyPublisher<[MotionSample], Never> { get }
func start()
func stop()
}
MotionCaptureService
Live sensor capture via CoreMotion.
public final class MotionCaptureService: MotionProvider {
public let sampleRate: Double
public init(sampleRate: Double = 50.0)
public var samplePublisher: AnyPublisher<[MotionSample], Never>
public func start()
public func stop()
}
FixtureMotionProvider
Replays pre-recorded samples for testing.
public final class FixtureMotionProvider: MotionProvider {
public init(
samples: [MotionSample],
batchSize: Int = 1,
speedMultiplier: Double = 1.0
)
public var samplePublisher: AnyPublisher<[MotionSample], Never>
public func start() // async replay on timer
public func stop()
public func replayAll() // synchronous, for unit tests
}