From 3404823d074a08b8c0824b505db16168f7e66201 Mon Sep 17 00:00:00 2001
From: LAPTOP-SNT8I5JK\Boounion <Chenluhua@qq.com>
Date: 星期一, 09 六月 2025 09:49:10 +0800
Subject: [PATCH] Merge branch 'clh'

---
 SourceCode/Bond/Servo/CPageGraph2.cpp     |    6 +
 SourceCode/Bond/Servo/Context.cpp         |   27 +++++
 SourceCode/Bond/Servo/CRobotTask.cpp      |   31 ++++++
 SourceCode/Bond/Servo/CMaster.h           |    1 
 SourceCode/Bond/Servo/CLoadPort.cpp       |    1 
 SourceCode/Bond/Servo/ServoDlg.cpp        |    9 +
 SourceCode/Bond/Servo/CBakeCooling.cpp    |    4 
 SourceCode/Bond/Servo/CSlot.h             |    3 
 SourceCode/Bond/Servo/CRobotTask.h        |    4 
 SourceCode/Bond/Servo/CSlot.cpp           |   11 ++
 SourceCode/Bond/Servo/CEquipmentPage2.cpp |   64 +++++++-----
 SourceCode/Bond/Servo/CEquipment.cpp      |   40 ++++++-
 SourceCode/Bond/Servo/Servo.rc            |    0 
 SourceCode/Bond/Servo/CMaster.cpp         |   41 ++++++++
 SourceCode/Bond/Servo/CEquipment.h        |    5 +
 SourceCode/Bond/Servo/CEquipmentPage2.h   |    1 
 SourceCode/Bond/Servo/CRobotTaskDlg.cpp   |    8 +
 17 files changed, 211 insertions(+), 45 deletions(-)

diff --git a/SourceCode/Bond/Servo/CBakeCooling.cpp b/SourceCode/Bond/Servo/CBakeCooling.cpp
index cf4caf4..422a81e 100644
--- a/SourceCode/Bond/Servo/CBakeCooling.cpp
+++ b/SourceCode/Bond/Servo/CBakeCooling.cpp
@@ -45,18 +45,22 @@
 		m_slot[0].setPosition(m_nID);
 		m_slot[0].setNo(1);
 		m_slot[0].setName("Bake 1");
+		m_slot[0].setLinkSignalPath(0);
 		m_slot[1].enable();
 		m_slot[1].setPosition(m_nID);
 		m_slot[1].setNo(2);
 		m_slot[1].setName("Bake 2");
+		m_slot[1].setLinkSignalPath(0);
 		m_slot[2].enable();
 		m_slot[2].setPosition(m_nID);
 		m_slot[2].setNo(3);
 		m_slot[2].setName("Cooling 1");
+		m_slot[2].setLinkSignalPath(1);
 		m_slot[3].enable();
 		m_slot[3].setPosition(m_nID);
 		m_slot[3].setNo(4);
 		m_slot[3].setName("Cooling 2");
+		m_slot[3].setLinkSignalPath(1);
 	}
 
 	void CBakeCooling::onTimer(UINT nTimerid)
diff --git a/SourceCode/Bond/Servo/CEquipment.cpp b/SourceCode/Bond/Servo/CEquipment.cpp
index 0aa06b1..35c81b8 100644
--- a/SourceCode/Bond/Servo/CEquipment.cpp
+++ b/SourceCode/Bond/Servo/CEquipment.cpp
@@ -47,7 +47,6 @@
 		for (int i = 0; i < SLOT_MAX; i++) {
 			CContext* pContext = m_slot[i].getContext();
 			if (pContext != nullptr) {
-				pContext->release();
 				m_slot[i].setContext(nullptr);
 			}
 		}
@@ -1149,10 +1148,11 @@
 			if (m_slot[i].isLock()) continue;
 			CGlass* pGlass = (CGlass*)m_slot[i].getContext();
 			if (pGlass == nullptr) continue;
-			if(!m_bLinkSignal[0][SIGNAL_UPSTREAM_INLINE]
-				|| m_bLinkSignal[0][SIGNAL_UPSTREAM_TROUBLE]
-				|| !m_bLinkSignal[0][SIGNAL_INTERLOCK]
-				|| !m_bLinkSignal[0][SIGNAL_SEND_ABLE] ) continue;
+			int lsPath = m_slot[i].getLinkSignalPath();
+			if(!m_bLinkSignal[lsPath][SIGNAL_UPSTREAM_INLINE]
+				|| m_bLinkSignal[lsPath][SIGNAL_UPSTREAM_TROUBLE]
+				|| !m_bLinkSignal[lsPath][SIGNAL_INTERLOCK]
+				|| !m_bLinkSignal[lsPath][SIGNAL_SEND_ABLE] ) continue;
 
 			MaterialsType glassType = pGlass->getType();
 			if (glassType == MaterialsType::G1 && putSlotType == MaterialsType::G2) continue;
