📄 cmsmanager.cpp
字号:
m_iUnsatisfiedUserOfVoice++;
}
//进行重撒
TotalUserType tt=T_voice;
int ID=pVoiceMs->GetMsID();
int nType=0;
float fV[10];
float fVelocity,pp;
fV[0]=m_fFractionOfChannel[0];
for (int i=1;i<10;i++)
fV[i]=1.0;
for (i=1;i<m_iChannelNumber;i++)
fV[i]=fV[i-1]+m_fFractionOfChannel[i];
//produce a random number between 0 and 1 to
//determine the user's channel type and correspondent velocity
pp=xUniform(0.,1.);
if (pp<fV[0])
{fVelocity=3.;nType=1;}
else if (pp<fV[1])
{fVelocity=10.;nType=2;}
else if (pp<fV[2])
{fVelocity=30.;nType=3;}
else if (pp<fV[3])
{fVelocity=120.;nType=4;}
else
{fVelocity=0.;nType=5;}
//call initialization functions
pVoiceMs->MobileInitialization(ID,this,m_pServiceArea,
fVelocity,nType,m_fStdSlowFading,tt);
pVoiceMs->Clean(); //释放VoiceMs的激活集链表和软切换消息链表
pVoiceMs->VoiceInitialization(m_pLinkPrediction);
m_iVoiceUserOfCurrentDrop++;
}
/*pVoiceMs->SetVoiceActivity();
//将原先放在更新激活集函数中的设置话音激活因子改在这里*/
if(pVoiceMs->GetSHOMsgNum())//判断切换事件队列是否为空
{
if(pVoiceMs->SHOMsgProcess()) //判断切换事件是否到时
{
pVoiceMs->ChangeActiveSet(); //到时,变更激活集;否则直接更新激活集
}
}
//更新激活集计算激活集内各BTS的业务信道C/I
pVoiceMs->UpdateActiveSet();
//进行软切换开销相关统计 add by slj, Modified by Li Jing,20041115
if(m_iSlotCurrentNum>INITIALSLOT)
{
for ( int i = 0; i < ActiveSetMaxSize; i++)
{
if( i == (( pVoiceMs->GetActiveSetSize() ) - 1) )
m_lSlotOfActiveSetSize[i]++;
}
//用于软切换中的统计 add by slj 20041020
if( ( pVoiceMs->GetActiveSetSize() ) > 1 )
{
m_lTotalMsSlotInSHO ++;
m_fTotalMsPowerInSHO += pVoiceMs->ObtainPowerInSHO();
}
}
//计算激活集内各BTS的业务信道C/I
pVoiceMs->ObtainC2I();
//根据实际的C/I与目标C/I,对激活集内各
//BTS发出功控信息(考虑PCBER的影响)
pVoiceMs->PowerControl();
//更新相邻集各个BTS到移动台的
//慢衰落和快衰落值
//更新移动台接收到的总功率值
//根据判断结果和时延特性,创建
//切换事件,写入切换事件队列
pVoiceMs->SHOMsgGenerator();
// if(m_iSlotCurrentNum>INITIALSLOT) //考虑初始化时间
// {
m=pVoiceMs->GetServiceLength()+1;
pVoiceMs->SetServiceLength(m);
//add up the slots C/I of one TTI time to calculate the TTI mean C/I
sum=pVoiceMs->GetTTIMeanC2I()+(float)pow(10,(pVoiceMs->GetC2I()/10));
pVoiceMs->SetTTIMeanC2I(sum);
// }
}
else //用户还没有接纳成功
{
if(m_iSlotCurrentNum>INITIALSLOT) //考虑初始化时间
{
m=pVoiceMs->GetAdmitTimer()+1;
pVoiceMs->SetAdmitTimer(m);
}
m=pVoiceMs->GetAdmitTimer();
if(m>=BlockTimeThreshold) //接入失败超时
{
m_iBlockUserOfVoice++; //话音用户接入失败数加一
m_iUnsatisfiedUserOfVoice++;
int ID=pVoiceMs->GetMsID(); //以下为进行重撒,产生一个新的话音用户
TotalUserType tt=T_voice;
int nType=0;
float fV[10];
float fVelocity,pp;
fV[0]=m_fFractionOfChannel[0];
for (int i=1;i<10;i++)
fV[i]=1.;
for (i=1;i<m_iChannelNumber;i++)
fV[i]=fV[i-1]+m_fFractionOfChannel[i];
pp=xUniform(0.,1.);
if (pp<fV[0])
{fVelocity=3.;nType=1;}
else if (pp<fV[1])
{fVelocity=10.;nType=2;}
else if (pp<fV[2])
{fVelocity=30.;nType=3;}
else if (pp<fV[3])
{fVelocity=120.;nType=4;}
else
{fVelocity=0.;nType=5;}
pVoiceMs->MobileInitialization(ID,this,m_pServiceArea,
fVelocity,nType,m_fStdSlowFading,tt);
pVoiceMs->Clean(); //释放VoiceMs的激活集链表和软切换消息链表
pVoiceMs->VoiceInitialization(m_pLinkPrediction);
m_iVoiceUserOfCurrentDrop++;
}
else //接入失败还没有超时
pVoiceMs->InitActiveSet();
}
}
}
//////////////////////////////////////////////////////////////////////////
//TITLE: TTIBlockCumulate(TTI时间内块累加函数)
//
//PARAMETERS:当前话音用户指针
//
//PURPOSE AND ALGORITHMS:
// 每个TTI结束时,累加这个TTI内的误块数至该用户的m_iNumOfErrorBlock
// 中累加这个TTI内的块数至该用户的m_iNumOfTotalBlock中
//
//AUTHOR: Li Jing
//
//MODIFIED RECORD:
// 1. 20041101 错误统计时,一个TTI里只考虑A块的对错
// 2. 20041115
//
//////////////////////////////////////////////////////////////////////////
void CMsManager::TTIBlockCumulate(CVoiceMs* VoiceMsPointer)
{
float pp;
// int BlockNum;
float TTIMeanC2I;
float n;
int m;
//float Ior2Ioc;
bool flag;
// BlockNum=VoiceMsPointer->GetTFIPointer()->iTransBLNum;
TTIMeanC2I=VoiceMsPointer->GetTTIMeanC2I()/TTISize;
TTIMeanC2I=(float)(10*log10(TTIMeanC2I));
VoiceMsPointer->SetTTIMeanC2I(0.0);
//Ior2Ioc=VoiceMsPointer->GetIor2Ioc();
//Ior2Ioc/=TTISize;
//Ior2Ioc=(float)(10*log10(Ior2Ioc));
//VoiceMsPointer->SetIor2Ioc(0.0);
n=VoiceMsPointer->BLERPrediction(TTIMeanC2I);
// for(int i=0;i<BlockNum;i++)
// {
m=VoiceMsPointer->GetNumOfTotalBlock()+1;
VoiceMsPointer->SetNumOfTotalBlock(m);
// m_lTotalVoiceBLNum++;
pp=xUniform(0.0,1.0); //produce a random between 0 and 1
if(pp<n)
{
m=VoiceMsPointer->GetNumOfErrorBlock()+1;
VoiceMsPointer->SetNumOfErrorBlock(m);
flag=false;
// m_lTotalVoiceFailedBLNum++;
}
else
flag=true;
//用于软切换下误块率的统计add by slj 20041020
if(m_iSlotCurrentNum>INITIALSLOT+TTISize && VoiceMsPointer->GetActiveSetSize()>1)
{
m=VoiceMsPointer->GetNumOfSHOBlock()+1;
VoiceMsPointer->SetNumOfSHOBlock(m);
m_lTotalBLNumInSHO ++;
if(pp<n)
{
m=VoiceMsPointer->GetNumOfSHOFailedBlock()+1;
VoiceMsPointer->SetNumOfSHOFailedBlock(m);
m_lTotalFailedBLNumInSHO ++;
}
}
// }
VoiceMsPointer->OuterLoopPowerControl(flag);
}
//////////////////////////////////////////////////////////////////////////
//TITLE: OutageAndDropJudgement(outage及drop判断函数)
//
//PARAMETERS:当前话音用户指针
//
//PURPOSE AND ALGORITHMS:
// 每个窗口结束时,计算这个窗口时间内的误块率,若是高于15%,则
// 为outage,若是高于50%,则droptimer++,并进行重撒。
//
//AUTHOR: Li Jing
//
//CALLING FUNCTIONS:
//
//MODIFIED RECORD:
// 1. 20041115
//
//////////////////////////////////////////////////////////////////////////
void CMsManager::OutageAndDropJudgement(CVoiceMs* VoiceMsPointer)
{
int m,n;
float BLER;
float a,b;
if(m_iSlotCurrentNum>INITIALSLOT+WindowSize)
{
m=VoiceMsPointer->GetTotalWindow()+1;
VoiceMsPointer->SetTotalWindow(m);
m_lTotalVoiceBLNum+=VoiceMsPointer->GetNumOfTotalBlock();
m_lTotalVoiceFailedBLNum+=VoiceMsPointer->GetNumOfErrorBlock();
a=(float)(VoiceMsPointer->GetNumOfErrorBlock());
b=(float)(VoiceMsPointer->GetNumOfTotalBlock());
BLER=a/b;
VoiceMsPointer->SetWindowBLER(BLER);
if(BLER>OutageThreshold)
{
m=VoiceMsPointer->GetTotalOutageWindow()+1;
VoiceMsPointer->SetTotalOutageWindow(m);
}
if(BLER>DropThreshold)
{
n=VoiceMsPointer->GetDropTimer()+1;
VoiceMsPointer->SetDropTimer(n);
if(n==3)
{
m_iDropUserOfVoice++;
VoiceMsPointer->SetIsDropped(true);
m_iUnsatisfiedUserOfVoice++;
VoiceMsPointer->SetServiceLength(MeanCallTime*1500);
//单位为时隙
//这样做是为了等会判断服务结束,以进行重撒
//Added by Li Jing for debugging,20041104
//统计掉话用户信息,包括当前时隙,用户ID,基站ID以及用户和基站距离,当前的C2I等
SECTORID_TYPE SectorID = VoiceMsPointer->m_aMonitorSector[VoiceMsPointer->GetBestSectorIndex()].stSectorID;
int iCellm = SectorID.stCellID.m;
int iCelln = SectorID.stCellID.n;
int iSectorIndex = SectorID.s;
float fDistance = DistanceCaculte(VoiceMsPointer->GetMsLocation(),SectorID);
CStdioFile f;
char buf[50];
f.Open("DroppedVoiceUsers.txt",CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite);
f.SeekToEnd();
_itoa(m_iSlotCurrentNum,buf,10);
f.WriteString(buf);
f.WriteString("\t");
_itoa(VoiceMsPointer->GetMsID(),buf,10);
f.WriteString(buf);
f.WriteString("\t(");
_itoa(iCellm,buf,10);
f.WriteString(buf);
f.WriteString(",");
_itoa(iCelln,buf,10);
f.WriteString(buf);
f.WriteString(",");
_itoa(iSectorIndex,buf,10);
f.WriteString(buf);
f.WriteString(")\t");
_gcvt(fDistance,10,buf);
f.WriteString(buf);
f.WriteString("\t");
_gcvt(VoiceMsPointer->GetC2I(),10,buf);
f.WriteString(buf);
f.WriteString("\n");
f.Close();
}
}
else
VoiceMsPointer->SetDropTimer(0);
}
VoiceMsPointer->SetNumOfErrorBlock(0);
VoiceMsPointer->SetNumOfTotalBlock(0);
}
//////////////////////////////////////////////////////////////////////////
//TITLE: VoiceStatistics(话音统计函数)
//
//PARAMETERS:NULL
//
//PURPOSE AND ALGORITHMS:
// 在每个Drop结束时由DataStatics调用,计算出话音用户的接入阻塞
// 率、中断率及掉话率,并写入相应的文件中
//
//AUTHOR: Li Jing
//
//CALLING FUNCTIONS:
//
//NOTES: 增加了DROP结束时,对话音用户链表上还未结束通话的用户的处理,以
// 增加统计的精确性
//
//////////////////////////////////////////////////////////////////////////
void CMsManager::VoiceStatistics()
{
float a,b,c;
CStdioFile f;
char buf[50];
POSITION pos;
pos=m_VoiceList.GetHeadPosition();
CVoiceMs* pVoiceMs=NULL;
while(pos!=NULL)
//循环处理此时的话音用户
{
pVoiceMs=m_VoiceList.GetNext(pos);
if(pVoiceMs->IsAdmitted())
//the user who has been admitted successfully
{
if(pVoiceMs->GetTotalWindow()>=1)
{
a=(float)(pVoiceMs->GetTotalOutageWindow());
b=(float)(pVoiceMs->GetTotalWindow());
c=a/b;
pVoiceMs->SetOutageRatio(c);
if(c>UserOutageThreshold)
{
m_iOutageUserOfVoice++;
if(pVoiceMs->IsDropped()==false)
m_iUnsatisfiedUserOfVoice++;
}
//对于已经接纳成功且通话时间已超过一个window的用户,按照现在的
//中断率来判断它是否outage user
}
else
m_iVoiceUserOfCurrentDrop--;
//对于通话时间还不到一个window的用户,由于无法计算,就将这个用户排除统计
}
else
m_iVoiceUserOfCurrentDrop--;
//对于还未接纳成功且还没有超时的用户,也将这个用户排除统计
}
//calculate the statistics
m_fBlockRatioOfVoice=float(m_iBlockUserOfVoice)/float(m_iVoiceUserOfCurrentDrop);
m_fOutageRatioOfVoice=float(m_iOutageUserOfVoice)/float(m_iVoiceUserOfCurrentDrop);
m_fDropRatioOfVoice=float(m_iDropUserOfVoice)/float(m_iVoiceUserOfCurrentDrop);
m_fSatisfiedRadioOfVoice=float(m_iVoiceUserOfCurrentDrop-m_iUnsatisfiedUserOfVoice)/float(m_iVoiceUserOfCurrentDrop);
m_fMeanVoiceBLER=(float)m_lTotalVoiceFailedBLNum/(float)(m_lTotalVoiceBLNum);
//SHO开销 add by slj
for ( int i = 0; i < ActiveSetMaxSize; i++)
{
m_lTotalSlotOfActiveSetSize += m_lSlotOfActiveSetSize[i];
}
for ( int j = 0; j < ActiveSetMaxSize; j++)
{
m_fScaleOfActiveSetSize[j] = float(m_lSlotOfActiveSetSize[j])/float(m_lTotalSlotOfActiveSetSize); //激活集内不同扇区数所占时间比例
}
for ( int k = 0; k < ActiveSetMaxSize; k++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -