📄 cmsmanager.cpp
字号:
}
//在对每个移动台进行处理时,还需要判断其通话时间是否完成,
//若已经完成,则重新调用移动台初始化函数,重新初始化。
pVoiceMs->SetVoiceActivity();
if(pVoiceMs->GetSHOMsgNum())//判断切换事件队列是否为空
{//...... modified by cqm, Apr.9 ......//
if((pVoiceMs->SHOMsgProcess()>0)&&(m_iSlotCurrentNum%16==1)) //判断切换事件是否到时
{//..............................//每帧结束时才变更激活集
pVoiceMs->ChangeActiveSet(); //到时,变更激活集;否则直接更新激活集
}
}
//为空,更新激活集计算激活集内各BTS的业务信道C/I
pVoiceMs->UpdateActiveSet();
//计算激活集内各BTS的业务信道C/I
pVoiceMs->ObtainC2I();
//根据实际的C/I与目标C/I,对激活集内各
//BTS发出功控信息(考虑PCBER的影响)
pVoiceMs->PowerControl();
//...... added by cqm, Apr.9 ......//
if(m_iSlotCurrentNum%16==0)
{
pVoiceMs->FERPrediction();
pVoiceMs->FrameQualityDecision();
if(m_iSlotCurrentNum>INITIALSLOT)
pVoiceMs->GOSDecision();
}
//更新相邻集各个BTS到移动台的
//慢衰落和快衰落值
//更新移动台接收到的总功率值
//根据判断结果和时延特性,创建
//切换事件,写入切换事件队列
pVoiceMs->SHOMsgGenerator();
if(m_iSlotCurrentNum>INITIALSLOT) //考虑初始化时间
{
m=pVoiceMs->GetServiceLength()-1;
pVoiceMs->SetServiceLength(m);
}
//test...................
if(m_iSlotCurrentNum==(480000+INITIALSLOT))
{
p=pVoiceMs->GetFERIndicator();
if(((float(p)/(float)1500)>0.01)&&(!pVoiceMs->m_bIsSHOOut))
{
m_iBadNumOfVoice++;
m_iVoiceUserOfCurrentDrop++;
}
else
m_iVoiceUserOfCurrentDrop++;
}
}
}
//////////////////////////////////////////////////////////////////////////////
//
// PURPOSE:
//
// AUTHOR:
//
// AUDITOR:
//
// DATE: 01/04/09
//
// TEST RECORD:
//
// MODIFICATIONS:
//
//////////////////////////////////////////////////////////////////////////////
void CMsManager::VoiceStatistics()
//输出文件为voice.txt
{
CStdioFile f;
char buf[50];
//cyu于5.14修改
//...... modified by cqm, Apr.9 ......//
// m_fDropRatioOfVoice=float(m_iDropNumOfVoice)/float(m_iVoiceUserOfCurrentDrop);
m_fBadRatioOfVoice=float(m_iBadNumOfVoice)/float(m_iVoiceUserOfCurrentDrop);
//....................................//
/* 打开数据文件准备写*/
if(!f.Open(m_sVoiceFile,
CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite))
{
#ifdef _DEBUG
afxDump<<"Unable to open file"<<"\n"; //异常处理
#endif
}
f.SeekToEnd();
//使文件指针指向文件尾部,输出数据可以在文件尾部接着写
// f.WriteString("话音用户掉话率\n");
// _gcvt(m_fDropRatioOfVoice,8,buf);
// f.WriteString(buf);
// f.WriteString("\n");
//...... modified by cqm, Apr.9 ......//
f.WriteString("话音用户中断率(每扇区");
_gcvt(m_iVoiceNumPerSector,8,buf);
f.WriteString(buf);
f.WriteString("用户):\n");
_gcvt(m_fBadRatioOfVoice,8,buf);
f.WriteString(buf);
f.WriteString("\n");
f.WriteString("话音用户中断数目:\n");
_gcvt((float)m_iBadNumOfVoice,8,buf);
f.WriteString(buf);
f.WriteString("\n");
f.WriteString("话音用户总数:\n");
_gcvt((float)m_iVoiceUserOfCurrentDrop,8,buf);
f.WriteString(buf);
f.WriteString("\n");
f.Close();
}
//孟松新增函数
//计算移动台到最近基站的距离(多个函数中用到)
float CMsManager::DistanceCaculte(LOCATION_TYPE MsLocation,
SECTORID_TYPE SectorID)
{
float x1,x2,y1,y2;
LOCATION_TYPE BsLocation;
x1=MsLocation.x;
y1=MsLocation.y;
BsLocation=m_pServiceArea->GetCor(SectorID.stCellID);
x2=BsLocation.x;
y2=BsLocation.y;
return (float)sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
//////////////////////////////////////////////////////////////////////////////
//
// PURPOSE:Process the data mobiles
//
// AUTHOR: Cheng Yu
//
// AUDITOR:Ouyang Hui
//
// DATE: 01/04/09
//
// TEST RECORD:
//
// MODIFICATIONS:
//
//////////////////////////////////////////////////////////////////////////////
void CMsManager::DataProcess()
//循环处理数据业务移动台,根据移动台对应最佳扇区的分组数据信道功率
//计算适合的数据传输速率,并统计各个扇区对应的优先级最高者,
//做出相应标记(即把扇区对应的最佳用户进行付值)。然后,更新衰落值和最佳扇区。
{
POSITION pos;
CSector* pSector=NULL;
//////////////////////////////////////////////////////////////////
pos=m_FtpDataList.GetHeadPosition();
CFtpDataMs* pFtpDataMs=NULL;
while(pos!=NULL) //ftp user
{
pFtpDataMs=m_FtpDataList.GetNext(pos);
pFtpDataMs->FillDataQueue();
pSector=m_pServiceArea->GetSector(pFtpDataMs
->GetCurrentSector());
//zx20010813 所有数据用户的平均速率都进行这样的递减操作,
//只有传输了的用户才需要另外加上使其平均速率增高的部分(Rreq/Tc)
pFtpDataMs->m_fAverageRate *= (float)((fConstTc-1.0)/fConstTc);
if(m_iSlotCurrentNum==1000)
{
#ifdef NEWMAXC2I
pFtpDataMs->m_fAverageRate=(float)pFtpDataMs->m_lTotalGoodBitsNum/(1.25*1000);
#endif
// pFtpDataMs->m_lTotalGoodBitsNum=0;
}
if(pFtpDataMs->IsTransmitingNow())
{
pSector->SetIsExistHighestPriority(true);//将该用户设为最高优先权指标用户
}
else
{
pFtpDataMs->C2ICalculate();
//在这里需要插入张定业编的时延函数
pFtpDataMs->C2IFeedbackDelay();
if(pFtpDataMs->m_fDelayedC2IValue==0.) continue;
pFtpDataMs->C2IFeedback();
//cyu于5.15修改
if(pSector->IsExistHighestPriority()==false&&pFtpDataMs->m_lDataQueueSize>0)
{
pFtpDataMs->RatePrediction();
RATE2CI_TYPE* pRatePrediction=pFtpDataMs->GetstRatePrediction();
if((pFtpDataMs->GetCurrentPacketSize()>0)&&(pRatePrediction!=NULL))
{
Scheduling((CDataMs*)pFtpDataMs);//zx20010813
}
}
}
}
pos=m_HttpDataList.GetHeadPosition();
CHttpDataMs* pHttpDataMs=NULL;
while(pos!=NULL) //http user
{
pHttpDataMs=m_HttpDataList.GetNext(pos);
pHttpDataMs->PacketCallProcess();
//根据业务模型,产生新的数据包,加入数据队列
pSector=m_pServiceArea->GetSector(pHttpDataMs
->GetCurrentSector());//得到当前扇区指针
//zx20010813 所有数据用户的平均速率都进行这样的递减操作,
//只有传输了的用户才需要另外加上使其平均速率增高的部分(Rreq/Tc)
pHttpDataMs->m_fAverageRate *= (float)((fConstTc-1.0)/fConstTc);
if(m_iSlotCurrentNum==1000)
{
#ifdef NEWMAXC2I
pHttpDataMs->m_fAverageRate=(float)pHttpDataMs->m_lTotalGoodBitsNum/(1.25*1000);
#endif
}
if(pHttpDataMs->IsTransmitingNow())
//这里的在传输指的就是Subpacket的传输正在进行
{
pSector->SetIsExistHighestPriority(true);//将该用户设为最高优先权指标用户
}
else
{
pHttpDataMs->C2ICalculate();
//在这里需要插入张定业编的时延函数
pHttpDataMs->C2IFeedbackDelay();
if(pHttpDataMs->m_fDelayedC2IValue==0.) continue;
pHttpDataMs->C2IFeedback();
if(pSector->IsExistHighestPriority()==false&&pHttpDataMs->m_lDataQueueSize>=384)
{
pHttpDataMs->RatePrediction();
RATE2CI_TYPE* pRatePrediction=pHttpDataMs->GetstRatePrediction();
if((pHttpDataMs->GetCurrentPacketSize()>0)&&(pRatePrediction!=NULL))
{
Scheduling((CDataMs*)pHttpDataMs);
}
}
}
}
}
//////////////////////////////////////////////////////////////////////////////
//
// PURPOSE:Set the best data mobile user in each sector
//
// AUTHOR: Cheng Yu
//
// AUDITOR:Ouyang Hui
//
// DATE: 01/04/09
//
// TEST RECORD:
//
// MODIFICATIONS:
//
//////////////////////////////////////////////////////////////////////////////
void CMsManager::Scheduling(CDataMs* pDataMs)
{
CSector* pSector=NULL;
float priorityfactor;
if (m_iSlotCurrentNum>1)
{
pSector=(m_pServiceArea->GetSector(pDataMs->GetCurrentSector()));
priorityfactor=DataPriorityCalculate(pDataMs);//调用优先权指标计算函数
#ifdef NEWMAXC2I
if(m_iSlotCurrentNum>1000)
{
if(pDataMs->m_fAverageRate>250.)
{
priorityfactor=0.;
}
}
#endif
if(priorityfactor>pSector->GetPriorityFactor())//如果大于当前优先权指标
{
pSector->SetPriorityFactor(priorityfactor);//重新写入优先权指标
pSector->SetCurrentDataMs(pDataMs);//记入最佳用户指针
}
#ifdef NEWMAXC2I
if(m_iSlotCurrentNum>1000)
{
if(pDataMs->m_fAverageRate<15.0)
{
pSector->SetIsExistHighestPriority(true);
pSector->SetCurrentDataMs(pDataMs);
}
}
#endif
}
}
//////////////////////////////////////////////////////////////////////////////
//
// PURPOSE:统计总的成功传输数据量
//
// AUTHOR: Cheng Yu
//
// AUDITOR:Ouyang Hui
//
// DATE: 01/04/09
//
// TEST RECORD:
//
// MODIFICATIONS:
//
//////////////////////////////////////////////////////////////////////////////
void CMsManager::DataBitsAndPacketCumulate()
//对所有的成功传输的数据量,EP数量和错误的EP数量进行累加
{
POSITION pos;
pos=m_HttpDataList.GetHeadPosition();
CHttpDataMs* pHttpDataMs=NULL;
while(pos!=NULL)
{
pHttpDataMs=m_HttpDataList.GetNext(pos);
m_fTotalBits+=pHttpDataMs->GetTotalGoodBitsNum();
m_lTotalErrorEP+=pHttpDataMs->GetErrorEPNum();
m_lTotalGoodEP+=pHttpDataMs->GetSuccessfulEPNum();
//zdy新加属性累加
m_lTotalErrorPacket+=pHttpDataMs->GetErrorPacketNum(); //总的差错Packet数
m_lTotalGoodPacket+=pHttpDataMs->GetSuccessfulPacketNum(); //总的正确Packet数
m_lRealErrorSP+=pHttpDataMs->m_iRealErrorSP;
m_lRealTotalSP+=pHttpDataMs->m_iRealTotalSP;
m_lDiscardedPacket+=pHttpDataMs->m_iDiscardedPacket;
m_lErrorSPDCCH+=pHttpDataMs->m_iErrorSPDCCH;
}
pos=m_FtpDataList.GetHeadPosition();
CFtpDataMs* pFtpDataMs=NULL;
while(pos!=NULL)
{
pFtpDataMs=m_FtpDataList.GetNext(pos);
m_fTotalBits+=pFtpDataMs->GetTotalGoodBitsNum();
m_lTotalErrorEP+=pFtpDataMs->GetErrorEPNum();
m_lTotalGoodEP+=pFtpDataMs->GetSuccessfulEPNum();
//目前的ftp模型中还没有packet的概念,因此无需统计相关量
m_lRealErrorSP+=pFtpDataMs->m_iRealErrorSP;
m_lRealTotalSP+=pFtpDataMs->m_iRealTotalSP;
m_lErrorSPDCCH+=pFtpDataMs->m_iErrorSPDCCH;
}
}
//////////////////////////////////////////////////////////////////////////////
//
// PURPOSE:Calculate a data user's priority
//
// AUTHOR: Cheng Yu
//
// AUDITOR:Ouyang Hui
//
// DATE: 01/04/09
//
// TEST RECORD:
//
// MODIFICATIONS:
//
//////////////////////////////////////////////////////////////////////////////
float CMsManager::DataPriorityCalculate(CDataMs* pDataMs)
{
float m=0.;
if (pDataMs->GetCurrentPacketSize()<=0)
m=0.;
else
{
#ifdef MAXC2I
m=pDataMs->GetFilterOutputC2I();
#endif
#ifdef RANDOMR
m=xUniform();
#endif
#ifdef PROPFAIRNESS
m=PropFairCalculate(pDataMs);
#endif
#ifdef NEWMAXC2I
m=pDataMs->GetFilterOutputC2I();
// if(pDataMs->m_fAverageRate
#endif
}
return m;
}
////cyu于5.15添加
float CMsManager::PropFairCalculate(CDataMs* pDataMs)
{
float n=0.;
RATE2CI_TYPE* pRatePrediction=pDataMs->GetstRatePrediction();
n=pRatePrediction->fDataRate/pDataMs->m_fAverageRate;
return n;
}
///////////////////////////////////////////////////////////////////////
//////////////// 以下函数由孟松编写
//平均吞吐量计算输出函数
//completed by ms in 3.29
void CMsManager::MeanThroughputStatistics()
//输出文件为meanthroughput.txt
{
float MeanThroughput;
char buf[50];
CStdioFile f;
MeanThroughput=(float)(m_fTotalBits/SectorNumber/(m_fDropTime));//不考虑初始化时间
// MeanThroughput=(float)(m_fTotalBits/(MM*NN*SectorNumber)/(m_fDropTime-INITIALSLOT*SlotSize/1000));//统计吞吐量时要减去初始化时间
/* 打开数据文件准备写*/
if(!f.Open(m_sSystemMeanThroughputFile,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite))
{
#ifdef _DEBUG
afxDump<<"Unable to open file"<<"\n"; //异常处理
#endif
}
f.SeekToEnd();//使文件指针指向文件尾部,输出数据可以在文件尾部接着写
f.WriteString("平均吞吐量_每扇区的数据用户的平均吞吐量_bit/s/sector \n");
_gcvt(MeanThroughput,8,buf);
f.WriteString(buf);
f.WriteString("\n");
f.Close();
}
//分组差错概率计算输出函数
//completed by ms in 3.29
void CMsManager::MeanPERStatistics()
//输出文件为meanper.txt
{
CStdioFile f;
char buf[50];
m_fMeanPER=(float)m_lTotalErrorEP/(m_lTotalErrorEP
+m_lTotalGoodEP);
/* 打开数据文件准备写*/
if(!f.Open(m_sSystemMeanPERFile,
CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite))
{
#ifdef _DEBUG
afxDump<<"Unable to open file"<<"\n"; //异常处理
#endif
}
f.SeekToEnd(); //使文件指针指向文件尾部,输出数据可以在文件尾部接着写
f.WriteString("EP分组差错概率_所有数据用户的结果\n");
_gcvt(m_fMeanPER,8,buf); //将浮点数转换成字符串
f.WriteString(buf);
f.WriteString("\n");
float fMeanPacketER=float(m_lTotalErrorPacket)/(m_lTotalErrorPacket+m_lTotalGoodPacket);
f.WriteString("Packet分组差错概率_所有http数据用户的结果\n");
_gcvt(fMeanPacketER,8,buf); //将浮点数转换成字符串
f.WriteString(buf);
f.WriteString("\n");
float fMeanRealPER=float(m_lRealErrorSP)/m_lRealTotalSP;
f.WriteString("SP分组差错概率_所有数据用户的结果\n");
_gcvt(fMeanRealPER,8,buf); //将浮点数转换成字符串
f.WriteString(buf);
f.WriteString("\n");
float fMeanDiscardedRatio=float(m_lDiscardedPacket)/(m_lTotalErrorPacket+m_lTotalGoodPacket);
f.WriteString("Packet丢弃概率_所有数据用户的结果\n");
_gcvt(fMeanDiscardedRatio,8,buf); //将浮点数转换成字符串
f.WriteString(buf);
f.WriteString("\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -