作者介紹
Liz Looney
Liz Looney是本書的合著者之一。她是谷歌的軟件工程師,也是谷歌“機器人工作小組”(Robotics Task Force)的成員,作為App Inventor團隊的初創(chuàng)成員,她領(lǐng)導了樂高頭腦風暴機器人(LEGO MINDSTORMS)組件的開發(fā)工作。Liz Looney是一位卓越的軟件工程師,有著超過25年的從業(yè)經(jīng)歷,曾先后在Borland、Oracle及Google公司工作。
本章將創(chuàng)建一個應用,將Android手機變成LEGO MINDSTORMS NXT 機器人的遙控器。應用中用按鈕來控制機器人前后移動、左右轉(zhuǎn)動和停止,如果機器人遇到障礙物,它還會自動停止。應用中使用具有藍牙功能的手機與機器人通信。
LEGO MINDSTORMS機器人不只是玩具,更是教具。After-school program 使用機器人來教小學和初中的孩子們掌握解決問題的能力,并引導他們了解工程和計算機編程。NXT機器人也用于FIRST LEGO League 機器人競賽,這項比賽允許9-14歲的孩子參加。
NXT可編程機器人套件中有一個“NXT智能積木”主單元,它可以控制三個電機及四個輸入傳感器。你可以用樂高的構(gòu)造元件、齒輪、車輪、電機和傳感器來組裝機器人。該套件自帶的軟件可以對機器人進行編程,但現(xiàn)在我們將用App Inventor來創(chuàng)建Android應用,通過藍牙連接來控制NXT機器人。
應用中參與協(xié)作的機器人具有超聲波傳感器以及用于移動的車輪,如Shooterbot 機器人。圖中所示,這款機器人通常是人們利用LEGO MINDSTORMS NXT 2.0套件建造的第一個機器人。它的左車輪與輸出端口C相連,右車輪與輸出端口B相連,顏色傳感器與輸入端口3相連,超聲波傳感器與輸入端口4相連。
本章用到了以下組件和概念:
BluetoothClient組件:用于建立Android設備與NXT機器人之間的藍牙連接;
ListPicker組件:為用戶提供機器人選擇列表,選中后開始建立機器人到Android的連接;
NxtDrive組件:用于驅(qū)動機器人的輪子;
NxtUltrasonicSensor組件:利用機器人的超聲波傳感器探測障礙物;
本章的應用需要Android 2.0或以上版本。此外,出于安全原因,藍牙設備必須首先配對才能彼此連通。在開始構(gòu)建應用之前,需要按以下步驟使Android設備與NXT機器人配對:
1. 在NXT上單擊向右箭頭,直到顯示“Bluetooth”,然后按下橙色方塊;
2. 點擊向右的箭頭,直到顯示“Visibility”,然后按下橙色方塊;
3. 如果“Visibility”值已設定為可見,繼續(xù)步驟4;如果不可見,請單擊向左或向右箭頭設置其值為可見;
4. 在Android設備上,進入設置→無線與網(wǎng)絡;
5. 確保打開藍牙功能;
6. 點擊“藍牙”;
7. 在“可用設備”中查找名為“NXT”的設備;
8. 如果機器人名字下顯示“已配對但未連接”字樣,則配對成功!否則,繼續(xù)執(zhí)行步驟9;
9. 如果機器人名字下顯示“與此設備配對”,則點擊它;
10. 在NXT上,要求輸入密碼,按下橙色方塊接受1234為密碼;
11. 在Android上,也會要求輸入PIN碼,輸入1234,然后按確定;
12. 現(xiàn)在應該看到“已配對但未連接?!?,說明配對成功!
注意:如果你曾經(jīng)修改過機器人的名字,則尋找機器人現(xiàn)在的名字,而非“NXT”。
連接到App Inventor網(wǎng)站,創(chuàng)建新項目“NXTRemoteControl”,將設置屏幕的標題為“遙控機器人”,并連接測試手機。
在這個應用中,我們需要分別創(chuàng)建可見組件及不可見組件,并分別定義它們的行為。
在創(chuàng)建用戶界面之前,先來創(chuàng)建表12-1中的不可見組件,如圖12-1所示,用來控制NXT。
表12-1 NXT“機器人遙控”應用中的不可見組件
組件類型 | 面板中分組 | 命名 | 作用 |
---|---|---|---|
BluetoothClient | Connectivity | BluetoothClient1 | 建立Android與NXT的連接 |
NxtDrive | LEGO? MINDSTORMS? | NxtDrive1 | 驅(qū)動機器人的輪 |
NxtUltrasonicSensor | LEGO? MINDSTORMS? | NxtUltrasonicSensor1 | 檢測障礙物 |
Notifier | User Interface | Notifier1 | 顯示錯誤信息 |
圖 12-1 在組件設計器底部顯示的不可見組件
按以下方式設置組件的屬性:
1. 設置NxtDrive1及NxtUltrasonicSensor1的BluetoothClient屬性為 BluetoothClient1;(說明輪子的驅(qū)動與障礙物的偵測都需要依賴藍牙通信——譯者注)
2. 勾選NxtUltrasonicSensor1的BelowRangeEventEnabled屬性(近距離偵測障礙物功能可用);
3. 設置NxtDrive1的DriveMotors屬性
如果機器人的左輪電機與輸出端口C連接,右輪電機與輸出端口B連接,則保持默認設置“CB”;
4. 設置NxtUltrasonicSensor1的SensorPort屬性
如果機器人的超聲波傳感器與輸入端口4連接,則保持默認值“4”;
現(xiàn)在創(chuàng)建用戶界面組件,如圖12-2所示。
圖 12-2 組件設計器中的應用
建立藍牙連接時,Android設備需要訪問NXT機器人具有唯一性的藍牙地址,但藍牙地址由8個用冒號分隔的2位數(shù)的十六進制數(shù)(二進制數(shù)的另一種表示方式)組成,輸入起來異常麻煩,而且每次運行應用都要在手機上輸入該地址。為了減少麻煩,使用ListPicker來顯示已經(jīng)與手機配對的機器人列表(列表項的值為機器人的名稱及藍牙地址),并從中選擇一個。
使用按鍵來驅(qū)動機器人的前進、后退、左右轉(zhuǎn)動、停止和斷開連接,使用VerticalArrangement來放置除ListPicker以外的所有組件,用HorizontalArrangement來放置左右轉(zhuǎn)向及停車按鈕。
按照表12-2中列出的組件來創(chuàng)建圖12-2所示的用戶界面。
表12-2 NXT機器人控制器應用中的可見組件
組件類型 | 面板中分組 | 命名 | 作用 |
---|---|---|---|
ListPicker | User Interface | ConnectListPicker | 選擇要連接的機器人 |
VerticalArrangement | layout | VerticalArrangement1 | 布局容器,容納除ListPicker之外的組件 |
Button | User Interface | ForwardButton | 前進 |
HorizonalArrangement | layout | HorizonalArrangement1 | 布局容器,容納左轉(zhuǎn)、右轉(zhuǎn)、停止按鈕 |
Button | User Interface | LeftButton | 左轉(zhuǎn) |
Button | User Interface | StopButton | 停止 |
Button | User Interface | RightButton | 右轉(zhuǎn) |
Button | User Interface | BackwardButton | 后退 |
Button | User Interface | DisconnectButton | 與NXT斷開連 |
按照圖12-2所示來設置可視組件布局:將LeftButton、StopButton和RightButton放在HorizontalArrangement1中,將ForwardButton、HorizontalArrangement1、BackwardButton和DisconnectButton放在VerticalArrangement1中。 按下列方式設置組件屬性:
1. 取消勾選Screen1的Scrollable屬性(滾屏功能);
2. 設置ConnectListPicker和DisconnectButton的寬度為“Fill parent”;
3. 設置VerticalArrangement1、ForwardButton、HorizontalArrangement1、LeftButton、StopButton、RightButton及BackwardButton的Width與Height為“Fill parent”;
4. 設置ConnectListPicker的Text屬性為“連接”;
5. 設置ForwardButton的Text屬性為“∧”;
6. 設置LeftButton的Text屬性為“<”;
7. 設置StopButton的Text屬性為“—”;
8. 設置RightButton的Text屬性為“>”;
9. 設置BackwardButton的Text屬性為“∨”;
10. 設置DisconnectButton的Text屬性為“斷開連接”;
11. 設置ConnectListPicker和DisconnectButton的FontSize屬性為30;
12. 設置ForwardButton、LeftButton、StopButton、RightButton及BackwardButton的FontSize屬性為40。
在這類應用中,當手機與NXT建立藍牙連接之前,應該隱藏用戶的操作界面,為此取消勾選VerticalArrangement1的Visible屬性。不要擔心,當NXT連通后,將重新顯示用戶界面。
本節(jié)將編程來設置應用的行為,包括:
用戶從列表中選擇機器人,并與之建立連接;
斷開機器人與應用的連接;
使用控制按鈕來操控機器人;
添加第一個行為:連接到NXT。點擊 ConnectListPicker將顯示已配對的機器人列表,選中一個,將在應用與機器人之間建立藍牙連接。
使用ConnectListPicker組件來顯示機器人列表。ListPicker的外表像按鈕,被點擊后則顯示列表項,并允許進行單選。
使用BluetoothClient1.AddressesAndNames塊來提供列表,列表項是已經(jīng)與Android設備配對的藍牙設備的名稱及地址。由于NXT已經(jīng)將輪驅(qū)動及超聲波組件的BluetoothClient屬性設定為BluetoothClient1,因此AddressesAndNames屬性列表中的設備會自動限定為這類機器人,其他類型的藍牙設備(如耳機)將不會出現(xiàn)在列表中。表12-3列出了所需要的塊。
表12-3 在應用中添加ListPicker列表所需要的塊
塊的類型 | 所在抽屜 | 作用 |
---|---|---|
ConnectListPicker.BeforePicking | ConnectListPicker | 當ConnectListPicker被點擊時,觸發(fā)該事件 |
set ConnectListPicker.Elements to | ConnectListPicker | 為ConnectListPicker設置可供選擇的列表項 |
點擊ConnectListPicker將觸發(fā)ConnectListPicker.BeforePicking事件,并顯示可選項列表。將ConnectListPicker.Elements屬性設置為 BluetoothClient1.AddressesAndNames塊,來設定可選項;ConnectListPicker將顯示已經(jīng)與Android設備配對的機器人列表。
圖 12-3 顯示機器人列表
測試:在手機上點擊“連接”,看看會發(fā)生什么,你會看到所有已經(jīng)與手機配對的機器人列表。
如果只見黑屏,說明手機尚未與任何機器人配對;如果見到其他藍牙設備,如藍牙耳機,說明 NxtDrive1與 NxtUltrasonicSensor1的BluetoothClient屬性設置有誤。
從列表中選擇一個機器人,應用將通過藍牙與機器人連接。如果連接成功,用戶界面將發(fā)生變化:隱藏ConnectListPicker,并顯示用戶界面的其余部分。如果機器人開關(guān)沒有打開,則連接失敗,會彈出錯誤信息。
使用call BluetoothClient1.Connect塊與機器人進行連接。ConnectListPicker.Selection屬性提供了選中機器人的地址和名稱信息。
使用ifelse塊來測試連接是否成功。ifelse塊需要連接三個不同的塊:“if”、“then”及“else”。“if”與BluetoothClient1.Connect塊連接,“then”區(qū)域放置連接成功時要執(zhí)行的塊;“else”區(qū)域放置連接失敗時要執(zhí)行的塊。
如果連接成功,使用Visible屬性來隱藏 ConnectListPicker并顯示VerticalArrangement1(其中放置了除ConnectListPicker之外的所有組件)。如果連接失敗,則使用Notifier1.ShowAlert塊來顯示錯誤信息。表12-4列出了設置上述行為所需的塊。
表12-4與機器人建立藍牙連接所需的塊
塊的類型 | 所在抽屜 | 作用 |
---|---|---|
ConnectListPicker.AfterPicking | ConnectListPicker | 當從ConnectListPicker選中一個機器人時觸發(fā) |
ifelse | Control | 檢驗藍牙連接是否成功 |
call BluetoothClient1.Connect | BluetoothClient1 | 連接到機器人 |
ConnectListPicker.Selection | ConnectListPicker | 選中的機器人的地址及名稱 |
set ConnectListPicker.Visible to | ConnectListPicker | 隱藏ConnectListPicker按鈕 |
false | Logic | 插入set ConnectListPicker.Visible to塊 |
set VerticalArrangement1.Visible to | VerticalArrangement | 顯示“連接”按鈕之外的所有組件 |
true | Logic | 插入set VerticalArrangement1.Visible to塊 |
Notifier1.ShowAlert | Notifier1 | 用來彈出錯誤信息 |
“無法建立藍牙連接?!?/td> | Text | 錯誤信息。 |
選中機器人后將觸發(fā)ConnectListPicker.AfterPicking事件,見圖12-4,BluetoothClient1.Connect塊用于建立與機器人之間的藍牙連接。如果連接成功,執(zhí)行“then”塊:隱藏ConnectListPicker按鈕并顯示VerticalArrangement1內(nèi)的所有組件,即,設置ConnectListPicker.Visible屬性為false,設置VerticalArrangement1.Visible屬性為true。如果連接失敗,執(zhí)行“else”塊:用Notifier1.ShowAlert塊彈出錯誤信息。
圖 12-4 建立藍牙連接
讓Android設備與NXT機器人連接著實讓人興奮,不過“斷開連接”是我們下面要添加的行為,這樣便于對連接與斷開進行連續(xù)測試。
當點擊DisconnectButton時,應用將關(guān)閉藍牙連接,用戶界面將發(fā)生變化:ConnectListPicker按鈕將重新出現(xiàn),而用戶界面上的其余組件將被隱藏。
表12-5列出了構(gòu)建BluetoothClient1.Disconnect(斷開藍牙連接)所需的塊。設置Visible屬性來顯示 ConnectListPicker按鈕并隱藏VerticalArrangement1中包含的所有組件。
表12-5 與機器人斷開連接所需的塊
塊的類型 | 所在抽屜 | 作用 |
---|---|---|
DisconnectButton.Click | DisconnectButton | 當點擊DisconnectButton時觸發(fā)該事件 |
BluetoothClient1.Disconnect | BluetoothClient1 | 斷開與機器人的藍牙連接 |
set ConnectListPicker.Visible to | ConnectListPicker | 顯示ConnectListPicker(“連接”按鈕) |
true | Logic | 插入set ConnectListPicker.Visible to塊 |
set VerticalArrangement1.Visible to | VerticalArrangement | 隱藏用戶界面上的其余組件 |
false | Logic | 插入set VerticalArrangement1.Visible to |
點擊DisconnectButton將觸發(fā)DisconnectButton.Clicked事件,如圖12-5所示,斷開藍牙連接要用BluetoothClient1.Disconnect塊,之后設置ConnectListPicker.Visible屬性為true來顯示 ConnectListPicker,設置VerticalArrangement1.Visible屬性為false來隱藏VerticalArrangement1。
圖 12-5 與機器人斷開連接
測試:請確保機器人已經(jīng)打開,點擊手機上的“連接”按鈕,并選擇要連接的機器人。建立藍牙連接需要一點時間。一旦連接成功,用戶界面將顯示機器人的控制按鈕,以及“斷開連接”按鈕。
單擊“斷開連接”按鈕:控制機器人的按鈕會消失,“連接”按鈕則重新出現(xiàn)。
下面是真正有趣的部分:添加前進、后退、左右轉(zhuǎn)動及停止行為。不要忘記“停止”,否則你手中的機器人會失去控制!
NxtDrive組件提供了五個塊,用來驅(qū)動機器人的電機:
MoveForwardIndefinitely塊:驅(qū)動兩個電機前進;
MoveBackwardIndefinitely塊:驅(qū)動兩個電機后退;
TurnCounterClockwiseIndefinitely塊:驅(qū)動機器人左轉(zhuǎn):讓右側(cè)電機向前而左側(cè)電機后退;
TurnClockwiseIndefinitely塊:驅(qū)動機器人右轉(zhuǎn):讓左側(cè)電機向前而右側(cè)電機后退;
每個移動及轉(zhuǎn)向塊都有一個Power參數(shù),需要與數(shù)字塊配合使用,來設定機器人電機的輸出功率,取值范圍可以從 0到100。但如果設置的功率太小,電機會發(fā)出吱吱聲而不運轉(zhuǎn)。在本例中建議使用90(百分比)。表12-6中列出了所需的塊。
表12-6 用于控制機器人的塊
塊的類型 | 所在抽屜 | 作用 |
---|---|---|
ForwardButton.Clic | ForwardButton | 點擊ForwardButton時觸 |
NxtDrive1.MoveForwardIndefinitely | NxtDrive1 | 驅(qū)動機器人前進 |
數(shù)字90 | Math | 功率值 |
BackwardButton.Click | BackwardButton | 點擊BackwardButton時觸發(fā) |
NxtDrive1.MoveBackwardIndefinitely | NxtDrive1 | 驅(qū)動機器人后退 |
數(shù)字90 | Math | 功率值 |
LeftButton.Click | LeftButton | 點擊LeftButton時觸發(fā) |
NxtDrive1.TurnCounterClockwiseIndefinitely | NxtDrive1 | 驅(qū)動機器人逆時針轉(zhuǎn)動 |
數(shù)字90 | Math | 功率值 |
RightButton.Click | RightButton | 點擊RightButton時觸發(fā) |
NxtDrive1.TurnClockwiseIndefinitely | NxtDrive1 | 驅(qū)動機器人順時針轉(zhuǎn)動 |
數(shù)字90 | Math | 功率值 |
StopButton.Click | StopButton | 點擊StopButton時觸發(fā) |
NxtDrive1.Stop | NxtDrive1 | 讓機器人停止 |
如圖12-6所示,點擊ForwardButton按鈕時觸發(fā)ForwardButton.Clicked事件,此時調(diào)用NxtDrive1.MoveForwardIndefinitely塊,讓機器人以90%的功率前進,其余按鈕的事件處理程序與此類似,并以相同的功率驅(qū)動機器人后退及左右轉(zhuǎn)動。點擊StopButton時觸發(fā)StopButton.Clicked事件,調(diào)用NxtDrive1.Stop塊讓機器人停止運動。
圖 12-6 操控機器人
更多建議: