我正在处理收集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")
}
}
我从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()
}
}
答案 0 :(得分:2)
从我看到的应用程序'传感器日志'你提到过使用更多的数据过滤器来清理他们的数据。因为即使在传感器融合数据如此干净之后,他们也无法做到这一点。
根据您的观察,手机Sensor Fusion已关闭。它不能关闭,因为如果关闭它将获得完全无法理解的原始数据,甚至接近输出的数据。
根据我的建议,您可以在Accelerometer和Magnetometer的帮助下搜索用于清洁陀螺仪数据的滤波器。如果你只对Roll,Pitch,Yaw感兴趣的话可能。搜索用于平衡四轮直升机的过滤器。他们可能会帮助你。
对不起,这不是一个答案,只是一个评论。但我没有多少声誉可以发表评论。所以,你可以理解。