首頁 / 真機前的模擬考 · 進行中

上真機之前的三場模擬考

目標是在真機(真的無人機)上證明「果蠅腦的接法本身有用」。

真機進度(2026-11-13 更新)

硬體在 11-11、11-12 陸續到貨。第一天把飛機組起來、讓電腦連得上,也第一次自己懸停成功。第二天裝相機時一度卡住,查出原因後當天解決;下午電腦收到相機的畫面,也把果蠅腦接上了(飛機不起飛,腦算出的指令不送出去)。但真腦對假腦的比較,目前還沒有任何真機結果——這一頁上面和下面的數字都來自模擬。

12 步的進度✓通過 10◐部分 / 有但書 2

點任一步,看做了什麼、結果如何。

看原始表格
步驟狀態說明
組裝機體✅ 完成馬達、螺旋槳、電池座都裝好。
無線電(Crazyradio)✅ 完成出廠時裡面只有「更新用的開機程式」,沒有正式的韌體(裝置裡的內建程式)。補裝韌體、在電腦裝好驅動程式後就能用。
電腦連上飛機✅ 完成無線連得上,電池電壓讀得到(4.1 V,充飽)。
升級飛機的內建程式✅ 完成用官方 2026.10 的更新包升級飛機的內建程式(韌體;裡面控制飛行的程式是 2026.08 版;這次更新只換了相機板 WiFi 晶片的程式)。刻意在裝相機板(AI deck)之前升級,免得升級時順便把相機板的 WiFi 程式換成不相容的版本。
光流板(Flow deck)✅ 修好這塊板子負責量高度和水平移動,沒有它飛機沒辦法自己懸停。一開始飛機認不出它:板子上有一顆記錄「我是哪種板子」的小晶片,出廠時沒寫資料,裡面只有測試用的固定圖樣。自己把正確的資料寫進去之後就正常了。
第一次自動懸停✅ 成功在亮面的白磁磚上,它起飛後一路往前飄,撞到牆。原因是光流板靠「看地面的紋理怎麼移動」來知道自己有沒有在飄,沒有花紋的亮磁磚上什麼也看不到。換到木地板(有木紋和接縫)後,在 30 cm 高停 3 秒只飄了約 10 cm。所以之後的場地,地面要有紋理。
裝相機(AI deck)✅ 程式已寫入相機板裝上後,飛機認得到它。但要把「傳影像的程式」寫進相機板上的影像處理晶片(GAP8)時,試了 4 次、換了兩台電腦,進度都卡在 0%。原本猜是那顆晶片少了開機用的程式,結果不是。真正的原因:程式要先交給相機板的 WiFi 晶片(ESP32),再由它轉交給影像處理晶片;而這片板子的 WiFi 晶片出廠時裝的程式太舊,看不懂轉交用的格式。用無線電把 WiFi 晶片的程式更新之後,傳影像的程式十幾秒就寫好,相機板也回報它已經啟動。不需要用到除錯器(專門把程式寫進晶片的工具)。
電腦收到畫面✅ 53 張 / 秒官方範例傳的是整張 324 × 244、沒壓縮的畫面,每秒只有約 9 張,遠低於模擬算出的最低要求(每秒 33 張)。瓶頸是 WiFi 一次能傳的資料量。改成先在相機板上把畫面縮成 162 × 122、再壓成 JPEG(常見的圖片壓縮格式)之後,每秒 53 張,連續 10 分鐘沒有中斷。在模擬裡,把「把畫面轉成逼近訊號的程式」(下面叫影像處理程式)換成同樣的解析度、壓縮方式和每秒張數,果蠅腦的閃避只多失敗 5 場,仍在可接受範圍。
斷線後重新連線✅ 修好電腦把影像連線關掉、再連一次時,常常連上了卻收不到畫面,或再也連不上,要把飛機重開才恢復。問題出在相機板 WiFi 晶片(ESP32)的官方程式:負責收資料和負責送資料的兩段程式,都會去關同一條連線,所以同一次斷線被關了兩次,下一條連線一接上就被當成「已經斷了」;另一種關法,它則完全沒發現對方已經離開。改掉這段程式、重新寫進 WiFi 晶片後,三種關閉方式輪流試 96 次都正常。另外,在家裡測試時,電腦和相機板的 WiFi 熱點之間會整段斷訊 5 到 15 秒以上(影像和測試連線用的 ping 一起停),連續收 10 分鐘的測試跑不完。原廠論壇上很多人回報過這個問題,原廠也沒找到原因。我們讓 WiFi 晶片每秒回報自己的狀態,發現斷訊那一秒,它還能用的記憶體從 42 KB 掉到 8 KB:原廠程式給「排隊等著送出的資料」設的上限,比實際剩下的記憶體還大。空中的訊號稍微卡一下,排隊的資料就把記憶體吃光,之後連重送都做不到。把上限調小之後,連續 10 分鐘收了 31,605 張(每秒 52.7 張)沒有斷線;不過中途仍有 5 次 0.3 到 2.6 秒的短暫停頓。(先前這裡寫「切過去後等 30 秒再連就沒事」,後來再試並不可靠,已更正。)
畫面亮度✅ 修好一開始畫面太暗,影像處理程式把整個畫面都當成障礙物。原因是相機的自動曝光(自動調整亮度的功能)把平均亮度固定在 60(滿分 255),而影像處理程式用 128 當「暗」的界線。把自動曝光的目標調到 128 之後,亮的牆面才真的算「亮」,每秒張數不變。
延遲⚠ 偏緊讓相機對著螢幕、螢幕黑白切換,量出「畫面變了 → 電腦收到」大約要 80 毫秒(包含螢幕本身的延遲)。模擬算出,從相機拍到畫面到飛機照著動,整段延遲要在 110 毫秒內,剩給無線電和馬達的時間不多。要實際飛起來量才算數。
接上果蠅腦(不起飛)◐ 做到一部分飛機放在桌上、馬達不轉。電腦每 10 毫秒讀一次飛機回報的數據和相機畫面,跑一次果蠅腦;腦算出的指令只記錄下來、不送出去,全部可以在儀表板上回放。但在雜亂的桌面上,看不出腦會分左右(桌上靜止的深色物體本身就讓它一直想閃),要到背景明亮的場地裡重做。

