📄 cmobile.cpp
字号:
//////////////////////////////////////////////////////////////////////////
// for Evaluation Project //
// Mobile User Team //
// BUPT Radio Research Center //
//////////////////////////////////////////////////////////////////////////
// //
// CMobile.CPP //
// //
//////////////////////////////////////////////////////////////////////////
// //
// 移动台基类CMobile的成员函数的声明 //
// //
// //
// Ref. documents: //
// "1xEV-DV仿真程序类的初步定义" //
// //
// Written by: CAI Qi-ming, ZHANG Ding-ye, //
// DOU Zhong-zhao, ZHANG Xin //
// Rev. date: 20010320 (yyyymmdd) //
// //
// What's NEW: //
// 20010319, include文件"header1.h"变为"systemsim.h",因为文件名 //
// 的可读性原因. by ZhangXin. //
// 20020409
// 1 MobileInitialization()增加一个入口参数,放在参数列表 //
// 最后一位,代表信道类型。
// 2 MobileInitialization()中每个扇区放入规定数量的话音移
// 动台和数据移动台
//////////////////////////////////////////////////////////////////////////
#include "CMobile.h"
#include "iostream.h"
#include "Newran.h"
#include "sys_random.h"
#include "CMsManager.h"
//#include "fstream.h"
//#include "iomanip.h"
//////////////////////////////////////////////////////////////////////////
// 初始化函数 //
// 参数有:ID,MsManager和ServiceArea的指针,运动速度,信道类型。 //
// 同时,调用其它函数,完成其它变量的初始化。 //
//////////////////////////////////////////////////////////////////////////
void CMobile::MobileInitialization(
int i_inputMsID,
CMsManager* p_inputCMsManager,
CServiceArea* p_inputCServiceArea,
float f_inputMsVelocity,
int i_inputChannelType,
float f_inputStdSlowFading,
int i_inputTrafficType)
{
bool bFlag=false; //越界标记
m_iMsID=i_inputMsID; //对MS的ID进行初始化
m_pMsManager=p_inputCMsManager; //MsManager指针初始化
m_pServiceArea=p_inputCServiceArea; //ServiceArea指针初始化
//...... modified by cqm, Apr.9 ......//
m_iSlotCount=1; //Slot记数器,设为1是因为VoiceProcess()从slot 1开始运行的
//....................................//
m_fStdSlowFading=f_inputStdSlowFading;//慢衰标准差
m_nChannelType=i_inputChannelType;
m_fMsVelocity=f_inputMsVelocity;
while (!bFlag)
{
LocationGenerator(); //对MS的位置坐标进行初始化
LocationSector(); //对MS的归属扇区标号进行初始化
if ((m_stLocationSector.stCellID.m==3)&&
(m_stLocationSector.stCellID.n==3))
{
//......modified by cqm, Apr.9 .......//
switch(i_inputTrafficType)
{
//如果在(3,3)小区
case Voice : switch(m_stLocationSector.s)//产生话音用户
{
case 1: //m_pMsManager->m_iVoiceNumGenerated[0]++;//记录生成的话音用户数
if(m_pMsManager->m_iVoiceNumGenerated[0]<m_pMsManager->m_iVoiceNumPerSector)//如果话音用户数目没有超标
{
m_pMsManager->m_iVoiceNumGenerated[0]++;//记录生成的话音用户数
bFlag=true; //该用户有效,标志位置为真
(m_pServiceArea->GetSector(m_stLocationSector)->m_iNumOfSector)++;//该扇区总用户数加一
}
break;//中断循环
case 2: //m_pMsManager->m_iVoiceNumGenerated[1]++;//记录生成的话音用户数
if(m_pMsManager->m_iVoiceNumGenerated[1]<m_pMsManager->m_iVoiceNumPerSector)//如果话音用户数目没有超标
{
m_pMsManager->m_iVoiceNumGenerated[1]++;//记录生成的话音用户数
bFlag=true; //该用户有效,标志位置为真
(m_pServiceArea->GetSector(m_stLocationSector)->m_iNumOfSector)++;//该扇区总用户数加一
}
break;//中断循环
case 3: //m_pMsManager->m_iVoiceNumGenerated[2]++;//记录生成的话音用户数
if(m_pMsManager->m_iVoiceNumGenerated[2]<m_pMsManager->m_iVoiceNumPerSector)//如果话音用户数目没有超标
{
m_pMsManager->m_iVoiceNumGenerated[2]++;//记录生成的话音用户数
bFlag=true; //该用户有效,标志位置为真
(m_pServiceArea->GetSector(m_stLocationSector)->m_iNumOfSector)++;//该扇区总用户数加一
}
break;//中断循环
default:
break;
}
break;
case Data : switch(m_stLocationSector.s)//产生数据用户
{
case 1: m_pMsManager->m_iDataNumGenerated[0]++;//记录生成的数据用户数
if(m_pMsManager->m_iDataNumGenerated[0]<=m_pMsManager->m_iDataNumPerSector)//如果数据用户数目没有超标
{
bFlag=true; //该用户有效,标志位置为真
(m_pServiceArea->GetSector(m_stLocationSector)->m_iNumOfSector)++;//该扇区总用户数加一
}
break;//中断循环
case 2: m_pMsManager->m_iDataNumGenerated[1]++;//记录生成的数据用户数
if(m_pMsManager->m_iDataNumGenerated[1]<=m_pMsManager->m_iDataNumPerSector)//如果数据用户数目没有超标
{
bFlag=true; //该用户有效,标志位置为真
(m_pServiceArea->GetSector(m_stLocationSector)->m_iNumOfSector)++;//该扇区总用户数加一
}
break;//中断循环
case 3: m_pMsManager->m_iDataNumGenerated[2]++;//记录生成的数据用户数
if(m_pMsManager->m_iDataNumGenerated[2]<=m_pMsManager->m_iDataNumPerSector)//如果数据用户数目没有超标
{
bFlag=true; //该用户有效,标志位置为真
(m_pServiceArea->GetSector(m_stLocationSector)->m_iNumOfSector)++;//该扇区总用户数加一
}
break;//中断循环
default:
break;
}
break;
}
}
}
InitChannelModel(f_inputStdSlowFading,i_inputChannelType); //对MS的信道模型数据进行初始化
InitNeighborSet(); //根据MS的归属扇区对相邻扇区数组成员数据进行初始化
InitCadidateSet(); //根据MS的归属扇区以及相邻扇区数据对候选扇区数组进行初始化
}
//end of MobileInitialization()
//////////////////////////////////////////////////////////////////////////
// 坐标生成函数 //
// 随机产生移动台的坐标 //
//////////////////////////////////////////////////////////////////////////
void CMobile::LocationGenerator()
{
#ifdef UNIFORMITY
m_stMsLocation.x
=xUniform((float)sqrt(3)*m_pServiceArea->GetSiteDistance(),(float)(5*m_pServiceArea->GetSiteDistance()
/sqrt(3))); //产生的移动台的坐标服从均匀分布(只针对(3.3)的小区)
m_stMsLocation.y
=xUniform((float)2*m_pServiceArea->GetSiteDistance(),(float)(3*m_pServiceArea->GetSiteDistance()));
#endif
//..............................Modified By hj, July,11,2003 ...............................//
//移动台撒在以BS为中心的圆上(只针对(3.3)的小区)
#ifdef R1
float m_stMsRadius=(float)0.9*m_pServiceArea->GetSiteDistance()/2; //半径R定义为小区间距的一半,移动台分布半径分别为0.9R,0.5R,0.1R移动台分布半径
float m_stMsCentreAngle=xUniform((float)0.0,(float)2*PI); //随机生成移动台圆心角,圆心角在0到2PI之间均匀分布
m_stMsLocation.x=(float)(4*m_pServiceArea->GetSiteDistance()/sqrt(3)+m_stMsRadius*cos(m_stMsCentreAngle));
m_stMsLocation.y=(float)(2.5*m_pServiceArea->GetSiteDistance()+m_stMsRadius*sin(m_stMsCentreAngle));
#endif
#ifdef R2
float m_stMsRadius=(float)0.5*m_pServiceArea->GetSiteDistance()/2; //半径R定义为小区间距的一半,移动台分布半径分别为0.9R,0.5R,0.1R移动台分布半径
float m_stMsCentreAngle=xUniform((float)0.0,(float)2*PI); //随机生成移动台圆心角,圆心角在0到2PI之间均匀分布
m_stMsLocation.x=(float)(4*m_pServiceArea->GetSiteDistance()/sqrt(3)+m_stMsRadius*cos(m_stMsCentreAngle));
m_stMsLocation.y=(float)(2.5*m_pServiceArea->GetSiteDistance()+m_stMsRadius*sin(m_stMsCentreAngle));
#endif
#ifdef R3
float m_stMsRadius=(float)0.1*m_pServiceArea->GetSiteDistance()/2; //半径R定义为小区间距的一半,移动台分布半径分别为0.9R,0.5R,0.1R移动台分布半径
float m_stMsCentreAngle=xUniform((float)0.0,(float)2*PI); //随机生成移动台圆心角,圆心角在0到2PI之间均匀分布
m_stMsLocation.x=(float)(4*m_pServiceArea->GetSiteDistance()/sqrt(3)+m_stMsRadius*cos(m_stMsCentreAngle));
m_stMsLocation.y=(float)(2.5*m_pServiceArea->GetSiteDistance()+m_stMsRadius*sin(m_stMsCentreAngle));
#endif
//.............................................................................................//
}
//end of LocationGenerator()
//////////////////////////////////////////////////////////////////////////
// 归属扇区确定函数 //
// 通过调用ServiceArea中的函数获得 //
//////////////////////////////////////////////////////////////////////////
void CMobile::LocationSector()
{
m_stLocationSector=m_pServiceArea->GetUserCell(m_stMsLocation); //调用ServiceArea的函数GetUserCell()完成归属扇区的初始化
}
//end of LocationSector()
//////////////////////////////////////////////////////////////////////////
// 信道模型初始化函数 //
// 调用CchannelModel的初始化函数,完成信道模型的初始化 //
//////////////////////////////////////////////////////////////////////////
void CMobile::InitChannelModel(float f_inputStdSlowFading,
int i_inputChannelType)
{ //定义必要的变量
int i,j; //循环变量
for(i=0;i<19;i++)
for(j=0;j<SectorNumber;j++)
{
m_aNeighborSector[i*SectorNumber+j].stSectorID.stCellID
=m_pServiceArea->GetCell(m_stLocationSector.stCellID)
->m_aNeighborCell[i]->m_stCellID;
//相邻扇区集的小区标号初始化
m_aNeighborSector[i*SectorNumber+j].stSectorID.s=j+1;
//相邻扇区集的扇区标号初始化,扇区的标号是从1到3
}
m_ChannelModel.Initialization(f_inputStdSlowFading,
i_inputChannelType,m_aNeighborSector); //信道模型初始化
}
//end of InitChannelModel()
//////////////////////////////////////////////////////////////////////////
// 相邻扇区信息初始化函数 //
// 从归属小区中读出相邻扇区的标号,计算路径损耗和天线增益, //
// 并通过CchannelModel获得快衰和慢衰的初始值,计算出总路径损耗, //
// 获得扇区到达移动台的干扰值。 //
//////////////////////////////////////////////////////////////////////////
void CMobile::InitNeighborSet()
{ //定义必要的变量
int i,j,k;
float fMsBsDistance; //基站和MS的距离,单位是米
float fTempPathLoss; //路径损耗
float fMsxAngel; //MS与x轴的夹角,范围0到2*PI
float fSectorMsAngel; //MS与扇区的夹角,范围-PI到PI
float fTempAngel;
float fTempAntennaGain; //天线增益
CCell* pCell=NULL; //指向相邻集中一个小区的指针
LOCATION_TYPE stNeighborCellCor; //邻小区基站坐标
m_pFadingValuePointer=m_ChannelModel.GetFadingValues(m_iSlotCount); //获得衰落数组(初始值)的首地址
pCell=m_pServiceArea->GetCell(m_stLocationSector.stCellID);
//获得MS所在小区的指针
for(i=0;i<19;i++) //循环19次(相邻a集小区的个数)
{
stNeighborCellCor=pCell->m_aNeighborCellLocation[i]; //第i个邻小区的坐标(实际上是BS的坐标)
fMsBsDistance=(float)(sqrt(pow((m_stMsLocation.x
-stNeighborCellCor.x),2)+pow((m_stMsLocation.y
-stNeighborCellCor.y),2))); //计算BS和MS的直线距离
fTempPathLoss=-(float)(28.6+35*log10(1000*fMsBsDistance));
//计算路径损耗,单位是dB(参考C50-20000918-011,
//"Evaluation Methods for High Speed Forward Link Packet Access,"
//September 20, 2000.)
if(fTempPathLoss>-82.6) //最小路径损耗是-82.6dB
fTempPathLoss=(float)-82.6;
fTempPathLoss=(float)pow(10,(fTempPathLoss/10));
//转换为倍数
fMsxAngel=(float)(atan2((m_stMsLocation.y-stNeighborCellCor.y),
(m_stMsLocation.x-stNeighborCellCor.x)));
//MS与x轴的夹角,范围-PI到PI
if(fMsxAngel<0)
//将角度的范围转化到0到2*PI
fMsxAngel=(float)(fMsxAngel+2*PI);
for(j=0;j<SectorNumber;j++)
{
m_aNeighborSector[i*SectorNumber+j].fPathLoss=fTempPathLoss; //小区的路径损耗值初始化
fTempAngel
=(float)(fMsxAngel-pCell->m_aSectorInCell[j].
GetSectorOrientation()*2*PI/360); //转化为弧度来算
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_aNeighborSector[i*SectorNumber+j].fAntennaGain
=fTempAntennaGain; //天线增益初始化
m_aNeighborSector[i*SectorNumber+j].fSlowFading
=m_pFadingValuePointer[i].fSlowFading; //慢衰值初始化
for(k=0;k<SubslotNumber;k++)
m_aNeighborSector[i*SectorNumber+j].fFastFading[k]
=m_pFadingValuePointer[i].fFastFadingSet[j][k];
m_aNeighborSector[i*SectorNumber+j].fPropagationLoss
=m_aNeighborSector[i*SectorNumber+j].fPathLoss
*m_aNeighborSector[i*SectorNumber+j].fAntennaGain
*m_aNeighborSector[i*SectorNumber+j].fSlowFading
*(float)pow(10,(MsAntennaGain-OtherLosses)/10);
//总的损耗值
m_aNeighborSector[i*SectorNumber+j].fPowerFromTheSector
=m_pServiceArea
->GetSector(m_aNeighborSector[i*SectorNumber+j].stSectorID)
->GetTxPower()
*m_aNeighborSector[i*SectorNumber+j].fPropagationLoss
*(m_aNeighborSector[i*SectorNumber+j].fFastFading[0]
+m_aNeighborSector[i*SectorNumber+j].fFastFading[1]
+m_aNeighborSector[i*SectorNumber+j].fFastFading[2]
+m_aNeighborSector[i*SectorNumber+j].fFastFading[3])/(float)4;
//扇区到达移动台的总功率为=发射功率*总的损耗
}
}
}
//end of InitNeighborSet()
//////////////////////////////////////////////////////////////////////////
// 候选扇区信息初始化函数 //
// 从归属小区读出候选扇区的标号,确定自己的相邻扇区在 //
// 相邻扇区信息数组中的相对位置(数组下标),完成干扰、 //
// 功率、信噪比的初始计算,复位定时器。 //
//////////////////////////////////////////////////////////////////////////
void CMobile::InitCadidateSet()
{ //定义必要的变量
int i,j,k,m; //循环变量
float fOtherChannelPower; //其他信道的干扰值,单位:mw
float fOrthogonalFactor; //正交因子
float fFastFading; //快衰(四个子时隙的算术平均)
CCell* pMsCell=NULL; //移动台所在小区指针
CELLID_TYPE stTempCell; //临时小区结构体
for(i=0;i<6+SectorNumber;i++) //第i个候选扇区
{
k=0;
m_aCandidateSector[i].fInterferenceFromOtherSector=0;
//初始化从其他扇区来的干扰值
pMsCell=m_pServiceArea->GetCell(m_stLocationSector.stCellID);
//得到MS所在的小区
m_aCandidateSector[i].stSectorID.stCellID
=pMsCell->m_aCandidateSector[i]->GetParentCellID();
//将属性中的候选扇区的标号初始化
m_aCandidateSector[i].stSectorID.s
=pMsCell->m_aCandidateSector[i]->GetSectorIndex();
for(j=0;j<19*SectorNumber;j++)
{
if((m_aCandidateSector[i].stSectorID.stCellID.m
==m_aNeighborSector[j].stSectorID.stCellID.m)
&&(m_aCandidateSector[i].stSectorID.stCellID.n
==m_aNeighborSector[j].stSectorID.stCellID.n)
&&(m_aCandidateSector[i].stSectorID.s
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -