簡體   English   中英

在 C++ 中為帶絕對編碼器的電機實施 PID 控制

[英]Implement a PID control in C++ for a motor with absolute encoder

對不起,如果我的問題太愚蠢,但我不知道如何解決我的問題。 我有一個帶變速箱的電機,我還有一個安裝在變速箱軸上的絕對編碼器。 我需要使 output 軸在 -90 到 +90 的范圍內旋轉,並且以 0° 為中心。 現在,當軸在0°時,編碼器輸出1010,當它在-90°時,編碼器輸出1120,當它在+90°時輸出900。 在此處輸入圖像描述

當軸處於0°,必須達到+90°時,電機必須順時針旋轉,當需要達到-90°時,電機需要逆時針旋轉。

我想通過只給它 position 度數來控制電機。 例如,我想要一個 function 像:

move_motor(1, 45°)

int move_motor(id_motor, pos){
 read current motor position
 // motor is at 0°
 make motor #1 spins clockwise until encoder returns 955
}

我認為 PID controller 將是一個聰明的解決方案,但我真的不知道如何在 C++ 中實現它,對不起,我不是開發人員。 還是您建議只使用 if/else 語句?

編輯:

為了使電機移動,我使用這個 function:

void move_motor(motor_id, direction)

它使電機根據第二個參數逆時針或順時針旋轉停止電機:

無效 stop_motor(motor_id, 0)

還有這個 function:

int get_enc(encoder1)

根據編碼器 1 的讀數返回 integer。

因此,例如,要達到所需的 position 它應該是:

while (get_enc != desired_position){
move_motor(motor_id, direction)
}

但是方向也應該處理。

以下是我的理解:

  input   output
----------------
<= -90°    1120
   -45°    1065
     0°    1010
   +45°     955
>= +90°     900

然后這個 function 會這樣做:

#include <algorithm>

unsigned angle2pid(float angle_in_degrees) {
    return std::clamp(1010 - angle_in_degrees * 55 / 45, 900.f, 1120.f);
}

std::clamp用於將 output 限制在9001120之間。

這里是 go:


unsigned angle2pid(double angle_in_degrees) 
{
    return 1010 - angle_in_degrees * 55 / 45;
}

void move_motor(int motor_id, double angle)
{
   static const int CLOSE_ENOUGH = 10;
   int currentPosition = get_enc(motor_id);
   int desiredPosition = angle2pid(angle);
   
   // IF WE ARE CLOSE ENOUGH, DO NOTHING...
   if(std::abs(currentPosition - desiredPosition) <= CLOSE_ENOUGH)
   {
       return;
   }
   
   if(desiredPosition > currentPosition)
   {
       move_motor(motor_id, CLOCKWISE);
       while(desiredPosition > currentPosition)
       {
           currentPosition = get_enc(motor_id);
       }
       stop_motor(motor_id);

   }
   else if(desiredPosition < currentPosition)
   {
       move_motor(motor_id, COUNTER_CLOCKWISE);
       while(desiredPosition < currentPosition)
       {
           currentPosition = get_enc(motor_id);
       }
       stop_motor(motor_id, 0);
   }
}

請注意,motor_id 可能是不同的類型,您需要稍微調整一下。 也許get_enc需要不同的參數,但這就是想法。

歸功於@TedLyngmo,他提供了angle2pid function。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM