在本文中,我們將繼續進行Arduino藍牙手套的研發。我們將建立一個機械系統來獲取手指的彎曲資訊。同時,我們將會來瞭解如何整合IMU資料,無線封裝和發送資料,使用Kinect以及如何在實際生活中使用Arduino藍牙手套。我們強烈建議您先閱讀Arduino藍牙手套第一部分-基礎來瞭解有關本專案的基礎知識。
硬體
軟體
工具
首先,為了測量手指的彎曲(手指彎折)資訊,我們必須將手指彎曲程度轉換為電位計的旋轉度。我們可以透過簡單的機械系統來實現這一目的,如下圖所示:
為了在現實生活中進行應用,我們需要先在實體建模編輯器(如Autodesk Inventor)中進行建模。
接下來,我們需要將模型用3D列印技術製造出來。STL檔是所有3D印表機中常見的3D模型類型。只需要將所有模型分別匯出成STL檔,並發送到3D印表機即可。如想查看已編譯的3D設計檔,請點擊此處。
取用電位計(不帶黑色旋鈕/手柄)、螺絲、螺母以及3D列印零件,然後如圖4所示進行組裝。
如圖5所示擰入關節。然後,我們將黑色手柄與擰入的手指關節粘合在一起。
將關節擰緊後,我們要將組裝好的手指粘合到手套上。粘合使用的是超強力的多用途膠水。粘合前,表面必須保持清潔和乾燥。然後在兩個表面塗一層薄薄的膠水,等待10到15分鐘後,將表面用力按壓幾秒鐘。如有必要,您可以在每個單元周圍也散佈一些膠水。建議您將其晾乾約24小時。
* 黏貼時請切勿將手指伸入手套,使用紙板或其他材料。
現在我們開始粘合手指關節。去除關節部分和兩一個粘性扣件,然後將他們黏貼在手指的指甲上方(圖8 & 9)。
將黑色手柄插入電位計孔中,以連接兩個組裝好的零件。
耐心對每根手指再重複9次相同的操作。
整個模組的接線圖如下所示。
現在,我們來對手指進行連線吧!
準備紅色和黑色的電線,以及三根分別帶有白光、黃色和黑色標記的電線。此處強烈建議將顏色編碼,以避免混淆。
如圖11所示,將黑色標記和黃色標記的電線焊接到電位計上。
用塑膠紮線帶捆紮電線,以避免其受任何機械外力破壞。
接下來,您需要將黑色標記的電線與黑色電線以及黃色和白光標記的電線焊接到電阻上。紅色電線必須焊接到電阻的另一端,白光標記的電線連接至Arduino類比輸入端。
焊接完所有單元後,我們將用熱縮管對電線進行收縮,並用束線帶將電線整合。
組裝完成!我們繼續進行程式設計部分。
安裝新版本的 IMU Library 。請參考第一部分瞭解如何安裝該程式館。
打開 bending.ino 並將其上傳到Arduino Uno。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
#include "glove.h" TFinger Finger1 = TFinger(A0); TFinger Finger2 = TFinger(A1); TFinger Finger3 = TFinger(A2); TFinger Finger4 = TFinger(A3); TFinger Finger5 = TFinger(A4); void setup() { Serial.begin (9600); // Open the serial port Serial.println ("Be ready to set min, in 3..."); delay(1000); Serial.println ("2..."); delay(1000); Serial.println ("1..."); delay(1000); Finger1.setmin(); Finger2.setmin(); Finger3.setmin(); Finger4.setmin(); Finger5.setmin(); Serial.println ("Minimum is set"); Serial.println ("Be ready to set max, in 3..."); delay(1000); Serial.println ("2..."); delay(1000); Serial.println ("1..."); delay(1000); Finger1.setmax(); Finger2.setmax(); Finger3.setmax(); Finger4.setmax(); Finger5.setmax(); Serial.println ("Maximum is set"); Finger1.calibrate(); Finger2.calibrate(); Finger3.calibrate(); Finger4.calibrate(); Finger5.calibrate(); Serial.println ("Calibrated"); } void loop() { Serial.print ( Finger1.read() ); Serial.print ("\t"); Serial.print (Finger2.read()); Serial.print ("\t"); Serial.print (Finger3.read()); Serial.print ("\t"); Serial.print (Finger4.read()); Serial.print ("\t"); Serial.print (Finger5.read()); Serial.println ("\t"); delay(300); // } |
您將會看到如圖20所示的運行結果:
請注意,必須遵循校準程式才能夠對資料進行準確測量。
在 Arduino藍牙手套第一部分 – 基礎中,我們介紹了IMU感測器的基礎知識。現在,我們將來學習如何整合陀螺儀和加速度計的資料。
首先,我們返回並查看之前的測量結果。
如果仔細研究L3G4200D資料表和IMU程式館,您就會發現MEMS陀螺儀以原始數位單元來測量角速度,而IMU程式館的函數可使數位單元轉換為每秒的角度(dsp)。
例如,陀螺儀返回12492數位值:
感測器的靈敏度表示的是該感測器可檢測到的最小變化值。請注意,範圍約大,您從陀螺儀獲得的靈敏度越低。
角速度是透過陀螺儀測量的值。因此,陀螺儀能夠估計人體繞某個軸旋轉的速度。在實際應用中,需要確定我們手套的位置。我們可以透過整合所有角速度值,然後除以時間變化,來估算當前角位置。
因為角速度的測量不是連續的,而是離散的,所以我們會得到一個叫做漂移的誤差。之所以稱為“漂移”,是因為即使身體處於靜止狀態,這些角位置變化的總和也會發生浮動。
我們一起看下面的陀螺儀漂移範例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
#include // Library for I²C #include // Library for working with IMU modules Gyroscope gyro; // Create an object to work with Gyroscope // Time Variables unsigned long starttime; unsigned long endtime; float dt; int ticker = 0; bool firstcall=true; // Indicator of a first iteration // Angle Variables float gyro_rateX, gyro_rateY, gyro_rateZ; float Pitch=0; float Roll=0; float Yaw=0; void setup () { Serial.begin (9600); // Open the serial port Serial.println ("Begin init ..."); // Display a message on the beginning of the initialization gyro.begin (); // Initialize the gyroscope at 100Hz Output Data Rate gyro.setRange(RANGE_2000); // set the gyroscope at 2000 dps range sensitivity Serial.println ("Init completed"); // Display a message about the successful initialization Serial.println ("Gyroscope"); } void loop () { endtime = micros(); // End time for the current Measurement if (firstcall) { firstcall=false; } else { dt = (float)(endtime - starttime)/1000000; // Get time beetween measurements gyro_rateX=gyro.readX_DegPerSec(); // Current Angle rate around the X-axis gyro_rateY=gyro.readY_DegPerSec(); // Current Angle rate around the Y-axis gyro_rateZ=gyro.readZ_DegPerSec(); // Current Angle rate around the Z-axis Pitch += 1 * gyro_rateX * dt; // Current Angle around the X-axis Roll += 1 * gyro_rateY * dt; // Current Angle around the Y-axis Yaw += 1 * gyro_rateZ * dt; // Current Angle around the Z-axis delay (10); } starttime = micros(); // Start time for the next Measurement if (ticker > 30) // Print Message every 300 ms { ticker=0; Serial.print (Roll); // Output angular velocity around the axis X Serial.print ("\t"); Serial.print (Pitch); // Output of the angular velocity around the Y axis Serial.print ("\t"); Serial.print (Yaw); // Output of the angular velocity about the Z axis Serial.print ("\t"); Serial.println (""); } else {ticker++;} } |
如果讓IMU感測器保持不動,您將會看到漂移現象(圖22)。
如上所述,由於有漂移的趨勢,總和將會隨著時間的增加產生誤差。但我們可以透過計算和利用零速率電平來緩解漂移帶來的影響。
有關零速率電平的定義在陀螺儀資料表的“2.6.2 零速率電平”一節中有詳細描述。有這一現象的主要原因是在IMU上外加的機械應力,例如,在印刷電路板上焊接之後殘留的應力。當有了機械應力之後,零速率電平會隨溫度略有改變,所以這一變化也許就可以被忽略了。
您可以點擊此處查看在新版本IMU程式館中的執行細節。
經過這些強化後,我們就可以使用陀螺儀資料了,但是只能短期使用。我們仍需要在長時間內能夠保持穩定的資訊。
加速度計是一種測量加速度的裝置。透過使用加速度計,我們可以根據計算獲得的重力向量來確定感測器工作平面的角度。但是,使用智慧手套時,感測器將測量所有其他加速度,包括手臂的運動,這可能會破壞所測量的重力向量。
低通濾波器可用於從隨機加速度中過濾掉重力向量。加速度計的測量值只適用於長期使用。
將感測器資料融合的最常見方法之一是使用功能強大的Kalman濾波器(很難理解,也很難在Arduino上實現)。
我們使用互補濾波器作為整合IMU資料的解決方案,這種濾波器非常易於理解,且容易在Arduino上實現。互補濾波器基本原理如下:
其中,Roll_i – 上一次反覆運算中計算出的橫滾角
gyroRoll_i+1 – 基於最近一次陀螺儀資料進行的最近一次測量所得到的角度變化
accelRoll_i+1 – 基於最近一次的加速度計資料計算出的橫滾角
Roll_i+1 – 最新計算得到的帶有互補濾波器的橫滾角
該濾波器可以在短期內利用陀螺儀的動態特性,並透過加速度計資料在長期內消除誤差。您可以自己進行測試,只需在Arduino IDE中打開imu_2.ino並將其上傳到您的Arduino IDE即可。
當我們獲取測量資料時,必須使用無線藍牙連接來將資料傳送到PC。
首先,檢查Bluetooth Bee是否已正確配置。將Bluetooth Bee安裝在Xbee USB適配器上,將Bluetooth Bee換為AT模式,然後使用“AT+UART?”指令檢查UART配置。Bluetooth Bee應返回“115200,0,0”(序列傳輸速率115200位/秒,一個停止位,無同位檢查位元)。如果不是,請發送“AT+ UART=115200,0,0”指令來配置Bluetooth Bee,然後再次檢查UART配置。檢查後不要忘記斷路AT模式!
另外需要注意的是位於無線SD擴展板上的“序列選擇”切換,該切換將指定將無線連接所讀取的資料發送到何處。
將其切換到MICRO位置。當處於MICRO位置時,藍牙模組會連接到Arduino。請注意,Arduino仍連接到USB串口轉換器。如果您從Arduino將資料寫入序列埠,資料將會以兩種方式發送:USB傳送和無線傳送。
將messaging.ino上傳到Arduino。請注意,每次打開或重置Arduino時,它都會透過三個步驟進行校準:
陀螺儀零速率電平計算;
測量手指位置最小值;
測量手指位置最大值。
在計算陀螺儀零速率電平之前,請保持IMU靜止不動。在測量手指位置最小值之前,請戴上Arduino手套並握緊拳頭。在測量手指最大位置之前,請戴上Arduino手套並鬆開拳頭。
在Arduino IDE中打開messaging.ino並將其上傳到您的Arduino UNO中。
斷路Arduino電源,然後將Bluetooth Bee放置在無線擴展板上。請確保Bluetooth Bee不在AT模式下,並且將無線擴展板序列選擇切換切換到MICRO位置。
用9V電池為Arduino Uno供電,並使用“1234”作為密碼與您的Bluetooth Bee配對。確認配對成功後,您可以在裝置管理員中找到您的無線藍牙連接作為虛擬COM埠。
從專案瀏覽器視窗中打開Messaging.lvprojLabVIEW項目和Messaging Test.vi。選擇相關COM埠並運行。
您將會看到Arduino Uno在序列埠中寫入的資料已透過藍牙傳輸,並從虛擬COM埠中讀取。
表面上看,Kinect 是一款Xbox 360遊戲裝置控制器,可替代常見的搖桿。實際上,它是一個功能強大的運動捕捉控制器,可獲取您的姿態資訊,並使您可以用手或者身體來控制遊戲過程。雖然這個裝置是為了遊戲而研發的,但也可以在實際生活中使用。
想要在LabVIEW環境中使用用於Xbox 360的Kinect,您需要安裝以下軟體:
從專案瀏覽器視窗中打開Kinect.lvprojLabVIEW Project和Kinect Test.vi,然後運行。如果正確安裝了所有要求的軟體,您將看到類似以下內容的視訊和Kinect處理結果:
現在,我們需要把所有內容整合到一個應用程式中。
打開Arduino Gloves.lvproj LabVIEW Project。然後從專案瀏覽器視窗打開Host Main.vi。為左右手套藍牙連接選擇相應的COM埠。插入Kinect,並確保可以使用。
然後戴上Arduino藍牙手套並打開電源,為校準提供所需要的必要條件。
之後,運行Host Main.vi,您將會看到以下內容:
請確認對每個手指的彎曲度進行了準確的測量,並且橫滾角、俯仰角和偏航角與您的手的實際姿勢相對應。
Arduino藍牙手套在現實生活中的機器人控制應用領域很有用。所有處理過的資料都可以透過UDP資訊傳輸到任何協力廠商應用程式中。
我們選擇工業機器人手臂的類比器 – UDPPuma560 作為協力廠商應用程式的範例,同時添加了UDP接收器環路。
從專案瀏覽器視窗打開Puma560 Simulator.lvproj, Host Main.vi 以及 Puma560 Simulator.vi 。
為左右手套藍牙連接選擇相應的COM埠。插入Kinect並確保可以使用。
然後戴上Arduino藍牙手套並打開電源,並為校準提供所需的必要條件。
運行完這兩個VI後,您將會得到以下結果:
請注意,您必須對從智慧手套獲取的資料進行正確的解譯,而不應該直接使用沒有經過任何處理的資料。例如,操作員的右手座標不可能與機器人的手臂夾持器相同,所以您需要將測量資料從操作員的坐標系轉換為機器人的坐標系。
演示: