Apple provides watchOS 3 SwingWatch sample code demonstrating how to use CMMotionManager()
and startDeviceMotionUpdates(to:)
to count swings in a racquet sport.
Their code demonstrates how to detect the direction of a one-second interval of motion, although you may have to tweak the thresholds to account for the characteristics of the motion you want to track.
func processDeviceMotion(_ deviceMotion: CMDeviceMotion) {
let gravity = deviceMotion.gravity
let rotationRate = deviceMotion.rotationRate
let rateAlongGravity = rotationRate.x * gravity.x // r⃗ · ĝ
+ rotationRate.y * gravity.y
+ rotationRate.z * gravity.z
rateAlongGravityBuffer.addSample(rateAlongGravity)
if !rateAlongGravityBuffer.isFull() {
return
}
let accumulatedYawRot = rateAlongGravityBuffer.sum() * sampleInterval
let peakRate = accumulatedYawRot > 0 ?
rateAlongGravityBuffer.max() : rateAlongGravityBuffer.min()
if (accumulatedYawRot < -yawThreshold && peakRate < -rateThreshold) {
// Counter clockwise swing.
if (wristLocationIsLeft) {
incrementBackhandCountAndUpdateDelegate()
} else {
incrementForehandCountAndUpdateDelegate()
}
} else if (accumulatedYawRot > yawThreshold && peakRate > rateThreshold) {
// Clockwise swing.
if (wristLocationIsLeft) {
incrementForehandCountAndUpdateDelegate()
} else {
incrementBackhandCountAndUpdateDelegate()
}
}
// Reset after letting the rate settle to catch the return swing.
if (recentDetection && abs(rateAlongGravityBuffer.recentMean()) < resetThreshold) {
recentDetection = false
rateAlongGravityBuffer.reset()
}
}