2017-12-08 12 views
0

私は実際にはfreeRTOSのロボットプロジェクトベースに取り組んでいます。私は、ロボットの車輪速度を制御するPIコントローラにいくつかの問題に直面しました。 モータPIレギュレータ構造コード

#define To 100 // 100 ms  
    #define Te 5 // 5 ms 
    #define Kp 0.01 
    #define Ti 10 //0.1*To 
    #define Ki 0.05/10 //Te/ti 

    void corrNum(int consigneVitesse) // takes speed as parameter 
    { 
     int eL,eR = 0; errors left and right 
     float cdeL = 0 ; 
     float UpL = 0 ; 
     int dutyL = 0 ; 
     float cdeR = 0 ; 
    float UpR = 0 ; 
    int dutyR = 0 ; 
    float UiL= 0 ; 
    float UiR = 0 ; 
    if(consigneVitesse) 
    { 
      tickL = quadEncoder_GetSpeedL(); 
      tickR = quadEncoder_GetSpeedR(); 
      eL = (int)(consigneVitesse - tickL); 
      eR = (int)(consigneVitesse - tickR); 
      UpL = Kp*eL ; 
      UpR = Kp*eR ; 
      UiL= UiL + Kp*Ki*eL ; 
      UiR= UiR + Kp*Ki*eR ; 
      UiL_prev = UiL ; 
      UiR_prev = UiR ; 
      cdeL = UpL + UiL ; 
      cdeR = UpR + UiR ; 
      dutyL = cdeL < 100 && cdeL > -100 ? (int)cdeL +100 : 200 ; 
      dutyR = cdeR < 100 && cdeR > -100 ? (int)cdeR +100 : 200 ; 
      motorLeft_SetDuty(dutyL); 
      motorRight_SetDuty(dutyR); 
      HAL_Delay(5); // sampling period 5 ms 
      term_printf("MOTOR LEFT ::::::> CMD : %d SPEED : %d Err : %d DUTY : %d\n\r",consigneVitesse,tickL,eL,dutyL`enter code here`); 
      term_printf("MOTOR RIGHT ::::::> CMD : %d SPEED : %d Err : %d DUTY : %d \n\r",consigneVitesse,tickR,eR,dutyR);; 
      tickL = 0 ; 
      tickR = 0; 
    } 
    else 
    { 
     motorLeft_SetDuty(100); 
     motorRight_SetDuty(100); 
    } 


}` 

prblem
エラーが安定であることがある代わりに0.0に達したときに発振を開始することです。

+0

あなたが遭遇した状況や行ったことを詳しく説明してください。 – zionpi

+0

このような潜在的な変数名... PIレギュレーターの仕組みが分かっていても、これは非常に読みにくいです。 'tickL'などはどんなタイプですか?全体的に、あなたのコードは、int型とfloat型の混合、そしてstdint.h型の代わりにint型の型を使用するという、非常にぎこちなく型付けされています。 – Lundin

+0

あなたはどこにでも不可欠な部分を保存していないようですか? PIレギュレータの呼び出しの間に保存しないと、レギュレータは決して動作しません。 eLがエラーであると仮定すると、 'UiL = UiL_prev + eL;'のようなものがあるはずです。 – Lundin

答えて

-1

あなたがこのソリューションでFreeRTOSを使用しているかは明らかではない - 何FreeRTOSは、フラグメントに呼び出して、非RTOS HAL_delay()とタイムクリティカルな制御ループ内の端末出力が助けにはなりませんがない - あなたがすることができ、出力5msで57文字しか出力できません。テキストを出力する時間はありません。

エラー信号が正しく計算されていません。時間の経過とともに位置の変化から速度を計算する必要があります。

効率的で正確なスケジューリングを実現するには、制御ループにタスクを割り当て、RTOSタイミングを使用する必要があります。ジッタのないタイミングを保証するために、タスクは他のタスクと比べて十分高い優先順位で実行する必要があります。

以下は擬似コードと見なされます。私はFreeRTOS APIに精通していないので、OSコールは現実的ではなく、タスク自体のインスタンス化には取り組んでおらず、十分な情報を提供していないスケーリングやその他の微妙な点については扱っていません。あなたはここから取るべきコントローラの構造 - ではない逐語的に実際のコード:

typedef enum 
{ 
    LEFT = 0, 
    RIGHT = 1 
} tMotorId 

volatile static struct 
{ 
    float integral ; 
    int speed ; 
    int previous_position ; 
} motor_ctrl_data[2] = {{0,0},{0,0}} ; 

void setSpeed(tMotorId id, int speed) 
{ 
    motor_ctrl_data[id] = speed ; 
} 

void motor_ctrl_task() 
{ 
    // Configure RTOS time for 5ms update period 
    OS_TIMER timer = creatTimer(5) ; 
    startTimer(timer) ; 

    // Get initial encoder counts 
    motor_ctrl_data[LEFT].previous_position = getEncoder(LEFT) ; 
    motor_ctrl_data[RIGHT].previous_position = getEncoder(RIGHT) ; 

    // PI control loop 
    for(;;) 
    { 
    // Loop update timer wait 
    waitTimer(timer) ; 

    // For each motor 
    for(int m = 0; m < 2; m++) 
    { 
     // Calculate speed 
     int speed = getEncoder[m] - motor_ctrl_data[m].previous_position ; 

     // Calculate speed error 
     int error = motor_ctrl_data[m].speed - speed[m] ; 

     // Calculate error integral 
     motor_ctrl_data[m].integral += error[m] ; 

     motorDuty(LEFT, Kp * error + Ki * motor_ctrl_data[m].integral) ; 
    } 
    } 
} 

これは振動を解決もちろんそれだけではないが、少なくとも制御与えられた適切な係数の可能​​コントローラ構成です。ループを調整するには、Ki = 0を設定し、モーターができるだけ早く動くまで、振動がなくなるまでKpを上げます。これは、ターゲットではエラーがゼロになるため、Kpだけでは動作しないため、目標速度に到達することはありません。その後、目標速度に達するまでKiを増加させ始める。小さなKiでさえ、最終的に目標速度に達するが、動的応答は遅くなる。あまりにも多く、オーバーシュートや振動が発生します。

モーターの動的応答によっては、積分制限や不感帯補償などの他の調整が必要な場合があります。あなたは微分項の恩恵を受けるかもしれませんが、単純なスピードコントローラの場合、これは一般的には不必要で、しばしば調整が困難です。

デバッグデータを出力する必要がある場合は、ループでデバッグデータを共有変数に書き込んでください(例えば上記の構造を使用している場合はmotor_ctrl_data)。そして、優先順位の低いタスクから非同期で出力できますサスティーン。

Tim Wescottの記事「PID Without a PhD」は役に立ちます。

+0

説明なしで投票された場合、この回答の問題に対処できません。それを改善したり、誤解を説明したりするのは楽しいです。コメントを残す。 – Clifford

関連する問題