今週末はカスケード制御の実装とPIDとの比較を行う。イナーシャ比10倍で減速ゼロ,および1/80のHD駆動という2パターンで評価している。結論としては,ほぼ全ての場合でカスケード制御が有利だ。前回田宮モータで実験したときにはFF付き位置ー速度カスケード制御が位置のPIDとほぼ同等の結果だった。今回電流F/Bを入れた3段のカスケードにしたところ,摩擦ありのときの立ち上がりや慣性が変動した時の速度変動がかなり小さく抑えられた。追従波形と位置の偏差いろいろな負荷,いろいろな軌道での誤差の絶対値を比べたグラフいずれの制御対象でも誤差の最大値,平均値ともにカスケードのほうが低くなっている。(立ち上がりや停止時に追従が速くなっているのはFF項が効いているため。)いくつか大事なポイントも分かってきている。ひとつは速度や電流信号等の検出信号に入れるフィルタ。ローパスフィルタをかけて信号をなまらせてしまえばノイズは収まりモータは静かになるが,一方で遅延が発生し系が発散しやすくなる。原信号のS/N比がもろに制御性能に効いてくるわけで,元の信号がノイズまみれだとカスケードの効能は半減してしまうことになる。次に目標信号の分解能。これは速度や電流フィードフォワード時に2階まで微分されるため高い分解能がいる。最初は16bitINTでホストから送っていたが,2回も微分すると分解能が1bit以下まで下がってしまい使い物にならなかった。そこで32bit固定小数に変更したらずいぶん応答が良くなった。目標信号にはゆっくりとした動きでも2回まで微分可能なだけの分解能が必要である。(0)比較実験の準備カスケード制御の方がそれらしい動きをするようになってきたので,例によって位置PIDとの比較をする準備を進めている。モータ単体では慣性が軽すぎておそらく差が出ないため,先端におもりを取り付け10倍のイナーシャ比にして実験することにした。おもりは回転対称でないため,位置によってモータトルクにかかる自重が変動する。今回はそれを外乱に見立ててテストすることにする。旧来のPID制御のほうをチューニングする。Dゲインを上げると金切り音がする。制御パラメータをダンプしてみるとD項が停止前後で細かく振動しているのが異音の原因だった。そこでとりあえず10msecの移動平均フィルタをかけてD項振動を抑えたら動作音はずいぶん静かになった。実験の様子:最初のほうでおもりが停止するときにキーキー音がしているが,途中からD項ローパスをかますと音が消えている。(ステップ応答の時のガタガタ音はモータを固定しているやぐらと机が揺れているので別問題・・・)これで制御性能のベンチマークが取れた。今日は問題がありそうなエンコーダ方形波を詳しく見る。オシロスコープの上書きスイープモードでどのぐらいエッジがぶれているか調べる。どの速度でもだいたい±34%のエッジ誤差。予想通りかなり厳しい。パルスエッジの周期誤差を速度に換算してプロットしたのが以下.高速になるほど大きな誤差になることが分かる。そこでエンコーダパルスから速度を求める3種類のアルゴリズムで検出精度を見てみる。SPM(Single-Pulse-Mesurement)法****パルス1個の周期を測定して速度を求めるCET(Constant-Elapsed-Time)法****一定時間内に計測したパルス周期,パルス数から速度を求めるDPC(Direct-Pulse-Count)法***一定時間内に計測したパルス数から速度を求める予想通りの結果となった.SPM→CET→DPCの順にパルスエッジばらつきの影響を受けにくくなる.DPC法が検出精度はベストとなるが,DPC法は検出分解能が低いのが難点だ.今回はカスケード制御のメリットを出すために,速度の更新周期を1msecとしている.そのため入ってくるパルスの数が少なくなりすぎるのである.仮に更新周期を10msecにすれば分解能も10倍となるが,モータの機械的時定数5msecを上回ってしまう.カスケードの魅力である速い外乱抑制効果を期待するには,機械的時定数の1/5とか1/10ぐらいでは制御したいものだ.となると,パルスエッジ情報が使えない以上,速度分解能を上げるためにはエンコーダ自体の出力パルス数を増やすしか解はないことになる.計算してみると256pprで60rpm刻みの7bit,最高の1024pprまで上げてもようやく9bit程度の分解能.ちょっと物足りない。何かほかに工夫がないか検討を続けたい。(0)速度検出イマイチ今日は引き続き位置-速度-電流のフィードバックを試す。振動が激しくゲインが上げられない。見ていくと,エンコーダ原信号の位相誤差が大きいことがわかってきた。このエンコーダはモータのセット品でMR(磁気抵抗式)の2相256ppr品。MR方式のエンコーダは内部でアナログ磁気信号を補完してパルスに変換しているみたいで,どうもその変換精度がイマイチのようだ。光学式のエンコーダに変える手もあるが,マクソンはお高いので,ひとまずは速度を求めるアルゴリズムを工夫して解決を試みたい。(0)割り込みではまる今日はカスケード制御ループを多重割り込みで動かす。はじめは順調だったが,突然謎のリセット発生。発生タイミングがランダムというイヤーなパタン。この手のバグはLEDデバッグが通用しないため,イマジネーションデバッグで解決するしかない。イマジネーションが追いつかず,結局トラブルシュートに数時間を要してしまった。原因はC言語が自動で処理してくれる待避レジスタにあった。dsPICでは割り込みハンドラを簡易マクロで記述できる(例えば下記のように)。_SPI1Interrupt(void){}ここで最初のおまじないに_ISRFASTと_ISRがあるのだが,何となくFASTがついていた方が速いのだろうと思って_ISRFASTばかり使っていたのが落とし穴だった。これはシャドウレジスタを使った高速PUSH&POPを指示するマクロで実は「PUSH&POPネストは1段のみ」の制約があった。(しかもC30コンパイラマニュアルには一言もそのことが書いていない・・・)よって多重割り込みでネスティングが起きると前段の待避レジスタが上書きされてしまい,リセットトラップが発生してしまうのだ。ハードウェアマニュアルのCPU動作のところで偶然この記述を見つけなければ,いつまでもコードとにらめっこした可能性もある。C言語の隠蔽されたライブラリは非常に便利だが,イマジネーションデバッグには不向きだ。(0)電流F/Bの実験開始ここのところは電流フィードバックのdsPICプログラムなどを少しずつ書いている。モータを電流制御するにはかなりの高速処理が必要なため,dsPICの性能を出し切る効率の良いコーディングが重要になってくる。組み込み野郎の血が騒ぐ。本当はアセンブラがベストだが,見通しが悪いのでまずはCでやっている。現状,電流PI制御のループをPWM周期に同期して20kHzで動作させることを目指している。dsPICにはA/D値取得タイミングをPWMのカウンタコンペアマッチのトリガで行う機能があってこれが電流F/Bではとても重宝する。(08/01)新適当マイコン電子工作研究所:知能ロボットコンテスト・フェスティバル2009を見てきました。