From 58edd8b23ce7d804c1e88eecde6fb42830034946 Mon Sep 17 00:00:00 2001
From: LAPTOP-SNT8I5JK\Boounion <Chenluhua@qq.com>
Date: 星期五, 01 八月 2025 16:35:15 +0800
Subject: [PATCH] 1.千传模式,待测;

---
 SourceCode/Bond/x64/Debug/Res/RunCt_Gray_32.ico        |    0 
 SourceCode/Bond/Servo/resource.h                       |    0 
 SourceCode/Bond/Servo/TopToolbar.h                     |    1 
 SourceCode/Bond/Servo/CEquipment.cpp                   |   31 ++++++
 SourceCode/Bond/Servo/Servo.rc                         |    0 
 SourceCode/Bond/Servo/TopToolbar.cpp                   |    8 +
 SourceCode/Bond/Servo/CMaster.cpp                      |  174 ++++++++++++++++++++++++++++++++++
 SourceCode/Bond/Servo/CMaster.h                        |    5 +
 SourceCode/Bond/Servo/CEquipment.h                     |    2 
 SourceCode/Bond/Servo/ServoDlg.cpp                     |   20 +++
 SourceCode/Bond/x64/Debug/Res/RunCt_High_32.ico        |    0 
 Document/Panel Bonder八零联合 SecsTest CheckList_v3.0.xlsx |    0 
 12 files changed, 238 insertions(+), 3 deletions(-)

diff --git "a/Document/Panel Bonder\345\205\253\351\233\266\350\201\224\345\220\210 SecsTest CheckList_v3.0.xlsx" "b/Document/Panel Bonder\345\205\253\351\233\266\350\201\224\345\220\210 SecsTest CheckList_v3.0.xlsx"
index 6b16c1a..48e2a37 100644
--- "a/Document/Panel Bonder\345\205\253\351\233\266\350\201\224\345\220\210 SecsTest CheckList_v3.0.xlsx"
+++ "b/Document/Panel Bonder\345\205\253\351\233\266\350\201\224\345\220\210 SecsTest CheckList_v3.0.xlsx"
Binary files differ
diff --git a/SourceCode/Bond/Servo/CEquipment.cpp b/SourceCode/Bond/Servo/CEquipment.cpp
index 0d99db6..322923d 100644
--- a/SourceCode/Bond/Servo/CEquipment.cpp
+++ b/SourceCode/Bond/Servo/CEquipment.cpp
@@ -1292,6 +1292,21 @@
 		return nullptr;
 	}
 
