国产精品久久久久影院,成人午夜福利视频,国产精品久久久久高潮,国产精品 欧美 亚洲 制服,国产精品白浆无码流出

MPU6050的四元數(shù)解算姿態(tài)方法

發(fā)布者:平靜寧靜最新更新時間:2024-07-01 來源: elecfans關(guān)鍵字:MPU6050  STM32 手機看文章 掃描二維碼
隨時隨地手機看文章

 最近在研究小四軸的飛行,姿態(tài)檢測主要用到的傳感器是MPU6050。從MPU6050讀出來的加速度和角速度數(shù)據(jù)最后要轉(zhuǎn)成姿態(tài),可以轉(zhuǎn)換成歐拉角(偏航角、俯仰角和滾轉(zhuǎn)角)或四元數(shù)表示,為了減少計算量(歐拉角涉及正弦運算,運算量相對較大),方便在STM32主控上實現(xiàn),可以轉(zhuǎn)換成四元數(shù)表示。


  使用MPU6050硬件DMP解算姿態(tài)是非常簡單的,下面介紹由三軸陀螺儀加速度計的值來使用四元數(shù)軟件解算姿態(tài)的方法。


  我們先來看看如何用歐拉角描述一次平面旋轉(zhuǎn)(坐標(biāo)變換):

  MPU6050的四元數(shù)解算姿態(tài)方法

  設(shè)坐標(biāo)系繞旋轉(zhuǎn)α角后得到坐標(biāo)系,在空間中有一個矢量在坐標(biāo)系中的投影為,在內(nèi)的投影為由于旋轉(zhuǎn)繞進行,所以Z坐標(biāo)未變,即有。

  MPU6050的四元數(shù)解算姿態(tài)方法

  轉(zhuǎn)換成矩陣形式表示為:

  MPU6050的四元數(shù)解算姿態(tài)方法

  整理一下:

  MPU6050的四元數(shù)解算姿態(tài)方法

  所以從旋轉(zhuǎn)到可以寫成

  上面僅僅是繞一根軸的旋轉(zhuǎn),如果三維空間中的歐拉角旋轉(zhuǎn)要轉(zhuǎn)三次:

  MPU6050的四元數(shù)解算姿態(tài)方法

  上面得到了一個表示旋轉(zhuǎn)的方向余弦矩陣。

  不過要想用歐拉角解算姿態(tài),其實我們套用歐拉角微分方程就行了:

  MPU6050的四元數(shù)解算姿態(tài)方法

  上式中左側(cè),,是本次更新后的歐拉角,對應(yīng)row,pit,yaw。右側(cè),是上個周期測算出來的角度,,,三個角速度由直接安裝在四軸飛行器的三軸陀螺儀在這個周期轉(zhuǎn)動的角度,單位為弧度,計算間隔時T陀螺角速度,比如0.02秒0.01弧度/秒=0.0002弧度。間因此求解這個微分方程就能解算出當(dāng)前的歐拉角。

  前面介紹了什么是歐拉角,而且歐拉角微分方程解算姿態(tài)關(guān)系簡單明了,概念直觀容易理解,那么我們?yōu)槭裁床挥脷W拉角來表示旋轉(zhuǎn)而要引入四元數(shù)呢?

  一方面是因為歐拉角微分方程中包含了大量的三角運算,這給實時解算帶來了一定的困難。而且當(dāng)俯仰角為90度時方程式會出現(xiàn)神奇的“GimbalLock”。所以歐拉角方法只適用于水平姿態(tài)變化不大的情況,而不適用于全姿態(tài)飛行器的姿態(tài)確定。

  四元數(shù)法只求解四個未知量的線性微分方程組,計算量小,易于操作,是比較實用的工程方法。

  我們知道在平面(x,y)中的旋轉(zhuǎn)可以用復(fù)數(shù)來表示,同樣的三維中的旋轉(zhuǎn)可以用單位四元數(shù)來描述。我們來定義一個四元數(shù):

  MPU6050的四元數(shù)解算姿態(tài)方法

  我們可以把它寫成,其中,。那么是矢量,表示三維空間中的旋轉(zhuǎn)軸。w是標(biāo)量,表示旋轉(zhuǎn)角度。那么就是繞軸旋轉(zhuǎn)w度,所以一個四元數(shù)可以表示一個完整的旋轉(zhuǎn)。只有單位四元數(shù)才可以表示旋轉(zhuǎn),至于為什么,因為這就是四元數(shù)表示旋轉(zhuǎn)的約束條件。

  而剛才用歐拉角描述的方向余弦矩陣用四元數(shù)描述則為:

  MPU6050的四元數(shù)解算姿態(tài)方法

  所以在軟件解算中,我們要首先把加速度計采集到的值(三維向量)轉(zhuǎn)化為單位向量,即向量除以模,傳入?yún)?shù)是陀螺儀x,y,z值和加速度計x,y,z值:

  《code》void IMUupdate(float gx, float gy, float gz, float ax, float ay, float az) { float norm; float vx, vy, vz; float ex, ey, ez; norm = sqrt(ax*ax + ay*ay + az*az); ax = ax / norm; ay = ay / norm; az = az / norm;

  下面把四元數(shù)換算成方向余弦中的第三行的三個元素。剛好vx,vy,vz 其實就是上一次的歐拉角(四元數(shù))的機體坐標(biāo)參考系換算出來的重力的單位向量。

  《code》// estimated direction of gravity vx = 2*(q1*q3 - q0*q2); vy = 2*(q0*q1 + q2*q3); vz = q0*q0 - q1*q1 - q2*q2 + q3*q3;

  axyz是機體坐標(biāo)參照系上,加速度計測出來的重力向量,也就是實際測出來的重力向量。

  axyz是測量得到的重力向量,vxyz是陀螺積分后的姿態(tài)來推算出的重力向量,它們都是機體坐標(biāo)參照系上的重力向量。

  那它們之間的誤差向量,就是陀螺積分后的姿態(tài)和加計測出來的姿態(tài)之間的誤差。

  向量間的誤差,可以用向量叉積(也叫向量外積、叉乘)來表示,exyz就是兩個重力向量的叉積。

  這個叉積向量仍舊是位于機體坐標(biāo)系上的,而陀螺積分誤差也是在機體坐標(biāo)系,而且叉積的大小與陀螺積分誤差成正比,正好拿來糾正陀螺。(你可以自己拿東西想象一下)由于陀螺是對機體直接積分,所以對陀螺的糾正量會直接體現(xiàn)在對機體坐標(biāo)系的糾正。

  《code》// integral error scaled integral gain exInt = exInt + ex*Ki; eyInt = eyInt + ey*Ki; ezInt = ezInt + ez*Ki;

  用叉積誤差來做PI修正陀螺零偏

  《code》// integral error scaled integral gain exInt = exInt + ex*Ki; eyInt = eyInt + ey*Ki; ezInt = ezInt + ez*Ki; // adjusted gyroscope measurements gx = gx + Kp*ex + exInt; gy = gy + Kp*ey + eyInt; gz = gz + Kp*ez + ezInt;

  四元數(shù)微分方程,其中T為測量周期,為陀螺儀角速度,以下都是已知量,這里使用了一階龍哥庫塔求解四元數(shù)微分方程:

  MPU6050的四元數(shù)解算姿態(tài)方法

  《code》// 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;

  最后根據(jù)四元數(shù)方向余弦陣和歐拉角的轉(zhuǎn)換關(guān)系,把四元數(shù)轉(zhuǎn)換成歐拉角:

  MPU6050的四元數(shù)解算姿態(tài)方法

  所以有:

  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

  以下是代碼實現(xiàn),attitude是上一次姿態(tài)融合的四元數(shù)(內(nèi)存地址),gyr[3]是MPU6050讀出來的角速度,acc[3]是MPU6050讀出來的加速度,interval為積分時間。

  void mix_gyrAcc_crossMethod(quaternion * attitude,const float gyr[3],const float acc[3],float interval)

  {

  const static float FACTOR = 0.001;//取接近0的數(shù)

  //

  float w_q = attitude-》w;

  float x_q = attitude-》x;

  float y_q = attitude-》y;

  float z_q = attitude-》z;

  float x_q_2 = x_q * 2;

  float y_q_2 = y_q * 2;

  float z_q_2 = z_q * 2;

  //

  // 加速度計的讀數(shù),單位化。

  float a_rsqrt = math_rsqrt(acc[0]*acc[0]+acc[1]*acc[1]+acc[2]*acc[2]);

  float x_aa = acc[0] * a_rsqrt;

  float y_aa = acc[1] * a_rsqrt;

  float z_aa = acc[2] * a_rsqrt; //加速度計測量出的加速度向量(載體坐標(biāo)系下)

  //

  // 載體坐標(biāo)下的重力加速度向量,單位化。

  float x_ac = x_q*z_q_2 - w_q*y_q_2;

  float y_ac = y_q*z_q_2 + w_q*x_q_2; //通過四元數(shù)旋轉(zhuǎn)矩陣與地理坐標(biāo)系下的重力加速度向量[0 0 0 1]叉乘得到載體坐標(biāo)系下的重力加速度向量

  float z_ac = 1 - x_q*x_q_2 - y_q*y_q_2;//(主要)角速度計測出的四元數(shù)表示的載體坐標(biāo)系下的重力加速度向量(這里已轉(zhuǎn)換成載體坐標(biāo)系下)

  //

  // 測量值與常量的叉積。

  float x_ca = y_aa * z_ac - z_aa * y_ac;

  float y_ca = z_aa * x_ac - x_aa * z_ac;

  float z_ca = x_aa * y_ac - y_aa * x_ac;//角速度計測出的角度誤差,疊加的FACTOR大小可以實驗試湊

  //

  // 構(gòu)造增量旋轉(zhuǎn)。

  float delta_x = gyr[0] * interval / 2 + x_ca * FACTOR;

  float delta_y = gyr[1] * interval / 2 + y_ca * FACTOR;

  float delta_z = gyr[2] * interval / 2 + z_ca * FACTOR;

  //

  // 融合,四元數(shù)乘法。

  attitude-》w = w_q - x_q*delta_x - y_q*delta_y - z_q*delta_z;

  attitude-》x = w_q*delta_x + x_q + y_q*delta_z - z_q*delta_y;

  attitude-》y = w_q*delta_y - x_q*delta_z + y_q + z_q*delta_x;

  attitude-》z = w_q*delta_z + x_q*delta_y - y_q*delta_x + z_q;

  quaternion_normalize(attitude);//歸一化

  }


關(guān)鍵字:MPU6050  STM32 引用地址:MPU6050的四元數(shù)解算姿態(tài)方法

上一篇:TM32F4 RT-thread移植
下一篇:基于機智云物聯(lián)網(wǎng)的智能花卉栽培系統(tǒng)

推薦閱讀最新更新時間:2025-07-16 20:40

STM32F429 >> 17. 利用MPU6050 進行姿態(tài)檢測(Code)
mpu6050.h /** ****************************************************************************** * @file mpu6050.h * @author Waao * @version V1.0.0 * @date 16-Feb-2019 * @brief This file contains some board support package's definition for the MPU6050. * ***********************************************
[單片機]
【玩轉(zhuǎn)STM32】:Default_Handler問題
記錄代碼進入Default_Handler錯誤的解決辦法 1 問題表述 在一次調(diào)試代碼的時候,發(fā)現(xiàn)代碼卡死在啟動文件 startup_stm32l431xx_.s 的355行,即 B. 處 B.是匯編代碼,B:跳轉(zhuǎn)到一個標(biāo)號,這里跳轉(zhuǎn)到一個‘.’,即表示無限死循環(huán) 通過在Debug窗口可以定位到,程序是進入Default_Handler錯誤 image 2 問題分析 使用某個外設(shè)的時候,開啟了某個中斷,但是又忘記編寫配套的中斷服務(wù)程序或者函數(shù)名寫錯,那當(dāng)中斷來臨的時,程序就會跳轉(zhuǎn)到啟動文件預(yù)先寫好的空的中斷服務(wù)程序中,并且在這個空函數(shù)中無線循環(huán),即程序就死在這里 在啟動文件里面已經(jīng)幫我們寫好所有中斷的中斷服務(wù)函數(shù),
[單片機]
STM32 MPU是什么產(chǎn)品?了解嵌入式系統(tǒng)中微處理器的新變化
微控制器 (MCU)和微處理器(MPU)有哪些不同之處?簡單來說,兩者都是嵌入式系統(tǒng)的大腦。幾年前,兩者之間有非常明顯的區(qū)別,功能截然不同,對開發(fā)者的研發(fā)技能要求也大不相同。如今,這兩個術(shù)語仍然存在,但創(chuàng)新使得兩者之間的分界線日趨模糊。以前只用 MCU 的系統(tǒng)集成商現(xiàn)在發(fā)現(xiàn),用MPU更容易,ST也注意到了這一點。微處理器已經(jīng)成為某些開發(fā)者手中的秘密武器,借助其原生的功能或運行嵌入式 Linux 的能力,他們能夠開發(fā)新的應(yīng)用或進入新的市場。因此,讓我們一起深入研究一下這個新趨勢。 故事的開頭 MCU的出現(xiàn)是替代 MPU 當(dāng)業(yè)界在上個世紀(jì)七十年代推出首個微控制器時,人們希望找到一種替代耗電量太大且設(shè)計復(fù)雜的 MPU
[單片機]
<font color='red'>STM32</font> MPU是什么產(chǎn)品?了解嵌入式系統(tǒng)中微處理器的新變化
stm32之RTC
1、stm32f10x_it.c文件 /******************************************************************************* * Function Name : RTC_IRQHandler RTC中斷 * Description : * Input : None * Output : None * Return : None *******************************************************************************/ extern volatile bool S
[單片機]
<font color='red'>stm32</font>之RTC
STM32學(xué)習(xí)之ADC
對于STM32,在使用ADC的時候需要配置幾個參數(shù)。 (1) 第一個參數(shù)是ADC_Mode,這里設(shè)置為獨立模式: ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; 在這個模式下,雙ADC不能同步,每個ADC接口獨立工作。所以如果不需要ADC同步或者只是用了一個ADC的時候,就應(yīng)該設(shè)成獨立模式了。 (2) 第二個參數(shù)是ADC_ScanConvMode,這里設(shè)置為DISABLE。 ADC_InitStructure.ADC_ScanConvMode = DISABLE; 如果只是用了一個通道的話,DISABLE就可以了,如果使用了多個通道的話,則必須將其設(shè)置
[單片機]
STM32 IAP example
1. 首先啟用 Flash模式. a)確認(rèn) stm32f7xx_hal_conf.h 中 啟用了 #define HAL_FLASH_MODULE_ENABLED b)在 Drivers/STM32F7xx_HAL_Drivers中確認(rèn)添加了源碼 stm32f7xx_hal_cortex/flash/flash_ex.c 三個文件. 2. 對flash進行分區(qū). 512K 共 8個扇區(qū). 擦除的時候只能根據(jù)刪除擦除. /* Base address of the Flash sectors Bank 1 */ #define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Bas
[單片機]
STM32中的func1和func2函數(shù),哪個效率高?
先看下面的兩個函數(shù): 函數(shù)1 int array ; int func1() { int x,int y; for(x=0;x 10240;x++) { for(y=0;y 10240;y++) { array =1234; } } } 函數(shù)2 intarray ; int func2() { int x,int y; for(x=0;x 10240;x++) { for(y=0;y 10240;y++) { array =1234; } } } 看出差異了嗎? 在STM32單片機中,上面的func1和func2函數(shù)
[單片機]
STM32大小端序與堆棧及其增長方向分析
  在開源電子中看到一篇文章講的是棧增長和大端/小端問題。學(xué)C語言的時候,我們知道堆棧的區(qū)別:   (1)棧區(qū)(stack):由編譯器自動分配和釋放,存放函數(shù)的參數(shù)值、局部變量的值等,其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。   (2)堆區(qū)(heap):一般由程序員分配和釋放,若程序員不釋放,程序結(jié)束時可能由操作系統(tǒng)回收。分配方式類似于數(shù)據(jù)結(jié)構(gòu)中的鏈表。   (3)全局區(qū)(靜態(tài)區(qū))(static):全局變量和靜態(tài)變量的存儲是放在一塊的,初始化的全局變量和靜態(tài)變量在一塊區(qū)域,未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域。程序結(jié)束后由系統(tǒng)自動釋放。   (4)文字常量區(qū):常量字符串就是存放在這里的。   (5)程序代碼區(qū):存放函數(shù)
[單片機]
<font color='red'>STM32</font>大小端序與堆棧及其增長方向分析
小廣播
設(shè)計資源 培訓(xùn) 開發(fā)板 精華推薦

最新單片機文章

 
EEWorld訂閱號

 
EEWorld服務(wù)號

 
汽車開發(fā)圈

 
機器人開發(fā)圈

電子工程世界版權(quán)所有 京ICP證060456號 京ICP備10001474號-1 電信業(yè)務(wù)審批[2006]字第258號函 京公網(wǎng)安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved