このページは現在編集途上です

手っ取り早く感覚的に理解をしたい場合は、下記の参考文献が役に立ちます。

二輪車の制御理論

本章では、大学課程での力学を踏まえた詳細な解説として、2輪車の力学モデルを提示し、状態の数式化、制御則設計、安定性解析、そしてジャイロ効果に関する誤解の解消までを詳述します。

倒立振子モデルの数学的定式化

倒立振子は、角度 \( \theta \) の小さな動作範囲を考慮した線形近似モデルで表します。
そして、ROBOBIKE(以下車体と表す)について下記の設定(モデル化)を行います。

  • 前後方向の軸をロール軸(y軸)、上下方向をヨー軸(z軸)、左右方向の軸をピッチ軸(x軸)とする
  • は剛体である
  • すべての質量が重心位置に集中する
  • 前項に起因して、車体の慣性モーメントは無い

この制御則の面白さは、教科書的な「静的な釣り合い」ではなく、「動的な角運動量のマネジメント」を直感的に行っている点にあります。以下の2段階構成で解説すると、先生や学生にも深く刺さるはずです。


なぜ倒れないのか:角速度による「勢い」の相殺

まず、制御則のC言語による実装コードを記す。

        str_dev = str_target - str_out;
        str_dev_diff = (str_dev - last_str_dev) * SV_FRQ;

        str_diff_lps =
            saved.str_diff_alph * str_diff_lps
            + (1.0f - saved.str_diff_alph) * str_dev_diff;

        w_roll_cmd =
            str_dev * saved.gain_str
            + str_diff_lps * saved.gain_str_diff;

        w_roll_dev =
            w_roll_cmd - IMU_roll();

        str_out -=
          w_roll_dev * saved.gain_w_roll * (1.0f / SV_FRQ);

        last_str_dev = str_dev;
        chklimit(&str_out, STRMAX);
        str_pwm_out(str_out);

注目すべきは「角度(姿勢)」を目標にするのではなく、「角速度(動き)」を制御対象にしていることです。

  • 「傾き」を直すのではなく「倒れる勢い」を殺す 通常の倒立振子は「直立(0度)」を目標にしますが、本機は「倒れようとする速度(w_roll_dev)」をゼロにすることを最優先しています。
  • 逆操舵(カウンターステア)の実装 コード内の str_out -= w_roll_dev... は、物理的に「左に倒れ始めたら、ハンドルを左に切る」という動作を指します。
    • 左に切ることで、タイヤの接地点が左に移動し、相対的に重心が右に残ります。
    • この瞬間的な「起立モーメント」の発生により、倒れようとする勢い(ロール角速度)を逆方向の加速度で打ち消します。
  • 積分項の役割:未知の釣り合い点の探索 ハンドル角を積分で更新する形式(速度型)は、路面の傾斜やメカ的な重心のズレといった「定数的な外乱」を、積分項が「必要なハンドル角」として勝手に溜め込んで相殺することを意味します。これにより、バンク角の計算を飛ばしても結果的に「倒れないハンドル角」に収束します。

好きな方向へ走らせる方法:目標進路と姿勢制御の「主従関係」

次に、外側のループを加えて「方向(str_target)」を制御する仕組みを説明します。

  • 進路偏差を「姿勢の変化」にすり替える 本来、ハンドルを左に切れば左に曲がりますが、二輪車はそのままでは外側に倒れてしまいます。 本機では、str_dev * gain_str によって、「目標進路からのズレ」を「発生させるべきロール速度(w_roll_cmd)」へと変換しています。
  • 「曲がるために、あえて一度逆に倒す」プロセス
    1. 左に曲がりたい(目標進路が左)
    2. str_dev がプラスになり、内側ループへ「左へロールせよ(w_roll_cmd)」と命令。
    3. 内側ループは左へ倒すため、あえて一瞬右にステアリングを切る(逆操舵)
    4. 車体が左に傾き、そのバンク角によって「セルフステア」が発生し、自然に左へ旋回を開始する。
  • カスケード制御の妙 この「進路を直したい」という欲求(外側ループ)が、内側の「バランスを保つ反射(内側ループ)」を上手く利用して、結果的に高度な旋回動作を実現しています。

第1段階:定常状態の維持(なぜ倒れないのか)

  • メカニズム: 微小な傾きに対し、接地点を重心の下へ滑り込ませる追従制御。
  • 物理: 重力による転倒モーメントが成長する前に、最小限の操舵で「起立(復元)モーメント」を発生させ、平衡状態を維持する。

第2段階:過渡状態の遷移(なぜ曲がれるのか)

  • メカニズム: 大型バイクの操縦と同様、復元力に抗ってハンドルを逆方向へ切り込むプロセス。
  • 物理: gain_str によって生成された強い要求(角速度目標)が、一時的に「安定の壁」を突き崩す。これにより車体を意図的に倒し込み、旋回に必要なバンク角を「重力を使って無理やり作り出す」。

「本制御系は、静的な『バンク角の目標値』を保持しない。代わりに、ステアリングの進路偏差を『必要な姿勢変化(角速度)』へと逐次変換し、内側の高速なバランス・リフレックス(反射)に委ねることで、人間が自転車を操る際の『無意識の身体知』を再現している。」

まとめ:論文向けのロジック構成

  1. 内側(反射層): 角速度フィードバックによる倒立維持。逆操舵の物理的実装。
  2. 外側(戦略層): 進路偏差を「姿勢変化要求」へ変換。
  3. 統合: 目標バンク角を計算しない「速度型カスケード制御」による、演算負荷の低減とロバスト性の両立。

「計算を端折った」のではなく、「物理現象の微分的な変化をダイレクトに叩くことで、非線形な挙動を抑え込んだ」と定義する


運動方程式は以下のように記述されます:

\[
I \cdot \ddot{\theta} = mgh \cdot \theta + u
\]

ここで、\( I \) は慣性モーメント、\( m \) は質量、\( g \) は重力加速度、\( h \) は重心の高さ、\( u \) は制御入力トルクを表します。

状態空間モデルの導出

状態変数を \( x = [\theta, \dot{\theta}]^T \) と定義すると、状態空間表現は以下のようになります:

\[
\begin{bmatrix}
\dot{\theta} \\
\ddot{\theta}
\end{bmatrix}
=
\begin{bmatrix}
0 & 1 \\
\frac{mgh}{I} & 0
\end{bmatrix}
\begin{bmatrix}
\theta \\
\dot{\theta}
\end{bmatrix}
+
\begin{bmatrix}
0 \\
\frac{1}{I}
\end{bmatrix}
u
\]

制御則設計

代表的な制御則として、状態フィードバック制御が挙げられます。制御入力 \( u \) を状態の線形結合として設計します:

\[
u = -Kx = -\begin{bmatrix} K_p & K_d \end{bmatrix}
\begin{bmatrix}
\theta \\
\dot{\theta}
\end{bmatrix}
\]

ここで、\( K_p \) は比例ゲイン、\( K_d \) は微分ゲインです。これにより、倒立振子の安定化を図ります。

また、PI制御の例としては:

\[
u(t) = -K_p \cdot \theta(t) - K_i \int_0^t \theta(\tau) \, d\tau
\]

があり、定常偏差の除去に寄与します。

  • 「ジャイロ効果で倒れない」は誤解であることを明言
  • 倒立振子モデルの導入(高校物理レベルの記法)
  • 制御則の例(状態フィードバック、PI制御など)
  • ジャイロスコピックプリセッションが式に現れないことの確認

ROBOBIKEの制御実装と工夫

  • 実際の制御構成(RTOS、マルチタスク、I2Cセンサ)
    サーボ制御パルスは通常20msec周期で送出されるところ、本気では5ms間隔で送出して、高速応答を実現
    パルスに同期して、最短時間でIMUによる角速度測定値取得から演算を経てパルス幅確定直後にサーボへ送出できるよう、GPIO入力立ち上がり割り込みからのハードウェアタイマによるタイミング調整を実施。一連の演算処理結果を最短時間でサーボ出力に反映する実装とする。
  • 倒立制御の安定化のためのパラメータ調整
  • ソフトウェア設計のポイント(C言語、ESP-IDF)
  • 複数台走行時の制御同期や干渉対策