+	CSlot* CEquipment::isSlotAvailable(unsigned int slot)
+	{
+		if (slot >= 8) return nullptr;
+		if (!m_slot[slot].isEnable()) return nullptr;
+		if (m_slot[slot].isLock()) return nullptr;
+		if (!m_slot[slot].isEmpty()) return nullptr;
+		int lsPath = m_slot[slot].getLinkSignalPath();
+		if (!m_bLinkSignalToDownstream[lsPath][SIGNAL_UPSTREAM_INLINE]
+			|| m_bLinkSignalToDownstream[lsPath][SIGNAL_UPSTREAM_TROUBLE]
+			|| !m_bLinkSignalToDownstream[lsPath][SIGNAL_INTERLOCK]
+			|| !m_bLinkSignalToDownstream[lsPath][SIGNAL_RECEIVE_ABLE]) return nullptr;
+
+		return &m_slot[slot];
+	}
+
 	CSlot* CEquipment::getNonEmptySlot(MaterialsType putSlotType)
 	{
 		for (int i = 0; i < SLOT_MAX; i++) {
@@ -1364,6 +1379,22 @@
 		return nullptr;
 	}
 
+	CSlot* CEquipment::getProcessedSlotCt(unsigned int slot)
+	{
+		if (slot >= 8) return nullptr;
+		if (!m_slot[slot].isEnable()) return nullptr;
+		if (m_slot[slot].isLock()) return nullptr;
+		CGlass* pGlass = (CGlass*)m_slot[slot].getContext();
+		if (pGlass == nullptr) return nullptr;
+		int lsPath = m_slot[slot].getLinkSignalPath();
+		if (!m_bLinkSignalToUpstream[lsPath][SIGNAL_UPSTREAM_INLINE]
+			|| m_bLinkSignalToUpstream[lsPath][SIGNAL_UPSTREAM_TROUBLE]
+			|| !m_bLinkSignalToUpstream[lsPath][SIGNAL_INTERLOCK]
+			|| !m_bLinkSignalToUpstream[lsPath][SIGNAL_SEND_ABLE]) return nullptr;
+		
+		return &m_slot[slot];
+	}
+
 	CSlot* CEquipment::getInspFailSlot()
 	{
 		for (int i = 0; i < SLOT_MAX; i++) {
diff --git a/SourceCode/Bond/Servo/CEquipment.h b/SourceCode/Bond/Servo/CEquipment.h
index 28bf252..ce75a56 100644
--- a/SourceCode/Bond/Servo/CEquipment.h
+++ b/SourceCode/Bond/Servo/CEquipment.h
@@ -176,6 +176,7 @@
 		// 获取一个指定物料类型(G1,G2,G1&G2)的空槽位
 		CSlot* getAvailableSlotForGlass(MaterialsType type);
 		CSlot* getAvailableSlotForGlassExcludeSignal(MaterialsType type);
+		CSlot* isSlotAvailable(unsigned int slot);
 
 		// 在指定的槽列表中,获取一个指定物料类型(G1,G2,G1&G2)的空槽位
 		CSlot* getAvailableSlotForGlass2(MaterialsType type, const std::vector<int>& candidates);
@@ -187,6 +188,7 @@
 		CSlot* getProcessedSlot(MaterialsType putSlotType);
 		CSlot* getProcessedSlot2(MaterialsType putSlotType, const std::vector<int>& candidates);
 		CSlot* getInspFailSlot();
+		CSlot* getProcessedSlotCt(unsigned int slot);
 
 		// 获取玻璃物料
 		CGlass* getGlassFromSlot(int slotNo);
diff --git a/SourceCode/Bond/Servo/CMaster.cpp b/SourceCode/Bond/Servo/CMaster.cpp
index 6bcda0c..6714999 100644
--- a/SourceCode/Bond/Servo/CMaster.cpp
+++ b/SourceCode/Bond/Servo/CMaster.cpp
@@ -54,6 +54,7 @@
 		m_isCompareMapsBeforeProceeding = FALSE;
 		m_bEnableEventReport = true;
 		m_bEnableAlarmReport = true;
+		m_bContinuousTransfer = false;
 		InitializeCriticalSection(&m_criticalSection);
 	}
 
@@ -251,6 +252,20 @@
 			return -1;
 		}
 
+		m_bContinuousTransfer = false;
+		setState(MASTERSTATE::STARTING);
+		m_ullStartTime = GetTickCount64();
+
+		return 0;
+	}
+
+	int CMaster::startContinuousTransfer()
+	{
+		if (m_state != MASTERSTATE::READY) {
+			return -1;
+		}
+
+		m_bContinuousTransfer = true;
 		setState(MASTERSTATE::STARTING);
 		m_ullStartTime = GetTickCount64();
 
@@ -260,7 +275,7 @@
 	int CMaster::stop()
 	{
 		// 运行时间为累加结果,本次停止时刷新;
-		if (m_state != MASTERSTATE::RUNNING) {
+		if (m_state != MASTERSTATE::RUNNING && m_state != MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER) {
 			return -1;
 		}
 
@@ -447,7 +462,11 @@
 
 
 				unlock();
-				setState(MASTERSTATE::RUNNING);
+				if(!m_bContinuousTransfer)
+					setState(MASTERSTATE::RUNNING);
+				else 
+					setState(MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER);
+
 				continue;
 			}
 
@@ -664,6 +683,132 @@
 				unlock();
 				continue;
 			}
+
+			// 千传模式调度逻辑
+			else if (m_state == MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER) {
+				// 检测判断robot状态
+				RMDATA& rmd = pEFEM->getRobotMonitoringData();
+				if (rmd.status != ROBOT_STATUS::Idle && rmd.status != ROBOT_STATUS::Run) {
+					unlock();
+					continue;
+				}
+
+				if (m_pActiveRobotTask != nullptr) {
+					if (m_pActiveRobotTask->isPicked()) {
+						m_pActiveRobotTask->place();
+					}
+					unlock();
+					// 检测到当前有正在下午的任务,确保当前任务完成或中止后继续
+					// LOGI("检测到当前有正在下午的任务,确保当前任务完成或中止后继续...");
+					continue;
+				}
+
+				// 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) {
+						for (int slot = 0; slot < SLOT_MAX; slot++) {
+							m_pActiveRobotTask = createTransferTask_continuous_transfer(pMeasurement,
+								0, pLoadPorts[s], slot);
+							if (m_pActiveRobotTask != nullptr) {
+								goto CT_PORT_PUT;
+							}
+						}
+					}
+				}
+
+			CT_PORT_PUT:
+				CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
+
+
+				// BakeCooling ->Measurement
+				if (!rmd.armState[0]) {
+					m_pActiveRobotTask = createTransferTask_continuous_transfer(pBakeCooling,
+						3, pMeasurement, 0);
+					CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
+				}
+
+				
+				// BakeCooling内部
+				if (!rmd.armState[0]) {
+					m_pActiveRobotTask = createTransferTask_continuous_transfer(pBakeCooling,
+						2, pBakeCooling, 3);
+					CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
+				}
+				if (!rmd.armState[0]) {
+					m_pActiveRobotTask = createTransferTask_continuous_transfer(pBakeCooling,
+						1, pBakeCooling, 2);
+					CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
+				}
+				if (!rmd.armState[0]) {
+					m_pActiveRobotTask = createTransferTask_continuous_transfer(pBakeCooling,
+						0, pBakeCooling, 1);
+					CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
+				}
+
+				// Bonder2 -> BakeCooling
+				if (!rmd.armState[0]) {
+					m_pActiveRobotTask = createTransferTask_continuous_transfer(pBonder2,
+						0, pBakeCooling, 0);
+					CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
+				}
+
+				// Bonder1 -> Bonder2
+				if (!rmd.armState[0] && !pBonder2->hasBondClass()) {
+					m_pActiveRobotTask = createTransferTask_continuous_transfer(pBonder1,
+						0, pBonder2, 0);
+					CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
+				}
+
+				// VacuumBake(G1) -> Bonder1
+				if (!rmd.armState[0] && !pBonder1->hasBondClass()) {
+					m_pActiveRobotTask = createTransferTask_continuous_transfer(pVacuumBake,
+						0, pBonder1, 0);
+					CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
+				}
+
+				// Fliper(G2) -> VacuumBake(G1)
+				if (!rmd.armState[0]) {
+					m_pActiveRobotTask = createTransferTask_continuous_transfer(pFliper,
+						0, pVacuumBake, 0);
+					CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
+				}
+
+				// Aligner -> Fliper(G2)
+				if (!rmd.armState[1]) {
+					m_pActiveRobotTask = createTransferTask_continuous_transfer(pAligner,
+						0, pFliper, 0);
+					CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
+				}
+
+				// LoadPort -> Aligner
+				for (int s = 0; s < 4; s++) {
+					PortType pt = pLoadPorts[s]->getPortType();
+					if (!rmd.armState[0] && pLoadPorts[s]->isEnable()
+						&& (pt == PortType::Loading || pt == PortType::Both)
+						&& pLoadPorts[s]->getPortStatus() == PORT_INUSE) {
+						for (int slot = 0; slot < SLOT_MAX; slot++) {
+							m_pActiveRobotTask = createTransferTask_continuous_transfer(pLoadPorts[s], 
+								slot, pAligner, 0);
+							if (m_pActiveRobotTask != nullptr) {
+								pEFEM->setContext(m_pActiveRobotTask->getContext());
+								goto CT_PORT_GET;
+							}
+						}
+					}
+				}
+
+			CT_PORT_GET:
+				CHECK_RUN_ACTIVE_ROBOT_TASK(m_pActiveRobotTask);
+
+
+				unlock();
+				continue;
+			}
+
+
 			unlock();
 		}
 
