本系列旨在以我自己寫的pid lib為例,講一下pid的幾點基本優化,pid的基本原理網上有很多資料,因此本系列將不會涉及pid的基本實現原理,在這裡特別推薦matlab tech talk的pid教程:
由於筆者大一在讀,還沒有學習自動控制原理等課程,因此本系列將不會從自控原理角度展開,相反的,本系列將試圖從「直覺」展開,通過直觀的描述讓大家從直覺上感受並理解pid的一些包括微分先行、積分分離等基礎的優化。
由於筆者水平有限,文中難免存在一些不足和錯誤之處,誠請各位批評指正。
(一)中主要講解**結構與**使用,演算法有關內容於(二)開始講解
該pid lib全部**詳見:
該lib通過pid結構體儲存於pid運算有關的引數資料,通過列舉表示其他有關量:
//pid結構體
typedef struct _pid_typedef
static void f_pid_param_init(
pid_typedef *pid,
uint16_t max_out,
uint16_t intergral_limit,
float deadband,
float kp,
float ki,
float kd,
float changing_integral_a,
float changing_integral_b,
uint8_t improve)
pid_calculate函式與網上大多數**大體結構相同,只是新增了不同的優化函式,具體優化在各函式(如:f_pid_errorhandle、f_trapezoid_intergral)中實現,pid_calculate函式具體**如下:
float pid_calculate(pid_typedef *pid, float measure, float target)
}//誤差更新
pid->measure = measure;
pid->target = target;
pid->err = pid->target - pid->measure;
//死區內進行計算
if (abs(pid->err) > pid->deadband)
//資料儲存供下一週期呼叫
pid->last_measure = pid->measure;
pid->last_output = pid->output;
pid->last_err = pid->err;
return pid->output;
}
這裡給出以發布在github上的示例,具體不在詳細講解
//pid函式連線
pid_init(&pid_example, 9600, 5000, 3, 1, 5, 0.3, 0.3, 100, 100,
errorhandle | integral_limit | outputfilter);
//修改kp ki kd
pid_example.pid_reset(&pid_example, 3, 1, 0);
//計算
pid_calculate(&pid_example, measure, target);
pid對微分器的優化
微分器對於雜訊很敏感,我們可以從微分器的laplace傳遞函式g s s看出來 通過簡單的求導也可以看得出 假設雜訊n t 是乙個正弦函式 a 就是經過微分得到的幅度,可以看出,頻率越高,對控制訊號的影響就越大 現實中,一般情況下無法避免雜訊的存在 在pid系統中,一般通過感測器來將裝置的資訊採集出...
不用浮點實現pid 關於PID公式實現的一點困惑。
查資料發現網上關於pid的實現方式有增量式pid和位置式pid兩種。struct pidpid 增量式實現 float pidcal float speed 輸入實測速度,返回執行器pwm的數值pid struct err queenerr queen 定義乙個儲存過去誤差值的環形陣列,用於積分。因...
USB裝置的VID與PID
下面這一段是抄的 一 vid和pid pid vid唯一標識乙個裝置,hardwareid是為了給系統識別的 他是根據pid vid而生成的。這個與序列號沒什麼關係,序列號一般都是廠家固化到晶元中的資訊而已。guid只是為了標誌你安裝的裝置是屬於乙個什麼類當中,這個類可以顯示再裝置管理器中。比如 你...