課程總覽

Smallsat — 立方衛星設計與實作 STK 課程教材

清華大學太空科學與工程研究所「立方衛星設計與實作」課程的 STK / Python 實驗教材。
以單一 FIREYE 火山觀測 CubeSat 任務貫穿 16 週,STK Enterprise 主導、Python 開源工具補位。

完整說明見 handbook/CubeSat_Course_Handbook.md。

資料夾結構

資料夾 週次 內容
handbook/ — 課程總手冊(Word + Markdown)
primers/ — 各週基礎知識導論(觀念、公式、外部參考連結)
reference/ — AGIPCEXP / Connect 指令速查
tools/ — 跨週共用工具(驗證段 stk_verify.py、記錄器積分)
week01_intro/ 1 導論:eSatellite FIREYE 場景與物件模型
week02_architecture/ 2 系統架構:通訊、地面站與 access
week03_budgets/ 3 系統工程:質量/功率/鏈路/資料預算(Python)
week04_orbit/ 4 軌道選擇 + 完整 FIREYE 場景(STK Connect + Python)
week05_fea/ 5 結構 FEA + 發射振動(CalculiX + Python)
week06_thermal/ 6 節點熱網路(Python,吃 STK 日照時間線)
week07_power/ 7 太陽能發電 + 儲存曲線(STK Solar Panel Tool)
week08_adcs/ 8 B-dot detumbling + STK 3D 姿態串接
week09_midterm/ 9 期中考(無實驗,附考前自我檢核清單)
week10_propulsion/ 10 Astrogator MCS 機動(STK 主軌)+ Python 驗證
week11_comm/ 11 通訊鏈路預算(STK Comm)
week12_payload_data/ 12 資料預算 / 記錄器填充 / 成像速率上限(吃 Week 4 的 STK 報告)
week13_automation/ 13 STK Python 物件模型自動化
week14_operations/ 14 地面站通聯排程(sgp4,與 STK 交叉驗證)
week15_launch/ 15 Aviator 發射 trade study(STK 主軌,含 AGI 原版範例)+ Python 驗證
week16_constellation/ 16 Walker 星座 + Coverage/FOM 整合展示 + Python 規模掃描

工具需求

安裝 Python 相依:pip install -r requirements.txt(STK API 與 CalculiX 需另裝,見該檔註解)。

執行前注意

Jupyter Notebook 版本

16 週各一本獨立 notebook,放在對應的週次資料夾(如 week03_budgets/week03_budgets.ipynb),
內容由該週的 .py / .txt 轉出。原始腳本保留不動,notebook 是它們的教學呈現版。

每一本的結構:

  1. 週次說明:對應資料夾、實驗單、附帶資料。
  2. 基礎知識導論:該週的觀念底稿,見下。
  3. STK Connect 腳本(需要 STK 的週次):以 Python API 逐行送出並回報 ACK/NACK。
    接續型腳本會自動先跑前置,並在上方標明相依關係。
  4. Python Lab:依原有分節切成 cell,圖表 inline 顯示。
  5. 驗證段:見下。

需要 STK 的 notebook(week 1、2、4、7、10、11、13、16)請先開啟 STK 12 桌面版,
不能用無介面的 STK Engine —— Animate、Graphics ... SetColor、VO ... SolarPanel、
OrbitWizard ... Color、ReportCreate ... Type Display 共 18 條指令在 Engine 上會被拒絕。

獨立章節(不屬於 16 週課程)

五個獨立主題,借用同一套方法論(STK 主導、Python 補位、ACK 不等於生效),
但題材不是立方衛星。每章各有導論、實驗單、Connect 腳本、Python 分析、
驗證段、notebook,以及一份 HTML 展示頁。

資料夾 主題 驗證段 招牌發現
radar_bistatic/ 地面雙基地雷達:干擾、雜波與航跡穩定度 62/62 20 W 干擾機打斷 100 kW 雷達的航跡;定位誤差變 4.9 倍
eoir_earlywarning/ 地面望遠鏡追蹤探空火箭尾焰:大氣站在哪一邊(EOIR,含動畫) 202/205(0 FAIL,3 SKIP) 天基的黃金波段 4.3 µm,從地面看天頂穿透率 5.2e−6、5° 仰角 3.3e−55
launch_conjunction/ 雙節運載火箭入軌 + AdvCAT 交會迴避 26/26 均勻粗掃找不到 1.8 km 的交會;500 km 比 800 km 擁擠 59 倍
tirem_coastal/ 岸際雷達:TIREM 地形傳播與四種靜默失敗 52/52 地表電性寫得進去、通過範圍檢查、回讀正確,對輸出差 0.000000000 dB
spaceport_suborbital/ 太空港次軌道任務:屏東旭海 → 休士頓 KEFD 的工程概念設計 65/65 升阻比夠低時機翼會變成淨負擔;到 5.62 時模擬工具的接縫消失

