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

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

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

複数の計算が同時に実行される手法

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

Q&A

解決済

1回答

680閲覧

加速度データ更新とデータの周期的な送信が並行してできない

Byarlant

総合スコア1

並列処理

複数の計算が同時に実行される手法

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

0グッド

0クリップ

投稿2020/09/02 14:54

前提・実現したいこと

ドローンに対し、iphoneの加速度センサーから取得した値を使って計算した単位時間当たりの速度を送信して、制御したいと考えています。
センサーからの速度は取得出来ています。
またデータの送信自体は送受信できているのを確認しています。
1。アプリ起動
2。接続
3。加速度センサーからのデータ取得、単位時間当たりの速度へ変換
4。周期的にTCP/IPでデータ送信
ループ3、4

しかし、データの取得と送信を同時に行おうとすると、データがアップデートされず、同じ値を送り続けてしまっています。
whileとOperationQueueの使い方が誤っているのだろうと推測しますが、どのように変えたらいいのかわかりません。

該当のソースコード

Xcode 11.6 Swift 5.2.4
ソースコード

var myMotionManager = CMMotionManager()

@IBAction func StartButton() { while(self.stopButtonPressed == false){ self.myMotionManager.deviceMotionUpdateInterval = 0.1 self.myMotionManager.startDeviceMotionUpdates(to:OperationQueue.main,withHandler:{(motion:CMDeviceMotion?, error:Error?) in self.getMotionData(deviceMotion: motion!)}) var command = "speed((self.speed))\n" print("speed\n") self.client.connection.send(data: (command.data(using: .utf8))!) usleep(100) } } func getMotionData(deviceMotion:CMDeviceMotion) { //加速度取得 self.Accel[0] = deviceMotion.userAcceleration.x self.Accel[1] = deviceMotion.userAcceleration.y self.Accel[2] = deviceMotion.userAcceleration.z self.Accel[3] = deviceMotion.rotationRate.x self.Accel[4] = deviceMotion.rotationRate.y self.Accel[5] = deviceMotion.rotationRate.z //速度計算 self.speed[0]=getVelocity(num: 0) self.speed[1]=getVelocity(num: 1) self.speed[2]=getVelocity(num: 2) self.speed[3]=getVelocity(num: 3) self.speed[4]=getVelocity(num: 4) self.speed[5]=getVelocity(num: 5) }

試したこと

overrideで先に加速度センサーのデータを取るようにし、データは周期的に更新されているのを確認しましたが、結局スタートボタンを押すと、アップデートがされなくなってしまいます。
データの取得と送信を並列処理も試みたのですが、うまくコーディングできていません。
ご教授いただければ幸いです。よろしくお願いします。

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

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

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

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

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

TsukubaDepot

2020/09/02 20:09

次にご質問する機会があれば、ソースコードの部分は```で囲まれるか、エディタの<CODE>機能をご利用下さるようお願いします。 ソースコードが整形されて表示されるため、大変みやすくなります。
guest

回答1

0

ベストアンサー

Swift

1 usleep(100)

Swiftの usleep(_:)はメインスレッドそのものを止めてしまう関数だったと思います。
指定された時間の間、アプリの動作を完全に止めてしまいます。

つまり、ボタンなどUI部品の反応のほか、その他非同期で行われる全ての処理が正しく行われなくなってしまいます。

そもそも、startDeviceMotionUpdates は指定間隔で加速度の値を取得できるようになっていますから、自分で usleep()したり、タイマ割り込みを使う必要はないと思います。

スタートボタンを押したときの処理で

Swift

1myMotionManager.deviceMotionUpdateInterval = 0.1 2 3// ボタンを押した時に一度だけ登録すれば良い。 4myMotionManager.startDeviceMotionUpdates(to:OperationQueue.main, withHandler: { (motion:CMDeviceMotion?, error:Error?) in 5 self.getMotionData(deviceMotion: motion!) 6 var command = "speed((self.speed))\n" 7 print("speed\n") 8 self.client.connection.send(data: (command.data(using: .utf8))!) 9}

を行い、ストップボタンを押したときの処理で

Swift

1 // 加速度センサの動作を止める 2 myMotionManager.stopAccelerometerUpdates()

とやれば良いのではないでしょうか。

startDeviceMotionUpdatesで登録するクロージャの処理(withHandler)内部が定期的に呼ばれたときの処理となりますので、そこで加速度データを取得し、print() で表示し、send(data:)で送るという具合に一連の処理を記述します。

投稿2020/09/02 20:08

TsukubaDepot

総合スコア5086

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

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

Byarlant

2020/09/03 06:53

ありがとうございました。頂いた修正で無事解決いたしました。ご助言も大変わかりやすく参考になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問