mrDarker
2025-06-17 58b5bb07de4bcbf670db5ad79ff8b9bd7afc1e28
Merge branch 'clh' into liuyang
已删除1个文件
已修改16个文件
351 ■■■■■ 文件已修改
Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.7(1).xlsx 补丁 | 查看 | 原始文档 | blame | 历史
Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.7.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CArm.cpp 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CArmTray.cpp 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CBonder.cpp 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CBonder.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEFEM.cpp 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEFEM.h 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CEquipment.cpp 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CGlass.cpp 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CGlass.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.cpp 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMeasurement.cpp 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CRobotTask.cpp 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CRobotTask.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ServoCommo.h 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.7(1).xlsx
Binary files differ
Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.7.xlsx
Binary files differ
SourceCode/Bond/Servo/CArm.cpp
@@ -41,10 +41,6 @@
        m_slot[0].setPosition(m_nID);
        m_slot[0].setNo(1);
        m_slot[0].setName("Slot 1(Temp)");
        m_slot[1].enable();
        m_slot[1].setPosition(m_nID);
        m_slot[1].setNo(2);
        m_slot[1].setName("Slot 2(Temp)");
    }
    void CArm::onTimer(UINT nTimerid)
@@ -70,22 +66,14 @@
    int CArm::tempStore(CGlass* pGlass)
    {
        // 原:保证列表中只存储一个物料
        // 修改为:先清空之前的,再添加当前pGlass, 如果pGlass有buddy,也要加入列表中
        // 修改为:先清空之前的,再添加当前pGlass
        Lock();
        CGlass* pPreviousGlass;
        pPreviousGlass = (CGlass*)m_slot[0].getContext();
        if (pPreviousGlass != nullptr) {
            pPreviousGlass->release();
        }
        pPreviousGlass = (CGlass*)m_slot[1].getContext();
        if (pPreviousGlass != nullptr) {
            pPreviousGlass->release();
        }
        m_slot[0].setContext(pGlass);
        if (pGlass->getBuddy() != nullptr) {
            m_slot[1].setContext(pGlass->getBuddy());
        }
        Unlock();
        if (m_listener.onDataChanged != nullptr) {
@@ -106,10 +94,6 @@
        pGlass = pPreviousGlass;
        pGlass->addRef();
        m_slot[0].setContext(nullptr);
        CGlass* pBuddy = pGlass->getBuddy();
        if (pBuddy != nullptr) {
            m_slot[1].setContext(nullptr);
        }
        Unlock();
        if (m_listener.onDataChanged != nullptr) {
SourceCode/Bond/Servo/CArmTray.cpp
@@ -41,10 +41,6 @@
        m_slot[0].setPosition(m_nID);
        m_slot[0].setNo(1);
        m_slot[0].setName("Slot 1");
        m_slot[1].enable();
        m_slot[1].setPosition(m_nID);
        m_slot[1].setNo(2);
        m_slot[1].setName("Slot 2");
    }
    void CArmTray::onTimer(UINT nTimerid)
SourceCode/Bond/Servo/CBonder.cpp
@@ -416,6 +416,14 @@
        return m_nIndex;
    }
    BOOL CBonder::hasBondClass()
    {
        CGlass* pGlass = (CGlass*)m_slot[1].getContext();
        if (pGlass == nullptr) return FALSE;
        CGlass* pBuddy = pGlass->getBuddy();
        return pBuddy != nullptr;
    }
    int CBonder::onProcessData(CProcessData* pProcessData)
    {
        CEquipment::onProcessData(pProcessData);
@@ -423,33 +431,27 @@
        // 检查数据,当前两片玻璃,一片为G1, 一片为G2, 且pProcessData中的id能匹配G1或G2
        Lock();
        CGlass* pGlass1 = getGlassFromSlot(1);
        CGlass* pGlass2 = getGlassFromSlot(2);
        CGlass* pGlass2 = getGlassFromSlot(1);
        CGlass* pGlass1 = getGlassFromSlot(2);
        if (pGlass1 == nullptr || pGlass2 == nullptr) {
            LOGE("<CBonder-%s>onProcessData,错误!不满足两片玻璃且分别为G1与G2的条件,请检查数据是否正确!", m_strName.c_str());
            Unlock();
            return -1;
        }
        if (pGlass1->getBuddy() != nullptr || pGlass2->getBuddy() != nullptr) {
        if (pGlass1->getBuddy() != nullptr) {
            LOGE("<CBonder-%s>onProcessData,错误!玻璃较早前已被绑定,请检查数据是否正确!", m_strName.c_str());
            Unlock();
            return -1;
        }
        if (pGlass1->getBuddy() != nullptr || pGlass2->getBuddy() != nullptr) {
            LOGE("<CBonder-%s>onProcessData,错误!玻璃较早前已被贴合,请检查数据是否正确!", m_strName.c_str());
            Unlock();
            return -1;
        }
        if (pGlass1->getType() == pGlass2->getType()) {
        if (pGlass1->getType() != MaterialsType::G1 || pGlass2->getType() != MaterialsType::G2) {
            LOGE("<CBonder-%s>onProcessData,错误!两片玻璃未匹配,必须分别为G1和G2类型,请检查数据是否正确!", m_strName.c_str());
            Unlock();
            return -1;
        }
        pGlass1->setBuddy(pGlass2);
        pGlass2->setBuddy(pGlass1);
        getSlot(0)->setContext(nullptr);
        LOGE("<CBonder-%s>onProcessData,%s和%s已贴合!", m_strName.c_str(),
            pGlass1->getID().c_str(), pGlass2->getID().c_str());
        Unlock();
SourceCode/Bond/Servo/CBonder.h
@@ -27,6 +27,7 @@
    public:
        void setIndex(unsigned int index);
        unsigned int getIndex();
        BOOL hasBondClass();
    private:
        unsigned int m_nIndex;
SourceCode/Bond/Servo/CEFEM.cpp
@@ -22,6 +22,10 @@
        m_pPort[3] = nullptr;
        m_pAligner = nullptr;
        m_pFliper = nullptr;
        m_robotData.status = ROBOT_STATUS::Idle;
        m_robotData.position = ROBOT_POSITION::Port1;
        m_robotData.armState[0] = FALSE;
        m_robotData.armState[1] = FALSE;
    }
    CEFEM::~CEFEM()
@@ -329,6 +333,11 @@
        cmds[1].rcmd = static_cast<short>(SERVO::RCMD::Robot_home);
        return robotCmds(cmds, 2, onWritedBlock);
    }
    RMDATA& CEFEM::getRobotMonitoringData()
    {
        return m_robotData;
    }
    void CEFEM::init()
@@ -692,6 +701,28 @@
    {
        __super::onReceiveLBData(pszData, size);
        // 解释得到Robot状态
        // 地址从(0x3500 - 0x3000)开始
        int index = 0x500;
        for (int i = 0; i < 6; i++) {
            if (isBitOn(pszData, size, index + i)) {
                m_robotData.status = (ROBOT_STATUS)i;
                break;
            }
        }
        index += 8;
        for (int i = 0; i < 11; i++) {
            if (isBitOn(pszData, size, index + i)) {
                m_robotData.position = (ROBOT_POSITION)i;
                break;
            }
        }
        index += 16;
        m_robotData.armState[0] = isBitOn(pszData, size, index);
        m_robotData.armState[1] = isBitOn(pszData, size, index + 1);
        for (unsigned int i = 0; i < 4; i++) {
            if (m_pPort[i] != nullptr) {
                m_pPort[i]->onReceiveLBData(pszData, size);
SourceCode/Bond/Servo/CEFEM.h
@@ -39,6 +39,7 @@
        void setArmTray(unsigned int index, CArmTray* pArmTray);
        int robotCmd(ROBOT_CMD_PARAM& robotCmdParam, ONWRITED onWritedBlock = nullptr);
        int robotCmds(ROBOT_CMD_PARAM* robotCmdParam, unsigned int count, ONWRITED onWritedBlock = nullptr);
        RMDATA& getRobotMonitoringData();
        // 快捷封装
        int robotSendHome(int seq, ONWRITED onWritedBlock = nullptr);
@@ -62,6 +63,7 @@
        CAligner* m_pAligner;
        CFliper* m_pFliper;
        CArmTray* m_pArmTray[2];
        RMDATA m_robotData;
    };
}
SourceCode/Bond/Servo/CEquipment.cpp
@@ -255,13 +255,21 @@
            if (!m_slot[i].isEnable()) continue;
            CGlass* pGlass = (CGlass*)m_slot[i].getContext();
            CGlass* pBuddy = nullptr;
            if (pGlass == nullptr) {
                attrubutes.addAttribute(new CAttribute(m_slot[i].getName().c_str(),
                    "", "", weight++));
            }
            else {
                pBuddy = pGlass->getBuddy();
                if (pBuddy == nullptr) {
                attrubutes.addAttribute(new CAttribute(m_slot[i].getName().c_str(),
                    pGlass->getID().c_str(), "", weight++));
                }
                else {
                    attrubutes.addAttribute(new CAttribute(m_slot[i].getName().c_str(),
                        (pGlass->getID() + " -> " + pBuddy->getID()).c_str(), "", weight++));
                }
            }
        }
@@ -317,8 +325,13 @@
            Lock();
            for (int i = 0; i < SLOT_MAX; i++) {
                m_slot[i].serialize(ar);
                if (m_slot[i].getContext() != nullptr) {
                    ((CGlass*)m_slot[i].getContext())->serialize(ar);
                CGlass* pGlass = (CGlass *)m_slot[i].getContext();
                if (pGlass != nullptr) {
                    pGlass->serialize(ar);
                    CGlass* pBuddy = pGlass->getBuddy();
                    if (pBuddy != nullptr) {
                        pBuddy->serialize(ar);
                    }
                }
            }
            Unlock();
@@ -330,10 +343,16 @@
                    CGlass* pGlass = theApp.m_model.m_glassPool.allocaGlass();
                    pGlass->serialize(ar);
                    m_slot[i].setContext(pGlass);
                    if (pGlass->getBuddy() != nullptr) {
                        CGlass* pBuddy = theApp.m_model.m_glassPool.allocaGlass();
                        pBuddy->serialize(ar);
                        pGlass->forceSetBuddy(pBuddy);
                    }
                }
            }
            
            // 梳理各玻璃之间的绑定关系
            /*
            Lock();
            for (int i = 0; i < SLOT_MAX; i++) {
                CGlass* pGlass = (CGlass*)m_slot[i].getContext();
@@ -351,6 +370,7 @@
                }
            }
            Unlock();
            */
        }
    }
