From 201046a8b83f34ea099a11043ade28d8457d7af9 Mon Sep 17 00:00:00 2001
From: mrDarker <mr.darker@163.com>
Date: 星期六, 02 八月 2025 10:47:04 +0800
Subject: [PATCH] 1. 添加计算时间戳宏 2. 重写切割两片玻璃函数 3. 添加分组过滤干扰点的函数

---
 SourceCode/Bond/SGMeasurement/SGMeasurementDlg.cpp |  248 +++++++++++++++++++++++++++++++++++++------------
 1 files changed, 185 insertions(+), 63 deletions(-)

diff --git a/SourceCode/Bond/SGMeasurement/SGMeasurementDlg.cpp b/SourceCode/Bond/SGMeasurement/SGMeasurementDlg.cpp
index eb946f3..7529194 100644
--- a/SourceCode/Bond/SGMeasurement/SGMeasurementDlg.cpp
+++ b/SourceCode/Bond/SGMeasurement/SGMeasurementDlg.cpp
@@ -35,6 +35,19 @@
 #define TIMER_INTERVAL_MS		500
 #define TIMER_ID_OUTPUT_UPDATE	1
 
+// 璁℃椂瀹忓畾涔�
+#define MEASURE_FUNC_START() \
+	clock_t __startClock = clock();
+
+#define MEASURE_FUNC_END() \
+	do { \
+		clock_t __endClock = clock(); \
+		double __elapsedMs = 1000.0 * (__endClock - __startClock) / CLOCKS_PER_SEC; \
+		CString __strElapsed; \
+		__strElapsed.Format(_T("%s 鎵ц鑰楁椂锛�%.1f ms"), _T(__FUNCTION__), __elapsedMs); \
+		AppendLogLineRichStyled(__strElapsed, LOG_COLOR_SUCCESS); \
+	} while (0)
+
 class CAboutDlg : public CDialogEx
 {
 public:
@@ -72,7 +85,7 @@
 	, m_dOutValues{ 0.0, 0.0, 0.0, 0.0 }
 	, m_nUseTrigger(0)
 	, m_nSavePointCount(100000)
-	, m_fJumpThreshold(1.0f)
+	, m_fJumpThreshold(0.2f)
 	, m_nJumpWindow(3)
 	, m_nValleyMargin(0)
 	, m_nMinGlass1Count(10)
@@ -232,7 +245,7 @@
 	strFullLogLine.Format(_T("%s %s"), strLevel, strContent);
 
 	// 鍐欏叆鏃ュ織鏂囦欢
-	LOG_LINE(strFullLogLine);
+	// LOG_LINE(strFullLogLine);
 }
 
 void CSGMeasurementDlg::HighlightAllMatches(const CString& strSearch, COLORREF clrHighlight/* = RGB(255, 165, 0)*/)
@@ -337,32 +350,38 @@
 		return false;
 	}
 
