ジャイロスコープ

🧭 ジャイロスコープとは?

ジャイロスコープは、物体の回転の速さ角速度)を検出するセンサーです。スマートフォンやドローンなど、身の回りにある多くのデバイスに使われています。

🔌 インターフェース(データのやり取り方法)

ジャイロスコープとコンピューターやマイコン(小さなコンピューター)がデータをやり取りする方法をインターフェースと呼びます。一般的に使われる主なインターフェースは以下の通りです。

1. I²C(Inter-Integrated Circuit)

  • 特徴: 2本の信号線(SDA: データ線, SCL: クロック線)で複数のセンサーと通信できる、広く使われる規格です。
  • 簡単さ: 比較的シンプルで、多くのマイコン(ArduinoやRaspberry Pi Picoなど)で簡単に扱えます。
  • データの形式: デジタルデータ(0と1の信号)で通信します。

2. SPI(Serial Peripheral Interface)

  • 特徴: 4本以上の信号線(MOSI, MISO, SCLK, CSなど)を使い、I²Cよりも高速な通信が可能です。
  • 簡単さ: 配線はI²Cより少し複雑ですが、高速なデータ取得が必要な場合に適しています。
  • データの形式: デジタルデータ(0と1の信号)で通信します。

💡 補足: 実際にセンサーから値を取得する際は、これらのインターフェースを使って、センサー内部のレジスタ(データを格納する場所)にアクセスし、保存されている計測値を読み出します。

🔢 取得できる値

ジャイロスコープは、主に3つの軸(X軸、Y軸、Z軸)周りの角速度(かくそくど)を測定し、デジタル値として出力します。

  • 角速度($\omega$:オメガ):
    • 単位は**[deg/s](度/秒)[rad/s](ラジアン/秒)**です。
    • 意味: 1秒間に何度の速さで回転しているかを示します。
    • 3軸:
      • X軸: 前後方向(ピッチ)の回転
      • Y軸: 左右方向(ロール)の回転
      • Z軸: 上下方向(ヨー)の回転

📝 具体例: Z軸の角速度が +90 [deg/s] と表示された場合、センサーはZ軸を中心に1秒間に90度の速さで時計回りに回転していることを意味します。

✅ 何ができるのか?(応用例)

ジャイロスコープが測定した角速度の値を活用することで、デバイスの姿勢の安定化動きの検出など、さまざまなことができます。

1. 姿勢の制御と安定化

  • ドローンや飛行機の制御: 機体が風などで傾いたとき(角速度が発生したとき)、その回転を検知し、自動で正しい姿勢に戻すための制御に使われます。
  • ロボットのバランス: 倒れそうになった方向への回転を検知し、モーターを制御して直立を維持するために使われます。

2. 動きや方向の検出

  • スマートフォンの機能:
    • 画面の自動回転:スマホが傾けられた(回転した)ことを検知します。
    • ゲームの操作:コントローラーやスマホを振る、傾けるといった動きを検知します。
  • VR/ARデバイス: ユーザーの頭の動き(回転)を正確に追跡し、仮想空間での視点の移動に反映させます。

3. 回転角度(姿勢角)の推定

  • ジャイロスコープで得られた角速度積分(時間をかけて足し合わせること)することで、現在の回転角度(姿勢角)を推定できます。
    • $$\text{回転角度} (\theta) = \sum (\text{角速度} (\omega) \times \text{測定時間間隔} (\Delta t))$$
  • ただし、この方法単独だと時間の経過とともに誤差が蓄積するため、実際には加速度センサーなど、他のセンサーの値と組み合わせて(センサーフュージョン)、より正確な姿勢を推定することが一般的です。

💡 ジャイロスコープによる姿勢更新

もう少し技術的に深掘りして見ていきます。

IMU(慣性計測装置)には「加速度センサー」と「角速度センサー(ジャイロスコープ)」があります。
ジャイロスコープは「どのくらいの速さで回転しているか(角速度)」を測ります。

この「回転の速さ」を時間に沿って積み重ねていく(積分する)と、「どのくらい向きが変わったか」がわかります。(先ほどの式です)
つまり、ジャイロは姿勢(向き)の変化を追跡するためのセンサーです。

🌀 回転の数学的な表現

1. 角速度ベクトル

ジャイロが出す値は「角速度ベクトル」$$\boldsymbol{\omega} = [\omega_x, \omega_y, \omega_z]$$ です。
これは、機体がそれぞれの軸(x, y, z)まわりにどのくらいのスピードで回っているかを示します。

