シミュレーション・制御・実機
倒立振子を立たせてみる——あなた、機械、そして遅延 2026/6/24
🤖 AIが下書き・人間が編集
台車の上に、棒が一本ヒンジで立っている。台車を左右に動かして、棒を倒さないように保つ——これが倒立振子 、制御とAIの最小の実験場である(解説記事)。下の振子は、あなたのブラウザの中で本物の運動方程式に従って動いている。三つ、試してほしい。
まず、あなたが操作する。 ◀ ▶ ボタン(または ← → キー)で台車を押す。たぶん、すぐ倒れる。人間は不安定な釣り合いを保つのが苦手である。
次に、自動操縦に任せる。 「フィードバック則」は、傾きと速度から押す力を毎瞬計算する(記事のLQR )。退屈なほど簡単に立て続ける。
最後に、遅延を足す。 制御の信号をほんの数十ミリ秒遅らせるだけで——完璧だった自動操縦が、倒れる。 これがsim2realギャップ。実機の作動には必ず遅延があり、シミュには無い。
あなたが操作 自動操縦(フィードバック則)
◀ 左 右 ▶
つつく(外乱) リセット 制御の遅延:0 ms
「あなたが操作」モード。← → かボタンで台車を押し、棒を立て続けてください。
立っていた時間:0.0 秒
仕組み——数式で書くとどうなるか(クリックで展開) 式はすべて上のデモの実装そのままである。状態は4つの数 s = [ x , x ˙ , θ , θ ˙ ] \mathbf{s} = [x,\, \dot{x},\, \theta,\, \dot{\theta}] s = [ x , x ˙ , θ , θ ˙ ] (台車位置・台車速度・棒の角度・角速度。θ \theta θ は鉛直からの傾きで、0 が真上)。物理定数は台車 M = 1.0 M=1.0 M = 1.0 、棒 m = 0.1 m=0.1 m = 0.1 、棒の半長 ℓ = 0.5 \ell=0.5 ℓ = 0.5 、重力 g = 9.8 g=9.8 g = 9.8 、加える力 F F F 。
運動方程式(標準の台車‑振子)。 力 F F F と現在の状態から、台車の加速度 x ¨ \ddot{x} x ¨ と棒の角加速度 θ ¨ \ddot{\theta} θ ¨ を出す。分母の 4 / 3 4/3 4/3 は、棒を一様な剛体棒とみなしたときの慣性モーメントから来る項である。
temp = F + m ℓ θ ˙ 2 sin θ M + m \text{temp} = \frac{F + m\ell\dot{\theta}^2\sin\theta}{M + m} temp = M + m F + m ℓ θ ˙ 2 sin θ θ ¨ = g sin θ − cos θ ⋅ temp ℓ ( 4 3 − m cos 2 θ M + m ) \ddot{\theta} = \frac{g\sin\theta - \cos\theta \cdot \text{temp}}{\ell\!\left(\dfrac{4}{3} - \dfrac{m\cos^2\theta}{M+m}\right)} θ ¨ = ℓ ( 3 4 − M + m m cos 2 θ ) g sin θ − cos θ ⋅ temp x ¨ = temp − m ℓ θ ¨ cos θ M + m \ddot{x} = \text{temp} - \frac{m\ell\ddot{\theta}\cos\theta}{M+m} x ¨ = temp − M + m m ℓ θ ¨ cos θ
一歩進める(準陰的オイラー、Δ t = 0.02 \Delta t = 0.02 Δ t = 0.02 秒=50Hz)。 まず加速度で速度を更新し、その更新後の速度 で位置を進める(速度を先に使うこの順序=準陰的オイラーは、素朴なオイラーより振動系で安定する)。
x ˙ ← x ˙ + x ¨ Δ t , x ← x + x ˙ Δ t \dot{x} \leftarrow \dot{x} + \ddot{x}\,\Delta t, \qquad x \leftarrow x + \dot{x}\,\Delta t x ˙ ← x ˙ + x ¨ Δ t , x ← x + x ˙ Δ t θ ˙ ← θ ˙ + θ ¨ Δ t , θ ← θ + θ ˙ Δ t \dot{\theta} \leftarrow \dot{\theta} + \ddot{\theta}\,\Delta t, \qquad \theta \leftarrow \theta + \dot{\theta}\,\Delta t θ ˙ ← θ ˙ + θ ¨ Δ t , θ ← θ + θ ˙ Δ t
自動操縦=LQR(線形二次レギュレータ)。 4つの状態それぞれに重み K K K を掛けて足し、その符号を反転した力を加える=F = − K s F = -K\mathbf{s} F = − K s 。ゲイン K K K は、上の非線形式を真上まわりで線形化したモデルに対しリッカチ方程式をオフラインで解いて求め(解説記事 と同じ方法)、非線形シミュで検証した固定値である。力は ± 60 \pm 60 ± 60 にクランプする。
F = − ( K 0 x + K 1 x ˙ + K 2 θ + K 3 θ ˙ ) F = -(K_0 x + K_1 \dot{x} + K_2 \theta + K_3 \dot{\theta}) F = − ( K 0 x + K 1 x ˙ + K 2 θ + K 3 θ ˙ ) K = [ − 5.8159 , − 10.6212 , − 76.2852 , − 19.471 ] K = [-5.8159,\ -10.6212,\ -76.2852,\ -19.471] K = [ − 5.8159 , − 10.6212 , − 76.2852 , − 19.471 ]
遅延=この記事の主役。 制御が計算した力をすぐには効かせず、いったんキューに積んで n n n ステップ遅らせて から台車に渡す(スライダーが n n n を 0〜6 ステップ=0〜120ms で動かす)。完璧なはずの LQR でも、わずか数十 ms の作動遅延でゲインの符号合わせが間に合わなくなり、振動が増幅して発散する 。これがsim2realギャップ ——実機の作動には必ず遅延があり、シミュには無い——を一行で再現している。棒が ∣ θ ∣ > 0.9 rad |\theta|>0.9\,\text{rad} ∣ θ ∣ > 0.9 rad 傾くか台車が軌道端(∣ x ∣ > 2.4 |x|>2.4 ∣ x ∣ > 2.4 )に達したら「転倒」。
物理は標準的な台車‑振子の運動方程式、自動操縦はその線形化からRiccati方程式で解いたLQRゲイン——記事と同じ方法である。遅延を上げると、完璧な制御則でも発散する。価値は派手な表面でなく、その下の測定と、測れなかったもの(遅延)の中にある。
この記事はAIが下書きし、人間が編集・公開しています。
#作品 #制御 #シミュレーション #検証