加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專(zhuān)業(yè)用戶(hù)
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入

開(kāi)源一個(gè)自己做的小四旋翼工程,會(huì)有相關(guān)講解

2016/08/24
35
服務(wù)支持:
技術(shù)交流群

完成交易后在“購(gòu)買(mǎi)成功”頁(yè)面掃碼入群,即可與技術(shù)大咖們分享疑惑和經(jīng)驗(yàn)、收獲成長(zhǎng)和認(rèn)同、領(lǐng)取優(yōu)惠和紅包等。

虛擬商品不可退

當(dāng)前內(nèi)容為數(shù)字版權(quán)作品,購(gòu)買(mǎi)后不支持退換且無(wú)法轉(zhuǎn)移使用。

加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論
放大
方塊圖(2)
相關(guān)方案
  • 方案介紹
  • 相關(guān)文件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

1.

float q0q0 = q0*q0;

float q0q1 = q0*q1;

float q0q2 = q0*q2;

// float q0q3 = q0*q3;

float q1q1 = q1*q1;

// float q1q2 = q1*q2;

float q1q3 = q1*q3;

float q2q2 = q2*q2;

float q2q3 = q2*q3;

float q3q3 = q3*q3;

這段程序就是為了把需要用到的姿態(tài)矩陣的元素求出來(lái)給出的。

2.

vx = 2*(q1q3 - q0q2); /

vy = 2*(q0q1 + q2q3);

vz = q0q0 - q1q1 - q2q2 + q3q3 ;

可以看到vx,vy,vz為CRb的最后一列的三項(xiàng),四元數(shù)矩陣帶入(1)式得vx,vy,vz分別是axB,ayB,azB每一項(xiàng)g前的系數(shù)。且靜止情況下vx,vy,vz組成向量模長(zhǎng)基本可以認(rèn)為為1.

3.

norm = sqrt(ax*ax + ay*ay + az*az); //acc數(shù)據(jù)歸一化

ax = ax /norm;

ay = ay / norm;

az = az / norm;

以上已說(shuō),由四元數(shù)倒推回去的加速度,向量模長(zhǎng)為1,為了比較誤差進(jìn)行歸1化,算的由加計(jì)得出的向量。

4.

ex = (ay*vz - az*vy) ;

ey = (az*vx - ax*vz) ;

ez = (ax*vy - ay*vx) ;

接著可以通過(guò)叉乘(向量外積)計(jì)算誤差

5.

exInt = exInt + ex * Ki;

eyInt = eyInt + ey * Ki;

ezInt = ezInt + ez * Ki;

對(duì)誤差進(jìn)行積分

6.

gx = gx + Kp*ex + exInt;

gy = gy + Kp*ey + eyInt;

gz = gz + Kp*ez + ezInt;

進(jìn)行pi濾波,其實(shí)就是互補(bǔ)濾波

7.

q0 = q0 + (-q1*gx - q2*gy - q3*gz)*halfT;

q1 = q1 + (q0*gx + q2*gz - q3*gy)*halfT;

q2 = q2 + (q0*gy - q1*gz + q3*gx)*halfT;

q3 = q3 + (q0*gz + q1*gy - q2*gx)*halfT;

龍格庫(kù)塔法。。。就是方程的數(shù)值解法。。近似解。。一階解法

0736fac7228d4220f912874ee8cee5e5_21.png (0 Bytes, 下載次數(shù): 0)

下載附件

2010-12-14 22:54 上傳

這個(gè)跟四元數(shù)的微分方程對(duì)應(yīng)有興趣的看看書(shū)。。。。

8.

norm = sqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);

q0 = q0 / norm;

q1 = q1 / norm;

q2 = q2 / norm;

q3 = q3 / norm;

對(duì)四元數(shù)進(jìn)行規(guī)范化,即化為模長(zhǎng)為1 ,因?yàn)橹挥幸?guī)范化的四元數(shù)才能表示剛體旋轉(zhuǎn)。

9.

Q_ANGLE.Y = asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3; // pitch

Q_ANGLE.X = atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3; // roll

仍舊一一對(duì)應(yīng)關(guān)系發(fā)現(xiàn)2(q1q3 -q0q2)剛好跟歐拉角對(duì)應(yīng),由此利用自帶庫(kù)函數(shù)即可求得俯仰角,橫滾角類(lèi)似,偏航角由于沒(méi)有羅盤(pán)進(jìn)行校正求沒(méi)有意義,控制中采用采用PD控制。

