---
# System prepended metadata

title: 109-2 電資工程入門設計與實作 工作紀錄簿 (固定分組)
tags: [電資工程入門設計與實作, 109-2]

---

# 109-2 電資工程入門設計與實作 工作紀錄簿 (固定分組)

**備註：因固定分組，本工作紀錄簿將沿用至學期末，請固定將每週紀錄填入！**
## 組名:BBMCC

## 成員
* 班別：週三班 
* 組員1：吳宣逸 B09901080
* 組員2：游菖鈺 B09901094
* 組員3：郭宇庭 B09901159

## 第四周pytest結果
![](https://i.imgur.com/ijqDfs7.png)

## 第五週紀錄 - 組車
* 課堂應完成事項(**下課前必須找助教檢查**)
    * 車子組裝完成Part 1(模組)
    * 車子組裝完成Part 2(電源線)
    * 車子組裝完成Part 3(訊號線)
> 給助教檢查[name=鐘民憲] 剩part3
* 實際達成事項 (必填)
    * 課堂上已經完成車子本體(除了頂板)並將模組以及電源線配好，等待openlab再接訊號線以及測試。
    * openlab配線：
    1. RFID
    
    | RFID | Sensor Shield |
    | -------- | -------- |
    | VCC | V |
    | RST | 9 |
    | GND | G |
    | MISO | 12 |
    | MOSI | 11 |
    | SCK | 13 |
    | NSS | 10 |
    2. HC05(Bluetooth)
    
    | HC05 | Sensor Shield |
    | -------- | -------- |
    | VCC | V |
    | GND | G |
    | TXD | 7 |
    | RXD | 8 |
    3. TCRT5000(紅外線循跡模組)
    
    | TCRT5000 | Sensor Shield |
    | -------- | --------|
    | VCC | V |
    | GND | G |
    | A0 | 左 → 右： A0 A1 A2 A3 A4|
    4. L298N
    
    | L298N | Sensor Shield |
    | -------- | -------- |
    | ENA | 6 |
    | ENB | 5 |
    | IN1 | 3 |
    | IN2 | 2 |
    | IN3 | 1 |
    | IN4 | 0 |
    * Tests
        1. DC motors(L298N)
            {%youtube IptoEcGeCpo %}
        2. IR sensors(TCRT5000)
        * [程式碼](https://github.com/Xuan-Yi/Cornerstone-EECS-Design-and-Implement-basic-codes.git) 
    
* 組內討論事項 (必填，如問題、構想、分工合作、時間安排...等等)
    * 在把左右板所到底板上時，我們覺得螺絲的頭部太小，因此另外在中間加了一塊墊片，使左右板比較不容易鬆脫![](https://i.imgur.com/q9M1VA4.jpg)

* 組員分工 (必填)
    * 這次並沒有明確的分工，因為剛開始並不熟悉各自的專長，因此可能等到下次才會開始分工。
* 遇到問題之處理狀況、解決方式 (必填)
    * 銅柱沒有15mm的尺寸只剩下10mm與20mm，這個問題到最後會發現影響不大，但在組裝時仍然不確定這個變動會不會造成嚴重的後果，因此我們使用10mm銅柱+較長的螺絲+一顆螺帽(當墊片)達到類似15mm銅柱的效果。![](https://i.imgur.com/8eUN6HV.jpg)

    * 降壓器與arduino板電源插頭間的線短於投影片中希望我們走的路徑長度(直接連到降壓器output)，因此我們利用電路學學到的"同一個節點有相同電位"這個性質將線改牽往同個節點上的L298N的電源input，因此不用重焊arduino電源供應插頭。![](https://i.imgur.com/t5QuFWZ.jpg)


* 課程建議 (選填)
    * 這次組車子其中最耗時間的就是排隊等待焊接，大家也都不熟練焊槍的使用方式，而makerspace就在隔壁而已，因此或許可以跟學術部協調使用makerspace的器材，或許就能有更多組別在下課前完成組車、試車。
* 想說的話 (選填)
    * 這台車子的諸設計之中，最棒的應該就是上面的平台結構了，這使得之後的自選專題有很大的發揮空間，希望能繼續維持甚至升級這個設計。

## 第五週批閱區 - 組車
* 助教批閱欄
    * 助教回饋
        * 紀錄完整，除了記錄下主要遇到的問題與解決方法，並給出具體建議之外，也把訊號線的腳位都記錄了下來，甚至有放上車子實際demo的影片，看起來進度不錯，不過分工的部分下次記得要記錄喔。焊槍的部分未來會補足數量，也感謝你們對於車子頂部平台的稱讚。
> [name=鐘民憲]
* 教授批閱欄
    * 評分等第
        * A-
    * 教授回饋
        * 紀錄完整，有提供遇到問題的解決方式與建議
        * 完成本週目標
> [name=林坤佑]

## 第六週紀錄 - 循跡
* 課堂應完成事項(**下課前必須找助教檢查**)
    * 可不輔助、不出軌，連續繞行橢圓狀地圖2圈
> 給助教檢查[name=鐘民憲]
* 實際達成事項 (必填)
    * 讓5顆TCRT5000(紅外線循跡模組)皆能正常感測並傳回digital訊號 
    * 在課堂上完成P control
        1. 沿直線行走
        2. 橢圓形軌道
        {%youtube AhtYEhY50EM %}
        3. C形軌道
        {%youtube S71FOHxwD_0 %}
    * PID control 
         {%youtube Pc3y-ddqhtU %}
    * 解決空轉問題：使用雙面膠增加輪胎磨擦力(最終成果，p.s. 使用上方PID control程式碼)
        {%youtube MkKNyWgA0-U %}
    * [P/PID control codes](https://github.com/Xuan-Yi/Cornerstone-EECS-Design-and-Implement-basic-codes.git)
* 組內討論事項 (必填，如問題、構想、分工合作、時間安排...等等)
    * 課堂上構思演算法的pseudo code(後來知道是P control)
        ```c=
        setup(){
            assign two weighted arrays(one for left wheel and one for right wheel)
            creat an int array S to store values of each sensor
            set both motors to some speed VL, VR
        }

        loop(){
            for all IR sensors
            V[n] = value of sensor_n

            int dvL, dvR = 0
            for all IR sensors
                dvL+=V[n]*weighted_array_left[n]
                dvR+=V[n]*weighted_array_right[n]

            left_speed = VL + dvL
            right_speed = VR = dvR
        }
        ```
    * 車車在轉彎時常常碰到的問題是跑過頭導致最後彎回來需要大幅度修正方向才能繼續沿著軌道跑，結果就是車子跑得很不平順，經過思考與實驗發現若轉彎時一輪向前一輪向後轉有助於解決這個問題，不過這樣的話仍然不夠好，之後再測試究竟甚麼值能做到更平順，我們覺得當向後的速度絕對值大於向前速度的絕對值時會是比較好的方式，最後試驗起來也應該是如此。

* 組員分工 (必填)
    bulk of P control：郭宇庭
    bulk of PID control：游菖鈺
    HackMD：吳宣逸
    Debug、調整參數：吳宣逸、游菖鈺、郭宇庭
    
* 遇到問題之處理狀況、解決方式 (必填)
    * 調整TCRT5000的敏感度時，發現每個模組的可變電阻轉到底的敏感度差異實際上滿大的，因此最一開始我們使用analog輸出常常會無法將各個模組的輸出值調到一致，還有幾個模組的可變電阻不小心被轉壞掉，最後的解決之道是改用digital輸出，效果果然好很多(但還是有模組壞掉所以又有換掉幾個)
    * 有可能是我們移動電池時太過粗暴，有一條電源線在我們測試時斷掉了，後來發現有組別會在焊接處纏上膠布，因此我們也學習他們這種方式，果然電源線更加穩固了。
    * 用P control時，在C形軌道上的大彎會衝出去或者轉不過去，我們的解決方式是將constant_V先調小，之後將P control的參數(偏移權數)慢慢調到可行值之後再將constant_V慢慢調大，如此一來若在C形軌道上能跑後就也可以克服橢圓形軌道了。
    * 輪胎空轉是我們一直碰到的問題，在4/1當天我們的解決方法是在頂板上靠輪胎那側壓上手機增加正向力(耶~頂板good XD)，作用是增加後輪的摩擦力，不過這樣做的主要缺點是會增加重量降低車子的動力以及因為手機無法固定導致只要甩得太大力手機就會掉下來，通常車子也跟著不動了。

        4/1更新：下課後郭宇庭有用膠水將輪框與外胎黏起來，而也有稍微改善，但仍然不時會被紙張卡住脫軌。
        
        4/10(凌晨)更新：我們將電池從原本的位置取出改放置在車子頂部中央，似乎又有更加改善了，不過因為之後並不會這樣配置電池位置所以這個改善並沒有實際功用:<。
        {%youtube LpHBGoqu20I %}
        4/10(Open lab)更新：我們終於解決輪胎空轉的問題了!靈感來自有一組將橡皮筋綁在輪胎上來止滑，當時我們手邊沒有橡皮筋只有一卷雙面膠，因此就產生了這個大膽的想法，原本以為會跑不動但是實際用上去之後發現效果很好，不但輪胎不再空轉，雙面膠也增加曳引力讓轉彎不打滑，因此速度也快起來了!
        ![](https://i.imgur.com/mULW1rv.jpg)

    * 做PID control時，不管怎麼調參數總是會跑出去，最後與其他組討論時發現可以在全部的TCRT5000都感應到白色時，根據_LastError去決定原地旋轉的方向以確保在沒感應到黑線時還能夠在找到黑線繼續循跡，最後也地卻達成目標了。
    

* 課程建議 (選填)
    與其他組交流後，發現其實不少組別都有輪胎空轉的問題，而在組車之前投影片就有建議若擔心空轉可以改裝成三輪車，但實際上就算改為三輪車狀況也沒改善多少，除了增加輪子摩擦力之外，或許改變車子的重量分布是最理想的方法，將重量多壓在後輪，而萬向輪端則能輕則輕(畢竟萬向輪本身就很重了)，不過基本上這就是改變整個設計了，所以可能不是一天兩天就能改善的，但還是希望空轉不要成為那麼令人頭痛的問題(畢竟也沒看過三輪腳踏車在平地空轉的：<...)。
    再者馬達也是大問題，直流馬達超難控制轉速，常常稍大稍小就會爆衝不然就是停住，因此或許之後可以換用步進馬達(?)之類的，至少稍微比較好控速的馬達，假如可以的話應該會有更少時間花在調馬達輸出上面。
* 想說的話 (選填)
    一開始覺得循跡車應該滿簡單的，但是在真正做下去之後才發現有一堆問題需要克服，原本的最大問題以為是演算法的參數，但實際上最後發現空轉才是最大的魔王，雖然從開始到真正完成前前後後花了一堆時間，但是這應該就是我們之後實作都會遇到的問題。花了幾個禮拜，或許我們根本不該期望在這堂課學到的是甚麼專業知識，一切都只是概論若真的有興趣應該是去修系上選修，在這堂課真正該帶走的是處理現實中問題的能力，而這些是平常學不到的東西，因此非常建議學弟妹能來修這節課。

## 第六週批閱區 - 循跡
* 助教批閱欄
    * 助教回饋
        * 紀錄很詳細、分工明確。改用PID control後循跡穩了很多。恭喜你們解決輪胎空轉的問題，不過當初電池位置會這樣設計也是考量車體底部的空間分配之後的trade-off，辛苦你們了。通常大家只想到改變配重，但你們這組的解法真的很酷，或許之後機會可以在課堂上跟大家分享這個方法。
> [name=宋馨慈]
* 教授批閱欄
    * 評分等第
    A+
    * 教授回饋
    紀錄內容很豐富很好喔，不過有些句子太長，讀起來不知道該怎麼斷句。與其他組同學多交流也是好事；彼此間常會遇到同樣的問題，大家未來還要當好幾年同學，現在以後的課程都可以互相交流。再者，很多基礎理論懂了以後就很簡單，但是實作與調教上所花的時間更多。這門課在系上、老師們、助教們都投入非常多心力與時間，幸運修到這門課，的確比其他同學多賺到。 :D 
> [name=君朋]


## 第八週紀錄 - 指定題介紹
* 課堂應完成事項(**下課前必須找助教檢查**)
    * 問題0回答、答案訂正
    * 問題1回答、答案訂正
    * 問題2回答、答案訂正
    * 問題3回答、答案訂正
    * 完成甘特圖
    * 完成系統方塊圖
> 給助教檢查[name=宋馨慈]剩下系統方塊圖未完成
* 實際達成事項 (必填)
    * 甘特圖
        ![](https://i.imgur.com/qcJ8uHr.png)

    * 資料介面流程
        * 筆電端流程
            最一開始會根據起始節點、.csv檔計算出最佳路徑(包括用adjacent list判斷節點是轉彎塊或死巷塊)並在筆電中儲存成陣列，若是Arduino回傳在非直行塊上(5個TCRT5000都是黑色)，則用這個陣列判斷下一個動作後利用筆電內建藍芽向Arduino下指令，類似人類大腦(筆電Python程式)與小腦(Arduino的控制程式)的分工模式。
            電腦端Python程式也同時接收讀取到的RFID卡號並自動計分，另外有個作為Timer的程式計時。
            
            ![](https://i.imgur.com/6UTCoYq.png)
            
        * Arduino端流程
            主要工作是控制在直線塊上時的循跡過程和以藍芽模組HC05回傳遇到非直線塊的狀況以讓筆電端Python程式做出反應，之後依照筆電端的指示轉彎或讀取RFID卡號回傳計分，接著便取回主控權繼續循跡直到再遇到非直行塊或筆電傳入「時間到」的訊息。
            ![](https://i.imgur.com/A5Tmi8K.png)


        * 總流程
            這裡的time out雖然是寫在Arduino的範圍內，但實際上是屬於筆電python程式的範疇，在此只是簡略表示而已。
            其他大部分皆有在上面說明了。
            ![](https://i.imgur.com/L06pOHr.png)





* 組內討論事項 (必填，如問題、構想、分工合作、時間安排...等等)
    * 問題0： 6(V)*180(mA)=1.08(W)
    * 問題1：
        1. 200(mW)+33(mW)+75(mW)*5+86(mW)+1.08(W)*2=2.854(W)
        2. 2.854(W)/11.1(V)=257.12(mA)
        3. 2250(mAh)/257.12(mA)=8.75(h)
    * 素養題：
        1. 人的運動功率為多少？ 300(W)
        2. 一般轎車的功率為多少? 100(kW)
    * 問題2：
        >假設
        >迷宮有150個node
        >所有node都用一個整數來儲存(在Arduino Uno中佔2B)
        >使用adjacency list+distance儲存整張地圖
        >Arduino Uno板SRAM容量為2KB

        1. 地圖本身所需記憶體容量？ 150*(1+4+4)*2(bytes)=2700(bytes)
        2. 執行BFS演算法時，所需最大額外暫存容量？ 
            queue：150*2(bytes)=300(bytes)
            +mark：150*2(bytes)=300(bytes)
            +predecessor：150*2(bytes)=300(bytes)
            =900(bytes)
        4. 地圖跟BFS演算法，可否放入Arduino中？ 不可能!!!
    * 問題3：
        >假設0.1秒內需要完成
        >* 通知看到轉彎塊
        >* 告知RFID UID (例如: FD02AA21)
        >* 接收後續指令
        >
        >假設藍牙位元速率為9600bits/sec
        >假設藍牙傳輸以Byte為單位
        
        1. 需要多少通訊速率(bits/secs)？ (1+8/2+1)(bytes)/0.1(secs)=480(bits/secs)
        2. 藍牙是否可以支持此通訊速率？ 可以!!!


* 組員分工 (必填)
    指定題分工：吳宣逸、游菖鈺、郭宇庭
    製作甘特圖：吳宣逸、郭宇庭
    HackMD：吳宣逸、游菖鈺
    
* 遇到問題之處理狀況、解決方式 (必填)
    * 課堂中討論問題時，會遇到我們持有不同答案的情況，也有我們心目中的答案與正確解答不符的時候。例如問題2-1，一開始我忘了要用一個整數儲存node的index值；問題3-1則沒想到原來接收後續指令僅需要傳輸一個byte，還以為要用很多。
    * 要做甘特圖時蠻猶豫要用哪個網站的，畢竟免費的都有各自一些不方便的地方，加上第一次製作，對這個有些生疏。另外也有查到可以直接用Excel做，但看在日期之類的還要自己建表格輸入，最後還是選擇線上的工具。但我們使用的這個網站有個不小的缺點，就是我們不知道怎麼換顏色，所以一看上去只能分辨項目和日期，沒辦法很明確的標示分工細節。
    * 對於誰要負責指定題的哪部分，我們也思考許久，感覺是突然接收到太多資訊，加上我們各自也沒什麼太大的偏好，然後不了解各自工作的loading，所以目前只有大概分配一下，日後應該還有可能會做更動。
* 課程建議 (選填)
    我覺得日後如果還有像這週這樣的問答式教學的話，可以請教授在講解比較複雜的問題時用個圖慢慢解釋，像問題3其實就有點複雜，一看到題目不太知道他到底要傳多少資料過去，聽完一個同學解釋之後好像有點道理，結果正確答案出來之後又馬上被推翻了，才剛稍微脫離一頭霧水，馬上又陷下去了，雖然這可能是我自己本身知識不夠，但我想如果能當下理解，總比之後再問再找答案來得有效率。不過我還是覺得這樣的互動方式不錯啦，我們可以當場思考，雖然這次沒有什麼動手實作的部分，但至少我們不只是一味地聽教授在上面授課。
    另外最後在講解sample code的時候，我覺得助教也可以再講慢一點，雖然當時是快下課了，但這樣我們好像也沒能馬上記得多少，還是得靠自己回家慢慢看了。
* 想說的話 (選填)
    兩週後要上台報告，而中間橫跨了期中考週，我想對我們來說這一點也不輕鬆，本來還想說一考完就全力投入，沒想到普物還延後一週，導致接下來的我們要一邊讀書一邊做車車了。前幾週的回家工作量都還不算多，但可預見的是接下來只會越來越忙，不過也離我們做出車車越來越近了，希望我們最後能成功達到目標！

## 第八週批閱區 - 指定題介紹
* 助教批閱欄
    * 助教回饋
        * 紀錄內容超詳細，尤其是方塊圖，畫得詳盡、清楚、精美，看得出你們對指定題的觀念清晰，而且對這門課很投入:)
        * 我們講解sample code確實有點趕，尤其python code行數很多，助教大一時也花很久才弄懂，如果有問題歡迎上課及open lab時段主動提問。關於arduino code 有誤之處，真的非常抱歉。
        * 關於時程問題，我們今年選擇多留一些時間做自選題，導致指定題時間被壓縮，我們了解那種被死線追著跑的壓力。對於時程有什麼建議，歡迎下週上課提出來討論。祝你們微甲期中順利XD
> [name=謝兆和]
* 教授批閱欄
    * 評分等第
        * A
    * 教授回饋
        * 
> [name=林坤佑]

## 第十週紀錄 - 指定題進度報告
* 預計完成事項 (必填)
    * 完成checkpoint要求
    * 完成指定專題要求
* 實際達成事項 (必填)
    * 甘特圖更新
        ![](https://i.imgur.com/dWFHEND.png)

    
* 組內討論事項 (必填，如問題、構想、分工合作、時間安排...等等)
    * 04/26 Checkpoint 策略討論
        * Map
            ![](https://i.imgur.com/ATYOoPu.png)
        * 計分
            1. RFID讀值
                使用之前的程式修改
            2. 藍芽回傳
                使用之前的程式修改，回傳卡號最適合的資料形態等openlab再做測試
            3. score.py計分
                再研究
            4. 藍芽回傳收到訊號
                一樣用之前的程式修改
        * 循跡
            使用之前的程式修改，參數可能需要再微調
        * 行為
            電腦端判斷在checkpoint map的位置，在轉彎塊、死巷塊傳給arduino 相對應的命令
            
    * 04/26 迷宮討論
        * 程式
            分成3個state：
            1. 直線 $\Rightarrow$ 循跡
            2. 死巷 $\Rightarrow$ 偵測到5顆全黑多走一點 $\to$ 停下來 $\to$ 讀RFID $\to$ 迴轉(離開)
            3. 轉彎 $\Rightarrow$ 偵測到5顆全黑多走一點(輪軸中心在轉彎塊中心) $\to$ 停下來 $\to$ 從電腦拿下一步(方向) $\to$ 轉彎(離開)
    * 05/01 checkpoint目標
        方案一、 路線由Python控制
        方案二、 路線由Arduino控制
        
        原先理想的方案應該是方案一(範例程式中也是這麼寫的)，但之後我們發現許多組其實都也是將程式寫死在arduino裡面，因此或許方案二也不錯。目前先以能控制車子為主，這兩個方案取捨可能留待較晚。
        
    * Sensor Shield
        ![](https://www.botsheet.com/cht/wp-content/uploads/arduino-sensor-shield-v5-pinout.jpg)
    * Arduino Uno
        ![](https://i.imgur.com/THItoMB.png)


* 組員分工 (必填)
    * 游菖鈺
        * **Python** score
        * **Arduino** 程式整合(final_project), node, track, 參數調整 
        * 簡報PPT
    * 吳宣逸
        * **Python** BT, interface
        * **Arduino** bluetooth, 程式整合, 參數調整
        * HackMD
    * 郭宇庭
        * **Python** maze, node, main
        * **Arduino** node
* 遇到問題之處理狀況、解決方式 (必填)
    * 05/01 HC05掛掉，在openlab時向學術部同學求助，之後在MKS暫時借到一顆HC05。幸好組員在宿舍也有HC05，所以可能有救。但在設定AT模式時遇到障礙，卡關中。
        * 05/01 17:59更新
        使用以下程式碼後，就能夠進行AT設定了，因為HC05是個人財產，所以命名為**BBMCC_HC05_of_Xuan_Yi_Wu**以免搞混，PIN碼為**1234**、鮑率為**9600**。
            | 功能 | AT指令 |
            |--|--|
            |查詢鮑率|AT+UART?|
            |設定鮑率|AT+UART=**UART**|
            |查詢地址|AT+ADDR?|
            |查詢PIN碼|AT+PSWD?|
            |設定PIN碼|AT+PSWD=**PSWD**|
            |查詢名稱|AT+NAME?|
            |設定名稱|AT+NAME=**NAME**|
            |恢復原廠設定|AT+ORGL|
            [AT 命令程式碼](https://github.com/Xuan-Yi/final-project.git)

    * 05/02 01:50 arduino程式執行時，右輪不會轉動，但左輪能夠根據 tracking() 改變方向。
        
        * 用之前PID control的程式執行能夠正常根據IR sensors讀值做出反應，顯示**硬體正常**。
        * 將主程式(final_project)的loop中內容全部註解掉，只寫 MotorWriting(200,200); 結果仍然是右輪不動，將**範圍限縮到MotorWriting(double, double)**。

        * 將MotorWriting(double, double)複製到之前PID control的MotorWriting()程式位置，並將原MotorWriting()註解掉，之前PID control的程式仍然可以正常執行(左右輪皆能對IR sensors的讀值做出適當的反應)，因此**猜測可能是一些變數、定義的問題**。

        * 目前問題算是解決了，又是個老掉牙的BUG - **D0、D1腳位**，但實際上我們也只剩下空出的一個D4腳位，無法避免還是會用到D0或D1腳位，因此目前的解決方法是做以下處理，畢竟debug時大概也不會用到馬達，因此這樣應該是最好的解法了。
            ```c=
            #ifdef DEBUG
            Serial.begin(9600);
            #endif
            ```
    * 以下是現有Arduino的程式，除了因為python尚未完成而無法確認發送card id的功能以及因為地圖被不知道是誰在openlab拿錯而手邊沒有地圖測試之外，其餘功能大致是完成了。

        ps. 因為HackMD的編輯有字數上限所以把程式上傳到GitHub (05/08)。
        [checkpoint程式碼](https://github.com/Xuan-Yi/Conerstone-EECS-Design-and-Implementation-checkpoint.git)

* 課程建議 (選填)
    * 前面的入門課程相對後面實作輕鬆，所以或許可以早點讓我們開始，而且盡量排除在指定專題前強撞期中考。
    * 05/01 的openlab時間有延長真的還滿不錯的，但在場助教只有一個，偏偏又有很多組都來做車車，明顯地一位助教會有不小的負擔，很多人都有問題時可能要等一段時間。而我想這個情況在接下來的日子裡應該會更頻繁的發生，所以希望以後能加開openlab的時間並配置適當的助教人數。
    * 今天我們的HC05掛掉了，但卻沒有模組可以馬上替換，希望以後能夠多準備一些零件，不然像今天只能請同學自行購買再報帳。若非今天MKS開著，可能我們組只能提早結束openlab了。
* 想說的話 (選填)
    * 之前我們就在紀錄簿貼上我們使用雙面膠改善輪胎磨擦力的想法，當時助教給予正面的回饋，教授評語也沒有表示這個想法不適當。結果在checkpoint的前一個禮拜，教授又突然說這個方式會破壞場地、影響之後的參數調整，並類比短跑穿釘鞋的例子，最後我們的車子換回一般輪子之後，在抓地的表現大幅退步，且讓我們有種前功盡棄的感覺，畢竟之前調參數也是花了不少時間，如今有新課題卻又得重頭來過。希望如果之後學弟妹的車車也有疑似會破壞場地或認為可能違反比賽公平性的疑慮時，能盡快通知學弟妹，否則以我們的例子而言，在checkpoint的前一個禮拜還需要做這種硬體上的更動真的有點力不從心。

## 第十週批閱區 - 指定題進度報告
* 助教批閱欄
    * 助教回饋
        * 關於輪胎年雙面膠這點，我猜測是因為上禮拜批改紀錄簿的教授為君朋老師，所以坤佑老師當時沒有看到，而坤佑老師在上課的時候看到你們的做法才提出可能會破壞場地這件事情，進而導致你們在checkpoint前一個禮拜得改回來，這點真的非常抱歉，不過老實說我並沒有實際看過你們走在地圖上是否會造成什麼破壞，所以到底黏雙面膠這件事可不可以，我想還是得請老師裁決...但既然你們已經改回來了，就維持現在的做法吧。
        * 前面的入門課程能否縮短讓做指定專題的時間多一些，我覺得這就是trade-off吧，如果前面的基礎沒打好，那麼你們在指定專題撞牆的情形會更嚴重，至於撞到期中考這件事應該歷年來都有，但不得不承認給你們做的時間真的偏少。
        * Open Lab的時間其實學期初就決定好了，加開其實都是助教很熱心地主動加班陪你們，只能說不是每個助教都有辦法額外撥出時間(像我也有跟一堆很硬的課在修...)，但只要可以，我們都會盡量幫助你們，畢竟我大一的時候修這門課也是這樣走過來的。
        * 缺模組真的很抱歉，已經有請大助教進貨了
        * 總之，很高興看到你們checkpoint的code大致上都完成了，不過不知道你們實際跑的情況如何，祝你們checkpoint及後續指定題能夠順利~
> [name=鐘民憲]
* 教授批閱欄
    * 評分等第
    A+
    * 教授回饋
    謝謝你們的回饋意見。其實我們老師們除了上課時間，另外還會每週固定約時間開會。我們老師多，對事情的看法很多地方一致，很多地方也不一致；正因為這樣的特性，所以這們課也才會有一些既定的流程，每個班的授課風格也不盡相同。
    其實說實話，每次我批改工作記錄簿，花的時間比你們寫的時間還要多囉。雙面膠基於學生創意上，我個人的確沒太多想法；但坤佑老師有不同想法，我也覺得他說的有道理。我會在這週老師會議上提出與其他老師們討論，畢竟我們這些老師們，都戮力於讓車車課變成大家心中的好課。謝謝你們的建議，讓你們覺得前功盡棄感到抱歉。

> [name=陳君朋]

## 第十一週紀錄 - 指定題進度檢視
- CHECKPOINTS
    - 車車
        - [x] 循跡
		- [x] 可以偵測到 node（包含十字路口和死巷）
		- [x] 偵測到 node 之後，穩定直走、轉彎、迴轉（寫死指令）
		- [x] 可以接收來自電腦的藍芽指令

	- python
		- [x] 完成基本的 BFS
		- [x] 完成第一題的設計
		- [x] 可以透過藍芽傳輸指令

	- combined
		- [x] 可以讀取 RFID 的值
		- [x] 能走完 3 個點
		- [x] 可以不輔助的情況下，完成小型 E 字地圖
		- [ ] 可以不輔助的情況下，完成進階地圖
		- [x] 可以正確在死巷讀取 RFID
> 給助教檢查[name=宋馨慈]

* 組內討論事項 (必填，如問題、構想、分工合作、時間安排...等等)
    * Checkpoint前已完成程式碼：
        * Arduino：
            * final_project.ino
                * 首先可以在此切換模式，主要有DEBUG、CHECKPOINT、REMOTE_CONTROL，(MAZE部分尚未完成)。
                * 而我們判斷進入node的方法是五顆紅外線中至少三顆測到黑色，因為有時候如果歪歪地進入node可能沒辦五顆全暗，這是由一個函式IR_counter()呼叫。
                * 另外介紹幾個變數:
                    * char start_sign 用於接收由電腦端給出的S開始指令。
                    * bool on_block 是為了解決我們有時候走到端點會停不下來的問題。
                    * int step_counter 是由於我們把Checkpoint的指令寫在一個陣列裡，這個counter在讀到node時++，依序吃進車車要執行的指令。
            * node.h
                * 這裡寫了五個走到node時可能的下一步行動，分別是左右轉、直行、迴轉、倒車。在進行左右轉及迴轉時，我們先讓車車往前走一小段，避免他在轉彎前再次讀到node，導致step_counter++而吃錯指令。
                * 另外在倒車部分我們有嘗試寫一點點P control，因為我們的馬達沒有很好，以定速倒車可能會歪掉。
            * bluetooth.h
                * 依照從藍芽收到的指令(為一字元)，轉換成車車的行動指令，呼叫node.h中的函式。
            * track.h
                * 主要沿用之前的PID control，再做一些係數的調整。
        * Checkpoint 程式碼
            ps. 因為HackMD的編輯有字數上限，所以把程式上傳到GitHub (05/08)。
            [checkpoint程式碼](https://github.com/Xuan-Yi/Conerstone-EECS-Design-and-Implementation-checkpoint.git)
    * 指定專題進度
        * Arduino
            目前已經可以利用藍芽從python端讀取**方向陣列**(開始S、左轉L、右轉R、直走F、迴轉T、結束E)，並存在Arduino這樣可以避免藍芽連線問題導致走錯路。
            RFID目前也能夠如期在死巷塊位置讀取UID並且透過藍芽回傳給python端。
            循跡雖然還不算到最平穩，但目前的參數已經能夠確保車車不會跑出線外。
            現在遇到最大的障礙是在轉彎塊或死巷塊轉彎時，儘管Arduino程式中設定的是兩輪往反方向旋轉，但實際測試時卻是有時能正常運作有時只有單輪轉，目前希望能夠解決這個問題。
        * Python
            python部分沒有做太大的更動，而其中BFS已經由郭宇庭在checkpoint前先寫好了，策略是從最近的UID開始吃。
            另外由於指定專題有新的程式碼，不確定新程式碼是否可以正常運作，因此目前GitHub裡的是不需要連網路的score和用舊score的main。
        * Pyhon BFS 演算法
            ![](https://i.imgur.com/WvnV3Eg.png)
            > 節點順序：
            > ['1', '2', '7', '6', '13', '6', '7', '14', '15', '8', '15', '16', '17', '24', '17', '18', '19', '18', '11', '12', '5', '4', '5', '12', '11', '10', '9', '16', '23', '30', '31', '32', '31', '36', '31', '30', '35', '42', '41', '42', '43', '44', '43', '42', '35', '34', '29', '28', '27', '20', '27', '39', '40', '33']

            > 對應方向指令(左轉L、右轉R、前進F、迴轉T)：
            > ['F', 'L', 'L', 'R', 'T', 'L', 'L', 'R', 'R', 'T', 'R', 'F', 'L', 'T', 'L', 'F', 'T', 'L', 'L', 'R', 'R', 'T', 'L', 'L', 'F', 'F', 'R', 'F', 'F', 'R', 'F', 'T', 'R', 'T', 'R', 'R', 'F', 'L', 'T', 'F', 'F', 'T', 'F', 'L', 'R', 'L', 'R', 'F', 'L', 'T', 'F', 'R', 'R']

            > 對應得分：
            > 60, 90, 210, 240, 130, 260, 270, 360, 240, 90, 170
        * [指定專題程式碼](https://github.com/Xuan-Yi/final-project.git)
        * 小地圖測試影像紀錄
            * 成功
                {%youtube J1gFmK88TaI %}
            * 失敗
                {%youtube BCCkrTk0tKI %}
* 組員分工 (必填)
    * HackMD：吳宣逸、游菖鈺
    * Arduino：吳宣逸、游菖鈺
    * Python：郭宇庭
* 遇到問題之處理狀況、解決方式 (必填)
    * 剛到教室試跑Checkpoint時，跑得還算順，只有倒車不太行，結果多跑幾次後，竟然越跑越歪，發現右輪很明顯的比左輪慢。原以為是程式問題，結果拿回來測試之後發現不是，再多跑幾次右輪就直接不轉了。量測L298N的右輪接頭兩端電壓很弱，於是只好在考前一小時臨時換模組。結果換完之後仍然不會轉，但現場沒有新的直流馬達，只能拔以前的學長姊留下來的。裝好之後趕快用E字地圖調整係數，然後就匆匆忙忙進考場了。最後雖然還是拿到100分，但就跟我們原本第一次試跑的結果一樣，中間那一個多小時都浪費在處理硬體問題。
    
* 課程建議 (選填)
    經過近幾個禮拜熬夜做車車之後，又想到之前加簽的盛況，假如教授、助教認為加簽人數過多，或許可以考慮再加簽的那堂課就先說明這堂課並不是一堂涼課(車車課這個暱稱聽起來就滿輕鬆愜意的)，而是一堂非常紮實的課程，或許之後就能解決過多加簽的問題，但也可能造成人數過少，但或許真的可以考慮一下這個做法。
* 想說的話 (選填)
    仍然期望能盡快補充不足的模組。
    教授、助教、同學真的非常熱心，在我們的車車出問題時，都非常熱心的幫助我們解決問題，真的非常感謝。
    同時因為快到自選專題的課程時間了，不知道有沒有過去的範例能夠觀摩，讓我們大概抓個難度、方向，這樣對於提升同學的專題成果品質會有滿大的幫助，畢竟若選的題目太過困難，在時間不允許的狀況下可能也不會有太好的成果。

## 第十一週批閱區 - 指定題進度檢視
* 助教批閱欄
    * 助教回饋
        * 不好意思因為馬達消耗的速度真的比預期的快很多，加上還要等物流送達，目前還是沒有新馬達，所以可能還是要請你們先拔其他台車子的馬達來用(或教室後面散落的馬達XD)，真的很抱歉，助教們會盡速補充。
        * 把方向陣列存在Arduino裡面要小心容量可能會不足的問題喔，雖然以目前地圖規模來說應該是沒有問題。
        * 收到你們的加簽建議了，不過我記得老師第一堂課應該有講過(?) 這堂課大多是靠同學們口耳相傳來宣傳，所以老師們可能也不知道學生當初是抱持甚麼心理準備來修課的。不過這堂課就是老師、助教、學生都累的課，但是也可以學到很多東西，希望你們有了這次寶貴的經驗之後，也可以把經驗傳承給學弟妹~。
        * 自選題之後上課會再詳細說明，應該也會提供一些過去的作品給你們參考，不用擔心。不過難度跟方向因為每一組的條件都不相同，所以還是建議以你們自己評估是否可行為主，有問題也可以隨時在上課時提出討論。
> [name=宋馨慈]
* 教授批閱欄
    * 評分等第
        * A+
    * 教授回饋
        * 加簽建議的部分，我們第一週應該有提到這門課會比較扎實。我們會再討論未來是否要第一次上課把修過課的學長姊對於修這門課負擔的意見在加簽時提供給學生。
        * 課程網頁已經有提供過去自選題的資料，可以參考一下。![](https://i.imgur.com/vEKyIgp.png)
        * 雖然車子臨時出狀況。不過能夠及時處理好車子的bug，順利通過check point的關卡，表現非常好。如果希望挑戰滿分，本週上課第一個小時，還會再提供一次check point的試跑機會，5分鐘為限，可以再嘗試看看。

> [name=林坤佑]

## 第十二週紀錄 - 指定題競賽
* 預計完成事項 (必填)
    * Checkpoint
        原先希望checkpoint能夠拿滿120分，但是硬體仍有問題，加上之前想說100分已經很足夠了，因此比較晚準備，所以最後甚至循跡都有問題。
    * 指定專題
        原本預計能夠至少以慢速跑到2分鐘結束，但最後卻發生許多問題。
* 實際達成事項 (必填)
    * 在宿舍測試小地圖
        {%youtube pKjCpCiZnT8 %}
    * 跑完中地圖...1次
        當時仍然硬體時好時壞，每次調參數的結果都相差很多，所以只能完整跑完一次。
    * 指定專題競賽
        指定專題在前面幾天於宿舍測試，常常發生今天可以順利跑完，隔天就又出狀況，儘管上次上課有更換L298N，但是感覺仍然有其他硬體上的問題，直到昨天晚上與今天指定專題競賽前才發現，使得之前調的參數不能適用現在正常的硬體(後面會提到)。最後以170分 & checkpoint100分\*0.8\=80分的慘況收場。
    * [指定專題競賽code](https://github.com/Xuan-Yi/Cornerstone-EECS-Design-and-Implementation-final-project.git)
* 組內討論事項 (必填，如問題、構想、分工合作、時間安排...等等)
    * 將輸入電壓調整為10.0 volt
        由於在試跑時常常發生轉彎轉不過去的問題，所以將電壓調高，嘗試增加直流馬達的穩定度。
    * 換電線
        這大概是我們無法完成指定專題競賽的最大原因。電線大概是我們最意料不到的問題，在多次測試中，一開始左輪常常在循跡、轉彎時卡住，我們百思不得其解，但是之後莫名其妙就又恢復正常，因此我們也沒有再在意左輪的問題。
        5/12指定專題競賽前一天賽前測試時，原本正常的車車突然右輪不轉了，我們發現動一動電線似乎可以改善這個問題，但不久兩輪又出狀況，結果我們發現跳線的頭與電線已近乎90彎折，而且沒有電線應有的韌性，我們才意識到應該是電線接觸不良，換掉ENA、ENB的兩條跳線之後才恢復正常。
        今天指定專題競賽測試時，左右輪又出問題了，有輪子的輸出特別的弱，經過昨天的經驗馬上想到應該是接線的問題，再馬上不論是非的把IN1~4全部得跳線都換掉，果然問題就解決了。
    * 調參數
        我們曾經嘗試調整各種轉彎速度、delay，但是自從我們發現我們電線有問題後，之前調的所有參數完全沒有意義了，這導致之後我們的車車在指定專題競賽中過彎速度過快而轉過頭、循跡「極度」不穩定、轉彎時多偵測到黑色格子而多算步數。這些原因都使得我們最後就算演算法、傳輸都寫好了，卻仍然沒辦法正確跑到指定的地方。
* 組員分工 (必填)
    * 軟體參數調整：吳宣逸、游菖鈺、郭宇庭
    * 硬體技術調整：郭宇庭
    * 硬體Debug：吳宣逸、游菖鈺
    * 軟體程式修改：吳宣逸、游菖鈺、郭宇庭
    * 指定題結果報告：游菖鈺
    * HackMD：吳宣逸
* 遇到問題之處理狀況、解決方式 (必填)
    * 車子進入格子、轉彎前的機制
        一開始我們設定車車偵測到黑色格子時就delay一段時間後停在黑色格子中間，但後來我們發現實際上這樣子抓不準時間，往往對不到我們要的位置，其中一個原因當然是當時我們還沒發現硬體有問題。後來我們讓車車偵測到進格子然後出格子後才停下來，果然這樣設定讓車車比較有辦法停在格子中間。但由於馬達時好時壞，所以實際上後來電壓真的調不準，有時候會讓車車跑出格子，有時候又能夠完美達到我們要的狀態。在競賽前換掉電線之後，我們沒時間調整程式與參數，所以問題仍然在競賽時存在。
        另外，為了維持轉彎的穩定性，我們在轉彎的動作前，都加了一個cool_down_delay，讓馬達完全停止後再轉彎，避免了原先馬達餘速帶來的影響。
        ```c=
        void turn_left()
        {
          while (IR_counter() >= 4)
          {
            MotorWriting(0.8*GO_Tp, 0.8*GO_Tp);
          }
          delay(stop_delay);
          MotorWriting(-GO_Tp, -GO_Tp);
          MotorWriting(0, 0);
          delay(cool_down_delay);
          MotorWriting(-(GO_Tp + 20), GO_Tp);
          delay(turn_delay);
          while (digitalRead(IR2) != 1 && digitalRead(IR1) != 1)
          {
            MotorWriting(-GO_Tp - 20, GO_Tp);
          }
        }
        ```
    * 馬達扭力不足
        在試跑時，常常遇到車車轉彎轉一半就卡住的情形，但往往將電壓調大之後又車速過快爆衝，一開始真的很困擾我們。後來發現若將頂板拆掉再將馬達電壓調降，果然穩定了許多，而在競賽前換掉壞掉的跳線之後，馬達終於恢復正常，能夠以正常速度轉彎和前進了(但參數...QQ)。
* 課程建議 (選填)
    跑過小地圖、中地圖、大地圖、checkpoint地圖之後，發現好像每種紙面的材質都不大相同，而非常不幸的車車輪胎好像對紙的材質滿敏感的，跑起來的結果都不太一樣，雖然說滿強人所難的，但之後假如可以，希望紙的材質能夠相同。
* 想說的話 (選填)
    教授、助教們在設計課程、openlab都辛苦了，就如教授所說，這是一門教授、助教、學生都會很累的課，但從一堆零件變成一台疑似可以走迷宮的車車，其中的成就感真的非常值得。

## 第十二週批閱區 - 指定題競賽
* 助教批閱欄
    * 助教回饋
        * 去年所有地圖(練習、Checkpoint及指定題地圖)都是鋪在地板上的，但我們發現木板材質能改善空轉問題，且能重複使用，今年才會選擇將指定題地圖黏在木板上，沒想到會帶給同學不方便，我們會跟老師討論地圖材質統一的問題。
        * 組內討論跟問題解決寫得超詳細，看得出來你們對指定題的投入及對車車的感情(?)，最後排名沒有很好不要太難過，硬體突然故障是常有的事，考驗臨機應變的能力，相信你們在過程中應該收穫良多~~
        * 謝謝同學對助教和老師的鼓勵:)
> [name=謝兆和]
* 教授批閱欄
    * 評分等第
    A
    * 教授回饋
    最後大地圖結果沒有很好沒關係，過程中有學到東西比較重要。另外還有幾週可以準備自選題，在有限時間內發揮一些創意，好好展現一定的成果，就可以在自選題扳回一城喔。另外這門課真的很累阿，但是看到你們的學長姊都對它有很好的評價，然後每學期開課都爆滿，就讓老師們覺得繼續開下去是很重要的。希望你們之後有機會，可以再來參加車車助教課，精進這門課程內容囉。  :D
> [name=陳君朋]

## 第十三週紀錄 - 自選題介紹
* 預計完成事項 (必填)
    * 討論出自選題的方向
    * 找到一些可能方案
    * 評估難度、在時間內完成的可能性
    * 完成自選題介紹簡報
* 實際達成事項 (必填)
    * 目前大方向是「是否戴口罩的人臉辨識」，並將流程分為1. Camera 2. Processing Level 3. Reaction
    * Camera提出三個方案
        1. Pi Camera
        2. OV7670 + Arduino
        3. ESP32-CAM + OV2640
        4. 網路攝影機
    * Processing Level只有兩種
        1. 筆電
        2. Rpi
    * Reaction目前算滿開放的，可能是比較不需要擔心的部分，暫定是自動門(模擬大樓的自動門)
* 組內討論事項 (必填，如問題、構想、分工合作、時間安排...等等)
    * 各方案優劣
        |Camera|Processing Level|相機像素|價格|
        |-|-|-|-|
        |Pi Camera|Rpi|v1: 500萬像素, v2: 800萬像素|X|
        |OV7670 + Arduino|筆電|30萬像素|OV7670帶FIFO約500元(不帶FIFO約100元)|
        |ESP32-CAM + OV2640|筆電|200萬像素|ESP32-CAM + OV2640約300元左右|
        |網路攝影機|筆電|最基本約200萬像素|約1000元以上|
        最後選擇Pi Camera + Rpi的方案。理由是Rpi基本上就是一台電腦，也能夠做電腦視覺處理，很適合在未來將裝置變成一個移動性的裝置而不需要依賴電腦，而且提供至少500萬像素的Pi Camera真的滿誘人的，所以目前暫定使用此方案。
* 組員分工 (必填)
    * 此次偏向於討論而非實作，三個人都有做到參與討論、提出建設性建議...等事項。
    * 指定題最終報告PPT製作 + 報告：游菖鈺
    * 自選題介紹PPT：吳宣逸、郭宇庭
    * 自選題介紹報告：吳宣逸
* 遇到問題之處理狀況、解決方式 (必填)
    * 目前遇到的問題是由於疫情，並無法確定Rpi的取得方式，因此期望能盡快想辦法拿到Rpi和Pi Camera，開始我們的Project。
* 課程建議 (選填)
    * 目前遇到疫情，課程變成線上並不是大家自願的，實作方面必定也會受到影響，因此非常感謝助教與教授們將自選題改為軟體為主的形式，也期望做後不論是線上或實體，能夠如期展演。
* 想說的話 (選填)
    * 教授與助教們辛苦了，在這樣快速變動的情況下大家都知道不是只有這門課程要顧，但是助教與教授們卻是為了這堂課需要常常開會討論，也需要用自己的時間去作出課程內容，甚至會在非課程時間回覆同學們的問題，實在是非常感下教授與助教們的付出。
    * 而關於Rpi和Pi Camera，不太確定目前情況還有可能回學校拿到這兩樣物品嗎？還有我個人想技術諮詢一下，若是我們將兩個作品分兩地做，我們做後是有辦法使用wifi讓兩塊板子互相溝通的嗎？因為我手邊剛好有ESP32具wifi功能的板子，我猜學校的Rpi應該也有wifi功能，所以或許可以不需要將所有東西交給一人做，不知道可不可行？
    * 最後為遲寫紀錄造成不便感到非常抱歉，下一篇會儘早寫完的！

## 第十三週批閱區 - 自選題介紹
* 助教批閱欄
    * 助教回饋
        * 記得要把你們這禮拜討論的自選題相關事項補上喔~
> [name=鐘民憲]
* 教授批閱欄
    * 評分等第
    A-
    * 教授回饋
    謝謝你們也能夠體諒。車車課老師們上週四就討論要怎麼進行比較好，系主任週五為了疫情特別召開會議，與系上有開實驗課的老師們一同討論解決方案。希望哪天你們當學長姊了，有機會也可以為學弟妹們付出一些，讓愛傳下去這個環境才會越來越好喔。 :D
    我沒有用過 ESP32，但是我用過 Raspberry Pi 與 Pi Camera，這兩個透過 wifi 互通是有可能的，但可能沒有這麼容易，需要花點時間做實驗，但是我不鼓勵同學們群聚，看用什麼方式解決這個問題。另外網路上有很多  Raspberry Pi 與 Pi Camera 資料；分工的好並且發揮各位的創意，才是最重要的囉。加油!
> [name=陳君朋]

## 第十四週紀錄 - 自選題proposal報告
* 預計完成事項 (必填)
    * Proposal
        * 甘特圖
        * 開銷報表
    * 拿到Rpi和Pi Camera硬體，並且弄清楚使用方法
    * 完成Python找到無罩惡徒
    * 完成Arduino硬體 (+ 軟體)
* 實際達成事項 (必填)
    * 甘特圖

        ```mermaid
        gantt
            title Gantt
            dateFormat  YYYY-MM-DD
            axisFormat  %m-%d
            section Proposal
                決定初步方案: done, 2021-05-19,2021-05-24
                Python找到圖片中人臉: done, a1, 2021-05-23,2021-05-24  
            section 進度報告1 (6/2)
                完成Arduino硬體雛形+軟體雛形: done, a5, 2021-05-26, 4d
                完成Arduino包括3D列印的整體硬體: active, crit,a7, after a5, 3d
                完成Python程式(方案二, 不甚理想): done, a2, after a1, 2021-05-29
                完成Python程式(方案一): active, crit, a6, after a2, 6d
                湊齊硬體: crit, a3, 2021-05-23, 2021-06-03
            section 進度報告2 (6/9)
                實際跑Rpi: after a3, 2021-06-16
            section 期末考+測試
                測試口罩辨識並修改程式: after a4, 2021-06-16
                測試Arduino程式 + 硬體: after a7, 2021-06-16
                自選題展示:  2021-06-30, 13h
        ```
    * 開銷報表
        |名稱|數量|單項金額|總金額|備註|
        |-|-|-|-|-|
        |Arduino|1|X|X|吳宣逸提供|
        |mg90s|2|X|X|吳宣逸提供|
        |無源蜂鳴器|1|X|X|吳宣逸提供|
        |HC05|1|X|X|吳宣逸提供|
        |Rpi|1|X|X|EE提供|
        |pi camera|1|X|X|EE提供|
        |電腦螢幕|1|X|X|郭宇庭提供|
        |HDMI線|1|X|X|郭宇庭提供|
        
    * opencv、dlib安裝方法
        [README](https://github.com/Xuan-Yi/Covid-19-mask-doorVguard/blob/893a884a594595b18303fb81c141ff27fcfb2bb2/README.md)
    * Facial Recognition (Python)
        * 此採用的是**方案2**，也就是使用dlib現成的臉部辨識，切割上2/3與下1/3，進行色差比對。
        * [python code (方案2)](https://github.com/Xuan-Yi/Covid-19-mask-doorVguard/blob/e775945d5f0c5b172603950bd52472b354ac392e/2020_5_29%20facial%20recognition%20python%20code%20test%201%20(%E6%96%B9%E6%A1%882).py)
        * 測試紀錄(2021/05/29){%youtube FI8rOzmMHXA %}    
        
    * Automatic Door (Arduino)
        * [arduino code](https://github.com/Xuan-Yi/Covid-19-mask-doorVguard/blob/9193a4519a3bf349131b6e67e4cc159feda77f82/arduino_automatic_door.ino)
        * 測試紀錄(2021/05/29){%youtube _FNTVsd6Ous%}
        * 目前正在設計3D列印所需模型(門、本體)，以下是除3D列印以外，所需的材料。
            |材料名稱|數量|
            |-|-|
            |Arduino Nano|1個|
            |HC05 藍芽模組|1個|
            |mg90s 伺服馬達|2個|
            |無源蜂鳴器|1個|
        * Arduino 硬體接線
            * 無源蜂鳴器 (buffer)
                |buffer|Arduino Nano|
                |-|-|
                |+|D9|
                |-|GND|
            * mg90s伺服馬達 (servo)
                [mg90s datasheet](https://www.electronicoscaldas.com/datasheet/MG90S_Tower-Pro.pdf)
                |mg90s|Arduino Nano|
                |-|-|
                |橘線|左門：D6，右門：D5|
                |紅線|5V|
                |棕線|GND|
            * HC05 藍芽模組
                |HC05|Arduino Nano|
                |-|-|
                |TX|D7|
                |RX|D8|
                |VCC|5V|
                |GND|GND|
                

* 組內討論事項 (必填，如問題、構想、分工合作、時間安排...等等)
    * Demo形式
        * 由於Arduino與Rpi硬體分屬兩地，所以我們最後討論出的Demo方式是分兩個部分
            1. Rpi部分展示能夠利用Rpi、影像辨識做人臉辨識，並且能夠分辨出有戴口罩與無戴口罩的差別，並且將影像標示後用HDMI傳輸到螢幕上顯示。
            2. Arduino部分需要用筆電的相機，使用Windows 10跑Python程式(與Rpi相同)，最後用電腦藍芽連結Arduino執行動作。
        * 這樣Demo的形式能夠證明
            1. 能夠在Rpi跑臉部辨識程式，並顯示出來
            2. 能夠用筆電讓程式跑臉部辨識，並由Arduino做出動作
            3. 若能達到上述兩點，大概就能夠做成獨立的人臉辨識系統了！
    * 臉部辨識方法我們提出兩個方案
        1. 使用臉部辨識dlib標記landmarks與未戴口罩的圖片庫[圖片生成網站](https://thispersondoesnotexist.com/)，P上口罩之後製造出有戴口罩的圖片庫，利用這兩個圖片庫訓練模型，使用此模型進行影像辨識。
        2. 使用dlib現成的臉部辨識，切割上2/3與下1/3，進行色差比對。
        
* 組員分工 (必填)
    * 吳宣逸：Arduino部分、HackMD
    * 郭宇庭：Python程式
    * 游菖鈺：Python程式、製作進度報告PPT
* 遇到問題之處理狀況、解決方式 (必填)
    * 目前我們做出的是方案二的成品，此方案的好處是方便簡單，但從上方Demo可以看出並不是非常靈敏，而且在偵測不到人臉時簡直沒輒。儘管還有很大改進空間，但基於不要惹自己的麻煩，我們將著手方案一，以求達到更好的效果。
* 課程建議 (選填)
    * 目前網路上課，品質都超乎原本預期，或許是本來這堂課本來就相對依賴課後討論，希望這個習慣能夠延續(雖然說應該是不得不)。
    * 網路課程目前進行的還不錯，但或許可以開放同學留言發問，或者開麥克風發問，幫助各組同學找出不足之處。
    * 但還是得顧及尚可時間的問題，提出此建議僅供參考。
* 想說的話 (選填)
    * 最後採用寄送Rpi的方式，一定帶給教授、助教們很大的不方便，但是卻是最理想的方式，真的很感謝助教教授。
    * Python一開始我們使用方案二進行臉部辨識，然而如上影片，若是偵測不到臉部就沒轍了。這迫使我們必須採取較複雜的方案，而接近期末事情越來越多，時間越發吃緊，期望我們能夠趕上我們的甘特圖。

## 第十四週批閱區 - 自選題proposal報告
* 助教批閱欄
    * 助教回饋
        * 把demo拆成兩個部分雖然是不得已之下的調整，但是基本上電腦跟arduino端沒問題的話，最後(如果你們在demo之後還會繼續完成它的話)rpi跟arduino的整合應該也不會有甚麼困難。
        * 原本很擔心車車課改成遠距上課會不會讓你們的學習大打折扣，看到你們的回饋就放心了，希望你們到學期末都能繼續維持積極討論的習慣!加油!
> [name=宋馨慈]
* 教授批閱欄
    * 評分等第
        * A-
    * 教授回饋
        * 各組報告應該也是要開放同學發問，共同討論。這部分我們這兩週疏忽了，接下來的課程會在各組報告完後，也詢問同學是否有問題或建議。謝謝你們提醒。
        * 辨識雖然還不是很靈敏，不過有看到基本的雛型了，加油。
> [name=林坤佑]

## 第十五週紀錄 - 自選題進度報告
* 預計完成事項 (必填)
    * 這禮拜希望測試兩種程式
        1. 辨識眼睛，再由眼睛往下抓嘴巴位置，判斷是否戴口罩，若辨識眼睛品質不錯，將採用此方案(姑且稱方案3)。
        2. 使用現成圖片庫與口罩圖片自動生成with-mask圖片庫，並訓練自己的model，以克服無法辨識臉部的問題。
    * 另外由於雖然這個系統的末端(目前是自動門開關)有諸多變化，但老實說仍然找不到更多更具延伸性、更實際的應用，因此期望能夠為這個系統找到更好的應用。
* 實際達成事項 (必填)
    * 甘特圖

        ```mermaid
        gantt
            title Gantt
            dateFormat  YYYY-MM-DD
            axisFormat  %m-%d
            section Proposal
                決定初步方案: done, 2021-05-19,2021-05-24
                Python找到圖片中人臉: done, a1, 2021-05-23,2021-05-24  
            section 進度報告1 (6/2)
                完成Arduino硬體雛形+軟體雛形: done, a5, 2021-05-26, 4d
                完成Python程式(方案二, 不甚理想): done, a2, after a1, 2021-05-29
                湊齊硬體: active, a3, 2021-05-23, 2021-06-03
            section 進度報告2 (6/9)
                實際跑Rpi: after a3, 2021-06-16
                完成Arduino包括3D列印的整體硬體: done, a7, after a5, 3d
                Python程式(方案一)：P上口罩: done, a6, after a2, 2021-06-07
                Python程式(方案一)：訓練模型: active, crit, after a6, 6d
            section 期末考+測試
                Python程式(方案一)：臉部辨識: active, crit, after a6, 6d
                測試口罩辨識並修改程式: after a4, 2021-06-16
                測試Arduino程式 + 硬體: done, after a7, 2021-06-16
                自選題展示:  2021-06-30, 13h
        ```
    * 目前方案二因為效果不佳被砍掉，方案一因為較為麻煩所以進度較為緩慢，而在經過上次進度報告我們將會測試方案三，以下是目前方案整理
        1. 使用臉部辨識dlib標記landmarks與未戴口罩的圖片庫[~~圖片生成網站~~](https://thispersondoesnotexist.com/)，P上口罩之後製造出有戴口罩的圖片庫，利用這兩個圖片庫訓練模型，使用此模型進行影像辨識。
            * 目前不使用上述的圖片生成網站，因為其中可能參雜了肉眼看不到的問題，所以現在是使用下面參考source code的資料庫圖片。
            * [參考source code](https://github.com/prajnasb/observations.git)
            * [參考網站](https://www.pyimagesearch.com/2020/05/04/covid-19-face-mask-detector-with-opencv-keras-tensorflow-and-deep-learning/)
        3. ~~使用dlib現成的臉部辨識，切割上2/3與下1/3，進行色差比對。~~
        4. 辨識眼睛，從眼睛位置下推嘴部，然後使用與方案二相同的方式辨識口罩，希望能夠克服偵測不到臉部的問題。
    * Automatic Door (Arduino)
        * [Code (arduino)](https://github.com/Xuan-Yi/Covid-19-mask-doorVguard/blob/fb9f07de66f70820ff51f097aea54a90f0ad60d5/arduino_automatic_door.ino)
        * 3D printing
            * [box segment](https://github.com/Xuan-Yi/Covid-19-mask-doorVguard/blob/6e23306aa318b12e141880dd8f80f22b0c011469/automatic%20door%20box%20-%20simplified%20version.stl)
            * [part1](https://github.com/Xuan-Yi/Covid-19-mask-doorVguard/blob/6e23306aa318b12e141880dd8f80f22b0c011469/door1.stl)
            * [part2](https://github.com/Xuan-Yi/Covid-19-mask-doorVguard/blob/6e23306aa318b12e141880dd8f80f22b0c011469/door2.stl)
            * 最原始的設計圖(後來我直接在檔案上修改，所以沒有新的紙本設計圖)![](https://i.imgur.com/LCH0asS.jpg)

        * Demo
            {%youtube t9NbY87SDeo %}
    * Data Generator
        * Code (Python)
            * [loop_through_folder.py](https://github.com/Xuan-Yi/Covid-19-mask-doorVguard/blob/fc29f176f80bbe1b7c7f97720773075e556f976c/loop_through_folder.py)
            * [mask.py](https://github.com/Xuan-Yi/Covid-19-mask-doorVguard/blob/fc29f176f80bbe1b7c7f97720773075e556f976c/mask.py)
        * 修改Prajna Bhandary的函式庫[observations](https://github.com/prajnasb/observations.git)中的[loop_through_folder.py](https://github.com/prajnasb/observations/blob/cdcf4501bf7fdec7ac8a4ee245e343b187fa53c7/mask_classifier/Data_Generator/loop_through_folder.py)與[mask.py](https://github.com/prajnasb/observations/blob/cdcf4501bf7fdec7ac8a4ee245e343b187fa53c7/mask_classifier/Data_Generator/mask.py)兩支程式而成，大致結構都沒改變，主要改變有
            1. 修改掉能夠在cmd執行(功能看起來應該是吧)的部分，避免不必要的麻煩，畢竟我們上禮拜經歷失敗就比別人耗費一個禮拜的時間了，但主要改掉的程式碼比較偏UI的部分，若沒這段也只需要修改一些檔案路徑就好，還算方便，也少import了3個函式庫。
            2. 關於旋轉口罩mask(或圖片)的程式，原作者Prajna Bhandary使用[Pillow (PIL)](https://pypi.org/project/Pillow/)函式庫中的```rotate```函式，而取口罩mask旋轉角度使用的是numpy的```arctan2```函式，其中```rotate```使用的參數```angle```是角度，而```arctan2```回傳的是弧度，所以一開始原作者沒有做轉換，這是第一個錯誤修正。接著會發現，若要正確旋轉，應該旋轉角度是```90-angle*180.0/np.pi```，經過修正後，終於口罩可以轉到正確角度了。
            3. 原作者使用在```face_recognition```的```face_locations```中使用的原模型是比較輕量但不準確的臉部辨識模型```hog```，而我改使用```cnn```這個模型以提高精準度。
        * 目前有三種口罩mask
            |white-mask.jpg|blue-mask.jpg|black-mask.jpg|
            |-|-|-|
            |![](https://i.imgur.com/KVoPeC0.png)|![](https://i.imgur.com/MXwHlzr.png)|![](https://i.imgur.com/QX0tt87.png)|
            三種mask皆是必須是透明底才能被PIL使用(不然似乎會被PIL嫌mask不夠透明)
        * 以下是目前已生成的資料庫中的幾個成功的範例
            |without-mask.jpg|white-mask.jpg|blue-mask.jpg|black-mask.jpg|
            |-|-|-|-|
            |![](https://i.imgur.com/6v4c3uh.jpg)|![](https://i.imgur.com/ASY9ATK.jpg)|![](https://i.imgur.com/EGTfFUx.jpg)|![](https://i.imgur.com/KGewJDW.jpg)|
            |![](https://i.imgur.com/arCmzqK.jpg)|![](https://i.imgur.com/jOWBxX4.jpg)|![](https://i.imgur.com/VKlam9Q.jpg)|![](https://i.imgur.com/TihwbbZ.jpg)|
        * 對於訓練模型，網路上有提到有戴口罩與沒戴口罩不要使用相同圖片，也就是上面的圖片勢必不能直接全部拿來訓練，在Prajna Bhandary用來訓練的data中還安插不少真實的戴口罩肖像，但這是之後的課題。
    * 偵測眼睛方案 (方案三)
        * 下載網路上訓練好專門找尋圖片眼睛的model，雖然可以順利找到照視訊畫面中人臉的兩顆眼睛，但是程式並不會自己判斷兩個眼睛是在同一張臉上，導致無法簡單算出兩眼距離並依照比例去畫出一個理想的矩形，而我們就此想到兩個解決方案。![](https://i.imgur.com/NhaRqVr.png)
            1. 可以利用opencv找左眼或是右眼的模型，這樣可以確保每張人臉都只會判讀到一個眼睛，這樣就可以避免重複判讀同一張臉的問題。
           2. 可以利用其他函式庫先將眼睛的輪廓都標定後再計算出兩顆眼睛的距離，這種方法的好處式可以較好劃出判斷有無戴口罩的矩形，但是缺點是如果沒有找到兩顆眼睛的話可能就還是沒有辦法判讀正確，類似於找不到臉的情況。![](https://i.imgur.com/wYaWasC.png)

* 組內討論事項 (必填，如問題、構想、分工合作、時間安排...等等)
    * 雖然目前最大的問題是臉部辨識軟體，但我們開門關門實在過於基本，因此針對延伸應用也有提出一些方法，以下是各式提案，但仍有滿多不合適的地方。
        1. 自動門
            * 作為大樓或商店門口自動檢查哨，若是有人未戴口罩便會自動關閉，也是目前已做出的方案。
            * 有點小無聊
        2. 疊加紅外線測溫影像
            * 目前最大問題是除了紅外線攝影機之外，可能還做不到
            * 所以希望以概念的方式呈現
            * 目前還想不到該如何模擬出類似的效果
        3. 在公共場所(例如車站)建立系統，以user interface監察各地沒戴口罩的民眾
            * 希望能夠減少警察、站務員負擔
            * 肯定會造成恐慌與反彈
            * 可行性、實用性不高
* 組員分工 (必填)
    * 吳宣逸：Arduino自動門部分、HackMD、Python(方案一)
    * 郭宇庭：Python程式(方案三)
    * 游菖鈺：Python程式(方案一)、製作進度報告PPT
* 遇到問題之處理狀況、解決方式 (必填)
    * 3D列印自動門時，門板經過4次大修改，門主體印壞兩次(前兩次理論上分別大約皆需要至少3小時)+一次印錯(計算錯誤導致)
        * 門板由於用料極少，所以能夠快速更改設計檔，在花費一些時間之後仍然在兩天中克服了。
        * 門主體第一次是由於PLA線材不知道為什麼中間有個瘤狀突起，所以卡住進料，在排除時不小心動到Z軸，所以整個報銷了。第二次是可能由於室內溫度過高或單純噴頭堵塞而無法出料，使得印到超過一半後整個報廢。第三次由於有開冷氣，所以有成功印完，但印完後發現尺寸不合(網路上mg90s的datasheet騙我QQ)，到了第四次修改設計，將多餘部分省去，壓低印刷時間，並經過再三檢查尺寸，終於得到我要的東西了！
            * 第四次的設計相較原始設計輕量，優點是不容易印壞![](https://i.imgur.com/iZGy7tf.jpg)
    * 關於Data Generator的小問題皆在「目前達成事項」中提及了，而較大的問題有兩個
        1. 有些圖片不知道為什麼口罩位置非常奇怪，例如以下幾張。這些照片的共同點是頭部有較大的扭轉，但奇怪的是有其他照片也有類似幅度的扭轉，卻不會發生這種狀況，另外一種是照片陰影較多，造成判讀困難，但這些照片應該可以刪除，不會有太大的影響。
            |臉上陰影多|側臉|臉上陰影多+側臉|不明原因|
            |-|-|-|-|
            |![](https://i.imgur.com/lb36FKr.jpg)|![](https://i.imgur.com/Ev5SHkq.jpg)|![](https://i.imgur.com/ugkF8sK.jpg)|![](https://i.imgur.com/vmmhhPT.jpg)|
        2. 要跑影像辨識真的真的超耗資源的，光是跑完600多張照片就至少3、4個小時，而Nvidia的Cuda和Cudnn又超難裝，裝了兩次都差點弄壞dlib，從工作管理員看到兩顆GPA幾乎是在偷懶，兩顆風扇又嗡嗡轉不停，雖然目前也沒要做其他事情所以電腦放著讓它跑也關係，但這樣效率真的超低的，目前還是找不到解決方式(裝Cuda + Cudnn好難：<)。![](https://i.imgur.com/QsSVWID.png)
            * 6/7 22:43更新
                剛才重新使用WSL2下去執行，不知道為什麼CPU竟然效能被催到100%，不過也可能不是因為WSL2才加速的。
                另外剛才也花了一些時間在WSL2上安裝python、cmake、dlib、cuda、cudnn、numpy等套件，但做到一半才發現，除非我使用到dlib，不然cuda、cudnn好像也不會做事，但後來使用WSL2速度變快真的滿開心的。

* 課程建議 (選填)
    * 對於最後的專題展示，希望助教和教授能夠給個大致的方向，例如過去有哪種展示方式效果看起來比較好，或者比較適用大部分專題的展示方式。
    * 上禮拜的經驗課末小組討論，突然覺得效果並不如實體課的課末小組討論效果好，原因應該是沒有地點的限制性，使得和課後討論沒有太大的差別(除了有助較會來提供不錯的建議之外：>)，所以還是覺得實體課絕對比網課效果好很多，之後疫情退了可以讓學弟妹有更多的共同實體空間、時間。
* 想說的話 (選填)
    * 現在真的漸漸發現網路課程缺少了實體課程的臨場感，不論如何都是如此，而且會漸漸怠惰，回到家後作息也變得不適合讀書(變得太正常了)，連帶地影響到做專題的時間，正常作息真的太可怕了。
    * 我們這次的是一直試驗，總共現在需要試錯三種方法，一種已經被否決掉了，而另一種並不實際，所以現在應該只剩下最麻煩的方式了，如果再失敗的話真的只能不斷找新模型或新資料庫了，玩影像辨識真的滿可怕的(尤其是變化那麼大的臉)。
    * 想請問教授或助教是否已經有能夠在Windows 10的VScode使用GPU(Nvidia的為佳，Intel內建的GPU也可以)跑```facial-recognition```和```dlib```？或者若能直接讓電腦能夠自動分配CPU與GPU的更佳，如果有的話是否能夠提供教學影片？
## 第十五週批閱區 - 自選題進度報告
* 助教批閱欄
    * 助教回饋
        * 紀錄很完整，特別是關於口罩辨識的部分，一些太 technical 的部分我看不太懂，可能要你們自己想想。
        * 這次線上成果展示，我們也很難提供建議，大家都不太清楚怎麼做，或許可以參考一些知識型Youtuber的作法吧?)
        * 前幾年自選題發表前，助教都會不斷加開 open lab 時段，明達402也幾乎永遠都有人在工作。遠距教學對任何一門課而言都很不方便，特別是實驗課，但大家的時間彈性也遠比以前大，希望你們能利用這次疫情學好時間管理XD
        * 你們的強項在於口罩影像辨識，門就算沒做出來也沒關係。只要確保蜂鳴器會響、門鎖會開等功能有正確執行就好。
> [name=謝兆和]
* 教授批閱欄
    * 評分等第
    A
    * 教授回饋
    在現在疫情的情況，其實老師們也很難給出什麼指示，像是一定要達成什麼樣子的規劃，或是一定非要有什麼樣的內容...(因為這可能會有公平性的問題)，所以各位能做的，就是在這些有限的環境下，儘量去展現各位的成果。
    評分也不會是只有我們幾個老師評，所以大多數老師都看出你們的創意與用心，那最後自選題的成績一定不會差。加油喔。
> [name=陳君朋]

## 第十六週紀錄 - 自選題進度報告
* 預計完成事項 (必填)
    * 更新訓練圖片庫
    * 完成訓練模型
    * 讓程式可以在筆電上，使用鏡頭判斷是否戴口罩
    * 大概弄清楚Rpi運作時會發生什麼事
* 實際達成事項 (必填)
    * 甘特圖

        ```mermaid
        gantt
            title Gantt
            dateFormat  YYYY-MM-DD
            axisFormat  %m-%d
            section Proposal
                決定初步方案: done, 2021-05-19,2021-05-24
                Python找到圖片中人臉: done, a1, 2021-05-23,2021-05-24  
            section 進度報告1 (6/2)
                完成Arduino硬體雛形+軟體雛形: done, a5, 2021-05-26, 4d
                完成Python程式(方案二, 不甚理想): done, a2, after a1, 2021-05-29
                湊齊硬體: done, a3, 2021-05-23, 2021-06-03
            section 進度報告2 (6/9)
                實際跑Rpi: active, after a3, 2021-06-16
                完成Arduino包括3D列印的整體硬體: done, a7, after a5, 3d
                Python程式(方案一)：P上口罩: done, a6, after a2, 2021-06-07
                Python程式(方案一)：訓練模型: done, after a6, 6d
            section 期末考+測試
                Python程式(方案一)：臉部辨識: done, after a6, 6d
                測試口罩辨識並修改程式: done,after a4, 2021-06-16
                測試Arduino程式 + 硬體: done, after a7, 2021-06-16
                自選題展示:  2021-06-30, 13h
        ```
    * Demo
        {%youtube uXLE35Vj9mg %}
    * 更新訓練圖片庫
        * 程式(無更新)
            1. [mask.py](https://github.com/Xuan-Yi/Covid-19-mask-doorVguard/blob/9684b66df9e32ae600baea2ff72b1c4edb53d52a/mask.py)
            2. [loop_through_folder.py](https://github.com/Xuan-Yi/Covid-19-mask-doorVguard/blob/9684b66df9e32ae600baea2ff72b1c4edb53d52a/loop_through_folder.py)
        * 圖片庫(最後是從其中揀選部分成功的圖片，並未採用全部圖片)
            1. [without_mask.zip](https://drive.google.com/file/d/18h5kHHEtnLTKGvCpISFZGFjLNh8uG-Wx/view?usp=sharing)
            2. [images.zip](https://drive.google.com/file/d/11gebLksGGlNDXUsM0tQ4r4wusQ4k2Yzy/view?usp=sharing)
        * 更新項目
            1. 增加口罩樣式

                |black-mask.png|blue-mask.png|green-mask.png|white-mask.png|
                |-|-|-|-|
                |![](https://i.imgur.com/1Use1ZR.png)|![](https://i.imgur.com/H7PoJmq.png)|![](https://i.imgur.com/o9Aw9ru.png)|![](https://i.imgur.com/zVtsitd.png)|
            1. 增加更多東亞人(韓國、中國、香港(？)、台灣)面孔
                |韓國|中國|台灣|
                |-|-|-|
                |![](https://i.imgur.com/Zy6wuOv.jpg)|![](https://i.imgur.com/gebQXVV.jpg)|![](https://i.imgur.com/VGdWoOQ.jpg)|
            3. 增加寶寶、年長者的臉
                |寶寶|年長者|
                |-|-|
                |![](https://i.imgur.com/wFDcbQV.jpg)|![](https://i.imgur.com/1I3NWa7.jpg)|
            5. 增加怪異的表情(如吳宗憲、meme)
                ![](https://i.imgur.com/edV8cPP.jpg)
            7. 一張照片出現多人
                ![](https://i.imgur.com/hczCk2G.jpg)![](https://i.imgur.com/JvvsXYB.jpg)
            11. 增加真實戴口罩的人
                ![](https://i.imgur.com/ToMSvHK.jpg)
        * 在使用這些不同的照片之後，不確定會不會有明顯的效果，但是我們選擇相信多少有幫助。
        * 這些圖片訓練出的模型精確度，最高達到0.994253。原先不使用這些較特殊的圖片，並且都使用藍色口罩訓練，**對於藍色口罩**的精確度雖然達到1.0，但無法辨識其他顏色，而且也缺乏實戰性(缺少一些特殊面孔)，1.0這個數字也不能代表什麼，因此採使用這樣新型態的資料庫。
            * 更新：模型精確度已能達到1.0
    * 訓練模型
        * 程式
            1. [training.ipynb](https://github.com/Xuan-Yi/Covid-19-mask-doorVguard/blob/8d7076b0cbac1a84349555bff7ccf6ff4a25fd1a/training.ipynb)
        * 訓練資料庫 (與training.ipynb放在同一層)
            1. [experiments.zip](https://drive.google.com/file/d/1hIF20_zFoS-TAJ3BmJ3HSJ0dTFR9CPvi/view?usp=sharing)
        * 目前訓練的模型(acc=1.0)
            1. [mask_recognition_model.pth](https://drive.google.com/file/d/1iRQ3-7Vn1hATtzjIhWjpQH5LKY8YE0SK/view?usp=sharing)
            
            顯示資訊：
            ```python=
            Epoch 0/19
            ----------
            train Loss: 0.4079 Acc:0.8993

            test Loss: 0.0068 Acc:1.0000

            Epoch 1/19
            ----------
            train Loss: 0.2306 Acc:0.9455

            test Loss: 0.0071 Acc:1.0000

            Epoch 2/19
            ----------
            train Loss: 0.2103 Acc:0.9373

            test Loss: 0.0066 Acc:1.0000

            Epoch 3/19
            ----------
            train Loss: 0.1974 Acc:0.9439

            test Loss: 0.0175 Acc:0.9887

            Epoch 4/19
            ----------
            train Loss: 0.2298 Acc:0.9398

            test Loss: 0.0064 Acc:1.0000

            Epoch 5/19
            ----------
            train Loss: 0.2362 Acc:0.9414

            test Loss: 0.0103 Acc:0.9887

            Epoch 6/19
            ----------
            train Loss: 0.2490 Acc:0.9431

            test Loss: 0.0062 Acc:1.0000

            Epoch 7/19
            ----------
            train Loss: 0.3014 Acc:0.9307

            test Loss: 0.0066 Acc:1.0000

            Epoch 8/19
            ----------
            train Loss: 0.2146 Acc:0.9431

            test Loss: 0.0056 Acc:1.0000

            Epoch 9/19
            ----------
            train Loss: 0.1978 Acc:0.9439

            test Loss: 0.0065 Acc:1.0000

            Epoch 10/19
            ----------
            train Loss: 0.2407 Acc:0.9307

            test Loss: 0.0059 Acc:1.0000

            Epoch 11/19
            ----------
            train Loss: 0.2577 Acc:0.9266

            test Loss: 0.0078 Acc:1.0000

            Epoch 12/19
            ----------
            train Loss: 0.1921 Acc:0.9389

            test Loss: 0.0070 Acc:1.0000

            Epoch 13/19
            ----------
            train Loss: 0.2699 Acc:0.9315

            test Loss: 0.0065 Acc:1.0000

            Epoch 14/19
            ----------
            train Loss: 0.1712 Acc:0.9488

            test Loss: 0.0064 Acc:1.0000

            Epoch 15/19
            ----------
            train Loss: 0.2273 Acc:0.9315

            test Loss: 0.0063 Acc:1.0000

            Epoch 16/19
            ----------
            train Loss: 0.2220 Acc:0.9480

            test Loss: 0.0059 Acc:1.0000

            Epoch 17/19
            ----------
            train Loss: 0.2239 Acc:0.9332

            test Loss: 0.0093 Acc:1.0000

            Epoch 18/19
            ----------
            train Loss: 0.2543 Acc:0.9257

            test Loss: 0.0060 Acc:1.0000

            Epoch 19/19
            ----------
            train Loss: 0.2133 Acc:0.9488

            test Loss: 0.0065 Acc:1.0000

            Training complete in 15.000000m 6s
            Best val acc: 1.000000
            ```

        * 資料夾架構
            ```
            Model_Generator
                |_training.ipynb
                |_experiments
                    |_data
                        |_with_mask
                        |_without_mask
                    |_dest_folder
                        |_train    (training.ipynb自動產生)
                            |_with_mask
                            |_without_mask
                        |_test    (training.ipynb自動產生)
                            |_with_mask
                            |_without_mask
                        |_training.csv
                        |_test.csv
            ```
            將training.ipynb與experiments放在同一層資料夾中，在training.ipynb中將路徑設定好便可生成模型。
            例如在我的電腦中，data、dest_folder的路徑是
            ```python=
            experiments_path = "D:/NTUEE/g1s/電資工程設計與實作(車車課)/自選專題 Arduino/Model_Generator/experiements/dest_folder/" # dest_folder
            data_path = "D:/NTUEE/g1s/電資工程設計與實作(車車課)/自選專題 Arduino/Model_Generator/experiements/data/" # data
            ```
        * 程式結構概說
            * 這個程式是一個基本的(？)分類器，使用1212張照片訓練、177張照片測試，精確度已達到1.0。
            * data資料夾、dest_folder資料夾
                dest_folder資料夾中的training.csv與test.csv分別記錄之後用來訓練與測試的圖檔在data資料夾的子資料夾：with_mask、without_mask中的名稱以及類別(witj_mask、without_mask)。之後training.ipynb會根據兩個.csv檔的內容在dest_folder中建立兩個子資料夾：train、test並且在其中皆再建立子資料夾：with_mask、without_mask，然後依照.csv檔的內容將圖片從data資料夾複製過去。
                之後train、test兩個資料夾將被作為image_dataset，而with_mask、without_mask兩個子資料夾將被作為class。
                ```python=
                # 建立數據集字典
                image_datasets = {x: datasets.ImageFolder(os.path.join(experiments_path, x), data_transforms[x]) for x in ['train', 'test']}
                ```
                ```python=
                class_names = image_datasets['train'].classes # with_mask、without_mask
                ```
                ```python=
                # 定義dataloader字典
                dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], 
                                                             batch_size=14, # 一次讀取的資料數(訓練時每次平行處理1 batch的資料) (若GPU記憶體無法負荷則改小)
                                                             shuffle=True, # reshuffle the data at every epoch
                                                             num_workers=4) # 載入檔案所用的子進程(subprocess)數
                               for x in ['train', 'test']}
               ```
            * 使用GPU運算(cuda)，模型使用resnet101下去修改成2種類別、損失函數(criterian)使用CrossEntropyLoss()、優化算法(optimizer)用SGD(stochastic gradient descent)、學習率調整函數是StepLR()。
                1. 使用GPU運算可以有效降低運算時間
                    ```python=
                    # 指定資料記憶體位置(應該可以理解成處理的裝置)
                    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
                    ```
                2. 使用已訓練的resnet101模型修改，能夠降低訓練時間，不用從頭開始。
                3. 損失函數用來計算模型所預測的結果，與實際照片分類的誤差(例如標準差就可以算是一種損失函數)，損失函數提供optimizer調整模型權重的依據。
                4. optimizer我認為算是此訓練的中心物件，optimizer使用損失函數修改模型。這裡使用的是**隨機梯度下降法(SGD)**，但PyTorch的SGD卻又不是標準的SGD，它多了momentum可選擇，momentum能夠使得在同方向上，學習速度增快，而且也可以幫助避免學習卡在局部最佳解。另外**學習率(learning rate, lr)** 亦是機器學習重要的參數。在此算法中，權重變化按下方公式給出(如果我查的資料沒錯的話)：$$V = momentum \cdot V-lr \cdot \frac{\partial\ 損失函數}{\partial\ 權重}$$$$權重 = 權重 + V$$這應該是個張量運算，但真正運作機制如何就不太清楚了。
                5. 學習率調整函數(lr_scheduler)用來調整學習率，因為在越接近最佳解前，若是學習率太大的話，很容易錯過最佳解，在未接近最佳解前，若學習率太小則會需要跑很久。因此透過學習率調整函數在固定epoch後就將學習率乘上固定倍數，維持較佳的學習速率。
                    ```python=
                    # 使用已訓練的模型：resnet101
                    model_ft = models.resnet101(pretrained=True)

                    # 修改resnet101模型
                    num_frts = model_ft.fc.in_features # 提取fc層的固定參數
                    model_ft.fc = nn.Linear(num_frts, len(class_names)) # 將維度從num_frts修改為len(class_names)=2，也就是將原本resnet101模型的fc層1000種類別改成我們要的兩種類別：with_maask、without_mask

                    model_ft = model_ft.to(device) #將模型轉移到device('cpu'或'cuda')上
                    criterion = nn.CrossEntropyLoss() # 使用損失函數CrossEntropyLoss()，loss可代表模型與實際狀況的誤差

                    optimizer_ft = optim.SGD(model_ft.parameters(), lr=0.02, momentum=1.0) # 使用SGD優化算法，lr(learing rate) = 0.01，動量 = 0.9
                    exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=0.1) # 使用學習率調整函數StepLR()，每step_size個epoch會將學習率調整為gamma倍
                    ```
                6. 學習率、momentum、step_size、gamma都是重要參數，只有調整適當才能得到最佳的模型。例如最一開始我用原作者的數據：lr = 0.01、momentum = 0.9，預測精確度一值無法達到1.0，但調整成lr=0.02、momentum = 1.0之後，就成功了。
                7. 其他內容見[training.ipynb](https://github.com/Xuan-Yi/Covid-19-mask-doorVguard/blob/44a6e5e4c71b6adcc3ce908183f1074e3860ced4/training.ipynb)中的註解。
                8. 最後參考test準確度決定是否保留該epoch中optimizer修改後的模型。
                    ```python=
                    running_loss += loss.item() * inputs.size(0) # lose.item()將loss從tensor轉成float32，loss.item()*batchsize = loss in abatch
                    running_corrects += torch.sum(preds == labels.data) # 計算模型結果與實際的相似度(？)
                    ```
                    ```python=
                    epoch_loss = running_loss / dataset_sizes[phase] # 此epoch中的損失(與真實數據的落差)
                    epoch_acc = running_corrects.double() / dataset_sizes[phase] # 此epoch中的精確度
                    ```
                    ```python=
                    # 若此次訓練模型較好，則取代舊模型
                    if phase == 'test' and epoch_acc > best_acc:
                        best_acc = epoch_acc
                        best_model = copy.deepcopy(model.state_dict()) # 紀錄最佳模型
                    ```
            * 訓練方法總結
                * 使用預訓練的模型，調整成2 classes的分類器
                * 損失函數在每個epoch都評估一次模型的loss，optimizer根據損失函數判斷如何修改模型權重
                * 學習率調整函數定期下修學習率
                * 若是該輪的預測準確度較高，則取代舊模型，共跑20個epoch。
    * 筆電鏡頭判斷是否戴口罩
        * 程式
            1. [label_detect.py](https://github.com/Xuan-Yi/Covid-19-mask-doorVguard/blob/8d7076b0cbac1a84349555bff7ccf6ff4a25fd1a/label_detect.py)
            2. [webcam_detect.py](https://github.com/Xuan-Yi/Covid-19-mask-doorVguard/blob/8d7076b0cbac1a84349555bff7ccf6ff4a25fd1a/webcam_detect.py)
        * 程式
            1. 主程式為 webcam_detect，在 while迴圈中呼叫位於 label_detect 裡的 classify_face 函式，傳入偵測到的影像，回傳 "with_mask" 或 "without_mask"。接著在螢幕下方印出 with_mask 或 without_mask 字樣（如前面 demo 影片所示）
            2. 接下來在 label_detect 中較複雜，以下大概列點：
                * 先用 PIL 的 Image.fromarray() 將收到的陣列型態的image轉成PIL的形式
                * 呼叫另一函式 process_image，再將PIL檔轉換成一PyTorch模型，以便後續使用。另外也將影像進行格式的標準化設定，最後回傳一個 Numpy array
                * 接下來是針對 output 進行判斷，它是一個包含兩個元素的陣列。當陣列中的第一個元素為正，後者為負時，代表他偵測為有戴口罩；反之亦然。
                * 最後就會回傳 "with_mask" 或 "without_mask"出去
    * Rpi
* 組內討論事項 (必填，如問題、構想、分工合作、時間安排...等等)
    * 訓練效果修改
        1. 修改原先不真實的口罩
        2. 增加新顏色
        
        |black-mask.png|blue-mask.png|green-mask.png|white-mask.png|
        |-|-|-|-|
        |![](https://i.imgur.com/QX0tt87.png)|![](https://i.imgur.com/MXwHlzr.png)|沒有QQ|![](https://i.imgur.com/KVoPeC0.png)|
        |![](https://i.imgur.com/1Use1ZR.png)|![](https://i.imgur.com/H7PoJmq.png)|![](https://i.imgur.com/o9Aw9ru.png)|![](https://i.imgur.com/zVtsitd.png)|
        實際訓練效果顯示，若用原作者不真實的口罩(+不旋轉的P圖)，精確度印象中應該是到0.96~0.97左右就是極限了，但是若使用我們修改後的程式生成較為真實的圖片，準確度甚至到達1.0。
        結論：**真的有差** 

    * 判斷口罩的程式訓練得差不多了，旋轉口罩再P上人臉的效果其實滿好的，感覺可以應用在專賣口罩的店家，讓五顏六色的口罩融入日常穿搭的一部份。接下來的幾周希望可以框出畫面中的人臉，再用兩種顏色分別表示有戴口罩及沒戴口罩，再來就是修改演算法讓判斷更有效率、訓練更精準。
   
    * 這個禮拜我們也有測試Rpi，但是因為使用的是一般手機充電的豆腐頭，沒有辦法穩定的供應5V電源，而且若接觸不良很容易就crash了，所以我們上網購買了兩組源場電源跟風扇，研究rpi的優先順序應該會在修改程式前。
* 組員分工 (必填)
    * 吳宣逸：HackMD、Python(方案一，生成戴口罩的.jpg圖片、訓練模型)
    * 郭宇庭：HackMD、Python程式(方案三)、製作口罩.png圖檔、Rpi
    * 游菖鈺：HackMD、Python程式(方案一，筆電鏡頭判斷是否戴口罩)
* 遇到問題之處理狀況、解決方式 (必填)
    * 原作者在README中寫說有提供一份.txt檔，記有需要另外安裝的lib，但實際上這個東西不存在。所以最後只能根據error message與網路去慢慢裝，最討厭的是有些不能使用pip安裝，否則會出錯，不然就是用pip有安裝的限制，為了避免踩雷，找了很久才找到正確的安裝方法。其中PyTorch與dlib是找最久的。最後把GitHub的[README.md](https://github.com/Xuan-Yi/Covid-19-mask-doorVguard/blob/8d7076b0cbac1a84349555bff7ccf6ff4a25fd1a/README.md)當作記事本，把雷都收集起來了。
    * 在訓練模型時，第一是資料夾路徑要對，第二是兩個.csv檔中的檔名，必須是data資料夾中有的，不然就會報錯。因為.csv檔中資料動輒就幾百個了，實在沒時間想在重新一個個重新打一份新的，因此就沿用原作者的.csv檔中without_mask部分然後在網路上找了好久，最後終於找到用[list.bat](https://drive.google.com/file/d/1w-ZUoVxVcrO68OJpXIAiQbtyooBpUseA/view?usp=sharing)這個小東東跑出檔案清單，不過複製上去之後不知道為什麼還是一直有圖片找不到，最後花了些時間才終於補齊。
    * 接著就是原作者將   ```scheduler.step()```放在```optimizer.step()```前面，但實際上這種做法似乎會讓學習變的怪怪的，而且也會報錯，最後我還是索性將它改過來了，學習速度還真的似乎有點差異。
    * 一開始執行時，Jupyter一直報cuda記憶體太滿，但一直找不到原因，最後是找到一篇文章說若發生這個情況，就調低batch_size，但修改成就調低batch_size = 2之後仍然會報相同的錯，最後又找到可以先釋放占用的GPU記憶體，便又加上以下第一行程式，果然重新執行就能動了。(我又另外加上尋找最佳卷積算法，雖然不知道有沒有用，但看起來很厲害就沒移除了！)
        ```python=
        torch.cuda.empty_cache() # 釋放占用的GPU記憶體
        torch.backends.cudnn.benchmark=True # 讓cuDNN尋找最快速的卷積演算法
        ```
        ```python=
        # 定義dataloader字典
        dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], 
                                                      batch_size=14, # 一次讀取的資料數(訓練時每次平行處理1 batch的資料) (若GPU記憶體無法負荷則改小)
                                                      shuffle=True, # reshuffle the data at every epoch
                                                      num_workers=4) # 載入檔案所用的子進程(subprocess)數
                        for x in ['train', 'test']}
        ```
* 課程建議 (選填)
    * 雖然這算是一個突發狀況，但寄送材料的時間應該可以再提早一點。當初也知道這週跟下週由於接近期末考，大部分的事情應該要大概完成了，如果以後學弟妹遇到類似的事情（希望不要），希望助教們可以注意一下這點，畢竟還是會對進度造成一些影響。另外還聽說有人的包裹寄到別人家去了，甚至他們根本不同組不同班。
        
* 想說的話 (選填)
    * 做這個專題真的花我們很多時間，雖然大部分的程式不用自己寫，但光看懂別人的code就足夠傷腦筋了。import了一堆函式庫，用了各種函式，都需要靠我們一個一個慢慢去找。說真的，即便當下看得懂，過了這陣子之後還記得多少？我想使蠻未知的。不過我認為這還是個學習的機會，畢竟很多知識並不一定能夠有人耐心地用淺顯的語言向我們解釋，自己搜尋資料還是相當重要的。不過過程中會覺得很心累倒是沒錯，但我們就都已經跳下去了，無論如何還是得嘗試爬出來。至少到目前為止，我們有達到當初設想的結果。
    * 暫時告一段落，該去搶救期末考了
    
## 第十六週批閱區 - 自選題進度報告
* 助教批閱欄
    * 助教回饋
        * 你們的紀錄簿寫得很詳細，把整個機器學習的訓練方法與過程都詳細地寫了下來，也恭喜你們得到了不錯的成果，把人臉口罩識別做了出來，就助教之前學ML的經驗，這些知識要全部弄懂並且把成果做出來必須得花費相當多時間與心力去鑽研，首先光是python環境的設置就是一大難關，資料庫的建立、pytorch與其他library的使用也都需要不斷查詢資料，而訓練的時候也必須一直調整參數，很高興你們大一願意花時間去研究自己有興趣的事物，有了這樣的基礎，未來你們有興趣就可以直接去修更多進階的ML課程了。
        * 很抱歉寄送材料的時間有點晚，然後有些組的材料寄錯地方，這方面我會再轉達給大助教，不過還是得感謝大助教願意冒著風險到學校幫你們寄材料。
        * 期末考加油~
> [name=鐘民憲]
* 教授批閱欄
    * 評分等第
        * A
    * 教授回饋
        * 看起來有不錯的成果，期待看到你們的demo。
> [name=坤佑]

## 第十七週紀錄 - 自選題進度報告
* 預計完成事項 (必填)
    * 這兩個禮拜由於是段考週，而且期末出現很多報告，加上甘特圖原本這禮拜就是彈性運用，所以並沒有任何進度要求。
* 實際達成事項 (必填)
    * 這禮拜沒有進度(aka 盡量all pass讓考完能不帶壓力地做期末專題)
    * 上禮拜購買的散熱風扇、電源供應器都已經收到，共花費350+340元(含運費)。
* 組內討論事項 (必填，如問題、構想、分工合作、時間安排...等等)
    * 如同前面所說，我們這組在上禮拜在筆電上做完程式之後，這禮拜決定以準備期末考試為主。
    * 考完之後會先處理Rpi再優化程式(或者我們會分工)。
* 組員分工 (必填)
    * 吳宣逸：HackMD
    * 郭宇庭：HackMD
    * 游菖鈺：HackMD
* 遇到問題之處理狀況、解決方式 (必填)
    * 無
* 課程建議 (選填)
    * 時間安排在期末考後還有幾天緩衝，但又不卡到暑假，這個時間安排目前看起來還不錯。
* 想說的話 (選填)
    * 之前學長姊專題好像有做海報，那我們改成線上之後是用ppt嗎？
* 疫情下之調整與心得建議
    * 吳宣逸
        疫情下改成線上教學，一些課程的效果是變好的，但也有一些是變差的。車車課除了無法解決的實作問題，大部分其實沒有什麼差別，這是車車課的先天條件、無法解決。
        在其他課程上，因為在家中能夠分心的事物太多了，常常就是耳機戴著卻心不在焉，效果很差。另外今天早上線上考微積分也是感覺差很多，遇到問題時感覺就是自己卡頓，無援的感覺，上課沒有同學的感覺超奇怪，車車課線上化有時候也是如此。希望至少暑假後能回去學校上課，否則真的要悶壞了。
        另外在學校如果有事情要討論，通常可以速戰速決，不然就是可以很歡樂，結果線上化就是太便利了，簡直無法快速解決，而且也一點都不歡樂。
        總之對於大部分課程而言，實體課還是好太多了。
    * 游菖鈺
        同前面所述，遠距上課的效果其實不太好，至少對我自己而言，心態會變得比較懶散，做事也比較沒有效率。而車車課最後只能迫於線上討論、報告，也算是有些遺憾，畢竟實作東西應該還是這門課的主軸。不過我想大家在這個時間都盡力了，學期的最後一段時間就好好考完試還有準備demo，現在只求疫情早日結束，家裡雖然舒適許多，但已經感到有些厭倦了。
        最早選課沒上，加簽週三早上沒中，那天下午只帶著抽樂透的心情踏進明達402，萬萬沒想到的是我竟然成為了最後一個名額，當下真的是欣喜若狂。但不得不承認，在學期中，我的確出現過"為什麼是我被抽中！"的想法，但很高興我們走到現在了。謝謝教授跟助教的協助，還有我很罩的隊友們，這是我大一一整年上過最酷的課！
    * 郭宇庭
        突然受疫情影響無法實體上課真的很可惜，很希望有大家都能聚在一起看彼此Demo的場合，感覺就很像看大家辛苦孕育出來的種子發芽的感覺，但是也很謝謝助教和教授在這麼不方便的情況下還是努力讓大家有最好的體驗，雖然可能沒有辦法跟大家再openlab一同奮鬥或是跟其他組的同學交流，但是也是因為這樣我們才能學習到原本指定題時所沒學到的，例如我們更能知道該如何有效率的分工或是安排進度，但是惋惜的是指定題的表現不如我們預期..硬體接二連三的故障讓我當時有點灰心，但是也是因為這樣才有手做的魅力吶，雖然期末改成遠距的方式，但是我們本來就想放棄那台有點秀斗的車車所以影響好像沒有那麼大?最後還是謝謝助教以及教授們這麼認真用心的準備最好的資源給我們，當初很幸運地抽到這門課，我也覺得我沒有辜負這份幸運，在這半年的課程中我學到了很多，大一下可以有車車課的陪伴真的太好了!
## 第十七週批閱區 - 自選題進度報告
* 助教批閱欄
    * 助教回饋
        * 改成遠距教學以後，有好有壞。自制力跟專注力的確會受到很大的挑戰，不過這也是一個學習如何和自己相處的難得機會，而且還能回家陪陪家人(除非你住宿舍)。這學期車車課，你們真的很努力，即使曾經心態炸裂但最後撐過來的成就感無可取代。後半學期你們線上分工、各自實作硬體再組合起來，這是過去學長姊都沒有過的經驗。未來在做其他課的project時，更知道怎麼妥善分工合作，相信這會成為你們一輩子的回憶。
        * 祝期末順利，希望你們未來在電機系都可以學到自己想學的東西，玩的開心!!
> [name=宋馨慈]
* 教授批閱欄
    * 評分等第
    A
    * 教授回饋
    唉，我不知道其他老師們怎麼樣，但是我一開始上課也很不習慣，然後線上上課比平常在課堂還要累。很謝謝你們滿滿的心得，車車課這麼多年，也是靠大家一起撐起來這門課，這是一門老師累、學生累、助教累的三累課。但是每次看到大家滿滿的推薦，也會讓老師們更有動力，覺得花這些時間與精神是值得的。幸運的是，我們大家都撐完這學期啦~  :D
    期待你們 6/30 有好的表現呦! 
> [name=君朋]

###### tags: `電資工程入門設計與實作` `109-2`
{%youtube mDa3y5Jq7LE %}