
簡介本資源是一款面向iOS 17設(shè)備用戶的免越獄虛擬定位跑步模擬工具專為需在不實際運動情況下完成健康類App打卡如Nike Run Club、Keep等的開發(fā)者、測試人員及進(jìn)階用戶設(shè)計解決因天氣、時間或身體限制無法真實跑步時的數(shù)據(jù)模擬需求。壓縮包共16個文件含9個Python核心腳本如main.py、run.py、route.py實現(xiàn)路徑加載與設(shè)備通信、2個文本配置文件HNroute.txt提供預(yù)置路線README.md說明使用流程、1個YAML配置模板config.yaml支持自定義距離/速度/軌跡點、以及LICENSE、.gitignore等工程規(guī)范文件整體僅15KB輕量易部署。目前已有707人學(xué)習(xí)下載。用戶可直接運行CLI工具通過在線拾取真實跑步路徑、設(shè)置起止點與配速參數(shù)生成符合iOS定位框架要求的模擬運動軌跡項目結(jié)構(gòu)清晰含driver/、util/等模塊化目錄附帶GitHub Actions配置dependabot.yml與完整依賴清單requirements.txt便于二次開發(fā)與跨平臺適配。1. 免越獄也能精準(zhǔn)模擬跑步軌跡為什么這套 iOS 17 虛擬定位方案成了課設(shè)答辯和企業(yè)內(nèi)測雙場景下的“穩(wěn)態(tài)選擇”你有沒有遇到過這種尷尬導(dǎo)師說“畢設(shè)要體現(xiàn)真實業(yè)務(wù)邏輯”可一打開 Xcode 就卡在「iOS 真機調(diào)試必須簽名」團(tuán)隊想驗證運動類 App 的軌跡上報策略但手頭只有三臺真機、沒人敢越獄、模擬器又壓根不支持 CoreLocation更別提測試多端同步——Android 測完 iOS 還得重搭一套。這不是玄學(xué)是現(xiàn)實里每天都在發(fā)生的開發(fā)斷點。這套方案不碰越獄、不依賴第三方服務(wù)、不改系統(tǒng)級權(quán)限只用 iOS 17 原生支持的 Location Simulation 自定義 GPX 軌跡注入 跨平臺坐標(biāo)協(xié)議封裝把「模擬跑步打卡」從黑匣子操作變成可配置、可回放、可嵌入 CI/CD 的標(biāo)準(zhǔn)動作。它適合兩類人一類是正在趕 iOS 課設(shè)/畢設(shè)的學(xué)生需要一份能跑通、能講清、能現(xiàn)場演示的完整交付物另一類是中小團(tuán)隊的 QA 或前端工程師要在無越獄真機上做軌跡類功能回歸——不是為了造假而是為了把「位置變化」這個不可控變量變成可控的測試輸入。2. 總體架構(gòu)設(shè)計三層結(jié)構(gòu)與四個核心模塊的職責(zé)劃分整套方案不是簡單拖一個 GPX 文件進(jìn) Xcode 就完事。它按「輸入層 → 控制層 → 注入層 → 驗證層」四層解耦確保每個環(huán)節(jié)可替換、可日志、可審計。iOS 17 的Simulate Location功能雖開放了 UI 操作入口但它本質(zhì)是 Xcode 對simctl命令的圖形化封裝底層仍走的是com.apple.CoreSimulator.SimDevice的私有通信通道。我們繞開 GUI直接對接simctl的 CLI 接口并在其之上構(gòu)建一層輕量控制協(xié)議讓軌跡模擬這件事脫離 IDE 環(huán)境變成可腳本化、可參數(shù)化的工程行為。2.1 輸入層GPX 軌跡文件的生成與校驗規(guī)范GPXGPS Exchange Format是跨平臺通用的地理坐標(biāo)交換格式但不是所有 GPX 都能被 iOS 模擬器正確識別。iOS 17 要求 GPX 文件必須滿足三項硬性條件必須包含time標(biāo)簽且時間戳需為 ISO 8601 格式如2024-05-20T08:30:00Z不能是相對時間或 Unix 時間戳trkpt中的ele海拔字段為可選但若存在值必須為數(shù)字不能為空或字符串整個 GPX 文件必須以gpx version1.1 ...開頭且version屬性嚴(yán)格為1.11.0或缺失均會觸發(fā) simctl 解析失敗。下面是一段經(jīng)實測通過的最小合法 GPX 片段用于 5 分鐘勻速直線跑步起點緯度 39.9042經(jīng)度 116.4074速度約 3.3 m/s?xml version1.0 encodingUTF-8? gpx version1.1 creatoriOS-GPX-Generator xmlnshttp://www.topografix.com/GPX/1/1 trk nameRun_5min_Straight/name trkseg trkpt lat39.904200 lon116.407400 time2024-05-20T08:30:00Z/time /trkpt trkpt lat39.904255 lon116.407488 time2024-05-20T08:30:10Z/time /trkpt trkpt lat39.904310 lon116.407576 time2024-05-20T08:30:20Z/time /trkpt trkpt lat39.904365 lon116.407664 time2024-05-20T08:30:30Z/time /trkpt trkpt lat39.904420 lon116.407752 time2024-05-20T08:30:40Z/time /trkpt trkpt lat39.904475 lon116.407840 time2024-05-20T08:30:50Z/time /trkpt trkpt lat39.904530 lon116.407928 time2024-05-20T08:31:00Z/time /trkpt /trkseg /trk /gpx提示這段 GPX 的關(guān)鍵在于時間間隔嚴(yán)格為 10 秒、經(jīng)緯度增量線性遞增對應(yīng)勻速、且所有time標(biāo)簽使用 UTC 時間Z 后綴。本地時區(qū)時間如08:00在某些 Xcode 版本中會導(dǎo)致模擬失敗這是血淚經(jīng)驗——我曾因沒加Z后綴在 Xcode 15.3 上反復(fù)失敗 7 次才定位到問題。2.2 控制層基于 simctl 的軌跡注入調(diào)度器設(shè)計simctl是 Apple 官方提供的模擬器命令行工具位于/Applications/Xcode.app/Contents/Developer/usr/bin/simctl。其boot、shutdown、spawn等子命令廣為人知但location子命令卻極少被文檔覆蓋。iOS 17 新增了simctl location device gpx-file支持但該命令有三個隱藏約束設(shè)備必須處于已啟動且前臺無鎖屏狀態(tài)即state Booted且isLocked falseGPX 文件路徑必須為絕對路徑相對路徑會被靜默忽略同一設(shè)備連續(xù)調(diào)用需間隔 ≥ 2 秒否則后一次調(diào)用會覆蓋前一次且不報錯。因此我們封裝了一個 Python 調(diào)度器gpx_injector.py它不直接執(zhí)行simctl location而是先輪詢設(shè)備狀態(tài)、再校驗 GPX、最后帶重試機制執(zhí)行注入# gpx_injector.py import subprocess import time import json from pathlib import Path def get_device_state(udid: str) - dict: 獲取指定設(shè)備當(dāng)前狀態(tài) result subprocess.run( [xcrun, simctl, list, devices, --json], capture_outputTrue, textTrue ) devices json.loads(result.stdout) for runtime in devices[devices].values(): for dev in runtime: if dev[udid] udid: return { state: dev.get(state, Unknown), isLocked: dev.get(isLocked, True) } return {state: NotFound, isLocked: True} def inject_gpx(udid: str, gpx_path: str, max_retries3): 向指定設(shè)備注入 GPX 軌跡含狀態(tài)檢查與重試 gpx_abs str(Path(gpx_path).resolve()) for attempt in range(max_retries): state get_device_state(udid) if state[state] ! Booted or state[isLocked]: print(f[{attempt1}/{max_retries}] 設(shè)備未就緒狀態(tài){state[state]}鎖定{state[isLocked]}等待 3s...) time.sleep(3) continue # 執(zhí)行注入 cmd [xcrun, simctl, location, udid, gpx_abs] result subprocess.run(cmd, capture_outputTrue, textTrue) if result.returncode 0: print(f? GPX 注入成功{gpx_abs}) return True else: print(f[{attempt1}/{max_retries}] 注入失敗{result.stderr.strip()}) time.sleep(2) raise RuntimeError(GPX 注入連續(xù)失敗檢查設(shè)備狀態(tài)與 GPX 文件路徑) if __name__ __main__: # 示例向 iPhone 15 Pro (iOS 17.4) 注入軌跡 inject_gpx( udidA1B2C3D4-E5F6-7890-G1H2-I3J4K5L6M7N8, gpx_path./tracks/run_5min.gpx )這段代碼的核心價值在于它把原本需要人工點擊 Xcode → Debug → Simulate Location → 選文件的流程變成了一個可寫入 Makefile 或 GitHub Actions 的原子操作。更重要的是它顯式暴露了「設(shè)備就緒性」這一常被忽略的狀態(tài)依賴——很多同學(xué)跑不通根本原因不是 GPX 寫錯而是模擬器剛啟動完還在加載 SpringBoard此時調(diào)用simctl location就是無效的。2.3 注入層iOS 端 App 的位置監(jiān)聽適配要點光有simctl注入還不夠。你的 App 必須主動監(jiān)聽位置變化否則模擬器發(fā)了坐標(biāo)App 卻沒收到。iOS 17 對CLLocationManager的權(quán)限模型做了微調(diào)即使用戶授予了whenInUse權(quán)限App 在后臺超過 10 秒后也會被系統(tǒng)掛起導(dǎo)致無法持續(xù)接收模擬位置。因此我們在 App 啟動時強制啟用「始終允許」權(quán)限申請僅用于測試環(huán)境并在 Info.plist 中聲明keyNSLocationAlwaysAndWhenInUseUsageDescription/key string本應(yīng)用在測試模式下需持續(xù)獲取位置用于驗證跑步軌跡上報邏輯/string keyNSLocationWhenInUseUsageDescription/key string本應(yīng)用在使用中需獲取位置用于記錄跑步路線/string同時在CLLocationManagerDelegate實現(xiàn)中我們增加了一層防抖與采樣率控制// Swift 5.9 / iOS 17 func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { guard let latest locations.last else { return } // 防抖僅處理時間戳變化 500ms 的位置更新 let delta abs(latest.timestamp.timeIntervalSinceReferenceDate - lastReceivedTimestamp.timeIntervalSinceReferenceDate) guard delta 0.5 else { return } lastReceivedTimestamp latest.timestamp // 采樣每 3 秒記錄一次避免高頻寫入影響性能 if CACurrentMediaTime() - lastSampleTime 3.0 { recordRunningPoint(latest.coordinate, timestamp: latest.timestamp) lastSampleTime CACurrentMediaTime() } }這段邏輯解決了兩個實際問題一是模擬器在高速注入時可能產(chǎn)生密集抖動尤其 GPX 時間間隔 1s二是避免測試期間因頻繁寫數(shù)據(jù)庫導(dǎo)致主線程卡頓。這不是教科書寫法而是某高校課程設(shè)計組在答辯前夜發(fā)現(xiàn)「模擬跑步時 App 卡死」后緊急補上的補丁。2.4 驗證層跨平臺軌跡比對與打卡結(jié)果確認(rèn)機制最終目標(biāo)不是「讓模擬器動起來」而是「驗證 App 是否按預(yù)期處理了這些位置」。為此我們設(shè)計了一套輕量驗證協(xié)議App 在每次成功上報軌跡點后向本地 HTTP Server運行在 Mac 主機發(fā)送一條 JSON 日志Server 將其與原始 GPX 中的理論坐標(biāo)做歐氏距離比對單位米并生成比對報告。Mac 端驗證服務(wù)用 Python Flask 實現(xiàn)verifier_server.py# verifier_server.py from flask import Flask, request, jsonify import json import math from typing import Dict, List, Tuple app Flask(__name__) expected_points: List[Tuple[float, float, float]] [] # (lat, lon, timestamp_sec) def haversine_distance(lat1, lon1, lat2, lon2): R 6371000 # 地球半徑單位米 dLat math.radians(lat2 - lat1) dLon math.radians(lon2 - lon1) a math.sin(dLat/2)**2 math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) * math.sin(dLon/2)**2 c 2 * math.asin(math.sqrt(a)) return R * c app.route(/report, methods[POST]) def receive_report(): data request.get_json() actual_lat data[latitude] actual_lon data[longitude] actual_ts data[timestamp] # Unix timestamp # 查找最接近的理論點時間差最小 best_match min( expected_points, keylambda p: abs(p[2] - actual_ts), defaultNone ) if not best_match: return jsonify({status: error, reason: no_matching_point}), 400 dist haversine_distance(actual_lat, actual_lon, best_match[0], best_match[1]) return jsonify({ status: ok, distance_meters: round(dist, 2), threshold_met: dist 15.0 # 允許 15 米誤差 }) if __name__ __main__: # 預(yù)加載 GPX 中的理論點此處省略解析邏輯 expected_points [ (39.904200, 116.407400, 1716194400.0), # 2024-05-20T08:30:00Z (39.904255, 116.407488, 1716194410.0), # ... 其余點 ] app.run(host0.0.0.0, port8080)App 端只需在recordRunningPoint后追加一行 HTTP POSTfunc reportToVerifier(_ coord: CLLocationCoordinate2D, timestamp: Date) { guard let url URL(string: http://127.0.0.1:8080/report) else { return } var request URLRequest(url: url) request.httpMethod POST request.setValue(application/json, forHTTPHeaderField: Content-Type) let body: [String: Any] [ latitude: coord.latitude, longitude: coord.longitude, timestamp: timestamp.timeIntervalSince1970 ] request.httpBody try? JSONSerialization.data(withJSONObject: body) URLSession.shared.dataTask(with: request).resume() }這樣一次完整的「模擬跑步→App 處理→結(jié)果驗證」就形成了閉環(huán)。你不再靠肉眼觀察地圖是否移動而是拿到一份帶誤差數(shù)值的量化報告——這正是答辯時最硬的底氣。3. 跨平臺支持實現(xiàn)Android 側(cè)復(fù)用同一套 GPX 協(xié)議與驗證邏輯雖然標(biāo)題強調(diào) iOS但「跨平臺支持」不是噱頭。Android 側(cè)我們不依賴任何商業(yè) SDK 或 root 權(quán)限而是利用 Android 12 原生支持的「Mock Location」機制配合 ADB 命令注入坐標(biāo)。關(guān)鍵在于Android 和 iOS 使用同一套 GPX 文件作為輸入源且驗證服務(wù)完全復(fù)用。這意味著你寫一次軌跡、跑兩套平臺、出一份報告。3.1 Android 側(cè) Mock Location 的免 root 啟用流程Android 12API 31起系統(tǒng)允許開發(fā)者通過adb shell settings put global mock_location 1啟用模擬位置但前提是設(shè)備已開啟「開發(fā)者選項」「模擬位置應(yīng)用」已明確指定為你自己的 App而非「無」或「None」App 的AndroidManifest.xml中聲明了android.permission.ACCESS_MOCK_LOCATION僅 debug build。!-- AndroidManifest.xml (debug only) -- uses-permission android:nameandroid.permission.ACCESS_MOCK_LOCATION /然后我們編寫一個adb_injector.sh腳本將 GPX 中的trkpt解析為adb shell am broadcast命令序列#!/bin/bash # adb_injector.sh GPX_FILE$1 DEVICE_ID$2 # 提取 GPX 中所有 trkpt 并轉(zhuǎn)為 adb 命令 xmlstar --text -t -m //trkpt \ -o adb shell am broadcast -a com.example.mock.LOCATION_UPDATE \ -o --es lat -v lat \ -o --es lon -v lon \ -o --es time -v time/text() \ $GPX_FILE | while read cmd; do echo [ADB] $cmd eval $cmd sleep 1 # 每點間隔 1 秒避免廣播隊列溢出 done注意xmlstar是 macOS/Linux 下解析 XML 的輕量命令行工具brew install xmlstar比用 Python 解析更貼近 Shell 工程習(xí)慣。Android 側(cè)不追求毫秒級精度1 秒間隔足夠覆蓋絕大多數(shù)運動類 App 的采樣邏輯。3.2 統(tǒng)一驗證服務(wù)的雙端兼容改造原 Flask 驗證服務(wù)只需微調(diào)路由即可同時接收 iOS 和 Android 上報# verifier_server.py續(xù) app.route(/report/platform, methods[POST]) # 新增 platform 參數(shù) def receive_report_by_platform(platform): if platform not in [ios, android]: return jsonify({error: invalid platform}), 400 data request.get_json() # ... 解析邏輯不變 # 區(qū)別僅在于Android 上報的時間戳可能為毫秒級Java System.currentTimeMillis() # 需統(tǒng)一轉(zhuǎn)為秒級浮點數(shù) actual_ts data[timestamp] / 1000.0 if platform android else data[timestamp] # 后續(xù)比對邏輯完全一致 ...App 端也只需在 URL 中帶上平臺標(biāo)識// iOS let url URL(string: http://127.0.0.1:8080/report/ios) // Android (Kotlin) val url http://127.0.0.1:8080/report/android至此「同一份 GPX → 兩套注入腳本 → 一個驗證服務(wù)」的跨平臺骨架就立住了。它不追求 Android 和 iOS 行為 100% 一致畢竟系統(tǒng)調(diào)度機制不同但保證了輸入源、驗證邏輯、誤差閾值的完全統(tǒng)一——這才是工程上真正可落地的「跨平臺」。4. 常見問題排查五個最容易翻車的點與對應(yīng)解法這套方案在某高校 3 個 iOS 課設(shè)組、2 個企業(yè)內(nèi)測項目中累計運行超 200 小時以下是高頻踩坑點的濃縮總結(jié)。每一條都來自真實翻車現(xiàn)場不是理論推測。4.1 現(xiàn)象Xcode 中點擊 “Simulate Location” 無反應(yīng)或彈窗一閃而逝原因Xcode 15.3 默認(rèn)禁用了「自動簽名」對模擬器的支持且模擬器設(shè)備未被正確識別為「可調(diào)試目標(biāo)」。解決在 Xcode → Preferences → Accounts → Manage Certificates 中右鍵點擊 Apple ID → 「Create iOS Development Certificate」然后在項目 Target → Signing Capabilities → Team 選擇該證書最后 Clean Build Folder??K并重啟 Xcode。4.2 現(xiàn)象simctl location命令返回Error: Could not find device with udid XXX原因UDID 輸入錯誤或設(shè)備未出現(xiàn)在simctl list devices輸出中常見于新創(chuàng)建的模擬器未啟動。解決先執(zhí)行xcrun simctl list devices復(fù)制輸出中iPhone 15 Pro (iOS 17.4) (XXXX...)括號內(nèi)的完整 UDID再確認(rèn)該設(shè)備是否處于Booted狀態(tài)xcrun simctl list devices --json查看state字段若為Shutdown先執(zhí)行xcrun simctl boot XXXX...。4.3 現(xiàn)象App 收到位置更新但坐標(biāo)始終為(0.0, 0.0)原因iOS 17 模擬器在首次啟動后若未手動打開一次「地圖」App 或「天氣」App 觸發(fā)定位初始化CoreLocation 會返回默認(rèn)零點。解決在注入 GPX 前先用xcrun simctl launch udid com.apple.Maps啟動地圖 App等待 3 秒后關(guān)閉xcrun simctl terminate udid com.apple.Maps再執(zhí)行注入。4.4 現(xiàn)象Android 側(cè)adb shell am broadcast發(fā)送后App 無響應(yīng)原因Broadcast Receiver 未在AndroidManifest.xml中靜態(tài)注冊或intent-filteraction 名稱不匹配。解決確保在AndroidManifest.xml的application內(nèi)聲明receiver android:name.MockLocationReceiver android:exportedtrue intent-filter action android:namecom.example.mock.LOCATION_UPDATE / /intent-filter /receiver且MockLocationReceiver類繼承自BroadcastReceiver并在onReceive()中解析intent.getStringExtra(lat)等字段。4.5 現(xiàn)象驗證服務(wù)返回distance_meters 100遠(yuǎn)超 15 米閾值原因GPX 中time標(biāo)簽使用了本地時區(qū)如08:00而simctl解析時將其誤認(rèn)為 UTC導(dǎo)致時間軸整體偏移 8 小時理論點與實際點完全錯位。解決用文本編輯器全局替換 GPX 中所有08:00為Z或用 Python 腳本強制標(biāo)準(zhǔn)化from datetime import datetime import re def fix_gpx_timezone(gpx_content: str) - str: # 匹配 time2024-05-20T08:30:0008:00/time 類型 def to_utc(match): dt datetime.fromisoformat(match.group(1)) utc_dt dt.astimezone(timezone.utc) return ftime{utc_dt.isoformat().replace(00:00, Z)}/time return re.sub(rtime([^])/time, to_utc, gpx_content)5. 答辯與驗收用「三步驗證法」讓評委當(dāng)場點頭而不是事后查日志答辯不是講 PPT是現(xiàn)場 demo。我?guī)н^的幾個課設(shè)組凡是能一次性跑通、且評委能親手操作驗證的基本都拿了高分。秘訣不是炫技而是把「驗證權(quán)」交出去——讓評委自己點按鈕、看數(shù)據(jù)、下結(jié)論。為此我固化了一套「三步驗證法」它不依賴你的口才只依賴方案本身的可驗證性。5.1 第一步一鍵啟動「全鏈路沙箱」耗時 ≤ 45 秒在項目根目錄下我們提供一個demo_setup.sh腳本它自動完成以下五件事啟動一臺預(yù)配置的 iPhone 15 Pro (iOS 17.4) 模擬器安裝已簽名的測試版 AppDebug build啟動本地驗證服務(wù)Flask加載默認(rèn) GPX 軌跡./tracks/demo_run.gpx輸出一條清晰指令「請打開 App → 點擊【開始跑步】→ 30 秒后查看終端驗證報告」。#!/bin/bash # demo_setup.sh echo 正在啟動全鏈路沙箱... xcrun simctl shutdown all xcrun simctl boot iPhone 15 Pro (iOS 17.4) sleep 8 xcrun simctl install iPhone 15 Pro (iOS 17.4) ./build/Runner.app open -a Simulator python3 verifier_server.py /dev/null 21 echo ? 沙箱就緒請執(zhí)行 echo 1. 打開 Simulator echo 2. 點擊 App 圖標(biāo) echo 3. 點擊【開始跑步】 echo 4. 等待 30 秒查看下方終端輸出評委不需要懂 Swift 或 GPX他只要照著四步做就能看到終端滾動出distance_meters: 2.34, threshold_met: True。這比你說一百遍「我們做了充分測試」都有力。5.2 第二步提供「可編輯 GPX」與「實時誤差熱力圖」答辯時評委常問「如果我想測一段爬坡路線呢」——這時千萬別現(xiàn)場改代碼。我們在./tracks/目錄下預(yù)置了 5 個典型 GPXflat_run.gpx平路、hill_climb.gpx爬升、circle_loop.gpx環(huán)形、stop_start.gpx啟停、gps_drift.gpx模擬信號漂移。每個文件都附帶 README.md說明其設(shè)計意圖與理論誤差范圍。更進(jìn)一步我們用 Python Matplotlib 生成「誤差熱力圖」將驗證服務(wù)收集的所有distance_meters值按時間順序繪制成折線圖并用紅色虛線標(biāo)出 15 米閾值。圖中還標(biāo)注了「最大誤差點」對應(yīng)的 GPX 序號與時間戳方便評委快速定位異常段。# generate_heatmap.py import matplotlib.pyplot as plt import json with open(verification_log.json) as f: logs json.load(f) distances [log[distance_meters] for log in logs] timestamps list(range(len(distances))) plt.figure(figsize(10, 4)) plt.plot(timestamps, distances, b-, linewidth1.5, label實測誤差米) plt.axhline(y15.0, colorr, linestyle--, label閾值 15 米) plt.xlabel(軌跡點序號) plt.ylabel(與理論點距離米) plt.title(跑步軌跡模擬誤差熱力圖) plt.legend() plt.grid(True, alpha0.3) plt.savefig(heatmap.png, dpi150, bbox_inchestight)這張圖放在答辯 PPT 的「測試結(jié)果」頁評委一眼就能判斷誤差是否可控、是否存在系統(tǒng)性偏差、哪個階段最不穩(wěn)定。它把抽象的「精度」轉(zhuǎn)化成了具象的視覺證據(jù)。5.3 第三步交付「可審計的驗證包」而非「可運行的代碼包」最終交付物不是.zip源碼而是一個verification_bundle.zip內(nèi)含report.pdf含所有測試用例的誤差統(tǒng)計表平均誤差、最大誤差、達(dá)標(biāo)率heatmap.png上述熱力圖verification_log.json原始驗證日志含每點時間戳、理論坐標(biāo)、實測坐標(biāo)、誤差值demo_recording.mp430 秒屏幕錄制展示從點擊「開始跑步」到終端輸出All points verified ?的全過程。提示這份包的價值在于「可審計」。評委可以下載verification_log.json用 Excel 打開自己算一遍平均誤差可以拿heatmap.png和你的 PPT 圖對比確認(rèn)是否一致甚至可以拿demo_recording.mp4回放核對時間點是否吻合。它不依賴你的解釋只依賴數(shù)據(jù)本身。從那以后我每次交付課設(shè)都強制走一遍make verification_bundle哪怕多花 10 分鐘也比答辯時被問住強。希望幫到你。本文還有配套的精品資源點擊獲取