之後的順序:量飛行場地的亮度 → 在場地裡重做「接上果蠅腦(不起飛)」 → 腦還不指揮飛行,用手拿物體從左右靠近,量延遲、每秒張數與左右方向 → 讓腦真的指揮飛行,閃一根柱子。

用到的零件,以及模擬裡對應的是什麼

地面電腦 果蠅腦(接線圖的一部分) 11,485 個神經細胞・接線照抄・不訓練 東西逼近 → 視覺細胞 → 下指令的細胞 → 閃避 把腦的決定換成飛行指令 閃避方向 → 速度 + 轉向快慢 + 高度 無線電(Crazyradio 2.0) USB 2.4 GHz 無線電 無人機 Crazyflie 2.1+(27 g) 飛行控制晶片 STM32F405 推算機身歪幾度、速度、高度 自動修正 → 四顆馬達 收不到指令就自動降落 相機板(AI deck 1.1) 黑白相機 87°・320×320 影像晶片 GAP8:算逼近訊號 WiFi 晶片 ESP32:傳回地面 光流板(Flow deck v2) 看地面紋理量水平速度 雷射測距量離地高度 測距板 Multi-ranger(選配) 5 個方向測距・只當安全保護 不接進腦 飛行指令・每 10 ms 逼近訊號(WiFi)・要 ≥ 33 fps
飛機

Crazyflie 2.1+

27 公克的四軸無人機。機體設計、機上的內建程式(韌體,Bitcraze 公司出的,GPL 授權)、電腦端的程式庫(cflib)全部公開。選它而不是 ArduPilot / PX4(另外兩種無人機飛行控制系統):它在室內飛、不用 GPS,而且模擬用的就是這個機型。

模擬:物理模擬軟體 PyBullet 裡的 Crazyflie 2.x 模型,所有測試都用它。

