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