2015年10月24日 星期六

PiQuadcopter(掰咖考特) -- 用Raspberry pi 做四軸飛行器(三) 四軸運動原理與控制

不是所有東西裝上馬達配螺旋槳就能飛起來的,就算飛得起來也不表示一定飛得穩!

一切都是從角動量守衡開始

想像一下,一個物體裝上有足夠馬力能把物體拉起來的螺旋槳,像這樣:

結果不會像漫畫一樣美好,因為角動量守衡的關係,如果這螺旋槳順時針方向轉,那這螺旋槳(跟接著螺旋槳的物體)會一起逆時針方向轉。所以哆啦A夢插上竹蜻蜓後應該會不停轉轉轉。

至於直昇機怎麼飛?它除了頭上那頂大螺旋槳以外,尾巴上還有個尾槳可以抵消上段中角動量守衡造成的力矩。

那四個螺旋槳要怎麼辦?如果全部逆時針轉,那根據角動量守衡,整個機體就得順時針轉,像這樣。
想要它機體不轉的話也簡單,對角線那兩對,一對轉順時針,一對轉逆時針,總角動量就是0了(假設四個軸的重量均勻分佈)。
那我要怎麼讓它移動?
假設要像下圖那樣走,就把那方向的相鄰兩個(或一個)馬達轉速降低,或提高反方向馬達轉速,這樣低速馬達相對位置降低,高速馬達相對位置升高,四個螺旋槳不垂直於地面,就產生一個水平分量,朝著低速馬達的方向前進。


如果要水平轉動,那就調整某對角線那組的馬達,讓角動量守衡造成的力矩轉動機身。



四軸本身需要的材料

首先你需要四組馬達+螺旋槳(廢話!),而且這四組馬達+螺旋槳不但需要提供足夠的升力去抵抗重力跟阻力(有風的情況下),還要有餘力去移動!一般的建議是馬達+螺旋槳能提供的最大升力必須大於四軸總重的一半:假設四軸總重為1.5kg,搭配的馬達+螺旋槳必須能提供3kg的最大升力,也就是說每一組馬達+螺旋槳的最大升力必須大於~770g。

根據前人的經驗,對於F450(對角線長度450mm,要用Raspberry Pi的話大概這是你可以用的"最小"機架了)的四軸來說,搭配2212 1000KV無刷馬達 + 1045螺旋槳 + 11.1V 電池的螺旋槳通常可以達到總升力為3kg。這裡2212是馬達的大小,表示馬達直徑22mm跟高12mm(馬達愈大通常出力愈大),1000KV表示電源每多增加1V則馬達多轉1000次/秒(馬達沒加螺旋槳的情況),1045則是螺旋槳的長度跟曲度。

鋰聚(LiPo)電池由於相對於別種電池來說同電量比較輕的緣故常被四軸選用。單節鋰聚電池的規格是3.7 V(最高到4.2 V),我用的是3S1P(就是三個單節並聯成一個)標準就是11.1V,它的放電速率跟電量各為35C跟5500mAh,意思就是說這電池可以在電流為5.5A的情況下維持1小時,然後放電速率為35*5500mA = 192.5A。

Electronic Speed Control (ESC,台灣好像叫電調還是電變)是用來控制馬達出力的,通常是使用脈衝寬度調變(PWM),藉由脈衝的寬度(1-2ms)來控制馬力大小(寬度愈高輸出愈大)。一般來說四軸要能飛最小需要50Hz的更新速率(每個脈衝訊號的頻率),要飛得好飛得穩就要更高的更新速率。要注意的是由於ESC直接輸出三相電壓給無刷馬達,所以要注意ESC本身可承受的電流大小。通常一個2212 100KV馬達接到11.1V電源時,最高可輸出10-12A電流,那ESC最好可以承受到兩倍以上,也就是20-25A(注意是每個馬達,不是四個加起來)。

四軸行進間的航向或姿態需要即時被系統所掌握,不然隨時有翻覆的危險。通常四軸是用慣性測量單元( inertial measurement unit,IMU) 的三軸加速度計(accelerometers)跟三軸角速度計(gyroscopes)得知當前姿態,若是需要知道當前航向則需使用電子羅盤(magnetometers)。想要知道高度的話,氣壓計(barometer)是一個選擇(不過精度要夠小,目前看到比較好的高度誤差可達10cm,做懸停還是很勉強)。GPS也是不錯的選擇,既可以知道位置也可以測量速度,可惜它反應比較慢(5-10 Hz)。

最後,少不了用來溝通遙控器跟四軸的無線通訊模組(RF module),通常我們使用的頻段為2.405GHz-2.485GHz,速度愈快有效距離愈短。

所以要控制四軸,主要的流程就是:
  1. 讀取感測器數據 + 收到控制器訊號
  2. 將感測器數據做數據處理(濾掉雜訊或校正)
  3. 根據處理過的數據換算成目前機體角度(所謂的roll, pitch和yaw是也 https://en.wikipedia.org/wiki/Aircraft_principal_axes)或機體位置
  4. 根據控制器給的命令跟當前角度和位置控制馬達出力(PID是也)
這邊其實對於Raspberry Pi來說,比較麻煩的還是讀取感測器數據的timing。我每次讀取加速度+角速度數據後會設暫停3ms左右,讓量測週期達到4ms,可是不是總是成功,以下是我取了一分鐘數據量測的控制週期,最多可以到8ms (第6秒那邊的空白我也不知道是啥回事) ...
 這個希望以後又Preempt RT kernel或Xenomai改善。

Reference
http://csenichijou.blogspot.fr/2014/03/Quadcopter-2.html


8 則留言:

  1. 請問一下為什麼要將感測器取樣時間固定呢?是為了要角速度積分時間固定嗎?還是有其他原因
    謝謝

    回覆刪除
    回覆
    1. 請問你是指固定週期?不懂你的問題喔。

      刪除
  2. 回覆
    1. 你如果不固定週期那你CPU讀完資料後要立刻重讀一次?那你CPU會爆忙的喔。

      刪除
    2. 了解,不過有需要固定週期嗎?不能夠讀完sleep個時間之後在讀,因為cpu排程的關係不一定能夠精準控制在想要的週期內。
      謝謝你的回答

      刪除
    3. 可以sleep完再讀阿,可是你要確定能在你要求的時間後醒來阿。nanosleep可以指定是隔一段時間醒來(ex: 4000us)或在指定時間醒來,我通常是選後者。後者有可能會提前醒過來,前者的話一定是在要求時間之後醒來,就看你怎麼決定了。

      刪除
    4. 在請教您一下,有直接用過mpu6050的驅動來讀取資料嗎?在user space要如何抓取呢。
      感謝

      刪除
    5. 我記得是在/sys裏面某目錄(我真的忘了,RPi不在手上,有時間我才能回去翻)

      刪除

Google Code Prettify