每章的 HTML 展示頁包含場景設定、模擬重點、結果圖表與程式碼,可獨立閱讀。

eoir_earlywarning/ 的 3 個 SKIP 不是失敗,是標示出來的無知:
EOIR_R 沒有回讀目標清單的選項(實測 NACK),以及 IntegrationTime 的單位
在 STK 裡找不到任何內部錨可以釘死 —— 本章取 ms,並把這個假設寫成
兩項具名的 SKIP,再用 NEI 的絕對量級當旁證。

這一項和 tirem_coastal/ 的招牌發現剛好是一對:
一個是知道自己不知道(標示成 SKIP),一個是以為自己知道
(回讀正確、範圍檢查通過,實際上對輸出毫無影響)。

驗證段能處理前者;後者只能靠「改動它並觀察輸出」抓出來。

tirem_coastal/ 的主角是一個會通過驗證的錯誤結論:
「TIREM 在這台機器上算不出結果」—— 那是錯的,而它通過了 41 項全綠的驗證。
該章把查證的方法本身變成教材:四種性質不同、沒有一種會給你錯誤訊息的
靜默失敗
。詳見該章導論第 5 節。

spaceport_suborbital/ 的兩個特別之處

一、沒有單一 STK 物件能涵蓋全程。 這一章的結論之一是工具邊界本身:

飛行階段 可用模型 狀態
動力上升 1,570 km Aircraft + 外部星曆 已實作並驗證
助推真空弧 2,400 km Missile + Ballistic 已實作並驗證
高超音速滑翔 + TAEM 9,139 km Aircraft + 外部星曆 已實作並驗證
跑道進場與降落 30 km 走廊 Aircraft + Aviator 已實作並驗證

滑翔段改用外部星曆是第二次架構更正:同一條航線交給 Aviator 飛,
航跡長度是直線距離的 5.32 倍 —— 載具在繞圈,而當時 32 項驗證全過。
改用外部星曆後是 1.00 倍。

第三次更正把上面那個「3,765 km 無物件涵蓋」拿掉了。
它原本被當成工具限制寫進對外文件,實際上是記帳錯誤:熄火速度被定義成
「從熄火起一路平衡滑翔全程」,但熄火後那段約 1,200 km 的真空弧幾乎沒有阻力,
把它也算進滑翔射程等於同一段路算了兩次。改成解自洽閉合條件之後,
熄火速度由 6,335 降到 6,118 m/s,航程接縫歸零(閉合殘差 0.000 m)。

第四次更正把動力上升段的沿程也算了進來 —— 它要飛 1,300 km 才到得了
熄火點,而任務幾何一直把它當成一個點,照原本的幾何飛會飛過休士頓
1,259 km
。現在是三段自洽閉合。

第五次更正把設計點從 L/D 4.0 改成 3.2 —— 4.0 是查文獻來的,
3.2 是算出來的(SU2 無黏裸翼 5.55,加上由實際網格算出的濕面積的平板摩擦,
整機剩 3.21)。熄火速度因此升到 6,298 m/s。

第六次更正把它再降到 2.2。 3.2 那個算法有一個沒被講出來的假設:
它把裸翼的無黏升阻比套在整機上,等於假設機身貢獻升力與阻力的比例
和機翼一樣。機身主要是阻力,所以那是偏樂觀的。改成在整機網格上算
牛頓流(含遮蔽測試),再套 SU2 在裸翼量到的修正,加上整機摩擦:
2.33 @ α 14°。

但 2.33 本身還不是答案 —— 它是在 L/D 3.2 所隱含的進入條件(6,338 m/s)
下算的。摩擦係數是 Re* 的函數,Re* 由弧終點的速度與高度決定,
而那個條件又由升阻比決定:升阻比降低 → 熄火速度升高 → 弧終點速度升高
→ Re* 降低 → C_f 升高 → 升阻比又更低
。這就是本章第 06 節那條設計迴圈,
在這裡變成一個真的數值問題。接到 2.3 自己的弧終點 6,798 m/s 之後只剩 2.21。

阻尼迭代五次收斂到 2.20 @ α 16° —— 那才是自洽的設計點,取 2.2。
熄火速度因此升到 6,819 m/s。2.3 與 2.2 只差 4%,遠在外插修正的
±10% 之內,但「設計點必須是不動點」不是 4% 的問題,是方法上的:
把摩擦釘在固定速度上算出來的升阻比屬於別的設計點。

