無人機——磁力計/電子羅盤 學習及校準

  注:本文轉載自

http://blog.sina.com.cn/s/blog_402c071e0102v8ie.html  、

http://www.dzsc.com/data/html/2010-11-29/87454.html




  電子羅盤是一種重要的導航工具,能實時提供移動物體的航向和姿態。隨着半導體工藝的進步和手機操作系統的發展,集成了越來越多傳感器的智能手機變得功能強大,很多手機上都實現了電子羅盤的功能。而基於電子羅盤的應用(如Android的Skymap)在各個軟件平臺上也流行起來。

  要實現電子羅盤功能,需要一個檢測磁場的三軸磁力傳感器和一個三軸加速度傳感器。隨着微機械工藝的成熟,意法半導體推出將三軸磁力計和三軸加速計集成在一個封裝裏的二合一傳感器模塊LSM303DLH,方便用戶在短時間內設計出成本低、性能高的電子羅盤。本文以LSM303DLH爲例討論該器件的工作原理、技術參數和電子羅盤的實現方法。

  1.    地磁場和航向角的背景知識

  如圖1所示,地球的磁場象一個條形磁體一樣由磁南極指向磁北極。在磁極點處磁場和當地的水平面垂直,在赤道磁場和當地的水平面平行,所以在北半球磁場方向傾斜指向地面。用來衡量磁感應強度大小的單位是Tesla或者Gauss(1Tesla=10000Gauss)。隨着地理位置的不同,通常地磁場的強度是0.4-0.6 Gauss。需要注意的是,磁北極和地理上的北極並不重合,通常他們之間有11度左右的夾角。


圖1 地磁場分佈圖

  地磁場是一個矢量,對於一個固定的地點來說,這個矢量可以被分解爲兩個與當地水平面平行的分量和一個與當地水平面垂直的分量。如果保持電子羅盤和當地的水平面平行,那麼羅盤中磁力計的三個軸就和這三個分量對應起來,如圖2所示。


圖2 地磁場矢量分解示意圖

  實際上對水平方向的兩個分量來說,他們的矢量和總是指向磁北的。羅盤中的航向角(Azimuth)就是當前方向和磁北的夾角。由於羅盤保持水平,只需要用磁力計水平方向兩軸(通常爲X軸和Y軸)的檢測數據就可以用式1計算出航向角。當羅盤水平旋轉的時候,航向角在0?- 360?之間變化。

  2.ST集成磁力計和加速計的傳感器模塊LSM303DLH

  2.1  磁力計工作原理

  在LSM303DLH中磁力計採用各向異性磁致電阻(Anisotropic Magneto-Resistance)材料來檢測空間中磁感應強度的大小。這種具有晶體結構的合金材料對外界的磁場很敏感,磁場的強弱變化會導致AMR自身電阻值發生變化。

  在製造過程中,將一個強磁場加在AMR上使其在某一方向上磁化,建立起一個主磁域,與主磁域垂直的軸被稱爲該AMR的敏感軸,如圖3所示。爲了使測量結果以線性的方式變化,AMR材料上的金屬導線呈45º角傾斜排列,電流從這些導線上流過,如圖4所示。由初始的強磁場在AMR材料上建立起來的主磁域和電流的方向有45º的夾角。


圖3 AMR材料示意圖


圖4 45º角排列的導線

  當有外界磁場Ha時,AMR上主磁域方向就會發生變化而不再是初始的方向了,那麼磁場方向和電流的夾角θ也會發生變化,如圖5所示。對於AMR材料來說,θ角的變化會引起AMR自身阻值的變化,並且呈線性關係,如圖6所示。


圖5 磁場方向和電流方向的夾角


圖6 θ-R特性曲線

  ST利用惠斯通電橋檢測AMR阻值的變化,如圖7所示。R1/R2/R3/R4是初始狀態相同的AMR電阻,但是R1/R2和R3/R4具有相反的磁化特性。當檢測到外界磁場的時候,R1/R2阻值增加∆R而R3/R4減少∆R。這樣在沒有外界磁場的情況下,電橋的輸出爲零;而在有外界磁場時電橋的輸出爲一個微小的電壓∆V。