-	RC nRet = SGIF_CloseDevice(DeviceID);
-	if (nRet == RC_OK) {
-		if (m_bSaving) {
-			m_bSaving = FALSE;
-			nRet = SGIF_DataStorageStop(DeviceID);
-			if (nRet == RC_OK) {
-				AppendLogLineRichStyled(_T("鏁版嵁瀛樺偍宸插仠姝€��"), LOG_COLOR_SUCCESS);
-			}
-			else {
-				CString strError;
-				strError.Format(_T("鍋滄鏁版嵁瀛樺偍澶辫触锛岄敊璇爜锛�%#X"), nRet);
-				AppendLogLineRichStyled(strError, LOG_COLOR_ERROR);
-			}
-		}
+	// 鍋滄瀹氭椂鍣紝閬垮厤鍦ㄦ柇寮�鍚庝粛灏濊瘯鏇存柊杈撳嚭鏁版嵁
+	KillTimer(TIMER_ID_OUTPUT_UPDATE);
 
+	// 鍏堝仠姝㈡暟鎹瓨鍌紙濡傛灉姝e湪杩涜锛�
+	RC nRet;
+	if (m_bConnected && m_bSaving) {
+		nRet = SGIF_DataStorageStop(DeviceID);
+		if (nRet == RC_OK) {
+			m_bSaving = FALSE;
+			AppendLogLineRichStyled(_T("鏁版嵁瀛樺偍宸插仠姝€��"), LOG_COLOR_SUCCESS);
+		}
+		else {
+			CString strError;
+			strError.Format(_T("鍋滄鏁版嵁瀛樺偍澶辫触锛岄敊璇爜锛�%#X"), nRet);
+			AppendLogLineRichStyled(strError, LOG_COLOR_ERROR);
+		}
+	}
+
+	// 鏂紑璁惧杩炴帴
+	nRet = SGIF_CloseDevice(DeviceID);
+	if (nRet == RC_OK) {
 		AppendLogLineRichStyled(_T("鏂紑杩炴帴鎴愬姛锛�"), LOG_COLOR_SUCCESS);
 
 		m_bConnected = FALSE;
 		UpdateControlStatus(FALSE, FALSE);
-		KillTimer(TIMER_ID_OUTPUT_UPDATE);
 		return true;
 	}
 	else {
 		CString strError;
 		strError.Format(_T("鏂紑杩炴帴澶辫触锛岄敊璇爜锛�%#X"), nRet);
 		AppendLogLineRichStyled(strError, LOG_COLOR_ERROR);
+		AppendLogLineRichStyled(_T("淇濇寔褰撳墠鐘舵�侊紝鏂紑澶辫触銆�"), LOG_COLOR_ERROR);
 
 		UpdateControlStatus(m_bConnected, m_bSaving);
 		return false;
@@ -371,6 +390,8 @@
 
 void CSGMeasurementDlg::CleanInvalidValuesInPlace(int nOutNo, std::vector<float>& vecData, float fInvalid/* = -999.0f*/)
 {
+	MEASURE_FUNC_START();
+
 	// 鎵惧埌绗竴涓湁鏁堝��
 	auto itStart = std::find_if(vecData.begin(), vecData.end(), [=](float v) { return v > fInvalid; });
 
@@ -406,62 +427,87 @@
 	else {
 		vecData.clear();
 	}
+
+	MEASURE_FUNC_END();
 }
 
-bool CSGMeasurementDlg::SplitGlassSegments(int nOutNo, const std::vector<float>& vecData, std::vector<float>& vecGlass1, std::vector<float>& vecGlass2, float fJumpThreshold /*= 0.2f*/, int nWindow /*= 3*/, int nValleyMargin /*= 0*/, int nMinGlass1Count /*= 10*/)
+bool CSGMeasurementDlg::SplitGlassSegments(int nOutNo, const std::vector<float>& vecData, std::vector<float>& vecGlass1, std::vector<float>& vecGlass2, float fJumpThreshold /*= 0.2f*/, int nWindow /*= 3*/, int nValleyMargin /*= 0*/, int nMinGlassCount /*= 10*/)
 {
-	const int n = static_cast<int>(vecData.size());
-	if (n < 2 * nWindow + 1 + nMinGlass1Count) {
-		CString strError;
-		strError.Format(_T("OUT%d: 鏁版嵁閲忎笉瓒筹紝鑷冲皯闇�瑕� %d 涓偣鎵嶈兘杩涜鍒囧壊銆�"), nOutNo, 2 * nWindow + 1 + nMinGlass1Count);
-		AppendLogLineRichStyled(strError, LOG_COLOR_WARNING);
+	MEASURE_FUNC_START();
+
+	CString strLog;
+	const int nTotal = static_cast<int>(vecData.size());
+
+	if (nTotal < 2 * nWindow + 1 + nMinGlassCount) {
+		strLog.Format(_T("OUT%d: 鏁版嵁閲忎笉瓒筹紝鑷冲皯闇�瑕� %d 涓偣鎵嶈兘鍒囧壊銆�"), nOutNo, 2 * nWindow + 1 + nMinGlassCount);
+		AppendLogLineRichStyled(strLog, LOG_COLOR_WARNING);
 		return false;
 	}
 
-	int nValleyIdx = -1;
-	for (int i = nWindow; i < n - nWindow - nMinGlass1Count; ++i) {
-		float fDelta = std::fabs(vecData[i + nWindow] - vecData[i - nWindow]);
-		if (fDelta > fJumpThreshold) {
-			// 鎵� valley 鐐癸紙绋嶅井寰�鍚庤烦鍑犳浠ラ伩寮�杈圭紭鎶栧姩锛�
-			int nSearchStart = i + nWindow + 2;
-			int nSearchEnd = min(nSearchStart + 10, n);
+	// 浠庝腑闂村悜涓よ竟鏌ユ壘 valley 鍊欓�夌偣
+	int nMid = nTotal / 2;
+	int nValleyLeft = -1, nValleyRight = -1;
 
-			auto itValley = std::min_element(vecData.begin() + nSearchStart, vecData.begin() + nSearchEnd,
-				[](float a, float b) {
-					return (a > -900.0f && b > -900.0f) ? a < b : false;
-				});
-
-			if (itValley != vecData.begin() + nSearchEnd) {
-				nValleyIdx = static_cast<int>(std::distance(vecData.begin(), itValley));
-				break;
-			}
+	// 鍚戝乏鏌ユ壘 valley
+	for (int i = nMid; i >= nWindow; --i) {
+		float fDelta = std::fabs(vecData[i] - vecData[i - nWindow]);
+		if (fDelta > fJumpThreshold &&
+			vecData[i] < vecData[i - 1] &&
+			vecData[i] < vecData[i + 1]) {
+			nValleyLeft = i;
+			break;
 		}
 	}
 
-	if (nValleyIdx < 0 || nValleyIdx < nMinGlass1Count) {
-		AppendLogLineRichStyled(_T("鏈壘鍒板悎閫� valley 鐐癸紝鎴� valley 澶潬鍓嶃��"), LOG_COLOR_WARNING);
-		return false;
+	// 鍚戝彸鏌ユ壘 valley
+	for (int i = nMid; i <= nTotal - nWindow - 2; ++i) {
+		float fDelta = std::fabs(vecData[i + nWindow] - vecData[i]);
+		if (fDelta > fJumpThreshold &&
+			vecData[i] < vecData[i - 1] &&
+			vecData[i] < vecData[i + 1]) {
+			nValleyRight = i;
+			break;
+		}
 	}
 
-	// 浠� valley 澶勫紑濮嬪垏鍓诧紝鎴栬�呭線鍚庡亸绉�
-	int nCutStart = min(nValleyIdx + nValleyMargin, n);
-	vecGlass1.assign(vecData.begin(), vecData.begin() + nCutStart);
-	vecGlass2.assign(vecData.begin() + nCutStart, vecData.end());
+	// 閫夊畾 valley 鐐�
+	int nValleyIdx = -1;
+	if (nValleyLeft > 0 && nValleyRight > 0) {
+		nValleyIdx = (vecData[nValleyLeft] < vecData[nValleyRight]) ? nValleyLeft : nValleyRight;
+	}
+	else if (nValleyLeft > 0) {
+		nValleyIdx = nValleyLeft;
+	}
+	else if (nValleyRight > 0) {
+		nValleyIdx = nValleyRight;
+	}
+
+	// fallback: valley 鏈壘鍒帮紝浣跨敤涓棿鍒囧壊娉�
+	if (nValleyIdx < 0) {
+		AppendLogLineRichStyled(_T("鏈壘鍒� valley 璺冲彉鐐癸紝浣跨敤涓棿浣嶇疆鍒囧壊銆�"), LOG_COLOR_WARNING);
+		nValleyIdx = nMid;
+	}
+
+	// 搴旂敤鍒囧壊浣嶇疆锛岄檺鍒惰竟鐣�
+	int nCutPos = max(1, min(nTotal - 1, nValleyIdx + nValleyMargin));
+
+	vecGlass1.assign(vecData.begin(), vecData.begin() + nCutPos);
+	vecGlass2.assign(vecData.begin() + nCutPos, vecData.end());
 
 	int nGlass1Count = static_cast<int>(vecGlass1.size());
 	int nGlass2Count = static_cast<int>(vecGlass2.size());
 
 	// 鏃ュ織杈撳嚭
-	CString strLog;
-	strLog.Format(_T("OUT%d: 鍒囧壊鎴愬姛锛岀涓�鐗囩幓鐠冩暟鎹噺 %d锛岀浜岀墖鐜荤拑鏁版嵁閲� %d銆�"), nOutNo, nGlass1Count, nGlass2Count);
+	strLog.Format(_T("OUT%d: 鍒囧壊鎴愬姛锛岀涓�鐗囩幓鐠� %d 鐐癸紝绗簩鐗囩幓鐠� %d 鐐广��"), nOutNo, nGlass1Count, nGlass2Count);
 	AppendLogLineRichStyled(strLog, LOG_COLOR_SUCCESS);
 
-	if (nGlass1Count < nMinGlass1Count) {
-		strLog.Format(_T("OUT%d: 绗竴鐗囩幓鐠冩暟鎹噺杩囧皯锛屽彲鑳藉奖鍝嶅悗缁鐞嗐��"), nOutNo);
+	if (nGlass1Count < nMinGlassCount) {
+		strLog.Format(_T("OUT%d: 绗竴鐗囩幓鐠冩暟鎹噺灏戜簬 %d 鐐癸紝鍙兘褰卞搷璁$畻銆�"), nOutNo, nMinGlassCount);
 		AppendLogLineRichStyled(strLog, LOG_COLOR_WARNING);
 	}
-	if (nGlass2Count < nMinGlass1Count) {
-		strLog.Format(_T("OUT%d: 绗簩鐗囩幓鐠冩暟鎹噺杩囧皯锛屽彲鑳藉奖鍝嶅悗缁鐞嗐��"), nOutNo);
+
+	if (nGlass2Count < nMinGlassCount) {
+		strLog.Format(_T("OUT%d: 绗簩鐗囩幓鐠冩暟鎹噺灏戜簬 %d 鐐癸紝鍙兘褰卞搷璁$畻銆�"), nOutNo, nMinGlassCount);
 		AppendLogLineRichStyled(strLog, LOG_COLOR_WARNING);
 	}
 
@@ -471,11 +517,61 @@
 	AppendLogLineRichStyled(_T("绗簩鐗囩幓鐠冩暟鎹細"), LOG_COLOR_NORMAL);
 	PrintSampleData(nOutNo, vecGlass2);
 
-	return !vecGlass1.empty() && !vecGlass2.empty();
+	MEASURE_FUNC_END();
+
+	return true;
+}
+
+bool CSGMeasurementDlg::FilterDominantGroup(int nOutNo, const std::vector<float>& vecInput, std::vector<float>& vecOutput)
+{
+	MEASURE_FUNC_START();
+
+	if (vecInput.empty()) {
+		AppendLogLineRichStyled(_T("杈撳叆鏁版嵁涓虹┖锛屾棤娉曡繘琛屽垎缁勭瓫閫夈��"), LOG_COLOR_WARNING);
+		return false;
+	}
+
+	// 鍒嗙粍锛歮ap<int鏁存暟閮ㄥ垎, vector<float>>
+	std::map<int, std::vector<float>> mapGroup;
+	for (float fVal : vecInput) {
+		int nKey = static_cast<int>(fVal);
+		mapGroup[nKey].push_back(fVal);
+	}
+
+	// 鎵惧嚭鏁伴噺鏈�澶氱殑閭g粍
+	size_t nMaxCount = 0;
+	auto itMaxGroup = mapGroup.begin();
+	for (auto it = mapGroup.begin(); it != mapGroup.end(); ++it) {
+		if (it->second.size() > nMaxCount) {
+			nMaxCount = it->second.size();
+			itMaxGroup = it;
+		}
+	}
+
+	if (nMaxCount == 0) {
+		AppendLogLineRichStyled(_T("鎵�鏈夋暟鎹兘琚繃婊ゆ垨涓虹┖锛屾棤娉曠瓫閫夊嚭涓昏鍒嗙粍銆�"), LOG_COLOR_WARNING);
+		return false;
+	}
+
+	vecOutput = itMaxGroup->second;
+
+	CString strLog;
+	strLog.Format(_T("鎴愬姛浠� %d 涓粍涓瓫閫夊嚭涓昏鍒嗙粍锛氬�肩害涓� %d锛屽叡 %zu 涓偣銆�"), static_cast<int>(mapGroup.size()), itMaxGroup->first, nMaxCount);
+	AppendLogLineRichStyled(strLog, LOG_COLOR_SUCCESS);
+
+	// 鎵撳嵃绛涢�夊悗鐨勬暟鎹�
+	AppendLogLineRichStyled(_T("绛涢�夊悗鐨勪富瑕佸垎缁勬暟鎹細"), LOG_COLOR_NORMAL);
+	PrintSampleData(nOutNo, vecOutput);
+
+	MEASURE_FUNC_END();
+
+	return true;
 }
 
 bool CSGMeasurementDlg::ExtractStableRegionFixed(int nOutNo, const std::vector<float>& vecIn, std::vector<float>& vecOut, int nFixedCount/* = 5*/, float fMaxDelta/* = 0.04f*/)
 {
+	MEASURE_FUNC_START();
+
 	const int n = static_cast<int>(vecIn.size());
 	if (n < nFixedCount) {
 		CString strError;
@@ -520,11 +616,15 @@
 	AppendLogLineRichStyled(_T("鎻愬彇鐨勭ǔ瀹氬尯鏁版嵁锛�"), LOG_COLOR_NORMAL);
 	PrintSampleData(nOutNo, vecOut);
 
+	MEASURE_FUNC_END();
+
 	return true;
 }
 
 bool CSGMeasurementDlg::CalcGlassOffset(const std::vector<float>& vecGlass1, const std::vector<float>& vecGlass2, float& fAvg1, float& fAvg2, float& fOffset)
 {
+	MEASURE_FUNC_START();
+
 	if (vecGlass1.empty() || vecGlass2.empty()) {
 		AppendLogLineRichStyled(_T("绋冲畾鍖烘暟鎹负绌猴紝鏃犳硶璁$畻骞冲潎鍊煎拰鍋忕Щ銆�"), LOG_COLOR_WARNING);
 		return false;
@@ -542,6 +642,8 @@
 	CString strLog;
 	strLog.Format(_T("绗竴鐗囩幓鐠冨钩鍧囧��: %.3f锛岀浜岀墖鐜荤拑骞冲潎鍊�: %.3f锛屽亸绉婚噺: %.3f"), fAvg1, fAvg2, fOffset);
 	AppendLogLineRichStyled(strLog, LOG_COLOR_SUCCESS);
+
+	MEASURE_FUNC_END();
 
 	return true;
 }
@@ -612,6 +714,8 @@
 
 float CSGMeasurementDlg::AnalyzeStoredData(int nOutNo)
 {
+	MEASURE_FUNC_START();
+
 	UpdateData(TRUE);
 
 	if (m_nUseTrigger) {
@@ -640,8 +744,6 @@
 		return -1.0f;
 	}
 
-	clock_t startClock = clock();  // 璁板綍寮�濮嬫椂闂�
-
 	std::vector<float> vecBuffer(m_nSavePointCount, 0.0f);
 	int nReceived = 0;
 
@@ -662,9 +764,29 @@
 		return -1.0f;
 	}
 
+	std::vector<float> vecGlass1Filtered, vecGlass2Filtered;
+	bool bGlass1Filtered = FilterDominantGroup(nOutNo, vecGlass1, vecGlass1Filtered);
+	bool bGlass2Filtered = FilterDominantGroup(nOutNo, vecGlass2, vecGlass2Filtered);
+
+	if (!bGlass1Filtered) {
+		AppendLogLineRichStyled(_T("Glass1 鍒嗘涓湭鑳借瘑鍒嚭涓绘暟鎹粍锛屼娇鐢ㄥ師濮嬫暟鎹��"), LOG_COLOR_WARNING);
+		vecGlass1Filtered = vecGlass1;
+	}
+	else {
+		AppendLogLineRichStyled(_T("Glass1 涓绘暟鎹粍宸叉彁鍙栥��"), LOG_COLOR_SUCCESS);
+	}
+
+	if (!bGlass2Filtered) {
+		AppendLogLineRichStyled(_T("Glass2 鍒嗘涓湭鑳借瘑鍒嚭涓绘暟鎹粍锛屼娇鐢ㄥ師濮嬫暟鎹��"), LOG_COLOR_WARNING);
+		vecGlass2Filtered = vecGlass2;
+	}
+	else {
+		AppendLogLineRichStyled(_T("Glass2 涓绘暟鎹粍宸叉彁鍙栥��"), LOG_COLOR_SUCCESS);
+	}
+
 	std::vector<float> vecStable1, vecStable2;
-	bool bStable1 = ExtractStableRegionFixed(nOutNo, vecGlass1, vecStable1, m_nFixedCount, m_fMaxDelta);
-	bool bStable2 = ExtractStableRegionFixed(nOutNo, vecGlass2, vecStable2, m_nFixedCount, m_fMaxDelta);
+	bool bStable1 = ExtractStableRegionFixed(nOutNo, vecGlass1Filtered, vecStable1, m_nFixedCount, m_fMaxDelta);
+	bool bStable2 = ExtractStableRegionFixed(nOutNo, vecGlass2Filtered, vecStable2, m_nFixedCount, m_fMaxDelta);
 
 	float fAvg1 = 0.0f, fAvg2 = 0.0f, fOffset = 0.0f;
 	if (bStable1 && bStable2) {
@@ -676,12 +798,7 @@
 		CalcGlassOffset(vecGlass1, vecGlass2, fAvg1, fAvg2, fOffset);
 	}
 
-	clock_t endClock = clock();  // 璁板綍缁撴潫鏃堕棿
-	double dElapsedMs = 1000.0 * (endClock - startClock) / CLOCKS_PER_SEC;
-
-	CString strElapsed;
-	strElapsed.Format(_T("AnalyzeStoredData 鎵ц鑰楁椂锛�%.1f ms"), dElapsedMs);
-	AppendLogLineRichStyled(strElapsed, LOG_COLOR_SUCCESS);
+	MEASURE_FUNC_END();
 
 	return fOffset;
 }
@@ -829,6 +946,11 @@
 			CString strError;
 			strError.Format(_T("鑾峰彇娴嬮噺鍊煎け璐ワ紝閿欒鐮侊細%#X"), nRet);
 			AppendLogLineRichStyled(strError, LOG_COLOR_ERROR);
+
+			// 鏂紑杩炴帴
+			if (m_bConnected) {
+				DisconnectFromDevice();
+			}
 		}
 	}
 

--
Gitblit v1.9.3