絡(luò)仿真:從節(jié)點(diǎn)建模到參數(shù)推導(dǎo)的完整實(shí)踐)
簡(jiǎn)介在無線通信系統(tǒng)設(shè)計(jì)中媒體訪問控制MAC協(xié)議決定了信道資源的分配效率與確定性保障。時(shí)分多址TDMA通過將時(shí)間劃分為固定時(shí)隙使各節(jié)點(diǎn)在專屬時(shí)隙內(nèi)傳輸從根本上避免了隨機(jī)碰撞為低時(shí)延、高可靠場(chǎng)景提供了基礎(chǔ)支撐。網(wǎng)絡(luò)仿真技術(shù)則能夠在真實(shí)部署前驗(yàn)證協(xié)議邏輯與參數(shù)配置而OPNET作為經(jīng)典的三層建模工具憑借其網(wǎng)絡(luò)域、節(jié)點(diǎn)域、進(jìn)程域的清晰分層和有限狀態(tài)機(jī)機(jī)制成為研究TDMA等MAC協(xié)議的主流平臺(tái)。從節(jié)點(diǎn)模型改造、收發(fā)狀態(tài)機(jī)設(shè)計(jì)到幀長(zhǎng)與保護(hù)時(shí)隙的工程計(jì)算再到仿真結(jié)果分析與協(xié)議迭代這一套方法可廣泛應(yīng)用于無線數(shù)據(jù)采集、戰(zhàn)術(shù)自組網(wǎng)、應(yīng)急通信等工程實(shí)踐。本文以實(shí)際項(xiàng)目復(fù)盤的方式完整呈現(xiàn)用OPNET搭建無線TDMA網(wǎng)絡(luò)的關(guān)鍵路徑幫助讀者系統(tǒng)掌握建模、仿真、排錯(cuò)與改進(jìn)的閉環(huán)方法。1. 為什么是OPNET為什么是TDMA這組技術(shù)棧解決的真實(shí)問題做無線網(wǎng)絡(luò)協(xié)議的人對(duì)TDMA一定不陌生。時(shí)分多址TDMATime Division Multiple Access把信道在時(shí)間上切成一段段等長(zhǎng)的時(shí)隙每個(gè)節(jié)點(diǎn)只在屬于自己的時(shí)隙里發(fā)送數(shù)據(jù)其余時(shí)間要么接收、要么休眠。這種接入方式最核心的價(jià)值是確定性——一個(gè)時(shí)隙里只有一個(gè)節(jié)點(diǎn)在發(fā)不會(huì)發(fā)生隨機(jī)的數(shù)據(jù)碰撞端到端時(shí)延可預(yù)測(cè)尤其適合需要低時(shí)延保障、遠(yuǎn)距離窄帶通信、節(jié)點(diǎn)數(shù)量相對(duì)固定的場(chǎng)景比如無線數(shù)據(jù)采集系統(tǒng)、應(yīng)急指揮通信網(wǎng)、戰(zhàn)術(shù)自組網(wǎng)等。即便是現(xiàn)在各種新協(xié)議層出不窮TDMA在特定場(chǎng)景下依然是繞不開的基礎(chǔ)方案。OPNET則是一款經(jīng)典的網(wǎng)絡(luò)仿真工具它最大的優(yōu)勢(shì)在于支持三層建模網(wǎng)絡(luò)域、節(jié)點(diǎn)域、進(jìn)程域。網(wǎng)絡(luò)域里擺節(jié)點(diǎn)、拖鏈路節(jié)點(diǎn)域里定義模塊之間的數(shù)據(jù)流向進(jìn)程域里用有限狀態(tài)機(jī)精確描述協(xié)議邏輯。對(duì)MAC層協(xié)議做定制化仿真這套建模機(jī)制剛好踩在點(diǎn)子上——你不需要從頭寫一套物理層信道模型OPNET已經(jīng)幫你處理了發(fā)射功率、路徑損耗、接收靈敏度、干擾計(jì)算這些底層的無線電傳播數(shù)學(xué)運(yùn)算你需要做的是在MAC層把TDMA的幀結(jié)構(gòu)、時(shí)隙調(diào)度、收發(fā)邏輯寫清楚。所以這篇文章不是講TDMA的理論課而是結(jié)結(jié)實(shí)實(shí)的一次仿真實(shí)踐復(fù)盤從零開始用OPNET搭一個(gè)無線TDMA網(wǎng)絡(luò)節(jié)點(diǎn)模型怎么改、狀態(tài)機(jī)怎么畫、幀長(zhǎng)時(shí)隙數(shù)怎么算、仿真跑通之后數(shù)據(jù)怎么解讀。這一套完整走下來你就能把TDMA OPNET 無線這組技術(shù)棧真正用起來而不是看了一堆資料還是不知道從哪下手。我默認(rèn)你看過OPNET的基礎(chǔ)操作至少知道怎么建工程、怎么搭簡(jiǎn)單節(jié)點(diǎn)鏈路。如果完全沒接觸過建議先跑一遍Modeler自帶的無線網(wǎng)絡(luò)教程再回到這里來。2. 模型改造的完整路徑從三層建模到TDMA MAC落地2.1 節(jié)點(diǎn)模型里各模塊怎么重新定義OPNET默認(rèn)提供的無線節(jié)點(diǎn)模型比如wlan_station_adv或者wlan_wkstn_adv都是802.11 MAC實(shí)現(xiàn)想要改成TDMA最直接的辦法是不用這些現(xiàn)成模型而是自己搭一個(gè)節(jié)點(diǎn)模型。聽起來有點(diǎn)土但這反而是最穩(wěn)妥的做法——你不需要跟自帶的WLAN協(xié)議狀態(tài)機(jī)做對(duì)抗也不用擔(dān)心改了一個(gè)屬性導(dǎo)致另外一堆底層行為不可控。我常用的自定義節(jié)點(diǎn)結(jié)構(gòu)是這樣的source模塊業(yè)務(wù)生成器按固定速率或隨機(jī)間隔產(chǎn)生數(shù)據(jù)包mac_tdma模塊核心的TDMA調(diào)度處理器負(fù)責(zé)幀同步、時(shí)隙判斷、排隊(duì)、發(fā)送觸發(fā)tx模塊無線發(fā)射機(jī)配置頻率、數(shù)據(jù)速率、調(diào)制方式rx模塊無線接收機(jī)配置匹配的接收頻率、靈敏度ant模塊天線仿真里一般用全向天線就夠模塊之間的包流連接是source - mac_tdma - tx接收方向是rx - mac_tdma。這里有一個(gè)容易被忽視的點(diǎn)mac_tdma同時(shí)連接了發(fā)射機(jī)和接收機(jī)所以它要能處理兩種觸發(fā)事件。一種是從上層的包到達(dá)stream intrpt另一種是物理層的包到達(dá)同樣也是stream intrpt區(qū)別要看中斷來源是哪個(gè)輸入流。還要考慮接收節(jié)點(diǎn)收到包之后要不要回復(fù)ACK這取決于你的協(xié)議有沒有設(shè)計(jì)確認(rèn)機(jī)制。實(shí)際上OPNET的節(jié)點(diǎn)模型編輯很簡(jiǎn)單從模塊面板拖幾個(gè)圖標(biāo)出來連上包流和統(tǒng)計(jì)線設(shè)置好參數(shù)。難的是背后進(jìn)程模型怎么寫。這就像搭積木模塊是積木塊進(jìn)程模型才是積木里的彈簧和齒輪。2.2 進(jìn)程模型狀態(tài)機(jī)TDMA收發(fā)狀態(tài)機(jī)的轉(zhuǎn)移條件設(shè)計(jì)進(jìn)程模型是TDMA邏輯的真正承載者也是整個(gè)仿真中最費(fèi)時(shí)間的部分。我設(shè)計(jì)的狀態(tài)機(jī)包含這樣幾個(gè)狀態(tài)強(qiáng)制狀態(tài)用/標(biāo)出非強(qiáng)制狀態(tài)是阻塞轉(zhuǎn)移點(diǎn)INIT讀入節(jié)點(diǎn)屬性登記統(tǒng)計(jì)句柄生成第一個(gè)自中斷進(jìn)入WAIT_FRAME。這是一個(gè)強(qiáng)制狀態(tài)。WAIT_FRAME非強(qiáng)制狀態(tài)等待幀時(shí)鐘。每次自中斷到點(diǎn)根據(jù)當(dāng)前op_sim_time()計(jì)算幀內(nèi)相位。SLOT_TX當(dāng)幀內(nèi)相位落到本節(jié)點(diǎn)發(fā)射時(shí)隙時(shí)進(jìn)入此狀態(tài)構(gòu)造并發(fā)送數(shù)據(jù)包然后重新安排下一次中斷。SLOT_RX相位落在其他節(jié)點(diǎn)時(shí)隙時(shí)進(jìn)入此狀態(tài)監(jiān)聽無線信道。實(shí)際情況下這個(gè)狀態(tài)不需要額外處理接收動(dòng)作因?yàn)镺PNET的無線接收是物理層事件驅(qū)動(dòng)的包到達(dá)時(shí)自然觸發(fā)流中斷你只需要在收包中斷處理里完成數(shù)據(jù)接收。CHECK_EVENT統(tǒng)一處理各種中斷類型包括自中斷、流中斷、統(tǒng)計(jì)中斷。關(guān)鍵點(diǎn)是自中斷的調(diào)度方式。我常用的做法是節(jié)點(diǎn)每毫秒醒來一次判斷當(dāng)前時(shí)間在幀結(jié)構(gòu)里的位置。偽邏輯是這樣frame_start floor(op_sim_time() / FRAME_DURATION) * FRAME_DURATION slot_index floor((op_sim_time() - frame_start) / SLOT_DURATION) if slot_index my_slot: 發(fā)送數(shù)據(jù)這個(gè)判斷看起來簡(jiǎn)單實(shí)際落地時(shí)要處理一個(gè)細(xì)節(jié)發(fā)送時(shí)隙邊界和自中斷之間的相位誤差。仿真中自中斷畢竟是離散的如果節(jié)點(diǎn)在第5.021秒醒來發(fā)現(xiàn)自己的時(shí)隙從第5.020秒開始那它已經(jīng)晚了1毫秒。為了精確可以在每次睡之前計(jì)算出離自己時(shí)隙邊界還有多久然后精確調(diào)度自中斷。這種做法會(huì)讓狀態(tài)機(jī)多一個(gè)狀態(tài)但精度高得多特別是在慢仿真步長(zhǎng)下錯(cuò)誤概率不會(huì)積累。狀態(tài)轉(zhuǎn)移條件寫在狀態(tài)之間的連線上用宏定義來區(qū)分。比如(op_intrpt_type() OPC_INTRPT_SELF)判斷是不是自中斷(op_intrpt_strm() SOURCE_STRM)判斷是不是上層業(yè)務(wù)流。整個(gè)狀態(tài)機(jī)畫出來大概6到8個(gè)狀態(tài)初期不用追求一次性完美先跑通基本收發(fā)再逐步加保護(hù)時(shí)隙、加同步校驗(yàn)。2.3 無線收發(fā)射頻參數(shù)與包格式的關(guān)聯(lián)設(shè)置很多人在節(jié)點(diǎn)模型上花了大功夫結(jié)果發(fā)現(xiàn)仿真里數(shù)據(jù)全丟最后排查半天是無線參數(shù)的鍋。這種坑在無線OPNET仿真里太常見了我甚至覺得無線參數(shù)配置才是真正區(qū)分懂不懂無線仿真的分水嶺。收發(fā)配置里最重要的幾個(gè)參數(shù)數(shù)據(jù)速率Data Rate發(fā)射機(jī)和接收機(jī)必須一致比如1 Mbps或250 kbps。不同數(shù)據(jù)速率直接影響每個(gè)時(shí)隙能塞下多少包。包格式Packet Format在發(fā)射機(jī)里指定。OPNET按包格式識(shí)別到達(dá)包的類型接收機(jī)的匹配格式要和發(fā)射機(jī)一致。如果發(fā)射機(jī)寫的是tdma_frame_format接收機(jī)里忘記關(guān)聯(lián)結(jié)果是所有包在物理層就被當(dāng)成噪聲丟掉。接收靈敏度Receiver Sensitivity與發(fā)射功率Transmit Power一對(duì)參數(shù)。發(fā)射功率按毫瓦配置接收靈敏度范圍一般在-95 dBm到-70 dBm之間。距離越遠(yuǎn)、路徑損耗越大接收端信噪比越低低于靈敏度包直接丟失。中心頻率和帶寬同一仿真場(chǎng)景中不同網(wǎng)絡(luò)如果頻率不同彼此不構(gòu)成干擾。如果所有節(jié)點(diǎn)共用一個(gè)信道那么頻率必須完全一致。包格式的設(shè)計(jì)按實(shí)際協(xié)議內(nèi)容來。我的TDMA幀里通常包含這幾個(gè)字段源節(jié)點(diǎn)ID、目的節(jié)點(diǎn)ID支持廣播、時(shí)隙編號(hào)、幀序號(hào)、載荷長(zhǎng)度、擴(kuò)展位。在OPNET的包格式編輯器里按比特/字節(jié)定義好生產(chǎn)包時(shí)用op_pk_create_fmt()創(chuàng)建用op_pk_nfd_set()填充字段接收側(cè)用op_pk_nfd_get()取出字段即可。這一套流程做過一次后面任何協(xié)議改造都輕車熟路。3. 關(guān)鍵參數(shù)推導(dǎo)實(shí)戰(zhàn)幀長(zhǎng)、時(shí)隙數(shù)與保護(hù)時(shí)隙是怎么算出來的3.1 業(yè)務(wù)負(fù)載決定幀長(zhǎng)下界的推導(dǎo)TDMA的幀長(zhǎng)設(shè)計(jì)不是拍腦袋定的它和業(yè)務(wù)量直接掛鉤。整個(gè)推導(dǎo)邏輯是先確定每個(gè)節(jié)點(diǎn)每個(gè)幀周期里要發(fā)多少數(shù)據(jù)再算需要多少時(shí)隙最后把時(shí)隙匯聚成幀。假設(shè)一個(gè)簡(jiǎn)單的無線數(shù)據(jù)采集場(chǎng)景網(wǎng)絡(luò)里有8個(gè)節(jié)點(diǎn)每個(gè)節(jié)點(diǎn)每秒鐘產(chǎn)生4包數(shù)據(jù)每包長(zhǎng)度是128字節(jié)。發(fā)送速率設(shè)定為250 kbps。那么每個(gè)包的傳輸時(shí)間為128字節(jié) 1024 bit 1024 / 250000 ≈ 4.096 ms每個(gè)節(jié)點(diǎn)每秒4包也就是說每秒至少要提供4個(gè)包的發(fā)包機(jī)會(huì)。如果幀長(zhǎng)為T秒T秒內(nèi)需要提供4T個(gè)時(shí)隙。每個(gè)時(shí)隙如果要容納1個(gè)包那么時(shí)隙時(shí)長(zhǎng)至少是4.096 ms。為了保證發(fā)送完還有一點(diǎn)余量假設(shè)時(shí)隙時(shí)長(zhǎng)為6 ms留出約1.9 ms的凈空。8個(gè)節(jié)點(diǎn)就需要8個(gè)業(yè)務(wù)時(shí)隙加上1個(gè)控制時(shí)隙用于廣播同步信息幀長(zhǎng)為幀長(zhǎng) 9 × 6 ms 54 ms每秒可以提供的發(fā)包機(jī)會(huì)數(shù)量是1 / 0.054 ≈ 18.5遠(yuǎn)大于每秒4包的需求看起來余量充足。但這個(gè)余量不是浪費(fèi)它留給了突發(fā)流量、重傳機(jī)制和以后擴(kuò)展節(jié)點(diǎn)的空間。反過來說如果業(yè)務(wù)量更大比如每秒20包那幀長(zhǎng)就要縮短或者單個(gè)時(shí)隙里塞多個(gè)包。把時(shí)隙時(shí)長(zhǎng)擴(kuò)大到10 ms、每時(shí)隙發(fā)2包也是一種方案。權(quán)衡點(diǎn)是時(shí)延——幀長(zhǎng)越大節(jié)點(diǎn)平均等待時(shí)間越長(zhǎng)端到端時(shí)延越高。這就是TDMA的經(jīng)典矛盾效率與時(shí)延的取舍。3.2 傳播時(shí)延與保護(hù)時(shí)隙的工程估算保護(hù)時(shí)隙是我在初期仿真中完全沒重視、后來被現(xiàn)實(shí)狠狠教育了一下的參數(shù)。它的作用是防止不同節(jié)點(diǎn)的時(shí)隙在時(shí)間上互相“越界”。原因有兩類一個(gè)是節(jié)點(diǎn)間距離不同信號(hào)傳播時(shí)延不同另一個(gè)是節(jié)點(diǎn)時(shí)鐘存在漂移雖然仿真里的時(shí)鐘是理想時(shí)鐘但真實(shí)系統(tǒng)不是。保護(hù)時(shí)隙的計(jì)算公式很簡(jiǎn)單保護(hù)時(shí)隙時(shí)長(zhǎng) 最大傳播時(shí)延 收發(fā)轉(zhuǎn)換時(shí)間 時(shí)鐘漂移裕量 處理余量其中最大傳播時(shí)延取決于節(jié)點(diǎn)間最大距離。如果最大距離是3公里電磁波傳播速度按光速算傳播時(shí)延 3000m / 3×10?m/s 10 μs收發(fā)轉(zhuǎn)換時(shí)間一般是20 μs左右模擬射頻開關(guān)的切換。時(shí)鐘漂移量需要知道晶振精度。按10 ppm百萬分之十的晶振一個(gè)100 ms的幀周期產(chǎn)生的漂移是1 μs??紤]到兩端節(jié)點(diǎn)都要算再留出幾倍的余量。綜合下來保護(hù)時(shí)隙取80到100 μs是比較穩(wěn)的選擇。在8節(jié)點(diǎn)、9時(shí)隙、每時(shí)隙6 ms的例子中100 μs的保護(hù)時(shí)隙占總時(shí)隙比例只有0.1ms / 6ms ≈ 1.7%影響不大。但如果幀長(zhǎng)很短、時(shí)隙又小保護(hù)時(shí)隙占比會(huì)迅速上升這時(shí)候就得考慮是否縮短幀長(zhǎng)或增大時(shí)隙時(shí)長(zhǎng)。OPNET仿真里雖然時(shí)鐘是理想的發(fā)射瞬間也是嚴(yán)格的仿真時(shí)間點(diǎn)但我還是建議把保護(hù)時(shí)隙留在協(xié)議設(shè)計(jì)里。原因很簡(jiǎn)單仿真模型要映射真實(shí)系統(tǒng)如果模型里沒有這一筆賬那后續(xù)用這些仿真結(jié)果去指導(dǎo)真實(shí)實(shí)現(xiàn)時(shí)會(huì)出現(xiàn)系統(tǒng)性偏差。3.3 把推導(dǎo)結(jié)果落進(jìn)OPNET仿真配置推導(dǎo)完成后這些參數(shù)值就直接作為節(jié)點(diǎn)屬性寫進(jìn)模型里。我的做法是在節(jié)點(diǎn)模型里定義用戶屬性比如TDMA Node ID、Frame Duration、Slot Duration、Number of Slots、Start Time Offset進(jìn)程模型通過op_ima_obj_attr_get()讀取。這樣同一個(gè)節(jié)點(diǎn)模型能復(fù)用在不同的仿真場(chǎng)景中改參數(shù)時(shí)不用重新編譯模型。起始時(shí)間偏移量是我常用的一個(gè)附加參數(shù)不同節(jié)點(diǎn)的幀起點(diǎn)不完全對(duì)齊用于模擬無線網(wǎng)絡(luò)中的入網(wǎng)同步偏差。真實(shí)網(wǎng)絡(luò)中節(jié)點(diǎn)入網(wǎng)時(shí)間有先有后OPNET仿真里這個(gè)偏移量可以控制在0到1個(gè)時(shí)隙范圍內(nèi)。幀結(jié)構(gòu)里的控制時(shí)隙可以這樣分配固定節(jié)點(diǎn)0作為網(wǎng)絡(luò)控制節(jié)點(diǎn)在每個(gè)幀周期的第0個(gè)時(shí)隙發(fā)送同步信號(hào)包含當(dāng)前幀號(hào)、時(shí)隙分配表、同步時(shí)間戳。其他節(jié)點(diǎn)收到控制包后更新本地幀計(jì)時(shí)。這種設(shè)計(jì)以后擴(kuò)展動(dòng)態(tài)TDMA、節(jié)點(diǎn)加入退出機(jī)制時(shí)底子就現(xiàn)成。落進(jìn)OPNET仿真場(chǎng)景時(shí)節(jié)點(diǎn)擺放距離也要留意。雖然仿真模型按傳播模型計(jì)算真實(shí)距離損耗但節(jié)點(diǎn)之間的距離直接決定了接收信號(hào)強(qiáng)度。我的測(cè)試場(chǎng)景里把節(jié)點(diǎn)隨機(jī)分布在半徑2公里的圓形區(qū)域內(nèi)這樣既能檢驗(yàn)保護(hù)時(shí)隙的傳播時(shí)延裕量是否足夠也能讓接收功率有起伏、避免所有節(jié)點(diǎn)都盲目樂觀地“收到”。4. 仿真跑通了但數(shù)據(jù)不對(duì)幾類典型問題的排查思路4.1 統(tǒng)計(jì)量全為0、延遲異常的排查鏈路最氣人的情況是仿真自動(dòng)跑了一天打開結(jié)果一看——吞吐量曲線是平的端到端延遲統(tǒng)計(jì)完全沒有值。我第一次遇到這個(gè)情況的時(shí)候第一反應(yīng)是代碼寫錯(cuò)了花了兩個(gè)多小時(shí)把狀態(tài)機(jī)從頭到尾看了一遍代碼邏輯沒問題最后才發(fā)現(xiàn)是統(tǒng)計(jì)句柄沒注冊(cè)成功。排查順序很重要我現(xiàn)在的習(xí)慣是先確認(rèn)數(shù)據(jù)是否真的生成了再看數(shù)據(jù)是否被收到最后才看統(tǒng)計(jì)寫入是否正常。第一步在發(fā)送節(jié)點(diǎn)進(jìn)程的發(fā)送分支里加一個(gè)printf打印當(dāng)前仿真時(shí)間和發(fā)送的包序號(hào)。如果終端滾動(dòng)輸出正常說明包確實(shí)在生成。第二步在接收節(jié)點(diǎn)的收包分支里打印仿真時(shí)間和源節(jié)點(diǎn)ID。如果收不到打印問題出在物理層或中間鏈路。這時(shí)去查發(fā)射機(jī)參數(shù)和接收機(jī)參數(shù)是否匹配、包格式有沒有寫對(duì)、距離是否超過通信范圍。第三步如果收發(fā)都有打印但統(tǒng)計(jì)量為0基本可以斷定統(tǒng)計(jì)函數(shù)寫錯(cuò)了。op_stat_reg()返回的句柄必須保存到進(jìn)程的state variable里每次op_stat_write()用的是同一個(gè)句柄并且要在INIT狀態(tài)完成注冊(cè)。很多人在頭文件和源文件之間傳句柄傳丟了導(dǎo)致后面的寫入悄悄失敗。這個(gè)排查鏈路非常機(jī)械但有效幾乎能解決80%的統(tǒng)計(jì)問題。4.2 半雙工與自干擾一個(gè)隱蔽的設(shè)計(jì)錯(cuò)誤TDMA本身是單信道時(shí)分復(fù)用節(jié)點(diǎn)不能同時(shí)收發(fā)。我在仿真里加了一個(gè)接收確認(rèn)機(jī)制接收節(jié)點(diǎn)收到數(shù)據(jù)包后在自己的發(fā)射時(shí)隙回一個(gè)ACK。表面看起來邏輯沒什么問題仿真跑起來卻發(fā)現(xiàn)總吞吐量比預(yù)期低不少。檢查后發(fā)現(xiàn)問題出在接收節(jié)點(diǎn)的狀態(tài)機(jī)設(shè)置上它自己的發(fā)送時(shí)隙和鄰居的發(fā)送時(shí)隙在時(shí)間上重疊了——我在計(jì)算節(jié)點(diǎn)間幀起點(diǎn)偏移時(shí)沒考慮半雙工約束導(dǎo)致接收節(jié)點(diǎn)一邊收包一邊發(fā)包。OPNET的無線模型在物理層會(huì)自動(dòng)計(jì)算同一信道上多路信號(hào)的干擾疊加自干擾信號(hào)能量高直接把合法信號(hào)壓掉了。解決方法是嚴(yán)格檢查每個(gè)節(jié)點(diǎn)的收發(fā)時(shí)隙關(guān)系。半雙工約束意味著節(jié)點(diǎn)在本身時(shí)隙內(nèi)不能同時(shí)接收其他信號(hào)。在狀態(tài)機(jī)里要加一個(gè)互斥判斷當(dāng)自我在發(fā)射時(shí)隙時(shí)即使接收中斷到來也要做丟棄處理并在物理層之上實(shí)現(xiàn)一個(gè)簡(jiǎn)單的收發(fā)互鎖。這個(gè)互斥邏輯在實(shí)際無線芯片中是由射頻開關(guān)實(shí)現(xiàn)的仿真里必須自己在協(xié)議層模擬一遍。4.3 時(shí)鐘同步在仿真里怎么表達(dá)一個(gè)容易偷懶但必須處理的點(diǎn)很多初學(xué)者覺得OPNET的仿真時(shí)鐘是全局統(tǒng)一的所以節(jié)點(diǎn)之間天然同步不需要處理鎖相環(huán)或者時(shí)間同步協(xié)議。這句話對(duì)也不對(duì)。OPNET的全局時(shí)鐘確實(shí)是同一個(gè)但TDMA協(xié)議的正確性依賴的是“所有節(jié)點(diǎn)對(duì)幀邊界的認(rèn)知一致”而幀邊界的建立需要節(jié)點(diǎn)收到同步源發(fā)來的時(shí)刻信息。如果你把每個(gè)節(jié)點(diǎn)的幀起點(diǎn)設(shè)成完全一樣那等于默認(rèn)所有節(jié)點(diǎn)開機(jī)即同步——這在單節(jié)點(diǎn)網(wǎng)絡(luò)里沒問題但在多跳場(chǎng)景中距離較遠(yuǎn)的節(jié)點(diǎn)根本收不到控制節(jié)點(diǎn)的同步包它們的幀起點(diǎn)一旦偏移整個(gè)時(shí)隙規(guī)劃就崩塌了。我的做法是把同步過程顯式建模出來控制節(jié)點(diǎn)在每個(gè)幀起點(diǎn)的控制時(shí)隙發(fā)同步包其他節(jié)點(diǎn)收到同步包后按包內(nèi)的時(shí)間戳校準(zhǔn)自己的幀起點(diǎn)。在仿真開始后的前幾個(gè)幀周期內(nèi)不同節(jié)點(diǎn)的幀起點(diǎn)可以有偏差它們的發(fā)射時(shí)隙也因此錯(cuò)開。通過設(shè)置不同節(jié)點(diǎn)的Start Time Offset屬性可以模擬節(jié)點(diǎn)在不同時(shí)刻完成入網(wǎng)同步的效果。這樣做還有一個(gè)額外好處可以直接觀測(cè)同步精度對(duì)網(wǎng)絡(luò)性能的影響。把同步包間隔加大或者把同步包里的時(shí)間戳精度降低你會(huì)看到時(shí)隙重疊導(dǎo)致的丟包率上升這就是一個(gè)非常直觀的、關(guān)于時(shí)間同步重要性的仿真實(shí)驗(yàn)。5. 從基礎(chǔ)TDMA到改進(jìn)方向仿真結(jié)果怎么指導(dǎo)協(xié)議迭代5.1 拿到吞吐量和時(shí)延曲線后先看什么等仿真跑完打開Output Results面對(duì)一堆曲線第一眼應(yīng)該看什么我的習(xí)慣是先看丟包率如果有統(tǒng)計(jì)再看端到端延遲的均值和最大值最后看吞吐量。這個(gè)順序的理由是如果丟包率不為0后面所有指標(biāo)都沒有意義說明協(xié)議存在邏輯錯(cuò)誤或參數(shù)配置不對(duì)。端到端延遲要重點(diǎn)看它的分布形態(tài)。TDMA的延遲由幾部分組成業(yè)務(wù)包在發(fā)送隊(duì)列里的排隊(duì)延遲、等待自己時(shí)隙到來的幀對(duì)齊延遲、包的實(shí)際傳輸時(shí)間、傳播延遲。其中幀對(duì)齊延遲占大頭且呈鋸齒狀分布——包在上一個(gè)時(shí)隙剛結(jié)束就到達(dá)那要等整整一個(gè)幀周期如果剛好趕在時(shí)隙開始前到達(dá)延遲就很小。這就是為什么TDMA時(shí)延曲線在均值附近上下波動(dòng)非常明顯最大值接近一個(gè)幀長(zhǎng)。如果看到延遲曲線有規(guī)律地周期性尖峰比如每54 ms出現(xiàn)一次尖峰那多半是業(yè)務(wù)生成速率和時(shí)隙到達(dá)相位之間有周期性重疊不是協(xié)議故障而是業(yè)務(wù)模型與幀結(jié)構(gòu)共振了。解決思路是讓業(yè)務(wù)包的生成時(shí)間在幀周期內(nèi)隨機(jī)分布或者把業(yè)務(wù)模型改成泊松到達(dá)。這個(gè)調(diào)整看似微小但直接影響延遲指標(biāo)的參考價(jià)值。5.2 空時(shí)隙浪費(fèi)與動(dòng)態(tài)調(diào)度的啟發(fā)把固定TDMA的仿真結(jié)果和理想情況對(duì)比后你會(huì)發(fā)現(xiàn)一個(gè)殘酷的現(xiàn)實(shí)輕負(fù)載下信道利用率極低。8個(gè)節(jié)點(diǎn)每個(gè)幀周期只有平均2個(gè)節(jié)點(diǎn)有數(shù)據(jù)要發(fā)剩下6個(gè)時(shí)隙全部空轉(zhuǎn)信道利用率才25%。這在固定分配時(shí)隙協(xié)議里幾乎無解?,F(xiàn)在通信圈里比較火的smart tdma mesh概念本質(zhì)上就是想解決這個(gè)問題。它保留了TDMA的避碰、確定性、幀結(jié)構(gòu)這些優(yōu)勢(shì)同時(shí)在非忙碌節(jié)點(diǎn)時(shí)隙上做文章讓時(shí)隙在空閑時(shí)可以被其他節(jié)點(diǎn)按需借用通過網(wǎng)狀拓?fù)渲械目刂葡⒔粨Q把時(shí)隙分配表動(dòng)態(tài)地同步到全網(wǎng)。仿真層面要驗(yàn)證動(dòng)態(tài)TDMA的改進(jìn)可以這樣改模型每個(gè)節(jié)點(diǎn)維護(hù)一個(gè)本地時(shí)隙占用位圖控制時(shí)隙中廣播各自位圖節(jié)點(diǎn)間互相學(xué)習(xí)。如果發(fā)現(xiàn)自己分配的空閑時(shí)隙被別人使用就在下個(gè)幀周期主動(dòng)讓出。這種改進(jìn)的建模成本不高在現(xiàn)有狀態(tài)機(jī)上增加一個(gè)位圖信息字段、一個(gè)處理位圖更新的分支就行但能直觀地對(duì)比靜態(tài)與動(dòng)態(tài)調(diào)度在吞吐量和時(shí)延上的差異是很典型的一套“仿真驗(yàn)證協(xié)議改進(jìn)”的閉環(huán)做法。5.3 把動(dòng)態(tài)時(shí)隙分配加進(jìn)現(xiàn)有模型的改造建議真要做動(dòng)態(tài)TDMA我建議分三步走每一步都先跑仿真驗(yàn)證再進(jìn)入下一步。第一步實(shí)現(xiàn)時(shí)隙占用廣播機(jī)制。在控制時(shí)隙的同步包中加入位圖字段。這個(gè)改動(dòng)量很小但能讓所有節(jié)點(diǎn)看到全網(wǎng)時(shí)隙占用情況。第二步實(shí)現(xiàn)空閑時(shí)隙借用邏輯。當(dāng)節(jié)點(diǎn)隊(duì)列中有積壓包時(shí)它不僅在自身時(shí)隙發(fā)送還可以在標(biāo)記為空閑的時(shí)隙里發(fā)送。接收端的處理需要擴(kuò)展——目標(biāo)節(jié)點(diǎn)要能識(shí)別這些額外時(shí)隙中的包并在應(yīng)答中區(qū)分原始時(shí)隙包和借用時(shí)隙包。第三步處理多節(jié)點(diǎn)同時(shí)借用同一空閑時(shí)隙的競(jìng)爭(zhēng)問題。這就需要在借用前做隨機(jī)退避或者通過集中式調(diào)度器統(tǒng)一裁決。每一步改完之后都要重新跑仿真對(duì)比之前靜態(tài)TDMA的結(jié)果。改進(jìn)協(xié)議并不總是一帆風(fēng)順——我當(dāng)時(shí)在第二步就遇到了明顯問題借用導(dǎo)致局部節(jié)點(diǎn)沖突增加丟包率反彈到了比靜態(tài)TDMA還高的水平。這個(gè)結(jié)果雖然不好看但恰恰是仿真的價(jià)值所在它讓你在寫真實(shí)協(xié)議之前就暴露了設(shè)計(jì)缺陷避免帶著錯(cuò)誤方案走進(jìn)硬件實(shí)現(xiàn)階段。做完整套仿真和迭代之后我最大的體會(huì)是OPNET雖然老了但它的分層模型設(shè)計(jì)在協(xié)議改造場(chǎng)景中的表達(dá)能力依然很強(qiáng)尤其是TDMA這種強(qiáng)狀態(tài)機(jī)、強(qiáng)時(shí)序的MAC協(xié)議用有限狀態(tài)機(jī)來建模天然就是合適的。關(guān)鍵是別把時(shí)間和精力浪費(fèi)在上手階段直接把節(jié)點(diǎn)模型和進(jìn)程模型的核心邏輯理順再去折騰參數(shù)和統(tǒng)計(jì)后面就是驗(yàn)證、發(fā)現(xiàn)問題、改設(shè)計(jì)、再驗(yàn)證的循環(huán)。每一步都留下仿真日志和參數(shù)記錄這份積累以后比仿真本身還有價(jià)值。本文還有配套的精品資源點(diǎn)擊獲取