飛機・主晶片

飛行控制晶片(STM32F405,跑 Bitcraze 的韌體)

負責不讓飛機翻掉:推算機身歪了幾度、速度、高度,再去驅動馬達。地面的指令一斷,它會自己降落。腦不碰這一層。

模擬:gym-pybullet-drones 這套軟體內建的飛行控制程式(PID,一種自動修正的算法),它接收地面送來的飛行指令。第一場模擬考把指令的格式和正負號的規定換成 Crazyflie 的。⚠ 模擬裡的飛行控制程式直接拿模擬器知道的正確答案(機身歪了幾度、速度)來用,不像真機的韌體要靠用感測器推算的程式(EKF)。

飛機・擴充板

相機板(AI deck 1.1)

上面有一台朝前的黑白相機(Himax HM01B0,水平視角 87°、320×320)、一顆影像處理晶片(GAP8,8+1 核 RISC-V)、一顆 WiFi 晶片(ESP32)。重 4.4 公克。

模擬:第二場把相機換成「一台朝前 87° 的相機,畫面從中線切成左右兩眼」;第三場把相機每秒拍的張數降低。建議直接在影像處理晶片上算逼近訊號,只把每隻眼 3 個數字傳回地面。

飛機・擴充板

光流板(Flow deck v2)

朝下的光流感測器(看地面紋理怎麼移動,量水平速度)加雷射測距(量離地高度),讓飛機不用 GPS 也能在室內定點、定速。

模擬:這三場沒有用到(模擬裡的飛行控制程式直接用模擬器知道的正確答案)。另一系列的模擬已經證明過,改用感測器來推算是可行的;真機上這件事交給韌體處理。

地面

無線電(Crazyradio 2.0)

插在地面電腦上的 2.4 GHz USB 無線電,每 10 ms 送一次指令,並收回飛行紀錄。

模擬:第一場在送指令的路上加 0 / 20 / 50 / 100 ms 的延遲。

地面

地面電腦上的果蠅腦

從一份果蠅腦的接線圖(MaleCNS)裡取出的 11,485 個神經細胞。兩個細胞之間有幾個接點,就直接當成那條連線的強度,不做任何訓練。為什麼先放在地面:飛行控制晶片只有 192 KB 記憶體,放不下;而且地面跑的就是模擬用的那份程式,真機的結果可以跟模擬一場一場對照。

模擬:同一份程式(自己寫的神經細胞模擬程式,事件驅動 LIF)。同一個場景重跑,結果每一個位元都相同。

文字說明

採購:原本要買 Bitcraze 官方的套組「The AI bundle – Crazyflie 2.1+」(2026-09-23 標價 US$610),因為缺貨改成分開買:Crazyflie 本體、光流板(Flow deck)、無線電(Crazyradio)向 Bitcraze 買,相機板(AI deck)向 Seeed 買,把程式寫進影像處理晶片(GAP8)用的除錯器另外買(預計 11-17 到)。

回放:用 Crazyflie 的指令格式,加上相機板的前向相機

同一個場景、四種控制方式各飛一次,從上往下看。切換「條件」可以看同一顆腦在相機變慢、或柱子變多時怎麼變差(45 / 60 / 90 根的場景,是在原本的 30 根上再加柱子,原本那些柱子的位置完全相同)。這些場景是從正式測試裡照固定規則挑出來的;重飛一次,結局和正式結果每一場都相同。

條件
場景
控制方式
相機板(AI deck)看到的畫面(+43.5° → −43.5°;色塊 = 柱子;中間那條帶 = 兩眼都看得到的範圍 ±10°)
0.00 s

1× = 跟真實時間一樣快。飛機以 1 m/s 前進,終點在 x = 20 m。軌跡上的粗點 = 正在急閃;✕ = 撞上;旗 = 抵達。相機畫面上方中間出現「沿用上一幀」= 這一刻腦拿到的還是上一張舊畫面(相機每秒張數低的時候會這樣)。

