<!-- .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/HkpE0TeuF#)
###### <kbd>ESC</kbd> 鍵進入總覽模式
###### <kbd>←</kbd> <kbd>↑</kbd> <kbd>↓</kbd> <kbd>→</kbd> 切換頁面
---
<center><img src="https://i.imgur.com/jeZY2OW.jpg" width=50%></img></center>
在==自動化==的環境中,通常會制定==固定的範圍與邊界==,使其中的設備能在固定的環境下運行,==減少外在因素==的同時也能==提高效率與容錯率==,如同動漫與電影中常有角色的能力是創造一個有利自己的固有空間,使自己的能力大幅增加。
---
## 目標
**使自走車隨機移動,在碰到邊界顏色時往反方向移動,讓車子保持在關卡圖內移動。**
---
## 設計原理
- 設定亂數範圍隨機抽選移動方式及速度控制自走車。
- 前後左右四個顏色感測器任一個判斷到邊界的顏色時,控制自走車往判斷的反方向移動。
----
:::info
:globe_with_meridians: 參考資源
- [JavaScript Random](https://www.w3schools.com/js/js_random.asp)
- [用Math.random()取得某區間內的隨機亂數](https://ithelp.ithome.com.tw/articles/10197920)
:::
---
## 範例程式碼
新增程式檔並命名 ==場地邊界判定==,將以下程式碼複製貼上程式編輯區執行。
```javascript=
function getRandom(min,max){
return Math.floor(Math.random()*(max-min+1))+min;
}
window.count = 0;
let border = "紫";
let randomMove = getRandom(0,5);
let randomSpeed = getRandom(30,50);
let move = [move_forward.set,move_backward.set,move_left.set,move_right.set,move_Lturn.set,move_Rturn.set];
if(DATA.colorF[3] === border)
{
console.log("前方碰觸邊界");
led_color.set("#FF0000");
delay(300);
move_stop.set();
delay(500);
move_backward.set(50);
delay(500);
count = 1500;
}
else if(DATA.colorB[3] === border)
{
console.log("後方碰觸邊界");
led_color.set("#FF0000");
delay(300);
move_stop.set();
delay(500);
move_forward.set(50);
delay(500);
count = 1500;
}
else if(DATA.colorL[3] === border)
{
console.log("左方碰觸邊界");
led_color.set("#FF0000");
delay(300);
move_stop.set();
delay(500);
move_right.set(50);
delay(500);
count = 1500;
}
else if(DATA.colorR[3] === border)
{
console.log("右方碰觸邊界");
led_color.set("#FF0000");
delay(300);
move_stop.set();
delay(500);
move_left.set(50);
delay(500);
count = 1500;
}
if(count >= 1500)
{
console.log("隨意移動");
count = 0;
led_color.set("#00FF00");
delay(300);
move[randomMove](randomSpeed);
}
count += 300;
```
---
## 程式解說
逐行講解程式意義。
----
```javascript=
function getRandom(min,max){
return Math.floor(Math.random()*(max-min+1))+min;
}
```
- 定義取得亂數值函式,給予最小及最大值,函式隨機返回在這範圍內的整數。
----
```javascript=3
window.count = 0;
```
- 定義全域變數count,作為計數器數值。
----
```javascript=15
let border = "紫";
let randomMove = getRandom(0,5);
let randomSpeed = getRandom(30,50);
```
- 定義區域變數border,設定為邊界顏色的值。
- 定義區域變數randomMove,每次迴圈開始時隨機取得 ==0 ~ 5== 的整數,作為==挑選自走車動作==的數值。
- 定義區域變數randomSpeed,每次迴圈開始時隨機取得 ==30 ~ 50== 的整數,作為自走車隨機==移動時的速度==。
----
```javascript=
let move = [move_forward.set,move_backward.set,move_left.set,move_right.set,move_Lturn.set,move_Rturn.set];
```
- 定義move陣列物件,設定6種自走車動作的函式,例:使用 ==```move[0](50);```== 會等於使用 ==```move_forward.set(50);```== ,意思是呼叫move陣列中第一個函式 ==```move_forward.set```==,並設定數值為50。
----
```javascript=
if(DATA.colorF[3] === border)
{
console.log("前方碰觸邊界");
led_color.set("#FF0000");
delay(300);
move_stop.set();
delay(500);
move_backward.set(100);
delay(500);
count = 1500;
}
else if(DATA.colorB[3] === border)
{
console.log("後方碰觸邊界");
led_color.set("#FF0000");
delay(300);
move_stop.set();
delay(500);
move_forward.set(100);
delay(500);
count = 1500;
}
else if(DATA.colorL[3] === border)
{
console.log("左方碰觸邊界");
led_color.set("#FF0000");
delay(300);
move_stop.set();
delay(500);
move_right.set(100);
delay(500);
count = 1500;
}
else if(DATA.colorR[3] === border)
{
console.log("右方碰觸邊界");
led_color.set("#FF0000");
delay(300);
move_stop.set();
delay(500);
move_left.set(100);
delay(500);
count = 1500;
}
```
- 每個方向的顏色皆做判斷,當==顏色與邊界顏色相同==時,將自走車上的==led燈設為紅色==,並暫停0.5秒,再朝==反方向移動==0.5秒,最後將==計數器值設為15000==(1.5秒),使下一步==直接觸發隨機移動==。
----
```javascript=
if(count >= 1500)
{
console.log("隨意移動");
count = 0;
led_color.set("#00FF00");
delay(300)
move[randomMove](randomSpeed);
}
count += 300;
```
- 當計數器值為1500時,將計數器歸零,led設為綠色,並進行隨機移動。
- 由於每次迴圈間隔為300毫秒,使用 ==```count += 300;```== 表示每次迴圈會增加計數器300的值。
---
## 參數修改
為方便實作,以下會將範例程式中可修改的參數標示出來,進行實作時只需修改對應參數,並觀察結果即可。
:::warning
:zap: 詳細內建JS參數參考 - [內建Js參數及功能總覽](/s/wlfjvQBzRPCmJ8LCL3f2Fg)
:::
----
:::success
**let randomMove = getRandom(==x==,==y==);**
:::
- 依據move陣列裡的元素數量進行設定,代表隨機挑出的動作編號,例:move裡有4個元素,x與y必須在0~3之間
----
:::success
**let randomSpeed = getRandom(==x==,==y==);**
:::
- x與y可代入30~100,表示隨機抽選的速度值,速度過快容易造成判斷失誤,需根據情況調整速度範圍。
----
:::success
**let move = [==1==,==2==...];**
:::
- 在move陣列中可存放自走車移動函式,可將1,2帶入 ==```move_forward.set```== 這種格式的函式,並以 ==```move[x](y);```== 的格式呼叫陣列中的函式,x表示函式在陣列中的編號,y表示速度。
---
## 範例影片
{%youtube xdNn30TOJjA %}
<a class="btn btn-warning" style="width:100%;color:#333333;" href="/s/J2S3MJ-vS5KM-0VFDUZDEA" role="button"> 指定顏色區域停車 **⇨** </a>
<a class="btn btn-primary" style="width:100%;" href="/s/29-IaRauQSu8SVPubviBhw" role="button"> **⇦** 手動與程式控制
</a>
{"metaMigratedAt":"2023-06-16T14:38:14.935Z","metaMigratedFrom":"YAML","title":"領域展開! - 場地邊界判定","breaks":true,"slideOptions":"{\"transition\":\"slide\",\"transitionSpeed\":\"fast\",\"theme\":\"league\"}","contributors":"[{\"id\":\"a1db0c29-d848-4070-be84-9191a2398ca8\",\"add\":9829,\"del\":4508}]"}