⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cvoicems.cpp

📁 这是cdma2000的一个分组调度算法实例
💻 CPP
📖 第 1 页 / 共 4 页
字号:
										//bIsAdd置为true(实际上是加入)
										pTempSHOMsg->iCandidateIndex=i; 
										//将当前扇区下标赋予iCandidateIndex
										pTempSHOMsg->iWaitTime=
											m_pMsManager->m_iSoftHandoffDelay;
										//软切换的时延为0.2s(转换为slot数)
										pTempSHOMsg->stTargetSector=
											m_aCandidateSector[i].stSectorID;
										//需要加入的目标扇区为当前扇区
										m_SoftHandoffMessageList.AddTail(pTempSHOMsg);
										//将产生的软切换消息加入队列
										m_iSHOMsgNum++;       
										//更新属性中的软切换消息队列长度

										m_aCandidateSector[i].bIsInActive=true;
										//是否在激活集中的标志置为true
										m_aCandidateSector[i].iStatusTimer=0;
										//状态改变计数器清零
										iLogicActiveSize++; 
										//逻辑激活集队列长度加一
									}
									//.......................................//
								}
							}
						}
						else     
						//如果最佳扇区的导频信噪比与当前扇区的导频信噪比之差
						//大于软切换加入的门限值
							m_aCandidateSector[i].iStatusTimer=0; 
							//当前扇区的状态改变计数器清零
		}
	}
}
//end of SHOMsgGenerator()


//////////////////////////////////////////////////////////////////////////
//							消息队列处理函数							//
//		完成每个时隙内消息等待时间递减的功能,并返回到时消息的数量。    //
//////////////////////////////////////////////////////////////////////////
int    CVoiceMs::SHOMsgProcess()
{                                           //定义必要的变量
	int iTimeoutSHOMsgNum=0;                //超时的软切换消息数
	POSITION posTemp;                       //临时位置指针
	SOFTHANDOFFMESSAGE_TYPE* pSHOMsg=NULL;  //软切换消息指针


	if(m_SoftHandoffMessageList.IsEmpty())   //如果链表为空
		return iTimeoutSHOMsgNum;            //直接返回到时消息数量
	else
	{
		posTemp=m_SoftHandoffMessageList.GetHeadPosition(); 
		//取得链表头,并令临时指针指向链表头
		while(posTemp!=NULL)                 //到达链表尾则结束循环
		{
			pSHOMsg=m_SoftHandoffMessageList.GetAt(posTemp); 
			//获得链表中的一个软切换消息结构			
			pSHOMsg->iWaitTime--;            //等待时长减一(以时隙为单位)
			if(pSHOMsg->iWaitTime<=0)        //如果iWaitTime小于等于0
			{
				pSHOMsg->iWaitTime=0;        //iWaitTime置为0
				iTimeoutSHOMsgNum++;         //到时的SHOMsg数量加一
			}
			m_SoftHandoffMessageList.GetNext(posTemp);       
			//获得链表的下一个软切换消息结构
		}
		return iTimeoutSHOMsgNum;            //返回iTimeoutSHOMsgNum值
	}
}
//end of SHOMsgProcess()


