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?
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
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 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 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.
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)
}
}