6軸センサー(MPU6050)から3軸回転の傾き角度の算出・補正方法

 6軸センサーから、3軸回転を考慮した傾き角度(姿勢角度)の算出方法、補正方法はいろいろあると思いますが一例を解説したいと思います。(ここら辺りの内容は散発して記事を投稿していたのですが、一度纏めたいと思います)

 

 使用する6軸センサーはMPU-6050、マイコンはArduinoUNOです。

 

 MPU-6050ではジャイロ(3軸角速度)、加速度センサー(3軸加速度)の値を取得できます。ジャイロのみでも加速度センサーのみでも角度算出はできるのですが、センサー毎に特徴がありその特徴を補う形で補正を行い、より正確な姿勢角を導きます。

 

 センサー値の補正には便利なフィルター、カルマンフィルターやMadgwickフィルターなどがあります。言語ライブラリも存在し使用するだけなら比較的簡単なのですが中身が私とっては非常に難解です。ブラックボックス的なものはあまり使用したくないということもあり今回は使用しないで姿勢角を算出・補正したいと思います。

 

 ではまずジャイロ値(角速度)からの角度算出方法とのその特徴です。

 

ジャイロ(角速度)からの3軸角度算出方法と特徴

MPU-6050の使い方
角速度から角度の算出方法
はそれぞれ別の投稿記事で解説してますのでそちらを参考にして下さい。

 

 ジャイロからの角度算出ですが、センサーから取得した角速度を時間で積分すれば角度となります。1軸回転のみを検出するのであれば単純な積算でも算出できるのですが、3軸回転となると少しややこしくなります。

 

 センサー軸自体が傾いてしまうため、そのベクトル(センサー軸の傾き)を考慮する必要があります。

 

▼動画解説▼

 (わかり難いでしょうか)上図のような回転があった場合、最終的には姿勢角は水平になるはずなのですが(z軸回転のみ残る)、単純な積算ではx軸、y軸ともに角速度からの積算値が残ってしまうため、おかしな算出値になってしまいます。

 

 3軸回転の場合はオイラー角、行列式や四元数などを使って、ベクトルを合わせて算出する必要があるのですか、これまた数学的理解が私にとっては非常に難解です。公式があるので使用するだけならなんとかなりますが、中身のわからないものはあまり使いたくないため、無理やりですが近似的に3軸回転を考慮する算出方法で行いたいと思います。

 

 まず、x軸回転後にz軸回転を加えた場合、x軸の傾きがどのように変わっていくのかを3DCadで作図しながらその角度を測定してみました。

 

▼3DCadから角度を測定▼

 このような感じでCADで作図しながら少しずつ実角度を測定してます。測定している角度は、x軸廻りに30度回転後(y軸が水平面と30度の状態)でz軸回転を少しずつ加えた時の「水平面」と「x軸」との角度です。(3DCadはフリーのFusion360使用してます。AutoDeskのギャラリーに作品をアップしてます。宜しければご覧ください)

 

▼z軸回転角度とx軸の傾きの移り変わりをグラフにすると▼

 こんな感じです。正弦波っぽい移り変わりをします。

 

▼正弦波と合わせると▼

 微妙に違いますが概ね合います。(ここら辺が少し無理やりです)

 

▼z軸回転とy軸傾きも▼

 このような感じで正弦波に近い形で移り変わります。90度回転後にx軸、y軸の傾きは入れ替わり、また180度回転後にもとの角度に戻ります。

 

 ということで単純に積算したx軸、y軸の傾き角度に、「z軸回転角度分の正弦波」を加味させていけば3軸回転(ベクトルの移り変わり)を考慮した傾き角度が算出できるはずです。

 

 ▼言語風に描くと、▼

  roll  += gx * dt;
  pitch += gy * dt;
  yaw   += gz * dt;

 まずジャイロ値(角速度)から3軸の回転角度を単純に積算(時間積分)します。

 

 ▼その後、z軸回転(yaw回転)分の移り変わりを加味します▼

  roll  += pitch * sin(gz * dt * pi()/180) ;
  pitch -= roll * sin(gz * dt* pi()/180) ;

 ここら辺も少し無理やりでしょうか?・・。

 

 このような感じでジャイロから傾き角度(姿勢角)を算出します。当然、オイラー角や四元数使った方が正確かと思いますが・・。

 

 またジャイロからの角度算出には少し欠点があります。

<スポンサーリンク>

 

 角度算出に積分を使用しているため、センサー誤差やノイズなどをどんどん積算してしまい角度がずれていってしまいます(ジャイロドリフト)。

 

▼ジャイロドリフト確認▼

 このグラフではジャイロドリフトを確認してます。センサーを水平に置いたまま、ジャイロ値を積算し角度を算出しているのですが、時間が経つにつれて角度が発生します。誤差やノイズなども積算してしまうため発生する現象です。

 

 このずれ(ジャイロドリフト)を補正する必要があるのですが、補正を行うために加速度センサーの値を使用します。

 

加速度センサーからの角度算出方法と特徴

加速度センサーからの角度算出方法

はこちらで詳細説明してます。

 

 まず加速度センサーからの取得値からの傾き角度ですが