@@ -770,18 +790,6 @@
            return -3;
        }
        // 如果此玻璃已经贴合,贴合的玻璃也要从列表中移除
        CGlass* pBuddy = pContext->getBuddy();
        if (pBuddy != nullptr) {
            for (int i = 0; i < SLOT_MAX; i++) {
                CGlass* pGlass = (CGlass*)m_slot[i].getContext();
                if (pGlass != nullptr && compareJobDataB(pBuddy->getJobDataB(), pGlass->getJobDataB())) {
                    m_slot[i].setContext(nullptr);
                    break;
                }
            }
        }
        ((CArm*)m_pArm)->tempStore(pContext);
        pContext->release();
@@ -815,6 +823,7 @@
        // 如果此玻璃已经贴合,贴合的玻璃也要从加入到列表中
        /*
        CGlass* pBuddy = pGlass->getBuddy();
        if (pBuddy != nullptr) {
            Lock();
@@ -827,7 +836,7 @@
            }
            Unlock();
        }
        */
        if (m_listener.onDataChanged != nullptr) {
            m_listener.onDataChanged(this, EDCC_STORED_JOB);
SourceCode/Bond/Servo/CGlass.cpp
@@ -135,7 +135,7 @@
            m_jobDataB.unserialize(temp, JOBDATAB_SIZE);
            ar.Read(temp, JOBDATAS_SIZE);
            m_jobDataS.unserialize(temp, JOBDATAS_SIZE);
            ar >> ullPath;                    // 这是m_pBuddy, 用不上
            ar >> ullPath;    m_pBuddy = (CGlass*)ullPath;
            ReadString(ar, m_strBuddyId);
            Unlock();
        }
