Core Motionでセンサーの生データを取得する方法

こちら」では、補正済みのモーションデータの取得方法を解説しました。本記事では、補正前のモーションセンサーの生データを取得する方法を解説します。

Core Motionの基本的な使い方を確認する

本記事では、Core Motionの基本的な使い方を理解していることを前提にしています。Core Motionを使うのが初めてという方は、先に下記の記事をお読みください。

【サンプルあり】Core Motionでモーションセンサーの値を取得する方法【Swift】

Core Motionで加速度センサーの値を取得してみる

前回の内容を理解していれば、今回の内容はとても簡単ですので、さっそく加速度センサーの生データを取得する「MotionSensorNaked」クラスのコードをお見せします。

import Foundation

import UIKit
import CoreMotion

class MotionSensorNaked: NSObject, ObservableObject {
    
    @Published var isStarted = false
    
    @Published var xStr = "0.0"
    @Published var yStr = "0.0"
    @Published var zStr = "0.0"
    
    let motionManager = CMMotionManager()
    
    func start() {
        if motionManager.isAccelerometerAvailable {
            motionManager.accelerometerUpdateInterval = 0.1
            motionManager.startAccelerometerUpdates(to: OperationQueue.current!) { (motion:CMAccelerometerData?, error:Error?) in
                self.updateMotionData(motionData: motion!)
            }
        }
        
        isStarted = true
    }
    
    func stop() {
        isStarted = false
        motionManager.stopAccelerometerUpdates()
    }
    
    private func updateMotionData(motionData:CMAccelerometerData) {
        xStr = String(motionData.acceleration.x)
        yStr = String(motionData.acceleration.y)
        zStr = String(motionData.acceleration.z)
    }
}

前回作成した「MotionSensor」クラスと見比べていただくとわかりますが、使い方は同じで、呼び出すメソッドが違うだけです。なので、コードを眺めただけでも、ある程度理解できてしまうでしょう。

順番に説明しますね。

まずは「CMMotionManager」を初期化します。これは前回と同じですね。

    let motionManager = CMMotionManager()

次に、デバイスが加速度センサーに対応しているかチェックして、対応していたら加速度センサーのデータ取得を開始します。使い方はまったく同じで、呼び出すメソッドが違うだけです。

        if motionManager.isAccelerometerAvailable {
            motionManager.accelerometerUpdateInterval = 0.1
            motionManager.startAccelerometerUpdates(to: OperationQueue.current!) { (motion:CMAccelerometerData?, error:Error?) in
                self.updateMotionData(motionData: motion!)
            }
        }

そして、データ取得開始時に指定した「updateMotionData()」メソッドを実装します。

    private func updateMotionData(motionData:CMAccelerometerData) {
        xStr = String(motionData.acceleration.x)
        yStr = String(motionData.acceleration.y)
        zStr = String(motionData.acceleration.z)
    }

Core MotionのAPIは使い方が統一されていて、非常にわかりやすいですね。さすがAppleさんといったところ。

前回と同様に画面表示します。こちらは前回とまったく同じコードです。

import SwiftUI

struct ContentView: View {
    @ObservedObject var sensor = MotionSensor()
    
    var body: some View {
        VStack {
            Text(sensor.xStr)
            Text(sensor.yStr)
            Text(sensor.zStr)
            Button(action: {
                self.sensor.isStarted ? self.sensor.stop() : self.sensor.start()
            }) {
                self.sensor.isStarted ? Text("STOP") : Text("START")
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

実機で動かしてみましょう。

表示されましたね!

デバイスを動かしていないのに、加速度の値が0付近ではないことを不思議に思うかもしれません。しかし、これは加速度センサーの正しい動作です。加速度センサーの詳しい内容については、下記のサイト様がわかりやすいのでご参照ください。
3軸加速度センサを用いた姿勢推定 – Watako-Lab.

Core Motionで他のセンサーの生データを取得してみる

Core Motionでは下記のモーションセンサーの生データを取得できます。

  • 加速度センサー
  • ジャイロセンサー
  • 磁気センサー

上記では、加速度センサーの値をみたので、残りのジャイロセンサーと磁気センサーの値もとってみましょう。

まずはジャイロセンサーの場合です。

class MotionSensorNaked: NSObject, ObservableObject {
    
    @Published var isStarted = false
    
    @Published var xStr = "0.0"
    @Published var yStr = "0.0"
    @Published var zStr = "0.0"
    
    let motionManager = CMMotionManager()
    
    func start() {
        if motionManager.isGyroAvailable {
            motionManager.gyroUpdateInterval = 0.1
            motionManager.startGyroUpdates(to: OperationQueue.current!) { (motion:CMGyroData?, error:Error?) in
                self.updateMotionData(motionData: motion!)
            }
        }
        
        isStarted = true
    }
    
    func stop() {
        isStarted = false
        motionManager.stopGyroUpdates()
    }
    
    private func updateMotionData(motionData:CMGyroData) {
        xStr = String(motionData.rotationRate.x)
        yStr = String(motionData.rotationRate.y)
        zStr = String(motionData.rotationRate.z)
    }
}

こちらは磁気センサーの場合です。

class MotionSensorNaked: NSObject, ObservableObject {

    @Published var isStarted = false

    @Published var xStr = "0.0"
    @Published var yStr = "0.0"
    @Published var zStr = "0.0"

    let motionManager = CMMotionManager()

    func start() {
        if motionManager.isMagnetometerAvailable {
            motionManager.magnetometerUpdateInterval = 0.1
            motionManager.startMagnetometerUpdates(to: OperationQueue.current!) { (motion:CMMagnetometerData?, error:Error?) in
                self.updateMotionData(motionData: motion!)
            }
        }

        isStarted = true
    }

    func stop() {
        isStarted = false
        motionManager.stopMagnetometerUpdates()
    }

    private func updateMotionData(motionData:CMMagnetometerData) {
        xStr = String(motionData.magneticField.x)
        yStr = String(motionData.magneticField.y)
        zStr = String(motionData.magneticField.z)
    }
}

本記事のコードの全体はGitHubに上げてありますので、ご自由にお使いください。

CoreMotionNakedSample – GitHub

終わりに

本記事ではCore Motionを使ってモーションセンサーの生データを取得する方法を解説しました。

生データをグラフで見てみたいということであれば、App Storeにモーションセンサーのデータを可視化するツールを公開していますので、ぜひダウンロードして使ってみてください。

もせろぐ

App Storeはこちら

使い方はこちら