@@ -1426,6 +1571,31 @@
 		return pTask;
 	}
 
+	CRobotTask* CMaster::createTransferTask_continuous_transfer(CEquipment* pSrcEq, int nSrcSlot,
+		CEquipment* pTarEq, int nTarSlot, int armNo/* = 1*/)
+	{
+		if (!pSrcEq->IsEnabled()) {
+			return nullptr;
+		}
+		if (!pTarEq->IsEnabled()) {
+			return nullptr;
+		}
+
+		CRobotTask* pTask = nullptr;
+		CSlot* pTarSlot = pTarEq->isSlotAvailable(nTarSlot);
+		CSlot* pSrcSlot = pSrcEq->getProcessedSlotCt(nSrcSlot);
+		if (pSrcSlot != nullptr && nullptr != pTarSlot) {
+			pTask = new CRobotTask();
+			pTask->setContext(pSrcSlot->getContext());
+			pTask->setEFEM((CEFEM*)getEquipment(EQ_ID_EFEM));
+			taskSeqNo = pTask->setRobotTransferParam(taskSeqNo, armNo, pSrcSlot->getPosition(),
+				pTarSlot->getPosition(), pSrcSlot->getNo(), pTarSlot->getNo());
+		}
+
+
+		return pTask;
+	}
+
 	int CMaster::abortCurrentTask()
 	{
 		lock();
diff --git a/SourceCode/Bond/Servo/CMaster.h b/SourceCode/Bond/Servo/CMaster.h
index 76d52eb..7b16db8 100644
--- a/SourceCode/Bond/Servo/CMaster.h
+++ b/SourceCode/Bond/Servo/CMaster.h
@@ -20,6 +20,7 @@
         READY = 0,
         STARTING,
         RUNNING,
+        RUNNING_CONTINUOUS_TRANSFER,
         STOPPING,
         MSERROR
     };
