1.Port编码错位问题修复;
2.调度时的判断条件优化。
3.支持上料下料混合;
| | |
| | | typedef std::function<BOOL(void* pEiuipment, int port, CJobDataB* pJobDataB, short& putSlot)> ONPRESTOREDJOB; |
| | | typedef std::function<void(void* pEiuipment, PROCESS_STATE state)> ONPROCESSSTATE; |
| | | typedef std::function<void(void* pEiuipment, short scanMap, short downMap)> ONMAPMISMATCH; |
| | | typedef std::function<void(void* pEiuipment, short scanMap)> ONPORTINUSE; |
| | | typedef std::function<void(void* pEiuipment, short status, __int64 data)> ONPORTSTATUSCHANGED; |
| | | typedef struct _EquipmentListener |
| | | { |
| | | ONALIVE onAlive; |
| | |
| | | ONPRESTOREDJOB onPreStoredJob; |
| | | ONPROCESSSTATE onProcessStateChanged; |
| | | ONMAPMISMATCH onMapMismatch; |
| | | ONPORTINUSE onPortInUse; |
| | | ONPORTSTATUSCHANGED onPortStatusChanged; |
| | | |
| | | } EquipmentListener; |
| | | |
| | |
| | | CLoadPort::CLoadPort() : CEquipment() |
| | | { |
| | | m_nIndex = 0; |
| | | m_portType = PortType::Loading; |
| | | m_portMode = PortMode::ReadyToLoad; |
| | | m_portType = PortType::Both; |
| | | m_portMode = PortMode::OutOfService; |
| | | m_cassetteType = CassetteType::G1; |
| | | m_transferMode = TransferMode::AGVMode; |
| | | m_bEnable = FALSE; |
| | |
| | | [&](void* pFrom, int code, const char* pszData, size_t size) -> int { |
| | | if (code == ROK && pszData != nullptr && size > 0) { |
| | | m_portMode = (PortMode)CToolUnits::toInt16(pszData); |
| | | LOGI("<LoadPort-%d>m_portMode:%d", m_nIndex, m_portMode); |
| | | } |
| | | return 0; |
| | | }); |
| | |
| | | static int ii = 0; |
| | | ii++; |
| | | if (ii == 20) { |
| | | char szBuffer[64]; |
| | | char szBuffer[64] = {0}; |
| | | CStep* pStep = getStepWithName(STEP_EQ_PORT1_INUSE); |
| | | CPortStatusReport portStatusReport; |
| | | portStatusReport.setPortStatus(PORT_INUSE); |
| | | portStatusReport.setPortStatus(PORT_UNLOAD_READY); |
| | | portStatusReport.setJobExistenceSlot(0xf); |
| | | int nRet = portStatusReport.serialize(szBuffer, 64); |
| | | decodePortStatusReport(pStep, szBuffer, 64); |
| | |
| | | |
| | | if (ar.IsStoring()) { |
| | | ar << m_nIndex; |
| | | //ar << (int)m_portType; |
| | | //ar << (int)m_portMode; |
| | | //ar << (int)m_cassetteType; |
| | | //ar << (int)m_transferMode; |
| | | //ar << m_bEnable; |
| | | //ar << m_bAutoChangeEnable; |
| | | m_portStatusReport.serialize(ar); |
| | | } |
| | | else { |
| | | int temp; |
| | | ar >> m_nIndex; |
| | | //ar >> temp; m_portType = (PortType)temp; |
| | | //ar >> temp; m_portMode = (PortMode)temp; |
| | | //ar >> temp; m_cassetteType = (CassetteType)temp; |
| | | //ar >> temp; m_transferMode = (TransferMode)temp; |
| | | //ar >> m_bEnable; |
| | | //ar >> m_bAutoChangeEnable; |
| | | m_portStatusReport.serialize(ar); |
| | | } |
| | | } |
| | |
| | | else { |
| | | // 抛出到应用层做选择要加工的片子 |
| | | generateGlassList(getScanCassetteMap()); |
| | | if (m_listener.onPortInUse != nullptr) { |
| | | m_listener.onPortInUse(this, getScanCassetteMap()); |
| | | if (m_listener.onPortStatusChanged != nullptr) { |
| | | m_listener.onPortStatusChanged(this, portStatusReport.getPortStatus(), |
| | | getScanCassetteMap()); |
| | | } |
| | | } |
| | | } |
| | |
| | | LOGI("Arm1 %s, Arm2 %s.", rmd.armState[0] ? _T("不可用") : _T("可用"), |
| | | rmd.armState[1] ? _T("不可用") : _T("可用")); |
| | | } |
| | | CEquipment* pEqTar[] = { pVacuumBake, pFliper }; |
| | | if (primaryType == MaterialsType::G2) { |
| | | pEqTar[0] = pFliper; |
| | | pEqTar[1] = pVacuumBake; |
| | | } |
| | | for (int s = 0; s < 4; s++) { |
| | | PortType pt = pLoadPorts[s]->getPortType(); |
| | | if (!rmd.armState[0] && pLoadPorts[s]->isEnable() |
| | | && pLoadPorts[s]->getPortType() == PortType::Unloading |
| | | && pLoadPorts[s]->getPortMode() == PortMode::ReadyToUnload) { |
| | | && (pt == PortType::Unloading || pt == PortType::Both) |
| | | && pLoadPorts[s]->getPortStatus() == PORT_INUSE) { |
| | | m_pActiveRobotTask = createTransferTask(pMeasurement, pLoadPorts[s], primaryType, secondaryType); |
| | | if (m_pActiveRobotTask != nullptr) { |
| | | goto PORT_PUT; |
| | |
| | | |
| | | // LoadPort -> Aligner |
| | | for (int s = 0; s < 4; s++) { |
| | | PortType pt = pLoadPorts[s]->getPortType(); |
| | | if (!rmd.armState[0] && pLoadPorts[s]->isEnable() |
| | | && pLoadPorts[s]->getPortType() == PortType::Loading |
| | | && pLoadPorts[s]->getPortMode() == PortMode::ReadyToLoad) { |
| | | && (pt == PortType::Loading || pt == PortType::Both) |
| | | && pLoadPorts[s]->getPortStatus() == PORT_INUSE) { |
| | | m_pActiveRobotTask = createTransferTask(pLoadPorts[s], pAligner, primaryType, secondaryType); |
| | | if (m_pActiveRobotTask != nullptr) { |
| | | pEFEM->setContext(m_pActiveRobotTask->getContext()); |
| | |
| | | LOGE("<Master-%s>Port InUse, map(%d!=%d)不一致,请检查。", |
| | | ((CEquipment*)pEquipment)->getName().c_str(), scanMap, downMap); |
| | | }; |
| | | listener.onPortInUse = [&](void* pEquipment, short scanMap) { |
| | | LOGE("<Master-%s>Port InUse。scanMap=%d", ((CEquipment*)pEquipment)->getName().c_str(), scanMap); |
| | | if (m_listener.onLoadPortInUse != nullptr) { |
| | | m_listener.onLoadPortInUse(this, (CEquipment*)pEquipment, scanMap); |
| | | listener.onPortStatusChanged = [&](void* pEquipment, short status, __int64 data) { |
| | | LOGE("<Master-%s>Port InUse。status=%d, data=%lld", ((CEquipment*)pEquipment)->getName().c_str(), status); |
| | | if (m_listener.onLoadPortStatusChanged != nullptr) { |
| | | m_listener.onLoadPortStatusChanged(this, (CEquipment*)pEquipment, status, data); |
| | | } |
| | | }; |
| | | pEquipment->setListener(listener); |
| | |
| | | typedef std::function<void(void* pMaster, CEquipment* pEquipment, CVcrEventReport* pReport)> ONEQVCREVENTREPORT; |
| | | typedef std::function<void(void* pMaster, CEquipment* pEquipment, int code)> ONEQDATACHANGED; |
| | | typedef std::function<void(void* pMaster, CRobotTask* pTask, int code)> ONROBOTTASKEVENT; |
| | | typedef std::function<void(void* pMaster, CEquipment* pEquipment, short scanMap)> ONLOADPORTINUSE; |
| | | typedef std::function<void(void* pMaster, CEquipment* pEquipment, short status, __int64 data)> ONLOADPORTSTATUSCHANGED; |
| | | typedef struct _MasterListener |
| | | { |
| | | ONMASTERSTATECHANGED onMasterStateChanged; |
| | |
| | | ONEQVCREVENTREPORT onEqVcrEventReport; |
| | | ONEQDATACHANGED onEqDataChanged; |
| | | ONROBOTTASKEVENT onRobotTaskEvent; |
| | | ONLOADPORTINUSE onLoadPortInUse; |
| | | ONLOADPORTSTATUSCHANGED onLoadPortStatusChanged; |
| | | } MasterListener; |
| | | |
| | | class CMaster |
| | |
| | | |
| | | // 测试 |
| | | else if (nCmd == ID_EQSGRAPHITEM_TEST1) { |
| | | |
| | | } |
| | | else if (nCmd == ID_EQSGRAPHITEM_TEST2) { |
| | | SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData; |
| | | SERVO::CArm* pArm = (SERVO::CArm*)pEquipment->getArm(); |
| | | if (pArm != nullptr) { |
| | | SERVO::CGlass* pGlass = pArm->getAnyGlass(); |
| | | if (pGlass != nullptr) { |
| | | SERVO::CJobDataS* pJobDataS = pGlass->getJobDataS(); |
| | | if (pJobDataS != nullptr) { |
| | | pEquipment->onReceivedJob(0, pJobDataS); |
| | | Sleep(600); |
| | | SERVO::CJobDataB jobDataB; |
| | | pEquipment->onStoredJob(0, &pJobDataS->getJobDataB(jobDataB)); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | else if (nCmd == ID_EQSGRAPHITEM_TEST3) { |
| | | SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData; |
| | | if (pEquipment != nullptr) { |
| | | SERVO::CGlass* pGlass = pEquipment->getAnyGlass(); |
| | | if (pGlass != nullptr) { |
| | | SERVO::CProcessData pd; |
| | | pd.setGlassId(pGlass->getID().c_str()); |
| | | pEquipment->onProcessData(&pd); |
| | | } |
| | | } |
| | | } |
| | | else if (nCmd == ID_EQSGRAPHITEM_TEST4) { |
| | | SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData; |
| | | if (pEquipment != nullptr) { |
| | | pEquipment->setLinkSignalUpstream(0, SIGNAL_UPSTREAM_INLINE, TRUE); |
| | | pEquipment->setLinkSignalUpstream(0, SIGNAL_UPSTREAM_TROUBLE, FALSE); |
| | | pEquipment->setLinkSignalUpstream(0, SIGNAL_INTERLOCK, TRUE); |
| | | pEquipment->setLinkSignalUpstream(0, SIGNAL_SEND_ABLE, TRUE); |
| | | pEquipment->setLinkSignalUpstream(1, SIGNAL_UPSTREAM_INLINE, TRUE); |
| | | pEquipment->setLinkSignalUpstream(1, SIGNAL_UPSTREAM_TROUBLE, FALSE); |
| | | pEquipment->setLinkSignalUpstream(1, SIGNAL_INTERLOCK, TRUE); |
| | | pEquipment->setLinkSignalUpstream(1, SIGNAL_SEND_ABLE, TRUE); |
| | | } |
| | | |
| | | if (pEquipment != nullptr && (pEquipment->getID() == EQ_ID_Bonder1 |
| | | || pEquipment->getID() == EQ_ID_Bonder2)) { |
| | | SERVO::CGlass* pGlass = pEquipment->getAnyGlass(); |
| | | if (pGlass != nullptr) { |
| | | SERVO::CProcessData pd; |
| | | pd.setGlassId(pGlass->getID().c_str()); |
| | | pEquipment->onProcessData(&pd); |
| | | } |
| | | } |
| | | } |
| | | else if (nCmd == ID_EQSGRAPHITEM_TEST5) { |
| | | SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData; |
| | | if (pEquipment != nullptr) { |
| | | pEquipment->setLinkSignalUpstream(0, SIGNAL_UPSTREAM_INLINE, TRUE); |
| | | pEquipment->setLinkSignalUpstream(0, SIGNAL_UPSTREAM_TROUBLE, TRUE); |
| | | pEquipment->setLinkSignalUpstream(0, SIGNAL_INTERLOCK, TRUE); |
| | | pEquipment->setLinkSignalUpstream(0, SIGNAL_SEND_ABLE, FALSE); |
| | | pEquipment->setLinkSignalUpstream(1, SIGNAL_UPSTREAM_INLINE, TRUE); |
| | | pEquipment->setLinkSignalUpstream(1, SIGNAL_UPSTREAM_TROUBLE, TRUE); |
| | | pEquipment->setLinkSignalUpstream(1, SIGNAL_INTERLOCK, TRUE); |
| | | pEquipment->setLinkSignalUpstream(1, SIGNAL_SEND_ABLE, FALSE); |
| | | } |
| | | } |
| | | else if (nCmd == ID_EQSGRAPHITEM_TEST6) { |
| | | SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData; |
| | |
| | | */ |
| | | |
| | | // 测试设置时间 |
| | | /* |
| | | if (pEquipment->getID() == EQ_ID_Bonder1 |
| | | || pEquipment->getID() == EQ_ID_Bonder2) { |
| | | if (pEquipment->getID() == EQ_ID_EFEM) { |
| | | CTime time = CTime::GetCurrentTime(); |
| | | pEquipment->setDateTime((short)time.GetYear(), |
| | | (short)time.GetMonth(), |
| | |
| | | (short)time.GetMinute(), |
| | | (short)time.GetSecond()); |
| | | } |
| | | */ |
| | | |
| | | |
| | | // 测试设置cim mode |
| | |
| | | } |
| | | */ |
| | | |
| | | |
| | | /* |
| | | if (pEquipment->getID() == EQ_ID_Bonder1 |
| | | || pEquipment->getID() == EQ_ID_Bonder2) { |
| | | static int ii = 0; ii++; |
| | | pEquipment->setEqMode((ii % 5) + 1); |
| | | } |
| | | |
| | | |
| | | /* |
| | | SERVO::CGlass* pGlass = pEquipment->getAnyGlass(); |
| | | if (pGlass != nullptr) { |
| | | std::string strDescription; |
| | | SERVO::CPath* pPath = pGlass->getPath(); |
| | | while (pPath != nullptr) { |
| | | pPath->getDescription(strDescription); |
| | | AfxMessageBox(strDescription.c_str()); |
| | | pPath = pPath->getNext(); |
| | | } |
| | | } |
| | | */ |
| | | |
| | | |
| | | // 请求主配方列表 |
| | | if (pEquipment != nullptr) { |
| | | pEquipment->masterRecipeListRequest(0, nullptr); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | BOOL bCheck = ((CButton*)GetDlgItem(IDC_CHECK_ENABLE))->GetCheck() == BST_CHECKED; |
| | | EnableCtrls(bCheck); |
| | | |
| | | #ifdef _LOCAL |
| | | ASSERT(m_pPort != nullptr); |
| | | theApp.m_model.setPortEnable(m_pPort->getIndex(), bCheck); |
| | | #else |
| | | |
| | | // enable port |
| | | g_nMsgDlgShow = 0; |
| | | CMsgDlg msgDlg("请等待", "正在操作,请等待..."); |
| | | |
| | | ASSERT(m_pPort != nullptr); |
| | | theApp.m_model.setPortEnable(m_pPort->getIndex(), bCheck); |
| | | /* |
| | | m_pPort->eablePort(bCheck, [&](int code) -> int { |
| | | Sleep(100); |
| | | CString strMsg; |
| | |
| | | |
| | | msgDlg.DoModal(); |
| | | g_nMsgDlgShow = 1; |
| | | */ |
| | | #endif |
| | | } |
| | | |
| | | void CPagePortProperty::OnCbnSelchangeComboPortType() |
| | |
| | | void CPagePortProperty::EnableCtrls(BOOL bEnable) |
| | | { |
| | | GetDlgItem(IDC_COMBO_PORT_TYPE)->EnableWindow(bEnable); |
| | | GetDlgItem(IDC_COMBO_PORT_MODE)->EnableWindow(bEnable); |
| | | GetDlgItem(IDC_COMBO_PORT_CASSERT_TYPE)->EnableWindow(bEnable); |
| | | GetDlgItem(IDC_COMBO_PORT_TRANSFER_MODE)->EnableWindow(bEnable); |
| | | GetDlgItem(IDC_CHECK_AUTO_CHANGE)->EnableWindow(bEnable); |
| | | } |
| | | |
| | |
| | | |
| | | // 创建Job Existence Slots控件 |
| | | m_ctrlJobSlotGrid.Create(AfxRegisterWndClass(0), _T("JobSlotGrid"), |
| | | WS_CHILD | WS_VISIBLE, CRect(0, 0, 100, 100), this, 1001); |
| | | m_ctrlJobSlotGrid.SetGridSize(12, 16); |
| | | WS_CHILD | WS_VISIBLE, CRect(0, 0, 88, 32), this, 1001); |
| | | m_ctrlJobSlotGrid.SetGridSize(1, 8); |
| | | m_ctrlJobSlotGrid.SetColors(RGB(34, 177, 76), RGB(200, 200, 200)); |
| | | |
| | | m_ctrlJobSlotGrid.SetSlotStatus(0, 1, true); |
| | | m_ctrlJobSlotGrid.SetSlotStatus(1, 9, true); |
| | | m_ctrlJobSlotGrid.SetSlotStatus(4, 9, false); |
| | | m_ctrlJobSlotGrid.SetSlotStatus(4, 10, true, TRUE); |
| | | auto statusMap = m_pPort->getScanCassetteMap(); |
| | | for (int i = 0; i < 8; ++i) { |
| | | bool isSet = (statusMap >> i) & 1; |
| | | m_ctrlJobSlotGrid.SetSlotStatus(0, i, isSet); |
| | | } |
| | | |
| | | return TRUE; // return TRUE unless you set the focus to a control |
| | | // 异常: OCX 属性页应返回 FALSE |
| | |
| | | GetClientRect(rcClient); |
| | | |
| | | m_ctrlJobSlotGrid.MoveWindow(rcComboBox.left, rcLabel.top, |
| | | rcClient.right - 22 - rcComboBox.left, rcClient.bottom - 12 - rcLabel.top); |
| | | 34 * 8, 32); |
| | | } |
| | |
| | | memcpy(&m_nLoadingCassetteType, &pszBuffer[index], sizeof(short)); |
| | | index += sizeof(short); |
| | | |
| | | memcpy(&m_nLoadingCassetteType, &pszBuffer[index], sizeof(short)); |
| | | index += sizeof(short); |
| | | |
| | | memcpy(&m_nQTimeFlag, &pszBuffer[index], sizeof(short)); |
| | | index += sizeof(short); |
| | | |
| | |
| | | #define RX_CODE_EQ_DATA_CHANGED 1010 |
| | | #define RX_CODE_MASTER_STATE_CHANGED 1011 |
| | | #define RX_CODE_EQ_ROBOT_TASK 1012 |
| | | #define RX_CODE_LOADPORT_INUSE 1013 |
| | | #define RX_CODE_LOADPORT_STATUS_CHANGED 1014 |
| | | |
| | | |
| | | /* Channel Name */ |
| | |
| | | notifyPtrAndInt(RX_CODE_EQ_ROBOT_TASK, pTask, nullptr, code); |
| | | |
| | | }; |
| | | masterListener.onLoadPortInUse = [&] (void* pMaster, SERVO::CEquipment* pEquipment, short scanMap) { |
| | | LOGE("<CModel>onLoadPortInUse. scanMap = %d", scanMap); |
| | | notifyPtr(RX_CODE_LOADPORT_INUSE, pEquipment); |
| | | masterListener.onLoadPortStatusChanged = [&] (void* pMaster, SERVO::CEquipment* pEquipment, short status, __int64 data) { |
| | | LOGE("<CModel>onLoadPortStatusChanged. status = %d", status); |
| | | notifyPtr(RX_CODE_LOADPORT_STATUS_CHANGED, pEquipment); |
| | | }; |
| | | m_master.setListener(masterListener); |
| | | |
| | |
| | | } |
| | | } |
| | | } |
| | | else if (RX_CODE_LOADPORT_INUSE == code) { |
| | | else if (RX_CODE_LOADPORT_STATUS_CHANGED == code) { |
| | | SERVO::CLoadPort* pLoadPort = nullptr; |
| | | if (pAny->getPtrValue("ptr", (void*&)pLoadPort)) { |
| | | //CPortConfigurationDlg dlg; |