?? cvoicems.cpp
字號:
///////////////////////////////////////////////////////////////////
// WCDMA TEAM //
// BUPT Radio Research Center //
///////////////////////////////////////////////////////////////////
//
// CVoiceMs.cpp
//
//////////////////////////////////////////////////////////////////////
// //
// 話音移動臺CVoiceMs的成員函數(shù)的聲明 //
// //
// Written by: 李晶 //
// Date: 200404 //
// //
//////////////////////////////////////////////////////////////////////
#include "CVoiceMs.h"
#include "systemsim.h"
#include "iostream.h"
#include "sys_random.h"
#include "CMsManager.h"
#include "CLinkPrediction.h"
//////////////////////////////////////////////////////////////////////////
// 構(gòu)造函數(shù)
// 將各屬性賦予初始值
//////////////////////////////////////////////////////////////////////////
CVoiceMs::CVoiceMs()
{
}
//end of CVoiceMs()
//////////////////////////////////////////////////////////////////////////
// 析構(gòu)函數(shù)
// 釋放內(nèi)存空間
//////////////////////////////////////////////////////////////////////////
CVoiceMs::~CVoiceMs()
{
Clean();
}
//end of ~CVoiceMs()
//////////////////////////////////////////////////////////////////////////
//TITLE: VoiceInitialization(話音移動臺初始化函數(shù))
//
//PARAMETERS:NULL
//
//PURPOSE AND ALGORITHMS:
// 初始化m_iServiceLength、m_eUsertype、m_iUnsatisfiedTimer、
// m_iDropTimer等參數(shù)
// 實際上,每一次初始化話音移動臺的時候,都是先調(diào)用基類的
// MobileInitialization函數(shù),再調(diào)用此函數(shù)進行初始化
//
//AUTHOR: Li Jing
//
//CALLING FUNCTIONS:
// CMarkovVoice::initRan()
// CMobile::ObtainBestSector()
// CMobile::InitActiveSet()
// CMobile::ObtainC2I()
//
//////////////////////////////////////////////////////////////////////////
void CVoiceMs::VoiceInitialization(CLinkPrediction *pLinkPrediction)
{
//Modified by Li Jing,20040713
m_pLinkPrediction = pLinkPrediction;//指向鏈路預測對象
POSITION pos;
pos=m_pLinkPrediction->m_pstRateTable.GetHeadPosition();
RATE2CI_TYPE *pRate = new RATE2CI_TYPE;
pRate=m_pLinkPrediction->m_pstRateTable.GetNext(pos);
while ((pos!=NULL)&&(pRate->fDataRate!=(float)12.2||pRate->iChannelType!=m_iChannelType))
{
pRate=m_pLinkPrediction->m_pstRateTable.GetNext(pos);
}
m_pstTFI=pRate->pTFI;
m_fC2ITarget=pRate->fTargetC2I;
m_eUsertype=voice; //初始化m_eUsertype為voice,表示為話音用戶
m_bIsDropped=false;
m_iDropTimer=0;
m_fVoiceActiveFactor=m_pMsManager->m_fVoiceActiveFactor;
//話音激活因子初始化
m_iServiceTime=0; //已經(jīng)服務的時長清0
m_iServiceLength=0; //用slot數(shù)表示的已經(jīng)服務的時長
m_iTotalOutageWindow=0; //中斷的窗口數(shù)清為0
m_iTotalWindow=0; //總的通話窗口清為0
m_fOutageRatio=0; //中斷率清為0
m_fC2IThreshold=m_pMsManager->m_fC2IThreshold;
//at present,consider full_rate only
m_fFwdCurrentActiveFactor=1.0; //本slot話音激活因子為1
m_fFwdLastActiveFactor=1.0; //上一slot話音激活因子為1
m_iFwdFrameRate=FULL_RATE;
m_pfC2IIndex=&(m_pMsManager->m_fC2IIndex[0]); //C/I指針
switch(m_iChannelType) //determine the C/I target
{
case 1 :
//MsVelocity=3
m_pfBLER=&(m_pMsManager->m_fBLER_1[0]);
break;
case 2 :
//MsVelocity=10
m_pfBLER=&(m_pMsManager->m_fBLER_2[0]);
break;
case 3 :
//MsVelocity=30
m_pfBLER=&(m_pMsManager->m_fBLER_3[0]);
break;
case 4 :
//MsVelocity=120
m_pfBLER=&(m_pMsManager->m_fBLER_4[0]);
break;
case 5 :
//MsVelocity=0
m_pfBLER=&(m_pMsManager->m_fBLER_5[0]);
break;
}
ObtainBestSector(); //在移動臺的監(jiān)測集中根據(jù)導頻情況找出最佳扇區(qū)
InitActiveSet(); //初始化激活集。話音移動臺與數(shù)據(jù)DCH狀態(tài)的移動臺的激活集初始化過程是相同的,而
//DSCH狀態(tài)的移動臺則不要初始化激活集。所以這個函數(shù)在實現(xiàn)時要加以區(qū)分!
//另外,初始化激活集與2000中有較大的區(qū)別:現(xiàn)在初始化時移動臺只是與最佳扇區(qū)進行
//接納控制,也就是說初始化時最多只有最佳扇區(qū)可能進入激活集
ObtainC2I(); //獲得當前時隙的C/I
}
//////////////////////////////////////////////////////////////////////////
//TITLE: PowerControl(功率控制函數(shù))
//
//PARAMETERS:NULL
//
//PURPOSE AND ALGORITHMS:
// 功率控制函數(shù),根據(jù)計算得到的C/I與功率控制目標C/I的關系,調(diào)整
// 激活集內(nèi)各個扇區(qū)的發(fā)射功率。需要考慮功控誤差,暫時不考慮功控時延
// (在基類中用的是純虛函數(shù),此處給出實現(xiàn))
//
//AUTHOR: Li Jing
//
//CALLING FUNCTIONS:
//
//////////////////////////////////////////////////////////////////////////
void CVoiceMs::PowerControl()
{
/* CStdioFile f;
char buf[50];
char FileName[40];
CString sp;
sp="Exception.txt";
strcpy(FileName,sp);*/
//Modified by Li Jing,20041012
float fPowerDelta_T;
float fPowerDelta_R;
float fPowerIncrement;
float fMinTrafficPower; //業(yè)務信道最小值,單位:mw
float fTotalC2I=0; //總的C/I,初值為零
float frv; //(0,1)分布的隨機數(shù)
float fOldTrafficPower; //功控前業(yè)務信道功率,單位:mW
float fTempTrafficPower; //業(yè)務信道功率,單位:dBm
float fTargetC2I;
POSITION posTemp; //臨時位置指針
CSector* pTempSector=NULL; //臨時扇區(qū)指針
bool bDecision;
fPowerDelta_T=(float)(-1*m_pMsManager->m_fPowerControlStep);
fTotalC2I=m_fC2I; //當前時隙的C/I
fTargetC2I=m_fC2ITarget;
if(fTotalC2I<=fTargetC2I)
//如果當前時隙的C/I小于目標C/I
fPowerDelta_T*=(-1);//調(diào)整步長為正(增加)
/* if(m_iMsID==90)
{
if(!f.Open(FileName,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite))
{
#ifdef _DEBUG
afxDump<<"Unable to open file"<<"\n"; //exception handling
#endif
}
f.SeekToEnd();
//使文件指針指向文件尾部,輸出數(shù)據(jù)可以在文件尾部接著寫
f.WriteString("\nthe mobile has done one power control");
}*/
posTemp=m_ActiveSetList.GetHeadPosition();
//取得鏈表頭,并令臨時指針指向鏈表頭
while(posTemp!=NULL) //到達鏈表尾則結(jié)束循環(huán)
{
pTempSector=
m_pServiceArea->GetSector(m_ActiveSetList.GetAt(posTemp)->stSectorID);
//獲得激活扇區(qū)的指針
fOldTrafficPower=m_ActiveSetList.GetAt(posTemp)->fTrafficPower;
//retrieve the transmit power before the power control
fTempTrafficPower=(float)(10*log10(fOldTrafficPower));
frv=xUniform(0.0,1.0);//產(chǎn)生一個(0,1)分布的隨機數(shù),用來模擬功控誤差
if(frv<m_pMsManager->m_fBEROfPC)
//如果隨機數(shù)小于功控比特差錯概率
fPowerDelta_R=fPowerDelta_T*(-1);//功控出錯,原來的加變成了減
else
fPowerDelta_R=fPowerDelta_T;
fTempTrafficPower+=fPowerDelta_R; //調(diào)整此目標扇區(qū)對此移動臺業(yè)務信道功率值
fTempTrafficPower=(float)(pow(10,(fTempTrafficPower/10)));
if(fTempTrafficPower>pTempSector->GetMaxPower()
*m_pMsManager->m_fMaxFractionOfTrafficPower)
//如果業(yè)務信道功率大于最大值
fTempTrafficPower=
pTempSector->GetMaxPower()*m_pMsManager->
m_fMaxFractionOfTrafficPower;
//就將業(yè)務信道功率置為最大值
fMinTrafficPower=
(float)((pTempSector->GetMaxPower()*
m_pMsManager->m_fMaxFractionOfTrafficPower)
/pow(10,(m_pMsManager->m_fDynamicRangeOfTrafficPower/10)));
//將dB轉(zhuǎn)化為mw
if(fTempTrafficPower<fMinTrafficPower)
//如果業(yè)務信道功率小于動態(tài)范圍
fTempTrafficPower=fMinTrafficPower;
//就將業(yè)務信道功率置為最小值(動態(tài)范圍)
fPowerIncrement=fTempTrafficPower-fOldTrafficPower;
//retrieve the power increment of the power control
bDecision=pTempSector->PowerControlDecision(fPowerIncrement);
if(bDecision)
{
m_ActiveSetList.GetAt(posTemp)->fTrafficPower=fTempTrafficPower;
pTempSector->VoicePowerCumulate(fPowerIncrement);
//add the voice power increment to the active sector
pTempSector->TxPowerUpdate();
//update the total power of the sector
}
/* if(m_iMsID==90)
{
f.WriteString("\nthe active sector's index in monitor is:");
_gcvt(m_ActiveSetList.GetAt(posTemp)->iIndexInMonitor,8,buf);
f.WriteString(buf);
f.WriteString("\nthe active sector's transmission power is:");
_gcvt(m_ActiveSetList.GetAt(posTemp)->fTrafficPower,8,buf);
f.WriteString(buf);
}*/
m_ActiveSetList.GetNext(posTemp);
//獲得鏈表的下一個激活扇區(qū)結(jié)構(gòu)
}
/* if(m_iMsID==90)
{
f.Close();
}*/
}
//////////////////////////////////////////////////////////////////////////
//TITLE: SetVoiceActivity(話音激活特性設置函數(shù))
//
//PARAMETERS:NULL
//
//PURPOSE AND ALGORITHMS:
// 根據(jù)話音激活因子,設置話音激活標志
//
//AUTHOR: Li Jing
//
//CALLING FUNCTIONS:
//
//////////////////////////////////////////////////////////////////////////
/*void CVoiceMs::SetVoiceActivity()
{
float fDif;
m_fFwdLastActiveFactor=m_fFwdCurrentActiveFactor;
if(m_iSlotCount%15==1)
//每一個幀,更新一次激活因子
{
m_iFwdFrameRate=m_cFwdMarkovState.GetNextState()%4;
switch(m_iFwdFrameRate)
{
case FULL_RATE : m_fFwdCurrentActiveFactor=1.0;
fDif=0.0;
break;
case HALF_RATE : m_fFwdCurrentActiveFactor=0.5;
fDif=3.0;
break;
case QUARTER_RATE : m_fFwdCurrentActiveFactor=0.25;
fDif=6.0;
break;
case EIGHTH_RATE : m_fFwdCurrentActiveFactor=0.125;
fDif=9.0;
break;
}
m_fC2IThreshold=m_pMsManager->m_fC2IThreshold-fDif;
switch(m_iChannelType)
{
case 1 : m_fC2ITarget=(float)C2ITargetForVoice1-fDif;
break;
case 2 : m_fC2ITarget=(float)C2ITargetForVoice2-fDif;
break;
case 3 : m_fC2ITarget=(float)C2ITargetForVoice3-fDif;
break;
case 4 : m_fC2ITarget=(float)C2ITargetForVoice4-fDif;
break;
case 5 : m_fC2ITarget=(float)C2ITargetForVoice5-fDif;
break;
}
}
}
*/
//////////////////////////////////////////////////////////////////////////
//TITLE: IsServiceOver(服務時長到時的判斷函數(shù))
//
//PARAMETERS:NULL
//
//PURPOSE AND ALGORITHMS:
// 判斷服務時長是否到時,到時返回TRUE
//
//AUTHOR: Li Jing
//
//CALLING FUNCTIONS:
//
//////////////////////////////////////////////////////////////////////////
bool CVoiceMs::IsServiceOver()
{
if(m_iServiceLength>=MeanCallTime*1500) //如果服務到時
return true; //返回true
else
return false; //返回false
}
//////////////////////////////////////////////////////////////////////////
//TITLE: UpdateActiveSetPower(更新激活集中激活扇區(qū)的功率函數(shù))
//
//PARAMETERS:NULL
//
//PURPOSE AND ALGORITHMS:
// 將移動臺激活集中的各個扇區(qū)各自的話音功率進行累加,調(diào)用函數(shù):
// CMsManager::UpdateSectorVoicePower()將所有的話音移動臺
// 進行循環(huán)一次后,實際上就將每一個扇區(qū)發(fā)射的話音總功率累加起來了
//
//AUTHOR: Li Jing
//
//CALLING FUNCTIONS:
// CServiceArea::GetSector()
// CSector::VoicePowerCumulate()
//
//CALLED FUNCTIONS:
// CMsManager::UpdateSectorVoicePower()
//
//NOTES: 這個函數(shù)還是放在話音移動臺中實現(xiàn),因為數(shù)據(jù)移動臺不調(diào)用這個函數(shù)
//
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -