質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

2回答

2824閲覧

iOSのCoreMotionでdeviceMotionUpdateIntervalを動的に変えたい

kazy1981

総合スコア44

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2017/02/08 15:47

こちらのページ等を参考にswiftで加速度情報を取得するアプリを作成しております。

取得することは出来たのですが、取得間隔を動的に変えたいと考えております。上記ウェブサイトで、

motionManager.accelerometerUpdateInterval = 0.1

とすると、取得間隔を0.1秒にすることができます。
できるだけ間隔を短く撮りたいのですが消費電力を浪費したくないのであまり移動していないときは間隔を広くしたいと考えています。

とすると、以下のmotionAnimationの中で加速度やジャイロが一定程度の大きさ以上になった際に取得間隔を小さくし(例えば=0.25)、逆に加速度やジャイロが一定程度の小ささ以下であれば、取得間隔を大きくする(例えば0.5)することをしたいと考えております。

func motionAnimation(motionData:CMDeviceMotion?, error:NSError?){ //ここで加速度情報が指定間隔ごとに取得される if (accel < 0.3) { //加速度が大きい際には取得間隔を0.25に小さくする cmManager.deviceMotionUpdateInterval = 0.025 }

ところが、これは出来ません。(エラーは出ないのですが、取得間隔が0.25まで小さくならないようです)。おそらくmotionAnimationの中では取得間隔の変更ができない仕様になっているのではないかと推測しております。(正しいのでしょうか?)

とはいってもこのような使用は消費電力を押させるために有効で、同じような境遇の方がいらっしゃらないかと考え質問させていただいております。例えばNotificationcenterを使用したイベントリスナーで行うとできたりしないものかと思うのですが。。。

日本語でも英語でもある程度検索したのですがヒントがわかりませんでした。
何かヒントだけでもいただけますと幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

いただきましたアドバイスに従い以下のようなコードにすることで動的に取得間隔を変更できました。

import UIKit import CoreMotion class ViewController: UIViewController { @IBOutlet weak var xLabel: UILabel! @IBOutlet weak var yLabel: UILabel! @IBOutlet weak var zLabel: UILabel! @IBOutlet weak var intervalLabel: UILabel! var timer: Timer! var cmManager = CMMotionManager() var interval: Double = 3.0 override func viewDidLoad() { super.viewDidLoad() } override func viewWillAppear(_ animated: Bool) { timer = Timer.scheduledTimer(timeInterval: 3.0, target: self, selector: #selector(ViewController.update), userInfo: nil, repeats: true) //pull型でモーションセンサー cmManager.startDeviceMotionUpdates() timer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(ViewController.update), userInfo: nil, repeats: true) } func update(){ if let data = cmManager.deviceMotion { xLabel.text = String(data.rotationRate.x) print(data) if abs(data.rotationRate.x) > 2 { interval = 0.1 changeIntervalForTimer(interval: interval) } } intervalLabel.text = String(interval) } func changeIntervalForTimer(interval:Double){ timer.invalidate() timer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(ViewController.update), userInfo: nil, repeats: true) } }

投稿2017/02/15 20:10

kazy1981

総合スコア44

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

取得間隔を動的に変えたい

specでは
accelerometerUpdateIntervalを使う以上は

The frequency of updates is determined by the value of an “interval” property.

という事ですが

An app can take one of two approaches when receiving motion data, by handling it at specified update intervals or periodically sampling the motion data. With both of these approaches, the app should call the appropriate stop method (stopAccelerometerUpdates(), stopGyroUpdates(), stopMagnetometerUpdates(), and stopDeviceMotionUpdates()) when it has finished processing accelerometer, rotation-rate, magnetometer, or device-motion data.

cmmotionmanager

2通りの使い方を推奨していますので2番目の方法、つまりポーリング、を使ってみたらどうでしょう

http://stackoverflow.com/questions/23251947/replace-sharedaccelerometer-with-motionmanager-ios

投稿2017/02/09 02:08

aja

総合スコア3733

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazy1981

2017/02/15 20:10

おかげさまで解決できました!ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問