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

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

ただいまの
回答率

87.92%

javaにおける角速度の積分について

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 4,021

score 21

Androidに搭載されているジャイロセンサと加速度センサを使って角度を得るプログラムを作成中なのですが、ジャイロセンサから得た角速度を積分して角度を求めることがうまくできません。角速度を配列にして保持することで1つ前の角速度も参照できるようにし、それを用いて台形法を使い積分しようとしています。しかし、全然まともな角度が出力されません…。配列を制御しているiを共用しているせいだとは思うのですが、共用しないとどんどん角速度の更新に比べて角度の更新が遅延してしまうような気がします…。ちなみに、class Transmission extends Threadは、ボタンが押された時に呼び出されるようにしており、ボタンが押されると一定間隔で積分を始めるようにしています。このようにすればいいよ。や、そもそもこのようなやり方では無理だ。などのアドバイスを貰えると嬉しいです。

以下にソースの一部を添付しておきます。


int deltat = 500; //500ミリ秒間隔で積分

public void onSensorChanged(SensorEvent event) {
  switch(event.sensor.getType()){
    //角速度に変化があったら
    case Sensor.TYPE_GYROSCOPE :
      //オフセット
      if(offset == 0){
        gyr_x_off = event.values[0];
        gyr_y_off = event.values[1];
        gyr_z_off = event.values[2];

        offset = 1;
      }

      gyr_x[i] = event.values[0]-gyr_x_off;//オフセットを引いたx軸の角速度
      gyr_y[i] = event.values[1]-gyr_y_off;//オフセットを引いたy軸の角速度
      gyr_z = event.values[2]-gyr_z_off;//オフセットを引いたz軸の角速度

      if((0 <= i) && (i < 9)){
        i = i+1;
      }else{
        i = 1;
      }
      break;
  }
}

class Transmission extends Thread {
  public void run() {
    try{
      while(running){
        //角速度を積分で角度に変換
        if((2 <= i) && (i <= 9)){
          ang_gyr_x = ang_gyr_x+((gyr_x[i-1]+gyr_x[i])/2)*(deltat/1000.0);
          ang_gyr_y = ang_gyr_y+((gyr_y[i-1]+gyr_y[i])/2)*(deltat/1000.0);
        }else if(i == 1){
          ang_gyr_x = ang_gyr_x+((gyr_x[9]+gyr_x[i])/2)*(deltat/1000.0);
          ang_gyr_y = ang_gyr_y+((gyr_y[9]+gyr_y[i])/2)*(deltat/1000.0);
        }else if(i == 0){
          //初回は静止していると仮定して加速度からの角度を入れる。
          ang_gyr_x = ang_acc_x;
          ang_gyr_y = ang_acc_y;
        }

        Thread.sleep(deltat); //deltatミリ秒遅延する
      }
    }catch(InterruptedException e){}
  }
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

比較する配列の前後(例えばgyr_x[1]gyr_x[2])の間で実際の計測時間の差と計算時のdeltatの値がずれているために結果がおかしくなっているのではないでしょうか。 gyr_x[1]gyr_x[2]の間での実際の計測時間は角速度に変化が発生した後、次に角速度に変化が発生するまでの時間になると思います。

角速度の測定をdeltatの間隔に合わせるか、実際の測定間隔を保持し、それを元に計算すれば良いのではないでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/12/07 13:30

    やっぱりそうなんですね…。回答ありがとうございます。

    キャンセル

0

質問と関係ありませんが、気になったことを。

コードを見ると各軸ごとに角速度を積分しています(そしてZ軸を無視しています)が、
実はこれ、意味のある値は得られません。

センサーは端末に固定されています。
従ってセンサーの値を積分するということは、端末の軸を基準にして回した値を求めることになります。
一方、目的が、「水平を保つ」なので、欲しい値は研究室系に対して、どれだけ回転しているかです。
(もっと言えば、端末のZ軸が、研究室系のZ軸に対して何度(スカラー)傾いているかが欲しい)

さて、各軸を独立して積分した結果からは、姿勢が一意に決まりません。
積分結果が非0でも水平という状態が普通にありえます。

例えば、
X+90 -> Y+90 -> X-90 -> Z-90
(X+90はセンサーX軸回りで90度回転の意)
という回転操作は、各軸の合計が(0,90,-90)ですが、
操作後の端末は操作前の状態に戻ります。
端末を実際に持って回して確かめてください。

したがって、各軸ごとに独立して積分しても、水平を保つのに役に立ちません。

じゃあどうするのかといえば回転行列やクォータニオンを使います。
オススメはクォータニオンです。  

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 87.92%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る