圖7 惠斯通電橋

  當R1=R2=R3=R4=R,在外界磁場的作用下電阻變化爲∆R時,電橋輸出?V正比於?R。這就是磁力計的工作原理。

  2.2  置位/復位(Set/Reset)電路

  由於受到外界環境的影響,LSM303DLH中AMR上的主磁域方向不會永久保持不變。LSM303DLH內置有置位/復位電路,通過內部的金屬線圈週期性的產生電流脈衝,恢復初始的主磁域,如圖8所示。需要注意的是,置位脈衝和復位脈衝產生的效果是一樣的,只是方向不同而已。


圖8 LSM303DLH置位/復位電路

  置位/復位電路給LSM303DLH帶來很多優點:

  1)    即使遇到外界強磁場的干擾,在干擾消失後LSM303DLH也能恢復正常工作而不需要用戶再次進行校正。

  2)    即使長時間工作也能保持初始磁化方向實現精確測量,不會因爲芯片溫度變化或內部噪音增大而影響測量精度。

  3)    消除由於溫漂引起的電橋偏差。

  2.3  LSM303DLH的性能參數

  LSM303DLH集成三軸磁力計和三軸加速計,採用數字接口。磁力計的測量範圍從1.3 Gauss到8.1 Gauss共分7檔,用戶可以自由選擇。並且在20 Gauss以內的磁場環境下都能夠保持一致的測量效果和相同的敏感度。它的分辨率可以達到8 mGauss並且內部採用12位ADC,以保證對磁場強度的精確測量。和採用霍爾效應原理的磁力計相比,LSM303DLH的功耗低,精度高,線性度好,並且不需要溫度補償。

  LSM303DLH具有自動檢測功能。當控制寄存器A被置位時,芯片內部的自測電路會產生一個約爲地磁場大小的激勵信號並輸出。用戶可以通過輸出數據來判斷芯片是否正常工作。

  作爲高集成度的傳感器模組,除了磁力計以外LSM303DLH還集成一顆高性能的加速計。加速計同樣採用12位ADC,可以達到1mg的測量精度。加速計可運行於低功耗模式,並有睡眠/喚醒功能,可大大降低功耗。同時,加速計還集成了6軸方向檢測,兩路可編程中斷接口。

  3.   ST電子羅盤方案介紹

  一個傳統的電子羅盤系統至少需要一個三軸的磁力計以測量磁場數據,一個三軸加速計以測量羅盤傾角,通過信號條理和數據採集部分將三維空間中的重力分佈和磁場數據傳送給處理器。處理器通過磁場數據計算出方位角,通過重力數據進行傾斜補償。這樣處理後輸出的方位角不受電子羅盤空間姿態的影響,如圖9所示。


圖9 電子羅盤結構示意圖

  LSM303DLH將上述的加速計、磁力計、A/D轉化器及信號條理電路集成在一起,仍然通過I2C總線和處理器通信。這樣只用一顆芯片就實現了6軸的數據檢測和輸出,降低了客戶的設計難度,減小了PCB板的佔用面積,降低了器件成本。

  LSM303DLH的典型應用如圖10所示。它需要的周邊器件很少,連接也很簡單,磁力計和加速計各自有一條I2C總線和處理器通信。如果客戶的I/O接口電平爲1.8V,Vdd_dig_M、Vdd_IO_A和Vdd_I2C_Bus均可接1.8V供電,Vdd使用2.5V以上供電即可;如果客戶接口電平爲2.6V,除了Vdd_dig_M要求1.8V以外,其他皆可以用2.6V。在上文中提到,LSM303DLH需要置位/復位電路以維持AMR的主磁域。C1和C2爲置位/復位電路的外部匹配電容,由於對置位脈衝和復位脈衝有一定的要求,建議用戶不要隨意修改C1和C2的大小。


