Raspberry Pi Smart Car
มาใช้ Raspberry pi ทำให้รถคุณพิเศษมากขึ้นไปอีก กันเถอะ !
อุปกรณ์มีดังนี้
- Raspberry pi 3 รุ่น B
- Raspberry Pi Touch Display
- Raspberry Pi camera
- สายเคเบิล Adafruit Flex สำหรับกล้อง Raspberry Pi หรือจอแสดงผล - 2 เมตร
- Adafruit CSI หรือ DSI Cable Extender Thingy สำหรับ Raspberry Pi
แรงบันดาลใจ
ฉันชอบไอเดียของรถยนต์อัจฉริยะ แต่มันยากสำหรับฉันที่จะจัดซื้อรถยนต์คันใหม่ แต่นั่นไม่ได้หมายความว่าฉันไม่สามารถลองและทำให้มันฉลาดขึ้นได้ !
คำว่า "สมาร์ทคาร์" สามารถมีความหมายต่าง ๆ ได้หลายอย่าง ขึ้นอยู่กับว่าคุณถามใคร ดังนั้นเรามาเริ่มด้วยคำจำกัดความของสมาร์ทคาร์ของฉันกัน
· หน้าจอสัมผัส interafce
· กล้องสำรองที่ให้คุณรู้ว่าวัตถุนั้นอยู่ใกล้เกินไปหรือไม่
· ข้อมูลพื้นฐานเกี่ยวกับรถยนต์เช่นการประหยัดน้ำมัน
· การเชื่อมต่อบลูทูธ
ฉันไม่แน่ใจว่าของชิ้นไหนที่ฉันจะประสบความสำเร็จ แต่ฉันเดาว่าจะค้นพบ
การเพิ่มอุปกรณ์ภายใน สมาร์ทคาร์ ของเราคือกล้องสำรอง มีหลายชุดที่ทำให้การเพิ่มกล้องสำรองค่อนข้างง่าย เนื่องจากฉันแค่ต้องการทดสอบ การพิสูจน์แนวคิด ฉันไม่ต้องการเจาะ ไข ให้รถเสียหาย ฉันแค่กำลังเดินสายไฟเข้ากับแบตเตอรี่บางก้อน และฉันจะติดมันเข้ากับป้ายทะเบียนโดยใช้เทปพันท่อที่ไว้ใจได้!
ฉันวิ่งสาย RCA จากกล้องไปยังแดชบอร์ดและเชื่อมต่อกับจอ LCD 5 นิ้วของฉัน จอแอลซีดีเฉพาะนี้สามารถขับเคลื่อนผ่าน USB ได้ดังนั้นฉันจึงเสียบเข้ากับอะแดปเตอร์ที่เบากว่าของ USB (รถยนต์เก่าส่วนใหญ่มีอะแดปเตอร์ที่มีน้ำหนักเบากว่า)
หลังจากสตาร์ทรถหน้าจอก็เปิดขึ้นมาทันทีและฉันเห็นภาพจากกล้อง เป็นไปตามที่คาดการไว้! นี่จะเป็นทางออกที่ดีสำหรับทุกคนที่ต้องการเพิ่มกล้องสำรองลงในรถ
ใส่Raspberry pi Pi เป็นแพลตฟอร์มที่สมบูรณ์แบบสำหรับสมาร์ทคาร์เนื่องจากเป็นคอมพิวเตอร์ขนาดเล็กที่มีอินพุตและเอาต์พุต เมื่อเชื่อมต่อกล้องเข้ากับ Pi คุณสามารถใช้เว็บแคม USB ทั่วไปหรือใช้กล้องของ Raspberry pi ก็ได้ กล้องไม่ต้องการแหล่งพลังงานแยกต่างหาก แต่ให้แน่ใจว่าคุณมีสายเคเบิลมากพอที่จะไปที่ด้านหลังของรถ
ฉันเลือกใช้กล้อง Pi เพราะมีอัตราความเร็วสูงกว่ากล้อง USB อีกครั้งฉันเพียงแค่แปะกล้องในแผ่นป้ายทะเบียนวิ่งสายเคเบิลแบนไปที่ Pi ที่ด้านหน้าของรถแล้วเชื่อมต่อกับหน้าจอสัมผัสขนาด 7 นิ้วทั้ง Pi และหน้าจอสัมผัสสามารถขับเคลื่อนโดยอะแดปเตอร์ USB ในรถ.
เมื่อเปิดรถทั้ง Pi และหน้าจอก็เปิดขึ้น ข้อเสียอย่างหนึ่งที่เห็นได้ชัดคือเวลาบูตที่ต้องใช้สำหรับ Pi ในการบู๊ต ... บางสิ่งที่ฉันจะต้องพิจารณาในภายหลัง ในการดู Pi camera ฉันเปิดเทอร์มินัลและเรียกใช้สคริปต์อย่างง่าย (สคริปต์ที่สามารถตั้งค่าให้บูตอัตโนมัติในอนาคต)
raspivid -t 0
หรือ
raspivid -t 0 --mode 7
หลังจากกดปุ่มป้อนฟีดของกล้องวิดีโอก็โผล่ขึ้นมา! สิ่งที่ดีเกี่ยวกับวิดีโอบน Pi คือคุณสามารถวิเคราะห์และอาจตั้งค่าระบบการแจ้งเตือนหากวัตถุเข้าใกล้เกินไป! งั้นมาทำเรื่องต่อไปกันเถอะ!
การตรวจจับวัตถุ
วิธีที่ 1
เมื่อพูดถึงกล้องสำรองเชิงพาณิชย์มีสองรุ่นที่ฉันเคยเห็น ครั้งแรกใช้การซ้อนทับแบบสแตติกที่มีช่วงสีเพื่อให้คุณสามารถกำหนดได้ว่าวัตถุอยู่ใกล้แค่ไหน วิธีที่สองใช้กล้องร่วมกับเซ็นเซอร์บางชนิดที่สามารถรับรู้ได้ว่าวัตถุอยู่ใกล้กับรถมากน้อยเพียงใดแล้วแจ้งเตือนคุณเมื่อมีสิ่งใดใกล้เกินไป
เนื่องจากวิธีแรกดูเหมือนง่ายกว่าลองใช้วิธีแรกก่อน โดยพื้นฐานแล้วมันเป็นเพียงภาพซ้อนทับบนสตรีมวิดีโอดังนั้นเรามาดูกันว่าการสร้างใหม่นั้นง่ายอย่างที่คิดหรือไม่ สิ่งแรกที่เราต้องการคือภาพซ้อนทับโปร่งใส นี่คือสิ่งที่ฉันใช้ (พบในที่เก็บ github ของฉันด้วย):
ภาพด้านบนคือ 640x480 ซึ่งเกิดขึ้นกับความละเอียดเดียวกันกับที่กล้องของฉันจะสตรีมที่ สิ่งนี้ทำโดยเจตนา แต่อย่าลังเลที่จะเปลี่ยนขนาดภาพหากคุณสตรีมด้วยความละเอียดที่แตกต่างกัน
ต่อไปเราจะสร้างสคริปต์ไพธอน ที่ใช้โปรแกรมแก้ไขรูปภาพ PIL python และ PiCamera (หากคุณไม่ได้ใช้กล้อง Pi ให้ปรับรหัสสำหรับอินพุตวิดีโอของคุณ) ฉันเพิ่งตั้งชื่อไฟล์image_overlay.py
import picamera
from PIL import Image
from time import sleep
#Start a loop with the Pi camera
with picamera.PiCamera() as camera:
camera.resolution = (640, 480)
camera.framerate = 24
camera.start_preview()
img = Image.open('bg_overlay.png')
img_overlay = camera.add_overlay(img.tobytes(), size=img.size)
img_overlay.alpha = 128
img_overlay.layer = 3
while True:
sleep(1)
บันทึกและทดสอบด้วยการเรียกใช้ "python image_overlay.py" ฉันทดสอบในระดับน้อยโดยใช้รถของเล่นเพื่อดูว่ามันทำงานอย่างไร มันใช้งานได้อย่างมีเสน่ห์และไม่มีความล่าช้าเลย!
อย่างไรก็ตามสิ่งหนึ่งที่สำคัญมากที่ควรทราบคือคุณควรใช้ความระมัดระวังเป็นพิเศษในการปรับเทียบกล้องของคุณเพื่อให้แน่ใจว่าฐานของมุมมองวิดีโอนั้นใกล้กับกันชนในรถของคุณมากที่สุด อย่างที่คุณสามารถบอกได้จากภาพด้านล่างกล้องหันหน้าสูงเกินไปดังนั้นวัตถุทดสอบจึงอยู่ไกลเกินกว่าที่กล้องบอกฉัน
วิธีที่ 2
ฉันสามารถใช้OpenCV กับ python เป็น API คอมพิวเตอร์ของฉันได้ สิ่งนี้จะทำให้ฉันสามารถวิเคราะห์สิ่งที่อยู่ในภาพและตั้งค่าพารามิเตอร์สำหรับสิ่งที่พบ ดังนั้นความคิดก็คือถ่ายวิดีโอและตั้งขอบเขตที่ด้านล่าง (ใกล้กับกันชนรถยนต์) สำหรับ "โซนเตือนภัย" จากนั้นฉันจะให้มันตรวจจับวัตถุขนาดใหญ่ใด ๆ ก็ตามที่อยู่ในภาพ หากบริเวณด้านล่างสุดของวัตถุเข้าสู่ "โซนเตือนภัย" ก็ควรส่งข้อความเตือน
เพื่อทำหน้าที่เป็นเสียง alret ฉันจะต่อออดสัญญาณ Piezo กับ Raspberry Pi โดยเชื่อมต่อขาบวกกับขา 22 และขาลบกับขากราวด์
ก่อนที่จะเริ่มรหัสเราต้องติดตั้ง OpenCV บน Pi ก่อน โชคดีที่สามารถทำได้ ผ่านคำสั่ง "pip"
pip3
install opencv-python
เมื่อติดตั้ง OpenCV เราสามารถสร้างไฟล์ Python ใหม่และเริ่มต้นโค้ด สำหรับรหัสเอกสารครบถ้วนคุณสามารถเยี่ยมชมของฉันที่เก็บ GitHub ฉันเพิ่งตั้งชื่อไฟล์ว่าcar_detector.py
import time
import cv2
import numpy as np
from picamera.array import PiRGBArray
from picamera import PiCamera
import RPi.GPIO as GPIO
buzzer = 22
GPIO.setmode(GPIO.BCM)
GPIO.setup(buzzer, GPIO.OUT)
camera = PiCamera()
camera.resolution = (320, 240) #a smaller resolution means faster processing
camera.framerate = 24
rawCapture = PiRGBArray(camera, size=(320, 240))
kernel = np.ones((2,2),np.uint8)
time.sleep(0.1)
for still in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):
GPIO.output(buzzer, False)
image = still.array
#create a detection area
widthAlert = np.size(image, 1) #get width of image
heightAlert = np.size(image, 0) #get height of image
yAlert = (heightAlert/2) + 100 #determine y coordinates for area
cv2.line(image, (0,yAlert), (widthAlert,yAlert),(0,0,255),2) #draw a line to show area
lower = [1, 0, 20]
upper = [60, 40, 200]
lower = np.array(lower, dtype="uint8")
upper = np.array(upper, dtype="uint8")
#use the color range to create a mask for the image and apply it to the image
mask = cv2.inRange(image, lower, upper)
output = cv2.bitwise_and(image, image, mask=mask)
dilation = cv2.dilate(mask, kernel, iterations = 3)
closing = cv2.morphologyEx(dilation, cv2.MORPH_GRADIENT, kernel)
closing = cv2.morphologyEx(dilation, cv2.MORPH_CLOSE, kernel)
edge = cv2.Canny(closing, 175, 175)
contours, hierarchy = cv2.findContours(closing, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
threshold_area = 400
centres = []
if len(contours) !=0:
for x in contours:
#find the area of each contour
area = cv2.contourArea(x)
#find the center of each contour
moments = cv2.moments(x)
#weed out the contours that are less than our threshold
if area > threshold_area:
(x,y,w,h) = cv2.boundingRect(x)
centerX = (x+x+w)/2
centerY = (y+y+h)/2
cv2.circle(image,(centerX, centerY), 7, (255, 255, 255), -1)
if ((y+h) > yAlert):
cv2.putText(image, "ALERT!", (centerX -20, centerY -20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,255,255),2)
GPIO.output(buzzer, True)
cv2.imshow("Display", image)
rawCapture.truncate(0)
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
GPIO.output(buzzer, False)
break
เอาล่ะบันทึกและทดสอบในขนาดเล็กมันทำได้ค่อนข้างดี มันตรวจพบวัตถุที่ไม่จำเป็นจำนวนมากและฉันสังเกตว่าบางครั้งมันจะตรวจจับเงาเป็นวัตถุ
อัพโหลดขึ้นรถและทดสอบในสถานการณ์จริงผลลัพธ์ที่ได้นั้นแม่นยำอย่างน่าประหลาดใจ! มันอยู่ใกล้กับสภาพที่สมบูรณ์แบบอย่างไรก็ตาม ฉันไม่รู้ว่าผลลัพธ์จะแตกต่างกันอย่างไรถ้าเป็นตอนกลางคืน
โดยรวมแล้วฉันรู้สึกพอใจและประหลาดใจกับผลลัพธ์ที่ได้ จากวิธีการสองวิธี
วิธีที่ 2 ค่อนข้างเจ๋ง แต่วิธีที่ 1 น่าเชื่อถือกว่าในหลาย ๆ สถานการณ์ ดังนั้นถ้าคุณจะทำสิ่งนี้ให้กับรถของคุณฉันจะใช้วิธีที่ 1
ต่อไปฉันจะพยายามจัดการการเชื่อมต่อกับพอร์ต OBDII ของรถยนต์และดูว่าฉันสามารถแตกไฟล์ได้อย่างไร!
การเชื่อมต่อในคณะกรรมการวินิจฉัย (OBDII)
ในสหรัฐอเมริการถยนต์จำเป็นต้องมีพอร์ต On Board Diagnostics (OBDII) ตั้งแต่ปี 1996 ประเทศอื่น ๆ ใช้มาตรฐานเดียวกันในภายหลัง
พอร์ต OBDII ช่วยให้คุณสามารถเชื่อมต่อและอ่านข้อมูลเกี่ยวกับรถยนต์เช่นปัญหาหมายเลข VIN ความเร็ว RPM's และอื่น ๆ เมื่อใดก็ตามที่ไฟ "Check Engine" ของคุณปรากฏขึ้นมันเป็นสิ่งที่ช่างทำการเสียบเข้าไปและเข้าใจปัญหา
สิ่งแรกที่เราต้องทำคือเชื่อมต่ออะแดปเตอร์เข้ากับพอร์ตเพื่อให้เราสามารถสื่อสารกับ Raspberry Pi สำหรับผู้ที่ไม่ทราบว่าพอร์ต OBDII ตรงไหน ส่วนใหญ่อยู่ใต้แผงควบคุมใต้พวงมาลัยในรถยนต์ หากคุณค้นหา "ODBII อะแดปเตอร์" แบบออนไลน์คุณจะพบว่ามีอะแดปเตอร์สองประเภทหลักคือ USB และบลูทูธ อะแดปเตอร์ USB มีความปลอดภัยมากกว่า ถ้าคุณทราบถึงช่องโหว่ในบลูทูธ สำหรับโครงการนี้ฉันจะใช้บลูทูธ
เมื่อเชื่อมต่ออะแดปเตอร์บลูทูธ เข้ากับพอร์ตคุณอาจสังเกตเห็นว่ามีไฟส่องสว่างบนอะแดปเตอร์ทันที นี่เป็นเพราะพอร์ต OBD มีเอาต์พุต 12v เสมอ "บน" นั่นหมายถึงว่าอะแดปเตอร์บลูทูธ จะใช้พลังงานและเปิดใช้งานอยู่ตลอดเวลาแม้ว่าคุณจะไม่ได้อยู่ในรถ ... นี้คือช่องโหว่
ด้วยอะแดปเตอร์บลูทูธ ในสถานที่เราสามารถเชื่อมต่อ Pi ของเรากับมันได้ ฉันใช้ Raspberry Pi 3 B + ซึ่งมีบลูทู ธ อยู่แล้วดังนั้นฉันไม่ต้องการอะแดปเตอร์อื่น เพียงเปิด pi เปิดเทอร์มินัลแล้วเปิดคอนโทรลเลอร์บลูทูธ
bluetoothctl
ภายในคอนโทรลเลอร์คุณต้องการป้อนคำสั่งเหล่านี้ตามลำดับ (ลบ # ความคิดเห็น)
power on # ensures bluetooth is on
power on # ensures bluetooth is onble
agent on # makes pairing persistent
default-agent
scan on # scans for bluetooth devices
# the OBDII adapter should read something
# like this - 00:00:00:00:00:00 Name: OBDII
# If it asks for a pin, the default pin is 1234
scan off #turn off scanning once your adapter has been found
pair #pair to your adapters mac address
trust #keeps pairing even after reboot
quit #exits out of bluetoothctl
ณ จุดนี้อะแดปเตอร์ควรจะเชื่อมต่อและคุณควรจะกลับไปที่สายสถานีหลักของคุณ เนื่องจากพอร์ต OBD เป็นพอร์ตอนุกรมเราต้องผูกมันกับพอร์ตอนุกรมใน Pi
sudo rfcomm
bind rfcomm0
address>
ตอนนี้เราควรจะสามารถเชื่อมต่อกับอะแดปเตอร์ได้แล้ว! โปรแกรมที่ดีที่ใช้สำหรับการสื่อสารเรียกว่า "หน้าจอ"
sudo apt-
get install
screen
screen /dev/rfcomm0
คุณควรนำเสนอด้วยหน้าจอที่ว่างเปล่า ณ จุดนี้เราสามารถเริ่มพิมพ์คำสั่งของเรา คำสั่งแรก ๆ นั้นเป็นมาตรฐานสำหรับการตั้งค่าการสื่อสาร พิมพ์แต่ละคำสั่ง (ลบ # ความคิดเห็น) แล้วกด Enter เพื่อหาข้อมูลเพิ่มเติมเกี่ยวกับคำสั่งเหล่านี้คุณสามารถเยี่ยมชมเว็บไซต์นี้
atz #resets the device and returns the device ID
atl1 #enables line feeds
ath0 #disables headers (ath1 enables)
atsp0 #automatically determines communication method
เมื่อทำเสร็จแล้วคำสั่งถัดไปจะบอกพอร์ตว่าข้อมูลใดที่เราต้องการแตกออก คำสั่งประกอบด้วยค่าฐานสิบหกสองค่า ชุดแรกบอกโหมดที่เราต้องการตั้งค่า
มีหน้า Wikipedia ที่ยอดเยี่ยมที่อธิบายรหัสและฉันได้แนบภาพหน้าจอด้านล่าง เนื่องจากฉันสนใจข้อมูลเรียลไทม์สำหรับโครงการนี้โหมดที่ฉันต้องการตั้งค่าจะเป็น 01 สำหรับค่าเลขฐานสิบหก
ชุดที่สองของค่าเป็น ID พารามิเตอร์ มี PID ที่พร้อมใช้งานเกือบ 200 ที่แตกต่างกันและอีกครั้งสามารถพบได้ในหน้า Wikipedia นี้ ที่นี่เราสามารถขออุณหภูมิ, ความเร็ว, RPM และอื่น ๆ สำหรับการทดสอบนี้ฉันจะขอความเร็วดังนั้น ค่าฐานสิบหกคือ 0D
ดังนั้นค่าสุดท้ายของฉันคือ 010D (ดังที่คุณเห็นจากแผนภูมิด้านบน RPM จะเป็น 010C) ดังนั้นฉันสามารถพิมพ์สิ่งนี้ลงในเทอร์มินัลเพื่อรับผลลัพธ์ของเรา
010D
แต่ผลลัพธ์ที่เราได้ก็คือรหัสฐานสิบหก ด้านล่างคือรหัสฐานสิบหกที่ฉันได้รับ
41 0D
32
11
นี่คือรายละเอียดของความหมาย (นี่เป็นเว็บไซต์ที่ดีสำหรับข้อมูลเพิ่มเติม):
41 - การตอบสนองสำหรับคำสั่งโหมดของเรา (01)
0D - การตอบสนองสำหรับคำสั่ง PID (0D) ของเรา
32 - ความเร็ว (เป็นฐานสิบหก)
11 - ไบต์ข้อมูลที่ไม่ได้ใช้
ดังนั้นความเร็วของเราใน hex คือ 32 การ popping ในตัวแปลง hex เป็นทศนิยมเราได้ 50 km / hr ใช่ค่าความเร็วเริ่มต้นอยู่ในกิโลเมตร การแปลงเป็นไมล์เราได้รับ 31 ไมล์ต่อชั่วโมง
สำคัญ: ในการรับอะแดปเตอร์บลูทูธ เพื่อเชื่อมต่อโดยอัตโนมัติมีสองขั้นตอนเพิ่มเติมที่คุณต้องใช้กับ Raspberry Pi วิธีแรกคือแก้ไข rc.local
sudo nano
/etc/rc.local
และเพิ่มบรรทัดต่อไปนี้ก่อน "exit 0"
rfcomm
bind rfcomm99
address>
โดยที่ "adapter mac address" เป็นที่อยู่ mac ของอะแดปเตอร์บลูทู ธ ของคุณ
สุดท้ายคุณจะต้องแก้ไขไฟล์กำหนดค่าบลูทูธ :
sudo nano
/etc/systemd
/system/dbus-org.bluez.service
ค้นหาบรรทัดที่ระบุว่า "ExecStart = / usr / lib / bluetooth / bluetoothd" และเปลี่ยนเป็น:
ExecStart=
/usr/lib
/bluetooth/bluetoothd -C
ExecStartPost=
/usr/bin/sdptool add SP
ตกลงดังนั้นนั่นไม่ใช่กระบวนการที่ง่ายที่สุด แต่อย่างน้อยตอนนี้เรารู้วิธีรับข้อมูลจากพอร์ต OBD ตั้งแต่เริ่มต้น ตอนนี้สิ่งที่เราต้องทำคือเขียนโปรแกรมที่ทำงานอัตโนมัติทั้งหมดนี้และแสดงในรูปแบบกราฟิก!
ทำให้การติดต่อทางกราฟิก
ตอนนี้เรามีข้อมูลแล้วเราต้องการวิธีที่ดีกว่าและน่าสนใจกว่าในการแสดงข้อมูล เนื่องจากฉันคุ้นเคยกับ Python มากที่สุดฉันจะใช้เพื่อจัดการข้อมูล ออนไลน์ผมพบว่าห้องสมุดที่ดีโดยเฉพาะสำหรับการเชื่อมต่อ OBD เรียกว่างูหลาม-OBD ดังนั้นฉันจึงติดตั้งพร้อมกับ PySerial
pip
install pyserial
pip
install obd
เมื่อทำเสร็จแล้วมาดำน้ำในและดูว่าเราสามารถทำอะไรได้บ้าง สำหรับการทดสอบพื้นฐานฉันจะเขียนโปรแกรมง่าย ๆ เพื่อแสดง RPM ของรถ
obd_hud_test.py
#import required libraries
import obd
#establish a connection with the OBD device
connection = obd.OBD()
#create a command varialbe
c = obd.commands.RPM
#query the command and store the response
response = connection.query(c)
#print the response value
print(response.value)
#close the connection
connection.close()
บันทึกและทดสอบมันจะส่งออก RPM ปัจจุบันของรถ!
ห้องสมุด python-OBD นั้นใช้งานได้ดี แต่ก็ยังไม่เป็นกราฟิก ในการสร้างส่วนต่อประสานกราฟิกใน Python มีหลายตัวเลือกให้เลือก บางอย่างที่ฉันคุ้นเคยคือ:
· PyQt
· Tkinter
· Pygame
Pygame นั้นง่ายและรวดเร็วดังนั้นฉันจะไปด้วยเพื่อจุดประสงค์ในการกวดวิชานี้ สิ่งที่สะดวกยิ่งกว่าคือ Pygame ติดตั้งมากับ Raspberry Pi แล้วดังนั้นไม่จำเป็นต้องติดตั้งอะไรเพิ่มเติม!
เอาล่ะลองมายิงกันดู นี่คือรหัสสุดท้ายสำหรับการแสดง
obd_hud_test.py
การทดสอบมันใช้งานได้อย่างมีเสน่ห์!
ขอบคุณข้อมูลดีๆ จาก www.hackster.io
Credits : Tinkernut
DIY Smart Car (Part 1)
https://www.youtube.com/watch?v=Kq_BJg_8iyU
DIY Smart Car (Part 2)
https://www.youtube.com/watch?v=FH015Pzys-8