#include "stdafx.h" #include "Common.h" #include "CMaster.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; InitializeCriticalSection(&m_criticalSection); } CMaster::~CMaster() { 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) { LOGI("°æ±¾ÐÅÏ¢£º%s.", version.toString().c_str()); } else { LOGE("»ñÈ¡CC-Link°æ±¾ÐÅϢʧ°Ü."); } BoardStatus status; nRet = m_cclink.GetBoardStatus(status); if (nRet == 0) { LOGI("״̬£º%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, pPort1); pEfem->setPort(2, pPort1); pEfem->setPort(3, pPort1); 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; } setState(MASTERSTATE::STARTING); m_ullStartTime = GetTickCount64(); return 0; } int CMaster::stop() { // ÔËÐÐʱ¼äΪÀÛ¼Ó½á¹û£¬±¾´ÎֹͣʱˢУ» if (m_state != MASTERSTATE::RUNNING) { return -1; } m_ullRunTime += (GetTickCount64() - m_ullStartTime); setState(MASTERSTATE::STOPPING); return 0; } ULONGLONG CMaster::getRunTime() { if (m_state == MASTERSTATE::RUNNING) 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* pLoadPort1 = (CLoadPort*)getEquipment(EQ_ID_LOADPORT1); CLoadPort* pLoadPort2 = (CLoadPort*)getEquipment(EQ_ID_LOADPORT2); CFliper* pFliper = (CFliper*)getEquipment(EQ_ID_FLIPER); CVacuumBake* pVacuumBack = (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); ASSERT(pLoadPort1); ASSERT(pLoadPort2); ASSERT(pFliper); ASSERT(pVacuumBack); ASSERT(pAligner); ASSERT(pBonder1); ASSERT(pBonder2); ASSERT(pBakeCooling); while (1) { // ´ýÍ˳öÐźŻòʱ¼äµ½ HANDLE hEvents[] = { m_hEventDispatchThreadExit[0], m_hDispatchEvent }; int nRet = WaitForMultipleObjects(2, hEvents, FALSE, 1000); if (nRet == WAIT_OBJECT_0) { break; } // Èç¹û״̬ΪSTARTING£¬¿ªÊ¼¹¤×÷²¢Çл»µ½RUNNING״̬ lock(); if (m_state == MASTERSTATE::STARTING) { unlock(); Sleep(1000); setState(MASTERSTATE::RUNNING); continue; } // ´¦ÀíÍê³Éµ±Ç°ÊÂÎñºó£¬Çл»µ½Í£Ö¹»ò¾ÍÐ÷״̬ else if (m_state == MASTERSTATE::STOPPING) { unlock(); Sleep(1000); setState(MASTERSTATE::READY); continue; } // µ÷¶ÈÂß¼­´¦Àí else if (m_state == MASTERSTATE::RUNNING) { unlock(); // LOGI("µ÷¶È´¦ÀíÖÐ..."); lock(); if (m_pActiveRobotTask != nullptr) { 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; } // Bonder -> BakeCooling m_pActiveRobotTask = createTransferTask_bonder_to_bakecooling(pBonder1, pBakeCooling, primaryType, secondaryType); if (m_pActiveRobotTask != nullptr) { std::string strDescription = m_pActiveRobotTask->getDescription(); unlock(); if (m_listener.onRobotTaskEvent != nullptr) { m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, 0); } LOGI("´´½¨ÐÂÈÎÎñ<%s>...", strDescription.c_str()); continue; } m_pActiveRobotTask = createTransferTask_bonder_to_bakecooling(pBonder2, pBakeCooling, primaryType, secondaryType); if (m_pActiveRobotTask != nullptr) { std::string strDescription = m_pActiveRobotTask->getDescription(); unlock(); if (m_listener.onRobotTaskEvent != nullptr) { m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, 0); } LOGI("´´½¨ÐÂÈÎÎñ<%s>...", strDescription.c_str()); continue; } // Aligner -> Bonder m_pActiveRobotTask = createTransferTask(pAligner, pBonder1, primaryType, secondaryType); if (m_pActiveRobotTask != nullptr) { std::string strDescription = m_pActiveRobotTask->getDescription(); unlock(); if (m_listener.onRobotTaskEvent != nullptr) { m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, 0); } LOGI("´´½¨ÐÂÈÎÎñ<%s>...", strDescription.c_str()); continue; } m_pActiveRobotTask = createTransferTask(pAligner, pBonder2, primaryType, secondaryType); if (m_pActiveRobotTask != nullptr) { std::string strDescription = m_pActiveRobotTask->getDescription(); unlock(); if (m_listener.onRobotTaskEvent != nullptr) { m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, 0); } LOGI("´´½¨ÐÂÈÎÎñ<%s>...", strDescription.c_str()); continue; } // Fliper(G2) -> Aligner // VacuumBake(G1) -> Aligner m_pActiveRobotTask = createTransferTask(pFliper, pAligner, primaryType, secondaryType); if (m_pActiveRobotTask != nullptr) { std::string strDescription = m_pActiveRobotTask->getDescription(); unlock(); if (m_listener.onRobotTaskEvent != nullptr) { m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, 0); } LOGI("´´½¨ÐÂÈÎÎñ<%s>...", strDescription.c_str()); continue; } m_pActiveRobotTask = createTransferTask(pVacuumBack, pAligner, primaryType, secondaryType); if (m_pActiveRobotTask != nullptr) { std::string strDescription = m_pActiveRobotTask->getDescription(); unlock(); if (m_listener.onRobotTaskEvent != nullptr) { m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, 0); } LOGI("´´½¨ÐÂÈÎÎñ<%s>...", strDescription.c_str()); continue; } // LoadPort -> Fliper(G2) // LoadPort -> VacuumBake(G1) CEquipment* pEqTar1 = pVacuumBack; CEquipment* pEqTar2 = pFliper; if (primaryType == MaterialsType::G2) { pEqTar1 = pFliper; pEqTar2 = pVacuumBack; } m_pActiveRobotTask = createTransferTask(pLoadPort1, pEqTar1, primaryType, secondaryType); if (m_pActiveRobotTask != nullptr) { std::string strDescription = m_pActiveRobotTask->getDescription(); unlock(); if (m_listener.onRobotTaskEvent != nullptr) { m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, 0); } LOGI("´´½¨ÐÂÈÎÎñ<%s>...", strDescription.c_str()); continue; } m_pActiveRobotTask = createTransferTask(pLoadPort2, pEqTar1, primaryType, secondaryType); if (m_pActiveRobotTask != nullptr) { std::string strDescription = m_pActiveRobotTask->getDescription(); unlock(); if (m_listener.onRobotTaskEvent != nullptr) { m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, 0); } LOGI("´´½¨ÐÂÈÎÎñ<%s>...", strDescription.c_str()); continue; } // LoadPort -> VacuumBake(G1) m_pActiveRobotTask = createTransferTask(pLoadPort1, pEqTar2, primaryType, secondaryType); if (m_pActiveRobotTask != nullptr) { std::string strDescription = m_pActiveRobotTask->getDescription(); unlock(); if (m_listener.onRobotTaskEvent != nullptr) { m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, 0); } LOGI("´´½¨ÐÂÈÎÎñ<%s>...", strDescription.c_str()); continue; } m_pActiveRobotTask = createTransferTask(pLoadPort2, pEqTar2, primaryType, secondaryType); if (m_pActiveRobotTask != nullptr) { std::string strDescription = m_pActiveRobotTask->getDescription(); unlock(); if (m_listener.onRobotTaskEvent != nullptr) { m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, 0); } LOGI("´´½¨ÐÂÈÎÎñ<%s>...", strDescription.c_str()); continue; } // BakeCooling ->Measurement // Measurement -> LoadPort unlock(); } unlock(); } SetEvent(m_hEventDispatchThreadExit[1]); // _endthreadex(0); TRACE("CMaster::DispatchProc Ïß³ÌÍ˳ö\n"); return 0; } unsigned CMaster::ReadBitsProc() { while (1) { // ´ýÍ˳öÐźŻòʱ¼äµ½ int nRet = ::WaitForSingleObject(m_hEventReadBitsThreadExit[0], 1000); if (nRet == WAIT_OBJECT_0) { break; } for (auto item : m_listEquipment) { if (item->getID() == EQ_ID_Bonder1 || item->getID() == EQ_ID_Bonder2) { const StationIdentifier& station = item->getStation(); MemoryBlock& block = item->getReadBitBlock(); int nRet = m_cclink.ReadData2(station, (DeviceType)block.type, block.start, block.size, block.buffer); if (0 == nRet) { item->onReceiveLBData(block.buffer, block.size); } } } } 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, CJobDataB* pJobDataB) -> BOOL { CEquipment* p = (CEquipment*)pEquipment; // ȡƬ£¬¸üе±Ç°°áËÍÈÎÎñ BOOL bOk = FALSE; lock(); if (m_pActiveRobotTask != nullptr) { if (m_pActiveRobotTask->getSrcPosition() == p->getID()) { CGlass* pGlass = p->getGlassFromSlot(m_pActiveRobotTask->getSrcSlot()); if (pGlass != nullptr) { CJobDataB* pJobDataBSrc = pGlass->getJobDataB(); if (pJobDataBSrc != nullptr && pJobDataBSrc->getCassetteSequenceNo() == pJobDataB->getCassetteSequenceNo() && pJobDataBSrc->getJobSequenceNo() == pJobDataB->getJobSequenceNo()) { bOk = TRUE; LOGI("onPreFethedOutJob, ÒÑУÑéÊý¾ÝÒ»ÖÂÐÔ."); } } } 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, CJobDataB* pJobDataB, short& slot) -> BOOL { CEquipment* p = (CEquipment*)pEquipment; // ·ÅƬ£¬¸üе±Ç°°áËÍÈÎÎñ BOOL bOk = FALSE; lock(); if (m_pActiveRobotTask != nullptr) { if (m_pActiveRobotTask->getTarPosition() == p->getID()) { CGlass* pGlass = p->getGlassFromSlot(m_pActiveRobotTask->getTarSlot()); if (pGlass == nullptr) { bOk = TRUE; slot = m_pActiveRobotTask->getTarSlot(); LOGI("onPreFethedOutJob, ÒÑУÑéÊý¾ÝÒ»ÖÂÐÔ."); } } else if (p->getID() == EQ_ID_ARM_TRAY1 || p->getID() == EQ_ID_ARM_TRAY2) { slot = 1; bOk = TRUE; } } unlock(); if (!bOk) { LOGE("onPreFethedOutJob, Êý¾ÝУÑéʧ°Ü."); } 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()) { m_pActiveRobotTask->fetchOut(); LOGI("¿ªÊ¼È¡Æ¬..."); } unlock(); } else if (code == EDCC_STORED_JOB) { lock(); if (m_pActiveRobotTask != nullptr && m_pActiveRobotTask->getTarPosition() == p->getID()) { m_pActiveRobotTask->stored(); m_pActiveRobotTask->completed(); LOGI("·ÅƬÍê³É..."); // Íê³É´ËÌõ°áËÍÈÎÎñ£¬µ«Òª°ÑÊý¾ÝºÍÏûÏ¢ÉÏÅ×Ó¦Óòã unlock(); lock(); if (m_listener.onRobotTaskEvent != nullptr) { m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, 1); } delete m_pActiveRobotTask; m_pActiveRobotTask = nullptr; } unlock(); } }; 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; } /* * Ìí¼Ó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); 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(0x4000, 0x45ff); 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(0x4000, 0x45ff); 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(0x4000, 0x45ff); 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(0x4000, 0x45ff); 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); } // °´Ò»¶¨ÆµÂÊɨÃèLBÊý¾Ý static int i = 0; i++; /* if (i % (4 * 1) == 0) { for (auto item : m_listEquipment) { if (item->getID() == EQ_ID_Bonder1) { const StationIdentifier& station = item->getStation(); MemoryBlock& block = item->getReadBitBlock(); int nRet = m_cclink.ReadData2(station, (DeviceType)block.type, block.start, block.size, block.buffer); if (0 == nRet) { item->onReceiveLBData(block.buffer, block.size); } } } } */ // ×Ô¶¯±£´æ»º´æ if (i % (4 * 2) == 0) { if (m_bDataModify) { saveCacheAndBackups(); m_bDataModify = FALSE; } } } 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("Out1")->connectPin(pFliper->getPin("In1")); if (nRet < 0) { LOGE("Á¬½ÓLoadPort1-Fliperʧ°Ü"); } nRet = pLoadPort2->getPin("Out1")->connectPin(pFliper->getPin("In2")); if (nRet < 0) { LOGE("Á¬½ÓLoadPort1-Fliperʧ°Ü"); } nRet = pLoadPort1->getPin("Out2")->connectPin(pVacuumBake->getPin("In1")); if (nRet < 0) { LOGE("Á¬½ÓLoadPort1-VacuumBakeʧ°Ü"); } nRet = pLoadPort2->getPin("Out2")->connectPin(pVacuumBake->getPin("In2")); if (nRet < 0) { LOGE("Á¬½ÓLoadPort1-VacuumBakeʧ°Ü"); } nRet = pFliper->getPin("Out")->connectPin(pAligner->getPin("In1")); if (nRet < 0) { LOGE("Á¬½ÓFliper-Alignerʧ°Ü"); } nRet = pVacuumBake->getPin("Out")->connectPin(pAligner->getPin("In2")); if (nRet < 0) { LOGE("Á¬½ÓVacuumBake-Alignerʧ°Ü"); } nRet = pAligner->getPin("Out1")->connectPin(pBonder1->getPin("In")); if (nRet < 0) { LOGE("Á¬½ÓAligner-Bondere1ʧ°Ü"); } nRet = pAligner->getPin("Out2")->connectPin(pBonder2->getPin("In")); if (nRet < 0) { LOGE("Á¬½ÓAligner-Bondere2ʧ°Ü"); } 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*/) { CRobotTask* pTask = nullptr; CSlot* pSrcSlot, * pTarSlot; pTarSlot = pTarEq->getAvailableSlotForGlass(primaryType); pSrcSlot = pSrcEq->getProcessedSlot(primaryType); if (pSrcSlot == nullptr || nullptr == pTarSlot) { pTarSlot = pTarEq->getAvailableSlotForGlass(secondaryType); pSrcSlot = pSrcEq->getProcessedSlot(secondaryType); } if (pSrcSlot != nullptr && nullptr != pTarSlot) { pTask = new CRobotTask(); pTask->setContext(pSrcSlot->getContext()); pTask->setRobotTransferParam(++taskSeqNo, 1, pSrcSlot->getPosition(), pTarSlot->getPosition(), pSrcSlot->getNo(), pTarSlot->getNo()); } return pTask; } CRobotTask* CMaster::createTransferTask_bonder_to_bakecooling(CEquipment* pSrcEq, CEquipment* pTarEq, MaterialsType primaryType/* = MaterialsType::G1*/, MaterialsType secondaryType/* = MaterialsType::G2*/) { std::vector slots = {1, 2}; CRobotTask* pTask = nullptr; CSlot* pSrcSlot, * pTarSlot; pTarSlot = pTarEq->getAvailableSlotForGlass2(primaryType, slots); pSrcSlot = pSrcEq->getProcessedSlot(primaryType); if (pSrcSlot == nullptr || nullptr == pTarSlot) { pTarSlot = pTarEq->getAvailableSlotForGlass(secondaryType); pSrcSlot = pSrcEq->getProcessedSlot(secondaryType); } if (pSrcSlot != nullptr && nullptr != pTarSlot) { pTask = new CRobotTask(); pTask->setContext(pSrcSlot->getContext()); pTask->setRobotTransferParam(++taskSeqNo, 1, pSrcSlot->getPosition(), pTarSlot->getPosition(), pSrcSlot->getNo(), pTarSlot->getNo()); } return pTask; } }