2. 姿勢行列(回転行列)とは

機体の姿勢を「回転行列」で表すことができます。
回転行列 $$C_b^n$$ は「機体の向きを世界座標に対してどう回っているか」を示す3×3の行列です。

3. 姿勢の変化を表す式

姿勢が時間とともにどう変化するかは、次の式で表されます:

$$\dot{C}_b^n = C_b^n \Omega_b​$$

ここで \( \dot{C}_b^n \)は「回転行列の時間変化率(どの方向に姿勢が変わるか)」です。
\( \Omega_b \) は角速度ベクトルから作った「回転の性質を表す行列」です。

4. 歪対称行列(すいたいしょうぎょうれつ)

\( \Omega_b \) は次のような形になります: $$\Omega_b = \begin{bmatrix} 0 & -\omega_z & \omega_y \\ \omega_z & 0 & -\omega_x \\ -\omega_y & \omega_x & 0 \end{bmatrix}$$​​

この形の行列を「歪対称行列(skew-symmetric matrix)」といいます。
特徴は、対角線の左右で符号が反対になっていることです。

この行列を使うと、ベクトルの「回転(クロス積)」を行列の掛け算で表現できるという便利な性質があります。
つまり「ベクトルの回転運動」を、行列として扱えるようにしたものです。

🧭 クォータニオン(四元数)を使う理由

3×3の行列でも姿勢は表せますが、次のような問題があります:

  • 数値計算中に行列が少しずつ「正しい回転行列」からズレていく
  • 計算量が多く、積分のたびに行列の直交性を保つのが面倒

そこで、実際の実装では「クォータニオン(四元数)」という4次元の数を使うのが一般的です。

クォータニオンによる姿勢更新

クォータニオン \( \mathbf{q} \) の時間変化は次のように表されます: $$\dot{\mathbf{q}} = \frac{1}{2} \mathbf{q} \otimes \boldsymbol{\omega}$$

ここで:

  • \( \mathbf{q} \) … 現在の姿勢を表すクォータニオン
  • \( \boldsymbol{\omega} \) … 角速度を拡張したクォータニオン([0, ωx, ωy, ωz])
  • \( \otimes \) … クォータニオンの掛け算(回転の合成を意味する)

つまり、「今の姿勢」+「角速度」から、次の姿勢が求まるということです。

🪄 イメージでまとめると

概念イメージ数学的表現
角速度「今どの方向にどのくらい速く回ってるか」\( \boldsymbol{\omega} \)
姿勢行列「どの向きを向いているか」\( C_b^n \)
姿勢の時間変化「時間が経つと姿勢がどう変わるか」\( \dot{C}_b^n = C_b^n \Omega_b \)
クォータニオン版「回転をスマートに扱う方法」\( \dot{\mathbf{q}} = \frac{1}{2} \mathbf{q} \otimes \boldsymbol{\omega} \)

🔧 実際の処理の流れ(ざっくり)

  1. ジャイロから角速度 \( \boldsymbol{\omega} \) を取得
  2. そのデータをもとに、微小な姿勢変化をクォータニオンで表現
  3. 前回の姿勢に掛けて、現在の姿勢 \( \mathbf{q}(t+\Delta t) \) を求める
  4. 必要に応じて、クォータニオンからオイラー角(ピッチ・ロール・ヨー)や回転行列に変換

例1:Z軸まわりに一定角速度(90°/s)で1秒回転

  • 初期姿勢:\( \mathbf{q}_0=[1,0,0,0] \)(単位姿勢)
  • 角速度:\( \boldsymbol{\omega}=[0,0,90]~\text{deg/s}\)
  • 区間:\( \Delta t=1.0~\text{s} \)(1秒間一定角速度とする)

ステップ

  1. 「この区間で回った角度」の大きさ

$$ \theta = \|\boldsymbol{\omega}\|\Delta t = 90^\circ \times 1.0 = 90^\circ = \frac{\pi}{2}\,\text{rad} $$

  1. 回転軸(単位ベクトル)

$$\mathbf{u}=\frac{\boldsymbol{\omega}}{\|\boldsymbol{\omega}\|} = [0,0,1]$$

  1. この区間の“微小でない”回転クォータニオン(デルタ姿勢)

$$ \Delta\mathbf{q} =\Big[\cos\frac{\theta}{2},\;\mathbf{u}\,\sin\frac{\theta}{2}\Big] = \left[\cos\frac{\pi}{4},\;0,\;0,\;\sin\frac{\pi}{4}\right] = [\,0.70710678,\;0,\;0,\;0.70710678\,]$$

  1. 新しい姿勢は右積(機体系での角速度想定)で更新

