如何利用一條短的 LED 燈帶來實時顯示飛機在進近過程中的位置以及其飛行高度
這個項目是為我物理計算課程中的數(shù)據(jù)可視化項目而設(shè)計的。其核心理念是通過 LED 燈帶來展示飛機在天空中的位置,每盞 LED 燈都代表著一個位置。這些燈光會隨著飛機的活動而移動并改變顏色。
我為這個項目使用了 Particle Photon 2,因為它非常出色,而且能非常輕松地將這個微控制器連接到互聯(lián)網(wǎng)。這絕對是一款出色的微控制器,我會強烈推薦(我還買了另外兩個)。
所有跑道均以芝加哥奧黑爾國際機場(ORD)為參照標(biāo)準。
Webhook/ API
查詢
這是通過使用 OpenSky 網(wǎng)絡(luò)及其 REST API 來完成的,該 API 的詳細文檔可在此處查閱。
這個 API 如何運作的最簡單且最易于演示的例子,可以通過一個匿名的 API 請求來實現(xiàn),該請求遵循基本的查詢設(shè)置,并將其輸入到網(wǎng)絡(luò)瀏覽器中。例如,要查找位于 28C/10C 圓形區(qū)域內(nèi)所有飛機的查詢,其格式應(yīng)如下所示:
理想情況下,應(yīng)該能夠?qū)⒃搩?nèi)容以 GET 請求服務(wù)的形式(比如使用 Particle 的服務(wù))提交出去。但對我來說,這似乎從未奏效。無論我嘗試何種身份驗證方式,無論使用何種訪問令牌,無論設(shè)置何種參數(shù)、頭信息還是響應(yīng)模板,都無法讓我擺脫“ETIMEDOUT”錯誤(即當(dāng) API 回復(fù)時間過長時出現(xiàn)的 Particle 錯誤)。我把它發(fā)到了 OpenSky 的 Discord 和 Particle 論壇,但都沒有效果。如果您找到了解決辦法,請告知我;那樣會讓這一切變得簡單得多。
為了解決這個問題,我使用了我手頭有一臺舊的 Raspberry Pi 3 來從 OpenSky API 獲取數(shù)據(jù),然后使用 Particle.publish() 函數(shù)將這些數(shù)據(jù)推送到我的 Particle 設(shè)備上。該代碼可以在本項目的“代碼”部分中查看。
一個優(yōu)點是這種接力方式確實可行。另一個優(yōu)點是它能為我提供 OAuth2 客戶端憑證,這樣我每天就能獲得 4000 個 API 信用額度。但有一個缺點是,如果我想要更改跑道的地理圍欄,我就得進入樹莓派并自行修改代碼。
“光子 2 編程”
這就是一切精彩內(nèi)容的開始。我將為大家展示每個步驟的具體操作過程,并且不會深入講解編程本身的內(nèi)容。如需了解更多詳情,請查看下面這個項目的“主”代碼部分。我用內(nèi)嵌注釋對其進行了詳細的記錄,這樣您就可以跟著實際的代碼一起操作了(如果您愿意的話)。我會標(biāo)注行號,以便于您更好地理解。
解析數(shù)據(jù)
首先,OpenSky API 返回的 JSON 文件包含了整個虛擬區(qū)域內(nèi)所有的飛機信息。所有的飛機。在空中飛行的、起飛的、在地面的……所有內(nèi)容都在其中。所以首先我們必須對其進行排序!我用這個來獲取每個數(shù)據(jù)值,還用這個便捷的工具讓我的工作變得輕松些。下面是我是如何操作的(第 45 行):
需要指出的是,當(dāng)我確定這架飛機正是我想要的那一架后,我會獲取其所有數(shù)據(jù)并將其存儲到一個“飛機”對象中,這樣我就再也不需要再接觸 JSON 數(shù)據(jù)了。這個飛機對象的結(jié)構(gòu)如下:
這些對象被添加到一個數(shù)組中,這樣我就能方便地對其進行存儲和排序了。
整理飛機停放位置
我不太清楚 OpenSky API 在返回 JSON 數(shù)據(jù)時是依據(jù)什么標(biāo)準對飛機進行排序的,但可以肯定的是,它并非依據(jù)距離奧爾德姆機場的遠近來進行排序。因此,我必須將這些混亂的對象數(shù)組整理成一個能觸發(fā)警報的數(shù)組。
需要指出的是,存儲混亂排列的飛機對象的數(shù)組長度總是會小于表示燈光的數(shù)組長度。我有 8 個燈,所以它由一個 7 個索引的數(shù)組來表示。每個燈代表 1.5 英里的空域。所以它看起來是這樣的:
飛機的數(shù)量絕不會超過 4 架,因為如果超過了,那一定是空中交通管制員搞錯了。因為根據(jù)美國聯(lián)邦航空局的 JO 7110.65 5-5-4 規(guī)定,飛行器之間必須保持 3 英里的間隔。這意味著最多每 3 個間隔才能有一架飛機。
那么如何對其進行排序呢?其實很簡單。這個過程發(fā)生在第 100 行到第 156 行之間,通過一系列“if”語句來實現(xiàn)。每架飛機都會被檢查其經(jīng)度,并被放置到相應(yīng)位置的正確數(shù)組槽中。如果沒有飛機在那里,就會創(chuàng)建一個假飛機,其高度設(shè)為 -1000 米,以便于更容易地識別出來。這就是您能得到的所有解釋了:)
打開燈
很簡單。首先,關(guān)閉所有沒有對應(yīng)飛機的燈。然后,如果這個燈有對應(yīng)的飛機,就將其打開,并將顏色設(shè)置為代表飛機所處高度的樣式。我使用了 switch-case 結(jié)構(gòu),因為我是個酷家伙(第 182 行至 219 行)。
結(jié)論
就是這樣啦!如果拆解開來的話,其實挺簡單的,但從零開始進行編程可不是一件容易的事!雖然仍有幾處關(guān)于神秘飛機和奇怪的地理圍欄錯誤的問題,但總體來說這個項目已經(jīng)達到了 98% 的功能性。
根據(jù) Raspberry Pi 代碼的最后一行設(shè)定,數(shù)據(jù)每 10 秒更新一次,而燈也會隨之相應(yīng)地變化,因為“光子”始終處于循環(huán)狀態(tài)。即便以這樣的頻率運行,我每天 4000 個 API 信用額度也需要大約 12 個小時的持續(xù)使用才會用完。我的 Pi 電腦連接到一個智能插座,這樣我就可以從家里遠程開關(guān)它,而且在我不需要它的時候它也不會消耗我的信用額度。
本文編譯自hackster.io





