新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 微型四旋翼飛行器的設(shè)計(jì)與制作

微型四旋翼飛行器的設(shè)計(jì)與制作

作者: 時間:2016-11-28 來源:網(wǎng)絡(luò) 收藏

硬件設(shè)計(jì):

總體思路:

整個機(jī)架采用PCB板,將四個電機(jī)固定在PCB板的四個角,外接電池。

本文引用地址:http://butianyuan.cn/article/201611/322607.htm

硬件模塊:

單片機(jī)、慣性測量模塊(IMU)、無線通訊模塊、電機(jī)驅(qū)動模塊、續(xù)流二極管、電源管理模塊(穩(wěn)壓與充放電)、直流有刷電機(jī)、大電流放電電池、遙控器。

硬件選型:

模塊名稱

元件名稱

數(shù)量

單片機(jī)

STM32F103CBT6

1

慣性測量模塊(IMU)

MPU6050(三軸加速度計(jì)+三軸陀螺儀)

1

無線通訊模塊

NRF24L01

1

電機(jī)驅(qū)動模塊

AO3400 5.8A

4

續(xù)流二極管

SS34 3A

4

電源管理模塊

穩(wěn)壓

TPS79333 3.3V

1

充放電

TP4057 USB兼容5V充電

1

直流有刷電機(jī)

空心杯有刷直流電機(jī)7*16mm

4

大電流放電電池

250mAh 20C

1

遙控器

JOYPAD游戲手柄

1

硬件工作綜述:

單片機(jī)負(fù)責(zé)整個系統(tǒng)的協(xié)調(diào)工作;慣性測量模塊(IMU)負(fù)責(zé)測量四旋翼的姿態(tài);無線通訊模塊負(fù)責(zé)四旋翼與遙控器的通訊;電機(jī)驅(qū)動模塊負(fù)責(zé)驅(qū)動電機(jī);續(xù)流二極管負(fù)責(zé)對電機(jī)進(jìn)行續(xù)流;電源管理模塊中的穩(wěn)壓模塊負(fù)責(zé)整個系統(tǒng)的供電,電源管理模塊中的充放電模塊負(fù)責(zé)對電池充電;有刷電機(jī)負(fù)責(zé)提供四旋翼的飛行動力;大電流放電電池負(fù)責(zé)四旋翼的能量來源;遙控器負(fù)責(zé)對四旋翼進(jìn)行遙控和控制。

硬件設(shè)計(jì)功能模塊圖:

實(shí)際效果圖與相關(guān)參數(shù):

尺寸:對角電機(jī)軸距10x10cm

重量:33.2g(帶電池)

軟件設(shè)計(jì):

總體思路:

慣性測量模塊(IMU)測量出當(dāng)前飛機(jī)的三軸加速度與三軸角速度并傳送給單片機(jī)處理,由單片機(jī)進(jìn)行基于四元數(shù)的姿態(tài)解算,求解出當(dāng)前飛機(jī)的pitch、roll、yaw三個角度值,然后根據(jù)這三個角度經(jīng)過PID控制運(yùn)算,輸出四路PWM控制四個直流有刷電機(jī)的加減速從而達(dá)到飛機(jī)的平衡懸停。

其中,慣性測量模塊(IMU)的加速度計(jì)由于噪聲比較大,所以需要對其進(jìn)行濾波處理;而遙控器則是對飛機(jī)進(jìn)行實(shí)時的姿態(tài)控制;最后由于四旋翼制作的特殊性,在調(diào)試PID參數(shù)階段會頻繁的燒寫程序,鑒于此,筆者開發(fā)了基于NRF24L01的Bootloader技術(shù),免除了燒寫Flash的物理連線限制,可實(shí)現(xiàn)遠(yuǎn)程程序一鍵下載。

姿態(tài)解算:

姿態(tài)解算屬于四旋翼制作的核心部分,如果姿態(tài)解算能夠?qū)崟r的反應(yīng)出飛機(jī)的狀態(tài),那么對于控制來講就相對來說比較容易了。而姿態(tài)結(jié)算所要做的事情就是兩個坐標(biāo)系之間的正確轉(zhuǎn)化(地理坐標(biāo)系與載體坐標(biāo)系),這種轉(zhuǎn)化有很多種表示方法,例如歐拉角法、方向余弦矩陣法、四元數(shù)法、旋轉(zhuǎn)矢量法等。筆者采用的是應(yīng)用廣泛的四元數(shù)法,而旋轉(zhuǎn)矢量法則是一種基于四元數(shù)法的改進(jìn)四元數(shù)法。

