1.增加Aligner --> Bonder1 | Bonder2的搬送检测逻辑;
2.优化搬送逻辑。搬送要分优先考虑的主类型和次要类型。一种情况,如果不分主次,一直搬G1, 等到Bonder1和Bonder2都放了G1, Aligner也放了G1, Bonder1和Bonder2需要的G2就过不来了(在Aligner阻塞了)。另外从生产效率上来说,也应该根据需求,尽快使其中一台Bonder的两片玻璃匹配以使其能尽快开始生产加工。
已修改3个文件
144 ■■■■ 文件已修改
SourceCode/Bond/Servo/CBonder.cpp 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.cpp 133 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.h 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CBonder.cpp
@@ -342,13 +342,13 @@
        m_slot[0].enable();
        m_slot[0].setPosition(m_nID);
        m_slot[0].setNo(1);
        m_slot[0].setName("Slot 1(G1)");
        m_slot[0].setType(MaterialsType::G1);
        m_slot[0].setName("Slot 1(G2)");
        m_slot[0].setType(MaterialsType::G2);
        m_slot[1].enable();
        m_slot[1].setPosition(m_nID);
        m_slot[1].setNo(2);
        m_slot[1].setName("Slot 2(G2)");
        m_slot[1].setType(MaterialsType::G2);
        m_slot[1].setName("Slot 2(G1)");
        m_slot[1].setType(MaterialsType::G1);
    }
    void CBonder::onTimer(UINT nTimerid)
SourceCode/Bond/Servo/CMaster.cpp
@@ -279,18 +279,29 @@
    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);
        ASSERT(pLoadPort1);
        ASSERT(pLoadPort2);
        ASSERT(pFliper);
        ASSERT(pVacuumBack);
        ASSERT(pAligner);
        ASSERT(pBonder1);
        ASSERT(pBonder2);
        while (1) {
            // 待退出信号或时间到
@@ -333,8 +344,30 @@
                    continue;
                }
                // LoadPort -> Fliper(G2)
                m_pActiveRobotTask = createTransferTask(pLoadPort1, pFliper);
                // 此处检测优先类型和次要类型(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;
                }
                // Aligner -> Bonder
                m_pActiveRobotTask = createTransferTask(pAligner, pBonder1, primaryType, secondaryType);
                if (m_pActiveRobotTask != nullptr) {
                    std::string strDescription = m_pActiveRobotTask->getDescription();
                    unlock();
@@ -345,32 +378,7 @@
                    continue;
                }
                m_pActiveRobotTask = createTransferTask(pLoadPort2, pFliper);
                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, pVacuumBack);
                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, pVacuumBack);
                m_pActiveRobotTask = createTransferTask(pAligner, pBonder2, primaryType, secondaryType);
                if (m_pActiveRobotTask != nullptr) {
                    std::string strDescription = m_pActiveRobotTask->getDescription();
                    unlock();
@@ -384,7 +392,7 @@
                // Fliper(G2) -> Aligner
                // VacuumBake(G1) -> Aligner
                m_pActiveRobotTask = createTransferTask(pFliper, pAligner);
                m_pActiveRobotTask = createTransferTask(pFliper, pAligner, primaryType, secondaryType);
                if (m_pActiveRobotTask != nullptr) {
                    std::string strDescription = m_pActiveRobotTask->getDescription();
                    unlock();
@@ -395,7 +403,38 @@
                    continue;
                }
                m_pActiveRobotTask = createTransferTask(pVacuumBack, pAligner);
                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();
@@ -408,9 +447,28 @@
                // 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;
                }
                // Aligner -> Bonder
                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;
                }
                // Bonder -> BakeCooling
@@ -1010,15 +1068,16 @@
    }
    static int taskSeqNo = 0;
    CRobotTask* CMaster::createTransferTask(CEquipment* pSrcEq, CEquipment* pTarEq)
    CRobotTask* CMaster::createTransferTask(CEquipment* pSrcEq, CEquipment* pTarEq,
        MaterialsType primaryType/* = MaterialsType::G1*/, MaterialsType secondaryType/* = MaterialsType::G2*/)
    {
        CRobotTask* pTask = nullptr;
        CSlot* pSrcSlot, * pTarSlot;
        pTarSlot = pTarEq->getAvailableSlotForGlass(MaterialsType::G1);
        pSrcSlot = pSrcEq->getNonEmptySlot(MaterialsType::G1);
        pTarSlot = pTarEq->getAvailableSlotForGlass(primaryType);
        pSrcSlot = pSrcEq->getNonEmptySlot(primaryType);
        if (pSrcSlot == nullptr || nullptr == pTarSlot) {
            pTarSlot = pTarEq->getAvailableSlotForGlass(MaterialsType::G2);
            pSrcSlot = pSrcEq->getNonEmptySlot(MaterialsType::G2);
            pTarSlot = pTarEq->getAvailableSlotForGlass(secondaryType);
            pSrcSlot = pSrcEq->getNonEmptySlot(secondaryType);
        }
SourceCode/Bond/Servo/CMaster.h
@@ -84,7 +84,8 @@
        int readCache();
        void serialize(CArchive& ar);
        void setState(MASTERSTATE state);
        CRobotTask* createTransferTask(CEquipment* pSrcEq, CEquipment* pTarEq);
        CRobotTask* createTransferTask(CEquipment* pSrcEq, CEquipment* pTarEq,
            MaterialsType primaryType = MaterialsType::G1, MaterialsType secondaryType = MaterialsType::G2);
    private:
        CRITICAL_SECTION m_criticalSection;