LQR 倒立振子シミュレーター 戻る
制御工学シミュレーター

LQR 倒立振子シミュレーター — 最適レギュレータと状態フィードバック

カート上の倒立振子を LQR 状態フィードバックで安定化。状態重み Q と入力ペナルティ R を調整して、応答の速さと入力の大きさのトレードオフを学べます。

パラメータ設定
位置重み Q_p
角度重み Q_θ
入力ペナルティ R
初期角度 θ_0
°

カート質量 M=1.0 kg、振子質量 m=0.1 kg、振子長 L=0.5 m、重力 g=9.81 m/s²、シミュレーション時間 5 s(dt=0.01 s、RK4 積分)。

計算結果
ゲイン K
整定時間 t_s(5%)
最大入力 |u|_max
角度オーバーシュート
時間応答と制御入力

上段=カート位置 p(t)(青)と振子角度 θ(t)(橙、deg)/下段=制御入力 u(t)(緑、N)

理論・主要公式

カート+振子の小角度線形化モデル。状態は $x=[p,\dot p,\theta,\dot\theta]^\top$、入力 $u$ はカートに加える水平力:

$$\dot x = A x + B u,\quad A=\begin{bmatrix}0&1&0&0\\0&0&-\tfrac{mg}{M}&0\\0&0&0&1\\0&0&\tfrac{(M+m)g}{ML}&0\end{bmatrix},\ B=\begin{bmatrix}0\\ \tfrac{1}{M}\\0\\ -\tfrac{1}{ML}\end{bmatrix}$$

LQR は二次評価関数 $J=\int_0^\infty(x^\top Q x + u^\top R u)\,dt$ を最小化する状態フィードバック:

$$u = -K x,\qquad K = R^{-1} B^\top P$$

$P$ は代数 Riccati 方程式 $A^\top P + PA - PBR^{-1}B^\top P + Q = 0$ の解です。

本ツールは教育目的のため、基準ゲイン K=[1, 1.5, 30, 5] に √(Q/R) を乗じる簡易スケーリングを採用しています。

LQR 倒立振子シミュレーターとは

🙋
「LQR」って制御の授業で出てきた気がするんですけど、要は何をやってるんですか?
🎓
ざっくり言うと「状態を素早く0に戻したい。でも入力は使いすぎたくない」を両立させる最適制御だ。式で書くと $J=\int(x^\top Q x + u^\top R u)dt$ を最小化する。Q が大きいと「ズレ」を嫌い、R が大きいと「入力」を嫌う。上のシミュレーターで Q_θ を1000、R を0.01にすると、めちゃくちゃ素早く立ち上がるけど入力が暴れるのが見えるよ。
🙋
なるほど。「角度重み Q_θ」を大きくすると、振子の角度に厳しくなるってことですか?
🎓
そう。Q_θ を上げるとゲイン K の角度成分が大きくなり、少しでも傾くと強く押し返すようになる。逆に Q_p を上げるとカート位置のズレに厳しくなる。実機の設計では「振子は絶対倒したくないけど、カート位置はある程度自由に動いていい」というケースが多いから、Q_θ ≫ Q_p に設定するのが定石だ。デフォルトの Q_θ=100, Q_p=1 もまさにこのバランスだよ。
🙋
下のグラフが入力 u(t) ですよね。R を変えると u が大きく変わりますね。
🎓
R は入力のコスト。R を小さくすると「入力タダ」と思って最適化器がガンガン押すから、応答は速いけど u_max が跳ね上がる。逆に R を大きくすると「入力は高いから節約しろ」となり、ゆっくり立ち上がる代わりに入力波形は穏やかになる。実機ではアクチュエータの飽和や消費電力で R を決めるんだ。$200{\rm N}$ までしか出せないモータなら、R を上げて u_max を抑える設計にする。
🙋
「整定時間」って何の時間ですか?
🎓
振子角度が初期値の5%以内に収まってから二度と外れなくなるまでの時間だ。制御性能を1つの数字で表す代表的な指標で、整定時間が短いほど「素早く」「安定に」止められたことを意味する。Q_θ や Q_p を上げると整定時間は短くなるけど、その代わり u_max が増える——このトレードオフが LQR 設計の核心だよ。

よくある質問