四元數(shù)本是用于描述四維空間向量的一種方法,對于他的線性變換也就是在四維空間中的拉伸和旋轉(zhuǎn),顯而易見,我們用四元數(shù)的向量乘法來表示三維空間中的旋轉(zhuǎn)是綽綽有余的。

通過慣性測量模塊(IMU)傳送過來的當(dāng)前飛機(jī)的三軸加速度和三軸角速度的值,這樣一個三維的向量,轉(zhuǎn)化為四維向量,然后在四維空間中做線性變換(也可以說在三維空間中旋轉(zhuǎn))后輸出,利用四元數(shù)與歐拉角的關(guān)系(一定要注意旋轉(zhuǎn)順序),將當(dāng)前四元數(shù)轉(zhuǎn)換為歐拉角pitch、roll、yaw即得到當(dāng)前飛機(jī)的姿態(tài)。

以下給出筆者姿態(tài)融合的代碼,該代碼網(wǎng)上都有,筆者在這里做了些許注釋,方便理解。

[cpp]view plaincopyprint?
  1. voidIMUupdata(floatgx,floatgy,floatgz,floatax,floatay,floataz)
  2. {
  3. floatrecipNorm;//平方根的倒數(shù)
  4. floathalfvx,halfvy,halfvz;//在當(dāng)前載體坐標(biāo)系中,重力分量在三個軸上的分量
  5. floathalfex,halfey,halfez;//當(dāng)前加速度計(jì)測得的重力加速度在三個軸上的分量與當(dāng)前姿態(tài)在三個軸上的重力分量的誤差,這里采用差積的方式
  6. floatqa,qb,qc;
  7. gx=gx*PI/180;//轉(zhuǎn)換為弧度制
  8. gy=gy*PI/180;
  9. gz=gz*PI/180;
  10. //如果加速度計(jì)處于自由落體狀態(tài),可能會出現(xiàn)這種情況,不進(jìn)行姿態(tài)解算,因?yàn)闀a(chǎn)生分母無窮大的情況
  11. if(!((ax==0.0f)&&(ay==0.0f)&&(az==0.0f)))
  12. {
  13. //單位化加速度計(jì),意義在于在變更了加速度計(jì)的量程之后不需要修改Kp參數(shù),因?yàn)檫@里歸一化了
  14. recipNorm=invSqrt(ax*ax+ay*ay+az*az);
  15. ax*=recipNorm;
  16. ay*=recipNorm;
  17. az*=recipNorm;
  18. //將當(dāng)前姿態(tài)的重力在三個軸上的分量分離出來
  19. //就是方向余弦旋轉(zhuǎn)矩陣的第三列,注意是地理坐標(biāo)系(n系)到載體坐標(biāo)系(b系)的,不要弄反了.如果書上是b系到n系,轉(zhuǎn)置即可
  20. //慣性測量器件測量的都是關(guān)于b系的值,為了方便,我們一般將b系轉(zhuǎn)換到n系進(jìn)行導(dǎo)航參數(shù)求解。但是這里并不需要這樣做,因?yàn)檫@里是對陀螺儀進(jìn)行補(bǔ)償
  21. halfvx=g_q1*g_q3-g_q0*g_q2;
  22. halfvy=g_q0*g_q1+g_q2*g_q3;
  23. halfvz=g_q0*g_q0-0.5f+g_q3*g_q3;
  24. //計(jì)算由當(dāng)前姿態(tài)的重力在三個軸上的分量與加速度計(jì)測得的重力在三個軸上的分量的差,這里采用三維空間的差積(向量積)方法求差
  25. //計(jì)算公式由矩陣運(yùn)算推導(dǎo)而來公式參見http://en.wikipedia.org/wiki/Cross_product中的Mnemonic部分
  26. halfex=(ay*halfvz-az*halfvy);
  27. halfey=(az*halfvx-ax*halfvz);
  28. halfez=(ax*halfvy-ay*halfvx);
  29. //積分求誤差,關(guān)于當(dāng)前姿態(tài)分離出的重力分量與當(dāng)前加速度計(jì)測得的重力分量的差值進(jìn)行積分消除誤差
  30. if(g_twoKi>0.0f)
  31. {
  32. g_integralFBx+=g_twoKi*halfex*CNTLCYCLE;//Ki積分
  33. g_integralFBy+=g_twoKi*halfey*CNTLCYCLE;
  34. g_integralFBz+=g_twoKi*halfez*CNTLCYCLE;
  35. gx+=g_integralFBx;//將積分誤差反饋到陀螺儀上,修正陀螺儀的值
  36. gy+=g_integralFBy;
  37. gz+=g_integralFBz;
  38. }
  39. else//不進(jìn)行積分運(yùn)算,只進(jìn)行比例調(diào)節(jié)
  40. {
  41. g_integralFBx=0.0f;
  42. g_integralFBy=0.0f;
  43. g_integralFBz=0.0f;
  44. }
  45. //直接應(yīng)用比例調(diào)節(jié),修正陀螺儀的值
  46. gx+=g_twoKp*halfex;
  47. gy+=g_twoKp*halfey;
  48. gz+=g_twoKp*halfez;
  49. }
  50. //以下為四元數(shù)微分方程.將陀螺儀和四元數(shù)結(jié)合起來,是姿態(tài)更新的核心算子
  51. //計(jì)算方法由矩陣運(yùn)算推導(dǎo)而來
  52. //.1
  53. //q=-*qxOmega式中左邊是四元數(shù)的倒數(shù),右邊的x是四元數(shù)乘法,Omega是陀螺儀的值(即角速度)
  54. //2
  55. //.
  56. //[q0][0-wx-wy-wz][q0]
  57. //.
  58. //[q1][wx0wz-wy][q1]
  59. //.=*
  60. //[q2][wy-wz0wx][q2]
  61. //.
  62. //[q3][wzwy-wx0][q3]
  63. gx*=(0.5f*CNTLCYCLE);
  64. gy*=(0.5f*CNTLCYCLE);
  65. gz*=(0.5f*CNTLCYCLE);
  66. qa=g_q0;
  67. qb=g_q1;
  68. qc=g_q2;
  69. g_q0+=(-qb*gx-qc*gy-g_q3*gz);
  70. g_q1+=(qa*gx+qc*gz-g_q3*gy);
  71. g_q2+=(qa*gy-qb*gz+g_q3*gx);
  72. g_q3+=(qa*gz+qb*gy-qc*gx);
  73. //單位化四元數(shù),意義在于單位化四元數(shù)在空間旋轉(zhuǎn)時是不會拉伸的,僅有旋轉(zhuǎn)角度.這類似與線性代數(shù)里面的正交變換
  74. recipNorm=invSqrt(g_q0*g_q0+g_q1*g_q1+g_q2*g_q2+g_q3*g_q3);
  75. g_q0*=recipNorm;
  76. g_q1*=recipNorm;
  77. g_q2*=recipNorm;
  78. g_q3*=recipNorm;
  79. //四元數(shù)到歐拉角轉(zhuǎn)換,轉(zhuǎn)換順序?yàn)閆-Y-X,參見.pdf一文,P24
  80. //注意此時的轉(zhuǎn)換順序是1-2-3,即X-Y-Z。但是由于畫圖方便,作者這里做了一個轉(zhuǎn)換,即調(diào)換Z和X,所以順序沒變
  81. g_Yaw=atan2(2*g_q1*g_q2+2*g_q0*g_q3,g_q1*g_q1+g_q0*g_q0-g_q3*g_q3-g_q2*g_q2)*180/PI;//Yaw
  82. g_Roll=asin(-2*g_q1*g_q3+2*g_q0*g_q2)*180/PI;//Roll
  83. g_Pitch=atan2(2*g_q2*g_q3+2*g_q0*g_q1,-2*g_q1*g_q1-2*g_q2*g_q2+1)*180/PI;//Pitch
  84. }