先跑敏感度再改(這是這一章第二次用同一個流程):掃描 L/D 2.0–3.4,
一路到 2.0 都還可行 —— 質量比最高 16.1,低於「20:1 難以實現」那條線,
酬載分數仍為正。2.2 時質量比 15.5、酬載 3.09%(比 3.2 少 25%),
遠地點與機腹壁溫幾乎不動。全章的招牌結論全部存活。

2.2 仍是估算:三個環節只有第一個是直接算的,第二個從裸翼外插。
要釘死它需要整機的 SU2 解,那件事沒有做。

這次更正還帶出一個新的物理限制:降到 2.3 之後,750 m/s 交棒時
交棒給終端能量管理時,載具比直線進場能吸收的還高 ——
以 750 m/s 交棒的話下滑道要 42°,那不是進場,是俯衝。

後來查清楚:那不是物理限制,是同一個錯誤的第三次。
「用設計下滑道降得完」的交棒速度是升阻比的函數(L/D 4.0 時是
743 m/s、2.2 時是 1,055),而常數寫的是 750 —— 又一個在舊設計點
L/D 4.0 下「剛好對」的值。和進場走廊、摩擦的參考速度是同一類錯。
改成由設計點解出來之後,每個升阻比的下滑道都回到設計值以內,
而代價只是 TAEM 段由星曆的 0.34% 變成 0.97%。

順帶更正:當時寫「往下要動的是翼負荷或 TAEM 進入速度」,
翼負荷那一半是錯的 —— 它方向對但效果很弱,
750 m/s 時由 150 kg/m² 的 45.3° 只能壓到 400 kg/m² 的 39.3°。

第七次更正把設計點從 2.2 再降到 1.74 —— 這一次不是模型換了,
是發現那一環本身算錯了。設計點鏈上唯一直接算的是整機的修正牛頓流,
而它的遮蔽測試有兩個方向相反、互相掩護的錯:零面積三角形參與了遮蔽
(它沒有面積、擋不住東西,但投影足跡可能很長),以及光柵化用的是投影的
「包圍盒」而不是三角形本身(細長的斜三角形會霸佔整個盒子)。
第二個錯的「過度宣稱」剛好補了「佔用集合會漏」的洞,所以先前的解析度
掃描看起來很穩定。

改成深度緩衝 + 可見比例加權之後才真的收斂(80 到 800 格之間穩在
1.73)。新的遮蔽碼有三項驗證:解析度收斂、凸體加不加遮蔽結果相同、
球體的牛頓流阻力對上解析解(差 0.11%)。整機 L/D 因此由 2.90 改為
1.78 @ α 20°,解不動點得到 1.74。熄火速度升到 7,074 m/s。

先跑敏感度再改:掃 L/D 1.4–2.2,一路到 1.4 都還可行(質量比最高 18.0,
仍低於 20:1;酬載分數仍為正)。招牌結論全部存活 —— 但有一件事變了:
設計點 1.74 距離「機翼是淨負擔」的損益平衡點只剩 8%。

後續更正:上面那個 8% 是錯的。那條門檻先前寫成 1.61,
但它是 L/D 4.0 時代的數字,而且程式裡從來沒有函式在算它。

新增的 wing_break_even_ld() 把三種記帳方式都算出來,而只有一種
是對的
:純彈道基準的假設是「起點與落點同半徑、無阻力」——
它根本沒有熄火高度,動力上升段被當成發射點的一個點事件。
所以助推滑翔那一側也要用同一個理想化層級。門檻是 0.81,
設計點 1.74 的餘裕 +116%。「無法排除機翼是淨負擔」收回。

(只在滑翔側加上真實的 1,570 km 上升段沿程會把門檻壓到 0.60 ——
那是不一致的比較,網頁先前畫的就是那一條,已改。)
在 4.0 的時候那是一個遙遠的教學用門檻,現在它是迫近的設計約束。

剩下的是工具邊界而不是航程缺口:弧終點 7,103 m/s 仍高於 Aviator 的
求解上限 5,400 m/s(實機量測),所以那一段要用外部星曆播放。
升阻比提高到 5.62 時弧終點速度降到該上限以下,整條任務可在 Aviator 內
端對端模擬 —— 工具邊界因此不是一條事後才浮現的限制,而是可以寫進規格的設計指標。

這七次更正有個共同點:大多數時候每一次的中間數字都是對的,錯的是組合起來的
形狀、帳、或是那個數字的來源。詳見 程式架構.md。

本章還記錄了一次架構層級的更正:初版用最小能量彈道當彈道段,
算出的遠地點 1,130 km(卡門線的 11 倍)—— 每個數字都對,
組合起來卻是一條沒有有翼載具會飛的軌跡。
現在改為淺角度(γ = 2°)熄火於卡門線,遠地點 117 km。
這個錯誤是從軌跡形狀看出來的,不是數值檢查抓到的。

