From 58b5bb07de4bcbf670db5ad79ff8b9bd7afc1e28 Mon Sep 17 00:00:00 2001
From: mrDarker <mr.darker@163.com>
Date: 星期二, 17 六月 2025 11:35:47 +0800
Subject: [PATCH] Merge branch 'clh' into liuyang

---
 SourceCode/Bond/Servo/CArm.cpp                               |   18 -
 SourceCode/Bond/Servo/CGlass.cpp                             |   15 +
 SourceCode/Bond/Servo/CGlass.h                               |    1 
 SourceCode/Bond/Servo/CRobotTask.cpp                         |   67 ++++++
 SourceCode/Bond/Servo/CEFEM.h                                |    2 
 SourceCode/Bond/Servo/CMaster.h                              |    1 
 /dev/null                                                    |    0 
 SourceCode/Bond/Servo/CMeasurement.cpp                       |    4 
 SourceCode/Bond/Servo/CRobotTask.h                           |    1 
 SourceCode/Bond/Servo/CEquipment.cpp                         |   43 ++-
 Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.7.xlsx |    0 
 SourceCode/Bond/Servo/CArmTray.cpp                           |    4 
 SourceCode/Bond/Servo/CEFEM.cpp                              |   31 +++
 SourceCode/Bond/Servo/CMaster.cpp                            |  297 +++++++++++++----------------
 SourceCode/Bond/Servo/ServoCommo.h                           |   32 +++
 SourceCode/Bond/Servo/CBonder.h                              |    1 
 SourceCode/Bond/Servo/CBonder.cpp                            |   24 +-
 17 files changed, 311 insertions(+), 230 deletions(-)

diff --git "a/Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.7\0501\051.xlsx" "b/Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.7\0501\051.xlsx"
deleted file mode 100644
index 15ab4ed..0000000
--- "a/Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.7\0501\051.xlsx"
+++ /dev/null
Binary files differ
diff --git a/Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.7.xlsx b/Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.7.xlsx
index 303ffbe..4c866cb 100644
--- a/Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.7.xlsx
+++ b/Document/ESWIN_EAS_Bonder_Inline_Mapping_Address_v1.1.7.xlsx
Binary files differ
diff --git a/SourceCode/Bond/Servo/CArm.cpp b/SourceCode/Bond/Servo/CArm.cpp
index cf6320e..7ca9be1 100644
--- a/SourceCode/Bond/Servo/CArm.cpp
+++ b/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) {
diff --git a/SourceCode/Bond/Servo/CArmTray.cpp b/SourceCode/Bond/Servo/CArmTray.cpp
index 0a043b6..6e74681 100644
--- a/SourceCode/Bond/Servo/CArmTray.cpp
+++ b/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)
diff --git a/SourceCode/Bond/Servo/CBonder.cpp b/SourceCode/Bond/Servo/CBonder.cpp
index db7cf76..cbeabd5 100644
--- a/SourceCode/Bond/Servo/CBonder.cpp
+++ b/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();
diff --git a/SourceCode/Bond/Servo/CBonder.h b/SourceCode/Bond/Servo/CBonder.h
index 28f557f..7771c57 100644
--- a/SourceCode/Bond/Servo/CBonder.h
+++ b/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;
diff --git a/SourceCode/Bond/Servo/CEFEM.cpp b/SourceCode/Bond/Servo/CEFEM.cpp
index 099e2cd..33e6b29 100644
--- a/SourceCode/Bond/Servo/CEFEM.cpp
+++ b/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);
diff --git a/SourceCode/Bond/Servo/CEFEM.h b/SourceCode/Bond/Servo/CEFEM.h
index b01036f..aade245 100644
--- a/SourceCode/Bond/Servo/CEFEM.h
+++ b/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;
     };
 }
 