補(bǔ)充,由于陀螺儀會(huì)有零點(diǎn)漂移開(kāi)始一定要進(jìn)行補(bǔ)償。這段是在mpu6050.c中程序,對(duì)直流偏執(zhí)進(jìn)行了補(bǔ)償。

MPU6050_ACC_LAST.X=((((int16_t)mpu6050_buffer[0]) << 8) | mpu6050_buffer[1]) - ACC_OFFSET.X;

MPU6050_ACC_LAST.Y=((((int16_t)mpu6050_buffer[2]) << 8) | mpu6050_buffer[3]) - ACC_OFFSET.Y;

MPU6050_ACC_LAST.Z=((((int16_t)mpu6050_buffer[4]) << 8) | mpu6050_buffer[5]) - ACC_OFFSET.Z;

MPU6050_GYRO_LAST.X=((((int16_t)mpu6050_buffer[8]) << 8) | mpu6050_buffer[9]) - GYRO_OFFSET.X;

MPU6050_GYRO_LAST.Y=((((int16_t)mpu6050_buffer[10]) << 8) | mpu6050_buffer[11]) - GYRO_OFFSET.Y;

MPU6050_GYRO_LAST.Z=((((int16_t)mpu6050_buffer[12]) << 8) | mpu6050_buffer[13]) - GYRO_OFFSET.Z;

這里還要說(shuō)一點(diǎn),這里加速計(jì)的數(shù)據(jù)用的是滑動(dòng)平均值濾波法,一定要有這個(gè)。。不然由于機(jī)械振動(dòng)造成的影響非常大。。。

void repare_Data(void)

{

static uint8_t filter_cnt=0;

int32_t temp1=0,temp2=0,temp3=0;

uint8_t i;

MPU6050_Read();

MPU6050_Dataanl();

ACC_X_BUF[filter_cnt] = MPU6050_ACC_LAST.X;

ACC_Y_BUF[filter_cnt] = MPU6050_ACC_LAST.Y;

ACC_Z_BUF[filter_cnt] = MPU6050_ACC_LAST.Z;

for(i=0;i<FILTER_NUM;i++)

{

temp1 += ACC_X_BUF;

temp2 += ACC_Y_BUF;

temp3 += ACC_Z_BUF;

}

選擇716電機(jī),720的轉(zhuǎn)速跟716的差不多,注意電機(jī)孔直徑一定要大一點(diǎn)。。不然塞不進(jìn)去。。然后補(bǔ)充一下MPU6050的擺放位置沒(méi)有關(guān)系。。同一坐標(biāo)系下測(cè)的的加速度角速度都是沒(méi)有關(guān)系的。。。

關(guān)于電源還有QFN的芯片。。。注意這個(gè)其實(shí)很好焊,用烙鐵沾點(diǎn)錫加點(diǎn)焊錫膏在對(duì)準(zhǔn)的引腳上拖焊就行。??梢阅脗€(gè)燈照著看反光比較容易對(duì)準(zhǔn)。

關(guān)于軟件最關(guān)建的說(shuō)說(shuō)。。只有姿態(tài)解算部分。。PID部分我的算法還得改。。。。這個(gè)網(wǎng)上有開(kāi)源的就是串機(jī)PID。。。額。。本人菜鳥(niǎo)。。還沒(méi)看懂。。大二還沒(méi)學(xué)自控。?;厝?huì)看的。。。注意這里MPU最好用硬件IIc,因?yàn)樾∷妮S的姿態(tài)更新頻率是1000HZ比較快,這里的IIC只是一個(gè)器件。。目前還沒(méi)出什么問(wèn)題。
這里有一部分是我之前寫(xiě)的總結(jié)

(1)歐拉角法靜止?fàn)顟B(tài),或者總加速度只是稍微大于g時(shí),由加計(jì)算出的值比較準(zhǔn)確。

使用歐拉角表示姿態(tài),令Φ,θ和Φ代表ZYX 歐拉角,分別稱(chēng)為偏航角、俯仰角和橫滾角 。 載體坐標(biāo)系下的 加 速 度(axB,ayB,azB)和參考坐標(biāo)系下的加速度(axN, ayN, azN)之間的關(guān)系可表示為(1)。其中 c 和 s 分別代表 cos 和 sin。axB,ayB,azB就是mpu讀出來(lái)的三個(gè)值。

這個(gè)矩陣就是三個(gè)旋轉(zhuǎn)矩陣相乘得到的,因?yàn)榫仃嚨某朔梢员硎拘D(zhuǎn)。

