<!-- .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/rJkLXBcPK#)
###### <kbd>ESC</kbd> 鍵進入總覽模式
###### <kbd>←</kbd> <kbd>↑</kbd> <kbd>↓</kbd> <kbd>→</kbd> 切換頁面
---
<center><img src="https://i.imgur.com/TP2HAi8.jpg" width=60%></img></center>
***我沒醉!我還可以喝啦!不信我走直線給你看!***
以上是人在喝醉的時候最常講的幹話,由於酒精會使人失去正常的平衡感及精神渙散,酒駕基本上跟閉上眼睛開車一樣非常危險,而一台==沒有眼睛的自走車==就跟==酒駕==一樣,會到處撞東撞西,所以我們把眼睛裝上去吧!
---
## 目標
**設置好直線車道後,將自走車放置在靠左或靠右的起點出發,利用自走車上的四個==超音波感測器==,讓車子保持在車道的==中央==移動,並在終點觸碰牆壁前停下。**
---
## 設計原理
- 將自走車放在車道中,確認左右==兩側==超音波數值==大於0==,在行走時不斷==判斷左右的差值==,當超過設定的範圍時,將車子向數值大的一方移動。
- ==前方==判斷==大於0==且==小於==設定範圍時停止移動。
- 這裡的超音波感測器預設為==超過40cm以上的距離不做判斷==,所以當感測器數值顯示0時有==兩種==情況,==大於4000(40cm)==或==小於200(2cm)==。
----
:::info
:globe_with_meridians: 參考資源
- [HC-SR04 超音波感測器介紹](http://coopermaa2nd.blogspot.com/2012/09/hc-sr04.html)
- [HC-SR04 DataSheet](https://cdn.sparkfun.com/datasheets/Sensors/Proximity/HCSR04.pdf)
:::
---
## 車道配置圖
<center><img src="https://i.imgur.com/8rfVn1W.png" width=70%></img></center>
---
## 範例程式碼
新增程式檔並命名==車道置中移動==,將以下程式碼複製貼上程式編輯區執行。
```javascript=
let pingF = DATA.pingF;
let pingB = DATA.pingB;
let pingL = DATA.pingL;
let pingR = DATA.pingR;
let range = 300;
let speed = 30;
if(pingF > 0 &&pingF < 1000)
{
speed = 20;
}
else
{
speed = 30;
}
if(pingF > 0 && pingF < 800)
{
move_stop.set();
}
else if(pingL == 0)
{
move_left.set(speed);
}
else if(pingR == 0)
{
move_right.set(speed);
}
else if((pingL -pingR) > range || pingL == 0)
{
move_left.set(speed);
}
else if((pingR - pingL) > range || pingR == 0)
{
move_right.set(speed);
}
else if(Math.abs(pingL - pingR) < range && pingL > 0 && pingR > 0)
{
move_forward.set(speed);
}
```
---
## 程式解說
逐行講解程式意義。
----
```javascript=
let pingF = DATA.pingF;
let pingB = DATA.pingB;
let pingL = DATA.pingL;
let pingR = DATA.pingR;
```
- 定義區域變數,==pingF==、==pingB==、==pingL==、==pingR==分別代表==前==、==後==、==左==、==右==方的超音波感測資料。
----
```javascript=
let range = 200;
let speed = 30;
```
- 定義超音波感測器容許範圍值(2cm)與初始速度。
----
```javascript=
if(pingF > 0 && pingF < 1000)
{
speed = 20;
}
else
{
speed = 30;
}
```
- 當距離==前方大於0cm且小於10cm==時,將移動速度調慢。
- 上述條件皆不成立時,將速度恢復正常。
----
```javascript=
if(pingF > 0 && pingF < 800)
{
move_stop.set();
}
```
- 當==前大於0且小於8cm==時,控制車子==停止==移動。
----
```javascript=
else if(pingL == 0)
{
move_left.set(speed);
}
else if(pingR == 0)
{
move_right.set(speed);
}
```
- 前項不成立時,當==左等於0==時,判斷為距離過遠,向左移動靠近牆壁。
- 前項不成立時,當==右等於0==時,判斷為距離過遠,向右移動靠近牆壁。
----
```javascript=
else if((pingL - pingR) > range || pingL == 0)
{
move_left.set(speed);
}
```
- 前項不成立時,當==左減去右==的值==大於==範圍值時,控制車子==向左==移動。
----
```javascript=
else if((pingR - pingL) > range || pingR == 0)
{
move_right.set(speed);
}
```
- 前項不成立時,當==右減去左==的值==大於==範圍值時,控制車子==向右==移動。
----
```javascript=
else if(Math.abs(pingL - pingR) < range && pingL > 0 && pingR > 0)
{
move_forward.set(speed);
}
```
- 前項不成立時,當==左與右的差==值(取絕對值)==小於==範圍值 且 左與右皆大於0時,控制車子==向前==移動。
---
## 參數修改
為方便實作,以下會將範例程式中可修改的參數標示出來,進行實作時只需修改對應參數,並觀察結果即可。
:::warning
:zap: 詳細內建JS參數參考 - [內建Js參數及功能總覽](/wlfjvQBzRPCmJ8LCL3f2Fg)
:::
----
:::success
**let range = ==x==**
:::
- x可代入 200 ~ 300,表示 2 ~ 3公分的誤差範圍值。
----
:::success
**let speed = ==x==**
:::
- x可代入 30 ~ 50,表示車子的預設速度,速度過快會使感測器來不及反應。
---
## 範例影片
{%youtube m2NSNcFIcCs %}
<a class="btn btn-warning" style="width:100%;color:#333333;" href="/s/d1hp6YXwTRuI71wx2ogw_g" role="button"> 水平移動避障 **⇨** </a>
<a class="btn btn-primary" style="width:100%;" href="/s/J2S3MJ-vS5KM-0VFDUZDEA" role="button"> **⇦** 指定顏色區域停車
</a>
{"metaMigratedAt":"2023-06-16T14:19:54.492Z","metaMigratedFrom":"YAML","title":"我沒醉!不然我走直線給你看! - 車道置中移動","breaks":true,"slideOptions":"{\"transition\":\"slide\",\"transitionSpeed\":\"fast\",\"theme\":\"league\"}","contributors":"[{\"id\":\"a1db0c29-d848-4070-be84-9191a2398ca8\",\"add\":5438,\"del\":1543}]"}