Core Motion

RSS for tag

Process accelerometer, gyroscope, pedometer, and environment-related events using Core Motion.

Core Motion Documentation

Posts under Core Motion tag

35 Posts
Sort by:
Post not yet marked as solved
0 Replies
428 Views
I am trying to read core motion data (accel, gyro) and store them using my iWatch 6 for an extended amount of time (about 14 days). So, I realize that my application becomes unresponsive. I looked into it and I think that the watchdog kills my application because I am constantly writing stuff in OperationQueue.current! .To extract data from this queue, I need to get the foreground. So, I thought that my best bet would be to schedule a task and call it every ~30 min to do that for me. But when I schedule a task, it keeps happening for the first couple of times and then becomes very sporadic (maybe every 10 hours instead of 30 min). So, I am just looking for a way to do such an EASY task. Since I was not able to use the scheduleBackgroundRefresh, I am using the locationmanager as an alternative (just like a timer) as it can run in the background. I know that it is not the best practice but I could not find any other way around this. To save the battery, I used the reduced accuracy which collects the location every 15 minutes or so. This runs great up until 8 hours. Then it becomes sporadic again! I am not sure what to do with that. // // ExtensionDelegate.swift // STMITest WatchKit Extension import WatchKit import CoreMotion class ExtensionDelegate: NSObject, WKExtensionDelegate, CLLocationManagerDelegate {   let motionManagerDelegate = CMMotionManager()   let locationManager:CLLocationManager = CLLocationManager()       var sensorTime=[Double]()   var sensorRx=[Double]()   var sensorRy=[Double]()   var sensorRz=[Double]()   var offsetTime=0.0   var offsetTimeFlag=true       var lastSyncedDate=Date()   var locationStartDate=Date()       func applicationDidFinishLaunching() {     print("Delegate:App finished lunching")           locationConfig()     locationStarter()           lastSyncedDate=Date()     locationStartDate=Date()   }           func locationConfig(){     print("LocationConfig Func")     locationManager.delegate=self     locationManager.desiredAccuracy = kCLLocationAccuracyReduced     locationManager.allowsBackgroundLocationUpdates=true     locationManager.activityType = .fitness   }       func locationStarter(){     if locationManager.authorizationStatus == .authorizedWhenInUse || locationManager.authorizationStatus == .authorizedAlways{       print("-------------initiation-authority is ok")       locationManager.startUpdatingLocation()     }     else{       print("-------------initiation-authority is changing")       locationManager.requestWhenInUseAuthorization()     }   }       func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {     if locations.first != nil {       print("location:: \(locations)")     }     startQueuedMotionUpdates()     var timeInterval=Date().timeIntervalSince(lastSyncedDate)     if timeInterval > 1 * 60{       binaryWriter("GPSSuccess")       lastSyncedDate=Date()     }     timeInterval=Date().timeIntervalSince(locationStartDate)     if timeInterval > 3 * 60 * 60{       locationManager.stopUpdatingLocation()       locationManager.startUpdatingLocation()     }   }       func locationManager(_ manager: CLLocationManager, didFailWithError error: Error ) {     print("Error in location manager")     startQueuedMotionUpdates()     var timeInterval=Date().timeIntervalSince(lastSyncedDate)     if timeInterval > 1 * 60{       binaryWriter("GPSError")       lastSyncedDate=Date()     }     timeInterval=Date().timeIntervalSince(locationStartDate)     if timeInterval > 3 * 60 * 60{       locationManager.stopUpdatingLocation()       locationManager.startUpdatingLocation()     }   }       func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {     print("authority should change",self.locationManager.authorizationStatus)     switch manager.authorizationStatus {     case .restricted, .denied, .notDetermined:       print("restricted, denied or notDetermined")       locationManager.requestWhenInUseAuthorization()       break             case .authorizedAlways:       print("always on")       break                case .authorizedWhenInUse:       print("only when it is in use")       locationManager.startUpdatingLocation()     }   }     //  func taskScheduler(){ //    let fireDate=Date(timeIntervalSinceNow: 60*60) //    let wkExt = WKExtension.shared() //    let info: NSDictionary = ["Caller": "to update motion"] //    wkExt.scheduleBackgroundRefresh(withPreferredDate: fireDate,userInfo:info) { (error: Error?) in if (error != nil) { //      print("background refresh could not be scheduled.") //    } //    else{ //      print("successfully scheduled") //    } //    } // //  }       func startQueuedMotionUpdates() {     if self.motionManagerDelegate.isDeviceMotionAvailable {       if !motionManagerDelegate.isDeviceMotionActive{         motionManagerDelegate.deviceMotionUpdateInterval = 30.0 / 60.0         motionManagerDelegate.showsDeviceMovementDisplay = true       }       motionManagerDelegate.startDeviceMotionUpdates(using: .xMagneticNorthZVertical, to: OperationQueue.current!, withHandler: { (data, error) in           if let validData = data {             let rX = validData.rotationRate.x             let rY = validData.rotationRate.y             let rZ = validData.rotationRate.z                           let aX = validData.userAcceleration.x             let aY = validData.userAcceleration.y             let aZ = validData.userAcceleration.z                           let timeStamp=validData.timestamp             if self.offsetTimeFlag{               self.offsetTime = 0.0-timeStamp               self.offsetTimeFlag=false             } //            self.sensorTime.append(contentsOf: [timeStamp+self.offsetTime])             self.sensorTime.append(contentsOf: [timeStamp+self.offsetTime,rX,rY,rZ,aX,aY,aZ])           }         })     }     else {       fatalError("The motion data is not avaialable")     }   }       func binaryWriter(_ extensionName: String) {     var myDate = Date()     let dateFormatter = DateFormatter()     dateFormatter.dateFormat = "dd-HH:mm:ss"     var currentTime = dateFormatter.string(from: myDate)     var fileName = currentTime+extensionName           print("Writing Start========================",fileName)     if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {       do {         fileName = currentTime+extensionName+"Time"         var fileURL = dir.appendingPathComponent(fileName)         try (self.sensorTime as NSArray).write(to: fileURL,atomically: true)         self.sensorTime.removeAll()                 }       catch{         print("Error in the binaryWriter Function")       }     }     myDate = Date()     currentTime = dateFormatter.string(from: myDate)     print("Writing End========================",currentTime)   } }
Posted
by
Post not yet marked as solved
0 Replies
334 Views
Hi I am pretty new to ios development and I am trying to write a code to store the acceleration and gyro data into files using iwatch se (OS 7.5), iPhone XSMax (14.7.1) and XCode 12.5.1. I wrote most of my application in the ExtensionDelegate which I put below. The application gets killed after a couple of hours. Any ideas why? I think the watchdog kills it. I know this is not the most efficient way to write it but I was unable to make the timer thing working in the background! :( import WatchKit import CoreMotion class ExtensionDelegate: NSObject, WKExtensionDelegate {   let motionManagerDelegate = CMMotionManager()   var sensorDataDelegate=[Double]()   var offsetTime=0.0   var offsetTimeFlag=true       func applicationDidFinishLaunching() {     print("Delegate:App finished lunching")     self.startQueuedMotionUpdates()   }   func applicationDidBecomeActive() {     print("Delegate:App active") //    self.startQueuedMotionUpdates()     // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.   }   func applicationWillResignActive() {     print("Delegate:App will be active") //    self.startQueuedMotionUpdates()     // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.     // Use this method to pause ongoing tasks, disable timers, etc.   }       func applicationDidEnterBackground() {     print("Delegate:App is background") //    self.startQueuedMotionUpdates()     self.binaryWriter()   }       func applicationWillEnterForeground() {     print("Delegate:App will be foreground") //    self.startQueuedMotionUpdates()   }           func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) {     // Sent when the system needs to launch the application in the background to process tasks. Tasks arrive in a set, so loop through and process each one.     self.startQueuedMotionUpdates()     self.binaryWriter()     for task in backgroundTasks {       // Use a switch statement to check the task type       switch task {         case let backgroundTask as WKApplicationRefreshBackgroundTask:           // Be sure to complete the background task once you’re done.           backgroundTask.setTaskCompletedWithSnapshot(false)         case let snapshotTask as WKSnapshotRefreshBackgroundTask:           // Snapshot tasks have a unique completion call, make sure to set your expiration date           snapshotTask.setTaskCompleted(restoredDefaultState: true, estimatedSnapshotExpiration: Date.distantFuture, userInfo: nil)         case let connectivityTask as WKWatchConnectivityRefreshBackgroundTask:           // Be sure to complete the connectivity task once you’re done.           connectivityTask.setTaskCompletedWithSnapshot(false)         case let urlSessionTask as WKURLSessionRefreshBackgroundTask:           // Be sure to complete the URL session task once you’re done.           urlSessionTask.setTaskCompletedWithSnapshot(false)         case let relevantShortcutTask as WKRelevantShortcutRefreshBackgroundTask:           // Be sure to complete the relevant-shortcut task once you're done.           relevantShortcutTask.setTaskCompletedWithSnapshot(false)         case let intentDidRunTask as WKIntentDidRunRefreshBackgroundTask:           // Be sure to complete the intent-did-run task once you're done.           intentDidRunTask.setTaskCompletedWithSnapshot(false)         default:           // make sure to complete unhandled task types           task.setTaskCompletedWithSnapshot(false)       }     }   }   func startQueuedMotionUpdates() {     var myDate = Date()     var dateFormatter = DateFormatter()     dateFormatter.dateFormat = "yyyy-MM-dd-HH:mm:ss"     var currentTime = dateFormatter.string(from: myDate)                 print("sensor function starts==============================",currentTime)           if self.motionManagerDelegate.isDeviceMotionAvailable {       if !self.motionManagerDelegate.isDeviceMotionActive{         self.motionManagerDelegate.deviceMotionUpdateInterval = 30 / 60.0         self.motionManagerDelegate.showsDeviceMovementDisplay = true       }         self.motionManagerDelegate.startDeviceMotionUpdates(using: .xMagneticNorthZVertical, to: OperationQueue.current!, withHandler: { (data, error) in           if let validData = data {             let rX = validData.rotationRate.x             let rY = validData.rotationRate.y             let rZ = validData.rotationRate.z             let timeStamp=validData.timestamp             if self.offsetTimeFlag{ //              let currentTime=Date().timeIntervalSince1970 //              self.offsetTime=currentTime-timeStamp               self.offsetTime = 0.0-timeStamp               self.offsetTimeFlag=false             }             self.sensorDataDelegate.append(contentsOf: [timeStamp+self.offsetTime])           }         })     }     else {       fatalError("The motion data is not avaialable")     }     myDate = Date()     currentTime = dateFormatter.string(from: myDate)     print("sensor function ends==============================",currentTime)   }       func binaryWriter() {     var tempVal = self.sensorDataDelegate     var myDate = Date()     var dateFormatter = DateFormatter()     dateFormatter.dateFormat = "MM-dd-HH:mm:ss"     var fileName = dateFormatter.string(from: myDate)           print("Writing Start========================",fileName)     if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {       let fileURL = dir.appendingPathComponent(fileName)       do {         try (tempVal as NSArray).write(to: fileURL,atomically: true)       }       catch {/* error handling here */}     }           myDate = Date()     var currentTime = dateFormatter.string(from: myDate)     print("Writing End========================",currentTime)     self.sensorDataDelegate.removeAll()     myDate = Date()     currentTime = dateFormatter.string(from: myDate)     print("Data is cleaned========================",currentTime)   }     }
Posted
by
Post not yet marked as solved
0 Replies
486 Views
Create a sample project in Creat ML and choose Activity Classifier. When lowering the sample rate, the preview timeline gets shorter instead of getting longer. Furthermore, it seems the entire preview timeline breaks (can't scroll) if the sample rate is anything other than 50. Try it out: Train a model with sample rate 50, then try training it with sample rate 10.
Posted
by
Post marked as solved
1 Replies
603 Views
Hi I am having an issue accessing gyroscope and magnometer data through CoreMotion. I have an apple watch 6 (os 7.6), iPhone XS max (ios 14.7) and XCode 12.5.1. I did write a simple application to print the accel, gyro and magno data. It works on the phone but not on the watch. On the watch, it only gives me accel data and when I do isGyroAvailable or isMagnoAvailable I get False, while isAccelAvailable gives me True. Should I turn on something? Maybe an authentication flag? Any help will be greatly appreciated.
Posted
by
Post not yet marked as solved
0 Replies
332 Views
I am recording accelerometer data using CMSensorRecorder and then trying to retrieve the data in background refresh. However, I am getting the following error: "[Connection] Error on message reply (sync) for kCLConnectionMessageSensorRecorderGetMetasByDateRange (Connection interrupted)" Thanks in advance.
Posted
by
Post not yet marked as solved
1 Replies
398 Views
Hi Team, help me out to know,, is it possible to get user activity status , even when app is TERMINATED or SUSPENDED. NOTE: as of now, i can track user activity , when app is in background i want to get activity , even when app is TERMINATED BY USER. thanks in advance, help me out.
Posted
by
Post not yet marked as solved
1 Replies
534 Views
I'm writing to see if anyone can help me debug a common crash I see in my crash reports. Context: My app uses CoreLocation for location tracking and also ARKit. These are both used only while the user is 3D scanning, and otherwise they are not used. We see the crash happening randomly when the user is in 3D scanning mode, also when they are not (when CoreLocation and CoreMotion should not be used at all). This is the most common crash we see in Crashlytics, but there is no reliably way to reproduce and as far as we can tell we are using the frameworks correctly. Does anybody know what's going on or have any suggestions to help debug? Much appreciated Stack trace: 0 CoreMotion 0x1b5aa4774 CLClientCreateIso6709Notation + 190724 1 CoreMotion 0x1b5a9f69c CLClientCreateIso6709Notation + 170028 2 CoreMotion 0x1b5b4680c CLShouldDisplayEEDUI + 271016 3 IOKit 0x1b5864958 __IOHIDEventSystemClientQueueCallback + 288 4 CoreFoundation 0x1aa90ba5c __CFMachPortPerform + 176 5 CoreFoundation 0x1aa931274 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 60 6 CoreFoundation 0x1aa9305f4 __CFRunLoopDoSource1 + 596 7 CoreFoundation 0x1aa92a1d8 __CFRunLoopRun + 2372 8 CoreFoundation 0x1aa929360 CFRunLoopRunSpecific + 600 9 CoreFoundation 0x1aa92a44c CFRunLoopRun + 64 10 CoreMotion 0x1b5aa5c78 CLClientCreateIso6709Notation + 196104 11 libsystem_pthread.dylib 0x1f6630bfc _pthread_start + 320 12 libsystem_pthread.dylib 0x1f6639758 thread_start + 8
Posted
by
Post not yet marked as solved
2 Replies
761 Views
In the documentation for CMFallDetectionManager and CMFalDetectionDelegate in XCode, there is a comment that says, "Fall Detection events can be simulated with the watchOS simulator. Use it to test the background functionality of your app." I have not seen any instructions or guides about how to do this. Therefore, I am wondering how I can simulate Fall Detection events in the WatchOS Simulator? Thank you so much!
Posted
by
Post not yet marked as solved
2 Replies
835 Views
I want to record both IMU data and Audio data from Airpods Pro. I have tried many times, and I failed. I can successfully record the IMU data and iPhone's microphone data simultaneously. When I choose Airpods Pro's microphone in the setCategory() function, the IMU data collection process stopped. If I change recordingSession.setCategory(.playAndRecord, mode: .default, options: .allowBluetooth) to ecordingSession.setCategory(.playAndRecord, mode: .default), everything is okay except the audio is recorded from the handphone. If I add options: .allowBluetooth, the IMU update will stop. Could you give me some suggestions for this? Below are some parts of my code.   let My_IMU = CMHeadphoneMotionManager()   let My_writer = CSVWriter()   var write_state: Bool = false   func test()   {     recordingSession = AVAudioSession.sharedInstance()     do {       try recordingSession.setCategory(.playAndRecord, mode: .default, options: .allowBluetooth)       try recordingSession.setActive(true)       recordingSession.requestRecordPermission() { [unowned self] allowed in         DispatchQueue.main.async {           if allowed == false {print("failed to record!")}         }       }     } catch {       print("failed to record!")     }                 let audioFilename = getDocumentsDirectory().appendingPathComponent("test_motion_Audio.m4a")     let settings = [       AVFormatIDKey: Int(kAudioFormatMPEG4AAC),       AVSampleRateKey: 8000,       AVNumberOfChannelsKey: 1,       AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue     ]     do     {       audioRecorder = try AVAudioRecorder(url: audioFilename, settings: settings)       audioRecorder.delegate = self       audioRecorder.record()     }     catch     {       print("Fail to record!")       finishRecording()     }           write_state.toggle()     let dir = FileManager.default.urls(      for: .documentDirectory,      in: .userDomainMask     ).first!           let filename = "test_motion_Audio.csv"     let fileUrl = dir.appendingPathComponent(filename)     My_writer.open(fileUrl)           APP.startDeviceMotionUpdates(to: OperationQueue.current!, withHandler: {[weak self] motion, error in       guard let motion = motion, error == nil else { return }       self?.My_writer.write(motion)     })   }
Posted
by
Post not yet marked as solved
1 Replies
959 Views
I am trying to use the Fall Detection API to handle fall event, but I keep getting : [Fall] Error fetching most recent fall event: 111 I am using CMFallDetectionManager with delegate The call back like the one below is not happening, any idea why? How to simulate fall using the Watch Series 6 simulator? func fallDetectionManager(_ fallDetectionManager: CMFallDetectionManager, didDetect event: CMFallDetectionEvent, completionHandler handler: @escaping () - Void) {     logger.debug("Fall Event Detected") }
Posted
by
Post not yet marked as solved
2 Replies
766 Views
Hello everyone. I'm trying to work with Core Motion, getting readings from my Apple Watch (Series 4), but am getting inconsistent behaviour. If I run the code from Apple's Core Motion documentation - https://developer.apple.com/documentation/coremotion/getting_processed_device-motion_data (see Listing 1), I don't get any readings. The code I run, which works fine on iPhone, but not on Apple Watch, is: func startDeviceMotion() { if motion.isDeviceMotionAvailable { self.motion.deviceMotionUpdateInterval = 1.0 / 60.0 self.motion.showsDeviceMovementDisplay = true self.motion.startDeviceMotionUpdates(using: .xMagneticNorthZVertical) self.timer = Timer(fire: Date(), interval: (1.0 / 60.0), repeats: true, block: { (timer) in if let data = self.motion.deviceMotion { let x = data.attitude.pitch let y = data.attitude.roll let z = data.attitude.yaw } }) RunLoop.current.add(self.timer!, forMode: RunLoop.Mode.default) } } The problem is that although .isDeviceMotionAvailable returns true and runs the if statement correctly, the returned data from self.motion.deviceMotion only gives me nil's. I.e. DeviceMotion is available but still returns nil. What I have tried so far without luck, is: Adding various Accelerometer, Gyroscope, Location, and Privacy entries to my Info.plist Modifying the code: lowered the update interval checking for returned errors from the closure running it on a different thread Searched online for example projects, StackOverflow, etc., but without luck Run the code as an iPhone app. Here it works as expected without issues. I'm fairly new to this forum and Apple Development, so any help would be much appreciated!
Posted
by
Post not yet marked as solved
0 Replies
734 Views
Hi everybody, Thanks for review my ask. I'm developing an app for WatchOS. I want to detect a magnetic field near to iWatch but when ask to isMagnetometerAvailable always response false. In iOS I've been able to detect a magnetic field save data from this to analyse. My iWatch has the compass and I thought that it was possible to detect a magnetic field like this app. Is possible in WatchOS detect a magnetic field with magnetometer?
Posted
by
Post not yet marked as solved
2 Replies
643 Views
Dear all,I am trying to get data from the magnetometer in my watch series 5.I am trying to see is the magentometer is available usingmotionManager.isMagnetometerAvailablethat always return a false value.Can I access to raw magnetometer data in the watch?
Posted
by
Post marked as solved
3 Replies
963 Views
Hi all, does anyone know if the Mac's, specifically a Mac Air, have the hardware acceleromater and gyros to really support the Core Motion APIs in MacOS?I've got a working iOS app that uses the accelerometer and gyro readings, but I've been asked to port it to a Mac Air.Thanks in advance for your help!A
Posted
by