Detecting Driving State with Core Motion Framework - Automotive Accuracy Issues

I am working on an iOS app where I need to detect when a user starts and stops driving using the Apple Core Motion framework. I've implemented the following MotionActivityManager class to handle activity updates and display the detected states in a SwiftUI view.

While I can accurately detect "Stationary" and "Walking" states, detecting the "Driving" (Automotive) state has been unreliable. The accuracy often fails, and the framework frequently misclassifies driving as other states like "Unknown" or "Walking."

Here's the implementation:

@Published var motionStates: [MotionState] = []
@Published var startDate: String = ""
@Published var confidence: String = ""

init() {
    setupDefaultStates()
    startActivityUpdates()
}

private func setupDefaultStates() {
    motionStates = [
        MotionState(label: "Stationary", value: false),
        MotionState(label: "Walking", value: false),
        MotionState(label: "Running", value: false),
        MotionState(label: "Automotive", value: false),
        MotionState(label: "Cycling", value: false),
        MotionState(label: "Unknown", value: false)
    ]
}

func startActivityUpdates() {
    guard CMMotionActivityManager.isActivityAvailable() else {
        print("Motion activity is not available.")
        return
    }

    motionActivityManager.startActivityUpdates(to: .main) { [weak self] motion in
        guard let self = self, let motion = motion else { return }
        DispatchQueue.main.async {
            self.updateProperties(with: motion)
        }
    }
}

private func updateProperties(with motion: CMMotionActivity) {
    motionStates = [
        MotionState(label: "Stationary", value: motion.stationary),
        MotionState(label: "Walking", value: motion.walking),
        MotionState(label: "Running", value: motion.running),
        MotionState(label: "Automotive", value: motion.automotive),
        MotionState(label: "Cycling", value: motion.cycling),
        MotionState(label: "Unknown", value: motion.unknown)
    ]
    startDate = dateFormatter.string(from: motion.startDate)

    switch motion.confidence {
    case .low:
        confidence = "Low"
    case .medium:
        confidence = "Medium"
    case .high:
        confidence = "High"
    @unknown default:
        confidence = "Unknown"
    }
}

}

struct MotionState: Identifiable { let id = UUID() let label: String let value: Bool }

struct ContentView: View { @StateObject private var motionManager = MotionActivityManager()

var body: some View {
    ScrollView {
        VStack(spacing: 16) {
            ForEach(motionManager.motionStates) { state in
                LabelView(label: state.label, value: state.value ? "True" : "False")
            }
            LabelView(label: "Confidence", value: motionManager.confidence)
        }
        .padding()
    }
    .onAppear {
        UIApplication.shared.isIdleTimerDisabled = true
        motionManager.startActivityUpdates()
    }
    .navigationTitle("Motion Activity")
}

} Issues:

The motion.automotive state is often not detected accurately. The confidence level remains low for the automotive state, even when the device is clearly in a car.

How can I improve the detection accuracy of the "Driving" state using the Core Motion framework?

We have seen the motion detection to get confused by certain use cases involving device orientation, vibrations, etc.

We would like to know some more details of the use case here:

  • how is the device traveling inside the car? Is it mounted, in a pocket, face up on a knee. Has changing the handling and orientation made a difference?
  • what is the vehicle and travel mode? A normal car on a highway? Start/Stop traffic? Offroad vehicle? Gravel road?
  • is the vehicle you are testing with running generally smoothly? Is there some vibration of the device?

If all is normal, like a modern car on a highway, going at a normal pace, mounted in a usual fashion, and changing placement and orientation does not make a positive difference, we would like to see a bug report about this.

We'd greatly appreciate it if you could open a bug report, include crash logs and sample code or models that reproduce the issue, and post the FB number here once you do.

Bug Reporting: How and Why? has tips on creating a successful bug report.

Also, we would need a diagnostic log of what's been happening. It would be very helpful if you could please go to https://developer.apple.com/bug-reporting/profiles-and-logs/ and follow the instructions for Location Services for iOS to install a logging profile on your device. Then reproduce the issue, and follow the instructions at the above link to create a sysdiagnose. And attach that to the Feedback report as well.

Please also explain in detail the testing conditions under which you have created that diagnostic log.


Argun Tekant /  DTS Engineer / Core Technologies

Detecting Driving State with Core Motion Framework - Automotive Accuracy Issues
 
 
Q