
AIエージェント Codex で 倒立振子3
ーモータモデルの同定手法を確立ー
本記事にはアフィリエイト広告が含まれます。
前回は Codex に倒立振子の制御そのものを考えてもらい、見事実機でも素晴らしい倒立制御が実現されました。
AIエージェントによるバイブコーディングで倒立振子の動作実現は無理であると考えていたため、非常に驚きました。
Codex先生に一生ついていこうと思いました。
目次
倒立制御の誤差
前回、Codex先生は最適制御則をMuJoCoシミュレーション上で探索して導出してくださいました。
結果は以下
$$ targetVelocity = 69.2\times \sin(\theta) + 10.6 \times \dot \theta + 3.9 \times wheelSpeed $$
$\theta$:機体傾斜角 [rad]、$ \dot \theta$:傾斜角速度 [rad/s]、wheelSpeed :ホイール回転速度 [rad/s]
コチラをそのまま実機に移植すると過制動やリンギング状態となったため以下のように各ゲインを調整しました。
$$ targetVelocity = 20.0\times \sin(\theta) + 8.6 \times \dot \theta + 3.0 \times wheelSpeed $$
これはモータモデル、機体定数や摩擦などにMuJoCoモデルとの誤差があるためです。
モータ同定
MuJoCoモデルと実機の誤差が小さくなれば Codex先生もより気持ちよく仕事ができると考え、ここではモータモデルの精度向上を考えます。
倒立振子に使用しているQDDモータ Robstride 05のモデルを実機動作ログをもとにパラメータ合わせこみを実施して誤差を小さくします (同定作業)。
現状のMuJoCoモデルのモータは velocity actuator で簡単にモデル化されています。
|
1 |
<velocity name="wheel_act" joint="wheel_hinge" ctrlrange="-50 50" kv = "0.01" gear="1"/> |
実機でもRobstride 05 を速度モードで制御しているので velocity actuator を選択しました。
ステップ応答
モータの速度応答をモデリングするために実機の動作ログを取得する必要があります。
Codex先生に速度ステップ応答を推奨されたので、コードを生成いただき実機で動作させてログを取得しました。
Codex先生にモータ同定用ログを取得するコードを生成いただきました。
人間の私は言われるがままに肉体作業をします。 pic.twitter.com/ErA1IhHd1E— HomeMadeGarbage (@H0meMadeGarbage) May 16, 2026
モータ回転速度指令値を 2, 5, 10, 15, -2, -5, -10, -15 rad/sとかえていって実速度を計測します。
Codex先生に同定作業工程を考えていただき、人間の私は実機書き込みなどの肉体労働をいたします。
得られたログとシミュレーションの速度ステップ応答を比較して velocity actuator のパラメータを調整してのフィッティングを先生にお願いしました。
指令速度 (cmd) の変更付近でログを比較してフィッティングします。
↓実機ログとモデルでフィッティングした部分のみ拡大表示
実機ログ (measured) とモデル (sim) で全然一致していません。。。
実は MuJoCo の velocity actuator モデルは動作に寄与するパラメータがKv しかありません。
Kv (速度応答係数) の1次係数で上のような遅れを表現するのは不可能です。
正弦波応答
単純にvelocity actuator モデルのパラメータを調整するだけでは、実機に近づけることはできないことが分かりました。
またステップ応答の速度変更部のみでのフィッティングも厳しい印象を受けました。
僭越ながらCodex先生に正弦波応答でのフィッティング実施を提案させていただきました。
振幅 10 rad/s の正弦波を入力して 周波数を 0.2 Hz から 8.0 Hz まで 60 秒でスイープします。
モータ同定用ログ取得
おこがましいのだけどCodex先生に正弦波を提案 pic.twitter.com/kaRUrtPw3e— HomeMadeGarbage (@H0meMadeGarbage) May 16, 2026
実機ログは以下の通り
中盤ではオーバーシュートが見られ、終盤は速度追従ができなくなっている様子が見られます。
これをKvのみで表現は不可能です。
MuJoCo アクチュエータモデルでのみのフィッティングはあきらめて、速度応答にマッチするフィルタをかます方法を思いつきました。
Codex先生に実機ログからフィルタを生成いただきました。
フィッティングは自己回帰外生入力モデル (ARXフィルタ) を用いて実施されました。
過去の出力 y と過去・現在の入力 u から 次の出力を推定するフィルタです。
y[n] = 1.72*y[n-1] – 0.77*y[n-2] + 0.29*u[n] – 0.53*u[n-1] + 0.29*u[n-2] – 0.00017
u[n] は時刻 n の速度指令、y[n] は推定される車輪速度
オーバーシュートまでは実現できていませんが、冒頭の応答や高速時の減衰はよく表現できております。
このフィルタy[n] をSim.上で 指令速度からvelocity actuatorの間に挿入すれば実機に近いモデルとなります。
フィルタを導入した状態で再度、制御ゲインの探索を再度実施しました。
モータ同定フィルタかまして改めて安定ゲイン探索
targetVelocity=34.4×sin(θ)+11.5×˙θ+2.5×wheelSpeed実機で安定した
targetVelocity=20.0×sin(θ)+8.6×˙θ+3.0×wheelSpeed
に近いのでこんなもんだろ pic.twitter.com/PYQ2QYkRym— HomeMadeGarbage (@H0meMadeGarbage) May 16, 2026
結果は以下
$$ targetVelocity = 34.4\times \sin(\theta) + 11.5 \times \dot \theta + 2.5 \times wheelSpeed $$
冒頭の手で調整したゲイン (20.0, 8.6, 3.0) と近い値になりました。
モータモデル同定によって実機との誤差が低減されたと言えます。
Sim2Real
実機を先ほど探索したゲイン (34.4, 11.5, 2.5) にして同定フィルタを導入したSim.モデルと動作を比較してみました。
モータ同定してゲインも揃えた
なんだよ ただの鏡じゃん pic.twitter.com/22eE3ggHnI— HomeMadeGarbage (@H0meMadeGarbage) May 16, 2026
ほぼ一致。まるで鏡です。
シミュレーション上で移動速度を指定し、その速度指令値をUDPで実機にも送信することで、MuJoCoモデルと実機を同時に動作させました。
物理Sim.モデルと実機が非常に近い状態になりました。
同定作業
今回確立した同定作業をまとめます。
- 実動作に近い条件で実機モータを駆動してログをとる
正弦波応答が最適 - 応答ログからフィッティングフィルタを生成
今回はARXモデルで近似 - フィッティングフィルタをシミュレーションモデルに導入
以上で所望の動作範囲での実用的モータモデルが得られます。
今度いろいろなモータで試してみます。
おわりに
ここではCodex先生と共にモータの同定手法の確立を検証しました。
MuJoCoのアクチュエータモデルは簡素すぎるのでフィルタを追加する手法を見つけました。
これよって実機ログからいろいろなモータの精度の高いモデル化が可能になると考えます。
モデルと実機の差がなくなれば、製作作業が大きく効率化されます。
今後は倒立振子以外でも さらに密接にCodex先生と絡み合って ものづくりをすることになりますので、
新手法など見つけたらまた紹介させてください。
ほな





