mrDarker
2025-07-24 2c7d546ddcd43669a433a99e1901339e491542d9
SourceCode/Bond/Servo/CMaster.cpp
@@ -51,6 +51,7 @@
      m_state = MASTERSTATE::READY;
      m_pActiveRobotTask = nullptr;
      m_nLastError = 0;
      m_isCompareMapsBeforeProceeding = FALSE;
      InitializeCriticalSection(&m_criticalSection);
   }
@@ -297,11 +298,12 @@
      // 各种机器
      CLoadPort* pLoadPorts[4];
      CEFEM* pEFEM = (CEFEM*)getEquipment(EQ_ID_EFEM);
      CLoadPort* pLoadPort1 = (CLoadPort*)getEquipment(EQ_ID_LOADPORT1);
      CLoadPort* pLoadPort2 = (CLoadPort*)getEquipment(EQ_ID_LOADPORT2);
      CLoadPort* pLoadPort3 = (CLoadPort*)getEquipment(EQ_ID_LOADPORT3);
      CLoadPort* pLoadPort4 = (CLoadPort*)getEquipment(EQ_ID_LOADPORT4);
      pLoadPorts[0] = (CLoadPort*)getEquipment(EQ_ID_LOADPORT1);
      pLoadPorts[1] = (CLoadPort*)getEquipment(EQ_ID_LOADPORT2);
      pLoadPorts[2] = (CLoadPort*)getEquipment(EQ_ID_LOADPORT3);
      pLoadPorts[3] = (CLoadPort*)getEquipment(EQ_ID_LOADPORT4);
      CFliper* pFliper = (CFliper*)getEquipment(EQ_ID_FLIPER);
      CVacuumBake* pVacuumBake = (CVacuumBake*)getEquipment(EQ_ID_VACUUMBAKE);
      CAligner* pAligner = (CAligner*)getEquipment(EQ_ID_ALIGNER);
@@ -311,10 +313,10 @@
      CMeasurement* pMeasurement = (CMeasurement*)getEquipment(EQ_ID_MEASUREMENT);
      ASSERT(pEFEM);
      ASSERT(pLoadPort1);
      ASSERT(pLoadPort2);
      ASSERT(pLoadPort3);
      ASSERT(pLoadPort4);
      ASSERT(pLoadPorts[0]);
      ASSERT(pLoadPorts[1]);
      ASSERT(pLoadPorts[2]);
      ASSERT(pLoadPorts[3]);
      ASSERT(pFliper);
      ASSERT(pVacuumBake);
      ASSERT(pAligner);
@@ -509,6 +511,9 @@
            }
            if (m_pActiveRobotTask != nullptr) {
               if (m_pActiveRobotTask->isPicked()) {
                  m_pActiveRobotTask->place();
               }
               unlock();
               // 检测到当前有正在下午的任务,确保当前任务完成或中止后继续
               // LOGI("检测到当前有正在下午的任务,确保当前任务完成或中止后继续...");
@@ -537,19 +542,20 @@
            // Measurement -> LoadPort
            LOGI("Arm1 %s, Arm2 %s.", rmd.armState[0] ? _T("不可用") : _T("可用"),
               rmd.armState[1] ? _T("不可用") : _T("可用"));
            CLoadPort* pEqLoadPort[] = { pLoadPort1, pLoadPort2, pLoadPort3, pLoadPort4 };
            if (rmd.armState[0] || rmd.armState[1]) {
               LOGI("Arm1 %s, Arm2 %s.", rmd.armState[0] ? _T("不可用") : _T("可用"),
                  rmd.armState[1] ? _T("不可用") : _T("可用"));
            }
            CEquipment* pEqTar[] = { pVacuumBake, pFliper };
            if (primaryType == MaterialsType::G2) {
               pEqTar[0] = pFliper;
               pEqTar[1] = pVacuumBake;
            }
            for (int s = 0; s < 4; s++) {
               if (!rmd.armState[0] && pEqLoadPort[s]->isEnable()
                  && pEqLoadPort[s]->getPortType() == PortType::Unloading
                  && pEqLoadPort[s]->getPortMode() == PortMode::ReadyToUnload) {
                  m_pActiveRobotTask = createTransferTask(pMeasurement, pEqLoadPort[s], primaryType, secondaryType);
               if (!rmd.armState[0] && pLoadPorts[s]->isEnable()
                  && pLoadPorts[s]->getPortType() == PortType::Unloading
                  && pLoadPorts[s]->getPortMode() == PortMode::ReadyToUnload) {
                  m_pActiveRobotTask = createTransferTask(pMeasurement, pLoadPorts[s], primaryType, secondaryType);
                  if (m_pActiveRobotTask != nullptr) {
                     goto PORT_PUT;
                  }
@@ -567,6 +573,25 @@
               LOGI("创建新任务<%s>...", strDescription.c_str());
               continue;
            }
            // Measurement NG -> LoadPort
            // NG回原位
            if (!rmd.armState[1]) {
               m_pActiveRobotTask = createTransferTask_restore(pMeasurement, pLoadPorts);
               if (m_pActiveRobotTask != nullptr) {
                  m_pActiveRobotTask->pick();
                  std::string strDescription = m_pActiveRobotTask->getDescription();
                  unlock();
                  if (m_listener.onRobotTaskEvent != nullptr) {
                     m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
                  }
                  LOGI("创建Measurement回退任务<%s>...", strDescription.c_str());
                  continue;
               }
            }
            // BakeCooling ->Measurement
@@ -635,8 +660,10 @@
            // Fliper(G2) -> Bonder
            // VacuumBake(G1) -> Bonder
            SERVO::CRobotTask* tempTask[2] = {nullptr, nullptr};
            if (!rmd.armState[1] && !pBonder1->hasBondClass()) {
               m_pActiveRobotTask = createTransferTask(pFliper, pBonder1, primaryType, secondaryType, 2);
               tempTask[0] = createTransferTask(pFliper, pBonder1, primaryType, secondaryType, 2);
               /*
               if (m_pActiveRobotTask != nullptr) {
                  m_pActiveRobotTask->pick();
                  std::string strDescription = m_pActiveRobotTask->getDescription();
@@ -647,24 +674,12 @@
                  LOGI("创建新任务<%s>...", strDescription.c_str());
                  continue;
               }
            }
            if (!rmd.armState[1] && !pBonder2->hasBondClass()) {
               m_pActiveRobotTask = createTransferTask(pFliper, pBonder2, primaryType, secondaryType, 2);
               if (m_pActiveRobotTask != nullptr) {
                  m_pActiveRobotTask->pick();
                  std::string strDescription = m_pActiveRobotTask->getDescription();
                  unlock();
                  if (m_listener.onRobotTaskEvent != nullptr) {
                     m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
                  }
                  LOGI("创建新任务<%s>...", strDescription.c_str());
                  continue;
               }
               */
            }
            if (!rmd.armState[0] && !pBonder1->hasBondClass()) {
               m_pActiveRobotTask = createTransferTask(pVacuumBake, pBonder1, primaryType, secondaryType);
               tempTask[1] = createTransferTask(pVacuumBake, pBonder1, primaryType, secondaryType);
               /*
               if (m_pActiveRobotTask != nullptr) {
                  m_pActiveRobotTask->pick();
                  std::string strDescription = m_pActiveRobotTask->getDescription();
@@ -675,10 +690,51 @@
                  LOGI("创建新任务<%s>...", strDescription.c_str());
                  continue;
               }
               */
            }
            if (tempTask[1] != nullptr && pBonder1->hasG2Class()) {
               m_pActiveRobotTask = tempTask[1];
               if(tempTask[0] != nullptr) delete tempTask[0];
            }
            else if (tempTask[0] != nullptr && tempTask[1] != nullptr) {
               m_pActiveRobotTask = tempTask[0];
               delete tempTask[1];
            }
            if (m_pActiveRobotTask != nullptr) {
               m_pActiveRobotTask->pick();
               std::string strDescription = m_pActiveRobotTask->getDescription();
               unlock();
               if (m_listener.onRobotTaskEvent != nullptr) {
                  m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
               }
               LOGI("创建新任务<%s>...", strDescription.c_str());
               continue;
            }
            if (tempTask[0] != nullptr) delete tempTask[0];
            if (tempTask[1] != nullptr) delete tempTask[1];
            tempTask[0] = nullptr;
            tempTask[1] = nullptr;
            if (!rmd.armState[1] && !pBonder2->hasBondClass()) {
               tempTask[0] = createTransferTask(pFliper, pBonder2, primaryType, secondaryType, 2);
               /*
               if (m_pActiveRobotTask != nullptr) {
                  m_pActiveRobotTask->pick();
                  std::string strDescription = m_pActiveRobotTask->getDescription();
                  unlock();
                  if (m_listener.onRobotTaskEvent != nullptr) {
                     m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
                  }
                  LOGI("创建新任务<%s>...", strDescription.c_str());
                  continue;
               }
               */
            }
            if (!rmd.armState[0] && !pBonder2->hasBondClass()) {
               m_pActiveRobotTask = createTransferTask(pVacuumBake, pBonder2, primaryType, secondaryType);
               tempTask[1] = createTransferTask(pVacuumBake, pBonder2, primaryType, secondaryType);
               /*
               if (m_pActiveRobotTask != nullptr) {
                  m_pActiveRobotTask->pick();
                  std::string strDescription = m_pActiveRobotTask->getDescription();
@@ -689,13 +745,36 @@
                  LOGI("创建新任务<%s>...", strDescription.c_str());
                  continue;
               }
               */
            }
            if (tempTask[1] != nullptr && pBonder1->hasG2Class()) {
               m_pActiveRobotTask = tempTask[1];
               if (tempTask[0] != nullptr) delete tempTask[0];
            }
            else if (tempTask[0] != nullptr && tempTask[1] != nullptr) {
               m_pActiveRobotTask = tempTask[0];
               delete tempTask[1];
            }
            if (m_pActiveRobotTask != nullptr) {
               m_pActiveRobotTask->pick();
               std::string strDescription = m_pActiveRobotTask->getDescription();
               unlock();
               if (m_listener.onRobotTaskEvent != nullptr) {
                  m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
               }
               LOGI("创建新任务<%s>...", strDescription.c_str());
               continue;
            }
            if (tempTask[0] != nullptr) delete tempTask[0];
            if (tempTask[1] != nullptr) delete tempTask[1];
            tempTask[0] = nullptr;
            tempTask[1] = nullptr;
            // Aligner -> Fliper(G2)
            // Aligner -> VacuumBake(G1)
            if (!rmd.armState[1]) {
               m_pActiveRobotTask = createTransferTask(pAligner, pFliper, primaryType, secondaryType, 2);
               m_pActiveRobotTask = createTransferTask(pAligner, pFliper, primaryType, secondaryType);
               if (m_pActiveRobotTask != nullptr) {
                  m_pActiveRobotTask->pick();
                  std::string strDescription = m_pActiveRobotTask->getDescription();
@@ -722,13 +801,32 @@
               }
            }
            // Aligner -> LoadPort
            if (!rmd.armState[1]) {
               m_pActiveRobotTask = createTransferTask_restore(pAligner, pLoadPorts);
               if (m_pActiveRobotTask != nullptr) {
                  m_pActiveRobotTask->pick();
                  std::string strDescription = m_pActiveRobotTask->getDescription();
                  unlock();
                  if (m_listener.onRobotTaskEvent != nullptr) {
                     m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
                  }
                  LOGI("创建Aligner回退任务<%s>...", strDescription.c_str());
                  continue;
               }
            }
            // LoadPort -> Aligner
            for (int s = 0; s < 4; s++) {
               if (!rmd.armState[0] && pEqLoadPort[s]->isEnable()
                  && pEqLoadPort[s]->getPortType() == PortType::Loading
                  && pEqLoadPort[s]->getPortMode() == PortMode::ReadyToLoad) {
                  m_pActiveRobotTask = createTransferTask(pEqLoadPort[s], pAligner, primaryType, secondaryType);
               if (!rmd.armState[0] && pLoadPorts[s]->isEnable()
                  && pLoadPorts[s]->getPortType() == PortType::Loading
                  && pLoadPorts[s]->getPortMode() == PortMode::ReadyToLoad) {
                  m_pActiveRobotTask = createTransferTask(pLoadPorts[s], pAligner, primaryType, secondaryType);
                  if (m_pActiveRobotTask != nullptr) {
                     pEFEM->setContext(m_pActiveRobotTask->getContext());
                     goto PORT_GET;
                  }
               }
@@ -773,11 +871,12 @@
         for (auto item : m_listEquipment) {
            const StationIdentifier& station = item->getStation();
            MemoryBlock& block = item->getReadBitBlock();
            int nRet = m_cclink.ReadData2(station, (DeviceType)block.type,
               block.start, block.size, block.buffer);
            if (0 == nRet) {
               item->onReceiveLBData(block.buffer, block.size);
            if (block.end > block.start) {
               int nRet = m_cclink.ReadData2(station, (DeviceType)block.type,
                  block.start, block.size, block.buffer);
               if (0 == nRet) {
                  item->onReceiveLBData(block.buffer, block.size);
               }
            }
         }
      }
@@ -818,7 +917,7 @@
            m_listener.onEqVcrEventReport(this, p, p2);
         }
      };
      listener.onPreFethedOutJob = [&](void* pEquipment, CJobDataB* pJobDataB) -> BOOL {
      listener.onPreFethedOutJob = [&](void* pEquipment, int port, CJobDataB* pJobDataB) -> BOOL {
         CEquipment* p = (CEquipment*)pEquipment;
@@ -851,7 +950,7 @@
         return bOk;
      };
      listener.onPreStoredJob = [&](void* pEquipment, CJobDataB* pJobDataB, short& slot) -> BOOL {
      listener.onPreStoredJob = [&](void* pEquipment, int port, CJobDataB* pJobDataB, short& slot) -> BOOL {
         CEquipment* p = (CEquipment*)pEquipment;
@@ -878,11 +977,22 @@
                  LOGI("<CMaster>onPreFethedOutJob, 已校验数据一致性.");
               }
            }
            // 是否回撤
            else if (m_pActiveRobotTask->isRestoring() &&
               m_pActiveRobotTask->getSrcPosition() == p->getID()) {
               CGlass* pGlass = p->getGlassFromSlot(m_pActiveRobotTask->getSrcSlot());
               if (pGlass == nullptr && m_pActiveRobotTask->getSrcSlot() == port) {
                  bOk = TRUE;
                  slot = m_pActiveRobotTask->getSrcSlot();
                  LOGI("<CMaster>onPreFethedOutJob, 已校验数据一致性.");
               }
            }
         }
         unlock();
         if (!bOk) {
            LOGE("<CMaster>onPreFethedOutJob, 数据校验失败.");
            LOGE("<CMaster>onPreStoredJob, 数据校验失败.");
         }
         return bOk;
@@ -912,7 +1022,7 @@
               ) {
               LOGI("取片完成.");
               m_pActiveRobotTask->fetchOut();
               m_pActiveRobotTask->place();
               m_pActiveRobotTask->picked();
            }
            else if (m_pActiveRobotTask != nullptr
@@ -932,11 +1042,40 @@
               delete m_pActiveRobotTask;
               m_pActiveRobotTask = nullptr;
            }
            else if (m_pActiveRobotTask != nullptr
               && m_pActiveRobotTask->isRestoring()
               && m_pActiveRobotTask->getSrcPosition() == p->getID()) {
               m_pActiveRobotTask->stored();
               m_pActiveRobotTask->restored();
               LOGI("回撤完成...");
               // 完成此条搬送任务,但要把数据和消息上抛应用层
               unlock();
               lock();
               if (m_listener.onRobotTaskEvent != nullptr) {
                  m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_RESTORE);
               }
               delete m_pActiveRobotTask;
               m_pActiveRobotTask = nullptr;
               stop();
            }
            unlock();
         }
      };
      listener.onProcessStateChanged = [&](void* pEquipment, PROCESS_STATE state) -> void {
         LOGI("<Master>onProcessStateChanged<%d>", (int)state);
      };
      listener.onMapMismatch = [&](void* pEquipment, short scanMap, short downMap) {
         LOGE("<Master-%s>Port InUse, map(%d!=%d)不一致,请检查。",
            ((CEquipment*)pEquipment)->getName().c_str(), scanMap, downMap);
      };
      listener.onPortInUse = [&](void* pEquipment, short scanMap) {
         LOGE("<Master-%s>Port InUse。scanMap=%d", ((CEquipment*)pEquipment)->getName().c_str(), scanMap);
         if (m_listener.onLoadPortInUse != nullptr) {
            m_listener.onLoadPortInUse(this, (CEquipment*)pEquipment, scanMap);
         }
      };
      pEquipment->setListener(listener);
      pEquipment->setCcLink(&m_cclink);
