From ce83df0657786b340be5cc2e9817fb2392117ac9 Mon Sep 17 00:00:00 2001
From: LAPTOP-SNT8I5JK\Boounion <Chenluhua@qq.com>
Date: 星期四, 29 五月 2025 16:23:54 +0800
Subject: [PATCH] 1.理顺CRobotTask(搬送任务)和Glass,Slot, JobData等关系,实现创建调度任务,模拟拔片测试;
---
SourceCode/Bond/Servo/CPageGraph2.cpp | 27 ++-
Document/BONDER流程信息表.xls | 0
SourceCode/Bond/Servo/CRobotTask.h | 23 +++
Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.6(5).xlsx | 0
SourceCode/Bond/Servo/CSlot.cpp | 23 ++-
SourceCode/Bond/Servo/CEquipment.cpp | 13 +
SourceCode/Bond/Servo/CRobotTask.cpp | 89 ++++++++++++++
SourceCode/Bond/Servo/CMaster.cpp | 127 ++++++++++++++++++++
SourceCode/Bond/Servo/CMaster.h | 1
SourceCode/Bond/Servo/CEquipment.h | 2
SourceCode/Bond/Servo/CLoadPort.cpp | 9 +
SourceCode/Bond/Servo/ServoCommo.h | 4
12 files changed, 294 insertions(+), 24 deletions(-)
diff --git "a/Document/BONDER\346\265\201\347\250\213\344\277\241\346\201\257\350\241\250.xls" "b/Document/BONDER\346\265\201\347\250\213\344\277\241\346\201\257\350\241\250.xls"
new file mode 100644
index 0000000..de0f4cf
--- /dev/null
+++ "b/Document/BONDER\346\265\201\347\250\213\344\277\241\346\201\257\350\241\250.xls"
Binary files differ
diff --git "a/Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.6\0505\051.xlsx" "b/Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.6\0505\051.xlsx"
new file mode 100644
index 0000000..e02265f
--- /dev/null
+++ "b/Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.6\0505\051.xlsx"
Binary files differ
diff --git a/SourceCode/Bond/Servo/CEquipment.cpp b/SourceCode/Bond/Servo/CEquipment.cpp
index 319cb86..d9fb8e9 100644
--- a/SourceCode/Bond/Servo/CEquipment.cpp
+++ b/SourceCode/Bond/Servo/CEquipment.cpp
@@ -27,7 +27,7 @@
CEquipment::CEquipment() : m_nID(0), m_strName(""), m_strDescription(""), m_station(0, 255)
{
- m_listener = { nullptr, nullptr, nullptr, nullptr, nullptr };
+ m_listener = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
m_alive = { FALSE, 0, FALSE };
m_bCimState = FALSE;
m_bUpstreamInline = FALSE;
@@ -76,6 +76,7 @@
m_listener.onAlarm = listener.onAlarm;
m_listener.onDataChanged = listener.onDataChanged;
m_listener.onVcrEventReport = listener.onVcrEventReport;
+ m_listener.onPreFethedOutJob = listener.onPreFethedOutJob;
}
void CEquipment::setCcLink(CCCLinkIEControl* pCcLink)
@@ -754,7 +755,7 @@
Unlock();
if (m_listener.onDataChanged != nullptr) {
- m_listener.onDataChanged(this, 0);
+ m_listener.onDataChanged(this, EDCC_FETCHOUT_JOB);
}
return 0;
@@ -794,7 +795,7 @@
if (m_listener.onDataChanged != nullptr) {
- m_listener.onDataChanged(this, 0);
+ m_listener.onDataChanged(this, EDCC_STORED_JOB);
}
*/
return 0;
@@ -1233,10 +1234,14 @@
return index;
}
- int CEquipment::onPreFetchedOutJob(int port, CJobDataB* pJobDataB)
+ BOOL CEquipment::onPreFetchedOutJob(int port, CJobDataB* pJobDataB)
{
LOGI("<CEquipment-%s>onPreFetchedOutJob:port:%d|GlassId:%s",
m_strName.c_str(), port, pJobDataB->getGlassId().c_str());
+ if (m_listener.onPreFethedOutJob != nullptr) {
+ return m_listener.onPreFethedOutJob(this, pJobDataB);
+ }
+
return TRUE;
}
diff --git a/SourceCode/Bond/Servo/CEquipment.h b/SourceCode/Bond/Servo/CEquipment.h
index b47ea75..fbd6ed7 100644
--- a/SourceCode/Bond/Servo/CEquipment.h
+++ b/SourceCode/Bond/Servo/CEquipment.h
@@ -44,6 +44,7 @@
typedef std::function<void(void* pEiuipment, int code)> ONDATACHANGED;
typedef std::function<void(void* pEiuipment, int state, int alarmId, int unitId, int level)> ONALARM;
typedef std::function<void(void* pEiuipment, void* pReport)> ONVCREVENTREPORT;
+ typedef std::function<BOOL(void* pEiuipment, CJobDataB* pJobDataB)> ONPREFETCHEDOUTJOB;
typedef struct _EquipmentListener
{
ONALIVE onAlive;
@@ -51,6 +52,7 @@
ONALARM onAlarm;
ONDATACHANGED onDataChanged;
ONVCREVENTREPORT onVcrEventReport;
+ ONPREFETCHEDOUTJOB onPreFethedOutJob;
} EquipmentListener;
diff --git a/SourceCode/Bond/Servo/CLoadPort.cpp b/SourceCode/Bond/Servo/CLoadPort.cpp
index 6df5ce3..6e689a9 100644
--- a/SourceCode/Bond/Servo/CLoadPort.cpp
+++ b/SourceCode/Bond/Servo/CLoadPort.cpp
@@ -1060,6 +1060,11 @@
*/
int CLoadPort::testGenerateGlassList(MaterialsType type, const char* pszPrefix, int startSuffix)
{
+ static unsigned short nJobSequenceNo = 0;
+ static unsigned short nCassetteSequenceNo = 0;
+ nCassetteSequenceNo++;
+
+
// 如果非空就不生成了
Lock();
if (hasGlass()) {
@@ -1079,7 +1084,11 @@
sprintf_s(szBuffer, "%s%d", pszPrefix, suffix++);
jb.setGlassId(szBuffer);
+ jb.setCassetteSequenceNo(nCassetteSequenceNo);
+ jb.setJobSequenceNo(++nJobSequenceNo);
js.setMaterialsType((int)type);
+ js.setCassetteSequenceNo(nCassetteSequenceNo);
+ js.setJobSequenceNo(nJobSequenceNo);
if (type == MaterialsType::G1) {
js.setGlass1Id(szBuffer);
}
diff --git a/SourceCode/Bond/Servo/CMaster.cpp b/SourceCode/Bond/Servo/CMaster.cpp
index 3bd5d26..e05c2f7 100644
--- a/SourceCode/Bond/Servo/CMaster.cpp
+++ b/SourceCode/Bond/Servo/CMaster.cpp
@@ -228,6 +228,12 @@
}
saveCache();
+ lock();
+ if (m_pActiveRobotTask != nullptr) {
+ delete m_pActiveRobotTask;
+ m_pActiveRobotTask = nullptr;
+ }
+ unlock();
for (auto item : m_listEquipment) {
delete item;
@@ -310,13 +316,60 @@
else if (m_state == MASTERSTATE::RUNNING) {
unlock();
LOGI("调度处理中...");
- Sleep(1000);
+ lock();
+ if (m_pActiveRobotTask != nullptr) {
+ unlock();
+ // 检测到当前有正在下午的任务,确保当前任务完成或中止后继续
+ LOGI("检测到当前有正在下午的任务,确保当前任务完成或中止后继续...");
+ continue;
+ }
// LoadPort -> Fliper(G2)
+ 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);
+ ASSERT(pLoadPort1);
+ ASSERT(pLoadPort2);
+ ASSERT(pFliper);
+ ASSERT(pVacuumBack);
+
+ m_pActiveRobotTask = createTransferTask(pLoadPort1, pFliper);
+ if (m_pActiveRobotTask != nullptr) {
+ std::string strDescription = m_pActiveRobotTask->getDescription();
+ unlock();
+ LOGI("创建新任务<%s>...", strDescription.c_str());
+ continue;
+ }
+
+ m_pActiveRobotTask = createTransferTask(pLoadPort2, pFliper);
+ if (m_pActiveRobotTask != nullptr) {
+ std::string strDescription = m_pActiveRobotTask->getDescription();
+ unlock();
+ 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();
+ LOGI("创建新任务1<%s>...", strDescription.c_str());
+ continue;
+ }
+
+ m_pActiveRobotTask = createTransferTask(pLoadPort2, pVacuumBack);
+ if (m_pActiveRobotTask != nullptr) {
+ std::string strDescription = m_pActiveRobotTask->getDescription();
+ unlock();
+ LOGI("创建新任务2<%s>...", strDescription.c_str());
+ continue;
+ }
+
// Fliper(G2) -> Aligner
@@ -338,7 +391,7 @@
-
+ unlock();
}
unlock();
@@ -412,11 +465,57 @@
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 && 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("<CMaster>onPreFethedOutJob, 已校验数据一致性.");
+ }
+ }
+ }
+ unlock();
+
+ if (!bOk) {
+ LOGE("<CMaster>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();
+ LOGI("放片完成...");
+ }
+ unlock();
}
};
@@ -828,4 +927,28 @@
m_listener.onMasterStateChanged(this, m_state);
}
}
+
+ static int taskSeqNo = 0;
+ CRobotTask* CMaster::createTransferTask(CEquipment* pSrcEq, CEquipment* pTarEq)
+ {
+ CRobotTask* pTask = nullptr;
+ CSlot* pSrcSlot, * pTarSlot;
+ pTarSlot = pTarEq->getAvailableSlotForGlass(MaterialsType::G1);
+ pSrcSlot = pSrcEq->getNonEmptySlot(MaterialsType::G1);
+ if (pSrcSlot == nullptr || nullptr == pTarSlot) {
+ pTarSlot = pTarEq->getAvailableSlotForGlass(MaterialsType::G2);
+ pSrcSlot = pSrcEq->getNonEmptySlot(MaterialsType::G2);
+ }
+
+
+ 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;
+ }
}
diff --git a/SourceCode/Bond/Servo/CMaster.h b/SourceCode/Bond/Servo/CMaster.h
index 2a2b9c0..93ff6cc 100644
--- a/SourceCode/Bond/Servo/CMaster.h
+++ b/SourceCode/Bond/Servo/CMaster.h
@@ -82,6 +82,7 @@
int readCache();
void serialize(CArchive& ar);
void setState(MASTERSTATE state);
+ CRobotTask* createTransferTask(CEquipment* pSrcEq, CEquipment* pTarEq);
private:
CRITICAL_SECTION m_criticalSection;
diff --git a/SourceCode/Bond/Servo/CPageGraph2.cpp b/SourceCode/Bond/Servo/CPageGraph2.cpp
index 1b4c9ae..6f06274 100644
--- a/SourceCode/Bond/Servo/CPageGraph2.cpp
+++ b/SourceCode/Bond/Servo/CPageGraph2.cpp
@@ -204,26 +204,31 @@
// 娴嬭瘯
else if (nCmd == ID_EQSGRAPHITEM_TEST1) {
+ BOOL bTestGenerate = FALSE;
SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData;
- if (pEquipment->getID() == EQ_ID_LOADPORT1) {
+ if (pEquipment->getID() == EQ_ID_LOADPORT1 && !pEquipment->hasGlass()) {
((SERVO::CLoadPort*)pEquipment)->testGenerateGlassList(SERVO::MaterialsType::G1,
"P20250320G1X", 1);
+ bTestGenerate = TRUE;
}
- else if (pEquipment->getID() == EQ_ID_LOADPORT2) {
+ else if (pEquipment->getID() == EQ_ID_LOADPORT2 && !pEquipment->hasGlass()) {
((SERVO::CLoadPort*)pEquipment)->testGenerateGlassList(SERVO::MaterialsType::G2,
"P20250320G2X", 1);
+ bTestGenerate = TRUE;
}
- /*
- SERVO::CGlass* pGlass = pEquipment->getAnyGlass();
- if (pGlass != nullptr) {
- SERVO::CJobDataB* pJobDataB = pGlass->getJobDataB();
- SERVO::CJobDataS* pJobDataS = pGlass->getJobDataS();
- if (pJobDataB != nullptr && pJobDataS != nullptr) {
- pEquipment->fetchedOutJob(pJobDataB);
- pEquipment->onSentOutJob(0, pJobDataS);
+
+ if (!bTestGenerate) {
+ SERVO::CRobotTask* pTask = theApp.m_model.getMaster().getActiveRobotTask();
+ if (pTask != nullptr) {
+ SERVO::CGlass* pGlass = (SERVO::CGlass*)pTask->getContext();
+ SERVO::CJobDataB* pJobDataB = pGlass->getJobDataB();
+ SERVO::CJobDataS* pJobDataS = pGlass->getJobDataS();
+ if (pJobDataB != nullptr && pJobDataS != nullptr) {
+ pEquipment->onFetchedOutJob(0, pJobDataB);
+ pEquipment->onSentOutJob(0, pJobDataS);
+ }
}
}
- */
}
else if (nCmd == ID_EQSGRAPHITEM_TEST2) {
SERVO::CEquipment* pEquipment = (SERVO::CEquipment*)pItem->pData;
diff --git a/SourceCode/Bond/Servo/CRobotTask.cpp b/SourceCode/Bond/Servo/CRobotTask.cpp
index 26017c7..17113b4 100644
--- a/SourceCode/Bond/Servo/CRobotTask.cpp
+++ b/SourceCode/Bond/Servo/CRobotTask.cpp
@@ -7,12 +7,56 @@
CRobotTask::CRobotTask()
{
generateId(m_strId);
+ m_state = ROBOT_TASK_STATE::Ready;
m_timeCreate = CToolUnits::getTimestamp();
+ m_timeFetchOut = 0;
+ m_timeStored = 0;
+ m_timeFinish = 0;
+ m_pContext = nullptr;
}
CRobotTask::~CRobotTask()
{
+ if (m_pContext != nullptr) {
+ m_pContext->release();
+ m_pContext = nullptr;
+ }
+ }
+ std::string CRobotTask::getDescription() const
+ {
+ std::string strOut = "CRobotTask<ID:";
+ strOut = strOut + std::to_string(m_robotCmdParam.sequenceNo);
+ strOut = strOut + ",Arm:";
+ strOut = strOut + std::to_string(m_robotCmdParam.armNo);
+ strOut = strOut + ",GetPossion:";
+ strOut = strOut + std::to_string(m_robotCmdParam.getPosition);
+ strOut = strOut + ",GetSlot:";
+ strOut = strOut + std::to_string(m_robotCmdParam.getSlotNo);
+ strOut = strOut + ",PutPossion:";
+ strOut = strOut + std::to_string(m_robotCmdParam.putPosition);
+ strOut = strOut + ",PutSlot:";
+ strOut = strOut + std::to_string(m_robotCmdParam.putSlotNo);
+ strOut = strOut + ">";
+
+ return strOut;
+ }
+
+ void CRobotTask::setContext(CContext* pContext)
+ {
+ if (pContext != nullptr) {
+ pContext->release();
+ }
+
+ m_pContext = pContext;
+ if (m_pContext != nullptr) {
+ m_pContext->addRef();
+ }
+ }
+
+ CContext* CRobotTask::getContext()
+ {
+ return m_pContext;
}
std::string& CRobotTask::generateId(std::string& out)
@@ -56,8 +100,53 @@
return m_timeCreate;
}
+ time_t CRobotTask::getFetchoutTime()
+ {
+ return m_timeFetchOut;
+ }
+
+ time_t CRobotTask::getStoredTime()
+ {
+ return m_timeStored;
+ }
+
time_t CRobotTask::getFinishTime()
{
return m_timeFinish;
}
+
+ ROBOT_TASK_STATE CRobotTask::getState()
+ {
+ return m_state;
+ }
+
+ int CRobotTask::getSrcPosition()
+ {
+ return m_robotCmdParam.getPosition;
+ }
+
+ int CRobotTask::getTarPosition()
+ {
+ return m_robotCmdParam.putPosition;
+ }
+
+ int CRobotTask::getSrcSlot()
+ {
+ return m_robotCmdParam.getSlotNo;
+ }
+
+ int CRobotTask::getTarSlot()
+ {
+ return m_robotCmdParam.putSlotNo;
+ }
+
+ void CRobotTask::fetchOut()
+ {
+ m_timeFetchOut = CToolUnits::getTimestamp();;
+ }
+
+ void CRobotTask::stored()
+ {
+ m_timeStored = CToolUnits::getTimestamp();;
+ }
}
diff --git a/SourceCode/Bond/Servo/CRobotTask.h b/SourceCode/Bond/Servo/CRobotTask.h
index 54e847b..0fa435f 100644
--- a/SourceCode/Bond/Servo/CRobotTask.h
+++ b/SourceCode/Bond/Servo/CRobotTask.h
@@ -1,5 +1,6 @@
#pragma once
#include "ServoCommo.h"
+#include "Context.h"
namespace SERVO {
@@ -11,18 +12,38 @@
public:
std::string& getId();
+ std::string getDescription() const;
+ void setContext(CContext* pContext);
+ CContext* getContext();
void setRobotTransferParam(int seq, int armNo, int fromPos, int toPos, int fromSlot, int toSlot);
ROBOT_CMD_PARAM& getRobotCmdParam();
time_t getCreateTime();
+ time_t getFetchoutTime();
+ time_t getStoredTime();
time_t getFinishTime();
+ ROBOT_TASK_STATE getState();
+ int getSrcPosition();
+ int getSrcSlot();
+ int getTarPosition();
+ int getTarSlot();
+
+ // 从源地拔片
+ void fetchOut();
+
+ // 在目的地放片
+ void stored();
private:
static std::string& generateId(std::string& out);
- public:
+ private:
+ ROBOT_TASK_STATE m_state; /* 任务状态 */
std::string m_strId;
time_t m_timeCreate; /* 创建时间 */
+ time_t m_timeFetchOut; /* 取片时间*/
+ time_t m_timeStored; /* 放片时间 */
time_t m_timeFinish; /* 结束时间 */
ROBOT_CMD_PARAM m_robotCmdParam; /* 参数 */
+ CContext* m_pContext;
};
}
diff --git a/SourceCode/Bond/Servo/CSlot.cpp b/SourceCode/Bond/Servo/CSlot.cpp
index ed297f2..8972986 100644
--- a/SourceCode/Bond/Servo/CSlot.cpp
+++ b/SourceCode/Bond/Servo/CSlot.cpp
@@ -10,11 +10,15 @@
m_pContext = nullptr;
m_bEnable = FALSE;
m_bLock = FALSE;
+ m_pContext = nullptr;
}
CSlot::~CSlot()
{
-
+ if (m_pContext != nullptr) {
+ m_pContext->release();
+ m_pContext = nullptr;
+ }
}
BOOL CSlot::isEnable()
@@ -92,14 +96,21 @@
return m_pContext == nullptr;
}
+ void CSlot::setContext(CContext* pContext)
+ {
+ if (pContext != nullptr) {
+ pContext->release();
+ }
+
+ m_pContext = pContext;
+ if (m_pContext != nullptr) {
+ m_pContext->addRef();
+ }
+ }
+
CContext* CSlot::getContext()
{
return m_pContext;
- }
-
- void CSlot::setContext(CContext* pContext)
- {
- m_pContext = pContext;
}
void CSlot::serialize(CArchive& ar)
diff --git a/SourceCode/Bond/Servo/ServoCommo.h b/SourceCode/Bond/Servo/ServoCommo.h
index 2444aca..acfd20a 100644
--- a/SourceCode/Bond/Servo/ServoCommo.h
+++ b/SourceCode/Bond/Servo/ServoCommo.h
@@ -112,5 +112,9 @@
Abort,
Completed
};
+
+ /* EQ Data changed code */
+#define EDCC_FETCHOUT_JOB 1000 /* 取片 */
+#define EDCC_STORED_JOB 1001 /* 放片 */
}
--
Gitblit v1.9.3