| | |
| | | m_ullRunTime = 0; |
| | | m_state = MASTERSTATE::READY; |
| | | m_curveMode = CurveMode::Production; |
| | | m_schedulingMode = SchedulingMode::Production; |
| | | m_pActiveRobotTask = nullptr; |
| | | m_nLastError = ER_CODE_NOERROR; |
| | | m_isCompareMapsBeforeProceeding = FALSE; |
| | |
| | | CurveMode CMaster::getCurveMode() const |
| | | { |
| | | return m_curveMode; |
| | | } |
| | | |
| | | void CMaster::setSchedulingMode(SchedulingMode mode) |
| | | { |
| | | m_schedulingMode = mode; |
| | | LOGI("<Master>SchedulingMode=%s", mode == SchedulingMode::Production ? "Production" : "Tuning"); |
| | | } |
| | | |
| | | SchedulingMode CMaster::getSchedulingMode() const |
| | | { |
| | | return m_schedulingMode; |
| | | } |
| | | |
| | | int CMaster::term() |
| | |
| | | |
| | | |
| | | // 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; |
| | | if (m_schedulingMode == SchedulingMode::Production) { |
| | | if (!rmd.armState[0]) { |
| | | m_pActiveRobotTask = createTransferTask_returnOrigin(pMeasurement, pLoadPorts); |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | | } |
| | | else { |
| | | 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; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | // 组数门限:≥2 组时不再从 LP 上片,避免堆积(与单片一致) |
| | | bool blockLoadFromLP = (nGlassGroup >= 2); |
| | | |
| | | // 7) Measurement -> LoadPort(固定:G1 优先回 LP) |
| | | // 7) 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], MaterialsType::G1, secondaryType); |
| | | if (m_pActiveRobotTask != nullptr) { goto BATCH_PORT_PUT; } |
| | | if (m_schedulingMode == SchedulingMode::Production) { |
| | | if (!rmd.armState[0]) { |
| | | m_pActiveRobotTask = createTransferTask_returnOrigin(pMeasurement, pLoadPorts); |
| | | CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask); |
| | | } |
| | | } |
| | | else { |
| | | 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 BATCH_PORT_PUT; } |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | nRet = pLoadPort1->getPin("Out")->connectPin(pAligner->getPin("In1")); |
| | | if (nRet < 0) { |
| | | LOGE("连接LoadPort1-Fliper失败"); |
| | | LOGE("连接LoadPort1-Aligner失败"); |
| | | } |
| | | nRet = pLoadPort2->getPin("Out")->connectPin(pAligner->getPin("In2")); |
| | | if (nRet < 0) { |
| | | LOGE("连接LoadPort1-Fliper失败"); |
| | | LOGE("连接LoadPort2-Aligner失败"); |
| | | } |
| | | nRet = pLoadPort3->getPin("Out")->connectPin(pAligner->getPin("In3")); |
| | | if (nRet < 0) { |
| | | LOGE("连接LoadPort3-Aligner失败"); |
| | | } |
| | | nRet = pLoadPort4->getPin("Out")->connectPin(pAligner->getPin("In4")); |
| | | if (nRet < 0) { |
| | | LOGE("连接LoadPort4-Aligner失败"); |
| | | } |
| | | |
| | | nRet = pAligner->getPin("Out1")->connectPin(pFliper->getPin("In")); |
| | |
| | | LOGE("连接BakeCooling-LoadPort3失败"); |
| | | } |
| | | |
| | | nRet = pMeasurement->getPin("Out1")->connectPin(pLoadPort3->getPin("In")); |
| | | if (nRet < 0) { |
| | | LOGE("连接BakeCooling-LoadPort3失败"); |
| | | } |
| | | if (m_schedulingMode == SchedulingMode::Production) { |
| | | // 生产模式:测量输出回到 G1 原位(默认 Port1 / Port3) |
| | | nRet = pMeasurement->getPin("Out1")->connectPin(pLoadPort1->getPin("In")); |
| | | if (nRet < 0) { |
| | | LOGE("连接Measurement-LoadPort1失败"); |
| | | } |
| | | |
| | | nRet = pMeasurement->getPin("Out2")->connectPin(pLoadPort4->getPin("In")); |
| | | if (nRet < 0) { |
| | | LOGE("连接BakeCooling-LoadPort4失败"); |
| | | nRet = pMeasurement->getPin("Out2")->connectPin(pLoadPort3->getPin("In")); |
| | | if (nRet < 0) { |
| | | LOGE("连接Measurement-LoadPort3失败"); |
| | | } |
| | | } |
| | | else { |
| | | // 调机模式:维持原连接(Out1->Port3, Out2->Port4) |
| | | nRet = pMeasurement->getPin("Out1")->connectPin(pLoadPort3->getPin("In")); |
| | | if (nRet < 0) { |
| | | LOGE("连接Measurement-LoadPort3失败"); |
| | | } |
| | | |
| | | nRet = pMeasurement->getPin("Out2")->connectPin(pLoadPort4->getPin("In")); |
| | | if (nRet < 0) { |
| | | LOGE("连接Measurement-LoadPort4失败"); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | return pTask; |
| | | } |
| | | |
| | | CRobotTask* CMaster::createTransferTask_returnOrigin(CEquipment* pEqSrc, CLoadPort** pPorts) |
| | | { |
| | | if (!pEqSrc->IsEnabled()) { |
| | | return nullptr; |
| | | } |
| | | |
| | | CSlot* pSrcSlot = pEqSrc->getProcessedSlot(MaterialsType::G1, m_bJobMode); |
| | | if (pSrcSlot == nullptr) { |
| | | return nullptr; |
| | | } |
| | | |
| | | CGlass* pGlass = (CGlass*)pSrcSlot->getContext(); |
| | | if (pGlass == nullptr) { |
| | | return nullptr; |
| | | } |
| | | |
| | | int port = 0, slot = 0; |
| | | pGlass->getOrginPort(port, slot); |
| | | if (port < 0 || port >= 4 || slot < 0 || slot >= SLOT_MAX) { |
| | | return nullptr; |
| | | } |
| | | |
| | | CLoadPort* pPort = pPorts[port]; |
| | | if (pPort == nullptr || !pPort->isEnable()) { |
| | | return nullptr; |
| | | } |
| | | PortType pt = pPort->getPortType(); |
| | | if (!(pt == PortType::Unloading || pt == PortType::Both)) { |
| | | return nullptr; |
| | | } |
| | | if (pPort->getPortStatus() != PORT_INUSE) { |
| | | return nullptr; |
| | | } |
| | | |
| | | CSlot* pTarSlot = pPort->getSlot(slot); |
| | | if (pTarSlot == nullptr) { |
| | | return nullptr; |
| | | } |
| | | if (!pTarSlot->isEnable() || pTarSlot->isLock() || pTarSlot->getContext() != nullptr) { |
| | | return nullptr; |
| | | } |
| | | |
| | | CRobotTask* 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*/) |
| | | { |
| | |
| | | pPort->localSetCessetteType(type); |
| | | } |
| | | |
| | | void CMaster::applySchedulingModePortMapping() |
| | | { |
| | | // 生产模式:固定 Port1/Port3 为 G1,Port2/Port4 为 G2(G4 未定义,按 G2 处理) |
| | | if (m_schedulingMode != SchedulingMode::Production) { |
| | | return; |
| | | } |
| | | |
| | | setPortCassetteType(0, SERVO::CassetteType::G1); |
| | | setPortCassetteType(1, SERVO::CassetteType::G2); |
| | | setPortCassetteType(2, SERVO::CassetteType::G1); |
| | | setPortCassetteType(3, SERVO::CassetteType::G2); |
| | | } |
| | | |
| | | void CMaster::setPortEnable(unsigned int index, BOOL bEnable) |
| | | { |
| | | ASSERT(index < 4); |
| | |
| | | slotProcess = jobExistence[0]; |
| | | } |
| | | |
| | | bool hasExistence = false; |
| | | for (short w : jobExistence) { |
| | | if (w != 0) { hasExistence = true; break; } |
| | | } |
| | | const int portStatus = pPort->getPortStatus(); |
| | | if (!hasExistence) { |
| | | LOGE("ProcessStart blocked (ProceedWithCarrier): no JobExistence map (port=%u, portStatus=%d, scanMap=%d, cassetteId=%s).", |
| | | port + 1, portStatus, scanMap, pPort->getCassetteId().c_str()); |
| | | return -2; |
| | | } |
| | | if (portStatus != PORT_INUSE) { |
| | | LOGW("ProcessStart warning (ProceedWithCarrier): port status is %d (expected INUSE).", portStatus); |
| | | } |
| | | |
| | | pPort->sendCassetteCtrlCmd(CCC_PROCESS_START, jobExistence, 12, slotProcess, jobCount, nullptr, nullptr); |
| | | return 0; |
| | | } |