@@ -975,6 +1114,7 @@
      pEquipment->setID(EQ_ID_LOADPORT1 + index);
      pEquipment->setName(szName);
      pEquipment->setDescription(szName);
      pEquipment->setCompareMapsBeforeProceeding(m_isCompareMapsBeforeProceeding);
      addToEquipmentList(pEquipment);
@@ -992,7 +1132,7 @@
      pEquipment->setBaseAlarmId(BASE_ALARM_EFEM);
      pEquipment->setName("Fliper(G2)");
      pEquipment->setDescription("Fliper(G2).");
      pEquipment->setReadBitBlock(0x4000, 0x45ff);
      pEquipment->setReadBitBlock(0x0, 0x0);
      pEquipment->setStation(0, 255);
      addToEquipmentList(pEquipment);
@@ -1027,7 +1167,7 @@
      pEquipment->setBaseAlarmId(BASE_ALARM_EFEM);
      pEquipment->setName("Aligner");
      pEquipment->setDescription("Aligner.");
      pEquipment->setReadBitBlock(0x4000, 0x45ff);
      pEquipment->setReadBitBlock(0x0, 0x0);
      pEquipment->setStation(0, 255);
      addToEquipmentList(pEquipment);
@@ -1154,27 +1294,8 @@
      }
      // 按一定频率扫描LB数据
      static int i = 0;
      i++;
      /*
      if (i % (4 * 1) == 0) {
         for (auto item : m_listEquipment) {
            if (item->getID() == EQ_ID_Bonder1) {
               const StationIdentifier& station = item->getStation();
               MemoryBlock& block = item->getReadBitBlock();
               int nRet = m_cclink.ReadData2(station, (DeviceType)block.type,
                  block.start, block.size, block.buffer);
               if (0 == nRet) {
                  item->onReceiveLBData(block.buffer, block.size);
               }
            }
         }
      }
      */
      // 自动保存缓存
      if (i % (4 * 2) == 0) {
@@ -1350,6 +1471,10 @@
      MaterialsType primaryType/* = MaterialsType::G1*/, MaterialsType secondaryType/* = MaterialsType::G2*/,
      int armNo/* = 1*/)
   {
      if (!pSrcEq->IsEnabled()) {
         return nullptr;
      }
      CRobotTask* pTask = nullptr;
      CSlot* pSrcSlot, * pTarSlot;
      pTarSlot = pTarEq->getAvailableSlotForGlass(primaryType);
@@ -1374,7 +1499,11 @@
   CRobotTask* CMaster::createTransferTask_bonder_to_bakecooling(CEquipment* pSrcEq, CEquipment* pTarEq)
   {
      std::vector<int> slots = {1, 2};
      if (!pSrcEq->IsEnabled()) {
         return nullptr;
      }
      std::vector<int> slots = {1, 3};
      CRobotTask* pTask = nullptr;
      CSlot* pSrcSlot, * pTarSlot;
@@ -1395,8 +1524,12 @@
   CRobotTask* CMaster::createTransferTask_bake_to_cooling(CEquipment* pSrcEq)
   {
      std::vector<int> slotsTar = { 3, 4 };
      std::vector<int> slotsSrc = { 1, 2 };
      if (!pSrcEq->IsEnabled()) {
         return nullptr;
      }
      std::vector<int> slotsTar = { 2, 4 };
      std::vector<int> slotsSrc = { 1, 3 };
      CRobotTask* pTask = nullptr;
      CSlot* pSrcSlot, * pTarSlot;
@@ -1417,12 +1550,52 @@
   CRobotTask* CMaster::createTransferTask_bakecooling_to_measurement(CEquipment* pSrcEq, CEquipment* pTarEq)
   {
      std::vector<int> slots = { 3, 4 };
      if (!pSrcEq->IsEnabled()) {
         return nullptr;
      }
      std::vector<int> slots = { 2, 4 };
      CRobotTask* pTask = nullptr;
      CSlot* pSrcSlot, * pTarSlot;
      pTarSlot = pTarEq->getAvailableSlotForGlass(MaterialsType::G1);
      pSrcSlot = pSrcEq->getProcessedSlot2(MaterialsType::G1, slots);
      if (pSrcSlot != nullptr && nullptr != pTarSlot) {
         pTask = new CRobotTask();
         pTask->setContext(pSrcSlot->getContext());
         pTask->setEFEM((CEFEM*)getEquipment(EQ_ID_EFEM));
         taskSeqNo = pTask->setRobotTransferParam(taskSeqNo, 1, pSrcSlot->getPosition(),
            pTarSlot->getPosition(), pSrcSlot->getNo(), pTarSlot->getNo());
      }
      return pTask;
   }
   CRobotTask* CMaster::createTransferTask_restore(CEquipment* pEqSrc, CLoadPort** pPorts)
   {
      if (!pEqSrc->IsEnabled()) {
         return nullptr;
      }
      CRobotTask* pTask = nullptr;
      CSlot* pSrcSlot, * pTarSlot = nullptr, * pTempSlot;
      pSrcSlot = pEqSrc->getInspFailSlot();
      if (pSrcSlot != nullptr) {
         CGlass* pGlass = (CGlass*)pSrcSlot->getContext();
         ASSERT(pGlass);
         int port, slot;
         pGlass->getOrginPort(port, slot);
         pGlass->setInspResult(pPorts[port]->getID(), 0, InspResult::Fail);
         ASSERT(0 <= port && port < 4);
         ASSERT(0 <= slot && slot < 8);
         pTempSlot = pPorts[port]->getSlot(slot);
         if (pTempSlot->getContext() == nullptr) {
            pTarSlot = pTempSlot;
         }
      }
      if (pSrcSlot != nullptr && nullptr != pTarSlot) {
         pTask = new CRobotTask();
@@ -1456,7 +1629,32 @@
      unlock();
      // 当前任务手动中止后,停止调度,需要操作员在解决问题后,重新启动
      stop();
      // 25年7月23日后修改为不停止任务
      // stop();
      return 0;
   }
   int CMaster::restoreCurrentTask()
   {
      lock();
      if (m_pActiveRobotTask != nullptr) {
         m_pActiveRobotTask->restore();
      }
      unlock();
      return 0;
   }
   int CMaster::resendCurrentTask()
   {
      lock();
      if (m_pActiveRobotTask != nullptr) {
         m_pActiveRobotTask->resend();
      }
      unlock();
      return 0;
   }
@@ -1474,4 +1672,17 @@
      pPort->localSetTransferMode((SERVO::TransferMode)transferMode);
      pPort->localAutoChangeEnable(autoChangeEnable);
   }
   void CMaster::setPortCassetteType(unsigned int index, SERVO::CassetteType type)
   {
      ASSERT(index < 4);
      int eqid[] = { EQ_ID_LOADPORT1, EQ_ID_LOADPORT2, EQ_ID_LOADPORT3, EQ_ID_LOADPORT4 };
      CLoadPort* pPort = (CLoadPort*)getEquipment(eqid[index]);
      pPort->localSetCessetteType(type);
   }
   void CMaster::setCompareMapsBeforeProceeding(BOOL bCompare)
   {
      m_isCompareMapsBeforeProceeding = bCompare;
   }
}