Loop Block迴圈命令方塊
探奇曾經在舊文章中討論NXT-G軟體的Loop Block迴圈命令方塊,這個命令方塊有五種模式,分別是Forever,Sensor,Time,Count,以及Logic。
利用這五種模式,Loop Block可以依據不同的條件跳出迴圈,也就是停止重複執行。
一般來說,程式依照順序執行,滿足條件後,跳出迴圈,執行後續的程式。
如果這個條件由其他多工程序控制,又該如何通知Loop Block迴圈命令方塊停止這項任務呢?
例如:一台攤販車,同時進行「前進轉彎行動」,以及「音樂撥放」兩項工作,當車子到達目的地後,車輛停止,音樂也應該停止撥放。
你要如何撰寫這個程式?
EV3軟體的新命令 – Loop Interrupt
在EV3軟體中有個新的命令方塊,Loop Interrupt,執行這個命令時,可以中斷特定的迴圈(迴圈可以設定特定的名稱)。如此一來,就能在多工程式中控制另一個分支程式。
讓我們看看下圖:
上圖的EV3程式有兩個多工程式,一個執行「前進轉彎行動」,一個執行「音樂播放」。前進轉彎行動只重複執行四次,當迴圈執行四次後,有個中斷迴圈命令方塊,這個命令方塊會對名稱為「music」的迴圈發出中斷訊息,跳出迴圈,執行後續的命令,發出Goodbye的聲音。
實際執行程式時,我們會發現,不論music迴圈內的程式執行到何處(任何一個命令) ,也不管各個命令是否執行完畢,都會立即中斷。例如當music迴圈執行到第二個E5的命令,發出Mi的聲音0.3秒,迴圈依然立即中斷。
這個迴圈中斷命令除了中斷其他迴圈,也能夠中斷自身所在的迴圈,是不是很方便呢?
NXT-G模擬迴圈中斷
在NXT-G中,雖然沒有迴圈中斷的命令,我們也可以想辦法解決這類問題。
沒錯,就是變數,Variable。我在這裡將這個變數稱為旗標。像是童軍或海軍的旗語,也像是遠方通訊用的狼煙、烽火台。
請看下圖:
扮演旗標角色就是變數Logic 1。上方程式中,重複四次「Move直行5圈,Move轉彎3圈」,將邏輯值True寫入變數Logic 1,當下方程式的迴圈判斷Logic 1的值為True時,就結束迴圈,執行最後面的Goodbye聲音命令。
在NXT-G中,變數都是全域變數,所以利用這個方式,我們可以很容易控制程式中所有迴圈,包含My
Block裡面的迴圈。
想一想:改良迴圈中斷
雖然我們利用變數中斷迴圈的執行,但是這種方式並沒有辦法達到立即中斷的效果。
當Loop Block執行所有迴圈內的命令之後,才會檢查變數Logic 1的狀態,這個音樂撥放迴圈中有三個發聲1秒的命令,也就是每3 秒鐘才會判斷Logic
1的邏輯值,於是我們觀察機器人動作時,會發現機器人已經停止一段時間,三個音樂命令完整撥放後才會發出Goodbye聲音。
我們需要縮短反應時間,有一種改良方式如下圖:
你想到了嗎?將音樂播放回中的命令放入Switch Block中,同樣以變數Logic 1作判別,如果變數邏輯值為「False」,表示迴圈尚未結束,Switch Block執行原來的聲音命令方塊;如果變數的邏輯值為「True」,所有Switch Block都不須執行命令,Loop Block迴圈迅速跳至最後的邏輯判別,確認為真,跳出迴圈,執行接下來的聲音命令,發出Goodbye。
這種改良型的迴圈中斷方式應該可以讓迴圈中斷的反應時間縮短至1秒鐘。不過程式寫法比較麻煩,我稱之為「人工苦力中斷」 ^^,將來還可以放入My Block,程式會比較簡潔易讀。
辛苦收穫
今天討論使用「人工苦力中斷」模擬EV3的Loop Interrupt。雖然NXT-G沒有可用的迴圈中斷指令,不過模擬的過程也讓我們瞭解一件事,其實中斷也就是一直不斷監視變數狀況,隨時處理反應。
你還想到那些應用呢?歡迎分享!
沒有留言:
張貼留言
探奇歡迎大家留言討論!謝謝分享你的意見。