圖10 LSM303DLH典型應用電路圖

  對於便攜式設備而言,器件的功耗非常重要,直接影響其待機的時間。LSM303DLH可以分別對磁力計和加速計的供電模式進行控制,使其進入睡眠或低功耗模式。並且用戶可自行調整磁力計和加速計的數據更新頻率,以調整功耗水平。在磁力計數據更新頻率爲7.5Hz、加速計數據更新頻率爲50Hz時,消耗電流典型值爲0.83mA。在待機模式時,消耗電流小於3uA。

  4.   鐵磁場干擾及校準

  電子指南針主要是通過感知地球磁場的存在來計算磁北極的方向。然而由於地球磁場在一般情況下只有微弱的0.5高斯,而一個普通的手機喇叭當相距2釐米時仍會有大約4高斯的磁場,一個手機馬達在相距2釐米時會有大約6高斯的磁場,這一特點使得針對電子設備表面地球磁場的測量很容易受到電子設備本身的干擾。

  磁場干擾是指由於具有磁性物質或者可以影響局部磁場強度的物質存在,使得磁傳感器所放置位置上的地球磁場發生了偏差。如圖11所示,在磁傳感器的XYZ 座標系中,綠色的圓表示地球磁場矢量繞z軸圓周轉動過程中在XY平面內的投影軌跡,再沒有外界任何磁場干擾的情況下,此軌跡將會是一個標準的以O(0,0)爲中心的圓。當存在外界磁場干擾的情況時,測量得到的磁場強度矢量α將爲該點地球磁場β與干擾磁場γ的矢量和。記作:



圖11 磁傳感器XY座標以及磁力線投影軌跡

  一般可以認爲,干擾磁場γ在該點可以視爲一個恆定的矢量。有很多因素可以造成磁場的干擾,如擺放在電路板上的馬達和喇叭,還有含有鐵鎳鈷等金屬的材料如屏蔽罩,螺絲,電阻, LCD背板以及外殼等等。同樣根據安培定律有電流通過的導線也會產生磁場,如圖12。


圖12 電流對磁場產生的影響

  爲了校準這些來自電路板的磁場干擾,主要的工作就是通過計算將γ求出。

  4.1  平面校準方法

  針對XY軸的校準,將配備有磁傳感器的設備在XY平面內自轉,如圖11,等價於將地球磁場矢量繞着過點O(γx,γy)垂直於XY平面的法線旋轉, 而紅色的圓爲磁場矢量在旋轉過程中在XY平面內投影的軌跡。這可以找到圓心的位置爲((Xmax + Xmin)/2,  (Ymax + Ymin)/2).  同樣將設備在XZ平面內旋轉可以得到地球磁場在XZ平面上的軌跡圓,這可以求出三維空間中的磁場干擾矢量γ(γx, γy, γz).

  4.2  立體8字校準方法

  一般情況下,當帶有傳感器的設備在空中各個方向旋轉時,測量值組成的空間幾何結構實際上是一個圓球,所有的採樣點都落在這個球的表面上,如圖13所示,這一點同兩維平面內投影得到的圓類似。


圖13 地球磁場空間旋轉後在傳感器空間座標內得到球體

  這種情況下,可以通過足夠的樣本點求出圓心O(γx, γy, γz), 即固定磁場干擾矢量的大小及方向。公式如下:


  8字校準法要求用戶使用需要校準的設備在空中做8字晃動,原則上儘量多的讓設備法線方向指向空間的所有8個象限,如圖14所示。


圖14 設備的空中8字校準示意圖

  4.2  十面校準方法

  同樣,通過以下10面校準方法,也可以達到校準的目的。


圖15 10面交準法步驟

  如圖16所示,經過10面校準方法之後,同樣可以採樣到以上所述球體表面的部分軌跡,從而推導出球心的位置,即固定磁場干擾矢量的大小及方向。


圖16 10面校準後的空間軌跡

  5.傾斜補償及航偏角計算

  經過校準後電子指南針在水平面上已經可以正常使用了。但是更多的時候手機並不是保持水平的,通常它和水平面都有一個夾角。這個夾角會影響航向角的精度,需要通過加速度傳感器進行傾斜補償。

  對於一個物體在空中的姿態,導航系統裏早已有定義,如圖17所示,Android中也採用了這個定義。Pitch(Φ)定義爲x軸和水平面的夾角,圖示方向爲正方向;Roll(θ)定義爲y軸和水平面的夾角,圖示方向爲正方向。由Pitch角引起的航向角的誤差如圖18所示。可以看出,在x軸方向10度的傾斜角就可以引起航向角最大7-8度的誤差。



