[watchOS 3] Apple Watch でデバイスモーションを取得する
Device Motion on Apple Watch
watchOS 3 から CoreMotion フレームワークを利用して、Apple Watch の様々なデバイス情報が取得できるようになりました。
今回は取得することのできる、いくつかの情報について説明したいと思います。
前提
Apple Watch の方向を以下のように定義します。
- 文字盤 :
上
- 底面 :
下
- 12 時方向 :
前
- 6 時方向 :
後
- 3 時方向 :
右
- 9 時方向 :
左
CMDeviceMotion
CMDeviceMotion オブジェクトには以下のようなデバイスモーションの基本情報が含まれます。
- Attitude
- Gravity
- Rotation rate
- User acceleration
Attitude
姿勢角 を表します。
CMAttitude クラスで表されるこのプロパティは Double 型の以下の値を保持します。
- roll
- pitch
- yaw
roll
roll(ロール) は Apple Watch の前後 Y 軸 に関する回転角を表します。
値の範囲は -π
から π
までの弧度法(ラジアン)で表現されます。
飛行機が左右に旋回するようにデバイスを傾けると、この値が増減します。
pitch
pitch(ピッチ) は Apple Watch の左右 X 軸 に関する回転角を表します。
値の範囲は -π/2
から π/2
までです。
これらを超えた場合、値は減少し roll が π 分回転した値になるようです。
Apple Watch の前方を上下に傾けることで値が増減します。
yaw
yaw(ヨー) は Apple Watch の上下 Z 軸 に関する回転角を表します。
値の範囲は -π
から π
までです。
Apple Watch の底面を床に接地した状態で、コマのように回転させることで値が増減します。
Gravity
重力加速度 を表します。
CMAcceleration クラスで表されるこのプロパティは Double 型の以下の値を保持します。
- x
- y
- z
Apple Watch の底面を床に接地した状態では (x, y, z) は (0, 0, -1)
となります。
Apple Watch を縦に置くと (0, -1, 0)
というように変化します。
x, y, z はそれぞれ
- 右、前、上が正の値
- 左、後、下が負の値
となっています。
値の範囲は -1
から 1
までで、合計の加速度はこの値に User acceleration を加えたものになります。
Rotation rate
回転率 を表します。
CMRotationRate クラスで表されるこのプロパティは Double 型の以下の値を保持します。
- x
- y
- z
これらはそれぞれ X 軸、Y 軸、Z 軸に関する回転率(ラジアン / sec)となりますので、速く回転させるほど値は大きくなっていきます。
User acceleration
ユーザーがデバイスに与えている加速度 を表します。
Gravity と同様に CMAcceleration クラスで表されます。
この値に Gravity を加えたものが合計の加速度となります。
サンプルコード
CoreMotion を利用するプログラムは複雑ではありません。
値の取得だけであれば以下のような短いコードで実現可能です。
import CoreMotion class InterfaceController: WKInterfaceController { let motionManager = CMMotionManager() let queue = OperationQueue() override func awake(withContext context: Any?) { super.awake(withContext: context) if !motionManager.isDeviceMotionAvailable { print("Device Motion is not available.") return } motionManager.startDeviceMotionUpdates(to: queue) { (deviceMotion: CMDeviceMotion?, error: Error?) in if error != nil { print("Encountered error: \(error!)") } if deviceMotion != nil { print("attitude = \(deviceMotion!.attitude)") print("gravity = \(deviceMotion!.gravity)") print("rotationRate = \(deviceMotion!.rotationRate)") print("userAcceleration = \(deviceMotion!.userAcceleration)") } } } }
CMMotionManager のインスタンスを生成し startDeviceMotionUpdates() メソッドを実行することで、一定間隔でハンドラが呼び出され、デバイス情報を参照することができます。
Apple も サンプルコード を公開しているので、興味のある方は確認してみてください。
さいごに
デバイスモーションということで結構カラダを動かしました。
サンプルコードを作りながら Apple Watch をブンブン振り回すのは、楽しくもあり恥ずかしくもありました。
今回から 会社が支給してくれた Apple Watch Series 2 を利用してみたのですが、Xcode からのプログラム転送速度も Series 1 に比べて格段に速く、ストレスフリーで開発することができました。
個人的にはとてもデバッグしやすくなったと感じました。
いいこと!
リンク
ミレニアム・ファルコン製作日記 #41
41 号 表紙
パーツ
成果
今回の作業は以下の 2 つでした。
- 砲操作プラットホームを組み立てる
- 上部砲塔ベイを組み立てる
これまでで一番細かいパーツを扱った作業かもしれません。
上部砲塔ベイには LED を取り付けたので、ここもライトアップされることでしょう。
砲塔ベイは フォースの覚醒 にも登場してきました。
ですが、フォースの覚醒でフィンが操作したのはおそらく下部砲塔ベイです。
よって、今後もう一対の砲塔ベイの組み立て作業も発生すると思います。
ロール・ピッチ・ヨー
今回ブログ本編で紹介した、これら回転運動の考えは 週間 スター・ウォーズ ミレニアム・ファルコン でも紹介されています。
以下、引用。
すべてのパイロットは、ロール(傾点)・ピッチ(仰角変化)・ヨー(振向)という3つの基本的な飛行制御技術をマスターしなければならない。 高速飛行する宇宙船で上昇・下降・急旋回を同時に行うには、冷静な頭脳と素早い反射神経、そして船の位置を三次元で把握する直観力が要求される。
映画では簡単に宇宙船を飛ばしていますが、それはとても難しいことなのですね。
改めてハン・ソロは非常に有能なパイロットであることがわかりました!
それではまた次回。
May the Force be with you!