General Tutorial 中OPNET信道模型的中文翻译
原文链接:http://cug19204104.blog.163.com/blog/static/8826612820104147116107/
1. 概述:
在OPNET模型中,当包被传送到发送器请求发送后,实际中的情况是 包将立即被发送到通信信道上进行传输,因此OPNET必须对通信信道进行建模,也就是在模型中要实现物理层的特征,以便将信道对包产生的传输效果考虑进整个网络模型。OPNET将信道对包产生的传输效果建模为若干个计算阶段(称为pipeline stage),最终来判断该包能否被接收到。
Pipeline的典型参数是一个packet指针,也就是说,pipeline是针对每个包来计算它在物理信道上的传输效果的。为了承载pipiline所需或计算的信道参数,每个包都包含着由transmission data attribute(TDA)的一组值构成的存储区,当包的传输效果计算进入某一pipeline stage时,系统内核为TDA分配初始值或者根据计算结果来设置TDA值。这一组TDA值可以为后续的pipeline stage提供计算的依据。
OPNET将传输信道划分为三种:点对点链路(point to point Link),总线式链路(bus Link)和无线链路(radio Link)。每一种链路由若干个标准的,缺省的pipeline stage组成。用户可以对缺省的pipeline stage 进行修改以适应用户所需的信道类型:用户可以在pipeline里定义自己的TDA,还可以调用系统内核里的支持对TDA进行操作的内核过程(KP)来编程实现自己的信道模型。
OPNET中缺省的pipeline stage模型文件后缀名为.ps.c,经编译后形成的目标文件后缀名为.ps.o。所有的三种信道的缺省pipeline stage 文件都存储在<opnet目录>/<版本目录>/models/std/links/文件夹下面。用户若要自己编写pipeline stage来代替缺省模型,则需先编写.ps.c后缀的c或c++文件,然后编译形成.ps.o目标文件。
2. 点对点链路的pipeline模型:
由四个缺省的pipeline stage组成,具体描述如下:
2.1 传输时延阶段:模型文件dpt_txdel.ps.c。
传输时延描述的是第一个比特发送时间到最后一个比特发送时间之间的时间间隔。
计算方法:
从包里读取传输该包的信道的标志号(ID);
tx_ch_obid = op_td_get_int (pkptr, OPC_TDA_PT_TX_CH_OBJID);
有了信道ID后,即可读取信道的数据速率;
op_ima_obj_attr_get (tx_ch_obid, "data rate", &tx_drate);
读取包的长度;
pklen = op_pk_total_size_get (pkptr);
传输时延=包长/数据速率;
tx_delay = pklen / tx_drate;
把计算而得的传输时延值写到包的TDA里。
op_td_set_dbl (pkptr, OPC_TDA_PT_TX_DELAY, tx_delay);
2.2 传播时延阶段:模型文件dpt_propdel.ps.c。
传播时延描述的是第一个比特开始发送时间到第一个比特到达时间之间的时间间隔。
计算方法:
从包里读取传输该包的链路标志号(ID);
link_objid = op_td_get_int (pkptr, OPC_TDA_PT_LINK_OBJID);
有了链路ID,即可读取链路的"delay"属性值;
op_ima_obj_attr_get (link_objid, "delay", &prop_delay);
把该传播时延值写进包的TDA中;
op_td_set_dbl (pkptr, OPC_TDA_PT_PROP_DELAY, prop_delay);
2.3 误码数目分配阶段:模型文件dpt_error.ps.c。
计算方法:
读取链路的标志号(ID);
link_objid = op_td_get_int (pkptr, OPC_TDA_PT_LINK_OBJID);
读取链路的误码率"ber"属性值,即单个比特可能误码的概率;
op_ima_obj_attr_get (link_objid, "ber", &pe)
读取包长;
seg_size = op_pk_total_size_get (pkptr);
计算"正好发生k个比特误码"的概率P(k),那么可以得到"至多发生k个比特误码"的概率P=P(0)+P(1)+……+P(k);
产生一个在{0,1}内平均分布的随机数r;
r = op_dist_uniform (1.0);
如果随机数r小于等于"至多发生k个比特误码"的概率P,那么就"认定"k就是这个包在信道上传输的误码数目;
如果r大于P,那么就将k的值加1,反复计算以得到算法能够接受的误码数目;
将误码数目写进包的TDA里。
op_td_set_int (pkptr, OPC_TDA_PT_NUM_ERRORS, ((int)num_errs))
2.4 纠错阶段:模型文件dpt_ecc.ps.c。
计算方法:
读取接收器的标志号(ID);
rx_obid = op_td_get_int (pkptr, OPC_TDA_PT_RX_OBJID);
读取接收器能纠正的误码数目门限值"ecc threshold"属性值;
op_ima_obj_attr_get (rx_obid, "ecc threshold", &ecc_thresh)
读取包的长度;
pklen = op_pk_total_size_get (pkptr);
读取前面计算的错误数目;
num_errs = op_td_get_int (pkptr, OPC_TDA_PT_NUM_ERRORS);
将错误数目与纠错门限"ecc threshold"比较,判决该包是否能被正确接收;
accept = ((((double) num_errs) / pklen) <= ecc_thresh) ? OPC_TRUE : OPC_FALSE;
将判断结果写进包的TDA里。
op_td_set_int (pkptr, OPC_TDA_PT_PK_ACCEPT, accept);
3. 总线链路的pipeline模型:
由六个缺省的pipeline stage组成,其中第一个阶段针对每个传输只计算一次,而后面的五个阶段针对各个可能接收到这次传输的接收器分别计算一次。具体描述如下:
3.1 封闭性计算阶段:模型文件dbu_closure.ps.c。
这个阶段的意义在于判断各个接收器节点是否能够接收到这次传输,即链路的封闭性。针对每个接收器都有一个判断结果。有了这个结果以后系统内核就可以决定是否再为该接收器执行后面的计算进程。这个判断的好处是提高了仿真效率,因为若已知某接收器不能接收到这次传输,就不必为其计算传输时延,冲突等值,避免了进行不必要的计算。
计算方法:
缺省认为所有bus上的站点都能接收到这次传输,因此直接把判断值写进包的TDA里。
op_td_set_int (pkptr, OPC_TDA_BU_CLOSURE, OPC_TRUE);
3.2 传输时延阶段:模型文件dbu_txdel.ps.c。
计算方法:与点对点链路情况一致。
3.3 传播时延阶段:模型文件dbu_propdel.ps.c。
计算方法:
读取链路的标志号(ID);
bus_obid = op_td_get_int (pkptr, OPC_TDA_BU_LINK_OBJID);
读取链路的单位距离的传播时延"delay"属性值。注意在这里的delay属性与点对点链路的delay属性意义不一样。这里指的是单位距离的传播时延,而点对点链路中的delay直接指的是总传播时延。因为点对点只涉及到单条链路的传播时延,而总线链路要针对不同接收器即不同的传播距离计算出多个传播时延;
op_ima_obj_attr_get (bus_obid, "delay", &unit_delay)
读取收发器之间的距离间隔;
prop_distance = op_td_get_dbl (pkptr, OPC_TDA_BU_DISTANCE);
二者乘积值即为传播时延,将其写进包的TDA里。
prop_delay = unit_delay * prop_distance;
op_td_set_dbl (pkptr, OPC_TDA_BU_PROP_DELAY, prop_delay);
3.4 冲突检测阶段:模型文件dbu_coll.ps.c。
在某个包的整个接收时间内(第一个比特到达时间到最后一个比特到达时间之间的时间间隔),可能会发生多次传输事件,于是对于该包来说,可能要遭遇多次冲突事件。在OPNET中,每当发生一次冲突事件,就调用本pipeline stage 一次,以记录这次冲突事件。这个pipeline stage对每个包传输不是总要调用,它只是在发生冲突时调用,而是否发生冲突是由系统内核来判别的。这个计算进程区别于其他的pipeline stage,有两个包指针参数:第一个是先到的分组,第二个是后到的分组(就是触发冲突事件的那一个)。
计算方法:
如果前一个包刚好在后一个包开始传输时结束了接收,则不考虑为一次冲突。因此读取前一个包的结束时间,将其与当前仿真时间进行比较。
如果相等则不认为冲突。
op_td_get_dbl (pkptr_prev, OPC_TDA_BU_END_RX) != op_sim_time ()
如果不等,则将前后两个包的记录冲突次数TDA都加一。
op_td_set_int (pkptr_prev, OPC_TDA_BU_NUM_COLLS,
op_td_get_int (pkptr_prev, OPC_TDA_BU_NUM_COLLS) + 1);
op_td_set_int (pkptr_arriv, OPC_TDA_BU_NUM_COLLS,
op_td_get_int (pkptr_arriv, OPC_TDA_BU_NUM_COLLS) + 1);
3.5 误码数目分配阶段:模型文件dbu_error.ps.c。
计算方法:与点对点链路的计算方法一致,根据误码率计算误码数目。
3.6 纠错阶段:模型文件dbu_ecc.ps.c。
包能被正确接收的判断标准与点对点链路稍有不同。首先是要求包未经冲突,然后将误码数目与纠错门限比较判断可正确接收与否。
计算方法:
读取包的冲突数目;
op_td_get_int (pkptr, OPC_TDA_BU_NUM_COLLS)
如果冲突数目不为0或节点被disabled,则直接判断为不能正确接收;
(op_td_get_int (pkptr, OPC_TDA_BU_NUM_COLLS) != 0) ||
(op_td_is_set (pkptr, OPC_TDA_BU_ND_FAIL)))
将误码数目与纠错门限比较以决定能否正确接收,将判断结果写进包的TDA里。具体步骤与点对点链路一致。
4. 无线链路的pipeline模型:
OPNET支持在通信节点间的无线链路的动态建模。无线链路的特征是其可通性决定于时间变化的因素,比如通信节点的移动,收发器属性的改变,以及并行传输互相作用的干扰等。缺省的无线链路由14个pipeline stage组成。具体描述如下:
4.1 接收器组计算阶段:模型文件dra_rxgroup.ps.c。
这个阶段只在仿真一开始时调用一次,以评估每一对收发器信道之间的连通性。 不同于其他pipeline stage的是,这个阶段不是针对包进行操作的。它是针对每对收发器信道进行判断连通性的。
判断方法:缺省认为所有的接收器信道都是任一发送器潜在的目的站,即任何一对收发器信道间都默认为是连通的。
4.2 传输时延阶段: 模型文件dra_txdel.ps.c。
计算方法:
读取信道的传输速率;(这里与点对点和总线不一样,只要直接从包里的TDA读取就可以了,无须在程序里取得链路的标志号ID,再读链路属性值。因为无线链路不存在独立的链路实体,因此传输速率不可能设在链路属性里,而是设在无线发送器的信道属性里,包括频率,带宽,数据速率等。系统内核已经将这些参数写进包里。);
tx_drate = op_td_get_dbl (pkptr, OPC_TDA_RA_TX_DRATE);
读取包长;
pklen = op_pk_total_size_get (pkptr);
传输时延=包长/传输速率,并写进包的TDA里。
tx_delay = pklen / tx_drate;
op_td_set_dbl (pkptr, OPC_TDA_RA_TX_DELAY, tx_delay);
4.3 链路封闭性计算阶段:模型文件dra_closure.ps.c。
无线链路的封闭性计算是依据通视性来决定的。算法测试连接发送器和接收器之间的线段是否和地球表面相交。若存在交点,那么认为接收器不可达,即其不可能接收到这次传输。因此导致与该包相关的剩下的所有pipeline stage不再执行。判断结果将写进包的相应TDA里。
计算方法:
收发器在地心坐标系统上的坐标由用户在收发器属性里预先设定。系统内核已自动将其写进包里。
读取包里已有的收发器坐标,由一定算法计算是否与地球表面相交。
将链路可达性判断结果写进包的TDA里。
4.4 链路匹配阶段:模型文件dra_chanmatch.ps.c。
这个计算阶段针对每条可能存在的链路(不可达的链路已在前面的计算阶段里打上标记,因此已被排除在外)来执行。根据发送器和接收器的频率,带宽,数据速率,传输编码,和调制方式等五个属性来判断传输结果。根据判断结果将包标上三种标记中间的某一个:
valid:接收器和发送器属性完全匹配,接收器能正确接收解码这个传输包;
interfence:带内干扰。接收器和发送器频率,带宽等属性有重叠的部分,因此包虽然不能被解码或利用,但是这个包影响接收器接收其他的包。
ignored:带外。也即接收器的频率等属性与发送器属性完全不一致,这个包既不能被接收器接收,也不会对接收器接收其他包产生干扰。
计算方法:
读取收发器的各五个属性;
tx_freq = op_td_get_dbl (pkptr, OPC_TDA_RA_TX_FREQ);
tx_bw = op_td_get_dbl (pkptr, OPC_TDA_RA_TX_BW);
tx_drate = op_td_get_dbl (pkptr, OPC_TDA_RA_TX_DRATE);
tx_code = op_td_get_dbl (pkptr, OPC_TDA_RA_TX_CODE);
tx_mod = op_td_get_ptr (pkptr, OPC_TDA_RA_TX_MOD);
rx_freq = op_td_get_dbl (pkptr, OPC_TDA_RA_RX_FREQ);
rx_bw = op_td_get_dbl (pkptr, OPC_TDA_RA_RX_BW);
rx_drate = op_td_get_dbl (pkptr, OPC_TDA_RA_RX_DRATE);
rx_code = op_td_get_dbl (pkptr, OPC_TDA_RA_RX_CODE);
rx_mod = op_td_get_ptr (pkptr, OPC_TDA_RA_RX_MOD);
如果频带不交叉,则将包置为ignore;
(tx_freq > rx_freq + rx_bw) || (tx_freq + tx_bw < rx_freq));
op_td_set_int (pkptr, OPC_TDA_RA_MATCH_STATUS, OPC_TDA_RA_MATCH_IGNORE);
如果频带交叉,但其他属性存在不匹配情况,则将包置为noise(interference);
(tx_freq != rx_freq) || (tx_bw != rx_bw) ||
(tx_drate != rx_drate) || (tx_code != rx_code) || (tx_mod != rx_mod));
op_td_set_int (pkptr, OPC_TDA_RA_MATCH_STATUS, OPC_TDA_RA_MATCH_NOISE);
完全匹配则置为valid。
op_td_set_int (pkptr, OPC_TDA_RA_MATCH_STATUS, OPC_TDA_RA_MATCH_VALID);
4.5 发送天线增益阶段:模型文件dra_tagain.ps.c。
天线模型问题提出:在信道pipeline里之所以要考虑天线的模型, 是因为天线在各个方向上对进行传输的包功率的衰减程度不一样,因此直接影响了包的接收功率,进而影响信噪比和误码数目。举例来说,对于一个有主瓣旁瓣的天线模型,在主瓣方向潜在链路上传输的包功率,比旁瓣方向潜在链路上传输的包功率要来得大。所谓的天线模型,它描述了不同方向上的天线增益值。天线模型函数基于的坐标系统是地心坐标系统,用两个角度来表示在地心三维坐标系上的一个方向向量(x,y平面角称为theta,x,z平面角称为phi),而对应与这个向量,由用户指定唯一的信号衰减db值与之相对应。这个函数(也即天线的数学模型)可以由用户在天线编辑器里来描绘。若天线模型为球型,则认为天线是各向同性的,也就是说,各个方向上传输的包里的记录天线增益的的TDA都将被赋值0 db。
天线模型的属性:
pattern属性:即用户指定的天线模型;
target目标特征:天线指向目标的经纬度和海拔(target latitude, longitude, altitude);
pointing ref.phi和pointing ref.theta :参考的theta和phi角的值。一般情况下,这两个角的意义是天线最大增益的方向,即主瓣方向。
计算方法:
从包里读取发送天线采用的天线模型表的存储位置指针,判断如果是空表,那么表示是各向同性,于是不进行任何计算,直接在包的TDA里设置发送天线增益是0 db。如果不是空表则进行下列步骤。
读取收发器位置的六个坐标值。计算这条链路的方向向量;
读取天线实际指向向量:phi和theta值(已经由系统内核基于天线的目标经纬度,海拔属性和发送器的位置属性计算出,并写入包里);
读取天线的最大增益方向向量:phi 2和theta2值(已经由系统内核基于天线的pointing ref.phi和pointing ref.theta属性得到,并写入包里);
我们要计算的是天线模型在目前链路方向向量上的增益是多少。天线模型的坐标系已经旋转到使得天线的最大增益方向对准target方向,因此应该将链路向量投影到旋转以后的坐标系上,才能查表获得链路方向上的衰减值。
可以知道,坐标系旋转方式是x,z平面旋转phi2 - phi角度,x,y平面旋转theta 2 - theta角度。因此链路向量投影到旋转后坐标系上的新的phi和新的theta角度可以计算出来,从而调用内核过程执行查表操作得到衰减值。
将衰减值写进packet的TDA里。
4.6 传播时延阶段:模型文件dra_propdel.ps.c
在无线链路里,由于节点可能发生移动,在包传输过程中,传输距离可能发生变化。因此,在这个阶段里,计算两个时延结果:传输开始时的传播时延和传输结束时的传播时延。计算基于收发器之间的距离和常量电磁波传播速率来进行。
计算方法:
读取开始距离和结束距离;
start_prop_distance = op_td_get_dbl (pkptr, OPC_TDA_RA_START_DIST);
end_prop_distance = op_td_get_dbl (pkptr, OPC_TDA_RA_END_DIST);
计算两个时延,并写入包的TDA里。
start_prop_delay = start_prop_distance / PROP_VELOCITY;
end_prop_delay = end_prop_distance / PROP_VELOCITY;
op_td_set_dbl (pkptr, OPC_TDA_RA_START_PROPDEL, start_prop_delay);
op_td_set_dbl (pkptr, OPC_TDA_RA_END_PROPDEL, end_prop_delay);
4.7 接收天线增益阶段:模型文件dra_ragain.ps.c。
计算方法与发送天线增益类似,只是参数不一样。
4.8 接收功率计算阶段:模型文件 dra_power.ps.c。
这个计算阶段缺省地支持"信号锁(signal lock)"概念。其意义是指接收器认定先到达的包是应该接收的包,而在这个包的接收期间,置信道的信号锁为1,表明信道已经正在被占用,其他到达的包被认为是干扰。相对的概念是"功率锁(power lock)"概念。其意义是指接收器认定功率最大的包是应该接收的包,功率小于该包的其他到达的包被认为是干扰,而不管包到达的先后顺序。但"功率锁"概念不是缺省支持的处理方式。
计算方法:
读取包的"match"标志(在信道匹配阶段计算得到的,包在那个阶段被标志上valid,interference,或ignore标志中间的任一个),如果match标志为valid,则执行以下操作,进行进一步的划分valid与noise包:
op_td_get_int (pkptr, OPC_TDA_RA_MATCH_STATUS) == OPC_TDA_RA_MATCH_VALID
读取信道的标志号(ID);
rx_ch_obid = op_td_get_int (pkptr, OPC_TDA_RA_RX_CH_OBJID);
读取信道的"信号锁"标记;
若信道已被加锁,则将包标记为noise(写入TDA);若信道为空闲状态,则将信道的"信号锁"置为1,表示信道从现在开始"忙";而不管包的"match"标志是不是valid,都要计算接收功率:
读取包的发送功率;
tx_power = op_td_get_dbl (pkptr, OPC_TDA_RA_TX_POWER);
读取发送器基准频率和带宽;
tx_base_freq = op_td_get_dbl (pkptr, OPC_TDA_RA_TX_FREQ);
tx_bandwidth = op_td_get_dbl (pkptr, OPC_TDA_RA_TX_BW);
读取接受器 基准频率和带宽,从而可以得到收发器重叠的带宽;
rx_base_freq = op_td_get_dbl (pkptr, OPC_TDA_RA_RX_FREQ);
rx_bandwidth = op_td_get_dbl (pkptr, OPC_TDA_RA_RX_BW);
bind_min;band_max;
in_band_tx_power = tx_power * (band_max - band_min) / tx_bandwidth;
读取发送天线和接收天线的增益;
tx_ant_gain = pow (10.0, op_td_get_dbl (pkptr, OPC_TDA_RA_TX_GAIN) / 10.0);
rx_ant_gain = pow (10.0, op_td_get_dbl (pkptr, OPC_TDA_RA_RX_GAIN) / 10.0);
由频率计算发送波长,读取传播距离,可以利用公式计算自由空间的电磁波功率传播损耗。
tx_center_freq = tx_base_freq + (tx_bandwidth / 2.0);
lambda = C / tx_center_freq;
prop_distance = op_td_get_dbl (pkptr, OPC_TDA_RA_START_DIST);
path_loss = (lambda * lambda) / (SIXTEEN_PI_SQ * prop_distance * prop_distance);
接收功率=发送功率*(重叠带宽/发送带宽)*发送天线增益*传播损耗*接收天线增益。计算出结果并写入到包的TDA里。
rcvd_power = in_band_tx_power * tx_ant_gain * path_loss * rx_ant_gain;
op_td_set_dbl (pkptr, OPC_TDA_RA_RCVD_POWER, rcvd_power);
4.9 背景噪声功率计算阶段:模型文件dra_bkgnoise.ps.c。
在OPNET里,将背景噪声功率建模为以下两部分组成:
环境噪声:系统提供环境噪声(ambient noise)的功率谱密度AMB_NOISE_LEVEL。因此环境噪声功率=带宽*功率谱密度AMB_NOISE_LEVEL;
累计热噪声:由有效的背景温度和有效的设备温度构成。计算公式是:
累计热噪声功率=带宽*波尔兹曼常数*(背景温度+设备温度);
计算方法:
读取接收器的noise_figure;
rx_noisefig = op_td_get_dbl (pkptr, OPC_TDA_RA_RX_NOISEFIG);
假设操作温度290开尔文,计算得设备温度=(noise_figure-1)*290.0
rx_temp = (rx_noisefig - 1.0) * 290.0;
背景温度 = 常数BKG_TEMP;
bkg_temp = BKG_TEMP;
背景噪声功率 = 环境噪声功率+背景热噪声功率,计算出结果并写入包的TDA里。(在OPNET的背景噪声模型里,没有对接收放大器增益造成的噪声效果直接建模。)
bkg_noise = (rx_temp + bkg_temp) * rx_bw * BOLTZMANN;
amb_noise = rx_bw * AMB_NOISE_LEVEL;
op_td_set_dbl (pkptr, OPC_TDA_RA_BKGNOISE, (amb_noise + bkg_noise));
4.10 干扰噪声功率计算阶段:模型文件dra_inoise.ps.c。
这个pipeline stage的调用发生在特定时机:当一个包正在被接收器接收且还未完成时,另一个包又到达该接受器,此时将调用这个计算阶段来计算干扰功率。当然干扰功率只对valid包(即被接收器认为是相匹配发送器发送的包,并且在接收功率计算阶段未被打上noise标记的包。在那里,如果一个valid包到达接收器时信道已经被锁定了,则该valid包仍然认为是noise)来计算。
计算方法:
读取前一个包的接收完成时间,与当前仿真时间(即后一个包的到达时间)进行比较,如果相等,则不认为这两个包产生了互相干扰,因此不计算干扰功率;如果不相等,则进行下列操作;
op_td_get_dbl (pkptr_prev, OPC_TDA_RA_END_RX) != op_sim_time ()
将两个包的冲突次数都加1;
op_td_increment_int (pkptr_prev, OPC_TDA_RA_NUM_COLLS, 1);
op_td_increment_int (pkptr_arriv, OPC_TDA_RA_NUM_COLLS, 1);
读取两个包的"match"标志和接收功率;
prev_match = op_td_get_int (pkptr_prev, OPC_TDA_RA_MATCH_STATUS);
arriv_match = op_td_get_int (pkptr_arriv, OPC_TDA_RA_MATCH_STATUS);
若后一个包的标志为"valid",则将其噪声功率再加上前一个包的接收功率作为它的噪声功率值;
若前一个包的标志是"valid",则将其噪声功率再加上后一个包的接收功率作为它的噪声功率值。
4.11 信噪比计算阶段:模型文件dra_snr.ps.c。
虽然背景噪声功率对于每个包的传输来说,只进行估算一次,但是干扰噪声功率却可能要计算多次。因为在一个包的整个接收过程当中,可能有多次的其他包的到达,形成了新的干扰功率,每形成一次干扰,都要重新对信噪比评估一次。一个包在两次评估信噪比的时间间隔里传输的那一段数据称为一个segment。
计算方法:
读取接收功率;
rcvd_power = op_td_get_dbl (pkptr, OPC_TDA_RA_RCVD_POWER);
读取干扰噪声功率和背景噪声功率;
accum_noise = op_td_get_dbl (pkptr, OPC_TDA_RA_NOISE_ACCUM);
bkg_noise = op_td_get_dbl (pkptr, OPC_TDA_RA_BKGNOISE);
计算信噪比,写入包的TDA里;
op_td_set_dbl (pkptr, OPC_TDA_RA_SNR,
10.0 * log10 (rcvd_power / (accum_noise + bkg_noise)));
将仿真时间也写入包里,以记录本次信噪比计算的时间点。
op_td_set_dbl (pkptr, OPC_TDA_RA_SNR_CALC_TIME, op_sim_time ());
4.12 误码率计算阶段:模型文件dra_ber.ps.c。
在无线链路里,误码率计算不是基于整个包来计算的,而是基于每一个segment段来计算的。因为在这个包的传输过程中,信噪比不是固定不变的,从而导致误码率也不是固定不变的。计算方法是根据信噪比和调制函数来计算误码率,在调制函数和信噪比已知的情况下,误码率可以被唯一确定。调制函数可以在modulation curve editor里来描述。
计算方法:
读取信噪比和接收器的处理增益;
snr = op_td_get_dbl (pkptr, OPC_TDA_RA_SNR);
proc_gain = op_td_get_dbl (pkptr, OPC_TDA_RA_PROC_GAIN);
二者相加得到有效的信噪比;
eff_snr = snr + proc_gain;
读取调制函数表的的地址指针;
modulation_table = op_td_get_ptr (pkptr, OPC_TDA_RA_RX_MOD);
调用系统内核过程op_tbl_mod_ber()来计算出误码率ber,并写入包的TDA里。
ber = op_tbl_mod_ber (modulation_table, eff_snr);
op_td_set_dbl (pkptr, OPC_TDA_RA_BER, ber);
4.13 误码数目分配阶段:模型文件dra_error.ps.c。
已知每一段(segment)的误码率,即可计算出每一段的误码数目,计算方法和其他两种链路的一样。然后将其累积起来即可得到总的误码数目,并写进包的TDA里。
4.14 纠错阶段:模型文件dra_ecc.ps.c
包的可接受标准有两条:一个是因为源端的问题导致包没有完整发送;另一个是比较误码数目和接收器的纠错门限值。
计算方法:
读取节点使能标志,如果节点被disabled,则置包为不可接受;
if (op_td_is_set (pkptr, OPC_TDA_RA_ND_FAIL))
accept = OPC_FALSE;
否则就读取误码数目和纠错门限,比较二者的值,以判断是否能接受该包;
ecc_thresh = op_td_get_dbl (pkptr, OPC_TDA_RA_ECC_THRESH);
num_errs = op_td_get_int (pkptr, OPC_TDA_RA_NUM_ERRORS);
accept = ((((double) num_errs) / pklen) <= ecc_thresh) ? OPC_TRUE : OPC_FALSE;
将判断结果写如包的TDA里。
op_td_set_int (pkptr, OPC_TDA_RA_PK_ACCEPT, accept);
无论如何接收的链路都不能被锁住
rxch_state_ptr = (DraT_Rxch_State_Info *) op_ima_obj_state_get (op_td_get_int (pkptr, OPC_TDA_RA_RX_CH_OBJID));
rxch_state_ptr->signal_lock = OPC_FALSE;