圖17 Pitch角和Roll角定義                圖18 Pitch角引起的航向角誤差

  手機在空中的傾斜姿態如圖19所示,通過3軸加速度傳感器檢測出三個軸上重力加速度的分量,再通過式2可以計算出Pitch和Roll。


圖19 手機在空中的傾斜姿態


  式3可以將磁力計測得的三軸數據(XM,YM ,ZM)通過Pitch和Roll轉化爲式1中計算航向角需要的Hy和Hx。之後再利用式1計算出航向角。


  6.Android平臺指南針的實現

  在當前流行的android 手機中,很多都配備有指南針的功能。爲了實現這一功能,只需要配備有ST提供的二合一傳感模塊LSM303DLH,ST 提供整套解決方案。Android中的軟件實現可以由以下框圖表示:



  其中包括:

  BSP Reference

  Linux Kernel Driver (LSM303DLH_ACC + LSM303DLH_MAG)

   HAL Library(Sensors_lsm303dlh + Liblsm303DLH) for sensors.default.so

  經過library 的計算,上層的應用可以很輕鬆的運用由Android定義由Library提供的航偏角信息進行應用程序的編寫。




  如果磁力計在含有附加的局部磁場的環境中進行操作磁力計的輸出做附加的修正將是必要的。 在沒有任何本地磁場的影響下,下圖1可以通過旋轉設備360°產生的平面 ,圖2爲引入本地磁場。

磁力計校準 磁力計校準


        方法一.修正的輸出可以根據下面的方法來計算:
        1)在磁場干擾的條件下進行,數據收集設備被旋轉360°。
        2)數據進行分析,以產生偏差的偏移和靈敏度的比例因子,以補償所述干擾。

        例子:
        從數據中發現的X和Y磁強計的最大輸出:
                        Xmin = -0.284gauss Xmax = +0.402gauss
                   Ymin = -0.322gauss Ymax = +0.246gauss
        從中可以看出X軸的數據,X具有更大的反應,我們設置其比例係數爲1
                        Xs = 1
        再計算其他比例係數:
                                    (Xmax - Xmin
                        Ys = ————————
                                    (Ymax - Ymin

        對於偏置補償:
                        Xb = Xs[1/2(Xmax - Xmin) - Xmax ]
                        Yb = Ys[1/2(Ymax - Ymin) - Ymax ]

 
        正確的輸出:
                        Xout = Xin*Xs + Xb
                        Yout = Yin*Ys + Yb


        方法二.
                1)水平勻速旋轉,收集XY軸數據
                2)轉動器材90度(Z軸)勻速轉動以收集Z軸數據
                        Xoffset = (Xmax + Xmin)/2
                        Yoffset = (Ymax + Ymin)/2
                        Zoffset = (Zmax + Zmin)/2

                將磁力計讀到的裸值減去offset,得到用做角度計算的Heading值
                        XH = X - Xoffset
                        YH = Y - Yoffset
                        ZH = Z - Zoffset

        水平測試,得到的方位角 = arctanYH/XH
        非水平測試,需要使用加速計進行傾角補償,先計算出翻滾角Roll和俯仰角Pitch,然後計算Heading值:
                       XH = x*cos(P)+Y*sin(R)*sin(P)-Z*cos(R)*sin(p)
                        YH = Y*cos(R)+Z*sin(R)

  


        關於爲什麼設置偏置,請參考以下文章:

        ST集成傳感器方案實現電子羅盤功能:http://www.dzsc.com/data/html/2010-11-29/87454.html

        HMC5883L常見問題解答:http://blog.sina.com.cn/s/blog_402c071e0102v8gj.html

 

        這裏我採用了上方的簡單方法,來計算一個 offsetX, offsetY, offsetZ,然後減去這個偏移量,得到了正確的結果。下方是代碼。下方我做了一個處理(諸如:mag.x*0.2 + magRange[0]*0.8)。是因爲偶爾mag.x mag.y mag.z 會出現一個異常的值,使得計算的offsetX  offsetY offsetZ不準,所以加了這個濾波處理。

 

        static float magRange[6] = {1.0,-1.0,1.0,-1.0,1.0,-1.0};// magRange[0] 對應X最小,magRange[1] 對應X最大

        // Magnetometer not yet used more then for logging.
        // 磁力計尚未使用到,僅僅只是 log 記錄下來。
        imu9Read(&gyro, &acc, &mag);
 
        if(magRange[0] > mag.x) magRange[0] = mag.x*0.2 + magRange[0]*0.8; // x min
        if(magRange[1] < mag.x) magRange[1] = mag.x*0.2 + magRange[1]*0.8; // x max
        if(magRange[2] > mag.y) magRange[2] = mag.y*0.2 + magRange[2]*0.8;
        if(magRange[3] < mag.y) magRange[3] = mag.y*0.2 + magRange[3]*0.8;
        if(magRange[4] > mag.z) magRange[4] = mag.z*0.2 + magRange[4]*0.8; // z min
        if(magRange[5] < mag.z) magRange[5] = mag.z*0.2 + magRange[5]*0.8; // z max
        magOffset[0] = (magRange[0]+magRange[1])/2.0;
        magOffset[1] = (magRange[2]+magRange[3])/2.0;
        magOffset[2] = (magRange[4]+magRange[5])/2.0;
        mag.x -= magOffset[0];
        mag.y -= magOffset[1];
        mag.z -= magOffset[2];

 

        自我檢測也比較重要。通過HMC5883l芯片提供的自我檢測功能,進行自我檢測,然後找到一個比例因子。將傳感器的檢測值乘以這個比例因子,就可以修正磁場。我在代碼中沒有使用。相關的詳細資料請看如下英文。

相關源代碼,可以參考 Crazyflie firmware中的 bool hmc5883lSelfTest() 函數。 

自我檢測

SELF TEST OPERATION

 

To check the HMC5883L  for proper operation, a self test feature in incorporated in which the sensor offset straps are excited to create a nominal field strength (bias field) to be measured. To implement self test, the least significant bits (MS1 and MS0) of configuration register A are changed from 00 to 01 (positive bias) or 10 (negetive bias), e.g. 0x11 or 0x12.

 

Then, by placing the mode register into single-measurement mode (0x01), two data acquisition cycles will be made on each magnetic vector. The first acquisition will be a set pulse followed shortly by measurement data of the external field. The second acquisition will have the offset strap excited (about 10 mA) in the positive bias mode for X, Y, and Z axes to create about a ±1.1 gauss self test field plus the external field. The first acquisition values  will be subtracted from the second acquisition, and the net measurement will be placed into the data output registers. 

 

Since self test adds ~1.1 Gauss additional field to the existing field strength, using a reduced gain setting prevents sensor from being saturated and data registers overflowed. For example, if the configuration register B is set to 0x60  (Gain=3), values around +766 LSB  (1.16 Ga * 660 LSB/Ga) will be placed in the X and Y data output registers and around +713 (1.08 Ga * 660 LSB/Ga) will be placed in Z data output register. To leave the self test mode, change MS1 and MS0 bit of the configuration register A back to 00 (Normal Measurement Mode), e.g. 0x10. 

 

比例因子校準

SCALE FACTOR CALIBRATION

 

Using the self test method described above,  the user can scale sensors’ sensitivity  to match each other.  Since placing device in positive bias mode  (or alternatively negative bias mode) applies a known artificial field on all three axes, the resulting ADC measurements in data output registers can be used to scale the sensors. For example, if the expected self test value for X-axis  is 766 and the actual value  is 750 then a scale factor of (766/750) should be multiplied to all future readings of X-axis. Doing so for all three axes will ensure their sensitivity are well matched.

 

The built-in self test can also be used to periodically compensate the scaling errors due to temperature variations. A compensation factor can be found by comparing the self test outputs with the ones obtained at a known temperature. For example, if the self test output is 750 at room temperature and 700 at the current temperature then a compensation factor of (750/700) should be applied to all current magnetic readings. A temperature sensor is not required using this method.

 