這是程序

void IMUupdate(float gx, float gy, float gz, float ax, float ay, float az)

{

float norm;

// float hx, hy, hz, bx, bz;

float vx, vy, vz;// wx, wy, wz;

float ex, ey, ez;

// 先把這些用得到的值算好

float q0q0 = q0*q0;

float q0q1 = q0*q1;

float q0q2 = q0*q2;

// float q0q3 = q0*q3;

float q1q1 = q1*q1;

// float q1q2 = q1*q2;

float q1q3 = q1*q3;

float q2q2 = q2*q2;

float q2q3 = q2*q3;

float q3q3 = q3*q3;

if(ax*ay*az==0)

return;

norm = sqrt(ax*ax + ay*ay + az*az); //acc數(shù)據(jù)歸一化

ax = ax /norm;

ay = ay / norm;

az = az / norm;

// estimated direction of gravity and flux (v and w)

vx = 2*(q1q3 - q0q2); //四元素中xyz的 vy = 2*(q0q1 + q2q3);

vz = q0q0 - q1q1 - q2q2 + q3q3 ;

// error is sum of cross product between reference direction of fields and direction measured by sensors

ex = (ay*vz - az*vy) ; //向量外積在相減得到差分就是誤差

ey = (az*vx - ax*vz) ;

ez = (ax*vy - ay*vx) ;

exInt = exInt + ex * Ki; //對(duì)誤差進(jìn)行積分

eyInt = eyInt + ey * Ki;

ezInt = ezInt + ez * Ki;

// adjusted gyroscope measurements

gx = gx + Kp*ex + exInt; //將誤差PI后補(bǔ)償?shù)酵勇輧x,即補(bǔ)償零點(diǎn)漂移

gy = gy + Kp*ey + eyInt;

gz = gz + Kp*ez + ezInt; //這里的gz由于沒(méi)有觀測(cè)者進(jìn)行矯正會(huì)產(chǎn)生漂移,表現(xiàn)出來(lái)的就是積分自增或自減

// integrate quaternion rate and normalise //四元素的微分方程

q0 = q0 + (-q1*gx - q2*gy - q3*gz)*halfT;

q1 = q1 + (q0*gx + q2*gz - q3*gy)*halfT;

q2 = q2 + (q0*gy - q1*gz + q3*gx)*halfT;

q3 = q3 + (q0*gz + q1*gy - q2*gx)*halfT;

// normalise quaternion

norm = sqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);

q0 = q0 / norm;

q1 = q1 / norm;

q2 = q2 / norm;

q3 = q3 / norm;

//Q_ANGLE.Yaw = atan2(2 * q1 * q2 + 2 * q0 * q3, -2 * q2*q2 - 2 * q3* q3 + 1)* 57.3; // yaw

Q_ANGLE.Y = asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3; // pitch

Q_ANGLE.X = atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3; // roll

}

1.

float q0q0 = q0*q0;

float q0q1 = q0*q1;

float q0q2 = q0*q2;

// float q0q3 = q0*q3;

float q1q1 = q1*q1;

// float q1q2 = q1*q2;

float q1q3 = q1*q3;

float q2q2 = q2*q2;

float q2q3 = q2*q3;

float q3q3 = q3*q3;

這段程序就是為了把需要用到的姿態(tài)矩陣的元素求出來(lái)給出的。

2.

vx = 2*(q1q3 - q0q2); /

vy = 2*(q0q1 + q2q3);

vz = q0q0 - q1q1 - q2q2 + q3q3 ;

可以看到vx,vy,vz為CRb的最后一列的三項(xiàng),四元數(shù)矩陣帶入(1)式得vx,vy,vz分別是axB,ayB,azB每一項(xiàng)g前的系數(shù)。且靜止情況下vx,vy,vz組成向量模長(zhǎng)基本可以認(rèn)為為1.

3.

norm = sqrt(ax*ax + ay*ay + az*az); //acc數(shù)據(jù)歸一化

ax = ax /norm;

ay = ay / norm;

az = az / norm;

以上已說(shuō),由四元數(shù)倒推回去的加速度,向量模長(zhǎng)為1,為了比較誤差進(jìn)行歸1化,算的由加計(jì)得出的向量。

4.

ex = (ay*vz - az*vy) ;

ey = (az*vx - ax*vz) ;

ez = (ax*vy - ay*vx) ;

接著可以通過(guò)叉乘(向量外積)計(jì)算誤差

5.

exInt = exInt + ex * Ki;

