optimize.c

来自「一整套电梯控制器源程序」· C语言 代码 · 共 971 行 · 第 1/3 页

C
971
字号
	}
}

//返回:0xFF--无电梯可以分配
//		0x00至0x07--正确的返回值
uchar WashOut_LargerIndexEle(uchar *pWashOutFlg)
{
	uchar m_cENum = m_pL_Data->cENum;
	uchar cPRINo_min = 0xFF;	//初始时,设置电梯优先级号足够大
	uchar cPRINo = 0;
	uchar i=0;
	uchar j=0;
	uchar cBestIdx=0xFF;

	for(i=0; i<m_cENum; i++){
		if(pWashOutFlg[i] == 0){
			//取得电梯优先级号
			cPRINo = m_InterData[i].cPRINo;
			if(cPRINo<cPRINo_min){			//出现新最小
				//更新最小
				cPRINo_min = cPRINo;
				//!!!最优电梯诞生
				cBestIdx = i;
				//确保淘汰前面的电梯
				for(j=0; j<i; j++){
					if(pWashOutFlg[j] == 0)
						pWashOutFlg[j] = 1;
				}
			}else if(cPRINo == cPRINo_min){	//与前次相同
				//do nothing 
			}else{							//出现更大
				//设置淘汰标记
				pWashOutFlg[i] = 1;
			}
		}
	}

	return cBestIdx;
}

//更新外呼分配数据
void UpdateDistribution(uchar cLIdx, uchar updown_flg, uchar cBestEleNo)
{
	E_XiangYing *pXiangYing = 0;
	uchar m_cENum = m_pL_Data->cENum;
	uchar i=0;

	for(i=0; i<m_cENum; i++){
		pXiangYing = &(m_pE_OutputData->mXiangYing[i]);
		if(updown_flg == D_Up){
			if(i != cBestEleNo)
//				pXiangYing->bShang[cLIdx] = 0;	//确保撤销原有分配
				SetArrayData(pXiangYing->bShang, cLIdx, 0);
			else
//				pXiangYing->bShang[cLIdx] = 1;	//将该外呼分配给最优电梯
				SetArrayData(pXiangYing->bShang, cLIdx, 1);
		}else{
			if(i != cBestEleNo)
//				pXiangYing->bXia[cLIdx] = 0;	//确保撤销原有分配
				SetArrayData(pXiangYing->bXia, cLIdx, 0);
			else
//				pXiangYing->bXia[cLIdx] = 1;	//将该外呼分配给最优电梯
				SetArrayData(pXiangYing->bXia, cLIdx, 1);
		}
	}	
}

//静态停靠时,更新内选数据
void UpdateStaticStopDistribution(uchar cLIdx, uchar cBestEleNo)
{
	E_DianTi    *pEleData = 0;
	E_WaiHu		*pWaiHu = &(m_pE_InputData->mWaiHu);
	uchar m_cENum = m_pL_Data->cENum;
	uchar i=0;

//	for(i=0; i<m_cENum; i++){
		pEleData   = &(m_pE_InputData->mDianTi[cBestEleNo]);
		//设置内选数据
		SetArrayData(pEleData->bNeiXuan, cLIdx, 1);
		//确保撤销"人为设定外呼"
		SetArrayData(pWaiHu->bShang, cLIdx, 0);
		SetArrayData(pWaiHu->bXia, cLIdx, 0);
//	}	
}

//第cEIdx部电梯响应第cLIdx层外呼所需要的时间(单位:十分之一秒)
//参数:cEIdx--电梯索引
//		cLIdx--外呼楼层数
//		updown_flg--外呼的方向(1:上 0:下)
uint GetEleToFloorTime(uchar cEIdx, uchar cLIdx, uchar updown_flg)
{
	E_DianTi	*pEleData	= &(m_pE_InputData->mDianTi[cEIdx]);
	E_FangXiang	*pFangXiang = &(pEleData->FangXiang);
	E_Men		*pMen		= &(pEleData->Men);
	E_MenTime	*pMenTime	= &(pEleData->MenTime);
	uchar cTopFloor		= pEleData->cZuiGaoCeng-1;	//可到最高层(-1是因为楼层计数从1开始)
	uchar cBottomFloor	= pEleData->cZuiDiCeng-1;	//可到最底层(-1是因为楼层计数从1开始)

	uchar cNextStopLIdx=0xFE;	//下一停靠层索引(0xFF代表搜索完毕)
	uchar cCurFloorIdx  = pEleData->cDangQianCeng-1;
	uchar cStartFloorIdx= pEleData->cDangQianCeng-1;
	uchar cCanStopFloorCnt= pEleData->cZuiGaoCeng - pEleData->cZuiDiCeng;
	uint  time=0;				//时间
	uchar  bStartDirect=0;		//初始搜索方向
	uchar  bDirect=0;			//搜索方向(1:上   0:下)
	uchar  bEnd=0;				//搜索结束标记(1:结束 0:未结束)

	uchar SearchCount=0;	//搜索计数(防止死循环,不能正常返回)
	uchar cLastStopLIdx = cStartFloorIdx;
	uint nYinZi = 10;		//2004.06.23 added by LHM(为解决计算为0的问题)
	uchar cStartSearchEnd=0;	//起始搜索阶段(分三个阶段:1,起始搜索阶段;2,第一次折返搜索阶段;3,第二次折返搜索阶段)

	//若外呼层正好有电梯,判断该电梯是否可以立即响应该外呼,以下情况视为可以立即响应:
	//1)外呼层=电梯当前层,无方向
	//2)外呼层=电梯当前层,运行方向与外呼方向一致,关门未到位
	if( cLIdx==cCurFloorIdx ){					//无方向时
		if((pFangXiang->bShang==0)&&(pFangXiang->bXia==0)){
			return time;
		}else if(((pFangXiang->bShang==1)&&(pFangXiang->bXia==0)) && (updown_flg==D_Up) && 
			(pEleData->Men.bGuanMenDaoWei==0)){ //都为上向,关门未到位
			return time;
		}else if(((pFangXiang->bShang==0)&&(pFangXiang->bXia==1)) && (updown_flg==D_Down) && 
			(pEleData->Men.bGuanMenDaoWei==0)){	//都为下向,关门未到位
			return time;
		}
	}

	//设定初始搜索方向(搜索方向应该与电梯运动方向一致)
	if(pFangXiang->bShang==1 && pFangXiang->bXia==0){	  //方向向上,搜索方向按"上->下->上"
		bStartDirect = D_Up;
		bDirect = D_Up;
	}
	else if(pFangXiang->bShang==0 && pFangXiang->bXia==1){//方向向下,搜索方向按"下->上->下"
		bStartDirect = D_Down;
		bDirect = D_Down;
	}else{												  //无方向,确定运动趋势方向
		bStartDirect = GetNoDirectEleTrend(cEIdx);
//		bDirect = GetNoDirectEleTrend(cEIdx);
		bDirect = bStartDirect;
	}

	if(cStartFloorIdx == cTopFloor){				  //当前层为最高层,搜索方向向下
		bStartDirect = D_Down;
		bDirect = D_Down;
	}else if(cStartFloorIdx == cBottomFloor){			  //当前层为最底层,搜索方向向下
		bStartDirect = D_Up;
		bDirect = D_Up;
	}

	//若电梯处于静止,检查门的状态,如需要累加开关门时间()
	//2004.07.16 LHM
	if(pEleData->bDongOrJing == 0){	//处于静止
		if(GetDoorActionState(cEIdx)==2/*Door_Opening*/){		//开门中
			time += pMenTime->cKaiMenTime*nYinZi;						//累加自动关门延迟时间	//2004.06.16 LHM debug
			time += pMenTime->cGMYanChiTime*nYinZi;						//累加自动关门延迟时间
			time += pMenTime->cGuanMenTime*nYinZi;						//累加关门时间
		}else if(GetDoorActionState(cEIdx) == 0/*Door_OpenOK*/){	//开门到位
			time += pMenTime->cGMYanChiTime*nYinZi;						//累加自动关门延迟时间	//2004.06.16 LHM debug
			time += pMenTime->cGuanMenTime*nYinZi;						//累加关门时间
		}else if(GetDoorActionState(cEIdx) == 3/*Door_Closing*/){//关门中
			time += pMenTime->cGuanMenTime*nYinZi;						//累加关门时间(不能确认关门到何位置,做保守处理)
		}else if(GetDoorActionState(cEIdx) == 1/*Door_CloseOK*/){//关门到位+电梯停止时序(不是当前层)
				//2004.07.14 Modified by LHM(因为前面已考虑过当前层响应问题,这里的累加时间仅适应于非当前层外呼)
				if(pEleData->bLingSuXinHao==1){
					time += pMenTime->cKaiMenTime*nYinZi;						//累加自动关门延迟时间	
					time += pMenTime->cGMYanChiTime*nYinZi;						//累加自动关门延迟时间
					time += pMenTime->cGuanMenTime*nYinZi;						//累加关门时间
				}
		}
	}

	while(1){

		SearchCount++;
		if(SearchCount>(cCanStopFloorCnt*2)){	// Error Logic. Dead loop.
//				TRACE("No.%d elevator cCurFloorIdx=%d cStartFloorIdx=%d cNextStopLIdx=%d bStartDirect=%d bDirect=%d\n",cEIdx,cCurFloorIdx,cStartFloorIdx,cNextStopLIdx,bStartDirect,bDirect);
//				AfxMessageBox("Dead loop.");
			SearchCount = 0;
			time=0xFFFF;
			return time;
		}

		//取得下一停靠层的楼层数,以及停靠之后的搜索方向
		cNextStopLIdx = GetNextStopLIdx(cEIdx, cStartFloorIdx, bStartDirect, &bDirect, &cStartSearchEnd);


		if( cNextStopLIdx == 0xFF){			//搜索结束,未发现到达或超越该外呼层的停靠
			cNextStopLIdx = cLIdx;				//设定下一停靠层为外呼层
			bEnd = 1;							//设置搜索结束标记
		}else{								//检查是否到达或"超过"外呼层,若超过,结束搜索
/*1)*/		if(updown_flg == D_Up){			//上呼
				if(bStartDirect == D_Down){		//初始搜索方向向下
					if(cLIdx<=cCurFloorIdx){		//外呼层小于等于当前层
						if((bDirect==D_Down) && (cNextStopLIdx<cCurFloorIdx)){
							//do nothing
						}else if((bDirect==D_Up) && (cNextStopLIdx>=cLIdx)){
							cNextStopLIdx = cLIdx;
							bEnd = 1;
						}else if((bDirect==D_Down) && (cNextStopLIdx>=cCurFloorIdx) &&(cStartSearchEnd==1)){
							
							cNextStopLIdx = cLIdx;
							bEnd = 1;
						}
					}else/*if(cLIdx>cCurFloorIdx)*/{	//外呼层大于当前层
						if((bDirect==D_Down) && (cNextStopLIdx<cCurFloorIdx)){
							//do nothing 
						}else if((bDirect==D_Up) && (cNextStopLIdx>=cLIdx)){
							cNextStopLIdx = cLIdx;
							bEnd = 1;
						}else if((bDirect==D_Down) && (cNextStopLIdx>=cCurFloorIdx) &&(cStartSearchEnd==1)){
							cNextStopLIdx = cLIdx;
							bEnd = 1;
						}
					}
				}else{							//初始搜索方向向上
					if(cLIdx<=cCurFloorIdx){		//外呼层小于等于当前层
						if((bDirect==D_Up) && (cNextStopLIdx>cCurFloorIdx)){
							//do nothing 
						}else if(bDirect==D_Down){
							//do nothing 
						}else if((bDirect==D_Up) && (cNextStopLIdx<=cCurFloorIdx) && (cNextStopLIdx>=cLIdx)&&(cStartSearchEnd==1)){
							cNextStopLIdx = cLIdx;
							bEnd = 1;
						}
					}else/*if(cLIdx>cCurFloorIdx)*/{	//外呼层大于当前层
						if((bDirect==D_Up) && (cNextStopLIdx>cCurFloorIdx) && (cNextStopLIdx>=cLIdx)){
							cNextStopLIdx = cLIdx;
							bEnd = 1;
						}else if(bDirect==D_Down){
							cNextStopLIdx = cLIdx;
							bEnd = 1;
						}else if((bDirect==D_Up) && (cNextStopLIdx<=cCurFloorIdx) &&(cStartSearchEnd==1)){
							cNextStopLIdx = cLIdx;
							bEnd = 1;
						}
					}
				}
/*2)*/		}else{							//下呼
				if(bStartDirect == D_Down){		//初始搜索方向向下
					if(cLIdx<=cCurFloorIdx){		//外呼层小于等于当前层
						if((bDirect==D_Down) && (cNextStopLIdx<cCurFloorIdx) && (cNextStopLIdx<=cLIdx)){
							cNextStopLIdx = cLIdx;
							bEnd = 1;
						}else if(bDirect==D_Up){
							cNextStopLIdx = cLIdx;
							bEnd = 1;
						}else if((bDirect==D_Down) && (cNextStopLIdx>=cCurFloorIdx) &&(cStartSearchEnd==1)){
							cNextStopLIdx = cLIdx;
							bEnd = 1;
						}
					}else/*if(cLIdx>cCurFloorIdx)*/{	//外呼层大于当前层
						if((bDirect==D_Down) && (cNextStopLIdx<cCurFloorIdx)){
							//do nothing 
						}else if(bDirect==D_Up){
							//do nothing
						}else if((bDirect==D_Down) && (cNextStopLIdx>=cCurFloorIdx) && (cNextStopLIdx<=cLIdx) &&(cStartSearchEnd==1)){
							cNextStopLIdx = cLIdx;
							bEnd = 1;
						}
					}
				}else{							//初始搜索方向向上
					if(cLIdx<=cCurFloorIdx){		//外呼层小于等于当前层
						if((bDirect==D_Up) && (cNextStopLIdx>cCurFloorIdx)){
							//do nothing 
						}else if((bDirect==D_Down) && (cNextStopLIdx<=cLIdx)){
							cNextStopLIdx = cLIdx;
							bEnd = 1;
						}else if((bDirect==D_Up) && (cNextStopLIdx<=cCurFloorIdx) &&(cStartSearchEnd==1)){
							cNextStopLIdx = cLIdx;
							bEnd = 1;
						}
					}else/*if(cLIdx>cCurFloorIdx)*/{	//外呼层大于当前层
						if((bDirect==D_Up) && (cNextStopLIdx>cCurFloorIdx)){
							//do nothing 
						}else if((bDirect==D_Down) && (cNextStopLIdx<=cLIdx)){
							cNextStopLIdx = cLIdx;
							bEnd = 1;
						}else if((bDirect==D_Up) && (cNextStopLIdx<=cCurFloorIdx) &&(cStartSearchEnd==1)){
							cNextStopLIdx = cLIdx;
							bEnd = 1;
						}
					}
				}
			}
		}

		//计算两次停靠之间所用时间(单位:十分之一秒)
//		if(cStartFloorIdx == cCurFloorIdx)	//第一行程
			time += CalTimeToDest(cEIdx, cLastStopLIdx, cNextStopLIdx);
			cLastStopLIdx = cNextStopLIdx;
//		else{
//			if(bDirect == D_Up)
//				time += CalTimeToDest(cEIdx, cStartFloorIdx-1, cNextStopLIdx);
//			else
//				time += CalTimeToDest(cEIdx, cStartFloorIdx+1, cNextStopLIdx);
//		}
		
		if((cNextStopLIdx==cLIdx) && (bEnd==1))
			return time;
		else if((cNextStopLIdx==cLIdx) && (bDirect==updown_flg))	//确保正常返回
			return time;

		if(bDirect == D_Up)
			cStartFloorIdx = cNextStopLIdx+1;	//记录停靠层
		else
			cStartFloorIdx = cNextStopLIdx-1;	//记录停靠层

		time += pMenTime->cKaiMenTime*nYinZi; //累加开门时间
		time += pMenTime->cGuanMenTime*nYinZi;//累加关门时间
		time += pMenTime->cGMYanChiTime*nYinZi; //累加自动关门延迟时间
	}

//	return time;
}

//得到下一停靠层(根据内选数据和外呼分配数据)
//参数:	cEIdx--第cEIdx部电梯
//      cStartFloorIdx--当前讨论起始层
//		bDirect--指向下一停靠之后的运行趋势
//说明:
//1)对于“无方向”的电梯,原则上"先试图分配它向上运动,再试图分配它向下运动";
//2)对于"上下方向都有"的电梯,视为错误信号,暂时不作分配,等下一轮再分配;
uchar GetNextStopLIdx(uchar cEIdx, uchar cStartFloorIdx, uchar bStartDirect, uchar *bDirect, uchar *cStartSearchEnd)
{

⌨️ 快捷键说明

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