@@ -1173,10 +1173,11 @@
 					if (m_slot[i].isLock()) continue;
 					CGlass* pGlass = (CGlass*)m_slot[i].getContext();
 					if (pGlass == nullptr) continue;
-					if (!m_bLinkSignal[0][SIGNAL_UPSTREAM_INLINE]
-						|| m_bLinkSignal[0][SIGNAL_UPSTREAM_TROUBLE]
-						|| !m_bLinkSignal[0][SIGNAL_INTERLOCK]
-						|| !m_bLinkSignal[0][SIGNAL_SEND_ABLE]) continue;
+					int lsPath = m_slot[i].getLinkSignalPath();
+					if (!m_bLinkSignal[lsPath][SIGNAL_UPSTREAM_INLINE]
+						|| m_bLinkSignal[lsPath][SIGNAL_UPSTREAM_TROUBLE]
+						|| !m_bLinkSignal[lsPath][SIGNAL_INTERLOCK]
+						|| !m_bLinkSignal[lsPath][SIGNAL_SEND_ABLE]) continue;
 
 					MaterialsType glassType = pGlass->getType();
 					if (glassType == MaterialsType::G1 && putSlotType == MaterialsType::G2) continue;
@@ -1188,6 +1189,12 @@
 		}
 
 		return nullptr;
+	}
+
+	CSlot* CEquipment::getSlot(int index)
+	{
+		if (index >= SLOT_MAX) return nullptr;
+		return &m_slot[index];
 	}
 
 	CGlass* CEquipment::getGlassFromSlot(int slotNo)
@@ -1229,6 +1236,21 @@
 		return TRUE;
 	}
 
+	int CEquipment::removeGlass(int slotNo)
+	{
+		CSlot* pSlot = nullptr;
+		for (int i = 0; i < SLOT_MAX; i++) {
+			if (!m_slot[i].isEnable()) continue;
+			if (m_slot[i].getNo() != slotNo) continue;
+			pSlot = &m_slot[i];
+			break;
+		}
+
+		if (pSlot == nullptr) return -1;
+		pSlot->setContext(nullptr);
+		return 0;
+	}
+
 	short CEquipment::decodeRecipeListReport(const char* pszData, size_t size)
 	{
 		return m_recipesManager.decodeRecipeListReport(pszData, size);
diff --git a/SourceCode/Bond/Servo/CEquipment.h b/SourceCode/Bond/Servo/CEquipment.h
index ac4b84c..da67314 100644
--- a/SourceCode/Bond/Servo/CEquipment.h
+++ b/SourceCode/Bond/Servo/CEquipment.h
@@ -150,6 +150,9 @@
 		// unitNo: 0:local; Others:unit No
 		int recipeParameterRequest(short masterRecipeId, short localRecipeId, short unitNo);
 
+		// 获取指定的Slot
+		CSlot* getSlot(int index);
+
 		// 获取一个可用的槽位
 		CSlot* getAvailableSlot();
 
@@ -182,6 +185,8 @@
 		// 指定槽位是否可以放置玻璃
 		BOOL canPlaceGlassInSlot(const short slotIndex);
 
+		// 手动移除物料
+		int removeGlass(int slotNo);
 
 	// 以下为从CC-Link读取到的Bit标志位检测函数
 	public:
diff --git a/SourceCode/Bond/Servo/CEquipmentPage2.cpp b/SourceCode/Bond/Servo/CEquipmentPage2.cpp
index f566568..14b46ac 100644
--- a/SourceCode/Bond/Servo/CEquipmentPage2.cpp
+++ b/SourceCode/Bond/Servo/CEquipmentPage2.cpp
@@ -74,25 +74,15 @@
 	ListView_SetImageList(m_listCtrl.GetSafeHwnd(), imageList, LVSIL_SMALL);
 	m_listCtrl.InsertColumn(0, _T(""), LVCFMT_RIGHT, width[0]);
 	m_listCtrl.InsertColumn(1, _T("ID"), LVCFMT_LEFT, width[1]);
-	m_listCtrl.InsertColumn(2, _T("璐村悎"), LVCFMT_LEFT, width[2]);
-	m_listCtrl.InsertColumn(3, _T("鏃堕棿"), LVCFMT_LEFT, width[3]);
-	m_listCtrl.SetColumnWidth(3, LVSCW_AUTOSIZE_USEHEADER);
+	m_listCtrl.InsertColumn(2, _T("鍚嶇О"), LVCFMT_LEFT, width[2]);
+	m_listCtrl.InsertColumn(3, _T("Glass ID"), LVCFMT_LEFT, width[3]);
+	m_listCtrl.InsertColumn(4, _T("璐村悎Glass ID"), LVCFMT_LEFT, width[4]);
+	m_listCtrl.InsertColumn(5, _T("鏃堕棿"), LVCFMT_LEFT, width[5]);
+	m_listCtrl.SetColumnWidth(5, LVSCW_AUTOSIZE_USEHEADER);
 
 
 	ASSERT(m_pEquipment);
-	for (int i = 0; i < SLOT_MAX; i++) {
-		SERVO::CGlass* pGlass = m_pEquipment->getGlassFromSlot(i+1);
-		if (pGlass != nullptr) {
-			pGlass->addRef();
-			SERVO::CGlass* pBuddy = pGlass->getBuddy();
-			int index = m_listCtrl.InsertItem(m_listCtrl.GetItemCount(), _T(""));
-			m_listCtrl.SetItemData(index, (DWORD_PTR)pGlass);
-			m_listCtrl.SetItemText(index, 1, pGlass->getID().c_str());
-			if (pBuddy != nullptr) {
-				m_listCtrl.SetItemText(index, 2, pBuddy->getID().c_str());
-			}
-		}
-	}
+	UpdateSlots();
 
 	return TRUE;  // return TRUE unless you set the focus to a control
 				  // 寮傚父: OCX 灞炴�ч〉搴旇繑鍥� FALSE
@@ -122,11 +112,6 @@
 		strItem.Format(_T("Col_%d_Width"), i);
 		strTemp.Format(_T("%d"), rect.right - rect.left);
 		WritePrivateProfileString("EquipmentPage2ListCtrl", strItem, strTemp, strIniFile);
-	}
-
-	for (int i = 0; i < m_listCtrl.GetItemCount(); i++) {
-		SERVO::CGlass* pGlass = (SERVO::CGlass*)m_listCtrl.GetItemData(i);
-		pGlass->release();
 	}
 }
 
@@ -171,16 +156,37 @@
 
 void CEquipmentPage2::OnBnClickedButtonRemove()
 {
-	/*
 	int index = GetSelectedItemIndex();
 	if (index >= 0) {
-		SERVO::CGlass* pGlass = (SERVO::CGlass*)m_listCtrl.GetItemData(index);
-		ASSERT(m_pEquipment);
-		BOOL bRet = m_pEquipment->removeClass(pGlass);
-		if (bRet) {
-			pGlass->release();
-			m_listCtrl.DeleteItem(index);
+		SERVO::CSlot* pSlot = (SERVO::CSlot*)m_listCtrl.GetItemData(index);
+		ASSERT(pSlot);
+		int bRet = m_pEquipment->removeGlass(pSlot->getNo());
+		if (bRet == 0) {
+			UpdateSlots();
 		}
 	}
-	*/
 }
+
+void CEquipmentPage2::UpdateSlots()
+{
+	m_listCtrl.DeleteAllItems();
+	for (int i = 0; i < SLOT_MAX; i++) {
+		SERVO::CSlot* pSlot = m_pEquipment->getSlot(i);
+		if (pSlot != nullptr && pSlot->isEnable()) {
+			int index = m_listCtrl.InsertItem(m_listCtrl.GetItemCount(), _T(""));
+			m_listCtrl.SetItemData(index, (DWORD_PTR)pSlot);
+			m_listCtrl.SetItemText(index, 1, std::to_string(pSlot->getNo()).c_str());
+			m_listCtrl.SetItemText(index, 2, pSlot->getName().c_str());
+
+			SERVO::CGlass* pGlass = (SERVO::CGlass*)pSlot->getContext();
+			if (pGlass != nullptr) {
+				m_listCtrl.SetItemText(index, 3, pGlass->getID().c_str());
+				SERVO::CGlass* pBuddy = pGlass->getBuddy();
+				if (pBuddy != nullptr) {
+					m_listCtrl.SetItemText(index, 4, pBuddy->getID().c_str());
+				}
+			}
+		}
+	}
+}
+
diff --git a/SourceCode/Bond/Servo/CEquipmentPage2.h b/SourceCode/Bond/Servo/CEquipmentPage2.h
index 99a7596..c20331a 100644
--- a/SourceCode/Bond/Servo/CEquipmentPage2.h
+++ b/SourceCode/Bond/Servo/CEquipmentPage2.h
@@ -18,6 +18,7 @@
 
 private:
 	int GetSelectedItemIndex();