二、附一個互動式教學工作單。 web/suborbital_workbench.html 是單檔
HTML,所有計算在瀏覽器端完成。移動任一設計變數,射程 → 所需速度 →
Δv → 質量比 → 分離時刻整條鏈會一起動。頁面同時顯示四層狀態:
數學可算 / 模型適用 / 模擬工具 / 工程可行(最後一層恆為「未驗證」)。

程式本身的架構、模組相依、執行順序與已知的坑寫在 程式架構.md。
公式的假設、適用範圍與失準處寫在 web/設計與計算原理.md,
並記錄了兩個在撰寫該文件時查出來的數值錯誤
(地球半徑常數與分析模組不一致、機翼損益平衡點畫在永遠不會相交的曲線上)。

Streamlit 部署

工作單可部署到 Streamlit Community Cloud 取得公開網址:

Main file path            streamlit_app.py
Dependencies              requirements-streamlit.txt   ← 不是根目錄的 requirements.txt

requirements.txt 是課程 Lab 用的(numpy / scipy / matplotlib / pandas /
sgp4 / ppigrf),Streamlit app 一項都不需要 —— 所有運算在瀏覽器端,
伺服器只送出靜態檔。用錯會拖慢建置。

本機試跑:

pip install -r requirements-streamlit.txt
streamlit run streamlit_app.py

streamlit_app.py 只是部署外殼,不是原生 Streamlit app ——
它把同一份 HTML 包進 iframe,而不是把滑桿改寫成 st.slider。
這樣 HTML 版與 Streamlit 版共用同一套公式,不會各自演化。
理由與取捨寫在該檔的 docstring 裡。

基礎知識導論 (primers/)

原本的教材是「實驗單 + 腳本 + 驗證段」—— 學生會做,但不一定知道為什麼這樣做、
以及這個數字憑什麼可信。primers/weekNN_primer.md 補的就是這一段。

每一份的結構固定:

  1. 這一週在解什麼問題 — 把週次主題還原成一個具體的工程問題
  2. 核心觀念 — 帶公式與典型數值,不只是名詞解釋
  3. 名詞與符號 — 一張表,含單位與本課典型值
  4. 觀念 → 本週實驗對照 — 每個觀念對應到哪一支腳本的哪一段
  5. 常見誤解 — 含本教材實測踩過的真實坑
  6. 延伸閱讀 — 外部連結,全部經過連線驗證
  7. 課前自我檢核 — 5 題

導論已收進各週 notebook(在標題之後、實驗之前)與課程 PDF 的每一章開頭,
primers/README.md 另有全課程通用的外部資源彙整。

驗證段:ACK 不等於生效

STK Connect 對絕大多數指令只回「收到」。本教材實測 396 條指令全部 ACK,
但真正能證明生效的只有一部分。學生若養成「送指令 → 沒報錯 → 相信成功了」的習慣,
在工程上是危險的。

因此每一週都附了 weekNN_verify.py(共用工具在 tools/stk_verify.py):

結果分三類:PASS(讀回值符合意圖)、FAIL(ACK 了卻沒生效)、
SKIP(沒有回讀路徑,需另行確認)。離開碼 0/1,可直接進 CI。

python week11_comm/week11_verify.py      # 37 項:回讀 + 結構 + 最差 Eb/No 餘裕
python week10_propulsion/week10_verify.py # 42 項:MCS 段序 + 修正器收斂 + 三次 delta-V

導入驗證段的過程中,它在既有教材裡抓出數個 0-NACK 的靜默失敗,包括
Model.DesignFrequency 屬性不存在、設定天線型別會沖掉先前寫的設計頻率、
Week 11 沿用 Lab1 掃描起點導致鏈路完全沒有 access、以及 Week 4 的
SolarPanel DeleteData 會讓 Week 7 的發電計算產出空報告。

Python Lab 快速執行

python week03_budgets/week3_mission_budgets.py     # 四大預算 + 圖
python week05_fea/week5_fea_launch_vibe.py          # FEA 模態 + 隨機振動
python week06_thermal/week6_thermal_network.py      # 節點溫度曲線
python week08_adcs/week8_detumble_stk_integrated.py # B-dot 消旋 + .a 姿態檔(約 18 s)
python week12_payload_data/week12_data_budget.py    # 資料預算 + 記錄器 + 速率上限
python week14_operations/week14_pass_scheduler.py   # 地面站通聯排程
python week16_constellation/week16_constellation_tradeoff.py  # 星座規模 vs 重訪
python week11_comm/week11_verify.py                 # 驗證段:確認參數真的生效(需 STK)