@@ -166,9 +166,16 @@
        if (m_pBuddy != nullptr) return FALSE;
        if (pGlass->getType() == this->getType()) return FALSE;
        m_pBuddy = pGlass;
        if (m_type == MaterialsType::G1) {
            m_pBuddy->addRef();
        m_strBuddyId = m_pBuddy->getID();
        return TRUE;
        }
    BOOL CGlass::forceSetBuddy(CGlass* pGlass)
    {
        m_pBuddy = pGlass;
        m_pBuddy->addRef();
        m_strBuddyId = m_pBuddy->getID();
        return TRUE;
SourceCode/Bond/Servo/CGlass.h
@@ -33,6 +33,7 @@
        void setJobDataS(CJobDataS* pJobDataS);
        CJobDataS* getJobDataS();
        BOOL setBuddy(CGlass* pGlass);
        BOOL forceSetBuddy(CGlass* pGlass);
        CGlass* getBuddy();
        std::string& getBuddyId();
        void processEnd(unsigned int nEqId, unsigned int nUnit);
SourceCode/Bond/Servo/CMaster.cpp
@@ -343,10 +343,13 @@
            // 调度逻辑处理
            else if (m_state == MASTERSTATE::RUNNING) {
                // 检测判断robot状态
                RMDATA& rmd = pEFEM->getRobotMonitoringData();
                if (rmd.status != ROBOT_STATUS::Idle && rmd.status != ROBOT_STATUS::Run) {
                unlock();
                // LOGI("调度处理中...");
                    continue;
                }
                lock();
                if (m_pActiveRobotTask != nullptr) {
                    unlock();
                    // 检测到当前有正在下午的任务,确保当前任务完成或中止后继续
@@ -376,6 +379,8 @@
                // Measurement -> LoadPort
                LOGI("Arm1 %s, Arm2 %s.", rmd.armState[0] ? _T("不可用") : _T("可用"),
                    rmd.armState[1] ? _T("不可用") : _T("可用"));
                CLoadPort* pEqLoadPort[] = { pLoadPort1, pLoadPort2, pLoadPort3, pLoadPort4 };
                CEquipment* pEqTar[] = { pVacuumBake, pFliper };
                if (primaryType == MaterialsType::G2) {
@@ -383,7 +388,7 @@
                    pEqTar[1] = pVacuumBake;
                }
                for (int s = 0; s < 4; s++) {
                    if (pEqLoadPort[s]->isEnable()
                    if (!rmd.armState[0] && pEqLoadPort[s]->isEnable()
                        && pEqLoadPort[s]->getPortType() == PortType::Unloading
                        && pEqLoadPort[s]->getPortMode() == PortMode::ReadyToUnload) {
                        m_pActiveRobotTask = createTransferTask(pMeasurement, pEqLoadPort[s], primaryType, secondaryType);
@@ -407,6 +412,7 @@
                // BakeCooling ->Measurement
                if (!rmd.armState[0]) {
                m_pActiveRobotTask = createTransferTask_bakecooling_to_measurement(pBakeCooling, pMeasurement);
                if (m_pActiveRobotTask != nullptr) {
                    m_pActiveRobotTask->pick();
@@ -418,10 +424,13 @@
                    LOGI("创建新任务<%s>...", strDescription.c_str());
                    continue;
                }
                }
                
                // BakeCooling内部
                // Bake -> Cooling
                if (!rmd.armState[0]) {
                m_pActiveRobotTask = createTransferTask_bake_to_cooling(pBakeCooling);
                if (m_pActiveRobotTask != nullptr) {
                    m_pActiveRobotTask->pick();
@@ -433,9 +442,11 @@
                    LOGI("创建新任务<%s>...", strDescription.c_str());
                    continue;
                }
                }
                // Bonder -> BakeCooling
                if (!rmd.armState[0]) {
                m_pActiveRobotTask = createTransferTask_bonder_to_bakecooling(pBonder1, pBakeCooling);
                if (m_pActiveRobotTask != nullptr) {
                    m_pActiveRobotTask->pick();
@@ -447,7 +458,9 @@
                    LOGI("创建新任务<%s>...", strDescription.c_str());
                    continue;
                }
                }
                if (!rmd.armState[0]) {
                m_pActiveRobotTask = createTransferTask_bonder_to_bakecooling(pBonder2, pBakeCooling);
                if (m_pActiveRobotTask != nullptr) {
                    m_pActiveRobotTask->pick();
@@ -459,9 +472,12 @@
                    LOGI("创建新任务<%s>...", strDescription.c_str());
                    continue;
                }
                }
                // Fliper(G2) -> Bonder
                // VacuumBake(G1) -> Bonder
                if (!rmd.armState[1] && !pBonder1->hasBondClass()) {
                m_pActiveRobotTask = createTransferTask(pFliper, pBonder1, primaryType, secondaryType, 2);
                if (m_pActiveRobotTask != nullptr) {
                    m_pActiveRobotTask->pick();
@@ -473,7 +489,9 @@
                    LOGI("创建新任务<%s>...", strDescription.c_str());
                    continue;
                }
                }
                if (!rmd.armState[1] && !pBonder2->hasBondClass()) {
                m_pActiveRobotTask = createTransferTask(pFliper, pBonder2, primaryType, secondaryType, 2);
                if (m_pActiveRobotTask != nullptr) {
                    m_pActiveRobotTask->pick();
@@ -485,7 +503,9 @@
                    LOGI("创建新任务<%s>...", strDescription.c_str());
                    continue;
                }
                }
                if (!rmd.armState[0] && !pBonder1->hasBondClass()) {
                m_pActiveRobotTask = createTransferTask(pVacuumBake, pBonder1, primaryType, secondaryType);
                if (m_pActiveRobotTask != nullptr) {
                    m_pActiveRobotTask->pick();
@@ -497,7 +517,9 @@
                    LOGI("创建新任务<%s>...", strDescription.c_str());
                    continue;
                }
                }
                if (!rmd.armState[0] && !pBonder2->hasBondClass()) {
                m_pActiveRobotTask = createTransferTask(pVacuumBake, pBonder2, primaryType, secondaryType);
                if (m_pActiveRobotTask != nullptr) {
                    m_pActiveRobotTask->pick();
@@ -509,9 +531,12 @@
                    LOGI("创建新任务<%s>...", strDescription.c_str());
                    continue;
                }
                }
                // Aligner -> Fliper(G2)
                // Aligner -> VacuumBake(G1)
                if (!rmd.armState[1]) {
                m_pActiveRobotTask = createTransferTask(pAligner, pFliper, primaryType, secondaryType, 2);
                if (m_pActiveRobotTask != nullptr) {
                    m_pActiveRobotTask->pick();
@@ -523,7 +548,9 @@
                    LOGI("创建新任务<%s>...", strDescription.c_str());
                    continue;
                }
                }
                if (!rmd.armState[0]) {
                m_pActiveRobotTask = createTransferTask(pAligner, pVacuumBake, primaryType, secondaryType);
                if (m_pActiveRobotTask != nullptr) {
                    m_pActiveRobotTask->pick();
@@ -535,11 +562,11 @@
                    LOGI("创建新任务<%s>...", strDescription.c_str());
                    continue;
                }
                }
                // LoadPort -> Aligner
                for (int s = 0; s < 4; s++) {
                    if (pEqLoadPort[s]->isEnable()
                    if (!rmd.armState[0] && pEqLoadPort[s]->isEnable()
                        && pEqLoadPort[s]->getPortType() == PortType::Loading
                        && pEqLoadPort[s]->getPortMode() == PortMode::ReadyToLoad) {
                        m_pActiveRobotTask = createTransferTask(pEqLoadPort[s], pAligner, primaryType, secondaryType);
@@ -1185,14 +1212,11 @@
        if (pSrcSlot != nullptr && nullptr != pTarSlot) {
            int srcPos, srcSlot, tarPos, tarSlot;
            transformPosAndSlot(pSrcSlot->getPosition(), pSrcSlot->getNo(), srcPos, srcSlot);
            transformPosAndSlot(pTarSlot->getPosition(), pTarSlot->getNo(), tarPos, tarSlot);
            pTask = new CRobotTask();
            pTask->setContext(pSrcSlot->getContext());
            pTask->setEFEM((CEFEM*)getEquipment(EQ_ID_EFEM));
            taskSeqNo = pTask->setRobotTransferParam(taskSeqNo, armNo, srcPos,
                tarPos, srcSlot, tarSlot);
            taskSeqNo = pTask->setRobotTransferParam(taskSeqNo, armNo, pSrcSlot->getPosition(),
                pTarSlot->getPosition(), pSrcSlot->getNo(), pTarSlot->getNo());
        }
@@ -1209,14 +1233,11 @@
        pSrcSlot = pSrcEq->getProcessedSlot(MaterialsType::G1);
        if (pSrcSlot != nullptr && nullptr != pTarSlot) {
            int srcPos, srcSlot, tarPos, tarSlot;
            transformPosAndSlot(pSrcSlot->getPosition(), pSrcSlot->getNo(), srcPos, srcSlot);
            transformPosAndSlot(pTarSlot->getPosition(), pTarSlot->getNo(), tarPos, tarSlot);
            pTask = new CRobotTask();
            pTask->setContext(pSrcSlot->getContext());
            pTask->setEFEM((CEFEM*)getEquipment(EQ_ID_EFEM));
            taskSeqNo = pTask->setRobotTransferParam(taskSeqNo, 1, srcPos,
                tarPos, srcSlot, tarSlot);
            taskSeqNo = pTask->setRobotTransferParam(taskSeqNo, 1, pSrcSlot->getPosition(),
                pTarSlot->getPosition(), pSrcSlot->getNo(), pTarSlot->getNo());
        }
@@ -1234,14 +1255,11 @@
        pSrcSlot = pSrcEq->getProcessedSlot2(MaterialsType::G1, slotsSrc);
        if (pSrcSlot != nullptr && nullptr != pTarSlot) {
            int srcPos, srcSlot, tarPos, tarSlot;
            transformPosAndSlot(pSrcSlot->getPosition(), pSrcSlot->getNo(), srcPos, srcSlot);
            transformPosAndSlot(pTarSlot->getPosition(), pTarSlot->getNo(), tarPos, tarSlot);
            pTask = new CRobotTask();
            pTask->setContext(pSrcSlot->getContext());
            pTask->setEFEM((CEFEM*)getEquipment(EQ_ID_EFEM));
            taskSeqNo = pTask->setRobotTransferParam(taskSeqNo, 1, srcPos,
                tarPos, srcSlot, tarSlot);
            taskSeqNo = pTask->setRobotTransferParam(taskSeqNo, 1, pSrcSlot->getPosition(),
                pTarSlot->getPosition(), pSrcSlot->getNo(), pTarSlot->getNo());
        }
@@ -1258,68 +1276,15 @@
        pSrcSlot = pSrcEq->getProcessedSlot2(MaterialsType::G1, slots);
        if (pSrcSlot != nullptr && nullptr != pTarSlot) {
            int srcPos, srcSlot, tarPos, tarSlot;
            transformPosAndSlot(pSrcSlot->getPosition(), pSrcSlot->getNo(), srcPos, srcSlot);
            transformPosAndSlot(pTarSlot->getPosition(), pTarSlot->getNo(), tarPos, tarSlot);
            pTask = new CRobotTask();
            pTask->setContext(pSrcSlot->getContext());
            pTask->setEFEM((CEFEM*)getEquipment(EQ_ID_EFEM));
            taskSeqNo = pTask->setRobotTransferParam(taskSeqNo, 1, srcPos,
                tarPos, srcSlot, tarSlot);
            taskSeqNo = pTask->setRobotTransferParam(taskSeqNo, 1, pSrcSlot->getPosition(),
                pTarSlot->getPosition(), pSrcSlot->getNo(), pTarSlot->getNo());
        }
        return pTask;
    }
    void CMaster::transformPosAndSlot(int srcPos, int srcSlot, int& tarPos, int& tarSlot)
    {
        switch (srcPos)
        {
        case EQ_ID_LOADPORT1:
        case EQ_ID_LOADPORT2:
        case EQ_ID_LOADPORT3:
        case EQ_ID_LOADPORT4:
        case EQ_ID_ARM_TRAY1:
        case EQ_ID_ARM_TRAY2:
        case EQ_ID_ALIGNER:
        case EQ_ID_FLIPER:
            tarPos = srcPos;
            tarSlot = 1;
            break;
        case EQ_ID_Bonder1:
            if (1 <= srcSlot && srcSlot <= 2) {
                tarPos = 9 + srcSlot;
                tarSlot = 1;
            }
            break;
        case EQ_ID_Bonder2:
            if (1 <= srcSlot && srcSlot <= 2) {
                tarPos = 11 + srcSlot;
                tarSlot = 1;
            }
            break;
        case EQ_ID_VACUUMBAKE:
            if (1 <= srcSlot && srcSlot <= 2) {
                tarPos = 13 + srcSlot;
                tarSlot = 1;
            }
            break;
        case EQ_ID_BAKE_COOLING:
            if (1 <= srcSlot && srcSlot <= 4) {
                tarPos = 15 + srcSlot;
                tarSlot = 1;
            }
            break;
        case EQ_ID_MEASUREMENT:
            tarPos = 19;
            tarSlot = 1;
            break;
        default:
            tarPos = srcPos;
            tarSlot = srcSlot;
            break;
        }
    }
    int CMaster::abortCurrentTask()
SourceCode/Bond/Servo/CMaster.h
@@ -93,7 +93,6 @@
        CRobotTask* createTransferTask_bonder_to_bakecooling(CEquipment* pSrcEq, CEquipment* pTarEq);
        CRobotTask* createTransferTask_bake_to_cooling(CEquipment* pSrcEq);
        CRobotTask* createTransferTask_bakecooling_to_measurement(CEquipment* pSrcEq, CEquipment* pTarEq);
        void transformPosAndSlot(int srcPos, int srcSlot, int& tarPos, int& tarSlot);
    private:
        CRITICAL_SECTION m_criticalSection;
SourceCode/Bond/Servo/CMeasurement.cpp
@@ -340,10 +340,6 @@
        m_slot[0].setPosition(m_nID);
        m_slot[0].setNo(1);
        m_slot[0].setName("Slot 1");
        m_slot[1].enable();
        m_slot[1].setPosition(m_nID);
        m_slot[1].setNo(2);
        m_slot[1].setName("Slot 2");
    }
    void CMeasurement::onTimer(UINT nTimerid)
SourceCode/Bond/Servo/CRobotTask.cpp
@@ -117,26 +117,31 @@
        m_robotCmdParam[ACTION_TRANSFER].putPosition = static_cast<short>(toPos);
        m_robotCmdParam[ACTION_TRANSFER].putSlotNo = static_cast<short>(toSlot);
        // 转换一下源和目标站号
        int srcPos, srcSlot, tarPos, tarSlot;
        transformPosAndSlot(fromPos, fromSlot, srcPos, srcSlot);
        transformPosAndSlot(toPos, toSlot, tarPos, tarSlot);
        m_robotCmdParam[ACTION_PICK] = {};
        m_robotCmdParam[ACTION_PICK].sequenceNo = static_cast<short>(seq+2);
        m_robotCmdParam[ACTION_PICK].rcmd = static_cast<short>(SERVO::RCMD::Get);
        m_robotCmdParam[ACTION_PICK].armNo = static_cast<short>(armNo);
        m_robotCmdParam[ACTION_PICK].getPosition = static_cast<short>(fromPos);
        m_robotCmdParam[ACTION_PICK].getSlotNo = static_cast<short>(fromSlot);
        m_robotCmdParam[ACTION_PICK].getPosition = static_cast<short>(srcPos);
        m_robotCmdParam[ACTION_PICK].getSlotNo = static_cast<short>(srcSlot);
        m_robotCmdParam[ACTION_PLACE] = {};
        m_robotCmdParam[ACTION_PLACE].sequenceNo = static_cast<short>(seq + 2);
        m_robotCmdParam[ACTION_PLACE].rcmd = static_cast<short>(SERVO::RCMD::Put);
        m_robotCmdParam[ACTION_PLACE].armNo = static_cast<short>(armNo);
        m_robotCmdParam[ACTION_PLACE].putPosition = static_cast<short>(toPos);
        m_robotCmdParam[ACTION_PLACE].putSlotNo = static_cast<short>(toSlot);
        m_robotCmdParam[ACTION_PLACE].putPosition = static_cast<short>(tarPos);
        m_robotCmdParam[ACTION_PLACE].putSlotNo = static_cast<short>(tarSlot);
        m_robotCmdParam[ACTION_RESTORE] = {};
        m_robotCmdParam[ACTION_RESTORE].sequenceNo = static_cast<short>(seq + 1);
        m_robotCmdParam[ACTION_RESTORE].rcmd = static_cast<short>(SERVO::RCMD::Put);
        m_robotCmdParam[ACTION_RESTORE].armNo = static_cast<short>(armNo);
        m_robotCmdParam[ACTION_RESTORE].putPosition = static_cast<short>(fromPos);
        m_robotCmdParam[ACTION_RESTORE].putSlotNo = static_cast<short>(fromSlot);
        m_robotCmdParam[ACTION_RESTORE].putPosition = static_cast<short>(srcPos);
        m_robotCmdParam[ACTION_RESTORE].putSlotNo = static_cast<short>(srcSlot);
        return seq + 1;
    }
@@ -339,4 +344,54 @@
    {
        m_timeStored = CToolUnits::getUnixTimestamp();;
    }
    void CRobotTask::transformPosAndSlot(int srcPos, int srcSlot, int& tarPos, int& tarSlot)
    {
        switch (srcPos)
        {
        case EQ_ID_LOADPORT1:
        case EQ_ID_LOADPORT2:
        case EQ_ID_LOADPORT3:
        case EQ_ID_LOADPORT4:
        case EQ_ID_ARM_TRAY1:
        case EQ_ID_ARM_TRAY2:
        case EQ_ID_ALIGNER:
        case EQ_ID_FLIPER:
            tarPos = srcPos;
            tarSlot = 1;
            break;
        case EQ_ID_Bonder1:
            if (1 <= srcSlot && srcSlot <= 2) {
                tarPos = 9 + srcSlot;
                tarSlot = 1;
            }
            break;
        case EQ_ID_Bonder2:
            if (1 <= srcSlot && srcSlot <= 2) {
                tarPos = 11 + srcSlot;
                tarSlot = 1;
            }
            break;
        case EQ_ID_VACUUMBAKE:
            if (1 <= srcSlot && srcSlot <= 2) {
                tarPos = 13 + srcSlot;
                tarSlot = 1;
            }
            break;
        case EQ_ID_BAKE_COOLING:
            if (1 <= srcSlot && srcSlot <= 4) {
                tarPos = 15 + srcSlot;
                tarSlot = 1;
            }
            break;
        case EQ_ID_MEASUREMENT:
            tarPos = 19;
            tarSlot = 1;
            break;
        default:
            tarPos = srcPos;
            tarSlot = srcSlot;
            break;
        }
    }
}
SourceCode/Bond/Servo/CRobotTask.h
@@ -55,6 +55,7 @@
    private:
        static std::string& generateId(std::string& out);
        void transformPosAndSlot(int srcPos, int srcSlot, int& tarPos, int& tarSlot);
    private:
        ROBOT_TASK_STATE m_state;                    /* 任务状态 */
SourceCode/Bond/Servo/ServoCommo.h
@@ -118,6 +118,38 @@
        Completed
    };
    enum class ROBOT_STATUS {
        Setup = 0,
        Idle,
        Run,
        Pause,
        Stop,
        Moving,
    };
    enum class ROBOT_POSITION {
        Port1 = 0,
        Port2,
        Port3,
        Port4,
        Aligner,
        Fliper,
        Bonder1,
        Bonder2,
        Bake,
        Cooling,
        Measurement
    };
    /* Indexer Monitoring Status */
    /* Robot Monitoring Data */
    typedef struct _ROBOT_MONITORING_DATA {
        ROBOT_STATUS status;
        ROBOT_POSITION position;
        BOOL armState[2];
    } ROBOT_MONITORING_DATA, RMDATA;
    /* EQ Data changed code */
#define EDCC_FETCHOUT_JOB                1000    /* ȡƬ */
#define EDCC_STORED_JOB                    1001    /* 放片 */