+	void UpdateSlots();
 
 private:
 	SERVO::CEquipment* m_pEquipment;
diff --git a/SourceCode/Bond/Servo/CLoadPort.cpp b/SourceCode/Bond/Servo/CLoadPort.cpp
index 895ca1e..7e73a0a 100644
--- a/SourceCode/Bond/Servo/CLoadPort.cpp
+++ b/SourceCode/Bond/Servo/CLoadPort.cpp
@@ -1103,7 +1103,6 @@
 			pGlass->setJobDataB(&jb);
 			pGlass->setType(type);
 			pGlass->setJobDataS(&js);
-			pGlass->addRef();
 			m_slot[i].setContext(pGlass);
 		}
 
diff --git a/SourceCode/Bond/Servo/CMaster.cpp b/SourceCode/Bond/Servo/CMaster.cpp
index bc2a884..6a7437a 100644
--- a/SourceCode/Bond/Servo/CMaster.cpp
+++ b/SourceCode/Bond/Servo/CMaster.cpp
@@ -287,6 +287,7 @@
 
 
 		// 各种机器
+		CEFEM* pEFEM = (CEFEM*)getEquipment(EQ_ID_EFEM);
 		CLoadPort* pLoadPort1 = (CLoadPort*)getEquipment(EQ_ID_LOADPORT1);
 		CLoadPort* pLoadPort2 = (CLoadPort*)getEquipment(EQ_ID_LOADPORT2);
 		CFliper* pFliper = (CFliper*)getEquipment(EQ_ID_FLIPER);
@@ -297,6 +298,7 @@
 		CBakeCooling* pBakeCooling = (CBakeCooling*)getEquipment(EQ_ID_BAKE_COOLING);
 		CMeasurement* pMeasurement = (CMeasurement*)getEquipment(EQ_ID_MEASUREMENT);
 
+		ASSERT(pEFEM);
 		ASSERT(pLoadPort1);
 		ASSERT(pLoadPort2);
 		ASSERT(pFliper);
