Hello, I am getting this error in the console when I run my code but I am not sure what it means:
2022-08-04 15:45:16.959881+0200 HFI WatchKit Extension[427:31640] [View] +[UIView flush] is deprecated, use +[CATransaction flush] instead.
Post
Replies
Boosts
Views
Activity
Hello,
I am trying to access the motion rotation rate on an Apple Watch and store up to 50 consecutive readings in an array. Currently, the readings stop suddenly after 32 readings. I have pretty much the exact same code for acceleration and roll, and the code for those sensors work just fine. Any insight into why this is happening?
struct ModelConstants {
static let predictionWindowSize = 50
static let sensorsUpdateInterval = 1.0 / 50.0
}
let motionManager = CMMotionManager()
func MyGyro(){
guard motionManager.isDeviceMotionAvailable else {
print("Device Motion is not available on the device")
return }
motionManager.deviceMotionUpdateInterval = TimeInterval(ModelConstants.sensorsUpdateInterval)
motionManager.startDeviceMotionUpdates(using: .xMagneticNorthZVertical, to: OperationQueue.current!){ [self] (deviceData, error) in
if let gyroDeviceData = deviceData {
self.gyroX.setText("\(gyroDeviceData.rotationRate.x)")
self.gyroY.setText("\(gyroDeviceData.rotationRate.y)")
self.gyroZ.setText("\(gyroDeviceData.rotationRate.z)")
// Add the current data sample to the data array
self.addGyroSampleToDataArray(deviceMotionSample: gyroDeviceData)
}
}
}
func addGyroSampleToDataArray (deviceMotionSample: CMDeviceMotion) {
// Add the current gyroscope reading to the data array
gyroDataX.append(deviceMotionSample.rotationRate.x)
gyroDataY.append(deviceMotionSample.rotationRate.y)
gyroDataZ.append(deviceMotionSample.rotationRate.z)
if (gyroDataZ.count == ModelConstants.predictionWindowSize) {
gyroDataX_mean = Double(gyroDataX.mean)
gyroDataY_mean = Double(gyroDataY.mean)
gyroDataZ_mean = Double(gyroDataZ.mean)
gyroDataX_std = Double(gyroDataX.sd)
gyroDataY_std = Double(gyroDataY.sd)
gyroDataZ_std = Double(gyroDataZ.sd)
gyroDataX_min = Double(gyroDataX.min() ?? 0)
gyroDataY_min = Double(gyroDataY.min() ?? 0)
gyroDataZ_min = Double(gyroDataZ.min() ?? 0)
gyroDataX_max = Double(gyroDataX.max() ?? 0)
gyroDataY_max = Double(gyroDataY.max() ?? 0)
gyroDataZ_max = Double(gyroDataZ.max() ?? 0)
gyroDataX.removeAll()
gyroDataY.removeAll()
gyroDataZ.removeAll()
}
}
func MyAccel(){
guard motionManager.isAccelerometerAvailable else { return }
motionManager.accelerometerUpdateInterval = TimeInterval(ModelConstants.sensorsUpdateInterval)
motionManager.startAccelerometerUpdates(to: OperationQueue.current!){ (accelerometerData, error) in
if let accelerometerData = accelerometerData {
self.accelX.setText("\(accelerometerData.acceleration.x)")
self.accelY.setText("\(accelerometerData.acceleration.y)")
self.accelZ.setText("\(accelerometerData.acceleration.z)")
// Add the current data sample to the data array
self.addAccelSampleToDataArray(accelSample: accelerometerData)
}
}
}
func addAccelSampleToDataArray (accelSample: CMAccelerometerData) {
// Add the current accelerometer reading to the data array
accelDataX.append(accelSample.acceleration.x)
accelDataY.append(accelSample.acceleration.y)
accelDataZ.append(accelSample.acceleration.z)
if (accelDataZ.count == ModelConstants.predictionWindowSize) {
accelDataX_mean = Double(accelDataX.mean)
accelDataY_mean = Double(accelDataY.mean)
accelDataZ_mean = Double(accelDataZ.mean)
accelDataX_std = Double(accelDataX.sd)
accelDataY_std = Double(accelDataY.sd)
accelDataZ_std = Double(accelDataZ.sd)
accelDataX_min = Double(accelDataX.min() ?? 0)
accelDataY_min = Double(accelDataY.min() ?? 0)
accelDataZ_min = Double(accelDataZ.min() ?? 0)
accelDataX_max = Double(accelDataX.max() ?? 0)
accelDataY_max = Double(accelDataY.max() ?? 0)
accelDataZ_max = Double(accelDataZ.max() ?? 0)
accelDataX.removeAll()
accelDataY.removeAll()
accelDataZ.removeAll()
}
}
override func awake(withContext context: Any?) {
// Configure interface objects here.
UNUserNotificationCenter.current().delegate = self
MyGyro()
MyAccel()
MyRoll()
self.scheduleNotifications(content_body: self.pred_action)
}
override func willActivate() {
// This method is called when watch view controller is about to be visible to user
}
override func didDeactivate() {
// This method is called when watch view controller is no longer visible
UNUserNotificationCenter.current().delegate = self
MyGyro()
MyAccel()
MyRoll()
self.scheduleNotifications(content_body: self.pred_action)
}
}
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.
Hello, I am trying to set up a table view but I am getting an error when I try to assign the ViewController table delegate and data source. Here is my code:
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)
}
}
extension ViewController: UITableViewDelegate {
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = "Hello World"
return cell
}
}
class ViewController: UIViewController {
@IBOutlet weak var gyroX: UILabel!
@IBOutlet weak var gyroY: UILabel!
@IBOutlet weak var gyroZ: UILabel!
@IBOutlet weak var accelX: UILabel!
@IBOutlet weak var accelY: UILabel!
@IBOutlet weak var accelZ: UILabel!
@IBOutlet weak var quaternionX: UILabel!
@IBOutlet weak var quaternionY: UILabel!
@IBOutlet weak var quaternionZ: UILabel!
@IBOutlet weak var quaternionW: UILabel!
@IBOutlet weak var gravityX: UILabel!
@IBOutlet weak var gravityY: UILabel!
@IBOutlet weak var gravityZ: UILabel!
@IBOutlet weak var useraccelX: UILabel!
@IBOutlet weak var useraccelY: UILabel!
@IBOutlet weak var useraccelZ: UILabel!
@IBOutlet weak var yaw: UILabel!
@IBOutlet weak var pitch: UILabel!
@IBOutlet weak var roll: UILabel!
@IBOutlet weak var predicted_activity: UILabel!
@IBAction func cancelToHome(_ segue: UIStoryboardSegue) {
}
@IBOutlet weak var notif_log: UITableView!
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 accelDataX = Array(repeating: Double(0), count: ModelConstants.predictionWindowSize)
var accelDataY = Array(repeating: Double(0), count: ModelConstants.predictionWindowSize)
var accelDataZ = Array(repeating: Double(0), count: ModelConstants.predictionWindowSize)
var gyroDataX = Array(repeating: Double(0), count: ModelConstants.predictionWindowSize)
var gyroDataY = Array(repeating: Double(0), count: ModelConstants.predictionWindowSize)
var gyroDataZ = Array(repeating: Double(0), count: ModelConstants.predictionWindowSize)
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 gravityDataX = Array(repeating: Double(0), count: ModelConstants.predictionWindowSize)
var gravityDataY = Array(repeating: Double(0), count: ModelConstants.predictionWindowSize)
var gravityDataZ = Array(repeating: Double(0), count: ModelConstants.predictionWindowSize)
var useraccelDataX = Array(repeating: Double(0), count: ModelConstants.predictionWindowSize)
var useraccelDataY = Array(repeating: Double(0), count: ModelConstants.predictionWindowSize)
var useraccelDataZ = Array(repeating: Double(0), count: ModelConstants.predictionWindowSize)
var yawData = Array(repeating: Double(0), count: ModelConstants.predictionWindowSize)
var rollData = Array(repeating: Double(0), count: ModelConstants.predictionWindowSize)
var pitchData = Array(repeating: Double(0), count: ModelConstants.predictionWindowSize)
var stateOutput = try! MLMultiArray(shape:[ModelConstants.stateInLength as NSNumber], dataType: MLMultiArrayDataType.double)
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
MyGyro()
MyAccel()
MyQuaternion()
MyGravity()
MyUserAccel()
MyYaw()
MyPitch()
MyRoll()
self.scheduleNotifications(content_body: self.pred_action)
}
The issue is at notif_log.delegate = self where it gets this error: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
I am not sure why there would be a nil value here. Any advice?
Hello, I am trying to evaluate data in MLMultiArrays. Is there an easy way to calculate the mean and standard deviation of the values within an MLMultiArray?