--- title: 路邊停車救星 - 自動停車系統 slideOptions: transition: slide transitionSpeed: 'fast' theme: league --- <!-- .slide: data-background="https://i.imgur.com/gJLfldF.jpg" data-background-color="#111111" data-background-opacity="0.2" --> ###### tags: `iot-car` `lab` 返回[物聯網智慧自走車](/s/5c7ggGf0Spqql5Gy31Cqzg) ## 路邊停車救星 <br> <span style="color:#F9BF45;">自動停車系統</span> ###### [點我開啟簡報模式](/@BEExANT-ta/B1KHGr5wK#) ###### <kbd>ESC</kbd> 鍵進入總覽模式 ###### <kbd>&#8592;</kbd> <kbd>&#8593;</kbd> <kbd>&#8595;</kbd> <kbd>&#8594;</kbd> 切換頁面 --- <center><img src="https://i.imgur.com/Bt76C3t.png" width=30%></img></center> 在入門的實作中,我們已熟悉如何透過顏色尋找指定車格,以及判斷超音波的距離來進行避障移動,這個單元將結合顏色感測及超音波感測,設計一套自動停車系統。 --- ## 目標 **在任意車格上擺放障礙物,自走車需停在未擺放障礙物的車格上,若皆有障礙物則在碰到邊界時停止,可依據情境改變障礙物放置方式。** --- ## 設計原理 - 當感測到車格時,依據方向上的超音波距離作為判斷是否進入的條件。 - (延伸思考)若行經在車道上遇障礙物,該如何避開障礙物回到車道上繼續尋找車格呢? --- ## 範例程式碼 新增程式檔並命名 ==自動停車系統==,將以下程式碼複製貼上程式編輯區執行。 ```javascript= window.state = "初始化"; window.color_record = ""; let park = ["綠","紅","藍","黃"]; let F = DATA.colorF[3]; let B = DATA.colorB[3]; let L = DATA.colorL[3]; let R = DATA.colorR[3]; let pingF = DATA.pingF; let pingB = DATA.pingB; let pingL = DATA.pingL; let pingR = DATA.pingR; let speed = 30; if(F == "紫" || B == "紫" || L == "紫" || R == "紫") { state = "觸碰邊界"; move_stop.set(); delay(300); led_color.set("紫"); } if(F == "黑" && B == "黑" && L == "黑" && R == "黑") { state = "車格探索"; move_forward.set(speed); delay(300); led_color.set("白"); } if(L == "白" && R == "黑" && state == "車格探索" ) { console.log("車身向左偏移,向右校正"); move_right.set(speed); } if(L == "黑" && R == "白" && state == "車格探索" ) { console.log("車身向右偏移,向左校正"); move_left.set(speed); } if(R == "黑" && park.includes(L) && state == "車格探索" && (pingL == 0 || pingL > 2000)) { state = "進入車格"; color_record = L; move_stop.set(); delay(300); led_color.set(L); delay(300); move_left.set(speed); } if(L =="黑" && park.includes(R) && state == "車格探索" && (pingR == 0 || pingR > 2000)) { state = "進入車格"; color_record = R; move_stop.set(); delay(300); led_color.set(R); delay(300); move_right.set(speed); } if(F == color_record && B == color_record && L == color_record && R == color_record && state == "進入車格") { state = "停車完畢"; move_stop.set(); delay(300); led_color.set("黑"); } console.log(state); console.log("顏色 - "+"前:"+F+",後:"+B+",左:"+L+",右:"+R); console.log("超音波 - "+"前:"+pingF+",後:"+pingB+",左:"+pingL+",右:"+pingR); ``` --- ## 程式解說 逐行講解程式意義。 ---- ```javascript= window.state = "初始化"; window.color_record = ""; ``` - 定義全域變數state,作為車子==目前狀態的記錄==,一開始設為 "初始化"。 - 定義全域變數color_record,作為記錄==進入中的車格顏色==。 ---- ```javascript= let park = ["綠","紅","藍","黃"]; ``` - 定義區域變數park,以陣列儲存==可停車的車格顏色==。 ---- ```javascript= let F = DATA.colorF[3]; let B = DATA.colorB[3]; let L = DATA.colorL[3]; let R = DATA.colorR[3]; let pingF = DATA.pingF; let pingB = DATA.pingB; let pingL = DATA.pingL; let pingR = DATA.pingR; let speed = 30; ``` - 定義區域變數==F==、==B==、==L==、==R==,分別設定為==四個方向顏色==的值。 - 定義區域變數==pingF==、==pingB==、==pingL==、==pingR==,分別代表==前==、==後==、==左==、==右==方的超音波感測資料。 - 定義區域變數speed,為車子的移動速度。 ---- ```javascript= if(F == "紫" || B == "紫" || L == "紫" || R == "紫") { state = "觸碰邊界"; move_stop.set(); delay(300); led_color.set("紫"); } ``` - 當四個方向顏色==其中一個紫色時==,將狀態state設為觸碰邊界,控制車子停止,並把車上的led燈設為紫色。 ---- ```javascript= if(F == "黑" && B == "黑" && L == "黑" && R == "黑") { state = "車格探索"; move_forward.set(speed); delay(300); led_color.set("白"); } ``` - 當四個方向顏色==皆為黑色==時,將狀態state設為車格探索,控制車子向前移動,並把車上的led燈設為白色。 ---- ```javascript= if(L == "白" && R == "黑" && state == "車格探索" ) { console.log("車身向左偏移,向右校正"); move_right.set(speed); } if(L == "黑" && R == "白" && state == "車格探索" ) { console.log("車身向右偏移,向左校正"); move_left.set(speed); } ``` - 當state為車格探索,且左或右邊的顏色為一黑一白時,表示偏離車道,控制車子往顏色為黑色的方向移動。 ---- ```javascript= if(R == "黑" && park.includes(L) && state == "車格探索" && (pingL == 0 || pingL > 2000)) { state = "進入車格"; color_record = L; move_stop.set(); delay(300); led_color.set(L); delay(300); move_left.set(speed); } if(L =="黑" && park.includes(R) && state == "車格探索" && (pingR == 0 || pingR > 2000)) { state = "進入車格"; color_record = R; move_stop.set(); delay(300); led_color.set(R); delay(300); move_right.set(speed); } ``` - 當左或右方的顏色感測有==包含park內所定義的顏色==且==另一方為黑色==,state為車格探索且==非黑色方向==的==超音波感測為0或大於2000==時(表示障礙物至少距離20公分以上),將狀態state設為進入車格,顏色記錄color_record設為車格的顏色,讓車子停止一下後設定車上led顏色為車格的顏色,再往對應方向移動進去。 ---- ```javascript= if(F == color_record && B == color_record && L == color_record && R == color_record && state == "進入車格") { state = "停車完畢"; move_stop.set(); delay(300); led_color.set("黑"); } ``` - 當感測到的四個方向顏色皆等於記錄的顏色且state為進入車格時,表示完成停車,將state設為停車完畢,控制車子停止移動,led顏色設為黑色(關閉)。 ---- ```javascript= console.log(state); console.log("顏色 - "+"前:"+F+",後:"+B+",左:"+L+",右:"+R); console.log("超音波 - "+"前:"+pingF+",後:"+pingB+",左:"+pingL+",右:"+pingR); ``` - 在訊息區顯示目前state的值,四個方向的顏色及超音波值。 --- ## 參數修改 為方便實作,以下會將範例程式中可修改的參數標示出來,進行實作時只需修改對應參數,並觀察結果即可。 :::warning :zap: 詳細內建JS參數參考 - [內建Js參數及功能總覽](/s/wlfjvQBzRPCmJ8LCL3f2Fg) ::: ---- :::success **let park = ["綠","紅","藍","黃"];** ::: - []內的字串表示自走車可以停車的顏色,假設只有綠與紅,那自走車經過藍色或黃色的車格時皆不會停車。 --- ## 範例影片 {%youtube d-j8v9ZgLOo %} <a class="btn btn-warning" style="width:100%;color:#333333;" href="/s/LuB5QmlVSrGBPZWmfeRq9Q" role="button"> 自動化搬運系統 **&#8680;** </a> <a class="btn btn-primary" style="width:100%;" href="/s/s2K5DrGBTXmf8fdqP0l8Hg" role="button"> **&#8678;** 遠程手臂控制 </a>