サーボの Kp・Ki・Kd はどこから来るのか ―― 自動であたり、手で仕上げる
- pid
- 制御
- モータ
- python
- シミュレーション
前回は、サーボモータを 電流 → 速度 → 位置 の三段カスケードで動かしました。そのとき、各段のゲインを「電流 Kp=6.28・Ki=6283、速度 Kp=0.6・Ki=12、位置 Kp=40」と、説明抜きにぽんと置いてしまいました。
前回の終わりでは「次はブラシレスの回る座標(dq 変換)へ」と予告していましたが、その前に一度、この置き去りにした宿題を片づけておきます。この数字はどこから来たのか。 PID には Kp・Ki・Kd という三つのつまみがあって、しかもカスケードだと三段ぶん。いったい、どうやって決めればいいのか。手作業なのか、自動で求まるのか ―― ここを、前回のモータをそのまま使い回して確かめます。
先に、私の実務での実感を書いておきます。三つもつまみがあると、正直、どこから手をつければいいのか分からなくなります。私がやっていたのは、自動である程度あたりをつけて、そこから手で微調整する という進め方でした。今回はその流れを順にたどります。
三つのつまみは、絡んでいる
PID の教科書は、Kp・Ki・Kd を独立した三つのつまみのように説明します。P は今のずれ、I は溜まったずれ、D はずれの変化 ―― それぞれ役割は分かる。でも実際に回してみると、これらは互いに絡んでいます。Kp を上げると、I や D の効き方まで変わる。 だから「まず Kp を決めて、次に Ki を…」と一つずつ順番に決めても、前の判断があとで崩れる。三次元の空間を、手探りで同時に探しているような感覚になります。
しかもカスケードだと、電流・速度・位置で三段。全部で六つも七つもゲインがある。これを白紙から手で合わせにいくのは、さすがに厳しい。だから最初のとっかかりは、機械に任せます。
まず自動で「あたり」をつける
自動チューニングのありがたみは、実は「完璧な答えをくれること」ではありません。まともな出発点に連れて行ってくれること です。いきなり広い空間をさまようのでなく、そこそこ動く場所にまず立たせてもらえる。そこからなら、手作業が「探索」でなく「仕上げ」になります。
では、自動は何をしているのか。まず、機械の慣性 J を測ります。既知のトルク(電流)でモータを短く回して、どれくらいの加速度で立ち上がるかを見る。ただし一回だけだと、摩擦や一定の負荷が邪魔をして正しく出ません。そこで 二つのトルクで測って、引き算します。
# 1A と 3A、二つのトルクで加速度を測る
# Kt·i - 摩擦 = J·a なので、二つの差をとると一定の摩擦が消える
J = Kt * (i2 - i1) / (a2 - a1)

一定の摩擦(クーロン摩擦や一定負荷)は、二つの加速度の差をとると打ち消えます(粘性摩擦の分はわずかに残りますが、ω がまだ小さい立ち上がりの窓で測るので小さい)。この testbench では 1A で約 400、3A で約 1390 rad/s² の加速度が出て、その差から慣性を 1.01×10⁻⁴ kg·m²(真値 1.00、誤差 +1.0%)と測れました。実機のオートチューニングにも、テスト運転で機械を少し動かして、こうした発想で慣性を推定するものがあります(往復運動や周波数応答など、やり方はメーカーによって色々です)。
慣性が分かれば、あとは 「どれくらいの速さで応答してほしいか」を一つ決めるだけ です。それだけで、絡み合っていたゲインが逆算で出てきます。
# 測った J と「目標の速さ ω」からゲインを逆算する
Kp_w = J * w_spd / Kt # 速度ループの P は、慣性に比例させる
Ki_w = Kp_w * w_spd / 15 # 積分は、その少し内側に
Kp_p = w_spd / 7.5 # 位置ループは、速度の数分の一の速さに
電流ループはコイルの R・L から、速度ループは測った J から、位置ループは速度の数分の一 ―― と、それぞれの段が芋づる式に決まります。電流の帯域や、段どうしの速さの比は、経験からくる定石としていったん固定してしまえば、あとで私が本当につまむのは「速度ループをどれくらい速くするか」だけ。絡み合っていた三つのつまみが、測った J と、この速さ一つに結びつく。 これが自動チューニングの本質だと思います。
面白いのは、この逆算で出たゲインです。目標の速さを「電流ループ 1000 Hz・速度ループ 48 Hz」と選ぶと ―― 電流 Kp=6.28・Ki=6283、速度 Kp=0.609・Ki=12.25、位置 Kp=40.2。前回、手でぽんと置いた 6.28 / 6283 / 0.6 / 12 / 40 と、ほとんど同じ数字が出てきます。 前回のあの数字は、じつは「この帯域で応答してほしい」と裏で決めていたのと同じことだったわけです。このゲインで回すと、前回と同じ、行き過ぎのほとんどない約 90 ミリ秒の応答になります。
そこから、手で一軸ずつ
あたりのゲインができたら、ここからが手作業です。良いあたりから始めると、つまみを一つだけ動かして、その効きをはっきり見られます。 白紙から三つ同時に探すのとは、まるで違います。
試しに、位置ループの P(Kp_p)だけを振ってみます。ほかは自動のあたりのまま、位置 P だけ動かして、2 rad の小さな位置決めをさせます。

- Kp_p=15:弱すぎて鈍い。目標になかなか届かず、整定に 268 ミリ秒かかる。
- Kp_p=40(自動のあたり):行き過ぎなく、122 ミリ秒できれいに収まる。
- Kp_p=90:ぐっと速くなって 55 ミリ秒。わずかに(3.7%)行き過ぎるが、速さが要るならここで止めるのもあり。
- Kp_p=180:上げすぎ。42% も行き過ぎて、行って戻ってと振れる。
P を上げると速くなる ―― けれど、あるところを越えると急に行き過ぎが出て、振れ始めます。しかもこの変化は、なめらかではありません。Kp_p=40 と 90 の間は素直でも、その先で急に崖になる(電流や速度の上限に当たる非線形も効いています)。だから最後は、数字の計算ではなく 波形を見て、ちょうどの手前を探す ことになります。これが「手で微調整」の中身です。一気に全部は無理でも、良いあたりの上で一軸ずつなら、こうして効きを目で確かめながら詰められます。
それでも、手作業は消えない
ここまでは、機械が「測ったときのまま」でいてくれる前提でした。実際には、そうとは限りません。ここからが、自動だけでは止まらない、手作業がかなり厳しくなる領域 です。
いちばん分かりやすいのが、慣性そのものが変わる 場合です。ロボットアームは、腕を伸ばすか畳むかで慣性が何倍も変わります。荷物を積めば重くなるし、巻き取り機はロールが太るほど重くなる。自動は一度測ってゲインを決めますが、その後で慣性が変われば、同じゲインはもう合いません。

上の図がそれです。J0 で測って合わせたゲインのまま、実際の慣性だけを変えました。測ったとおりの 1 倍ならきれいに収まりますが、慣性が 3 倍になると 3 rad 以上も行き過ぎ、5 倍では 4.4 rad 行き過ぎて振れます。
同じゲインなのに、なぜ重いほうが行き過ぎるのか。慣性が増えると、内側の速度ループは同じ電流では思うように加速・減速できず、応答が鈍ります。ところが外側の位置ループは以前と同じ速さで動かそうとするので、鈍った内側に対して要求が攻めすぎになり、止めきれずに行き過ぎる。前回の「内側ほど速く」という速さの分担が、慣性が変わったことで崩れるわけです。
もうひとつ、ここには前回の電流制限も効いています。出せるトルクは ±8A ぶんで頭打ちなので、重い相手ほど、加速にも減速にも電流が上限に張り付きっぱなしになります。実際この testbench でも、電流が上限に張り付いていた時間の割合は、1 倍で 15%、3 倍で 45%、5 倍では 74% まで増えました。同じ最大トルクしか出せない以上、重いほど止めるのに長い距離が要る ―― ブレーキが効きにくくなるわけで、これも行き過ぎを大きくしている一因です。
では、どうするか。素直な対策は、起こりうる最悪の慣性に合わせて、帯域(ゲイン)を落としておく ことです。下の図は、3 倍の重い慣性に対して帯域を 48 → 30 → 20 Hz と下げたものです。20 Hz まで落とせば行き過ぎは 0 になって安定しますが、そのぶん遅くなる ―― 整定は 90 ミリ秒級から 412 ミリ秒へ。安定と速さの、どちらかを諦める折り合い です。ここをどこで折り合わせるかは、自動は決めてくれません。もっと欲張るなら、慣性ごとにゲインを切り替える(ゲインスケジューリング)といった手もありますが、それには機械をもっと理解する手間が要ります。
そして慣性は、まだ分かりやすいほうです。現場には、もっと素直でない相手がいます。たわむ軸やベルトでつながった負荷の 共振、噛み合いの遊びである バックラッシュ、そして前回見た エンコーダのノイズ(D を上げれば帯域は稼げるが、そのぶんノイズを拾う)。どれも「ゲインをどこまで上げられるか」を狭める側に効いてきます。自動が出したあたりの上で、これらと一つずつ折り合いをつけていく ―― これが、最後まで手元に残る作業です。
おわりに
最初の問いに答えると ―― 自動で、ある程度は止まります。機械が素直で、慣性が測ったまま変わらないなら、自動のあたりだけでかなりのところまでいく。でも、最後の詰めと、機械が素直でない場面は、今も波形と手と経験の領分です。「自動であたりをつけ、手で仕上げる」。三つのつまみを前に途方に暮れていた私が、実務で落ち着いた進め方は、結局これでした。
次回は、ここまでの DC モータから一歩進んで、ブラシレス(三相交流)モータの話に入ろうと思っています。電流の向きがローターと一緒に回ってしまうのを、「回る座標に私たちも乗ってしまう」ことでほどく dq 変換 / FOC ―― やはり波形で確かめてみます。
コード一式(慣性推定、ゲインの逆算、位置 P のスイープ、慣性ミスマッチと帯域の折り合い、三枚の図の生成)は、そのまま動く形で置いてあります。python tune_servo.py で本文の数値が、python plot_tune.py で三枚の図が出ます。
- リポジトリ: logicia32/servo-lab
この記事は Zenn に初出したものを加筆・補足したものです ── Zenn の元記事を見る