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 + -
显示快捷键?