//////////////////////////////////////////////////////////////////////////
//							 激活集变更函数								//
//			根据消息处理函数的返回值,读出相应的软切换消息,			//
//                     根据该消息完成相应的操作,						//
//			去掉:直接从链表中删除,加入:加入新的激活信息结构体,		//
//						并初始化各个变量。								//
//////////////////////////////////////////////////////////////////////////
void   CVoiceMs::ChangeActiveSet()
{                                      //定义必要的变量
	int iTargetSectorIndex;            //目标扇区在候选集中的下标
	int j;                             //循环变量
	int iTempIndex;                    //临时下标
	float fC2ITarget;                  //目标C/I
	float fOrthogonalFactor;           //正交因子
	float fOtherChannelPower;          //其他信道干扰,单位:mw
	float fMaxTrafficPower;            //最大业务信道功率,单位:mw
	float fTempTrafficPower;           //临时业务信道功率,单位:mw
	float fMinTrafficPower;            //最小业务信道功率,单位:mw
	float fFastFading;
	//...... added by cqm, Apr.25 ......//
	Random R;
	float fRand;
	//..................................//
	SOFTHANDOFFMESSAGE_TYPE* pSHOMsg=NULL;    //软切换消息指针
	POSITION posSHOMsg1,posSHOMsg2,posActive1,posActive2;
	//所用到的位置指针
	CSector* pTargetSector=NULL;              //目标扇区指针
	ACTIVESECTOR_TYPE* pTempActiveSector=NULL;//临时激活扇区指针


	posSHOMsg1=posSHOMsg2=m_SoftHandoffMessageList.GetHeadPosition();
	//两个位置变量同时指向链表头
	while(posSHOMsg1!=NULL)                 //到链表尾则结束循环
	{
		pSHOMsg=m_SoftHandoffMessageList.GetAt(posSHOMsg1);              
		//获得一个软切换消息指针
		pTargetSector=m_pServiceArea->GetSector(pSHOMsg->stTargetSector);
		//得到目标扇区指针
		iTargetSectorIndex=pSHOMsg->iCandidateIndex;      
		//获得目标扇区在候选集中的下标
		m_SoftHandoffMessageList.GetNext(posSHOMsg2);    
		//posSHOMsg2指向链表中的下一个元素

		if(pSHOMsg->iWaitTime==0)            //如果软切换消息到时
		{
			if(pSHOMsg->bIsAdd)              //如果消息类型是加入            
			{
				//...... added by cqm, Apr.25 ......//
				if((pSHOMsg->stTargetSector.stCellID.m!=3)||(pSHOMsg->stTargetSector.stCellID.n!=3))
				{//如果切换到了周围小区
					fRand=R.Next();
					if(fRand>=0.05)
					{
						m_iServiceLength=16;//模拟软切换成功,认为服务时间到时(需要重新初始化一个话音用户)
						m_bIsSHOOut=true;
					}


					delete m_SoftHandoffMessageList.GetAt(posSHOMsg1);    
					//删除当前的软切换消息
					m_SoftHandoffMessageList.RemoveAt(posSHOMsg1);
					//移去位置指针
					posSHOMsg1=posSHOMsg2;    
					//指针指向链表中下一个软切换消息
					m_iSHOMsgNum--;      
					//软切换消息队列长度减一
				}
				//.................................//
				else//如果切换到了中心小区
				{
					if(!pTargetSector->IsTransmiting())    
					//如果目标扇区没有数据正在传输
					{
						fMaxTrafficPower
							=m_pMsManager->m_fMaxFractionOfTrafficPower
							*m_pServiceArea->GetSector(pSHOMsg->stTargetSector)->
							GetMaxPower();  
						//计算业务信道最大功率
						//(为最大发射功率乘以最大业务信道所占的最大比例)
						for(j=0;j<19*SectorNumber;j++)    
						//对相邻集中的扇区进行循环
							if((m_aNeighborSector[j].stSectorID.stCellID.m
								==m_aCandidateSector[iTargetSectorIndex].stSectorID.stCellID.m)
								&&(m_aNeighborSector[j].stSectorID.stCellID.n
								==m_aCandidateSector[iTargetSectorIndex].stSectorID.stCellID.n)
								&&(m_aNeighborSector[j].stSectorID.s
								==m_aCandidateSector[iTargetSectorIndex].stSectorID.s))  
							//找到当前候选扇区在相邻集中的位置
							{
								switch(m_iFwdFrameRate)
								{
									case FULL_RATE : fC2ITarget=(float)pow(10,(/*m_pMsManager->*/m_fC2ITarget/10));
										break;
									case HALF_RATE : fC2ITarget=(float)pow(10,((/*m_pMsManager->*/m_fC2ITarget-(float)3)/10));
										break;
									case QUARTER_RATE : fC2ITarget=(float)pow(10,((/*m_pMsManager->*/m_fC2ITarget-(float)6)/10));
										break;
									case EIGHTH_RATE : fC2ITarget=(float)pow(10,((/*m_pMsManager->*/m_fC2ITarget-(float)9)/10));
										break;
								}
							//	fC2ITarget=(float)pow(10,(m_pMsManager->m_fC2ITarget/10));
								fOrthogonalFactor=m_pServiceArea->GetOrthogonalFactor();
								fFastFading=(m_aNeighborSector[j].fFastFading[0]
									+m_aNeighborSector[j].fFastFading[1]
									+m_aNeighborSector[j].fFastFading[2]
									+m_aNeighborSector[j].fFastFading[3])/(float)4;
								fOtherChannelPower=
									m_pServiceArea->GetSector(pSHOMsg->stTargetSector)->
									GetTxPower()*m_aNeighborSector[j].fPropagationLoss*fFastFading;
								fTempTrafficPower=
									(float)(fC2ITarget*
									(m_aCandidateSector[iTargetSectorIndex].fInterferenceFromOtherSector
									+fOtherChannelPower*fOrthogonalFactor
									+NoisePower)
									/(m_aNeighborSector[j].fPropagationLoss*fFastFading));
									//业务信道功率赋初值,公式参考UpAndDown里的公式
								if(fTempTrafficPower>fMaxTrafficPower)  
								//如果算出来的功率大于功率最大值
									fTempTrafficPower=fMaxTrafficPower;
									//则将业务信道功率赋最大值
								fMinTrafficPower=
									(float)(fMaxTrafficPower
									/pow(10,(m_pMsManager->m_fDynamicRangeOfTrafficPower/10)));
								//将dB转化为mw
								if(fTempTrafficPower<fMinTrafficPower)            //如果业务信道功率小于动态范围
									fTempTrafficPower=fMinTrafficPower;           //就将业务信道功率置为最小值(动态范围)
								if(pTargetSector->GetMaxPower()
									-pTargetSector->GetTxPower()>=
									fTempTrafficPower)
//wgt
//								if(pTargetSector->GetMaxPower()
//									-pTargetSector->GetTxPower1()>=
//									fTempTrafficPower)

								//如果剩余的功率比所许要的业务信道功率大
								{
									pTempActiveSector=new ACTIVESECTOR_TYPE;
									//产生一个新的软切换消息
									pTempActiveSector->fTrafficPower=fTempTrafficPower;  
									//激活扇区业务信道功率赋初值
									pTempActiveSector->fTrafficC2I=(float)(10*log10(fC2ITarget));
									//激活扇区业务信道C/I先置为零
									pTempActiveSector->iIndexInCandidate=iTargetSectorIndex; 
									//激活扇区在候选集中的下标赋初值
									pTempActiveSector->stSectorID=pSHOMsg->stTargetSector;   
									//激活扇区的扇区标号赋初值
									m_ActiveSetList.AddTail(pTempActiveSector);           
									//将生成的激活扇区加入激活集
									//...... added by cqm, May.10 ......//
									m_iActiveSetSize++;
									//..................................//
//wgt
//									pTargetSector->SetTxPower1(pTargetSector->GetTxPower1()+fTempTrafficPower);
//将该话音用户所需要的功率累加到m_fTxPower1								

									delete m_SoftHandoffMessageList.GetAt(posSHOMsg1);    
									//删除当前的软切换消息
									m_SoftHandoffMessageList.RemoveAt(posSHOMsg1);
									//移去位置指针
									posSHOMsg1=posSHOMsg2;    
									//指针指向链表中下一个软切换消息
									m_iSHOMsgNum--;      
									//软切换消息队列长度减一
								}
								else  //如果剩余的功率比所许要的业务信道功率小
								{
									delete m_SoftHandoffMessageList.GetAt(posSHOMsg1);
									//删除当前的软切换消息
									m_SoftHandoffMessageList.RemoveAt(posSHOMsg1);   
									//移去位置指针
									posSHOMsg1=posSHOMsg2;   
									//指针指向链表中下一个软切换消息
									m_iSHOMsgNum--;      
									//软切换消息队列长度减一
								}
								break;
							}
					}
					else//如果目标扇区有数据传输
						posSHOMsg1=posSHOMsg2;//指针指向链表中下一个软切换消息
				}
			}
			else                 //如果消息类型是去掉
			{
				posActive1=posActive2=m_ActiveSetList.GetHeadPosition(); 
				//两个位置变量同时指向链表头
				while(posActive1!=NULL)           //到链表尾则结束循环
				{
					m_ActiveSetList.GetNext(posActive2);       
					//posActive2指向链表中的下一个元素
					iTempIndex=m_ActiveSetList.GetAt(posActive1)->iIndexInCandidate;
					//获得当前激活集在候选集中的下标
					if(iTempIndex==iTargetSectorIndex)
					//如果当前激活扇区是目标扇区
					{
						delete m_ActiveSetList.GetAt(posActive1);   
						//删除当前的激活扇区
						m_ActiveSetList.RemoveAt(posActive1);    
						//移去指针
						//...... added by cqm, May.10 ......//
						m_iActiveSetSize--;
						//..................................//
					}
					posActive1=posActive2;   
					//指针指向链表中下一个激活扇区
				}
						
				delete m_SoftHandoffMessageList.GetAt(posSHOMsg1);
				//删除当前的软切换消息
				m_SoftHandoffMessageList.RemoveAt(posSHOMsg1); 
				//移去指针
				posSHOMsg1=posSHOMsg2;          
				//指针指向链表中下一个软切换消息
				m_iSHOMsgNum--;           
				//软切换消息队列长度减一
			}
		}
		else                            //如果软切换消息未到时
			posSHOMsg1=posSHOMsg2;      //指针指向链表中下一个软切换消息
	}
}
//end of ChangeActiveSet()


//////////////////////////////////////////////////////////////////////////
//							激活集更新函数,								//
//			根据候选集更新的情况,计算业务信道的信噪比					//
//		在每个时隙中均需调用,激活集初始化和变更之后也需调用			//
//////////////////////////////////////////////////////////////////////////
void   CVoiceMs::UpdateActiveSet()
{                                          //定义必要的变量
	int iTempIndex;                        //临时下标
	int i;                                 //循环变量
//	bool  bIsLastActive;
	float fOtherSectorInterference;        //从别的扇区来的干扰
	float fOtherChannelInterference;       //从别的信道来的干扰
	float fTrafficPower;                   //业务信道功率
	float fOrthogonalFactor;               //正交因子
	float fFastFading;
	POSITION posTemp;                      //临时位置指针
	ACTIVESECTOR_TYPE* pTempActiveSector=NULL;  //临时激活扇区


//	bIsLastActive=m_bIsServiceActive;  //保存上一个时隙的激活标志
//	SetVoiceActivity();                //设置本slot话音激活标志
	posTemp=m_ActiveSetList.GetHeadPosition();
	//取得链表头,并令临时指针指向链表头
	while(posTemp!=NULL)               //到达链表尾则结束循环
	{
		pTempActiveSector=m_ActiveSetList.GetAt(posTemp); 
		//获得当前的激活扇区
		iTempIndex=pTempActiveSector->iIndexInCandidate;  
		if((m_aCandidateSector[iTempIndex].fPilotSNR<-16)&&(m_iActiveSetSize==1)&&(m_bIsSHOOut))//test by cqm
		{
			m_iServiceLength=80;//认为掉话
			m_bIsSHOOut=true;
		}
		//获得该扇区在候选集中的下标
		fOtherSectorInterference=
			m_aCandidateSector[iTempIndex].fInterferenceFromOtherSector;
		//获得从其他扇区来的干扰
		fOrthogonalFactor=m_pServiceArea->GetOrthogonalFactor();    
		//获得正交因子
		fOtherChannelInterference=m_pServiceArea->GetSector(pTempActiveSector->stSectorID)->GetTxPower()
			-pTempActiveSector->fTrafficPower;
//		if(m_iMsID==18)
//			cout<<m_pServiceArea->GetSector(pTempActiveSector->stSectorID)->GetTxPower()<<endl;



		for(i=0;i<19*SectorNumber;i++)        //对相邻扇区集进行循环
		{
			if((pTempActiveSector->stSectorID.s
				==m_aNeighborSector[i].stSectorID.s)
				&&(pTempActiveSector->stSectorID.stCellID.m
				==m_aNeighborSector[i].stSectorID.stCellID.m)
				&&(pTempActiveSector->stSectorID.stCellID.n
				==m_aNeighborSector[i].stSectorID.stCellID.n))  
			//找到当前扇区在相邻集中的位置
			{
				fFastFading=(m_aNeighborSector[i].fFastFading[0]
					+m_aNeighborSector[i].fFastFading[1]
					+m_aNeighborSector[i].fFastFading[2]
					+m_aNeighborSector[i].fFastFading[3])/(float)4;
				pTempActiveSector->fTrafficPower=pTempActiveSector->fTrafficPower
					*m_fFwdCurrentActiveFactor/m_fFwdLastActiveFactor;
				//...... added by cqm ......//
				if(pTempActiveSector->fTrafficPower>m_pServiceArea->GetSector(pTempActiveSector->stSectorID)->GetMaxPower()*m_pMsManager->m_fMaxFractionOfTrafficPower)
					pTempActiveSector->fTrafficPower=m_pServiceArea->GetSector(pTempActiveSector->stSectorID)->GetMaxPower()*m_pMsManager->m_fMaxFractionOfTrafficPower;
				fTrafficPower=pTempActiveSector->fTrafficPower
					*m_aNeighborSector[i].fPropagationLoss*fFastFading;
				//............//
				//计算MS接收到的业务信道功率
//				fOtherChannelInterference=m_pServiceArea->GetSector(pTempActiveSector->stSectorID)->GetTxPower()
//					-pTempActiveSector->fTrafficPower;
				fOtherChannelInterference*=
					m_aNeighborSector[i].fPropagationLoss*fFastFading;  
				//计算本扇区从其他信道来的干扰值
				break;
			}
		}
		pTempActiveSector->fTrafficC2I=
				(float)(10*log10(fTrafficPower
				/(fOtherChannelInterference*fOrthogonalFactor
				+fOtherSectorInterference+NoisePower)));  
			//计算实际的C/I

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -