LAPTOP-SNT8I5JK\Boounion
2025-08-15 697fa6b857fe202fe2e5f50d4ecf2c7268e527cc
SourceCode/Bond/Servo/CMaster.cpp
@@ -3,6 +3,7 @@
#include "CMaster.h"
#include <future>
#include <vector>
#include "RecipeManager.h"
namespace SERVO {
@@ -54,11 +55,19 @@
      m_isCompareMapsBeforeProceeding = FALSE;
      m_bEnableEventReport = true;
      m_bEnableAlarmReport = true;
      m_bContinuousTransfer = false;
      m_nContinuousTransferCount = 0;
      m_nContinuousTransferStep = CTStep_Unknow;
      InitializeCriticalSection(&m_criticalSection);
   }
   CMaster::~CMaster()
   {
      for (auto item : m_processJobs) {
         delete item;
      }
      m_processJobs.clear();
      if (m_hEventReadBitsThreadExit[0] != nullptr) {
         ::CloseHandle(m_hEventReadBitsThreadExit[0]);
         m_hEventReadBitsThreadExit[0] = nullptr;
@@ -251,6 +260,20 @@
         return -1;
      }
      m_bContinuousTransfer = false;
      setState(MASTERSTATE::STARTING);
      m_ullStartTime = GetTickCount64();
      return 0;
   }
   int CMaster::startContinuousTransfer()
   {
      if (m_state != MASTERSTATE::READY) {
         return -1;
      }
      m_bContinuousTransfer = true;
      setState(MASTERSTATE::STARTING);
      m_ullStartTime = GetTickCount64();
@@ -260,7 +283,7 @@
   int CMaster::stop()
   {
      // 运行时间为累加结果,本次停止时刷新;
      if (m_state != MASTERSTATE::RUNNING) {
      if (m_state != MASTERSTATE::RUNNING && m_state != MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER) {
         return -1;
      }
@@ -279,7 +302,7 @@
   ULONGLONG CMaster::getRunTime()
   {
      if (m_state == MASTERSTATE::RUNNING)
      if (m_state == MASTERSTATE::RUNNING || m_state == MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER)
         return m_ullRunTime + (GetTickCount64() - m_ullStartTime);
      else
         return m_ullRunTime;
@@ -330,7 +353,7 @@
      while (1) {
         // 待退出信号或时间到
         HANDLE hEvents[] = { m_hEventDispatchThreadExit[0], m_hDispatchEvent };
         int nRet = WaitForMultipleObjects(2, hEvents, FALSE, 1000);
         int nRet = WaitForMultipleObjects(2, hEvents, FALSE, 500);
         if (nRet == WAIT_OBJECT_0) {
            break;
         }
@@ -447,7 +470,11 @@
            unlock();
            setState(MASTERSTATE::RUNNING);
            if(!m_bContinuousTransfer)
               setState(MASTERSTATE::RUNNING);
            else
               setState(MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER);
            continue;
         }
@@ -548,15 +575,11 @@
               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++) {
               PortType pt = pLoadPorts[s]->getPortType();
               if (!rmd.armState[0] && pLoadPorts[s]->isEnable()
                  && pLoadPorts[s]->getPortType() == PortType::Unloading
                  && pLoadPorts[s]->getPortMode() == PortMode::ReadyToUnload) {
                  && (pt == PortType::Unloading || pt == PortType::Both)
                  && pLoadPorts[s]->getPortStatus() == PORT_INUSE) {
                  m_pActiveRobotTask = createTransferTask(pMeasurement, pLoadPorts[s], primaryType, secondaryType);
                  if (m_pActiveRobotTask != nullptr) {
                     goto PORT_PUT;
@@ -649,9 +672,10 @@
            // LoadPort -> Aligner
            for (int s = 0; s < 4; s++) {
               PortType pt = pLoadPorts[s]->getPortType();
               if (!rmd.armState[0] && pLoadPorts[s]->isEnable()
                  && pLoadPorts[s]->getPortType() == PortType::Loading
                  && pLoadPorts[s]->getPortMode() == PortMode::ReadyToLoad) {
                  && (pt == PortType::Loading || pt == PortType::Both)
                  && pLoadPorts[s]->getPortStatus() == PORT_INUSE) {
                  m_pActiveRobotTask = createTransferTask(pLoadPorts[s], pAligner, primaryType, secondaryType);
                  if (m_pActiveRobotTask != nullptr) {
                     pEFEM->setContext(m_pActiveRobotTask->getContext());
@@ -667,6 +691,199 @@
            unlock();
            continue;
         }
         // 千传模式调度逻辑
         else if (m_state == MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER) {
            // 检测判断robot状态
            RMDATA& rmd = pEFEM->getRobotMonitoringData();
            if (rmd.status != ROBOT_STATUS::Idle && rmd.status != ROBOT_STATUS::Run) {
               unlock();
               continue;
            }
            if (m_pActiveRobotTask != nullptr) {
               if (m_pActiveRobotTask->isPicked()) {
                  m_pActiveRobotTask->place();
               }
               unlock();
               // 检测到当前有正在下午的任务,确保当前任务完成或中止后继续
               // LOGI("检测到当前有正在下午的任务,确保当前任务完成或中止后继续...");
               continue;
            }
            // Measurement -> LoadPort
            for (int s = 0; s < 4; s++) {
               PortType pt = pLoadPorts[s]->getPortType();
               if ((m_nContinuousTransferStep == CTStep_Unknow || m_nContinuousTransferStep == CTStep_BakeCooling_Measurement)
                  && !rmd.armState[0] && pLoadPorts[s]->isEnable()
                  && (pt == PortType::Unloading || pt == PortType::Both)
                  && pLoadPorts[s]->getPortStatus() == PORT_INUSE) {
                  for (int slot = 0; slot < SLOT_MAX; slot++) {
                     m_pActiveRobotTask = createTransferTask_continuous_transfer(pMeasurement,
                        0, pLoadPorts[s], slot);
                     if (m_pActiveRobotTask != nullptr) {
                        m_nContinuousTransferStep = CTStep_Measurement_LoadPort;
                        m_nContinuousTransferStep = CTStep_end;
                        goto CT_PORT_PUT;
                     }
                  }
               }
            }
         CT_PORT_PUT:
            CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
            // BakeCooling ->Measurement
            if ((m_nContinuousTransferStep == CTStep_Unknow || m_nContinuousTransferStep == CTStep_BakeCooling_BakeCooling3)
               && !rmd.armState[0]) {
               m_pActiveRobotTask = createTransferTask_continuous_transfer(pBakeCooling,
                  3, pMeasurement, 0);
               if (m_pActiveRobotTask != nullptr) {
                  m_nContinuousTransferStep = CTStep_BakeCooling_Measurement;
                  LOGI("<ContinuousTransfer>千传测试,开始搬送任务(BakeCooling -> Measurement)...");
               }
               CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
            }
            // BakeCooling内部
            if ((m_nContinuousTransferStep == CTStep_Unknow || m_nContinuousTransferStep == CTStep_BakeCooling_BakeCooling2)
               && !rmd.armState[0]) {
               m_pActiveRobotTask = createTransferTask_continuous_transfer(pBakeCooling,
                  2, pBakeCooling, 3);
               if (m_pActiveRobotTask != nullptr) {
                  m_nContinuousTransferStep = CTStep_BakeCooling_BakeCooling3;
                  LOGI("<ContinuousTransfer>千传测试,开始搬送任务(BakeCooling-2 -> BakeCooling-3)...");
               }
               CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
            }
            if ((m_nContinuousTransferStep == CTStep_Unknow || m_nContinuousTransferStep == CTStep_BakeCooling_BakeCooling1)
               && !rmd.armState[0]) {
               m_pActiveRobotTask = createTransferTask_continuous_transfer(pBakeCooling,
                  1, pBakeCooling, 2);
               if (m_pActiveRobotTask != nullptr) {
                  m_nContinuousTransferStep = CTStep_BakeCooling_BakeCooling2;
                  LOGI("<ContinuousTransfer>千传测试,开始搬送任务(BakeCooling-1 -> BakeCooling-2)...");
               }
               CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
            }
            if ((m_nContinuousTransferStep == CTStep_Unknow || m_nContinuousTransferStep == CTStep_VacuumBake_BakeCooling)
               && !rmd.armState[0]) {
               m_pActiveRobotTask = createTransferTask_continuous_transfer(pBakeCooling,
                  0, pBakeCooling, 1);
               if (m_pActiveRobotTask != nullptr) {
                  m_nContinuousTransferStep = CTStep_BakeCooling_BakeCooling1;
                  LOGI("<ContinuousTransfer>千传测试,开始搬送任务(BakeCooling-0 -> BakeCooling-1)...");
               }
               CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
            }
            // VacuumBake(G1) -> BakeCooling
            if ((m_nContinuousTransferStep == CTStep_Unknow || m_nContinuousTransferStep == CTStep_VacuumBake_VacuumBake)
               && !rmd.armState[0]) {
               m_pActiveRobotTask = createTransferTask_continuous_transfer(pVacuumBake,
                  1, pBakeCooling, 0);
               if (m_pActiveRobotTask != nullptr) {
                  m_nContinuousTransferStep = CTStep_VacuumBake_BakeCooling;
                  LOGI("<ContinuousTransfer>千传测试,开始搬送任务(VacuumBake(G1) -> BakeCooling)...");
               }
               CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
            }
            // VacuumBake(G1) -> VacuumBake(G1)
            if ((m_nContinuousTransferStep == CTStep_Unknow || m_nContinuousTransferStep == CTStep_Bonder2_VacuumBake)
               && !rmd.armState[0]) {
               m_pActiveRobotTask = createTransferTask_continuous_transfer(pVacuumBake,
                  0, pVacuumBake, 1);
               if (m_pActiveRobotTask != nullptr) {
                  m_nContinuousTransferStep = CTStep_VacuumBake_VacuumBake;
                  LOGI("<ContinuousTransfer>千传测试,开始搬送任务(VacuumBake(G1-0) -> VacuumBake(G1-1))...");
               }
               CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
            }
            // Bonder2 -> VacuumBake(G1)
            if ((m_nContinuousTransferStep == CTStep_Unknow || m_nContinuousTransferStep == CTStep_Bonder1_Bonder2)
               && !rmd.armState[0]) {
               m_pActiveRobotTask = createTransferTask_continuous_transfer(pBonder2,
                  1, pVacuumBake, 0);
               if (m_pActiveRobotTask != nullptr) {
                  m_nContinuousTransferStep = CTStep_Bonder2_VacuumBake;
                  LOGI("<ContinuousTransfer>千传测试,开始搬送任务(Bonder2 -> VacuumBake(G1))...");
               }
               CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
            }
            // Bonder1 -> Bonder2
            if ((m_nContinuousTransferStep == CTStep_Unknow || m_nContinuousTransferStep == CTStep_Fliper_Bonder1)
               && !rmd.armState[0] && !pBonder2->hasBondClass()) {
               m_pActiveRobotTask = createTransferTask_continuous_transfer(pBonder1,
                  1, pBonder2, 1);
               if (m_pActiveRobotTask != nullptr) {
                  m_nContinuousTransferStep = CTStep_Bonder1_Bonder2;
                  LOGI("<ContinuousTransfer>千传测试,开始搬送任务(Bonder1 -> Bonder2)...");
               }
               CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
            }
            // Fliper(G2) -> Bonder1
            if ((m_nContinuousTransferStep == CTStep_Unknow || m_nContinuousTransferStep == CTStep_Aligner_Fliper)
               &&!rmd.armState[0] && !pBonder1->hasBondClass()) {
               m_pActiveRobotTask = createTransferTask_continuous_transfer(pFliper,
                  0, pBonder1, 1);
               if (m_pActiveRobotTask != nullptr) {
                  m_nContinuousTransferStep = CTStep_Fliper_Bonder1;
                  LOGI("<ContinuousTransfer>千传测试,开始搬送任务(Fliper(G2) -> Bonder1)...");
               }
               CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
            }
            // Aligner -> Fliper(G2)
            if ((m_nContinuousTransferStep == CTStep_Unknow || m_nContinuousTransferStep == CTStep_LoadPort_Aligner)
               && !rmd.armState[1]) {
               m_pActiveRobotTask = createTransferTask_continuous_transfer(pAligner,
                  0, pFliper, 0);
               if (m_pActiveRobotTask != nullptr) {
                  m_nContinuousTransferStep = CTStep_Aligner_Fliper;
                  LOGI("<ContinuousTransfer>千传测试,开始搬送任务(Aligner -> Fliper(G2))...");
               }
               CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
            }
            // LoadPort -> Aligner
            for (int s = 0; s < 4; s++) {
               PortType pt = pLoadPorts[s]->getPortType();
               if ((m_nContinuousTransferStep == CTStep_Unknow || m_nContinuousTransferStep == CTStep_end)
                  && !rmd.armState[0] && pLoadPorts[s]->isEnable()
                  && (pt == PortType::Loading || pt == PortType::Both)
                  && pLoadPorts[s]->getPortStatus() == PORT_INUSE) {
                  for (int slot = 0; slot < SLOT_MAX; slot++) {
                     m_pActiveRobotTask = createTransferTask_continuous_transfer(pLoadPorts[s],
                        slot, pAligner, 0);
                     if (m_pActiveRobotTask != nullptr) {
                        m_nContinuousTransferStep = CTStep_LoadPort_Aligner;
                        LOGI("<ContinuousTransfer>千传测试,开始搬送任务(LoadPort -> Aligner)...");
                        pEFEM->setContext(m_pActiveRobotTask->getContext());
                        goto CT_PORT_GET;
                     }
                  }
               }
            }
         CT_PORT_GET:
            if (m_pActiveRobotTask != nullptr) {
               m_nContinuousTransferStep = CTStep_begin;
               LOGI("<ContinuousTransfer>千传测试,开始第 %d 轮", m_nContinuousTransferCount + 1);
            }
            CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
            unlock();
            continue;
         }
         unlock();
      }
@@ -680,6 +897,16 @@
   unsigned CMaster::ReadBitsProc()
   {
      // 标志位清0复位
      {
         StationIdentifier station;
         station.nNetNo = 0;
         station.nStNo = 255;
         char szBuffer[528] = { 0 };   // 0x0, 0x1087
         m_cclink.WriteData(station, (long)DeviceType::B, 0, 528, (short*)szBuffer);
      }
      while (1) {
         // 待退出信号或时间到
         int nRet = ::WaitForSingleObject(m_hEventReadBitsThreadExit[0], 1000);
@@ -740,6 +967,8 @@
      listener.onPreFethedOutJob = [&](void* pEquipment, int port, CJobDataB* pJobDataB) -> BOOL {
         CEquipment* p = (CEquipment*)pEquipment;
         // 可能要加这一句
         Sleep(750);
         // 取片,更新当前搬送任务
         BOOL bOk = FALSE;
@@ -773,6 +1002,8 @@
      listener.onPreStoredJob = [&](void* pEquipment, int port, CJobDataB* pJobDataB, short& slot) -> BOOL {
         CEquipment* p = (CEquipment*)pEquipment;
         // 可能要加这一句
         Sleep(750);
         // 放片,更新当前搬送任务
         BOOL bOk = FALSE;
@@ -850,6 +1081,17 @@
               && m_pActiveRobotTask->getTarPosition() == p->getID()) {
               m_pActiveRobotTask->stored();
               m_pActiveRobotTask->completed();
               if (m_state == MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER) {
                  if (m_nContinuousTransferStep == CTStep_end) {
                     m_nContinuousTransferCount++;
                     LOGI("<ContinuousTransfer>千传测试,第 %d 轮结束", m_nContinuousTransferCount);
                     if (m_listener.onCTRoundEnd != nullptr) {
                        m_listener.onCTRoundEnd(this, m_nContinuousTransferCount);
                     }
                  }
               }
               LOGI("放片完成...");
               // 完成此条搬送任务,但要把数据和消息上抛应用层
               unlock();
@@ -891,10 +1133,10 @@
         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);
      listener.onPortStatusChanged = [&](void* pEquipment, short status, __int64 data) {
         LOGE("<Master-%s>onPortStatusChanged。status=%d, data=%lld", ((CEquipment*)pEquipment)->getName().c_str(), status);
         if (m_listener.onLoadPortStatusChanged != nullptr) {
            m_listener.onLoadPortStatusChanged(this, (CEquipment*)pEquipment, status, data);
         }
      };
      pEquipment->setListener(listener);
@@ -910,6 +1152,15 @@
   }
   CEquipment* CMaster::getEquipment(int id)
   {
      for (auto item : m_listEquipment) {
         if (item->getID() == id) return item;
      }
      return nullptr;
   }
   CEquipment* CMaster::getEquipment(int id) const
   {
      for (auto item : m_listEquipment) {
         if (item->getID() == id) return item;
@@ -1429,6 +1680,35 @@
      return pTask;
   }
   CRobotTask* CMaster::createTransferTask_continuous_transfer(CEquipment* pSrcEq, int nSrcSlot,
      CEquipment* pTarEq, int nTarSlot, int armNo/* = 1*/)
   {
      if (!pSrcEq->IsEnabled()) {
         return nullptr;
      }
      if (!pTarEq->IsEnabled()) {
         return nullptr;
      }
      CRobotTask* pTask = nullptr;
      CSlot* pSrcSlot = pSrcEq->getProcessedSlotCt(nSrcSlot);
      if (pSrcSlot != nullptr && pSrcEq->getID() == EQ_ID_MEASUREMENT
         && (pTarEq->getID() == EQ_ID_LOADPORT1 || pTarEq->getID() == EQ_ID_LOADPORT2 || pTarEq->getID() == EQ_ID_LOADPORT3 || pTarEq->getID() == EQ_ID_LOADPORT4)) {
         pTarEq->removeGlass(1);
      }
      CSlot* pTarSlot = pTarEq->isSlotAvailable(nTarSlot);
      if (pSrcSlot != nullptr && nullptr != pTarSlot) {
         pTask = new CRobotTask();
         pTask->setContext(pSrcSlot->getContext());
         pTask->setEFEM((CEFEM*)getEquipment(EQ_ID_EFEM));
         taskSeqNo = pTask->setRobotTransferParam(taskSeqNo, armNo, pSrcSlot->getPosition(),
            pTarSlot->getPosition(), pSrcSlot->getNo(), pTarSlot->getNo());
      }
      return pTask;
   }
   int CMaster::abortCurrentTask()
   {
      lock();
@@ -1501,6 +1781,14 @@
      pPort->localSetCessetteType(type);
   }
   void CMaster::setPortEnable(unsigned int index, BOOL bEnable)
   {
      ASSERT(index < 4);
      int eqid[] = { EQ_ID_LOADPORT1, EQ_ID_LOADPORT2, EQ_ID_LOADPORT3, EQ_ID_LOADPORT4 };
      CLoadPort* pPort = (CLoadPort*)getEquipment(eqid[index]);
      pPort->localEanblePort(bEnable);
   }
   void CMaster::setCompareMapsBeforeProceeding(BOOL bCompare)
   {
      m_isCompareMapsBeforeProceeding = bCompare;
@@ -1528,4 +1816,98 @@
   {
      return m_bEnableAlarmReport;
   }
   int CMaster::proceedWithCarrier(unsigned int port)
   {
      if (port >= 4) return -1;
      static int pid[] = { EQ_ID_LOADPORT1, EQ_ID_LOADPORT2, EQ_ID_LOADPORT3, EQ_ID_LOADPORT4};
      CLoadPort* pPort = (CLoadPort*)getEquipment(pid[port]);
      pPort->sendCassetteCtrlCmd(CCC_PROCESS_START, nullptr, 0, 0, 0, nullptr, nullptr);
      return 0;
   }
   int CMaster::carrierRelease(unsigned int port)
   {
      if (port >= 4) return -1;
      static int pid[] = { EQ_ID_LOADPORT1, EQ_ID_LOADPORT2, EQ_ID_LOADPORT3, EQ_ID_LOADPORT4 };
      CLoadPort* pPort = (CLoadPort*)getEquipment(pid[port]);
      pPort->sendCassetteCtrlCmd(CCC_PROCESS_CANCEL, nullptr, 0, 0, 0, nullptr, nullptr);
      return 0;
   }
   int CMaster::getContinuousTransferCount()
   {
      return m_nContinuousTransferCount;
   }
   void CMaster::setContinuousTransferCount(int round)
   {
      m_nContinuousTransferCount = round;
   }
   int CMaster::setProcessJobs(std::vector<SERVO::CProcessJob*>& pjs)
   {
      std::vector<SERVO::CProcessJob*> temp;
      for (auto p : pjs) {
         if (p->validate(*this)) {
            temp.push_back(p);
         }
      }
      m_processJobs = temp;
      return m_processJobs.size();
   }
   std::vector<SERVO::CProcessJob*>& CMaster::getProcessJobs()
   {
      return m_processJobs;
   }
   CLoadPort* CMaster::getPortWithCarrierId(const std::string& carrierId) const
   {
      CLoadPort* pPort;
      int eqid[] = { EQ_ID_LOADPORT1, EQ_ID_LOADPORT2, EQ_ID_LOADPORT3, EQ_ID_LOADPORT4};
      for (int i = 0; i < 4; i++) {
         pPort = (CLoadPort*)getEquipment(eqid[i]);
         ASSERT(pPort);
         if (pPort->getCassetteId().compare(carrierId) == 0) return pPort;
      }
      return nullptr;
   }
   bool CMaster::isProcessJobsEmpty() const
   {
      return m_processJobs.empty();
   }
   bool CMaster::recipeExists(const std::string& ppid) const
   {
      std::vector<std::string> vecRecipe = RecipeManager::getInstance().getAllPPID();
      bool exists = std::find(vecRecipe.begin(), vecRecipe.end(), ppid) != vecRecipe.end();
      return exists;
   }
   bool CMaster::carrierPresent(const std::string& carrierId) const
   {
      CLoadPort* pPort = getPortWithCarrierId(carrierId);
      return pPort != nullptr;
   }
   bool CMaster::slotUsable(const std::string& carrierId, uint16_t slot) const
   {
      CLoadPort* pPort = getPortWithCarrierId(carrierId);
      if(pPort == nullptr) return false;
      CSlot* pSlot = pPort->getSlot(slot);
      if (pSlot == nullptr) return false;
      return pSlot->isEnable();
   }
   bool CMaster::ceidDefined(uint32_t ceid) const
   {
      return true;
   }
}