---
# System prepended metadata

title: 我沒醉！不然我走直線給你看！ - 車道置中移動
tags: [lab, iot-car]

---

---
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/rJkLXBcPK#)

###### <kbd>ESC</kbd> 鍵進入總覽模式

###### <kbd>&#8592;</kbd> <kbd>&#8593;</kbd> <kbd>&#8595;</kbd> <kbd>&#8594;</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"> 水平移動避障 **&#8680;**  </a>

<a class="btn btn-primary" style="width:100%;"  href="/s/J2S3MJ-vS5KM-0VFDUZDEA" role="button"> **&#8678;** 指定顏色區域停車
</a>