doo*_*ers 7 ios core-motion swift
我正在开发一个收集CoreMotion数据的应用程序,我正在使用现有的应用程序商店应用程序作为参考,以确保我正确地收集数据.
在大多数情况下,一切都是等价的,但我在某些测试中看到了一些奇怪的数据.问题出现在滚动,俯仰和偏航值上,然而,来自加速度计,陀螺仪和磁力计的原始数据是等效的...
下面的图表绘制了从100Hz的装备上的5个设备收集的数据:
首先,从SensorLog收集的数据:
其次,从我的应用收集的数据:
第三,从我的应用程序收集的数据,但这次@ 10Hz:

观察:
放大图块:
并在上图中覆盖手动拉伸的滚动数据:
码:
func start(_ interval: TimeInterval = 0.1) {
self.interval = interval
logTimer = Timer.new(every: interval, {
self.motionData.currentRecord = self.motionDataRecord
self.motionData.createCoreDataRecord()
NotificationCenter.default.post(name: .motionHelperDidUpdateData, object: nil)
})
logTimer.start()
startCoreLocation()
startAccelerometer()
startDeviceMotion()
startGyroscope()
startMagnetometer()
}
func startCoreLocation() {
switch CLLocationManager.authorizationStatus() {
case .authorizedAlways:
locationManager.startUpdatingLocation()
locationManager.startUpdatingHeading()
case .notDetermined:
locationManager.requestAlwaysAuthorization()
case .authorizedWhenInUse, .restricted, .denied:
delegate?.reRequestAlwaysAuthorization()
}
}
func startAccelerometer() {
if motionManager.isAccelerometerAvailable {
motionManager.accelerometerUpdateInterval = interval
motionManager.startAccelerometerUpdates(to: queue) {
[weak self] (data, error) in
guard let weakSelf = self else { return }
if error != nil {
print("Accelerometer Error: %@", error)
}
guard let data = data else { return }
weakSelf.motionDataRecord.accelerometer = data
}
} else {
print("The accelerometer is not available")
}
}
func startGyroscope() {
if motionManager.isGyroAvailable {
motionManager.gyroUpdateInterval = interval
motionManager.startGyroUpdates(to: queue) {
[weak self] (data, error) in
guard let weakSelf = self else { return }
if error != nil {
print("Gyroscope Error: %@", error)
}
guard let data = data else { return }
weakSelf.motionDataRecord.gyro = data
}
} else {
print("The gyroscope is not available")
}
}
func startMagnetometer() {
if motionManager.isMagnetometerAvailable {
motionManager.magnetometerUpdateInterval = interval
motionManager.startMagnetometerUpdates(to: queue) {
[weak self] (data, error) in
guard let weakSelf = self else { return }
if error != nil {
print("Magnetometer Error: %@", error)
}
guard let data = data else { return }
weakSelf.motionDataRecord.magnetometer = data
}
} else {
print("The magnetometer is not available")
}
}
func startDeviceMotion() {
if motionManager.isDeviceMotionAvailable {
motionManager.deviceMotionUpdateInterval = interval
motionManager.startDeviceMotionUpdates(using: attitudeReferenceFrame, to: queue) {
[weak self] (data, error) in
guard let weakSelf = self else { return }
if error != nil {
print("Device Motion Error: %@", error)
}
guard let data = data else { return }
weakSelf.motionDataRecord.deviceMotion = data
}
} else {
print("Device motion is not available")
}
}
Run Code Online (Sandbox Code Playgroud)
我从CoreMotion收集数据的方式有问题吗?有更有效的方法吗?
这可能发生什么?
更新:
我写了一个简单的骨头应用程序,如下所示,我得到了类似的结果:
class ViewController: UIViewController {
@IBOutlet weak var startStop: UIButton!
var isRunning = false
let manager: CMMotionManager = {
let manager = CMMotionManager()
manager.deviceMotionUpdateInterval = 1/100
return manager
}()
@IBAction func handleStartStop(_ sender: AnyObject) {
if isRunning {
stopMotionUpdates()
startStop.setTitle("Start", for: .normal)
} else {
startMotionUpdates()
startStop.setTitle("Stop", for: .normal)
}
isRunning = !isRunning
}
func startMotionUpdates() {
manager.startDeviceMotionUpdates(using: .xTrueNorthZVertical, to: .main) { (data, error) in
print("Roll: \(data!.attitude.roll), Pitch: \(data!.attitude.pitch), Yaw: \(data!.attitude.yaw)")
}
}
func stopMotionUpdates() {
manager.stopDeviceMotionUpdates()
}
}
Run Code Online (Sandbox Code Playgroud)
据我所知,您提到的应用程序“传感器日志”正在使用更多数据过滤器来清理其数据。因为即使在传感器融合数据如应用程序所示如此干净之后,他们也不可能做到这一点。
根据您的观察,手机传感器融合已关闭。它不能关闭,因为如果它关闭,您将获得完全原始的数据,这些数据将无法理解,甚至接近您的输出。
我可以建议您在加速度计和磁力计的帮助下搜索用于清理陀螺仪数据的过滤器。可能如果您只对 Roll、Pitch、Yaw 感兴趣。搜索用于平衡四轴飞行器的过滤器。他们可能会帮助你。
抱歉,这不是一个答案,只是一条评论。但我没有太多的声誉来发表评论。所以,你可以理解。