@@ -57,6 +58,7 @@
         int init();
         int term();
         int start();
+        int startContinuousTransfer();
         int stop();
         void clearError();
         ULONGLONG getRunTime();
@@ -107,6 +109,8 @@
         CRobotTask* createTransferTask_bake_to_cooling(CEquipment* pSrcEq);
         CRobotTask* createTransferTask_bakecooling_to_measurement(CEquipment* pSrcEq, CEquipment* pTarEq);
         CRobotTask* createTransferTask_restore(CEquipment* pEqSrc, CLoadPort** pPorts);
+        CRobotTask* createTransferTask_continuous_transfer(CEquipment* pSrcEq, int nSrcSlot,
+            CEquipment* pTarEq, int nTarSlot, int armNo = 1);
 
     private:
         CRITICAL_SECTION m_criticalSection;
@@ -115,6 +119,7 @@
         std::list<CEquipment*> m_listEquipment;
         std::string m_strFilepath;
         BOOL m_bDataModify;
+        bool m_bContinuousTransfer;
 
     private:
         /* 监控比特位的线程*/
diff --git a/SourceCode/Bond/Servo/Servo.rc b/SourceCode/Bond/Servo/Servo.rc
index 04cab1e..552795b 100644
--- a/SourceCode/Bond/Servo/Servo.rc
+++ b/SourceCode/Bond/Servo/Servo.rc
Binary files differ
diff --git a/SourceCode/Bond/Servo/ServoDlg.cpp b/SourceCode/Bond/Servo/ServoDlg.cpp
index 457a1fe..84b1f21 100644
--- a/SourceCode/Bond/Servo/ServoDlg.cpp
+++ b/SourceCode/Bond/Servo/ServoDlg.cpp
@@ -189,6 +189,7 @@
 				SERVO::MASTERSTATE state = theApp.m_model.getMaster().getState();
 				if (state == SERVO::MASTERSTATE::READY) {
 					m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(TRUE);
+					m_pTopToolbar->GetBtn(IDC_BUTTON_RUN_CT)->EnableWindow(TRUE);
 					m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(FALSE);
 					m_pMyStatusbar->setBackgroundColor(STATUSBAR_BK_NORMAL);
 					m_pMyStatusbar->setForegroundColor(RGB(0, 0, 0));
@@ -204,13 +205,15 @@
 				}
 				else if (state == SERVO::MASTERSTATE::MSERROR) {
 					m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(TRUE);
+					m_pTopToolbar->GetBtn(IDC_BUTTON_RUN_CT)->EnableWindow(TRUE);
 					m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(FALSE);
 					m_pMyStatusbar->setBackgroundColor(STATUSBAR_BK_ALARM);
 					m_pMyStatusbar->setForegroundColor(RGB(0, 0, 0));
 					m_pMyStatusbar->setRunTimeText("启动失败.");
 				}
