I'm trying to detect Automotive
ActivtyType, however the problem is if "I go on a drive and then stop the car and stay in the car" and simply check the coreMotion logs: I would continue to get numerous mixed callbacks of either
high Confidence: Automotive: True, Stationary: True
or
high confidence: Automotive: True, Stationary: False
or
low confidence: Automotive: True, Stationary: True
I do not get an only Stationary: True, it always comes with automotive being True as well
There's not much of a pattern to how they come, or at least I haven't been able to find a pattern.
Q: Has anyone found a reliable way of detecting when the car is truly automotive?
I've tried counting the number of callbacks I get and then doing some calculation but that doesn't seem reliable.
FWIW the moment the user gets out of the car then I get either a walking or stationary (with no automotive...which is good) callback and use those callbacks to set a flag to true...so after that if I get any automotive
callback...then I know it’s a real automotive...
My code:
func beginMotionTracking(){
let motionLog = OSLog(subsystem: "Spike", category: "Motion")
shouldUseTimer = false
motionActivityManager = CMMotionActivityManager()
var totalWalking = 0
var totalAutomotive = 0
var totalStationary = 0
var totalFalseAutomotive = 0
motionActivityManager?.startActivityUpdates(to: OperationQueue.main){
[weak self] activity in
os_log("Motion is Tracking | desiredAccuracy is %{public}f | RemainingTime : %{public}f ",log: motionLog, type: .default, (self?.locationManager.desiredAccuracy)! , UIApplication.shared.remainingTime())
if activity?.walking == true && (activity?.confidence == .medium || activity?.confidence == .high) && activity?.automotive == false && activity?.stationary == false && activity?.unknown == false {
totalWalking += 1
os_log("medium and high conf: walking %{public}d time", log: motionLog, type: .error, totalWalking)
}else if activity?.stationary == true && (activity?.confidence == .medium || activity?.confidence == .high) && activity?.automotive == false && activity?.walking == false && activity?.unknown == false {
totalStationary += 1
os_log("medium and high conf: stationary %{public}d time", log: motionLog, type: .error, totalStationary)
// false automotive
}else if activity?.automotive == true && activity?.stationary == true && (activity?.confidence == .high) && activity?.walking == false && activity?.unknown == false {
totalFalseAutomotive += 1
os_log("high conf: FALSE Automotive %{public}d time", log: motionLog, type: .error, totalFalseAutomotive)
if totalFalseAutomotive > 2{
totalFalseAutomotive = 0
totalAutomotive = 0
totalStationary = 0
totalWalking = 0
os_log("Too many FALSE automotives, REST all counts back to 0", log: motionLog, type: .fault)
}
}
else if activity?.automotive == true && (activity?.confidence == .high) && activity?.walking == false && activity?.stationary == false && activity?.unknown == false {
totalAutomotive += 1
os_log("high conf: Automotive %{public}d time", log: motionLog, type: .error, totalAutomotive)
if ((totalWalking > 3 && totalAutomotive > 2) || (totalStationary > 3 && totalAutomotive > 2) || (totalAutomotive > 7)){
self?.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
os_log("Motion is Automotive and is about to be stopped: desired AccuracyChanged to HundredMeters | RemainingTime : %{public}f ", log: motionLog, type: .fault, UIApplication.shared.remainingTime())
self?.shouldUseTimer = true
self?.motionActivityManager?.stopActivityUpdates()
}
}
}
}
I'm going through all this hassle, because I'm trying to degrade my core-location Accuracy whenever the user isn't driving for more than 3 minutes and then later using core-motion to detect automotive
Motion and use that to put back location Accuracy to hundredMeter.