自從做了第一個Arduino小車興趣大增,於是開始制作第二個Arduino小車,這次我想做得相對復雜一點。一直對SEGWAY非常着迷,查了些技術資料發現自平衡小車的原理也比較簡單:利用陀螺儀和加速度模塊獲得小車角度,Arduino對獲取的數據進行處理,然后控制電機運轉糾正傾斜,從而達到平衡的效果。
先來個視頻:
需要准備的硬件有:
1、陀螺儀 我選用的是L3G4200D三軸陀螺儀,其實自平衡小車只用到其中的一軸
2、加速度計 我用的是ADXL345三軸加速度計,自平衡小車也只用到其中兩軸
3、Arduino板子 我用的是 我使用的是 arduino duemilanove 2009 arduino硬件區別請看這里:http://arduino.cc/en/Main/Hardware
4、L298N電機驅動模塊 一個 需要帶光耦
還需要一些杜邦線、 電池、螺絲等輔助的東西
有朋友問我這些東西哪里能買到,其實這些材料拜一下淘寶大神就能找到的。
組裝過程比較簡單,在塑料盒合適的位置打孔,然后用螺絲固定住電路板和電機即可:
制作之前我們需要對陀螺儀 + 加速度計 進行測試,看我們獲取的角度數據是否滿足要求。網上常用的方法是使用卡爾曼濾波將陀螺儀和加速度計的數據進行融合而得到一個相對穩定正確的角度值,具體方法在我前面的文章中提到過:L3G4200D + ADXL345 卡爾曼濾波
獲取到角度以后需要找到小車的平衡點,也就是無外力作用的時候小車能夠立在地面上的角度: 角度差 = 小車角度 - 平衡點角度。
用小車角度數據結合當前的傾斜目標值,通過PID運算,得出電機PWM脈寬數據,指揮電機運行即可。
PID算法相對比較簡單,而且arduino有現成的PID libraries : http://arduino.cc/playground/Code/PIDLibrary
double Kp, double Ki, double Kd, int ControllerDirection)
{
PID::SetOutputLimits( 0, 255); // default output limit corresponds to
// the arduino pwm limits
SampleTime = 100; // default Controller Sample Time is 0.1 seconds
PID::SetControllerDirection(ControllerDirection);
PID::SetTunings(Kp, Ki, Kd);
lastTime = millis()-SampleTime;
inAuto = false;
myOutput = Output;
myInput = Input;
mySetpoint = Setpoint;
}
PID LIB的參數分別是這樣的:
Input 輸入值(這里輸入卡爾曼融合獲取的角度值)
Output PID計算的結果,供電機驅動的PWM使用
Setpoint 期望值(這里輸入小車平衡點的角度值)
Kp、Ki、Kd 這是KPI的三個重要參數
這三個參數的詳細說明我從網上摘錄了一段:
在微分控制中,控制器的輸出與輸入誤差信號的微分(即誤差的變化率)成正比關系。自動控制系統在克服誤差的調節過程中可能會出現振盪甚至失穩。其原因是由於存在有較大慣性組件(環節)或有滯后(delay)組件,具有抑制誤差的作用,其變化總是落后於誤差的變化。解決的辦法是使抑制誤差的作用的變化“超前”,即在誤差接近零時,抑制誤差的作用就應該是零。這就是說,在控制器中僅引入 “比例”項往往是不夠的,比例項的作用僅是放大誤差的幅值,而目前需要增加的是“微分項”,它能預測誤差變化的趨勢,這樣,具有比例+微分的控制器,就能夠提前使抑制誤差的控制作用等於零,甚至為負值,從而避免了被控量的嚴重超調。所以對有較大慣性或滯后的被控對象,比例+微分(PD)控制器能改善系統在調節過程中的動態特性。
PID計算相關代碼如下:
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT); //PID對象聲明
setupPID(); // PID初始化
....
Kalman_Filter(Adxl_angle, Gyro_sensor); // 卡爾曼融合獲取angle
Input = angle;
myPID.Compute(); // PID計算獲取 Output
Drive(Output); // 根據Output驅動電機
void setupPID(){
Input = 0;
Setpoint = 17; // 我的小車自平衡角度為17
myPID.SetSampleTime( 100); // 控制器的采樣時間100ms
// myPID.SetOutputLimits(0, 2000);
myPID.SetMode(AUTOMATIC);
}
如果你做完這些小車也能成功站起來了,我的小車抖動得比較厲害,是因為我的直流電機減速太多了(減速比1:220的單軸電機),而且PID的kp,ki,kd三個參數沒調整好。等有時間換個電機再仔細調整一下參數,最好能做成可以控制前景、后退、轉彎的小車。 弄個體積大點的就能騎着上下班了,哈。