#include "stdafx.h" #include "Common.h" #include "CMaster.h" #include #include #include "RecipeManager.h" #include #include "SerializeUtil.h" namespace SERVO { CMaster* g_pMaster = NULL; unsigned __stdcall DispatchThreadFunction(LPVOID lpParam) { if (g_pMaster != NULL) { return g_pMaster->DispatchProc(); } return 0; } unsigned __stdcall ReadBitsThreadFunction(LPVOID lpParam) { if (g_pMaster != NULL) { return g_pMaster->ReadBitsProc(); } return 0; } void CALLBACK MasterTimerProc(HWND hWnd, UINT nMsg, UINT nTimerid, DWORD dwTime) { if (g_pMaster != NULL) { g_pMaster->onTimer(nTimerid); } } CMaster::CMaster() { m_listener = {}; m_bDataModify = FALSE; m_hEventReadBitsThreadExit[0] = ::CreateEvent(NULL, TRUE, FALSE, NULL); m_hEventReadBitsThreadExit[1] = ::CreateEvent(NULL, TRUE, FALSE, NULL); m_hReadBitsThreadHandle = nullptr; m_nReadBitsThreadAddr = 0; m_hDispatchEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL); m_hEventDispatchThreadExit[0] = ::CreateEvent(NULL, TRUE, FALSE, NULL); m_hEventDispatchThreadExit[1] = ::CreateEvent(NULL, TRUE, FALSE, NULL); m_hDispatchThreadHandle = nullptr; m_nDispatchThreadAddr = 0; m_ullStartTime = 0; m_ullRunTime = 0; m_state = MASTERSTATE::READY; m_pActiveRobotTask = nullptr; m_nLastError = ER_CODE_NOERROR; m_isCompareMapsBeforeProceeding = FALSE; m_bJobMode = FALSE; m_bEnableEventReport = true; m_bEnableAlarmReport = true; m_bContinuousTransfer = false; m_bBatch = false; m_nContinuousTransferCount = 0; m_nContinuousTransferStep = CTStep_Unknow; m_nContinuousWorkingPort = 0; m_nContinuousWorkingSlot = 0; m_pControlJob = nullptr; m_nTestFlag = 0; InitializeCriticalSection(&m_criticalSection); } CMaster::~CMaster() { // ÊÍ·ÅJobÏà¹Ø for (auto item : m_processJobs) { delete item; } m_processJobs.clear(); if (m_pControlJob != nullptr) { delete m_pControlJob; m_pControlJob = nullptr; } if (m_hEventReadBitsThreadExit[0] != nullptr) { ::CloseHandle(m_hEventReadBitsThreadExit[0]); m_hEventReadBitsThreadExit[0] = nullptr; } if (m_hEventReadBitsThreadExit[1] != nullptr) { ::CloseHandle(m_hEventReadBitsThreadExit[1]); m_hEventReadBitsThreadExit[1] = nullptr; } if (m_hDispatchEvent != nullptr) { ::CloseHandle(m_hDispatchEvent); m_hDispatchEvent = nullptr; } if (m_hEventDispatchThreadExit[0] != nullptr) { ::CloseHandle(m_hEventDispatchThreadExit[0]); m_hEventDispatchThreadExit[0] = nullptr; } if (m_hEventDispatchThreadExit[1] != nullptr) { ::CloseHandle(m_hEventDispatchThreadExit[1]); m_hEventDispatchThreadExit[1] = nullptr; } DeleteCriticalSection(&m_criticalSection); } void CMaster::setListener(MasterListener listener) { m_listener = listener; } CRobotTask* CMaster::getActiveRobotTask() { return m_pActiveRobotTask; } int CMaster::init() { LOGI("ÕýÔÚ³õʼ»¯..."); // cclink if (m_cclink.Connect(CC_LINK_IE_CONTROL_CHANNEL(1)) != 0) { LOGE("Á¬½ÓCC-Linkʧ°Ü."); } else { LOGI("Á¬½ÓCC-Link³É¹¦."); BoardVersion version{}; int nRet = m_cclink.GetBoardVersion(version); if (nRet == 0) { LOGD("°æ±¾ÐÅÏ¢£º%s.", version.toString().c_str()); } else { LOGE("»ñÈ¡CC-Link°æ±¾ÐÅϢʧ°Ü."); } BoardStatus status; nRet = m_cclink.GetBoardStatus(status); if (nRet == 0) { LOGD("״̬£º%s.", status.toString().c_str()); } else { LOGE("»ñÈ¡CC-Link״̬ʧ°Ü."); } } // ³õʼ»¯Ìí¼Ó¸÷×ÓÉ豸 CLoadPort* pPort1, * pPort2, * pPort3, * pPort4; CBonder* pBonder1, * pBonder2; CEFEM* pEfem; CArm* pArm; CArmTray* pArmTray1, * pArmTray2; CFliper* pFliper; CVacuumBake* pVacuumBake; CAligner* pAligner; CBakeCooling* pBakeCooling; CMeasurement* pMeasurement; pPort1 = addLoadPort(0); pPort2 = addLoadPort(1); pPort3 = addLoadPort(2); pPort4 = addLoadPort(3); pEfem = addEFEM(); pArm = addArm(); pArmTray1 = addArmTray(0); pArmTray2 = addArmTray(1); pFliper = addFliper(); pVacuumBake = addVacuumBake(); pAligner = addAligner(); pBonder1 = addBonder(0); pBonder2 = addBonder(1); pBakeCooling = addBakeCooling(); pMeasurement = addMeasurement(); ASSERT(pEfem); ASSERT(pFliper); ASSERT(pVacuumBake); ASSERT(pAligner); ASSERT(pBonder1); ASSERT(pBonder2); ASSERT(pBakeCooling); ASSERT(pMeasurement); pEfem->setPort(0, pPort1); pEfem->setPort(1, pPort2); pEfem->setPort(2, pPort3); pEfem->setPort(3, pPort4); pEfem->setFliper(pFliper); pEfem->setAligner(pAligner); pEfem->setArmTray(0, pArmTray1); pEfem->setArmTray(1, pArmTray2); pPort1->setArm(pArm); pPort2->setArm(pArm); pPort3->setArm(pArm); pPort4->setArm(pArm); pArmTray1->setArm(pArm); pArmTray2->setArm(pArm); pFliper->setArm(pArm); pVacuumBake->setArm(pArm); pAligner->setArm(pArm); pBonder1->setArm(pArm); pBonder2->setArm(pArm); pBakeCooling->setArm(pArm); pMeasurement->setArm(pArm); connectEquipments(); // ¶Á»º´æÊý¾Ý readCache(); // ¶¨Ê±Æ÷ g_pMaster = this; SetTimer(NULL, 1, 250, (TIMERPROC)MasterTimerProc); // µ÷¶ÈÏß³Ì m_hDispatchThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::DispatchThreadFunction, this, 0, &m_nDispatchThreadAddr); // ¼à¿ØbitÏß³Ì m_hReadBitsThreadHandle = (HANDLE)_beginthreadex(NULL, 0, SERVO::ReadBitsThreadFunction, this, 0, &m_nReadBitsThreadAddr); LOGI("³õʼ»¯Íê³É."); return 0; } int CMaster::term() { SetEvent(m_hEventReadBitsThreadExit[0]); SetEvent(m_hEventDispatchThreadExit[0]); ::WaitForSingleObject(m_hEventReadBitsThreadExit[1], INFINITE); ::WaitForSingleObject(m_hEventDispatchThreadExit[1], INFINITE); LOGI("ÕýÔÚ½áÊø³ÌÐò."); for (auto item : m_listEquipment) { item->term(); } saveCache(); lock(); if (m_pActiveRobotTask != nullptr) { delete m_pActiveRobotTask; m_pActiveRobotTask = nullptr; } unlock(); for (auto item : m_listEquipment) { delete item; } m_listEquipment.clear(); return 0; } int CMaster::start() { if (m_state != MASTERSTATE::READY) { return -1; } m_bContinuousTransfer = false; m_bBatch = false; setState(MASTERSTATE::STARTING); m_ullStartTime = GetTickCount64(); return 0; } int CMaster::startContinuousTransfer() { if (m_state != MASTERSTATE::READY) { return -1; } m_bContinuousTransfer = true; m_bBatch = false; setState(MASTERSTATE::STARTING); m_ullStartTime = GetTickCount64(); return 0; } int CMaster::startBatch() { if (m_state != MASTERSTATE::READY) { return -1; } m_bContinuousTransfer = false; m_bBatch = true; setState(MASTERSTATE::STARTING); m_ullStartTime = GetTickCount64(); return 0; } int CMaster::stop(int nErCode/* = ER_CODE_NOERROR*/) { // ÔËÐÐʱ¼äΪÀÛ¼Ó½á¹û£¬±¾´ÎֹͣʱˢУ» lock(); if (m_state != MASTERSTATE::RUNNING && m_state != MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER && m_state != MASTERSTATE::RUNNING_BATCH) { unlock(); return -1; } m_ullRunTime += (GetTickCount64() - m_ullStartTime); unlock(); // ¸üÐÂ״̬ m_nLastError = nErCode; setState(MASTERSTATE::STOPPING); // ControlJobÔÝÍ£ lock(); if (m_pControlJob != nullptr) { m_pControlJob->pause(); saveState(); } unlock(); return 0; } void CMaster::clearError() { m_nLastError = 0; m_strLastError = ""; setState(MASTERSTATE::READY); } ULONGLONG CMaster::getRunTime() { if (m_state == MASTERSTATE::RUNNING || m_state == MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER || m_state == MASTERSTATE::RUNNING_BATCH) return m_ullRunTime + (GetTickCount64() - m_ullStartTime); else return m_ullRunTime; } MASTERSTATE CMaster::getState() { return m_state; } unsigned CMaster::DispatchProc() { // ÓÅÏÈ¿¼ÂǵÄÀàÐͺʹÎÒªÀàÐÍ // Ò»ÖÖÇé¿ö£¬Èç¹û²»·ÖÖ÷´Î£¬Ò»Ö±°áG1, µÈµ½Bonder1ºÍBonder2¶¼·ÅÁËG1, AlignerÒ²·ÅÁËG1, // Bonder1ºÍBonder2ÐèÒªµÄG2¾Í¹ý²»À´ÁË // ×î»ù±¾µÄʵÏÖ£¬¿ÉÒÔG2ºÍG2ÂÖÁ÷°áËÍ£¬µ«×îºÃ¸ù¾ÝBonderµÄÐèÇóÀ´¾ö¶¨ MaterialsType primaryType, secondaryType; // ¸÷ÖÖ»úÆ÷ CLoadPort* pLoadPorts[4]; CEFEM* pEFEM = (CEFEM*)getEquipment(EQ_ID_EFEM); 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); CBonder* pBonder1 = (CBonder*)getEquipment(EQ_ID_Bonder1); CBonder* pBonder2 = (CBonder*)getEquipment(EQ_ID_Bonder2); CBakeCooling* pBakeCooling = (CBakeCooling*)getEquipment(EQ_ID_BAKE_COOLING); CMeasurement* pMeasurement = (CMeasurement*)getEquipment(EQ_ID_MEASUREMENT); ASSERT(pEFEM); ASSERT(pLoadPorts[0]); ASSERT(pLoadPorts[1]); ASSERT(pLoadPorts[2]); ASSERT(pLoadPorts[3]); ASSERT(pFliper); ASSERT(pVacuumBake); ASSERT(pAligner); ASSERT(pBonder1); ASSERT(pBonder2); ASSERT(pBakeCooling); ASSERT(pMeasurement); while (1) { // ´ýÍ˳öÐźŻòʱ¼äµ½ HANDLE hEvents[] = { m_hEventDispatchThreadExit[0], m_hDispatchEvent }; int nRet = WaitForMultipleObjects(2, hEvents, FALSE, 500); if (nRet == WAIT_OBJECT_0) { break; } // Èç¹û״̬ΪSTARTING£¬¿ªÊ¼¹¤×÷²¢Çл»µ½RUNNING״̬ lock(); if (m_state == MASTERSTATE::STARTING) { // ·¢ËÍindexerOperationModeChangeµ½¸÷¸ö»ų́£¬³É¹¦ºóÇл»µ½RUNNING״̬ // ·ñÔòÇл»µ½MSERROR״̬ int nRet; CEquipment* pEq[6] = { pEFEM, pBonder1, pBonder2, pBakeCooling, pVacuumBake, pMeasurement}; BOOL bIomcOk[7] = {FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE}; std::vector> promises(6); std::vector> futures; nRet = pEq[0]->indexerOperationModeChange(IDNEXER_OPERATION_MODE::Start, [&](int writeCode, int retCode) -> void { bIomcOk[0] = retCode == (int)RET::OK; promises[0].set_value(); TRACE("a0001\n", writeCode, retCode); }); if (nRet != 0) { LOGE("EFEMÇл»Start״̬ʧ°Ü"); m_nLastError = ER_CODE_OPERATION_MODE_FAIL; m_strLastError = "EFEMÇл»Start״̬ʧ°Ü."; goto WAIT; } futures.push_back(promises[0].get_future()); /* nRet = pEq[1]->indexerOperationModeChange(IDNEXER_OPERATION_MODE::Start, [&](int writeCode, int retCode) -> void { bIomcOk[1] = retCode == (int)RET::OK; promises[1].set_value(); TRACE("a0002\n"); }); if (nRet != 0) { LOGE("Bonder1Çл»Start״̬ʧ°Ü"); m_nLastError = ER_CODE_BONDER_OPERATION_MODE_FAIL; m_strLastError = "Bonder1Çл»Start״̬ʧ°Ü."; goto WAIT; } futures.push_back(promises[1].get_future()); nRet = pEq[2]->indexerOperationModeChange(IDNEXER_OPERATION_MODE::Start, [&](int writeCode, int retCode) -> void { bIomcOk[2] = retCode == (int)RET::OK; promises[2].set_value(); TRACE("a0003\n"); }); if (nRet != 0) { LOGE("Bonder2Çл»Start״̬ʧ°Ü"); m_nLastError = ER_CODE_BONDER_OPERATION_MODE_FAIL; m_strLastError = "Bonder2Çл»Start״̬ʧ°Ü."; goto WAIT; } futures.push_back(promises[2].get_future()); nRet = pEq[3]->indexerOperationModeChange(IDNEXER_OPERATION_MODE::Start, [&](int writeCode, int retCode) -> void { bIomcOk[3] = retCode == (int)RET::OK; promises[3].set_value(); TRACE("a0004\n"); }); if (nRet != 0) { LOGE("BakeCoolingÇл»Start״̬ʧ°Ü"); m_nLastError = ER_CODE_OPERATION_MODE_FAIL; m_strLastError = "BakeCoolingÇл»Start״̬ʧ°Ü."; goto WAIT; } futures.push_back(promises[3].get_future()); nRet = pEq[4]->indexerOperationModeChange(IDNEXER_OPERATION_MODE::Start, [&](int writeCode, int retCode) -> void { bIomcOk[4] = retCode == (int)RET::OK; promises[4].set_value(); TRACE("a0005\n"); }); if (nRet != 0) { LOGE("VacuumBakeÇл»Start״̬ʧ°Ü"); m_nLastError = ER_CODE_OPERATION_MODE_FAIL; m_strLastError = "VacuumBakeÇл»Start״̬ʧ°Ü."; goto WAIT; } futures.push_back(promises[4].get_future()); nRet = pEq[5]->indexerOperationModeChange(IDNEXER_OPERATION_MODE::Start, [&](int writeCode, int retCode) -> void { bIomcOk[5] = retCode == (int)RET::OK; promises[5].set_value(); TRACE("a0006\n"); }); if (nRet != 0) { LOGE("MeasurementÇл»Start״̬ʧ°Ü"); m_nLastError = ER_CODE_OPERATION_MODE_FAIL; m_strLastError = "MeasurementÇл»Start״̬ʧ°Ü."; goto WAIT; } futures.push_back(promises[5].get_future()); */ WAIT: for (auto& f : futures) { f.wait(); // ×èÈûµÈ´ý¶ÔÓ¦É豸Íê³É } for (int i = 0; i < 6; i++) { if (!bIomcOk[i]) { bIomcOk[6] = FALSE; LOGE("%sÇл»Start״̬ʧ°Ü", pEq[i]->getName().c_str()); } } // ¼ì²é¿´ÊÇ·ñ¶¼ÒѾ­Çл»µ½START״̬ if (!bIomcOk[6]) { unlock(); setState(MASTERSTATE::MSERROR); continue; } unlock(); if(m_bContinuousTransfer) setState(MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER); else if (m_bBatch) setState(MASTERSTATE::RUNNING_BATCH); else setState(MASTERSTATE::RUNNING); continue; } // ´¦ÀíÍê³Éµ±Ç°ÊÂÎñºó£¬Çл»µ½Í£Ö¹»ò¾ÍÐ÷״̬ else if (m_state == MASTERSTATE::STOPPING) { unlock(); LOGI("¿ªÊ¼Çл»¸÷É豸µ½ Stop ģʽ..."); std::vector> promises(6); std::vector> futures; BOOL bIomcOk[7] = { FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }; int nRet; CEquipment* pEq[6] = { pEFEM, pBonder1, pBonder2, pBakeCooling, pVacuumBake, pMeasurement }; for (int i = 0; i < 1; ++i) { nRet = pEq[i]->indexerOperationModeChange(IDNEXER_OPERATION_MODE::Stop, [i, &promises, &bIomcOk](int writeCode, int retCode) -> void { bIomcOk[i] = retCode == (int)RET::OK; promises[i].set_value(); TRACE("s000%d: ret=%d\n", i + 1, retCode); }); if (nRet != 0) { LOGE("%sÇл»Stop״̬·¢ËÍʧ°Ü", pEq[i]->getName().c_str()); m_nLastError = ER_CODE_OPERATION_MODE_FAIL; m_strLastError = pEq[i]->getName() + "Çл»Stop״̬·¢ËÍʧ°Ü."; bIomcOk[i] = FALSE; promises[i].set_value(); // ±ÜÃâ wait ×èÈû } futures.push_back(promises[i].get_future()); } for (auto& f : futures) { f.wait(); // µÈ´ýËùÓÐÍê³É } for (int i = 0; i < 6; ++i) { if (!bIomcOk[i]) { bIomcOk[6] = FALSE; LOGE("%sÇл»Stop״̬ʧ°Ü", pEq[i]->getName().c_str()); } } if (!bIomcOk[6]) { setState(MASTERSTATE::MSERROR); continue; } LOGI("ËùÓÐÉ豸³É¹¦Çл»µ½ Stop ģʽ"); if(m_nLastError == ER_CODE_NOERROR) setState(MASTERSTATE::READY); else setState(MASTERSTATE::ATHERERROR); continue; } // µ÷¶ÈÂß¼­´¦Àí else if (m_state == MASTERSTATE::RUNNING) { // ¼ì²âÅжÏ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; } // Bonder1¡¢Bonder2¡¢Fliper¡¢VacuumBake¡¢Aligner£¬Í³¼ÆG2ºÍG1µÄÊýÁ¿, Åä¶Ô×éÊý, ¶à³öµÄÀàÐÍ int nG2Count = 0, nG1Count = 0, nGlassGroup, nExtraType; if (pBonder1->slotHasGlass(0)) { nG2Count++; } if (pBonder1->slotHasGlass(1)) { nG1Count++; } if (pBonder2->slotHasGlass(0)) { nG2Count++; } if (pBonder2->slotHasGlass(1)) { nG1Count++; } if (pFliper->slotHasGlass(0)) { nG2Count++; } if (pVacuumBake->slotHasGlass(0)) { nG1Count++; } if (pVacuumBake->slotHasGlass(1)) { nG1Count++; } CGlass* pTempGlass = pAligner->getGlassFromSlot(0); if (pTempGlass != nullptr) { MaterialsType type = pTempGlass->getType(); if(type == MaterialsType::G1) nG1Count++; else if (type == MaterialsType::G2) nG2Count++; } nGlassGroup = min(nG1Count, nG2Count); if (nG1Count == nG2Count) { nExtraType = 0; } else if (nG1Count > nG2Count) { nExtraType = 1; } else { nExtraType = 2; } secondaryType = MaterialsType::G0; // Measurement -> LoadPort for (int s = 0; s < 4; s++) { PortType pt = pLoadPorts[s]->getPortType(); if (!rmd.armState[0] && pLoadPorts[s]->isEnable() && (pt == PortType::Unloading || pt == PortType::Both) && pLoadPorts[s]->getPortStatus() == PORT_INUSE) { m_pActiveRobotTask = createTransferTask(pMeasurement, pLoadPorts[s], MaterialsType::G1, secondaryType); if (m_pActiveRobotTask != nullptr) { goto PORT_PUT; } } } PORT_PUT: CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); // Measurement NG -> LoadPort // NG»ØÔ­Î» if (!rmd.armState[1]) { m_pActiveRobotTask = createTransferTask_restore(pMeasurement, pLoadPorts); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } // BakeCooling ->Measurement if (!rmd.armState[0]) { m_pActiveRobotTask = createTransferTask_bakecooling_to_measurement(pBakeCooling, pMeasurement); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } // BakeCoolingÄÚ²¿ // Bake -> Cooling if (!rmd.armState[0]) { m_pActiveRobotTask = createTransferTask_bake_to_cooling(pBakeCooling); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } // Bonder -> BakeCooling if (!rmd.armState[0]) { m_pActiveRobotTask = createTransferTask_bonder_to_bakecooling(pBonder1, pBakeCooling); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } if (!rmd.armState[0]) { m_pActiveRobotTask = createTransferTask_bonder_to_bakecooling(pBonder2, pBakeCooling); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } // Fliper(G2) -> Bonder //m_nTestFlag = 1; //pVacuumBake->m_nTestFlag = 1; auto pSrcSlot = pVacuumBake->getProcessedSlot(MaterialsType::G1); //LOGI("pSrcSlot = %x", pSrcSlot,); if (pSrcSlot != nullptr && !rmd.armState[1] && pBonder1->canPlaceGlassInSlot(0)) { m_pActiveRobotTask = createTransferTask(pFliper, pBonder1, MaterialsType::G2, MaterialsType::G0, 2); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } if (pSrcSlot != nullptr && !rmd.armState[1] && pBonder2->canPlaceGlassInSlot(0)) { m_pActiveRobotTask = createTransferTask(pFliper, pBonder2, MaterialsType::G2, MaterialsType::G0, 2); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } //m_nTestFlag = 0 ; // VacuumBake(G1) -> Bonder if (!rmd.armState[0] && pBonder1->slotHasGlass(0) && !pBonder1->slotHasGlass(1)) { m_pActiveRobotTask = createTransferTask(pVacuumBake, pBonder1, MaterialsType::G1, MaterialsType::G0); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } if (!rmd.armState[0] && pBonder2->slotHasGlass(0) && !pBonder2->slotHasGlass(1)) { m_pActiveRobotTask = createTransferTask(pVacuumBake, pBonder2, MaterialsType::G1, MaterialsType::G0); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } // Aligner -> Fliper(G2) // Aligner -> VacuumBake(G1) if (!rmd.armState[1]) { m_pActiveRobotTask = createTransferTask(pAligner, pFliper, MaterialsType::G2, secondaryType); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } if (!rmd.armState[0]) { // m_nTestFlag = 1; if (m_nTestFlag == 1) LOGD("createTransferTask 004df %d, %d", MaterialsType::G1, secondaryType); m_pActiveRobotTask = createTransferTask(pAligner, pVacuumBake, MaterialsType::G1, secondaryType); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); m_nTestFlag = 0; } // Aligner -> LoadPort if (!rmd.armState[1]) { m_pActiveRobotTask = createTransferTask_restore(pAligner, pLoadPorts); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } // LoadPort -> Aligner if (nGlassGroup >= 2) { unlock(); continue; } if(nExtraType == 0) primaryType = MaterialsType::G2; else { primaryType = MaterialsType::G1; } for (int s = 0; s < 4; s++) { PortType pt = pLoadPorts[s]->getPortType(); if (!rmd.armState[0] && pLoadPorts[s]->isEnable() && (pt == PortType::Loading || pt == PortType::Both) && pLoadPorts[s]->getPortStatus() == PORT_INUSE) { m_pActiveRobotTask = createTransferTask(pLoadPorts[s], pAligner, primaryType, secondaryType, 1, m_bJobMode); if (m_pActiveRobotTask != nullptr) { CGlass* pGlass = (CGlass*)m_pActiveRobotTask->getContext(); if (pGlass->getBuddy() != nullptr) { delete m_pActiveRobotTask; m_pActiveRobotTask = nullptr; continue; } pGlass->queue(); pGlass->start(); pEFEM->setContext(m_pActiveRobotTask->getContext()); goto PORT_GET; } } } PORT_GET: CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); unlock(); continue; } // Åú´¦Àíģʽ£¬×îÖÕÒÔ´ËΪ׼£¬µ«Ïȱ£Áô֮ǰµÄµ¥Æ¬Ä£Ê½ else if (m_state == MASTERSTATE::RUNNING_BATCH) { // Ê×Ñ¡¼ì²éÓÐûÓÐCControlJob, ״̬µÈ if (m_pControlJob == nullptr) { unlock(); continue; } CJState state = m_pControlJob->state(); if (state == CJState::Completed || state == CJState::Aborted || state == CJState::Failed) { // ConrolJpbÒÑÍê³É LOGE("ControlJobÒѾ­Íê³É»òʧ°ÜÖжÏ"); unlock(); continue; } if (m_pControlJob->state() == CJState::NoState) { LOGI("ControlJobÒѾ­½øÈëÁжÓ"); m_pControlJob->queue(); } if (m_pControlJob->state() == CJState::Queued) { LOGI("ControlJobÒѾ­Æô¶¯"); m_pControlJob->start(); if (m_listener.onCjStart != nullptr) { m_listener.onCjStart(this, m_pControlJob); } } if (m_pControlJob->state() == CJState::Paused) { LOGI("ControlJobÒѾ­»Ö¸´ÔËÐÐ"); m_pControlJob->resume(); } // Èç¹ûµ±Ç°Î´Ñ¡ÔñCProcessJob, Ñ¡ÔñÒ»¸ö if (m_inProcesJobs.empty()) { auto pj = acquireNextProcessJob(); if (pj != nullptr) { m_inProcesJobs.push_back(pj); // ÕâÀïÉϱ¨PJ Startʼþ if (m_listener.onPjStart != nullptr) { m_listener.onPjStart(this, pj); } } } if (m_inProcesJobs.empty()) { LOGE("Ñ¡Ôñµ±Ç°ProcessJobʧ°Ü£¡"); unlock(); continue; } // Èç¹ûµ±Ç°Ã»ÓÐGlass, Ñ¡Ôñ if (m_queueGlasses.empty()) { int nCount = acquireGlassToQueue(); LOGI("ÒѼÓÈë %d ¿éGlassµ½¹¤ÒÕÁжӣ¡", nCount); } // ¼ì²âÅжÏ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; } // ´Ë´¦¼ì²âÓÅÏÈÀàÐͺʹÎÒªÀàÐÍ£¨G1»òG2£© // Èç¹ûÆäÖÐÒ»BonderÓе¥¸ö²£Á§£¬ÓÅÏÈÈ¡ËüµÄÅä¶ÔÀàÐÍ£¬·ñÔòÎÞËùνÁË primaryType = MaterialsType::G1; secondaryType = MaterialsType::G2; if ((!pBonder1->canPlaceGlassInSlot(0) && !pBonder1->canPlaceGlassInSlot(1)) && (!pBonder2->canPlaceGlassInSlot(0) && !pBonder2->canPlaceGlassInSlot(1))) { // Èç¹ûG1ºÍG2¶¼ÂúÁË£¬ÄǾͿ´Aligner, Èç¹ûAlignerÓв£Á§ÎªG1, ÔòÈ¡G2 CGlass* pGlass = pAligner->getGlassFromSlot(1); if (pGlass != nullptr && pGlass->getType() == MaterialsType::G1) { primaryType = MaterialsType::G2; secondaryType = MaterialsType::G1; } } else if ((pBonder1->canPlaceGlassInSlot(0) && !pBonder1->canPlaceGlassInSlot(1)) || (pBonder2->canPlaceGlassInSlot(0) && !pBonder2->canPlaceGlassInSlot(1))) { primaryType = MaterialsType::G2; secondaryType = MaterialsType::G1; } // Measurement -> LoadPort if (rmd.armState[0] || rmd.armState[1]) { LOGD("Arm1 %s, Arm2 %s.", rmd.armState[0] ? _T("²»¿ÉÓÃ") : _T("¿ÉÓÃ"), rmd.armState[1] ? _T("²»¿ÉÓÃ") : _T("¿ÉÓÃ")); } for (int s = 0; s < 4; s++) { PortType pt = pLoadPorts[s]->getPortType(); if (!rmd.armState[0] && pLoadPorts[s]->isEnable() && (pt == PortType::Unloading || pt == PortType::Both) && pLoadPorts[s]->getPortStatus() == PORT_INUSE) { m_pActiveRobotTask = createTransferTask(pMeasurement, pLoadPorts[s], primaryType, secondaryType); if (m_pActiveRobotTask != nullptr) { goto BATCH_PORT_PUT; } } } BATCH_PORT_PUT: CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); // Measurement NG -> LoadPort // NG»ØÔ­Î» if (!rmd.armState[1]) { m_pActiveRobotTask = createTransferTask_restore(pMeasurement, pLoadPorts); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } // BakeCooling ->Measurement if (!rmd.armState[0]) { m_pActiveRobotTask = createTransferTask_bakecooling_to_measurement(pBakeCooling, pMeasurement); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } // BakeCoolingÄÚ²¿ // Bake -> Cooling if (!rmd.armState[0]) { m_pActiveRobotTask = createTransferTask_bake_to_cooling(pBakeCooling); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } // Bonder -> BakeCooling if (!rmd.armState[0]) { m_pActiveRobotTask = createTransferTask_bonder_to_bakecooling(pBonder1, pBakeCooling); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } if (!rmd.armState[0]) { m_pActiveRobotTask = createTransferTask_bonder_to_bakecooling(pBonder2, pBakeCooling); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } // Fliper(G2) -> Bonder auto pSrcSlot = pVacuumBake->getProcessedSlot(primaryType); if (pSrcSlot != nullptr && !rmd.armState[1] && !pBonder1->hasBondGlass()) { m_pActiveRobotTask = createTransferTask(pFliper, pBonder1, primaryType, secondaryType, 2); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } if (pSrcSlot != nullptr && !rmd.armState[1] && !pBonder2->hasBondGlass()) { m_pActiveRobotTask = createTransferTask(pFliper, pBonder2, primaryType, secondaryType, 2); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } // VacuumBake(G1) -> Bonder if (!rmd.armState[0] && !pBonder1->hasBondGlass()) { m_pActiveRobotTask = createTransferTask(pVacuumBake, pBonder1, primaryType, secondaryType); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } if (!rmd.armState[0] && !pBonder2->hasBondGlass()) { m_pActiveRobotTask = createTransferTask(pVacuumBake, pBonder2, primaryType, secondaryType); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } // Aligner -> Fliper(G2) // Aligner -> VacuumBake(G1) if (!rmd.armState[1]) { m_pActiveRobotTask = createTransferTask(pAligner, pFliper, primaryType, secondaryType); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } if (!rmd.armState[0]) { m_pActiveRobotTask = createTransferTask(pAligner, pVacuumBake, primaryType, secondaryType); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } // Aligner -> LoadPort if (!rmd.armState[1]) { m_pActiveRobotTask = createTransferTask_restore(pAligner, pLoadPorts); CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } // LoadPort -> Aligner for (int s = 0; s < 4; s++) { PortType pt = pLoadPorts[s]->getPortType(); if (!rmd.armState[0] && pLoadPorts[s]->isEnable() && (pt == PortType::Loading || pt == PortType::Both) && pLoadPorts[s]->getPortStatus() == PORT_INUSE) { m_pActiveRobotTask = createTransferTask(pLoadPorts[s], pAligner, primaryType, secondaryType, m_bJobMode); if (m_pActiveRobotTask != nullptr) { CGlass* pGlass = (CGlass*)m_pActiveRobotTask->getContext(); if (pGlass->getBuddy() != nullptr) { delete m_pActiveRobotTask; m_pActiveRobotTask = nullptr; continue; } pEFEM->setContext(pGlass); pGlass->start(); bool bMoved = glassFromQueueToInPorcess(pGlass); if (bMoved) { LOGI("Glass(%s)´ÓµÈ´ýÁжӵ½¹¤ÒÕÁжÓ×ªÒÆ³É¹¦.", pGlass->getID().c_str()); } else { LOGE("Glass(%s)´ÓµÈ´ýÁжӵ½¹¤ÒÕÁжÓ×ªÒÆÊ§°Ü.", pGlass->getID().c_str()); } // ÕâÀïÉϱ¨Panel Startʼþ if (m_listener.onPanelStart != nullptr) { m_listener.onPanelStart(this, pGlass); } goto BATCH_PORT_GET; } } } BATCH_PORT_GET: CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); 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 p = 0; p < 4; p++) { if (p != m_nContinuousWorkingPort) continue; PortType pt = pLoadPorts[p]->getPortType(); if ((m_nContinuousTransferStep == CTStep_Unknow || m_nContinuousTransferStep == CTStep_BakeCooling_Measurement) && !rmd.armState[0] && pLoadPorts[p]->isEnable() && (pt == PortType::Unloading || pt == PortType::Both) && pLoadPorts[p]->getPortStatus() == PORT_INUSE) { for (int slot = 0; slot < SLOT_MAX; slot++) { if (slot != m_nContinuousWorkingSlot) continue; m_pActiveRobotTask = createTransferTask_continuous_transfer(pMeasurement, 0, pLoadPorts[p], 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("ǧ´«²âÊÔ£¬¿ªÊ¼°áËÍÈÎÎñ(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("ǧ´«²âÊÔ£¬¿ªÊ¼°áËÍÈÎÎñ(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("ǧ´«²âÊÔ£¬¿ªÊ¼°áËÍÈÎÎñ(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("ǧ´«²âÊÔ£¬¿ªÊ¼°áËÍÈÎÎñ(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("ǧ´«²âÊÔ£¬¿ªÊ¼°áËÍÈÎÎñ(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("ǧ´«²âÊÔ£¬¿ªÊ¼°áËÍÈÎÎñ(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("ǧ´«²âÊÔ£¬¿ªÊ¼°áËÍÈÎÎñ(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->hasBondGlass()) { m_pActiveRobotTask = createTransferTask_continuous_transfer(pBonder1, 1, pBonder2, 1); if (m_pActiveRobotTask != nullptr) { m_nContinuousTransferStep = CTStep_Bonder1_Bonder2; LOGI("ǧ´«²âÊÔ£¬¿ªÊ¼°áËÍÈÎÎñ(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->hasBondGlass()) { m_pActiveRobotTask = createTransferTask_continuous_transfer(pFliper, 0, pBonder1, 1); if (m_pActiveRobotTask != nullptr) { m_nContinuousTransferStep = CTStep_Fliper_Bonder1; LOGI("ǧ´«²âÊÔ£¬¿ªÊ¼°áËÍÈÎÎñ(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("ǧ´«²âÊÔ£¬¿ªÊ¼°áËÍÈÎÎñ(Aligner -> Fliper(G2))..."); } CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); } // LoadPort -> Aligner for (int p = 0; p < 4; p++) { PortType pt = pLoadPorts[p]->getPortType(); if ((m_nContinuousTransferStep == CTStep_Unknow || m_nContinuousTransferStep == CTStep_end) && !rmd.armState[0] && pLoadPorts[p]->isEnable() && (pt == PortType::Loading || pt == PortType::Both) && pLoadPorts[p]->getPortStatus() == PORT_INUSE) { for (int slot = 0; slot < SLOT_MAX; slot++) { m_pActiveRobotTask = createTransferTask_continuous_transfer(pLoadPorts[p], slot, pAligner, 0); if (m_pActiveRobotTask != nullptr) { m_nContinuousTransferStep = CTStep_LoadPort_Aligner; m_nContinuousWorkingPort = p; m_nContinuousWorkingSlot = slot; LOGI("ǧ´«²âÊÔ£¬¿ªÊ¼°áËÍÈÎÎñ(LoadPort -> Aligner)..."); pEFEM->setContext(m_pActiveRobotTask->getContext()); goto CT_PORT_GET; } } } } CT_PORT_GET: if (m_pActiveRobotTask != nullptr) { m_nContinuousTransferStep = CTStep_begin; LOGI("ǧ´«²âÊÔ£¬¿ªÊ¼µÚ %d ÂÖ", m_nContinuousTransferCount + 1); } CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); unlock(); continue; } unlock(); } SetEvent(m_hEventDispatchThreadExit[1]); // _endthreadex(0); TRACE("CMaster::DispatchProc Ïß³ÌÍ˳ö\n"); return 0; } 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); if (nRet == WAIT_OBJECT_0) { break; } // ¶Á±ê־λ for (auto item : m_listEquipment) { const StationIdentifier& station = item->getStation(); MemoryBlock& block = item->getReadBitBlock(); 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); } } } } SetEvent(m_hEventReadBitsThreadExit[1]); // _endthreadex(0); TRACE("CMaster::ReadBitsProc Ïß³ÌÍ˳ö\n"); return 0; } int CMaster::addToEquipmentList(CEquipment* pEquipment) { EquipmentListener listener; listener.onAlive = [&](void* pEquipment, BOOL bAlive) -> void { CEquipment* p = (CEquipment*)pEquipment; if (m_listener.onEqAlive != nullptr) { m_listener.onEqAlive(this, p, bAlive); } }; listener.onCimStateChanged = [&](void* pEquipment, BOOL bOn) -> void { CEquipment* p = (CEquipment*)pEquipment; if (m_listener.onEqCimStateChanged != nullptr) { m_listener.onEqCimStateChanged(this, p, bOn); } }; listener.onAlarm = [&](void* pEquipment, int state, int alarmId, int unitId, int level) -> void { CEquipment* p = (CEquipment*)pEquipment; if (m_listener.onEqAlarm != nullptr) { m_listener.onEqAlarm(this, p, state, alarmId, unitId, level); } }; listener.onVcrEventReport = [&](void* pEquipment, void* pReport) -> void { CEquipment* p = (CEquipment*)pEquipment; CVcrEventReport* p2 = (CVcrEventReport*)pReport; if (m_listener.onEqVcrEventReport != nullptr) { m_listener.onEqVcrEventReport(this, p, p2); } }; listener.onPreFethedOutJob = [&](void* pEquipment, int port, CJobDataB* pJobDataB) -> BOOL { CEquipment* p = (CEquipment*)pEquipment; // ¿ÉÄÜÒª¼ÓÕâÒ»¾ä Sleep(750); // ȡƬ£¬¸üе±Ç°°áËÍÈÎÎñ BOOL bOk = FALSE; lock(); if (m_pActiveRobotTask != nullptr) { LOGD("onPreFethedOutJob 0001."); if (m_pActiveRobotTask->getSrcPosition() == p->getID()) { LOGD("onPreFethedOutJob 0002."); CGlass* pGlass = p->getGlassFromSlot(m_pActiveRobotTask->getSrcSlot()); if (pGlass != nullptr) { LOGD("onPreFethedOutJob 0003."); CJobDataS* pJobDataS = pGlass->getJobDataS(); if (pJobDataS != nullptr && pJobDataS->getCassetteSequenceNo() == pJobDataB->getCassetteSequenceNo() && pJobDataS->getJobSequenceNo() == pJobDataB->getJobSequenceNo()) { bOk = TRUE; LOGD("onPreFethedOutJob, ÒÑУÑéÊý¾ÝÒ»ÖÂÐÔ."); } LOGD("onPreFethedOutJob 0004."); if (pJobDataS != nullptr) { LOGD("onPreFethedOutJob 0005. %d,%d,%d,%d", pJobDataS->getCassetteSequenceNo(), pJobDataB->getCassetteSequenceNo(), pJobDataS->getJobSequenceNo(), pJobDataB->getJobSequenceNo() ); } } } else if (p->getID() == EQ_ID_ARM_TRAY1 || p->getID() == EQ_ID_ARM_TRAY2) { bOk = TRUE; } } unlock(); if (!bOk) { LOGE("onPreFethedOutJob, Êý¾ÝУÑéʧ°Ü."); } return bOk; }; listener.onPreStoredJob = [&](void* pEquipment, int port, CJobDataB* pJobDataB, short& slot) -> BOOL { CEquipment* p = (CEquipment*)pEquipment; // ¿ÉÄÜÒª¼ÓÕâÒ»¾ä Sleep(750); // ·ÅƬ£¬¸üе±Ç°°áËÍÈÎÎñ BOOL bOk = FALSE; lock(); if (m_pActiveRobotTask != nullptr) { // ÊÇ·ñÒѾ­½øÈëÊÖ±Û(¼´È¡Æ¬Íê³É),½øÈëÏÂÒ»²½£¬·ÅƬ if (m_pActiveRobotTask->isPicking() && ((m_pActiveRobotTask->getArmNo() == 1 && p->getID() == EQ_ID_ARM_TRAY1) || (m_pActiveRobotTask->getArmNo() == 2 && p->getID() == EQ_ID_ARM_TRAY2)) ) { slot = 1; bOk = TRUE; } // ÊÇ·ñ·ÅƬÍê³É else if (m_pActiveRobotTask->isPlacing() && m_pActiveRobotTask->getTarPosition() == p->getID()) { CGlass* pGlass = p->getGlassFromSlot(m_pActiveRobotTask->getTarSlot()); if (pGlass == nullptr) { bOk = TRUE; slot = m_pActiveRobotTask->getTarSlot(); LOGI("onPreStoredJob, ÒÑУÑéÊý¾ÝÒ»ÖÂÐÔ."); } } // ÊÇ·ñ»Ø³· 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("onPreStoredJob, ÒÑУÑéÊý¾ÝÒ»ÖÂÐÔ."); } } } unlock(); if (!bOk) { LOGE("onPreStoredJob, Êý¾ÝУÑéʧ°Ü."); } return bOk; }; listener.onDataChanged = [&](void* pEquipment, int code) -> void { m_bDataModify = TRUE; CEquipment* p = (CEquipment*)pEquipment; if (m_listener.onEqDataChanged != nullptr) { m_listener.onEqDataChanged(this, p, 0); } // È¡·ÅƬ£¬¸üе±Ç°°áËÍÈÎÎñ if (code == EDCC_FETCHOUT_JOB) { lock(); if (m_pActiveRobotTask != nullptr && m_pActiveRobotTask->getSrcPosition() == p->getID()) { LOGI("¿ªÊ¼È¡Æ¬..."); } unlock(); } else if (code == EDCC_STORED_JOB) { lock(); if (m_pActiveRobotTask != nullptr && m_pActiveRobotTask->isPicking() && ((m_pActiveRobotTask->getArmNo() == 1 && p->getID() == EQ_ID_ARM_TRAY1) || (m_pActiveRobotTask->getArmNo() == 2 && p->getID() == EQ_ID_ARM_TRAY2)) ) { LOGI("ȡƬÍê³É."); m_pActiveRobotTask->fetchOut(); m_pActiveRobotTask->picked(); } else if (m_pActiveRobotTask != nullptr && m_pActiveRobotTask->isPlacing() && 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("ǧ´«²âÊÔ£¬µÚ %d ÂÖ½áÊø", m_nContinuousTransferCount); if (m_listener.onCTRoundEnd != nullptr) { m_listener.onCTRoundEnd(this, m_nContinuousTransferCount); } } } LOGI("·ÅƬÍê³É..."); // Íê³É´ËÌõ°áËÍÈÎÎñ£¬µ«Òª°ÑÊý¾ÝºÍÏûÏ¢ÉÏÅ×Ó¦Óòã // Èç¹ûÊǰáËͻشÓAOI°áËÍ»ØPort, Ôòglass¹¤ÒÕÍê³É if (m_pActiveRobotTask->getSrcPosition() == EQ_ID_MEASUREMENT) { CGlass* pGlass = (CGlass*)m_pActiveRobotTask->getContext(); pGlass->complete(); CGlass* pBuddy = pGlass->getBuddy(); if (pBuddy != nullptr) pBuddy->complete(); this->saveState(); bool bMoved = glassFromInPorcessToComplete(pGlass); if (bMoved) { LOGI("Glass(%s)´Ó¹¤ÒÕÁжӵ½Íê³ÉÁжÓ×ªÒÆ³É¹¦.", pGlass->getID().c_str()); } else { LOGE("Glass(%s)´Ó¹¤ÒÕÁжӵ½Íê³ÉÁжÓ×ªÒÆÊ§°Ü.", pGlass->getID().c_str()); } if (m_listener.onPanelEnd != nullptr) { m_listener.onPanelEnd(this, pGlass); } // ¼ì²éPJÊÇ·ñÒѾ­Íê³É CProcessJob* pJob = getGlassProcessJob((CGlass*)m_pActiveRobotTask->getContext()); if (pJob != nullptr && checkAndUpdatePjComplete(pJob)) { this->saveState(); LOGE("ProcessJob(%s)Íê³É.", pJob->id().c_str()); if (m_listener.onPjEnd != nullptr) { m_listener.onPjEnd(this, pJob); } // ¼ì²éCJÊÇ·ñÒѾ­Íê³É ASSERT(m_pControlJob); if (checkAndUpdateCjComplete(m_pControlJob)) { this->saveState(); LOGE("ControlJob(%s)Íê³É.", m_pControlJob->id().c_str()); if (m_listener.onCjEnd != nullptr) { m_listener.onCjEnd(this, pJob); } } } } unlock(); lock(); if (m_listener.onRobotTaskEvent != nullptr) { m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_FINISH); } 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("onProcessStateChanged<%d>", (int)state); }; listener.onMapMismatch = [&](void* pEquipment, short scanMap, short downMap) { LOGE("Port InUse, map(%d!=%d)²»Ò»Ö£¬Çë¼ì²é¡£", ((CEquipment*)pEquipment)->getName().c_str(), scanMap, downMap); }; listener.onPortStatusChanged = [&](void* pEquipment, short status, __int64 data) { LOGE("onPortStatusChanged¡£status=%d, data=%lld", ((CEquipment*)pEquipment)->getName().c_str(), status); if (status == PORT_INUSE && m_pControlJob != nullptr) { CLoadPort* pPort = (CLoadPort*)pEquipment; auto pjs = m_pControlJob->getPjs(); for (auto pj : pjs) { auto carrier = pj->getCarrier(pPort->getCassetteId()); if (carrier != nullptr) { for (auto slot : carrier->slots) { CGlass* pGlass = pPort->getGlassFromSlot(slot); carrier->contexts.push_back((void*)pGlass); if (pGlass != nullptr) { pGlass->setProcessJob(pj); } } } } } if (m_listener.onLoadPortStatusChanged != nullptr) { m_listener.onLoadPortStatusChanged(this, (CEquipment*)pEquipment, status, data); } }; listener.onSVDataReport = [&](void* pEquipment, void* pData) { CSVData* pSVData = (CSVData*)pData; auto rawData = pSVData->getSVRawData(); std::vector params; ((CEquipment*)pEquipment)->parsingSVData((const char*)rawData.data(), rawData.size(), params); std::string strOut; char szBuffer[256]; for (auto p : params) { if (!strOut.empty()) strOut.append(","); if (p.getValueType() == PVT_INT) { sprintf_s(szBuffer, 256, "%s:%d", p.getName().c_str(), p.getIntValue()); } else if (p.getValueType() == PVT_DOUBLE) { sprintf_s(szBuffer, 256, "%s:%f", p.getName().c_str(), p.getDoubleValue()); } strOut.append(szBuffer); } LOGD("SVDataReport:%s", ((CEquipment*)pEquipment)->getName().c_str(), strOut.c_str()); }; listener.onPanelDataReport = [&](void* pEquipment, void* pContext) { LOGD("onPanelDataReport", ((CEquipment*)pEquipment)->getName().c_str()); CEquipment* pEq = (CEquipment*)pEquipment; CGlass* pGlass = (CGlass*)pContext; // Èç¹ûAOI¼ì²âʧ°Ü£¬ÒªÍ£»ú if (pEq->getID() == EQ_ID_MEASUREMENT) { LOGD("onPanelDataReport 01", ((CEquipment*)pEquipment)->getName().c_str()); if (pGlass->getAOIInspResult() == InspResult::Fail) { LOGD("onPanelDataReport 02", ((CEquipment*)pEquipment)->getName().c_str()); if (stop() == 0) { m_nLastError = ER_CODE_AOI_NG; m_strLastError = "AOI¼ì²âδͨ¹ý."; } } } }; pEquipment->setListener(listener); pEquipment->setCcLink(&m_cclink); m_listEquipment.push_back(pEquipment); return 0; } std::list& CMaster::getEquipmentList() { return m_listEquipment; } 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; } return nullptr; } /* * Ìí¼ÓLoadPort1 * index -- 0~3 */ CLoadPort* CMaster::addLoadPort(int index) { ASSERT(index == 0 || index == 1 || index == 2 || index == 3); char szName[64]; sprintf_s(szName, 64, "LoadPort %d", index + 1); CLoadPort* pEquipment = new CLoadPort(); pEquipment->setIndex(index); pEquipment->setID(EQ_ID_LOADPORT1 + index); pEquipment->setName(szName); pEquipment->setDescription(szName); pEquipment->setCompareMapsBeforeProceeding(m_isCompareMapsBeforeProceeding); addToEquipmentList(pEquipment); pEquipment->init(); LOGE("ÒÑÌí¼Ó¡°%s¡±.", pEquipment->getName().c_str()); return pEquipment; } CFliper* CMaster::addFliper() { CFliper* pEquipment = new CFliper(); pEquipment->setID(EQ_ID_FLIPER); pEquipment->setBaseAlarmId(BASE_ALARM_EFEM); pEquipment->setName("Fliper(G2)"); pEquipment->setDescription("Fliper(G2)."); pEquipment->setReadBitBlock(0x0, 0x0); pEquipment->setStation(0, 255); addToEquipmentList(pEquipment); pEquipment->init(); LOGE("ÒÑÌí¼Ó¡°Fliper¡±."); return pEquipment; } CVacuumBake* CMaster::addVacuumBake() { CVacuumBake* pEquipment = new CVacuumBake(); pEquipment->setID(EQ_ID_VACUUMBAKE); pEquipment->setBaseAlarmId(BASE_ALARM_EFEM); pEquipment->setName("VacuumBake(G1)"); pEquipment->setDescription("VacuumBake(G1)."); pEquipment->setReadBitBlock(0x5c00, 0x66ff); pEquipment->setStation(0, 255); addToEquipmentList(pEquipment); pEquipment->init(); LOGE("ÒÑÌí¼Ó¡°VacuumBake¡±."); return pEquipment; } CAligner* CMaster::addAligner() { CAligner* pEquipment = new CAligner(); pEquipment->setID(EQ_ID_ALIGNER); pEquipment->setBaseAlarmId(BASE_ALARM_EFEM); pEquipment->setName("Aligner"); pEquipment->setDescription("Aligner."); pEquipment->setReadBitBlock(0x0, 0x0); pEquipment->setStation(0, 255); addToEquipmentList(pEquipment); pEquipment->init(); LOGE("ÒÑÌí¼Ó¡°Aligner¡±."); return pEquipment; } CEFEM* CMaster::addEFEM() { CEFEM* pEquipment = new CEFEM(); pEquipment->setID(EQ_ID_EFEM); pEquipment->setBaseAlarmId(BASE_ALARM_EFEM); pEquipment->setName("EFEM(ROBOT)"); pEquipment->setDescription("EFEM(ROBOT)."); pEquipment->setReadBitBlock(0x3000, 0x3aff); pEquipment->setStation(0, 255); addToEquipmentList(pEquipment); pEquipment->init(); LOGE("ÒÑÌí¼Ó¡°EFEM(ROBOT)¡±."); return pEquipment; } CArm* CMaster::addArm() { CArm* pEquipment = new CArm(); pEquipment->setID(EQ_ID_ARM); pEquipment->setBaseAlarmId(BASE_ALARM_EFEM); pEquipment->setName("ARM"); pEquipment->setDescription("ARM."); addToEquipmentList(pEquipment); pEquipment->init(); LOGE("ÒÑÌí¼Ó¡°ARM¡±."); return pEquipment; } CArmTray* CMaster::addArmTray(int index) { CArmTray* pEquipment = new CArmTray(); pEquipment->setID(index == 0 ? EQ_ID_ARM_TRAY1 : EQ_ID_ARM_TRAY2); pEquipment->setBaseAlarmId(BASE_ALARM_EFEM); pEquipment->setName(index == 0 ? "Arm Tray1" : "Arm Tray2"); pEquipment->setDescription(index == 0 ? "Arm Tray1." : "Arm Tray2."); addToEquipmentList(pEquipment); pEquipment->init(); LOGE("ÒÑÌí¼Ó¡°%s¡±.", pEquipment->getName().c_str()); return pEquipment; } /* Ìí¼Óbonder1 »ò bonder2 * index -- 0, bonder1 * index -- 1, bonder2 */ CBonder* CMaster::addBonder(int index) { ASSERT(index == 0 || index == 1); CBonder* pEquipment = new CBonder(); pEquipment->setID(EQ_ID_Bonder1 + index); pEquipment->setName(index == 0 ? "Bonder 1" : "Bonder 2"); pEquipment->setDescription(index == 0 ? "Bonder 1." : "Bonder 2."); pEquipment->setStation(0, 255); pEquipment->setReadBitBlock(index == 0 ? 0x3b00 : 0x4600, index == 0 ? 0x5600 : 0x6100); pEquipment->setIndex(index); addToEquipmentList(pEquipment); pEquipment->init(); LOGE("ÒÑÌí¼Ó¡°%s¡±.", pEquipment->getName().c_str()); return pEquipment; } CBakeCooling* CMaster::addBakeCooling() { CBakeCooling* pEquipment = new CBakeCooling(); pEquipment->setID(EQ_ID_BAKE_COOLING); pEquipment->setBaseAlarmId(BASE_ALARM_EFEM); pEquipment->setName("BakeCooling"); pEquipment->setDescription("BakeCooling."); pEquipment->setReadBitBlock(0x5100, 0x5bff); pEquipment->setStation(0, 255); addToEquipmentList(pEquipment); pEquipment->init(); LOGE("ÒÑÌí¼Ó¡°Aligner¡±."); return pEquipment; } CMeasurement* CMaster::addMeasurement() { CMeasurement* pEquipment = new CMeasurement(); pEquipment->setID(EQ_ID_MEASUREMENT); pEquipment->setBaseAlarmId(BASE_ALARM_EFEM); pEquipment->setName("Measurement"); pEquipment->setDescription("Measurement."); pEquipment->setReadBitBlock(0x6700, 0x6e00); pEquipment->setStation(0, 255); addToEquipmentList(pEquipment); pEquipment->init(); LOGE("ÒÑÌí¼Ó¡°Measurement¡±."); return pEquipment; } void CMaster::onTimer(UINT nTimerid) { for (auto item : m_listEquipment) { item->onTimer(nTimerid); } static int i = 0; i++; // ×Ô¶¯±£´æ»º´æ if (i % (4 * 2) == 0) { if (m_bDataModify) { saveCacheAndBackups(); m_bDataModify = FALSE; } } // Ä£Äâ²âÊÔ static int aaa = 0; aaa++; if (aaa % 30 == 0) { if (!m_queueGlasses.empty()) { CGlass* pGlass = m_queueGlasses.front(); pGlass->start(); glassFromQueueToInPorcess(pGlass); this->saveState(); // ÕâÀïÉϱ¨Panel Startʼþ if (m_listener.onPanelStart != nullptr) { m_listener.onPanelStart(this, pGlass); } } } if (aaa % 45 == 0) { if (!m_inProcesGlasses.empty()) { CGlass* pGlass = m_inProcesGlasses.front(); pGlass->complete(); CGlass* pBuddy = pGlass->getBuddy(); if (pBuddy != nullptr) pBuddy->complete(); glassFromInPorcessToComplete(pGlass); this->saveState(); // ÕâÀïÉϱ¨Panel Endʼþ if (m_listener.onPanelEnd != nullptr) { m_listener.onPanelEnd(this, pGlass); } CProcessJob* pJob = getGlassProcessJob(pGlass); if (pJob != nullptr && checkAndUpdatePjComplete(pJob)) { processJobFromInPorcessToComplete(pJob); this->saveState(); LOGE("ProcessJob(%s)Íê³É.", pJob->id().c_str()); if (m_listener.onPjEnd != nullptr) { m_listener.onPjEnd(this, pJob); } // ¼ì²éCJÊÇ·ñÒѾ­Íê³É ASSERT(m_pControlJob); if (checkAndUpdateCjComplete(m_pControlJob)) { this->saveState(); LOGE("ControlJob(%s)Íê³É.", m_pControlJob->id().c_str()); if (m_listener.onCjEnd != nullptr) { m_listener.onCjEnd(this, pJob); } } } } } } void CMaster::connectEquipments() { int nRet; 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); CFliper* pFliper = (CFliper*)getEquipment(EQ_ID_FLIPER); CVacuumBake* pVacuumBake = (CVacuumBake*)getEquipment(EQ_ID_VACUUMBAKE); CAligner* pAligner = (CAligner*)getEquipment(EQ_ID_ALIGNER); CBonder* pBonder1 = (CBonder*)getEquipment(EQ_ID_Bonder1); CBonder* pBonder2 = (CBonder*)getEquipment(EQ_ID_Bonder2); CBakeCooling* pBakeCooling = (CBakeCooling*)getEquipment(EQ_ID_BAKE_COOLING); CMeasurement* pMeasurement = (CMeasurement*)getEquipment(EQ_ID_MEASUREMENT); nRet = pLoadPort1->getPin("Out")->connectPin(pAligner->getPin("In1")); if (nRet < 0) { LOGE("Á¬½ÓLoadPort1-Fliperʧ°Ü"); } nRet = pLoadPort2->getPin("Out")->connectPin(pAligner->getPin("In2")); if (nRet < 0) { LOGE("Á¬½ÓLoadPort1-Fliperʧ°Ü"); } nRet = pAligner->getPin("Out1")->connectPin(pFliper->getPin("In")); if (nRet < 0) { LOGE("Á¬½ÓAligner-Fliperʧ°Ü"); } nRet = pAligner->getPin("Out2")->connectPin(pVacuumBake->getPin("In")); if (nRet < 0) { LOGE("Á¬½ÓAligner-VacuumBakeʧ°Ü"); } nRet = pFliper->getPin("Out1")->connectPin(pBonder1->getPin("In1")); if (nRet < 0) { LOGE("Á¬½ÓFliper-Bonder1ʧ°Ü"); } nRet = pFliper->getPin("Out2")->connectPin(pBonder2->getPin("In1")); if (nRet < 0) { LOGE("Á¬½ÓFliper-Bonder2ʧ°Ü"); } nRet = pVacuumBake->getPin("Out1")->connectPin(pBonder1->getPin("In2")); if (nRet < 0) { LOGE("Á¬½ÓVacuumBake-Bonder1ʧ°Ü"); } nRet = pVacuumBake->getPin("Out2")->connectPin(pBonder2->getPin("In2")); if (nRet < 0) { LOGE("Á¬½ÓVacuumBake-Bonder2ʧ°Ü"); } nRet = pBonder1->getPin("Out")->connectPin(pBakeCooling->getPin("In1")); if (nRet < 0) { LOGE("Á¬½ÓBonder1-BakeCoolingʧ°Ü"); } nRet = pBonder2->getPin("Out")->connectPin(pBakeCooling->getPin("In2")); if (nRet < 0) { LOGE("Á¬½ÓBonder2-BakeCoolingʧ°Ü"); } nRet = pBakeCooling->getPin("Out")->connectPin(pMeasurement->getPin("In")); if (nRet < 0) { LOGE("Á¬½ÓBakeCooling-LoadPort3ʧ°Ü"); } nRet = pMeasurement->getPin("Out1")->connectPin(pLoadPort3->getPin("In")); if (nRet < 0) { LOGE("Á¬½ÓBakeCooling-LoadPort3ʧ°Ü"); } nRet = pMeasurement->getPin("Out2")->connectPin(pLoadPort4->getPin("In")); if (nRet < 0) { LOGE("Á¬½ÓBakeCooling-LoadPort4ʧ°Ü"); } } int CMaster::saveCache() { CFile file; if (!file.Open(m_strFilepath.c_str(), CFile::modeCreate | CFile::modeWrite)) { return -1; } CArchive ar(&file, CArchive::store); serialize(ar); ar.Close(); file.Close(); return 0; } int CMaster::saveCacheAndBackups() { saveCache(); // ´´½¨±¸·ÝĿ¼ CString strNewFile; CString strFileDir = m_strFilepath.c_str(); int index = strFileDir.ReverseFind('\\'); ASSERT(index > 0); strFileDir = strFileDir.Left(index); strFileDir = strFileDir + _T("Backups"); ::CreateDirectory(strFileDir, nullptr); CTime time = CTime::GetCurrentTime(); strNewFile.Format(_T("%s//Master_%d_%02d_%02d_%02d_%02d_%02d.dat"), (LPTSTR)(LPCTSTR)strFileDir, time.GetYear(), time.GetMonth(), time.GetDay(), time.GetHour(), time.GetMinute(), time.GetSecond()); ::CopyFile(m_strFilepath.c_str(), strNewFile, FALSE); return 0; } void CMaster::setCacheFilepath(const char* pszFilepath) { m_strFilepath = pszFilepath; } int CMaster::readCache() { try { CFile file; if (!file.Open(m_strFilepath.c_str(), CFile::modeRead)) { return -1; } CArchive ar(&file, CArchive::load); serialize(ar); ar.Close(); file.Close(); } catch (CFileException* e) { TCHAR szErr[512]; e->GetErrorMessage(szErr, 512); AfxMessageBox(szErr); e->Delete(); } return 0; } void CMaster::serialize(CArchive& ar) { for (auto item : m_listEquipment) { item->serialize(ar); } } void CMaster::setState(MASTERSTATE state) { m_state = state; if (m_listener.onMasterStateChanged != nullptr) { m_listener.onMasterStateChanged(this, m_state); } } static int taskSeqNo = 0; CRobotTask* CMaster::createTransferTask(CEquipment* pSrcEq, CEquipment* pTarEq, MaterialsType primaryType/* = MaterialsType::G1*/, MaterialsType secondaryType/* = MaterialsType::G2*/, int armNo/* = 1*/, BOOL bJobMode/* = FALSE*/) { if (!pSrcEq->IsEnabled()) { return nullptr; } CRobotTask* pTask = nullptr; CSlot* pSrcSlot, * pTarSlot; pSrcEq->m_nTestFlag = m_nTestFlag; pTarSlot = pTarEq->getAvailableSlotForGlass(primaryType); pSrcSlot = pSrcEq->getProcessedSlot(primaryType, bJobMode); if (m_nTestFlag == 1) LOGD("createTransferTask 003 %x, %x", pTarSlot, pSrcSlot); if ((pSrcSlot == nullptr || nullptr == pTarSlot) && secondaryType != SERVO::MaterialsType::G0) { pTarSlot = pTarEq->getAvailableSlotForGlass(secondaryType); pSrcSlot = pSrcEq->getProcessedSlot(secondaryType, bJobMode); } if (m_nTestFlag == 1) LOGD("createTransferTask 004 %x, %x", pTarSlot, pSrcSlot); 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; } CRobotTask* CMaster::createTransferTask_bonder_to_bakecooling(CEquipment* pSrcEq, CEquipment* pTarEq) { if (!pSrcEq->IsEnabled()) { return nullptr; } std::vector slots = {1, 3}; CRobotTask* pTask = nullptr; CSlot* pSrcSlot, * pTarSlot; pTarSlot = pTarEq->getAvailableSlotForGlass2(MaterialsType::G1, slots); pSrcSlot = pSrcEq->getProcessedSlot(MaterialsType::G1); 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_bake_to_cooling(CEquipment* pSrcEq) { if (!pSrcEq->IsEnabled()) { return nullptr; } std::vector slotsTar = { 2, 4 }; std::vector slotsSrc = { 1, 3 }; CRobotTask* pTask = nullptr; CSlot* pSrcSlot, * pTarSlot; pTarSlot = pSrcEq->getAvailableSlotForGlass2(MaterialsType::G1, slotsTar); pSrcSlot = pSrcEq->getProcessedSlot2(MaterialsType::G1, slotsSrc); 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_bakecooling_to_measurement(CEquipment* pSrcEq, CEquipment* pTarEq) { if (!pSrcEq->IsEnabled()) { return nullptr; } std::vector 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(); 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_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(); if (m_pActiveRobotTask != nullptr) { m_pActiveRobotTask->abort(); } unlock(); if (m_listener.onRobotTaskEvent != nullptr) { m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_ABORT); } lock(); if (m_pActiveRobotTask != nullptr) { delete m_pActiveRobotTask; m_pActiveRobotTask = nullptr; } unlock(); // µ±Ç°ÈÎÎñÊÖ¶¯ÖÐÖ¹ºó£¬Í£Ö¹µ÷¶È£¬ÐèÒª²Ù×÷Ô±ÔÚ½â¾öÎÊÌâºó£¬ÖØÐÂÆô¶¯ // 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; } void CMaster::setPortType(unsigned int index, BOOL enable, int type, int mode, int cassetteType, int transferMode, BOOL autoChangeEnable) { 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(enable); pPort->localSetPortType((SERVO::PortType)type); pPort->localSetPortMode((SERVO::PortMode)mode); pPort->localSetCessetteType((SERVO::CassetteType)cassetteType); 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::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); } int CMaster::getPortCassetteSnSeed(int port) { ASSERT(1 <= port && port <= 4); int eqid[] = { EQ_ID_LOADPORT1, EQ_ID_LOADPORT2, EQ_ID_LOADPORT3, EQ_ID_LOADPORT4 }; CLoadPort* pPort = (CLoadPort*)getEquipment(eqid[port - 1]); return pPort->getPortCassetteSnSeed(); } void CMaster::setPortCassetteSnSeed(int port, int seed) { ASSERT(1 <= port && port <= 4); int eqid[] = { EQ_ID_LOADPORT1, EQ_ID_LOADPORT2, EQ_ID_LOADPORT3, EQ_ID_LOADPORT4 }; CLoadPort* pPort = (CLoadPort*)getEquipment(eqid[port - 1]); return pPort->setPortCassetteSnSeed(seed); } void CMaster::setCompareMapsBeforeProceeding(BOOL bCompare) { m_isCompareMapsBeforeProceeding = bCompare; } void CMaster::setJobMode(BOOL bJobMode) { m_bJobMode = bJobMode; } void CMaster::datetimeSync(SYSTEMTIME& time) { for (auto item : m_listEquipment) { item->setDateTime(time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond); } } void CMaster::enableEventReport(bool bEnable) { m_bEnableEventReport = bEnable; } void CMaster::enableAlarmReport(bool bEnable) { m_bEnableAlarmReport = bEnable; } bool CMaster::isAlarmReportEnable() { 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& pjs) { std::vector temp; for (auto p : pjs) { if (p->validate(*this)) { p->queue(); temp.push_back(p); } } m_processJobs = temp; this->saveState(); return (int)m_processJobs.size(); } std::vector& CMaster::getProcessJobs() { return m_processJobs; } CProcessJob* CMaster::getProcessJob(const std::string& id) { for (auto item : m_processJobs) { if (item->id().compare(id) == 0) return item; } return nullptr; } int CMaster::setControlJob(CControlJob& controlJob) { // »Øµ÷£ºÊÇ·ñ²Î´´½¨ControlJob auto canCreateCjFn = [&](uint32_t& cc, std::string& mm) -> bool { if (m_pControlJob != nullptr) { cc = 1100; mm = "µ±Ç°ControlJobδ½áÅú£¬²»ÄÜ´´½¨ÐµÄControlJob"; return false; } return true; }; // »Øµ÷£ºÊÇ·ñ´æÔÚ auto pjExists = [&](const std::string& id) -> bool { return getProcessJob(id) != nullptr; }; // »Øµ÷£ºÊÇ·ñ¿É¼ÓÈë CJ£¨ÕâÀﶨÒ壺±ØÐëÊÇ Queued£© auto pjJoinable = [&](const std::string& id) -> bool { auto pj = getProcessJob(id); if (pj == nullptr) return false; return pj->state() == PJState::Queued; }; bool bRet = controlJob.validateForCreate(canCreateCjFn, pjExists, pjJoinable); if (!bRet) return -1; std::vector temps; m_pControlJob = new CControlJob(controlJob); auto pjIds = controlJob.pjIds(); for (auto id : pjIds) { auto pj = getProcessJob(id); if (pj != nullptr) { temps.push_back(pj); } } m_pControlJob->setPJs(temps); this->saveState(); return 0; } CControlJob* CMaster::getControlJob() { return m_pControlJob; } 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 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; } bool CMaster::saveState() const { std::ofstream ofs(m_strStatePath, std::ios::binary); if (!ofs) return false; // ÎļþÍ· uint32_t magic = 0x4D415354; // 'MAST' uint16_t version = 1; ofs.write(reinterpret_cast(&magic), sizeof(magic)); ofs.write(reinterpret_cast(&version), sizeof(version)); // ±£´æ ControlJob bool hasCJ = (m_pControlJob != nullptr); ofs.write(reinterpret_cast(&hasCJ), sizeof(hasCJ)); if (hasCJ) { m_pControlJob->serialize(ofs); } // ±£´æ ProcessJob Áбí uint32_t count = static_cast(m_processJobs.size()); ofs.write(reinterpret_cast(&count), sizeof(count)); for (const auto& job : m_processJobs) { job->serialize(ofs); } // ÒÔºó¿ÉÒÔÔÚÕâÀï×·¼ÓÐÂ×Ö¶Î return true; } bool CMaster::loadState(const std::string& path) { // ±£´æÎļþ·¾¶ m_strStatePath = path; std::ifstream ifs(path, std::ios::binary); if (!ifs) return false; // ÎļþÍ· uint32_t magic = 0; uint16_t version = 0; ifs.read(reinterpret_cast(&magic), sizeof(magic)); ifs.read(reinterpret_cast(&version), sizeof(version)); if (magic != 0x4D415354) { // Îļþ²»ºÏ·¨ return false; } if (m_pControlJob != nullptr) { delete m_pControlJob; m_pControlJob = nullptr; } // ¶ÁÈ¡ ControlJob bool hasCJ = false; ifs.read(reinterpret_cast(&hasCJ), sizeof(hasCJ)); if (hasCJ) { m_pControlJob = new CControlJob(); if (!CControlJob::deserialize(ifs, *m_pControlJob)) return false; } else { return false; } // ¶ÁÈ¡ ProcessJob Áбí uint32_t count = 0; ifs.read(reinterpret_cast(&count), sizeof(count)); m_processJobs.clear(); for (uint32_t i = 0; i < count; i++) { CProcessJob* pProcessJob = new CProcessJob(); if (!CProcessJob::deserialize(ifs, *pProcessJob)) return false; m_processJobs.push_back(pProcessJob); } // ÕÒµ½CProcessJobÖ¸Õë¼ÓÈëÁбíÖÐ std::vector tempPjs; auto ids = m_pControlJob->pjIds(); for (auto id : ids) { auto pj = getProcessJob(id); if (pj != nullptr) { tempPjs.push_back(pj); } } m_pControlJob->setPJs(tempPjs); // Èç¹û°æ±¾Éý¼¶£¬¿ÉÔÚÕâÀïÅÐ¶Ï version À´¼ÓÔØÐÂ×Ö¶Î return true; } CProcessJob* CMaster::acquireNextProcessJob() { auto& pjs = m_pControlJob->getPjs(); for (const auto pj : pjs) { if (pj->state() == PJState::Queued) { pj->start(); return pj; } } return nullptr; } CGlass* CMaster::acquireNextGlass() { for (auto* pj : m_inProcesJobs) { // ±éÀú PJ µÄ carriers ºÍ slots for (auto& cs : pj->carriers()) { for (auto ctx : cs.contexts) { CGlass* pGlass = (CGlass*)ctx; if (pGlass->state() == GlsState::NoState) { pGlass->queue(); return pGlass; } } } } return nullptr; // ûÓпɼӹ¤µÄ Glass } int CMaster::acquireGlassToQueue() { int nCount = 0; for (auto* pj : m_inProcesJobs) { // ±éÀú PJ µÄ carriers ºÍ slots for (auto& cs : pj->carriers()) { for (auto ctx : cs.contexts) { CGlass* pGlass = (CGlass*)ctx; if (pGlass->state() == GlsState::NoState) { pGlass->queue(); if(addGlassToQueue(pGlass)) nCount++; } } } } return nCount; } bool CMaster::addGlassToQueue(CGlass* pGlass) { for (auto g : m_queueGlasses) { if (g == pGlass) return false; } m_queueGlasses.push_back(pGlass); return true; } bool CMaster::glassFromQueueToInPorcess(CGlass* pGlass) { auto it = std::find(m_queueGlasses.begin(), m_queueGlasses.end(), pGlass); if (it != m_queueGlasses.end()) { m_inProcesGlasses.push_back(*it); m_queueGlasses.erase(it); return true; } return false; } bool CMaster::glassFromInPorcessToComplete(CGlass* pGlass) { auto it = std::find(m_inProcesGlasses.begin(), m_inProcesGlasses.end(), pGlass); if (it != m_inProcesGlasses.end()) { m_completeGlasses.push_back(*it); m_inProcesGlasses.erase(it); return true; } return false; } bool CMaster::processJobFromInPorcessToComplete(CProcessJob* pProcessJob) { auto it = std::find(m_inProcesJobs.begin(), m_inProcesJobs.end(), pProcessJob); if (it != m_inProcesJobs.end()) { m_completeProcessJobs.push_back(*it); m_inProcesJobs.erase(it); return true; } return false; } bool CMaster::checkAndUpdatePjComplete(CProcessJob* pJob) { ASSERT(pJob); auto state = pJob->state(); if (state != PJState::InProcess && state != PJState::Paused) return false; for (auto c : pJob->carriers()) { for (auto g : c.contexts) { auto state = ((CGlass*)g)->state(); if (state != GlsState::Aborted && state != GlsState::Completed && state != GlsState::Failed) return false; } } return pJob->complete(); } bool CMaster::checkAndUpdateCjComplete(CControlJob* pJob) { ASSERT(pJob); auto state = pJob->state(); if (state != CJState::Executing && state != CJState::Paused) return false; for (auto pj : pJob->getPjs()) { auto state = pj->state(); if (state != PJState::Aborted && state != PJState::Completed && state != PJState::Failed) { return false; } } return pJob->complete(); } CProcessJob* CMaster::getGlassProcessJob(CGlass* pGlass) { if (m_pControlJob == nullptr) return nullptr; for (auto pj : m_pControlJob->getPjs()) { for (auto c : pj->carriers()) { for (auto g : c.contexts) { if (g == pGlass) return pj; } } } return nullptr; } bool CMaster::completeControlJob(std::string description) { if (m_pControlJob == nullptr || m_state != SERVO::MASTERSTATE::READY) { return false; } for (auto item : m_processJobs) { item->abort(description); } m_pControlJob->abort(description); // ÊÍ·ÅJobÏà¹Ø for (auto item : m_processJobs) { delete item; } m_processJobs.clear(); if (m_pControlJob != nullptr) { delete m_pControlJob; m_pControlJob = nullptr; } saveState(); return true; } bool CMaster::canCreateControlJob() { return m_pControlJob == nullptr; } bool CMaster::canCompleteControlJob() { return m_pControlJob != nullptr && m_state == SERVO::MASTERSTATE::READY; } bool CMaster::canDeleteControlJob() { return m_pControlJob != nullptr && m_pControlJob->state() == CJState::NoState && m_state == SERVO::MASTERSTATE::READY; } int CMaster::getWipGlasses(std::vector& glasses) { for (auto eq : m_listEquipment) { auto p = dynamic_cast(eq); if (p == nullptr) { eq->getAllGlass(glasses); } } return (int)glasses.size(); } int CMaster::getLastError() { return m_nLastError; } std::string& CMaster::getLastErrorText() { return m_strLastError; } void CMaster::test() { if (stop() == 0) { m_nLastError = ER_CODE_AOI_NG; m_strLastError = "AOI¼ì²âδͨ¹ý."; } } bool CMaster::moveGlassToBuf(int eqid, int slotNo) { CEquipment* pEquipment = getEquipment(eqid); if (pEquipment == nullptr) return false; CSlot* pSlot = pEquipment->getSlotWithNo(slotNo); if (pSlot == nullptr) return false; CGlass* pGlass = (CGlass*)pSlot->getContext(); m_bufGlass.push_back(pGlass); pGlass->addRef(); pSlot->setContext(nullptr); m_bDataModify = TRUE; if (m_listener.onEqDataChanged != nullptr) { m_listener.onEqDataChanged(this, pEquipment, 0); } return true; } bool CMaster::moveGlassToSlot(int eqid, int slotNo) { CEquipment* pEquipment = getEquipment(eqid); if (pEquipment == nullptr) return false; CSlot* pSlot = pEquipment->getSlotWithNo(slotNo); if (pSlot == nullptr) return false; if (m_bufGlass.empty()) return false; CGlass* pGlass = m_bufGlass.front(); m_bufGlass.pop_front(); if (pGlass == nullptr) return false; pSlot->setContext(pGlass); pGlass->release(); m_bDataModify = TRUE; if (m_listener.onEqDataChanged != nullptr) { m_listener.onEqDataChanged(this, pEquipment, 0); } return true; } }