@@ -372,6 +374,7 @@
 				// BakeCooling ->Measurement
 				m_pActiveRobotTask = createTransferTask_bakecooling_to_measurement(pBakeCooling, pMeasurement);
 				if (m_pActiveRobotTask != nullptr) {
+					m_pActiveRobotTask->run();
 					std::string strDescription = m_pActiveRobotTask->getDescription();
 					unlock();
 					if (m_listener.onRobotTaskEvent != nullptr) {
@@ -386,6 +389,7 @@
 				// Bake -> Cooling
 				m_pActiveRobotTask = createTransferTask_bake_to_cooling(pBakeCooling);
 				if (m_pActiveRobotTask != nullptr) {
+					m_pActiveRobotTask->run();
 					std::string strDescription = m_pActiveRobotTask->getDescription();
 					unlock();
 					if (m_listener.onRobotTaskEvent != nullptr) {
@@ -399,6 +403,7 @@
 				// Bonder -> BakeCooling
 				m_pActiveRobotTask = createTransferTask_bonder_to_bakecooling(pBonder1, pBakeCooling);
 				if (m_pActiveRobotTask != nullptr) {
+					m_pActiveRobotTask->run();
 					std::string strDescription = m_pActiveRobotTask->getDescription();
 					unlock();
 					if (m_listener.onRobotTaskEvent != nullptr) {
@@ -410,6 +415,7 @@
 
 				m_pActiveRobotTask = createTransferTask_bonder_to_bakecooling(pBonder2, pBakeCooling);
 				if (m_pActiveRobotTask != nullptr) {
+					m_pActiveRobotTask->run();
 					std::string strDescription = m_pActiveRobotTask->getDescription();
 					unlock();
 					if (m_listener.onRobotTaskEvent != nullptr) {
@@ -422,6 +428,7 @@
 				// Aligner -> Bonder
 				m_pActiveRobotTask = createTransferTask(pAligner, pBonder1, primaryType, secondaryType);
 				if (m_pActiveRobotTask != nullptr) {
+					m_pActiveRobotTask->run();
 					std::string strDescription = m_pActiveRobotTask->getDescription();
 					unlock();
 					if (m_listener.onRobotTaskEvent != nullptr) {
@@ -433,6 +440,7 @@
 
 				m_pActiveRobotTask = createTransferTask(pAligner, pBonder2, primaryType, secondaryType);
 				if (m_pActiveRobotTask != nullptr) {
+					m_pActiveRobotTask->run();
 					std::string strDescription = m_pActiveRobotTask->getDescription();
 					unlock();
 					if (m_listener.onRobotTaskEvent != nullptr) {
@@ -447,6 +455,7 @@
 				// VacuumBake(G1) -> Aligner
 				m_pActiveRobotTask = createTransferTask(pFliper, pAligner, primaryType, secondaryType);
 				if (m_pActiveRobotTask != nullptr) {
+					m_pActiveRobotTask->run();
 					std::string strDescription = m_pActiveRobotTask->getDescription();
 					unlock();
 					if (m_listener.onRobotTaskEvent != nullptr) {
@@ -458,6 +467,7 @@
 
 				m_pActiveRobotTask = createTransferTask(pVacuumBack, pAligner, primaryType, secondaryType);
 				if (m_pActiveRobotTask != nullptr) {
+					m_pActiveRobotTask->run();
 					std::string strDescription = m_pActiveRobotTask->getDescription();
 					unlock();
 					if (m_listener.onRobotTaskEvent != nullptr) {
@@ -478,6 +488,7 @@
 				}
 				m_pActiveRobotTask = createTransferTask(pLoadPort1, pEqTar1, primaryType, secondaryType);
 				if (m_pActiveRobotTask != nullptr) {
+					m_pActiveRobotTask->run();
 					std::string strDescription = m_pActiveRobotTask->getDescription();
 					unlock();
 					if (m_listener.onRobotTaskEvent != nullptr) {
@@ -489,6 +500,7 @@
 
 				m_pActiveRobotTask = createTransferTask(pLoadPort2, pEqTar1, primaryType, secondaryType);
 				if (m_pActiveRobotTask != nullptr) {
+					m_pActiveRobotTask->run();
 					std::string strDescription = m_pActiveRobotTask->getDescription();
 					unlock();
 					if (m_listener.onRobotTaskEvent != nullptr) {
@@ -503,6 +515,7 @@
 				// LoadPort -> VacuumBake(G1)
 				m_pActiveRobotTask = createTransferTask(pLoadPort1, pEqTar2, primaryType, secondaryType);
 				if (m_pActiveRobotTask != nullptr) {
+					m_pActiveRobotTask->run();
 					std::string strDescription = m_pActiveRobotTask->getDescription();
 					unlock();
 					if (m_listener.onRobotTaskEvent != nullptr) {
@@ -514,6 +527,7 @@
 
 				m_pActiveRobotTask = createTransferTask(pLoadPort2, pEqTar2, primaryType, secondaryType);
 				if (m_pActiveRobotTask != nullptr) {
+					m_pActiveRobotTask->run();
 					std::string strDescription = m_pActiveRobotTask->getDescription();
 					unlock();
 					if (m_listener.onRobotTaskEvent != nullptr) {
@@ -1131,6 +1145,7 @@
 		if (pSrcSlot != nullptr && nullptr != pTarSlot) {
 			pTask = new CRobotTask();
 			pTask->setContext(pSrcSlot->getContext());
+			pTask->setEFEM((CEFEM*)getEquipment(EQ_ID_EFEM));
 			pTask->setRobotTransferParam(++taskSeqNo, 1, pSrcSlot->getPosition(),
 				pTarSlot->getPosition(), pSrcSlot->getNo(), pTarSlot->getNo());
 		}
@@ -1151,6 +1166,7 @@
 		if (pSrcSlot != nullptr && nullptr != pTarSlot) {
 			pTask = new CRobotTask();
 			pTask->setContext(pSrcSlot->getContext());
+			pTask->setEFEM((CEFEM*)getEquipment(EQ_ID_EFEM));
 			pTask->setRobotTransferParam(++taskSeqNo, 1, pSrcSlot->getPosition(),
 				pTarSlot->getPosition(), pSrcSlot->getNo(), pTarSlot->getNo());
 		}
@@ -1172,6 +1188,7 @@
 		if (pSrcSlot != nullptr && nullptr != pTarSlot) {
 			pTask = new CRobotTask();
 			pTask->setContext(pSrcSlot->getContext());
+			pTask->setEFEM((CEFEM*)getEquipment(EQ_ID_EFEM));
 			pTask->setRobotTransferParam(++taskSeqNo, 1, pSrcSlot->getPosition(),
 				pTarSlot->getPosition(), pSrcSlot->getNo(), pTarSlot->getNo());
 		}
@@ -1200,4 +1217,28 @@
 		return pTask;
 	}
 
+	int CMaster::abortCurrentTask()
+	{
+		lock();
+		if (m_pActiveRobotTask != nullptr) {
+			m_pActiveRobotTask->abort();
+		}
+		unlock();
+
+		if (m_listener.onRobotTaskEvent != nullptr) {
+			m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_ABORT);
+		}
+
+		lock();
+		if (m_pActiveRobotTask != nullptr) {
+			delete m_pActiveRobotTask;
+			m_pActiveRobotTask = nullptr;
+		}
+		unlock();
+
+		// 当前任务手动中止后,停止调度,需要操作员在解决问题后,重新启动
+		stop();
+
+		return 0;
+	}
 }
diff --git a/SourceCode/Bond/Servo/CMaster.h b/SourceCode/Bond/Servo/CMaster.h
index 9d00447..8a879dd 100644
--- a/SourceCode/Bond/Servo/CMaster.h
+++ b/SourceCode/Bond/Servo/CMaster.h
@@ -63,6 +63,7 @@
         std::list<CEquipment*>& getEquipmentList();
         CEquipment* getEquipment(int id);
         void setCacheFilepath(const char* pszFilepath);
+        int abortCurrentTask();
 
     private:
         inline void lock() { EnterCriticalSection(&m_criticalSection); }
diff --git a/SourceCode/Bond/Servo/CPageGraph2.cpp b/SourceCode/Bond/Servo/CPageGraph2.cpp
index b16eae2..d095b21 100644
--- a/SourceCode/Bond/Servo/CPageGraph2.cpp
+++ b/SourceCode/Bond/Servo/CPageGraph2.cpp
@@ -148,7 +148,7 @@
 		CEquipmentPage2* pPage2 = new CEquipmentPage2();
 		pPage2->setEquipment(pEquipment);
 		pPage2->Create(IDD_PAGE_EQUIPMENT2);
-		dlg.addPage(pPage2, "Glass");
+		dlg.addPage(pPage2, "Slots");
 
 		if (pEquipment->getID() == EQ_ID_EFEM) {
 			CEquipmentPage3* pPage3 = new CEquipmentPage3();
@@ -269,6 +269,10 @@
 				pEquipment->setLinkSignal(0, SIGNAL_UPSTREAM_TROUBLE, FALSE);
 				pEquipment->setLinkSignal(0, SIGNAL_INTERLOCK, TRUE);
 				pEquipment->setLinkSignal(0, SIGNAL_SEND_ABLE, TRUE);
+				pEquipment->setLinkSignal(1, SIGNAL_UPSTREAM_INLINE, TRUE);
+				pEquipment->setLinkSignal(1, SIGNAL_UPSTREAM_TROUBLE, FALSE);
+				pEquipment->setLinkSignal(1, SIGNAL_INTERLOCK, TRUE);
+				pEquipment->setLinkSignal(1, SIGNAL_SEND_ABLE, TRUE);
 			}
 
 			if (pEquipment != nullptr && (pEquipment->getID() == EQ_ID_Bonder1
diff --git a/SourceCode/Bond/Servo/CRobotTask.cpp b/SourceCode/Bond/Servo/CRobotTask.cpp
index a33cc40..dc1b82e 100644
--- a/SourceCode/Bond/Servo/CRobotTask.cpp
+++ b/SourceCode/Bond/Servo/CRobotTask.cpp
@@ -1,6 +1,7 @@
 #include "stdafx.h"
 #include "CRobotTask.h"
 #include "ToolUnits.h"
+#include "Log.h"
 
 
 namespace SERVO {
@@ -13,6 +14,7 @@
 		m_timeStored = 0;
 		m_timeFinish = 0;
 		m_pContext = nullptr;
+		m_pEFEM = nullptr;
 	}
 
 	CRobotTask::~CRobotTask()
@@ -78,6 +80,11 @@
 		return m_pContext;
 	}
 
+	void CRobotTask::setEFEM(CEFEM* pEFEM)
+	{
+		m_pEFEM = pEFEM;
+	}
+
 	std::string& CRobotTask::generateId(std::string& out)
 	{
 		char szBuffer[256];
@@ -139,6 +146,30 @@
 		return m_state;
 	}
 
+	void CRobotTask::run()
+	{
+		ASSERT(m_pEFEM);
+		m_state = ROBOT_TASK_STATE::Running;
+
+		static int seq = 0;
+		m_pEFEM->robotSendTransfer(++seq,
+			m_robotCmdParam.armNo,
+			m_robotCmdParam.getPosition, 
+			m_robotCmdParam.putPosition,
+			m_robotCmdParam.getSlotNo,
+			m_robotCmdParam.putSlotNo, 
+			[&](int code) -> int {
+				if (code == WOK) {
+					LOGI(_T("RobotTask已下发到EFEM"));
+				}
+				else {
+					LOGI(_T("RobotTask已下发失败"));
+				}
+
+				return 0;
+			});
+	}
+
 	void CRobotTask::completed()
 	{
 		m_state = ROBOT_TASK_STATE::Completed;
diff --git a/SourceCode/Bond/Servo/CRobotTask.h b/SourceCode/Bond/Servo/CRobotTask.h
index 2cd8654..63edbeb 100644
--- a/SourceCode/Bond/Servo/CRobotTask.h
+++ b/SourceCode/Bond/Servo/CRobotTask.h
@@ -1,6 +1,7 @@
 #pragma once
 #include "ServoCommo.h"
 #include "Context.h"
+#include "CEFEM.h"
 
 
 namespace SERVO {
@@ -16,6 +17,7 @@
 		std::string getSimpleDescription() const;
 		void setContext(CContext* pContext);
 		CContext* getContext();
+		void setEFEM(CEFEM* pEFEM);
 		void setRobotTransferParam(int seq, int armNo, int fromPos, int toPos, int fromSlot, int toSlot);
 		ROBOT_CMD_PARAM& getRobotCmdParam();
 		time_t getCreateTime();
@@ -23,6 +25,7 @@
 		time_t getStoredTime();
 		time_t getFinishTime();
 		ROBOT_TASK_STATE getState();
+		void run();
 		void completed();
 		void error();
 		void abort();
@@ -50,5 +53,6 @@
 		time_t m_timeFinish;						/* 结束时间 */
 		ROBOT_CMD_PARAM m_robotCmdParam;			/* 参数 */
 		CContext* m_pContext;
+		CEFEM* m_pEFEM;
 	};
 }
diff --git a/SourceCode/Bond/Servo/CRobotTaskDlg.cpp b/SourceCode/Bond/Servo/CRobotTaskDlg.cpp
index b354216..cb39af5 100644
--- a/SourceCode/Bond/Servo/CRobotTaskDlg.cpp
+++ b/SourceCode/Bond/Servo/CRobotTaskDlg.cpp
@@ -194,8 +194,10 @@
 
 void CRobotTaskDlg::OnBnClickedAbortTask()
 {
-	if (m_pRobotTask) {
-		m_pRobotTask->abort();
-		AfxMessageBox(_T("浠诲姟宸插仠姝€��"));
+	int ret = AfxMessageBox(_T("纭瑕佺粓姝㈠綋鍓嶆惉閫佷换鍔″悧?闄ら潪鍙戠敓浜嗗紓甯革紝鍚﹀垯璇蜂笉瑕佹墜鍔ㄧ粓姝换鍔★紒"), MB_OKCANCEL | MB_ICONEXCLAMATION);
+	if (ret != IDOK) {
+		return;
 	}
+
+	theApp.m_model.getMaster().abortCurrentTask();
 }
\ No newline at end of file
diff --git a/SourceCode/Bond/Servo/CSlot.cpp b/SourceCode/Bond/Servo/CSlot.cpp
index 94299a1..629f7ac 100644
--- a/SourceCode/Bond/Servo/CSlot.cpp
+++ b/SourceCode/Bond/Servo/CSlot.cpp
@@ -12,6 +12,7 @@
 		m_bLock = FALSE;
 		m_pContext = nullptr;
 		m_pTempContext = nullptr;
+		m_nLinkSignalPath = 0;
 	}
 
 	CSlot::~CSlot()
@@ -119,6 +120,16 @@
 		return m_pTempContext;
 	}
 
+	void CSlot::setLinkSignalPath(int path)
+	{
+		m_nLinkSignalPath = path;
+	}
+
+	int CSlot::getLinkSignalPath()
+	{
+		return m_nLinkSignalPath;
+	}
+
 	void CSlot::serialize(CArchive& ar)
 	{
 		if (ar.IsStoring()) {
diff --git a/SourceCode/Bond/Servo/CSlot.h b/SourceCode/Bond/Servo/CSlot.h
index 76461d8..d1869fc 100644
--- a/SourceCode/Bond/Servo/CSlot.h
+++ b/SourceCode/Bond/Servo/CSlot.h
@@ -29,6 +29,8 @@
 		CContext* getContext();
 		CContext* getTempContext();
 		void setContext(CContext* pContext);
+		void setLinkSignalPath(int path);
+		int getLinkSignalPath();
 		void serialize(CArchive& ar);
 
 	private:
@@ -44,6 +46,7 @@
 		CContext* m_pTempContext;
 		BOOL m_bEnable;
 		BOOL m_bLock;
+		int m_nLinkSignalPath;
 	};
 }
 
diff --git a/SourceCode/Bond/Servo/Context.cpp b/SourceCode/Bond/Servo/Context.cpp
index d71cf34..dff60f2 100644
--- a/SourceCode/Bond/Servo/Context.cpp
+++ b/SourceCode/Bond/Servo/Context.cpp
@@ -1,7 +1,34 @@
 #include "stdafx.h"
 #include "Context.h"
+#include <dbghelp.h>
+
+#pragma comment(lib, "dbghelp.lib")
 
 
+void PrintStackTrace()
+{
+	void* stack[62]; // 最多抓62层
+	USHORT frames = CaptureStackBackTrace(0, 62, stack, NULL);
+
+	HANDLE process = GetCurrentProcess();
+	SymInitialize(process, NULL, TRUE);
+	for (USHORT i = 0; i < frames; ++i) {
+		DWORD64 address = (DWORD64)(stack[i]);
+		char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
+		PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
+		symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
+		symbol->MaxNameLen = MAX_SYM_NAME;
+
+		if (SymFromAddr(process, address, 0, symbol)) {
+			TRACE(">>>> name:%s\n", symbol->Name);
+		}
+		else {
+			TRACE(">>>> name:%s\n", "SymFromAddr failed");
+		}
+	}
+
+	SymCleanup(process);
+}
 CContext::CContext()
 {
 	m_onReleaseCallback = nullptr;
diff --git a/SourceCode/Bond/Servo/Servo.rc b/SourceCode/Bond/Servo/Servo.rc
index 2f13140..8a548dd 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 80117a5..e689f1a 100644
--- a/SourceCode/Bond/Servo/ServoDlg.cpp
+++ b/SourceCode/Bond/Servo/ServoDlg.cpp
@@ -174,6 +174,8 @@
 			else if (RX_CODE_MASTER_STATE_CHANGED == code) {
 				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_STOP)->EnableWindow(FALSE);
 					m_pMyStatusbar->setBackgroundColor(STATUSBAR_BK_NORMAL);
 					m_pMyStatusbar->setForegroundColor(RGB(0, 0, 0));
 					KillTimer(TIMER_ID_UPDATE_RUMTIME);
@@ -182,6 +184,8 @@
 					m_pMyStatusbar->setRunTimeText((LPTSTR)(LPCTSTR)strText);
 				}
 				else if (state == SERVO::MASTERSTATE::RUNNING) {
+					m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(FALSE);
+					m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(TRUE);
 					m_pMyStatusbar->setBackgroundColor(STATUSBAR_BK_RUNNING);
 					m_pMyStatusbar->setForegroundColor(RGB(255, 255, 255));
 					SetTimer(TIMER_ID_UPDATE_RUMTIME, 500, nullptr);
@@ -207,6 +211,9 @@
 						}
 					}
 					else if (exCode == ROBOT_EVENT_FINISH) {
+						m_pMyStatusbar->setCurTaskBtnText("无");
+					}
+					else if (exCode == ROBOT_EVENT_ABORT) {
 						m_pMyStatusbar->setCurTaskBtnText("无");
 					}
 				}
@@ -793,11 +800,9 @@
 	if (id == IDC_BUTTON_RUN) {
 		theApp.m_model.getMaster().start();
 		m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(FALSE);
-		m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(TRUE);
 	}
 	else if (id == IDC_BUTTON_STOP) {
 		theApp.m_model.getMaster().stop();
-		m_pTopToolbar->GetBtn(IDC_BUTTON_RUN)->EnableWindow(TRUE);
 		m_pTopToolbar->GetBtn(IDC_BUTTON_STOP)->EnableWindow(FALSE);
 	}
 	else if (id == IDC_BUTTON_ROBOT) {

--
Gitblit v1.9.3