Crazyflie firmware中的 bool hmc5883lSelfTest() 函數代碼如下,僅供參考:(函數中的各種定義這裏未給出)

bool hmc5883lSelfTest()
{
  bool testStatus = TRUE;
  int16_t mxp, myp, mzp;  // positive magnetometer measurements
  int16_t mxn, myn, mzn;  // negative magnetometer measurements
  struct
  {
    uint8_t configA;
    uint8_t configB;
    uint8_t mode;
  } regSave;

  // Save register values
  if (i2cdevRead(I2Cx, devAddr, HMC5883L_RA_CONFIG_A, sizeof(regSave), (uint8_t *)&regSave) == FALSE)
  {
    // TODO: error handling
    return FALSE;
  }
  // Set gain (sensitivity)
  hmc5883lSetGain(HMC5883L_ST_GAIN);

  // Write CONFIG_A register and do positive test
  i2cdevWriteByte(I2Cx, devAddr, HMC5883L_RA_CONFIG_A,
      (HMC5883L_AVERAGING_1 << (HMC5883L_CRA_AVERAGE_BIT - HMC5883L_CRA_AVERAGE_LENGTH + 1)) |
      (HMC5883L_RATE_15 << (HMC5883L_CRA_RATE_BIT - HMC5883L_CRA_RATE_LENGTH + 1)) |
      (HMC5883L_BIAS_POSITIVE << (HMC5883L_CRA_BIAS_BIT - HMC5883L_CRA_BIAS_LENGTH + 1)));

 
  hmc5883lSetMode(HMC5883L_MODE_SINGLE);
  vTaskDelay(M2T(HMC5883L_ST_DELAY_MS));
  hmc5883lGetHeading(&mxp, &myp, &mzp);

  // Write CONFIG_A register and do negative test
  i2cdevWriteByte(I2Cx, devAddr, HMC5883L_RA_CONFIG_A,
      (HMC5883L_AVERAGING_1 << (HMC5883L_CRA_AVERAGE_BIT - HMC5883L_CRA_AVERAGE_LENGTH + 1)) |
      (HMC5883L_RATE_15 << (HMC5883L_CRA_RATE_BIT - HMC5883L_CRA_RATE_LENGTH + 1)) |
      (HMC5883L_BIAS_NEGATIVE << (HMC5883L_CRA_BIAS_BIT - HMC5883L_CRA_BIAS_LENGTH + 1)));

 
  hmc5883lSetMode(HMC5883L_MODE_SINGLE);
  vTaskDelay(M2T(HMC5883L_ST_DELAY_MS));
  hmc5883lGetHeading(&mxn, &myn, &mzn);

  if (hmc5883lEvaluateSelfTest(HMC5883L_ST_X_MIN, HMC5883L_ST_X_MAX, mxp, "pos X") &&
      hmc5883lEvaluateSelfTest(HMC5883L_ST_Y_MIN, HMC5883L_ST_Y_MAX, myp, "pos Y") &&
      hmc5883lEvaluateSelfTest(HMC5883L_ST_Z_MIN, HMC5883L_ST_Z_MAX, mzp, "pos Z") &&
      hmc5883lEvaluateSelfTest(-HMC5883L_ST_X_MAX, -HMC5883L_ST_X_MIN, mxn, "neg X") &&
      hmc5883lEvaluateSelfTest(-HMC5883L_ST_Y_MAX, -HMC5883L_ST_Y_MIN, myn, "neg Y") &&
      hmc5883lEvaluateSelfTest(-HMC5883L_ST_Z_MAX, -HMC5883L_ST_Z_MIN, mzn, "neg Z"))
  {
    DEBUG_PRINT("Self test [OK].\n");
  }
  else
  {
    testStatus = FALSE;
  }

  // Restore registers
  if (i2cdevWrite(I2Cx, devAddr, HMC5883L_RA_CONFIG_A, sizeof(regSave), (uint8_t *)&regSave) == FALSE)
  {
    // TODO: error handling
    return FALSE;
  }

  return testStatus;
}

 

        另外這裏提供了一個方法,日後若有研究,我將給出詳細說明,這裏提供鏈接供參考:

        http://bbs.kechuang.org/read/67382


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章