注意其中的快速開方函數(shù)來自維基百科,精度0.175%。并且注意輸入的陀螺儀必須是弧度制(這一點(diǎn)在進(jìn)入函數(shù)的時候已經(jīng)做了轉(zhuǎn)換),否則姿態(tài)解算是錯誤的。

針對上述代碼我還想說明一個筆者發(fā)現(xiàn)的問題:有很多網(wǎng)友和許多外國的四軸代碼(CrazyFlie)在這個姿態(tài)解算的加速度計(jì)部分都做了零點(diǎn)校準(zhǔn)處理。意思就是在開機(jī)的時候讀取一定次數(shù)的加速度計(jì)的值,然后平均一下,得到一個初始狀態(tài)的偏移量,最后在輸出的時候加速度計(jì)減掉這個值,然后再給到姿態(tài)解算代碼部分。而筆者在剛開始移植代碼的時候是沒有做這個零點(diǎn)校準(zhǔn)處理的(當(dāng)然,陀螺儀必須要做零點(diǎn)處理,因?yàn)橥勇輧x的原理,必須要在靜止時輸出為0),包括現(xiàn)在依舊沒有對加速度計(jì)做零點(diǎn)校準(zhǔn)處理,仍然可以獲得較為實(shí)時的姿態(tài)。


上一頁 1 2 下一頁

評論


技術(shù)專區(qū)

關(guān)閉