eyInt = eyInt + ey * Ki;

ezInt = ezInt + ez * Ki;

對(duì)誤差進(jìn)行積分

6.

gx = gx + Kp*ex + exInt;

gy = gy + Kp*ey + eyInt;

gz = gz + Kp*ez + ezInt;

進(jìn)行pi濾波,其實(shí)就是互補(bǔ)濾波

7.

q0 = q0 + (-q1*gx - q2*gy - q3*gz)*halfT;

q1 = q1 + (q0*gx + q2*gz - q3*gy)*halfT;

q2 = q2 + (q0*gy - q1*gz + q3*gx)*halfT;

q3 = q3 + (q0*gz + q1*gy - q2*gx)*halfT;

龍格庫(kù)塔法。。。就是方程的數(shù)值解法。。近似解。。一階解法

這個(gè)跟四元數(shù)的微分方程對(duì)應(yīng)有興趣的看看書(shū)。。。。

8.

norm = sqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);

q0 = q0 / norm;

q1 = q1 / norm;

q2 = q2 / norm;

q3 = q3 / norm;

對(duì)四元數(shù)進(jìn)行規(guī)范化,即化為模長(zhǎng)為1 ,因?yàn)橹挥幸?guī)范化的四元數(shù)才能表示剛體旋轉(zhuǎn)。

9.

Q_ANGLE.Y = asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3; // pitch

Q_ANGLE.X = atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3; // roll

仍舊一一對(duì)應(yīng)關(guān)系發(fā)現(xiàn)2(q1q3 -q0q2)剛好跟歐拉角對(duì)應(yīng),由此利用自帶庫(kù)函數(shù)即可求得俯仰角,橫滾角類(lèi)似,偏航角由于沒(méi)有羅盤(pán)進(jìn)行校正求沒(méi)有意義,控制中采用采用PD控制。

補(bǔ)充,由于陀螺儀會(huì)有零點(diǎn)漂移開(kāi)始一定要進(jìn)行補(bǔ)償。這段是在mpu6050.c中程序,對(duì)直流偏執(zhí)進(jìn)行了補(bǔ)償。

MPU6050_ACC_LAST.X=((((int16_t)mpu6050_buffer[0]) << 8) | mpu6050_buffer[1]) - ACC_OFFSET.X;

MPU6050_ACC_LAST.Y=((((int16_t)mpu6050_buffer[2]) << 8) | mpu6050_buffer[3]) - ACC_OFFSET.Y;

MPU6050_ACC_LAST.Z=((((int16_t)mpu6050_buffer[4]) << 8) | mpu6050_buffer[5]) - ACC_OFFSET.Z;

MPU6050_GYRO_LAST.X=((((int16_t)mpu6050_buffer[8]) << 8) | mpu6050_buffer[9]) - GYRO_OFFSET.X;

MPU6050_GYRO_LAST.Y=((((int16_t)mpu6050_buffer[10]) << 8) | mpu6050_buffer[11]) - GYRO_OFFSET.Y;

MPU6050_GYRO_LAST.Z=((((int16_t)mpu6050_buffer[12]) << 8) | mpu6050_buffer[13]) - GYRO_OFFSET.Z;

這里還要說(shuō)一點(diǎn),這里加速計(jì)的數(shù)據(jù)用的是滑動(dòng)平均值濾波法,一定要有這個(gè)。。不然由于機(jī)械振動(dòng)造成的影響非常大。。。

void repare_Data(void)

{

static uint8_t filter_cnt=0;

int32_t temp1=0,temp2=0,temp3=0;

uint8_t i;

MPU6050_Read();

MPU6050_Dataanl();

ACC_X_BUF[filter_cnt] = MPU6050_ACC_LAST.X;

ACC_Y_BUF[filter_cnt] = MPU6050_ACC_LAST.Y;

ACC_Z_BUF[filter_cnt] = MPU6050_ACC_LAST.Z;

for(i=0;i<FILTER_NUM;i++)

{

temp1 += ACC_X_BUF;

temp2 += ACC_Y_BUF;

temp3 += ACC_Z_BUF;

}




  • 四軸第三版-改.SchDoc
    描述:四軸第三版
  • 四軸飛行第三版-改.PcbDoc
    描述:四軸飛行第三版
  • 基于PI_PD控制器的四旋翼姿態(tài)控制_唐健杰.pdf
    描述:論文
  • 小四旋翼.rar
    描述:參考資料等

相關(guān)推薦

電子產(chǎn)業(yè)圖譜