📄 cmobile.cpp
字号:
// CServiceArea::GetSiteDistance()
//
//////////////////////////////////////////////////////////////////////////
void CMobile::LocationGenerator()
{
m_stMsLocation.x
=xUniform(0,(float)((MM+3.5)*m_pServiceArea->GetSiteDistance()
/sqrt(3))); //m_pServiceArea->GetSiteDistance():返回基站间隔(小区半径)
m_stMsLocation.y
=xUniform(0,(float)((NN+0.5)*m_pServiceArea->GetSiteDistance()));
}
//////////////////////////////////////////////////////////////////////////
//TITLE: LocationSector(归属扇区确定函数)
//
//PARAMETERS:NULL
//
//PURPOSE AND ALGORITHMS:
// 移动台初始化时,在产生了移动台的坐标后调用.
// 通过调用ServiceArea中的函数GetUserSector来实现
//
//AUTHOR: Li Jing
//
//CALLING FUNCTIONS:
// CServiceArea::GetUserSector()
//
//////////////////////////////////////////////////////////////////////////
void CMobile::LocationSector()
{
m_stLocationSector=m_pServiceArea->GetUserSector(m_stMsLocation);
//调用ServiceArea的函数GetUserCell()完成归属扇区的初始化
}
//////////////////////////////////////////////////////////////////////////
//TITLE: InitChannelModel(信道模型初始化函数)
//
//PARAMETERS:慢衰标准差,信道类型
//
//PURPOSE AND ALGORITHMS:
// 调用CchannelModel的初始化函数,完成信道模型的初始化
//
//AUTHOR: Li Jing
//
//CALLING FUNCTIONS:
// CServiceArea::GetCell()
// CChannelModel::Initialization()
//
//////////////////////////////////////////////////////////////////////////
void CMobile::InitChannelModel(float f_inputStdSlowFading,
int i_inputChannelType)
{
for(int i=0;i<19;i++)
for(int j=0;j<SectorNumber;j++)
{
m_aMonitorSector[i*SectorNumber+j].stSectorID.stCellID
=m_pServiceArea->GetCell(m_stLocationSector.stCellID)
->m_aMonitorSector[i*SectorNumber+j]->GetParentCellID();
//移动台监测集中扇区的归属小区标号初始化
m_aMonitorSector[i*SectorNumber+j].stSectorID.s=j+1;
//移动台监测集中扇区标号初始化,扇区的标号是从1到3
}
m_ChannelModel.Initialization(f_inputStdSlowFading,
i_inputChannelType,m_aMonitorSector); //信道模型初始化
}
//////////////////////////////////////////////////////////////////////////
//TITLE: InitMonitorSet(监测扇区信息初始化函数)
//
//PARAMETERS:NULL
//
//PURPOSE AND ALGORITHMS:
// 从移动台归属小区中读出监测扇区的标号,计算路径损耗和天线增益,
// 并通过CchannelModel获得慢衰的初始值,计算出总路径损耗,
// 获得扇区到达移动台的干扰值。完成监测扇区的干扰、功率、信噪比
// 的初始计算,复位定时器等。
// 整个函数流程主要是两次多重循环:
// 第一次循环是计算出每一个监测扇区到移动台的
// fPowerFromTheSector值,并将除了移动台所在的那个扇区之外的20个
// 监测扇区的这个值累加到移动台的m_fInterferenceFromOtherSector值中
// 第二次循环是最终得到各监测扇区的fPilotSNR,并初始化其他一些参数
//
//AUTHOR: Li Jing
//
//CALLING FUNCTIONS:
// CChannelModel::GetFadingValues()
// CServiceArea::GetCell()
// CSector::GetSectorOrientation()
// CServiceArea::GetSector()
// CSector::GetTxPower()
// CSector::GetPilotPower()
// CServiceArea::GetOrthogonalFactor()
// CMobile::ObtainBestSector()
// CServiceArea::GetID()
//
//Notes: CCell.h中要定义CSector* m_aMonitorSector[7*SectorNumber]
// 及LOCATION_TYPE m_aMonitorCellLocation[7]
//
// 有关天线增益的计算公式好像有毛病,弄清楚后再作修改。
//
//////////////////////////////////////////////////////////////////////////
//by zl 20050512
void CMobile::InitMonitorSet()
{
int i,j,k;
float fFastFading; //新增内部参数,快衰值,为四个子时隙的平均
float fPowerSummation;
fPowerSummation=0.0;
float fOtherChannelPower; //本监测扇区除导频信道之外其他信道的干扰值,单位:mw
float fOrthogonalFactor; //正交因子
float fMsBsDistance; //监测扇区的基站和MS的距离,单位是米
float fTempPathLoss; //路径损耗
float fMsxAngel; //移动台、基站的连线与x轴的夹角,范围限制在0到2*PI之间
float fSectorMsAngel; //MS与扇区的夹角,范围-PI到PI
float fTempAngel;
float fTempAntennaGain; //天线增益
CCell* pCell=NULL; //指向监测集中一个小区的指针
LOCATION_TYPE stMonitorCellCor; //监测扇区所属小区的基站坐标
// SECTORID_TYPE sectorid; //新增内部参数,为移动台所在扇区的标号(根据移动台的归属坐标确定)
m_pFadingValuePointer=m_ChannelModel.GetFadingValues(m_iSlotCount);
//获得衰落数组初始值的首地址
pCell=m_pServiceArea->GetCell(m_stLocationSector.stCellID);//获得MS所在小区的指针
for(i=0;i<19;i++) //第一次循环,计算出每一个监测扇区(共21个)到移动台的fPowerFromTheSector值
{
stMonitorCellCor=pCell->m_aMonitorCellLocation[i];
//第i个监测小区的坐标(实际上是BS的坐标)
fMsBsDistance=(float)(sqrt(pow((m_stMsLocation.x
-stMonitorCellCor.x),2)+pow((m_stMsLocation.y
-stMonitorCellCor.y),2)));
//计算第i个相邻BS和MS的直线距离,单位公里
fTempPathLoss=-(float)(28.6+35*log10(1000*fMsBsDistance));
//根据移动台与基站的距离计算路径损耗,单位是dB(此公式引用的是2000平台中的公式)
if(fTempPathLoss>-82.6)
//此处设定的最小路径损耗是-82.6dB,以前最小路径损耗设的是-70dB
fTempPathLoss=(float) -82.6;
fTempPathLoss=(float)pow(10,(fTempPathLoss/10));
//转换为倍数形式
fMsxAngel=(float)(atan2((m_stMsLocation.y-stMonitorCellCor.y),
(m_stMsLocation.x-stMonitorCellCor.x)));
//移动台、监测集中扇区基站的连线与x轴正向的夹角,这样得出的结果范围为-PI到PI
if(fMsxAngel<0)
//将角度的范围转化到0到2*PI
fMsxAngel=(float)(fMsxAngel+2*PI);
for(j=0;j<SectorNumber;j++)
{
m_aMonitorSector[i*SectorNumber+j].fPathLoss=fTempPathLoss;//监测扇区到移动台的路径损耗值初始化
fTempAngel
=(float)(fMsxAngel-pCell->m_aSectorInCell[j].
GetSectorOrientation()*2*PI/360);
//一个小区中3个扇区的朝向分别为60,180,300,并转换为弧度
if(fTempAngel>=PI) //若差值大于等于PI,则换算
fSectorMsAngel=(float)(fTempAngel-2*PI);
else
if(fTempAngel<-PI) //若差值小于-PI,也换算
fSectorMsAngel=(float)(fTempAngel+2*PI);
else
fSectorMsAngel=fTempAngel;
//否则就取此差值作为扇区朝向与MS的夹角
fTempAntennaGain=AntennaGain-20; //天线增益,单位dB
if(12*pow((fSectorMsAngel/(70*2*PI/360)),2)<20)
//公式参考《关于服务区环境模型的一些初步设想》
fTempAntennaGain=(float)(AntennaGain
-12*pow((fSectorMsAngel/(70*2*PI/360)),2));
fTempAntennaGain=(float)pow(10,(fTempAntennaGain/10));
//转换为倍数
m_aMonitorSector[i*SectorNumber+j].fAntennaGain
=fTempAntennaGain; //天线增益初始化
m_aMonitorSector[i*SectorNumber+j].fSlowFading
=m_pFadingValuePointer[i].fSlowFading; //慢衰值初始化
m_aMonitorSector[i*SectorNumber+j].fPropagationLoss
=m_aMonitorSector[i*SectorNumber+j].fPathLoss
*m_aMonitorSector[i*SectorNumber+j].fAntennaGain
*m_aMonitorSector[i*SectorNumber+j].fSlowFading
*(float)pow(10,(MsAntennaGain-OtherLosses)/10);
//得到总的传输损耗值。相对以前多考虑了移动台天线增益和其他损耗
for(k=0;k<SubslotNumber;k++)
m_aMonitorSector[i*SectorNumber+j].fFastFading[k]
=m_pFadingValuePointer[i].fFastFadingSet[j][k];
fFastFading=(m_aMonitorSector[i*SectorNumber+j].fFastFading[0]
+m_aMonitorSector[i*SectorNumber+j].fFastFading[1]
+m_aMonitorSector[i*SectorNumber+j].fFastFading[2]
+m_aMonitorSector[i*SectorNumber+j].fFastFading[3])/(float)4;
//取四个子时隙的快衰值,并求平均
m_aMonitorSector[i*SectorNumber+j].fPowerFromTheSector
=m_pServiceArea
->GetSector(m_aMonitorSector[i*SectorNumber+j].stSectorID)
->GetTxPower()
*m_aMonitorSector[i*SectorNumber+j].fPropagationLoss
*fFastFading;
//监测扇区到达移动台的总功率(干扰)为=发射功率*总的传输损耗
fPowerSummation+=m_aMonitorSector[i*SectorNumber+j].fPowerFromTheSector;
/* //for compile
CStdioFile f;
char buf[50];
// 打开数据文件准备写
if(!f.Open("PowerFromTheSector.txt",CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite))
{
#ifdef _DEBUG
afxDump<<"Unable to open file"<<"\n"; //异常处理
#endif
}
f.SeekToEnd();
_itoa(i*SectorNumber+j,buf,10);
f.WriteString(buf);
f.WriteString("\t");
_gcvt(m_aMonitorSector[i*SectorNumber+j].fPowerFromTheSector,10,buf);;
f.WriteString(buf);
f.WriteString("\n");
//end compile*/
}
}
for(i=0;i<19;i++) //第二次循环,最终得到各监测扇区的fPilotSNR,并初始化其他一些参数。
for(j=0;j<SectorNumber;j++)
{
//上面算出的fPowerSummation值是移动台全部57个监测扇区fPowerFromTheSector
//值的累加,而实际上应该去掉本监测扇区的fPowerFromTheSector值。这样得到的
//才是初始化后的移动台所在监测扇区受到的来自其它扇区的干扰
m_aMonitorSector[i*SectorNumber+j].fInterferenceFromOtherSector
=fPowerSummation-m_aMonitorSector[i*SectorNumber+j].fPowerFromTheSector;
fFastFading=(m_aMonitorSector[i*SectorNumber+j].fFastFading[0]
+m_aMonitorSector[i*SectorNumber+j].fFastFading[1]
+m_aMonitorSector[i*SectorNumber+j].fFastFading[2]
+m_aMonitorSector[i*SectorNumber+j].fFastFading[3])/(float)4;
m_aMonitorSector[i*SectorNumber+j].fPilotPower
=m_pServiceArea
->GetSector(m_aMonitorSector[i*SectorNumber+j].stSectorID)
->GetPilotPower()
*m_aMonitorSector[i*SectorNumber+j].fPropagationLoss
*fFastFading;
//监测扇区到达移动台的导频功率
fOtherChannelPower=m_pServiceArea
->GetSector(m_aMonitorSector[i*SectorNumber+j].stSectorID)
->GetTxPower()*
m_aMonitorSector[i*SectorNumber+j].fPropagationLoss
*fFastFading
-m_aMonitorSector[i*SectorNumber+j].fPilotPower;
//本监测扇区其他信道到达移动台的功率
fOrthogonalFactor=m_pServiceArea->GetOrthogonalFactor();
m_aMonitorSector[i*SectorNumber+j].fPilotSNR
=(float)(m_aMonitorSector[i*SectorNumber+j].fPilotPower
/(fOtherChannelPower/**fOrthogonalFactor*/
+m_aMonitorSector[i*SectorNumber+j].fInterferenceFromOtherSector
+NoisePower)); //本监测扇区到达移动台的SNR
m_aMonitorSector[i*SectorNumber+j].fPilotSNR
=(float)(10*log10(m_aMonitorSector[i*SectorNumber+j].fPilotSNR));//转化为dB值
m_aMonitorSector[i*SectorNumber+j].bIsInActive=false;
//是否在激活集的标志初始化
m_aMonitorSector[i*SectorNumber+j].iStatusTimer=0;
//状态改变记数器初始化
m_aMonitorSector[i*SectorNumber+j].bIsBestSector=false;
//是否是最佳基站初始化
}
ObtainBestSector(); //得到最佳扇区
}
//////////////////////////////////////////////////////////////////////////
//TITLE: InitActiveSet(激活集初始化函数)
//
//PARAMETERS:NULL
//
//PURPOSE AND ALGORITHMS:
// 移动台与最佳扇区进行接纳控制,如果最佳扇区功率充足,最佳扇区就
// 给移动台分配功率,并就将最佳扇区加入到移动台的激活集中
//
//AUTHOR: Li Jing
//
//CALLING FUNCTIONS:
//
//NOTES: 初始化激活集函数与2000的初始化函数有较大的变化。主要是现在移动台只是
// 与最佳扇区进行接纳控制,也就是初始化时移动台最多只是将最佳扇区加入其
// 激活集
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -