モーターフェーダーPID制御


15

Arduinoを使用して電動フェーダー(リニアスライドポテンショメーター)を制御しようとしています。
PID制御は、特定のターゲット位置への「ジャンプ」に対して良い結果をもたらしますが、ランプの追跡は問題であり、まったくスムーズではありません。何をしようとしても、動きはとてもぎくしゃくしています。

ランプを追跡するときの基準位置、測定位置、モーター出力のプロットは次のとおりです。 ランプの追跡

そして、同じテストのビデオがあります。

商用システムでは、はるかにスムーズに見えますこれを参照してください。

詳細
モーターフェーダーは、アルプスRSA0N11M9A0Kです。それを駆動するために、安定化された10 V DC電源(XL6009)から電力を供給されるST L293D Hブリッジを使用しています。 Arduino UNO(ATmega328P)では、ピン9と10を使用して、PWM周波数31.372 kHzで聞こえないようにします(プリスケーラが1のTimer1 )。 ポテンショメータはグランドと5Vの間に配線され、ワイパーは通常どおりADC0に接続されます。
TCCR1B = (TCCR1B & 0b11111000) | 0b001

コントローラー
アンチワインドアップ機能を備えたシンプルなPIDコントローラーを使用しています。これは、1 kHzのレート(Ts = 1e-3 s)で更新します。

float update(int16_t input) {
  int16_t error = setpoint - input;
  int16_t newIntegral = integral + error;
  float output = k_p * error 
               + k_i * newIntegral * Ts 
               + k_d * (input - previousInput) / Ts;

  if (output > maxOutput)
    output = maxOutput;
  else if (output < -maxOutput)
    output = -maxOutput;
  else
    integral = newIntegral;

  previousInput = input;
  return output;
}

コントローラーの出力は-127〜127の値です。PWM出力は次のように生成されます。

const int8_t knee = 48;

uint8_t activation(int8_t val) {
  if (val == 0)
    return 0;
  else {
    return map(val, 0, 127, 2 * knee, 255);
  }
}

void writeMotor(int8_t val) {
  if (val >= 0) {
    analogWrite(forward, activation(val));
    digitalWrite(backward, 0);
  } else {
    analogWrite(backward, activation(-val));
    digitalWrite(forward, 0);
  }
}

モーターが31 kHzで動き始めるので、7ビットPWM信号に48を追加し、それを8ビット数にスケールアップします(analogWrite関数が期待するものだからです): PWM速度

試したこと
入力、制御信号、PIDコントローラーの派生コンポーネントにEMAフィルターを追加しようとしましたが、役に立ちませんでした。また、ヒステリシスを使用して、静止時に2つの値の間で反転しないようにアナログ入力の解像度を下げてみました。これは何にも影響しないようです。タイムステップを10ミリ秒に増やしても効果はありません。

また、MATLABでシステム識別を試み、Simulinkでそれを調整しようとしました(このビデオシリーズに従って)。91%の適合のモデルを得ま​​したが、MATLABモデルの入力および出力の非線形性を処理する方法、それらがPIDチューニングにどのように影響するか、Arduinoに実装する方法がわかりませんでした。

私が最後に試したのは、2つの異なるコントローラーを作成することです。1つは基準位置での大きなジャンプ用で、もう1つはランプの追跡時の小さなエラー用です。これは少し助けになるようです。なぜなら、ジャンプするときにオーバーシュートを増やすことなく、追跡するときに積分係数を増やすことができるからです。
ただし、積分(および比例)ゲインを増加させることで、モーターは静止している必要があり、基準が変化しない場合でも、常に何かを実行しています。(実際には移動しませんが、振動を感じることができます。)
1e-4よりも高くすると、さらにジャーキーになるように見えるため、実質的に微分ゲインはありません。 1e-4。

私の推測では、静止摩擦を克服するにはより多くの力が必要であり、動的摩擦は小さいためオーバーシュートするため、モーターを後方に駆動して再び停止し、再び静止摩擦を克服しなければならず、再び前方に撃ちますなど

商用コントローラーはこの問題をどのように克服しますか?

私の経歴
電気工学の3年生で、制御理論、デジタル信号処理、LQR制御などのコースを受講しているため、理論的な背景はありますが、これらすべての理論を適用するのに苦労していますこの現実のシステム。


編集
laptop2dが推奨するように、開ループセンサー測定をテストしましたが、その結果に非常に驚いています:高PWM周波数では、読み取り値に不快なピークがあります。490 Hzでは、何もありません。
これは一定のデューティサイクルであるため、モーターが非常に高速で方向を反転しているときにどのようなノイズが発生するか想像できません。

ここに画像の説明を入力してください

そのため、コントローラーでの作業を再開する前に、そのノイズを除去する方法を見つける必要があります。

編集2
指数移動平均フィルターを使用しても、ノイズを除去するのに十分ではありませんでした。

EMA

0.25、0.50、0.75でポールを試しました。小さなポールはあまり効果がなく、大きなポールはレイテンシーを追加しすぎたため、ゲインを下げて安定性を維持する必要があり、全体的なパフォーマンスが低下しました。

ポテンショメータ(ワイパーとグランドの間)に0.1 µFのコンデンサを追加しましたが、これできれいになったようです。

今のところ、それは十分に機能します。それまでは、ティムウェスコットが投稿し論文を読んでいます。
ご協力ありがとうございます。


31KHz pwmを正確に制御できますか?
ハサンalattar

@Hasanalattar:いいえ、使用できる周波数は2番目のグラフにあります(1、8、64、256、1024のプリスケーラー)。4 kHzと500 Hzは可聴であるため、不快なビープ音が鳴りますが、これは避けたいと思います。これにより、31 kHz、120 Hz、および30 Hzが残ります。そして、後者の2つは遅すぎると思います。PWM分解能は8ビットですが、制御信号は7ビットのみであり、96を超えるPWM値のみを使用しているため、使用量は少なくなっています
。– tttapa

1
リンクしたHブリッジは、データシートのフロントページにあります。This device is suitable for use in switching applications at frequencies up to 5 kHz. しかし、3ページの電気的特性は、すべての遅延を加算した場合、690kHzの絶対最大値を示しています。(下の4行は)個人的に、私は遅くそれよりも多くのことをいいと思うが、私は31kHzが適切でなければならないこと...それは1ページのノートがなかった場合に思うだろう
AaronD

ただし、それは固定デューティサイクルを前提としています。(または「それを小刻み」に絶対最大周波数のデューティ・サイクル「を気にしない」 -あなたはそれが非対称だわかります)高および低デューティサイクルは、いくつかの非常に狭いパルスを生成することができますので、どのように広いものに比べて3ページの一番下?
AaronD

1
それがあなたの問題であるかどうかはわかりませんが、タイムスタンプが変化する可能性がある場合は、エラーだけでなく、エラーにエラー* Tを追加し、積分にTを乗算しないでください。(Tsが常に定数である場合、それは重要ではありません)
-user253751

回答:


9

制御システムは、センサーと同じくらい優れているだけで、センサーの開ループを実行し、制御入力を削除します。センサーへの独自の入力を作成し、位置データを取得してセンサーではないことを確認しながら、ゆっくりスライドさせます(またはゆっくりと確実にスライドさせる方法を見つけます)。センサーにノイズが多い場合は、新しいセンサーを取得するか並列化するか、センサーの出力をフィルタリングすることにより、センサーのパフォーマンスを向上させます。より高い解像度のセンサーが必要になる場合があります。

センサーにノイズがない場合は、別の制御ループを取得する必要があります。PIDは一次システムであり、レート制御にはあまり適していません。


ありがとう、PWM周波数が高いと確かに多くのノイズが発生するため、それを改善する方法を見つける必要があります。あなたはそれを行う方法について何かポインタを持っていますか?
tttapa

機械式またはデジタルのフィルターを使用してください。それができない場合、センサーを並列接続するのが良いでしょう。meta.stackexchange.com/questions/126180/...
電圧スパイク

6

問題は摩擦によるもの、または摩擦とバックラッシュの組み合わせによるものであることは間違いありません。さまざまなパルス幅の平均速度とデューティサイクルのプロットは、摩擦があるシステムの特性です。 このホワイトペーパーでは、表示されている内容について説明し、問題を処理するために永遠に使用されてきたソリューションの概要を示します。分析が難しいため、エンジニアリングカリキュラムでそれらを見たことはありません。基本的に、それらを機能させるには、ケースバイケースでそれらをいじる必要があります。

市販のコントローラーが何をするのかわかりませんが、さまざまなソリューションがあると思います。過去にこのようなことで行ったことは、PIDコントローラーからのモーター駆動信号がしきい値(おそらく60〜70カウント)を下回ったときです。平均駆動をPID出力と等しくするサイクル。私は通常、非常に少数の行で実装できるため、これにシグマ-デルタ-様変調器を使用しますが、あなたはあなたのために何でもうまくいくことができます。


4

ほとんどのノイズはPWM駆動信号から発生しているようです。

ADCキャプチャをPWMサイクルに同期しようとしましたか?ほとんどのマイクロコントローラーには、タイマーでADCキャプチャーをトリガーする方法があるため、サイクルの同じポイントでいつでもトリガーできます。

ノイズを最小限に抑えるには、モーターの電源をオンにする直前に最適なサンプリング位置を設定します。これは、スパイクが最も安定するまでの時間が長いためです。しかし、位置が何であっても、PWMサイクルの同じポイントでオフセットの量がほぼ同じになるため、キャプチャを同期するとスパイクが減少します。


3

そのため、コントローラーでの作業を再開する前に、そのノイズを除去する方法を見つける必要があります。

次のようなコードでセンサーノイズ(またはその他のノイズの多い測定/変数)をフィルター処理できます(ローパスフィルター処理)。

Sフィルター済み[k]=αSフィルター済み[k1]+1αS[k]

0<<α1


私はそれを試しましたが、ピークを取り除くのに十分ではなく、それはあまりにも多くの遅れを追加します。
tttapa

@tttapaなるほど。アルファのどの値を試しましたか?(0.8,0.9)多少のチューニングが必要になりますが、これはすでに行っているかもしれませんが、ただ疑問に思っているだけです。
Big6

元の投稿を更新して、試したEMAフィルターのプロットを追加しました。私も0.9を試しましたが、0.75よりもさらに悪かったので、遅延のためにゲインをもっと低くする必要があります。限られたEMAを使用してADCノイズをクリーンアップすると思いますが、今のところはコンデンサで十分です。
tttapa
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.