rollAccel   = atan2(ay, sqrt(ax * ax + az * az)) * pi()/180;
pitchAccel  = atan2(ax, sqrt(ay * ay + az * az)) * pi()/180;

で算出できます。少しリンク先の説明と違いますが水平面からの各軸傾きの算出であればこれでも問題ないと思います。いろいろと算出方法があると思いますがなんでも良いのかな?お好みで・・。

 

 加速度センサーからはz軸廻り(yaw回転)の角度は算出は困難です。また加速度センサーは感度が良すぎるというのか、値が結構暴れます。またセンサー自体に加減速がある場合には計算される角度がおかしくなってしまいます。

 

 こういったことを考慮に入れて使用する必要があります。

 

まとめと補正方法

 ジャイロからでも加速度センサーからでも傾き角度(姿勢角度)は算出できるのですが、それぞれの特徴があり、補正を行ってより正確な傾き角度を算出します。

 

◆ジャイロの場合

  • 3軸回転がある場合は単純な積算ではなくベクトルを考慮する必要がある。
  • 誤差が蓄積して角度が少しずつずれていく。(ジャイロドリフト)

 

◆加速度センサーの場合

  • z軸廻り(yaw回転)の角度算出が困難(できない?)
  • センサーが加減速しているときには正確な角度算出は困難。
  • ドリフトは無い

 

 ここでより正確な角度を算出するための補正方法となりますが、互いの特徴を生かして行います。

 

 基本的にはジャイロで角度算出し、加速度センサーでジャイロドリフトを補正する方法で行います。

roll = 0.995 * (roll + gx * dt) + 0.005 * rollAccel

 1次遅れの伝達関数みたいな感じ??、加速度センサー側の値を小さくすればするほど微細な動きの影響は無視できますが、補正が遅くなる感じでしょうか。ジャイロ、加速度のどっちに重みを持たせるかってとこでしょうか。

 

確認動画

 いろいろな方法で角度算出したものを比較してみました。

▼確認動画▼

 左から順に、加速度センサーのみ。ジャイロのみ。相補フィルター(本記事で紹介した方法)。madgwickフィルターとなってます。(動画がコマ落ちしてますがすみません)

 

 加速度センサーはz軸(yaw回転)回転は可視化してません。動画途中でセンサーを揺すってますが、加減速が発生すると角度がおかしくなってます。

 

 ジャイロのみからの算出は割といい感じで姿勢角を算出できてますが、動画最後にはドリフトが発生していて、水平に戻っていません(少しわかり難いですが)。

 

 相補フィルター(本記事で紹介した方法)ではz軸回転(yaw回転)時に動きが少し微妙で、(係数小さすぎ?)角度も少し遅れて補正する感じでしょうか。目的によってはこの方法でも十分使えそう?です。

 

 madgwickフィルターはさすがです。特に問題なく角度算出している感じです。中身は全くわかませんがライブラリ使うだけなら簡単です。

 

 ちなみに本記事で紹介した角度算出方法で、自作ドローンの姿勢制御ロジックのソース作ってます。まだ改良中ですがこちらでテスト稼働の動画をアップしてます。興味がありましたらご覧ください。(madgwickフィルターへ変えようかな、と思ってますけど・・・。)

 

 長文となってしまいました。ここまで読んで頂きなんですが特にこだわりがなければ、四元数使って角度算出したり、madgwickフィルターやカルマンフィルター使って補正したりするのが一番無難かと・・・。

<スポンサーリンク>


この投稿へのコメント

  1. あんぱん said on 2017-11-22 at 13:28

    はじめまして。
    ジャイロセンサの勉強を行っているものなのですが、
    角度の検出には角速度のみでは誤差が多いことをこちらのブログを拝見して初めて知り、目から鱗です。
    1つお願いがあるのですが、madwickフィルターを用いた角度検出のソースコードを教えて下さることは可能でしょうか。

    急なお願いで申し訳ありませんが、宜しくお願い致します。

    • imo said on 2017-11-22 at 22:37

      あんぱんさん、はじめまして。コメント有難うございます。
      ソースコードを教えることはなかなか難しく困ってしまいます。また私もmadgwickフィルターの中身はほとんどわかっていないためライブラリを使用しているだけとなります。もしArduinoをお使いでしたらライブラリがあるため確認頂いて、そのうえで具体的に質問頂けないでしょうか

  2. 匿名 said on 2017-12-15 at 22:14

    記事を拝見させていただき、非常に参考になりました。ありがとうございます。1つ質問があるのですが、
    加速度センサーからはyaw回転の角度算出が困難であるとのことですが、確認動画の結果においてはyaw回転についても相補フィルターを通しているように思います。
    yaw回転の相補フィルターの式はどのようなものでしょうか?教えて頂けると幸いです。

    • imo said on 2017-12-16 at 00:18

      匿名さん、こんにちは。コメント有難うございます。
       yaw回転の補正は残念ながら行っておりません。本ページにある動画の相補フィルターではジャイロ値を単純に積算した値を使用してます。動画内ではyaw回転のドリフトがたまたま目に見える程発生していないだけだと思います。

コメントを残す

メールアドレスが公開されることはありません。

この投稿へのトラックバック

トラックバックはありません。

トラックバック URL