diff --git a/SourceCode/Bond/Servo/CEquipment.cpp b/SourceCode/Bond/Servo/CEquipment.cpp
index 7f10e53..473afdb 100644
--- a/SourceCode/Bond/Servo/CEquipment.cpp
+++ b/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 {
-				attrubutes.addAttribute(new CAttribute(m_slot[i].getName().c_str(),
-					pGlass->getID().c_str(), "", weight++));
+				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);
diff --git a/SourceCode/Bond/Servo/CGlass.cpp b/SourceCode/Bond/Servo/CGlass.cpp
index e975351..dc47c5e 100644
--- a/SourceCode/Bond/Servo/CGlass.cpp
+++ b/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_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;
diff --git a/SourceCode/Bond/Servo/CGlass.h b/SourceCode/Bond/Servo/CGlass.h
index d2f4197..3374f84 100644
--- a/SourceCode/Bond/Servo/CGlass.h
+++ b/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);
diff --git a/SourceCode/Bond/Servo/CMaster.cpp b/SourceCode/Bond/Servo/CMaster.cpp
index b9ea92b..96ad405 100644
--- a/SourceCode/Bond/Servo/CMaster.cpp
+++ b/SourceCode/Bond/Servo/CMaster.cpp
@@ -343,10 +343,13 @@
 
 			// 调度逻辑处理
 			else if (m_state == MASTERSTATE::RUNNING) {
-				unlock();
-				// LOGI("调度处理中...");
+				// 检测判断robot状态
+				RMDATA& rmd = pEFEM->getRobotMonitoringData();
+				if (rmd.status != ROBOT_STATUS::Idle && rmd.status != ROBOT_STATUS::Run) {
+					unlock();
+					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,139 +412,161 @@
 
 
 				// BakeCooling ->Measurement
-				m_pActiveRobotTask = createTransferTask_bakecooling_to_measurement(pBakeCooling, pMeasurement);
-				if (m_pActiveRobotTask != nullptr) {
-					m_pActiveRobotTask->pick();
-					std::string strDescription = m_pActiveRobotTask->getDescription();
-					unlock();
-					if (m_listener.onRobotTaskEvent != nullptr) {
-						m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
+				if (!rmd.armState[0]) {
+					m_pActiveRobotTask = createTransferTask_bakecooling_to_measurement(pBakeCooling, pMeasurement);
+					if (m_pActiveRobotTask != nullptr) {
+						m_pActiveRobotTask->pick();
+						std::string strDescription = m_pActiveRobotTask->getDescription();
+						unlock();
+						if (m_listener.onRobotTaskEvent != nullptr) {
+							m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
+						}
+						LOGI("创建新任务<%s>...", strDescription.c_str());
+						continue;
 					}
-					LOGI("创建新任务<%s>...", strDescription.c_str());
-					continue;
 				}
+
 
 				
 				// BakeCooling内部
 				// Bake -> Cooling
-				m_pActiveRobotTask = createTransferTask_bake_to_cooling(pBakeCooling);
-				if (m_pActiveRobotTask != nullptr) {
-					m_pActiveRobotTask->pick();
-					std::string strDescription = m_pActiveRobotTask->getDescription();
-					unlock();
-					if (m_listener.onRobotTaskEvent != nullptr) {
-						m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
+				if (!rmd.armState[0]) {
+					m_pActiveRobotTask = createTransferTask_bake_to_cooling(pBakeCooling);
+					if (m_pActiveRobotTask != nullptr) {
+						m_pActiveRobotTask->pick();
+						std::string strDescription = m_pActiveRobotTask->getDescription();
+						unlock();
+						if (m_listener.onRobotTaskEvent != nullptr) {
+							m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
+						}
+						LOGI("创建新任务<%s>...", strDescription.c_str());
+						continue;
 					}
-					LOGI("创建新任务<%s>...", strDescription.c_str());
-					continue;
 				}
 
 
 				// Bonder -> BakeCooling
-				m_pActiveRobotTask = createTransferTask_bonder_to_bakecooling(pBonder1, pBakeCooling);
-				if (m_pActiveRobotTask != nullptr) {
-					m_pActiveRobotTask->pick();
-					std::string strDescription = m_pActiveRobotTask->getDescription();
-					unlock();
-					if (m_listener.onRobotTaskEvent != nullptr) {
-						m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
+				if (!rmd.armState[0]) {
+					m_pActiveRobotTask = createTransferTask_bonder_to_bakecooling(pBonder1, pBakeCooling);
+					if (m_pActiveRobotTask != nullptr) {
+						m_pActiveRobotTask->pick();
+						std::string strDescription = m_pActiveRobotTask->getDescription();
+						unlock();
+						if (m_listener.onRobotTaskEvent != nullptr) {
+							m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
+						}
+						LOGI("创建新任务<%s>...", strDescription.c_str());
+						continue;
 					}
-					LOGI("创建新任务<%s>...", strDescription.c_str());
-					continue;
 				}
 
-				m_pActiveRobotTask = createTransferTask_bonder_to_bakecooling(pBonder2, pBakeCooling);
-				if (m_pActiveRobotTask != nullptr) {
-					m_pActiveRobotTask->pick();
-					std::string strDescription = m_pActiveRobotTask->getDescription();
-					unlock();
-					if (m_listener.onRobotTaskEvent != nullptr) {
-						m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
+				if (!rmd.armState[0]) {
+					m_pActiveRobotTask = createTransferTask_bonder_to_bakecooling(pBonder2, pBakeCooling);
+					if (m_pActiveRobotTask != nullptr) {
+						m_pActiveRobotTask->pick();
+						std::string strDescription = m_pActiveRobotTask->getDescription();
+						unlock();
+						if (m_listener.onRobotTaskEvent != nullptr) {
+							m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
+						}
+						LOGI("创建新任务<%s>...", strDescription.c_str());
+						continue;
 					}
-					LOGI("创建新任务<%s>...", strDescription.c_str());
-					continue;
 				}
+
 
 				// Fliper(G2) -> Bonder
 				// VacuumBake(G1) -> Bonder
-				m_pActiveRobotTask = createTransferTask(pFliper, pBonder1, primaryType, secondaryType, 2);
-				if (m_pActiveRobotTask != nullptr) {
-					m_pActiveRobotTask->pick();
-					std::string strDescription = m_pActiveRobotTask->getDescription();
-					unlock();
-					if (m_listener.onRobotTaskEvent != nullptr) {
-						m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
+				if (!rmd.armState[1] && !pBonder1->hasBondClass()) {
+					m_pActiveRobotTask = createTransferTask(pFliper, pBonder1, primaryType, secondaryType, 2);
+					if (m_pActiveRobotTask != nullptr) {
+						m_pActiveRobotTask->pick();
+						std::string strDescription = m_pActiveRobotTask->getDescription();
+						unlock();
+						if (m_listener.onRobotTaskEvent != nullptr) {
+							m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
+						}
+						LOGI("创建新任务<%s>...", strDescription.c_str());
+						continue;
 					}
-					LOGI("创建新任务<%s>...", strDescription.c_str());
-					continue;
 				}
 
-				m_pActiveRobotTask = createTransferTask(pFliper, pBonder2, primaryType, secondaryType, 2);
-				if (m_pActiveRobotTask != nullptr) {
-					m_pActiveRobotTask->pick();
-					std::string strDescription = m_pActiveRobotTask->getDescription();
-					unlock();
-					if (m_listener.onRobotTaskEvent != nullptr) {
-						m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
+				if (!rmd.armState[1] && !pBonder2->hasBondClass()) {
+					m_pActiveRobotTask = createTransferTask(pFliper, pBonder2, primaryType, secondaryType, 2);
+					if (m_pActiveRobotTask != nullptr) {
+						m_pActiveRobotTask->pick();
+						std::string strDescription = m_pActiveRobotTask->getDescription();
+						unlock();
+						if (m_listener.onRobotTaskEvent != nullptr) {
+							m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
+						}
+						LOGI("创建新任务<%s>...", strDescription.c_str());
+						continue;
 					}
-					LOGI("创建新任务<%s>...", strDescription.c_str());
-					continue;
 				}
 
-				m_pActiveRobotTask = createTransferTask(pVacuumBake, pBonder1, primaryType, secondaryType);
-				if (m_pActiveRobotTask != nullptr) {
-					m_pActiveRobotTask->pick();
-					std::string strDescription = m_pActiveRobotTask->getDescription();
-					unlock();
-					if (m_listener.onRobotTaskEvent != nullptr) {
-						m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
+				if (!rmd.armState[0] && !pBonder1->hasBondClass()) {
+					m_pActiveRobotTask = createTransferTask(pVacuumBake, pBonder1, primaryType, secondaryType);
+					if (m_pActiveRobotTask != nullptr) {
+						m_pActiveRobotTask->pick();
+						std::string strDescription = m_pActiveRobotTask->getDescription();
+						unlock();
+						if (m_listener.onRobotTaskEvent != nullptr) {
+							m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
+						}
+						LOGI("创建新任务<%s>...", strDescription.c_str());
+						continue;
 					}
-					LOGI("创建新任务<%s>...", strDescription.c_str());
-					continue;
 				}
 
-				m_pActiveRobotTask = createTransferTask(pVacuumBake, pBonder2, primaryType, secondaryType);
-				if (m_pActiveRobotTask != nullptr) {
-					m_pActiveRobotTask->pick();
-					std::string strDescription = m_pActiveRobotTask->getDescription();
-					unlock();
-					if (m_listener.onRobotTaskEvent != nullptr) {
-						m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
+				if (!rmd.armState[0] && !pBonder2->hasBondClass()) {
+					m_pActiveRobotTask = createTransferTask(pVacuumBake, pBonder2, primaryType, secondaryType);
+					if (m_pActiveRobotTask != nullptr) {
+						m_pActiveRobotTask->pick();
+						std::string strDescription = m_pActiveRobotTask->getDescription();
+						unlock();
+						if (m_listener.onRobotTaskEvent != nullptr) {
+							m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
+						}
+						LOGI("创建新任务<%s>...", strDescription.c_str());
+						continue;
 					}
-					LOGI("创建新任务<%s>...", strDescription.c_str());
-					continue;
 				}
+
 
 				// Aligner -> Fliper(G2)
 				// Aligner -> VacuumBake(G1)
-				m_pActiveRobotTask = createTransferTask(pAligner, pFliper, primaryType, secondaryType, 2);
-				if (m_pActiveRobotTask != nullptr) {
-					m_pActiveRobotTask->pick();
-					std::string strDescription = m_pActiveRobotTask->getDescription();
-					unlock();
-					if (m_listener.onRobotTaskEvent != nullptr) {
-						m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
+				if (!rmd.armState[1]) {
+					m_pActiveRobotTask = createTransferTask(pAligner, pFliper, primaryType, secondaryType, 2);
+					if (m_pActiveRobotTask != nullptr) {
+						m_pActiveRobotTask->pick();
+						std::string strDescription = m_pActiveRobotTask->getDescription();
+						unlock();
+						if (m_listener.onRobotTaskEvent != nullptr) {
+							m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
+						}
+						LOGI("创建新任务<%s>...", strDescription.c_str());
+						continue;
 					}
-					LOGI("创建新任务<%s>...", strDescription.c_str());
-					continue;
 				}
 
-				m_pActiveRobotTask = createTransferTask(pAligner, pVacuumBake, primaryType, secondaryType);
-				if (m_pActiveRobotTask != nullptr) {
-					m_pActiveRobotTask->pick();
-					std::string strDescription = m_pActiveRobotTask->getDescription();
-					unlock();
-					if (m_listener.onRobotTaskEvent != nullptr) {
-						m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
+				if (!rmd.armState[0]) {
+					m_pActiveRobotTask = createTransferTask(pAligner, pVacuumBake, primaryType, secondaryType);
+					if (m_pActiveRobotTask != nullptr) {
+						m_pActiveRobotTask->pick();
+						std::string strDescription = m_pActiveRobotTask->getDescription();
+						unlock();
+						if (m_listener.onRobotTaskEvent != nullptr) {
+							m_listener.onRobotTaskEvent(this, m_pActiveRobotTask, ROBOT_EVENT_CREATE);
+						}
+						LOGI("创建新任务<%s>...", strDescription.c_str());
+						continue;
 					}
-					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()
diff --git a/SourceCode/Bond/Servo/CMaster.h b/SourceCode/Bond/Servo/CMaster.h
index 6d2e380..2f8577d 100644
--- a/SourceCode/Bond/Servo/CMaster.h
+++ b/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;
diff --git a/SourceCode/Bond/Servo/CMeasurement.cpp b/SourceCode/Bond/Servo/CMeasurement.cpp
index dfc731f..a20066f 100644
--- a/SourceCode/Bond/Servo/CMeasurement.cpp
+++ b/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)
diff --git a/SourceCode/Bond/Servo/CRobotTask.cpp b/SourceCode/Bond/Servo/CRobotTask.cpp
index 4ac89d3..ed82d43 100644
--- a/SourceCode/Bond/Servo/CRobotTask.cpp
+++ b/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;
+		}
+	}
 }
diff --git a/SourceCode/Bond/Servo/CRobotTask.h b/SourceCode/Bond/Servo/CRobotTask.h
index 7e83046..990e106 100644
--- a/SourceCode/Bond/Servo/CRobotTask.h
+++ b/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;					/* 任务状态 */
diff --git a/SourceCode/Bond/Servo/ServoCommo.h b/SourceCode/Bond/Servo/ServoCommo.h
index 6e70ac3..aa02acc 100644
--- a/SourceCode/Bond/Servo/ServoCommo.h
+++ b/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	/* 放片 */

--
Gitblit v1.9.3