微型四旋翼飛行器的設(shè)計與制作
硬件設(shè)計:
總體思路:
硬件模塊:
硬件選型:
模塊名稱 | 元件名稱 | 數(shù)量 | |
單片機 | STM32F103CBT6 | 1 | |
慣性測量模塊(IMU) | MPU6050(三軸加速度計+三軸陀螺儀) | 1 | |
無線通訊模塊 | NRF24L01 | 1 | |
電機驅(qū)動模塊 | AO3400 5.8A | 4 | |
續(xù)流二極管 | SS34 3A | 4 | |
電源管理模塊 | 穩(wěn)壓 | TPS79333 3.3V | 1 |
充放電 | TP4057 USB兼容5V充電 | 1 | |
直流有刷電機 | 空心杯有刷直流電機7*16mm | 4 | |
大電流放電電池 | 250mAh 20C | 1 | |
遙控器 | JOYPAD游戲手柄 | 1 |
硬件工作綜述:
硬件設(shè)計功能模塊圖:
實際效果圖與相關(guān)參數(shù):
尺寸:對角電機軸距10x10cm
重量:33.2g(帶電池)
軟件設(shè)計:
總體思路:
姿態(tài)解算:
以下給出筆者姿態(tài)融合的代碼,該代碼網(wǎng)上都有,筆者在這里做了些許注釋,方便理解。
- void
IMUupdata(float gx, float gy, float gz, float ax, float ay, float az) - {
float recipNorm; //平方根的倒數(shù) float halfvx, halfvy, halfvz; //在當前載體坐標系中,重力分量在三個軸上的分量 float halfex, halfey, halfez; //當前加速度計測得的重力加速度在三個軸上的分量與當前姿態(tài)在三個軸上的重力分量的誤差,這里采用差積的方式 float qa, qb, qc; gx = gx * PI / 180; //轉(zhuǎn)換為弧度制 gy = gy * PI / 180; gz = gz * PI / 180; //如果加速度計處于自由落體狀態(tài),可能會出現(xiàn)這種情況,不進行姿態(tài)解算,因為會產(chǎn)生分母無窮大的情況 if(!((ax == 0.0f) && (ay == 0.0f) && (az == 0.0f))) { //單位化加速度計,意義在于在變更了加速度計的量程之后不需要修改Kp參數(shù),因為這里歸一化了 recipNorm = invSqrt(ax * ax + ay * ay + az * az); ax *= recipNorm; ay *= recipNorm; az *= recipNorm; //將當前姿態(tài)的重力在三個軸上的分量分離出來 //就是方向余弦旋轉(zhuǎn)矩陣的第三列,注意是地理坐標系(n系)到載體坐標系(b系)的,不要弄反了.如果書上是b系到n系,轉(zhuǎn)置即可 //慣性測量器件測量的都是關(guān)于b系的值,為了方便,我們一般將b系轉(zhuǎn)換到n系進行導(dǎo)航參數(shù)求解。但是這里并不需要這樣做,因為這里是對陀螺儀進行補償 halfvx = g_q1 * g_q3 - g_q0 * g_q2; halfvy = g_q0 * g_q1 + g_q2 * g_q3; halfvz = g_q0 * g_q0 - 0.5f + g_q3 * g_q3; //計算由當前姿態(tài)的重力在三個軸上的分量與加速度計測得的重力在三個軸上的分量的差,這里采用三維空間的差積(向量積)方法求差 //計算公式由矩陣運算推導(dǎo)而來 公式參見http://en.wikipedia.org/wiki/Cross_product 中的Mnemonic部分 halfex = (ay * halfvz - az * halfvy); halfey = (az * halfvx - ax * halfvz); halfez = (ax * halfvy - ay * halfvx); //積分求誤差,關(guān)于當前姿態(tài)分離出的重力分量與當前加速度計測得的重力分量的差值進行積分消除誤差 if(g_twoKi > 0.0f) { g_integralFBx += g_twoKi * halfex * CNTLCYCLE; //Ki積分 g_integralFBy += g_twoKi * halfey * CNTLCYCLE; g_integralFBz += g_twoKi * halfez * CNTLCYCLE; gx += g_integralFBx; //將積分誤差反饋到陀螺儀上,修正陀螺儀的值 gy += g_integralFBy; gz += g_integralFBz; } else //不進行積分運算,只進行比例調(diào)節(jié) { g_integralFBx = 0.0f; g_integralFBy = 0.0f; g_integralFBz = 0.0f; } //直接應(yīng)用比例調(diào)節(jié),修正陀螺儀的值 gx += g_twoKp * halfex; gy += g_twoKp * halfey; gz += g_twoKp * halfez; } //以下為四元數(shù)微分方程.將陀螺儀和四元數(shù)結(jié)合起來,是姿態(tài)更新的核心算子 //計算方法由矩陣運算推導(dǎo)而來 // . 1 // q = - * q x Omega 式中左邊是四元數(shù)的倒數(shù),右邊的x是四元數(shù)乘法,Omega是陀螺儀的值(即角速度) // 2 // . // [q0] [0 -wx -wy -wz] [q0] // . // [q1] [wx 0 wz -wy] [q1] // . = * // [q2] [wy -wz 0 wx ] [q2] // . // [q3] [wz wy -wx 0 ] [q3] gx *= (0.5f * CNTLCYCLE); gy *= (0.5f * CNTLCYCLE); gz *= (0.5f * CNTLCYCLE); qa = g_q0; qb = g_q1; qc = g_q2; g_q0 += (-qb * gx - qc * gy - g_q3 * gz); g_q1 += ( qa * gx + qc * gz - g_q3 * gy); g_q2 += ( qa * gy - qb * gz + g_q3 * gx); g_q3 += ( qa * gz + qb * gy - qc * gx); //單位化四元數(shù),意義在于單位化四元數(shù)在空間旋轉(zhuǎn)時是不會拉伸的,僅有旋轉(zhuǎn)角度.這類似與線性代數(shù)里面的正交變換 recipNorm = invSqrt(g_q0 * g_q0 + g_q1 * g_q1 + g_q2 * g_q2 + g_q3 * g_q3); g_q0 *= recipNorm; g_q1 *= recipNorm; g_q2 *= recipNorm; g_q3 *= recipNorm; //四元數(shù)到歐拉角轉(zhuǎn)換,轉(zhuǎn)換順序為Z-Y-X,參見.pdf一文,P24 //注意此時的轉(zhuǎn)換順序是1-2-3,即X-Y-Z。但是由于畫圖方便,作者這里做了一個轉(zhuǎn)換,即調(diào)換Z和X,所以順序沒變 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 g_Roll = asin(-2 * g_q1 * g_q3 + 2 * g_q0* g_q2) * 180 / PI; //Roll 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 - }
評論