Skip to main content

COREMOTION TO FLASK 串流IPHONE姿态信息

Core Motion是Apple为iOS和watchOS设备提供的框架,可从设备上的硬件获取运动和环境相关数据。Core Motion框架提供了对各种用户移动,包括步行、奔跑、骑车等的支持。它还提供了对加速度计、陀螺仪、计步器和磁力计传感器的数据访问,以及提供用户高度、航向和位置的数据。

Core Motion可用于开发与健身、健康、位置跟踪、游戏等相关的应用程序。它提供了一组丰富的API,可用于监视和分析用户的动作,并使用这些数据为用户创建有意义的体验。

这里我们需要实现iOS CoreMotion获取的手机姿态数据,然后串流到我们的Flask服务器App上。

首先我们来实现iPhone端的程序。

TransEngine.swift – Swift

Swift
import Foundation
import CoreMotion

class TransEngine {
    //Motion reading
    //Accelerometer movement - Gyroscope rotation
    private let motionManager = CMMotionManager()
    
    init() {
        if motionManager.isDeviceMotionAvailable {
            motionManager.deviceMotionUpdateInterval = 1 / 60 //60Hz
            motionManager.startDeviceMotionUpdates(to: OperationQueue.current!) { [weak self] (motion, error) in
                //read motion
                self?.processMotionWith(motion)
            }
        } else {
            print("No motion support")
        }
}
    
    private func processMotionWith(_ motion: CMDeviceMotion?) {
        guard let motion = motion else {
            return
        }
        
        let attitude = motion.attitude
        let rotationRate = motion.rotationRate
        let userAcceleration = motion.userAcceleration
                
        let rawData = [
            "pitch": attitude.pitch,
            "roll": attitude.roll,
            "yaw": attitude.yaw,
            "rotationRateX": rotationRate.x,
            "rotationRateY": rotationRate.y,
            "rotationRateZ": rotationRate.z,
            "userAccelerationX": userAcceleration.x,
            "userAccelerationY": userAcceleration.y,
            "userAccelerationZ": userAcceleration.z
        ]

        sendData(data: rawData)
    }
    
    
    //Networking
    func sendData(data: [String: Any]) {
        let url = URL(string: "http://192.168.3.58:9527/data")!
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.httpBody = try! JSONSerialization.data(withJSONObject: data)
        let task = URLSession.shared.dataTask(with: request)
        task.resume()
    }
}

您提供的代码使用Core Motion从设备的运动传感器(加速度计、陀螺仪)读取数据,并使用URLSession将该数据通过网络发送到服务器。

使用CMMotionManager()类来初始化新的 Motion Manager 实例。然后,如果运动设备可用,则将更新间隔设置为1/60秒(60 Hz),并启动设备运动更新。更新将放置在当前操作队列上,以更新可读的连续传感器相关输出数据流。

processMotionWith(_motion: CMDeviceMotion?)方法使用保护语句处理更新的传感器数据以验证运动值是否为空。然后从姿态、旋转速率和用户加速度中提取俯仰角、翻滚角和偏航角。

sendData(data: [String:Any])方法将处理后的传感器数据作为JSON字典通过POST网络请求发送到http://192.168.3.58:9527/data。’Content-Type‘ 设置为‘application/json’,使用URLSession.shared.dataTask(with: request)进行请求的共享单例URL会话实例。这将根据开发人员指定的请求对象获取URL的内容。

下面是Flask写的服务端程序:server.py – Python

Swift
from flask import Flask, request
from flask_socketio import SocketIO, send
import json

app = Flask("__name__")
socketio = SocketIO(app)

@app.route('/data', methods=['POST'])
def data():

    json_data = request.get_json()

    json_data = {
        "position": [json_data["pitch"], json_data["roll"], json_data["yaw"]],
        "rotation": [json_data["rotationRateX"], json_data["rotationRateY"], json_data["rotationRateZ"]]
    }

    json_data_string = json.dumps(json_data)
    socketio.emit('motion_data', json_data_string)
    print(json_data_string)
    return 'OK', 200

if __name__ == '__main__':
    #0.0.0.0 will expose your server to local network
    socketio.run(app, host='0.0.0.0', port=9527)

这里对获取数据json_data做了一点格式化,我们把他格式为字典对象,加了position,rotation两个Keyword。以便下一步处理更方便。

视屏Demo:

Flask, iOS, macOS, Python, Swift, Tutorial, Xcode