≤ 110 ms從相機拍到畫面,到飛機照著動(相機 → 地面電腦 → 無線電 → 飛機上的飛行控制程式),整段延遲在這個範圍內都撐得住,失敗只多 7 場
87° 一台只用相機板(AI deck)上那一台朝前的相機也夠:100 場裡真腦失敗 16 場,假腦失敗 79 場
≥ 33 fps逼近訊號(東西在畫面裡愈變愈大,表示正在靠近)每秒至少要更新這麼多次(fps = 每秒幾次);降到 17 fps 就多失敗 16 場
≤ 45 根場地(16 × 8 m)裡的柱子數:45 根時真腦有 61% 抵達終點、假腦 11%;60 根時統計上仍贏,但真腦只有 17% 抵達;90 根就不贏了

測試結果(每個條件飛 100 個隨機擺柱子的場景;失敗 = 沒抵達終點)

第一場:換成 Crazyflie 的指令格式,再加延遲 紀錄編號 H0

相機仍是模擬原本的兩眼寬視野。先過一關:只換指令格式時,真腦的成績要跟原本一樣——。

第二場:只剩相機板上那一台朝前的 87° 相機 紀錄編號 H0b

原本每隻眼有兩台朝側面的相機(合計約 ±150°)。視野變窄反而更好:看不到側面的柱子,就不會為了閃它們一路橫著移到飛出場地。

第三場:相機每秒拍的張數變少 紀錄編號 H0c

表裡的 fps = 相機每秒拍幾張。沒有新畫面時,逼近訊號沿用上一張畫面的。要看最近 10 張畫面,才能穩定算出「東西變大得多快」;每秒張數一少,發現「東西在逼近」就晚了。

加考一:柱子加到 3 倍(30 → 90 根)——沒過 紀錄編號 H0d

柱子這麼密的時候,真腦沒有贏假腦。

同一塊範圍、同樣的最小間距(柱子之間至少留 0.5 m 的縫,機身過得去),每個場景都是原本的 30 根再多 60 根。朋友看了這頁說「障礙也太少了」——說得對。 結果:柱子這麼密的時候,真腦沒有贏假腦。真腦幾乎全撞(97 / 100),閃的方向跟亂猜差不多(正確率 82% → 54%),而且撞得比不控制還早(撞上時已經前進的距離,取中位數是 4.35 m 對 5.02 m)。 兩個可能的原因:影像處理程式在柱子很密時把好幾根柱子看成一整塊、選錯邊;或是腦只會「看到就急閃」,閃開一根就撞上下一根。

加考二:同樣 90 根,但直接給腦「完美的」逼近訊號(用來分辨上面兩個可能) 紀錄編號 H0e

加考三:只調急閃門檻(多容易觸發急閃)和往旁邊移的力道,能不能救回 90 根?——不能 紀錄編號 H0f

加考四:一路加密柱子,看多密的時候真腦就不再贏假腦 紀錄編號 H0g

「直飛會擋到」= 飛機直直往前飛,16 m 的路上平均會被幾根柱子擋到。每一種密度的場景,都是在 30 根的場景上再加柱子;比的時候是同一個場景的真腦對假腦,一場對一場。

為什麼柱子一多就不行

為什麼柱子一多就不行

① 要連續閃的次數變多:直飛時 30 根只要閃 1–2 根,90 根要連閃 4–5 根。像連過好幾道門,門越多,全部過關的機會越小。

② 每一次閃也變難:畫面裡好幾根柱子連成一塊,分不清哪根最危險、該往哪邊閃(閃對方向的比例從 82% 掉到 58%);相機只看得到前方 87°,往旁邊一閃常常閃進看不到的柱子。

③ 腦只有反射、沒有規劃:它只會「看到東西逼近就往另一邊跳」,不會想閃完之後往哪走。空曠的時候跳一下就安全,柱子密的時候跳開這根正好撞下一根——就算給它完美的逼近訊號(加考二),90 根時還是撞 99 場。 像在人群裡只會「快撞到人時往旁邊跳」:空曠大廳沒問題,擠滿人的車站每跳一次都撞到另一個人。真的果蠅除了這條逃開的反射,腦裡還有別的認路用的線路;這個專案目前只接了「看到東西逼近 → 逃開」這一條。

