Accessing Sensor Data (XCode 13.4.1)

Hello,

I am trying to implement an algorithm that uses sensor data, but I am having trouble accessing the sensor data and storing it in a data array. For example, here is the basic code I'm using to try to access Quaternion and store it in an array:

import UIKit
import CoreMotion
import CoreML
import UserNotifications

protocol Numeric {
   var asDouble: Double { get }
   init(_: Double)
 }
 extension Int: Numeric {var asDouble: Double { get {return Double(self)}}}
 extension Float: Numeric {var asDouble: Double { get {return Double(self)}}}
 extension Double: Numeric {var asDouble: Double { get {return Double(self)}}}
 extension CGFloat: Numeric {var asDouble: Double { get {return Double(self)}}}
 extension Array where Element: Numeric {
   var mean : Element { get { return Element(self.reduce(0, {$0.asDouble + $1.asDouble}) / Double(self.count))}}
   var sd : Element { get {
    let sss = self.reduce((0.0, 0.0)){ return ($0.0 + $1.asDouble, $0.1 + ($1.asDouble * $1.asDouble))}
    let n = Double(self.count)
    return Element(sqrt(sss.1/n - (sss.0/n * sss.0/n)))
   }}
 }
extension Array where Element: Hashable {
  func allEqual(to value: Element) -> Bool {
    let set = Set(self)
    return (set.count == 1 && set.first == value)
  }
}

class ViewController: UIViewController {
   
  @IBOutlet weak var quaternionX: UILabel!
  @IBOutlet weak var quaternionY: UILabel!
  @IBOutlet weak var quaternionZ: UILabel!
  @IBOutlet weak var quaternionW: UILabel!
  
  @IBOutlet weak var predicted_activity: UILabel!
   
  struct ModelConstants {
    static let predictionWindowSize = 50
    static let sensorsUpdateInterval = 1.0 / 50.0
    static let stateInLength = 400
  }
   
  var pred_action = "Nothing yet"

  let activityClassificationModel = TC_RF()
  var currentIndexInPredictionWindow = 0
   
  var quaternionDataX = Array(repeating: Double(0), count: ModelConstants.predictionWindowSize)
  var quaternionDataY = Array(repeating: Double(0), count: ModelConstants.predictionWindowSize)
  var quaternionDataZ = Array(repeating: Double(0), count: ModelConstants.predictionWindowSize)
  var quaternionDataW = Array(repeating: Double(0), count: ModelConstants.predictionWindowSize)

  var quaternionDataX_mean = Double(0)
  var quaternionDataY_mean = Double(0)
  var quaternionDataZ_mean = Double(0)
  var quaternionDataW_mean = Double(0)
  var quaternionDataX_std = Double(0)
  var quaternionDataY_std = Double(0)
  var quaternionDataZ_std = Double(0)
  var quaternionDataW_std = Double(0)
  var quaternionDataX_min = Double(0)
  var quaternionDataY_min = Double(0)
  var quaternionDataZ_min = Double(0)
  var quaternionDataW_min = Double(0)
  var quaternionDataX_max = Double(0)
  var quaternionDataY_max = Double(0)
  var quaternionDataZ_max = Double(0)
  var quaternionDataW_max = Double(0)


 let motionManager = CMMotionManager()
   
  override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    notif_log.delegate = self
    notif_log.dataSource = self
    UNUserNotificationCenter.current().delegate = self
    MyQuaternion()

    self.scheduleNotifications(content_body: self.pred_action)

  }

   func MyQuaternion(){
    guard motionManager.isDeviceMotionAvailable else {
      print("Device Motion is not available on the device")
      return }
     
    motionManager.deviceMotionUpdateInterval = TimeInterval(ModelConstants.sensorsUpdateInterval)
     
   
    motionManager.startDeviceMotionUpdates(to: OperationQueue.current!){ (quaternionData, error) in
      if let quaternionData = quaternionData {
        self.quaternionX.text = "\(quaternionData.attitude.quaternion.x)"
        self.quaternionY.text = "\(quaternionData.attitude.quaternion.y)"
        self.quaternionZ.text = "\(quaternionData.attitude.quaternion.z)"
        self.quaternionW.text = "\(quaternionData.attitude.quaternion.w)"
         
        // Add the current data sample to the data array
        self.addQuaternionSampleToDataArray(deviceMotionSample: quaternionData.attitude.quaternion)
      }
       
    }
     
  }
   
  func addQuaternionSampleToDataArray (deviceMotionSample: CMQuaternion) {
    // Add the current gyroscope reading to the data array
    quaternionDataX[currentIndexInPredictionWindow] = deviceMotionSample.x
    quaternionDataY[currentIndexInPredictionWindow] = deviceMotionSample.y
    quaternionDataZ[currentIndexInPredictionWindow] = deviceMotionSample.z
    quaternionDataW[currentIndexInPredictionWindow] = deviceMotionSample.w

    // Update the index in the prediction window data array
    currentIndexInPredictionWindow += 1

    // If the data array is full, call the prediction method to get a new model prediction.
    // We assume here for simplicity that the Gyro data was added to the data arrays as well.
    if (currentIndexInPredictionWindow == ModelConstants.predictionWindowSize) {
       
      quaternionDataX_mean = Double(quaternionDataX.mean)
      quaternionDataY_mean = Double(quaternionDataY.mean)
      quaternionDataZ_mean = Double(quaternionDataZ.mean)
      quaternionDataW_mean = Double(quaternionDataW.mean)
      quaternionDataX_std = Double(quaternionDataX.sd)
      quaternionDataY_std = Double(quaternionDataY.sd)
      quaternionDataZ_std = Double(quaternionDataZ.sd)
      quaternionDataW_std = Double(quaternionDataW.sd)
      quaternionDataX_min = Double(quaternionDataX.min() ?? 0)
      quaternionDataY_min = Double(quaternionDataY.min() ?? 0)
      quaternionDataZ_min = Double(quaternionDataZ.min() ?? 0)
      quaternionDataW_min = Double(quaternionDataW.min() ?? 0)
      quaternionDataX_max = Double(quaternionDataX.max() ?? 0)
      quaternionDataY_max = Double(quaternionDataY.max() ?? 0)
      quaternionDataZ_max = Double(quaternionDataZ.max() ?? 0)
      quaternionDataW_max = Double(quaternionDataW.max() ?? 0)
       
      if let predictedActivity = performModelPrediction() {

        // Use the predicted activity here
        // ...
   
        switch predictedActivity {
          case "0":
            self.predicted_activity.text = "Eating"
            self.pred_action = "Eating"
            self.scheduleNotifications(content_body: self.pred_action)
         
          case "1":
            self.predicted_activity.text = "Eye rubbing light"
            self.pred_action = "Eye rubbing light"
            self.scheduleNotifications(content_body: self.pred_action)
         
         
        default:
          print("Have you done something ?")
        }
         
        //self.predicted_activity.setText(predictedActivity)

        // Start a new prediction window
        currentIndexInPredictionWindow = 0
         
      }
    }
  }

I'm not sure exactly where it's going wrong. Any advice would be appeciated.

You write data into the array, but where do you store array permanently ?

Accessing Sensor Data (XCode 13.4.1)
 
 
Q