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

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

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

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

6992閲覧

pythonを使用した加速度とジャイロセンサーによる回転行列について

yohehe

総合スコア48

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/06/28 17:57

編集2018/06/29 13:13

測定した加速度とジャイロのデータを回転行列で分解するプログラムを作成しております。
動作データと測定データの誤差が大きいのですが、何が課題かわからず困っております。

python

1 2#取得した加速度データをそれぞれacX,acY,acZとする 3取得したジャイロデータをそれぞれradX,radY,radZとする。 4#加速度はG表示のため、取得時にm/s*2へ変換 5 6#角速度から角度へ 単位はradに 7kakudoX=[] 8kakudoY=[] 9kakudoZ=[] 10for i in range(len(radX)): 11 radsecX=radX[i]+radX[i+1]*0.1 12 kakudoX.append(radsecX) 13 radsecY=radY[i]+radY[i+1]*0.1 14 kakudoY.append(radsecY) 15 radsecZ=radZ[i]+radZ[i+1]*0.1 16 kakudoZ.append(radsecZ) 17 18#acgyのリストを作成 19acgy_list=[] 20def kaiten(rx,ry,rz): 21 #回転行列を定義 22 Rx=np.array([[1,0,0],[0,np.cos(rx),-np.sin(rx)],[0,np.sin(rx),np.cos(rx)]]) 23 Ry=np.array([[np.cos(ry),0,np.sin(ry)],[0,1,0],[-np.sin(ry),0,np.cos(ry)]]) 24 Rz=np.array([[np.cos(rz),-np.sin(rz),0],[np.sin(rz),np.cos(rz),0],[0,0,1]]) 25 #基準座標系からみた座標の方向余弦行列.オイラー角z:ヨー角>x:ピッチ角>y:ロール角 26 R=Rz.dot(Ry).dot(Rx) 27 return R 28accelgyro=kaiten(np.radians(x),np.radians(y),np.radians(z)).dot([[acX[i]],[acY[i]],[acZ[i]]]) 29 acgy_list.append(accelgyro) 30 31#ノイズ除去のためにフィルタリングを行う。 32# ローパスフィルターでフィルタリング 33#1に近づけるほど平滑化の度合いは大きくなっていく 34lowpass_acX=[] 35lowpass_acY=[] 36lowpass_acZ=[] 37for i in range(len(acX)): 38 a=0.3 39 low=a*dataX[i]+(1-a)*dataX[i] 40 lowpass_acX.append(low) 41 low=a*dataY[i]+(1-a)*dataY[i] 42 lowpass_acY.append(low) 43 low=a*dataZ[i]+(1-a)*dataZ[i] 44 lowpass_acZ.append(low) 45highpass_X=[] 46highpass_Y=[] 47highpass_Z=[] 48#次にハイパスフィルターでフィルタリング 49for i in range(len(acX)): 50 #ローパスフィルター:現在の値=係数*一つ前の値+(1-係数)センサーの値 51 #ハイパスフィルター:センサーの値ーローパスフィルター 52 a=0.4 53 lowX=a*lowpass_X+rdataX[i]*(1-a) 54 highX=rdataX[i]-lowX 55 lowY=a*lowpass_Y+rdataY[i]*(1-a) 56 highY=rdataY[i]-lowY 57 lowZ=a*lowpass_Z+rdataZ[i]*(1-a) 58 highZ=rdataZ[i]-lowZ 59 highpass_X.append(highX) 60 highpass_Y.append(highY) 61 highpass_Z.append(highZ) 62 63 64コード

以上の方法で加速度とジャイロデータを回転行列として計算しております。このaccel*gyroデータをもとに速度、距離(台形積分法なども試しました)を求めていくと誤差が拡大し困っています。
何が問題かアドバイスをいただけますと幸いです。
よろしくお願いいたします。

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

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

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

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

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

ozwk

2018/06/29 00:18 編集

temp_pitch=temp_pitch+motion_Pitch[num]*0.2 <-これは何をしているつもりなんですか?角速度の積分?
yohehe

2018/06/29 00:45

回転行列にかけるために角速度rad/secをradianの単位に変更しようとしたのですが。もしかして必要がないのでしょうか。
guest

回答1

0

ベストアンサー

1
理由は面倒なので説明しませんが、
3次元の回転において、角速度の値を軸ごとに個別に足し合わせて"角度"を求めるのは誤りです。

そもそも3次元の回転は角度で持たずにクォータニオンや回転行列で持ったほうが計算上楽です。
クォータニオンや回転行列を角速度で更新する方法を調べてください。

「無限小回転」「微小回転」というキーワードが役に立つかもしれません。

2
加速度を2回の積分で位置とするのはとんでもなく誤差が大きくなります。
ある条件下では速度を0と推定するというような何らかの制約をつける必要があります。
(例えば、動加速度の大きさが一定以下なら静止しているものとみなすなど)

投稿2018/06/29 01:05

編集2018/06/29 01:24
ozwk

総合スコア13521

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

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

yohehe

2018/06/29 01:57

ozwk様ありがとうございます。そもそも角速度の段階が間違っていたために、徐々に誤差が大きくなっていくという現象だったのですか。ベクトルと同じように考えて速度と同じよう考えず、無限小回転、小回転について調べて一つずつ追記いたします。
ozwk

2018/06/29 12:40

もとの質問から大幅に内容が変わるなら前の質問を残すか質問を別で立ててください
yohehe

2018/06/29 12:47

すみません、そのほうが適切でした。消してしまってます前のプログラムデータを追記いたします。
yohehe

2018/06/29 13:14

ozwk様、文章を修正し、この質問を終了して別の質問にさせていただくようにいたします。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問