文字說明

這一頁在講什麼

目標是在真機(真的無人機)上證明「果蠅腦的接法本身有用」。第一台真機選 Bitcraze 公司的 Crazyflie 2.1+(27 公克,在室內摔得起)。 腦是照果蠅腦的接線圖做的,共 11,485 個神經細胞。它先跑在地面的電腦上,每 10 毫秒(ms,千分之一秒)用無線電送一個「往哪飛」的指令給飛機。買硬體之前,先在模擬裡把真機會遇到的三件事一件一件換上去, 每次都看真腦(照真果蠅的接線)還贏不贏假腦(接線被隨機打亂)。假腦是對照組(拿來比的那一組):細胞數和連線數都一樣,只把誰接誰隨機重排。前三場真腦都贏了。但把柱子加到 3 倍就不贏了,所以又一路加密柱子,找出贏到哪裡為止。結果照實放在下面。

先看懂兩個詞

先看懂兩個詞

真腦(照真果蠅的接線):照果蠅大腦實際的接線,一條都不改。

假腦(接線被隨機打亂):用同樣的零件、同樣多的電線,只是把「哪條線接到哪裡」隨機換掉。

就像一個城市:路口數量、每種道路有幾條都一樣,但每條路通到哪裡是亂抽的。兩張地圖的統計數字一模一樣,差別只在「誰連到誰」。

為什麼要比:如果只有真腦做得到,才能說功勞在果蠅大腦的接法;如果假腦也做得到,就只是「零件夠多」而已,跟接法無關。

下面的按鈕和表格怎麼對照:「腦」或「腦(真實接線)」就是真腦,「打亂接線」就是假腦,「手寫規則」是人寫的規則,「不控制」是不做任何閃避。「seed」加數字是場景的編號。

影片

影片

左上是跟在飛機後面看的 3D 畫面(右上亮起 ESCAPE = 正在急閃),左下是相機板的畫面切成的兩眼,右邊是腦裡神經細胞的活動(綠圈是偵測東西逼近的視覺細胞 LPLC2 / LC4,黃圈是下指令的細胞 DNp,紅圈是觸發急閃的細胞 GF)。1× = 跟真實時間一樣快。

柱子密度的限制

柱子密度的限制:三場模擬考的結論,是在 30 根(每 4.3 m² 一根)的場地量的。加密柱子的那場(加考四)顯示:統計上到 60 根真腦都還贏假腦,但真機每個條件只飛 10–20 趟,所以建議場地用 45 根(每 2.8 m² 一根),差別才看得出來。

還沒模擬的:真相機的動態模糊、曝光、背景紋理;WiFi 不規則的卡頓;Crazyflie 韌體自己的飛行控制與感測器推算(PID 與 EKF;模擬裡的飛行控制程式直接拿模擬器知道的正確答案);光流板的推算誤差。這些要等真機(下一階段)。

為什麼是這三場:第一場看指令格式與延遲,第二場看相機視野,第三場看相機每秒張數——都是「買了硬體才會碰到、但不用硬體就能先量」的差別。它們的結果直接變成真機的規格:從相機到飛機動作的整段延遲 ≤ 110 ms、逼近訊號每秒更新 ≥ 33 次(fps)。

給想查原始紀錄的人:三場模擬考的紀錄編號是 H0(指令格式與延遲)、H0b(一台前向相機)、H0c(相機每秒張數);加考是 H0d(90 根)、H0e(完美輸入)、H0f(調急閃門檻與側移力道)、H0g(密度掃描)。細節與事先寫好的判定標準:docs/DESIGN-drone-snn.md §70(H0)、§72(H0b)、§73(H0c);選型理由:docs/PLAN-flight-stack.md。真機接下來兩步的編號是 H2(腦不控制)、H3(腦控制)。光流板那張卡片說的「另一系列的模擬」是 M4;結果表裡的 M3d 是 30 根、完美輸入的那一場。模擬用的機型檔是 cf2x.urdf。