$$ \mathbf{q}_1 =\mathbf{q}_0\otimes\Delta\mathbf{q} =\Delta\mathbf{q} = [\,0.70710678,\;0,\;0,\;0.70710678\,] $$

(正規化はこの例では既に単位長ですが、実装では毎回 normalize を推奨)

  1. 検算(ヨー角を取り出す)
    Z軸まわりの純回転なのでヨー \( \psi \) は 90° になります(実際、式に代入しても \( \psi=90^\circ \)∘)。

例2:斜め軸(\( [10,20,30]°/s \) )で \(\Delta t=0.01s \)の1ステップ更新

  • 初期姿勢:\( \mathbf{q}_0=[1,0,0,0] \)
  • 角速度:\( \boldsymbol{\omega}=[10,20,30]~\text{deg/s} \)
  • サンプリング間隔:\( \Delta t=0.01~\text{s} \)

ステップ

  1. 角速度の大きさ

$$ \|\boldsymbol{\omega}\|=\sqrt{10^2+20^2+30^2}=37.4166~\text{deg/s}$$

  1. 区間角度

$$ \theta=\|\boldsymbol{\omega}\|\Delta t=37.4166\times0.01=0.374166^\circ = 0.00653042~\text{rad}$$

  1. 単位回転軸

$$\mathbf{u}=\frac{\boldsymbol{\omega}}{\|\boldsymbol{\omega}\|} =[\,0.26726124,\;0.53452248,\;0.80178373\,]$$

  1. デルタ姿勢クォータニオン

$$ \Delta\mathbf{q}=\Big[\cos\frac{\theta}{2},\;\mathbf{u}\,\sin\frac{\theta}{2}\Big] $$

$$ \frac{\theta}{2}=0.00326521\ \Rightarrow\ \cos\frac{\theta}{2}=0.9999946692,\ \ \sin\frac{\theta}{2}=0.0032652062$$

$$ \Rightarrow\ \Delta\mathbf{q} =\big[\,0.9999946692,\;0.0008726631,\;0.0017453262,\;0.0026179892\,\big]$$

  1. 更新(右積)

$$ \mathbf{q}_1=\mathbf{q}_0\otimes\Delta\mathbf{q}=\Delta\mathbf{q} $$

実装では \( \mathbf{q}_1 \)​ を正規化しておきます。

連続時間で \( \dot{\mathbf{q}}=\tfrac12\mathbf{q}\otimes[0,\boldsymbol{\omega}] \) を数値積分する代わりに、
上のように「角速度一定」の仮定で各サンプルごとに \( \Delta\mathbf{q} \) を作って右積するのが定番です。

実装ミニチュートリアル(擬似コード)

function step(q, omega_body_deg_per_s, dt_sec):
    # 1) 角速度の大きさ(deg/s)
    wmag = norm(omega_body_deg_per_s)
    if wmag == 0:
        return q  # 変化なし

    # 2) 区間角度(rad)
    theta = radians(wmag * dt_sec)    # deg → rad
    half = theta / 2
    c = cos(half)
    s = sin(half)

    # 3) 単位回転軸
    u = omega_body_deg_per_s / wmag

    # 4) Δq
    dq = [c, u.x*s, u.y*s, u.z*s]

    # 5) 右積更新 & 正規化
    q_next = quat_multiply(q, dq)
    return normalize(q_next)

※ 機体系角速度なら右積\( (q \leftarrow q\otimes\Delta)\)、
地表座標系角速度なら左積\((q \leftarrow \Delta q\otimes)\)になる点に注意。

実務でのポイント(超重要)

  • 単位の統一:センサー出力(だいたい rad/s)とコード内の単位を必ず揃える。上は説明都合で deg/s を使いましたが、実装は rad に統一を推奨。
  • 正規化:毎ステップ \( \mathbf{q} \) を normalize して数値誤差の蓄積を防ぐ。
  • バイアス補正:ジャイロのバイアス(オフセット)を引かないと、姿勢がじわじわ流れます。
  • サンプリング:\( \Delta t\) は実測のサンプル周期で。可変の場合は都度その値で更新。
  • オイラー角化:可視化用に \( \mathbf{q}\to(\phi,\theta,\psi) \) 変換はOKだが、内部表現は \( \mathbf{q}\) のままが安定。
← ITQ Lab トップに戻る