代数 Riccati 方程式 $A^\top P + PA - PBR^{-1}B^\top P + Q = 0$ は、無限時間 LQR 最適化問題の最適コスト行列 $P$ を与える非線形行列方程式です。$P$ が求まれば最適ゲインは $K=R^{-1}B^\top P$ で一意に決まります。$P$ は対称正定値で、その物理的意味は「現在の状態 $x$ から将来全期間にわたって生じる最小コスト $x^\top P x$」です。数値解法は Schur 分解や Hamiltonian 行列の固有値分解が標準で、MATLAB の lqr() や Python の scipy.linalg.solve_continuous_are() で簡単に解けます。
実機ではセンサノイズやプロセス外乱があり、全状態を直接観測できないことがほとんどです。Kalman フィルタは観測値と内部モデルから最小分散の状態推定 $\hat x$ を作る最適推定器で、これに LQR ゲイン $K$ を組み合わせて $u=-K\hat x$ とするのが LQG(Linear Quadratic Gaussian)制御です。「分離原理(Separation Principle)」により、最適制御器(LQR)と最適推定器(Kalman フィルタ)を別々に設計しても全体最適となることが保証されます。LQR の理論を現実の不完全観測下で使うための標準的な拡張です。
基本原理は同じです。人型ロボットの直立は重心が支持基底面(足裏)の上にある不安定平衡で、倒立振子と等価なモデル(線形倒立振子モデル、LIPM)で近似されます。床反力モーメントを入力として LQR や MPC(モデル予測制御)で姿勢を安定化する研究は多く、ホンダの ASIMO、ボストン・ダイナミクスの Atlas など多くの実機に同種の制御則が組み込まれています。複雑な多関節ロボットでも、重心動力学を抜き出せばこの単純な4次モデルの拡張として扱えるのが面白いところです。
本ツールの状態空間モデルは小角度近似 $\sin\theta\approx\theta,\ \cos\theta\approx1$ を前提としています。経験則として $|\theta|<20°$ 程度なら線形モデルと非線形モデルの差は数%以内ですが、$30°$ を超えると無視できない誤差が出ます。初期角度スライダーを $\pm30°$ にすると、現実には立ち上がらないかもしれませんが、本ツールでは線形モデル上で「安定する」と表示される点に注意してください。実機では非線形動力学を直接扱う Energy-Based Swing-Up 制御や、より広い動作域をカバーする Gain Scheduling、MPC が併用されます。

実世界での応用

ロケットとミサイルの姿勢制御:打ち上げ直後のロケットは推力線が重心の下にあるため、倒立振子と同じ不安定平衡にあります。SpaceX の Falcon 9 の垂直着陸も、各エンジンのジンバル角を状態フィードバックで制御して機体を立てたまま降ろす技術です。LQR や、より発展した LQR-LQG・MPC が姿勢制御則のベースになっています。

2輪セルフバランスロボット:セグウェイ、Ninebot、ホビー用2輪倒立ロボットはすべて倒立振子そのものです。ジャイロと加速度センサで車体傾斜を計測し、車輪のモータトルクをフィードバックして直立を保ちます。教育用キット(LEGO Mindstorms 等)でも、LQR や PID で安定化する例が定番です。本ツールで Q・R を変えたときの応答特性は、実機チューニングのまさに体験版です。

制振装置(TMD・AMD):超高層ビルや橋梁の揺れを抑える能動制振装置(Active Mass Damper)は、巨大な質量を建物頂部で動かして地震や風揺れに反作用させます。建物の振動モードを状態空間で記述し、LQR でアクチュエータ力を決めるのが基本設計です。台北101の風揺れ制振、東京スカイツリーの心柱制振など、巨大構造物の安定化に LQR の親戚が稼働しています。

人型ロボットと外骨格:ASIMO、Atlas、Digit などの人型ロボットの歩行制御は、ZMP(Zero Moment Point)規範や LQR 系の姿勢制御を組み合わせています。リハビリ用外骨格スーツも、装着者の姿勢を倒立振子としてモデル化し、関節モータで支援トルクを LQR 的に与える設計が研究されています。

よくある誤解と注意点

最も多い誤解は、「Q や R を大きくすればするほど性能が良くなる」と考えてしまうことです。LQR は Q と R の絶対値ではなく「比 Q/R」だけが効きます。Q=1, R=1 と Q=100, R=100 はまったく同じゲイン K を生みます。重要なのは状態の各成分の重要度の「比率」(Q_p と Q_θ の比、Q_θ と R の比)であり、闇雲に Q を大きくしても得られるのは入力 u_max の暴走だけです。本ツールでも R を 0.01 まで下げると、整定時間は短くなりますが u_max が数百Nに達することを確認してください。アクチュエータ飽和を考えれば、現実的な R の選定が設計の腕の見せどころです。

次に多いのが、線形化モデルが任意の初期条件で成り立つと信じることです。本ツールの A 行列は小角度近似 $\sin\theta\approx\theta$ の元で導出されており、$|\theta|<20°$ 程度でしか正確ではありません。初期角度スライダーを $30°$ にすると「線形モデル上は安定する」と表示されますが、実機では振子の慣性で振り戻しが大きく、線形仮定が破綻して制御失敗するケースが普通です。現実の倒立振子では Swing-Up(振り上げ)と Stabilize(安定化)を別の制御則で組み合わせ、$|\theta|<15°$ になってから LQR に切り替える設計が一般的です。

最後に、本ツールは「教育目的の簡易 LQR」であり厳密な最適解ではない点に注意してください。本来 LQR ゲインは4次の代数 Riccati 方程式を解いて得られますが、ブラウザ上で Schur 分解を実装するのは過剰なため、典型的に良好な基準ゲイン K=[1, 1.5, 30, 5] を $\sqrt{Q/R}$ に比例してスケーリングする近似を採用しています。Q・R の比による応答の質的変化は正しく観察できますが、厳密な最適 K を得たい場合は MATLAB の `K = lqr(A,B,Q,R)` や Python の `scipy.linalg.solve_continuous_are` を使ってください。本ツールはあくまで「LQR とはどんなものか」を直感的に掴むための入門ツールです。