-				else if (state == SERVO::MASTERSTATE::RUNNING) {
+				else if (state == SERVO::MASTERSTATE::RUNNING || state == SERVO::MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER) {
 					m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(FALSE);
+					m_pTopToolbar->GetBtn(IDC_BUTTON_RUN_CT)->EnableWindow(FALSE);
 					m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(TRUE);
 					m_pMyStatusbar->setBackgroundColor(STATUSBAR_BK_RUNNING);
 					m_pMyStatusbar->setForegroundColor(RGB(255, 255, 255));
@@ -937,6 +940,18 @@
 		else {
 			if (theApp.m_model.getMaster().start() == 0) {
 				m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(FALSE);
+				m_pTopToolbar->GetBtn(IDC_BUTTON_RUN_CT)->EnableWindow(FALSE);
+			}
+		}
+	}
+	else if (id == IDC_BUTTON_RUN_CT) {
+		if (theApp.m_model.getMaster().getState() == SERVO::MASTERSTATE::MSERROR) {
+			AfxMessageBox("当前有机台发生错误,不能启动,请确认解决问题后再尝试重新启动!");
+		}
+		else {
+			if (theApp.m_model.getMaster().startContinuousTransfer() == 0) {
+				m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(FALSE);
+				m_pTopToolbar->GetBtn(IDC_BUTTON_RUN_CT)->EnableWindow(FALSE);
 			}
 		}
 	}
@@ -1057,6 +1072,9 @@
 	if (state == SERVO::MASTERSTATE::RUNNING) {
 		strText.Format(_T("正在运行:%02d:%02d:%02d   %s"), h, m, s, pszSuffix);
 	}
+	else if (state == SERVO::MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER) {
+		strText.Format(_T("千传模式:%02d:%02d:%02d   %s"), h, m, s, pszSuffix);
+	}
 	else {
 		strText.Format(_T("已运行:%02d:%02d:%02d   %s"), h, m, s, pszSuffix);
 	}
diff --git a/SourceCode/Bond/Servo/TopToolbar.cpp b/SourceCode/Bond/Servo/TopToolbar.cpp
index a601129..0208ece 100644
--- a/SourceCode/Bond/Servo/TopToolbar.cpp
+++ b/SourceCode/Bond/Servo/TopToolbar.cpp
@@ -27,6 +27,7 @@
 {
 	CDialogEx::DoDataExchange(pDX);
 	DDX_Control(pDX, IDC_BUTTON_RUN, m_btnRun);
+	DDX_Control(pDX, IDC_BUTTON_RUN_CT, m_btnRunCt);
 	DDX_Control(pDX, IDC_BUTTON_STOP, m_btnStop);
 	DDX_Control(pDX, IDC_BUTTON_ALARM, m_btnAlarm);
 	DDX_Control(pDX, IDC_BUTTON_SETTINGS, m_btnSettings);
@@ -52,6 +53,7 @@
 	CDialogEx::OnInitDialog();
 
 	InitBtn(m_btnRun, "Run_High_32.ico", "Run_Gray_32.ico");
+	InitBtn(m_btnRunCt, "RunCt_High_32.ico", "RunCt_Gray_32.ico");
 	InitBtn(m_btnStop, "Stop_High_32.ico", "Stop_Gray_32.ico");
 	InitBtn(m_btnAlarm, "Alarm_o_32.ico", "Alarm_gray_32.ico");
 	InitBtn(m_btnSettings, "Settings_High_32.ico", "Settings_Gray_32.ico");
@@ -112,6 +114,11 @@
 	int x = 2, y = 3;
 
 	pItem = GetDlgItem(IDC_BUTTON_RUN);
+	pItem->MoveWindow(x, y, BTN_WIDTH, nBthHeight);
+	x += BTN_WIDTH;
+	x += 2;
+
+	pItem = GetDlgItem(IDC_BUTTON_RUN_CT);
 	pItem->MoveWindow(x, y, BTN_WIDTH, nBthHeight);
 	x += BTN_WIDTH;
 	x += 2;
@@ -190,6 +197,7 @@
 {
 	switch (LOWORD(wParam)) {
 	case IDC_BUTTON_RUN:
+	case IDC_BUTTON_RUN_CT:
 	case IDC_BUTTON_STOP:
 	case IDC_BUTTON_ALARM:
 	case IDC_BUTTON_SETTINGS:
diff --git a/SourceCode/Bond/Servo/TopToolbar.h b/SourceCode/Bond/Servo/TopToolbar.h
index e4e0408..6400443 100644
--- a/SourceCode/Bond/Servo/TopToolbar.h
+++ b/SourceCode/Bond/Servo/TopToolbar.h
@@ -31,6 +31,7 @@
 
 private:
 	CBlButton m_btnRun;
+	CBlButton m_btnRunCt;
 	CBlButton m_btnStop;
 	CBlButton m_btnAlarm;
 	CBlButton m_btnSettings;
diff --git a/SourceCode/Bond/Servo/resource.h b/SourceCode/Bond/Servo/resource.h
index 3a430cc..3658421 100644
--- a/SourceCode/Bond/Servo/resource.h
+++ b/SourceCode/Bond/Servo/resource.h
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/RunCt_Gray_32.ico b/SourceCode/Bond/x64/Debug/Res/RunCt_Gray_32.ico
new file mode 100644
index 0000000..bb7d956
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/RunCt_Gray_32.ico
Binary files differ
diff --git a/SourceCode/Bond/x64/Debug/Res/RunCt_High_32.ico b/SourceCode/Bond/x64/Debug/Res/RunCt_High_32.ico
new file mode 100644
index 0000000..ef3c3f9
--- /dev/null
+++ b/SourceCode/Bond/x64/Debug/Res/RunCt_High_32.ico
Binary files differ

--
Gitblit v1.9.3