瀏覽代碼

优化探测器逻辑加入超时线程,1.5s未等待后续的的上图消息就认为本次DDR上图结束了!

lwk 1 月之前
父節點
當前提交
bef62fec99

+ 133 - 8
Detector/TiRay/CCOS.Dev.FPD.TiRayDR/Detector_TiRayDR.cpp

@@ -78,6 +78,8 @@ Detector_TiRayDR::Detector_TiRayDR()
 	m_hFPDScanThread{},
 	m_hRadAcquisitionThread{},
 	m_hStatusMonitorThread{},
+	m_hAcquisitionCheckThread{0},
+	m_bAcquisitionCheckThreadRunning{false},
 	m_pRawImgBuffer{},
 	m_pImgBuffer{},
 	m_pZSKKCalib{},
@@ -85,6 +87,9 @@ Detector_TiRayDR::Detector_TiRayDR()
 	m_strSerialNum{},
 	m_strCurrentSessionTimestamp{},
 	m_nSessionFrameCounter{0},
+	m_bIsAcquiring{false},
+	m_bAcquisitionCompleted{false},
+	m_bWaitingForNextExposure{false},
 	m_nImageNum{},
 	m_nDetectorID{},
 	m_nNotifyStatusTimePeriod{},
@@ -524,8 +529,17 @@ bool Detector_TiRayDR::PrepareAcquisition(FPDDeviceTiRay* pDrvDPC)
 	// 生成新的会话时间戳,这次拍摄的所有图片都将使用这个时间戳
 	m_strCurrentSessionTimestamp = generateReadableTimestamp();
 	m_nSessionFrameCounter = 0; // 重置帧计数器
+
+	// 初始化采集状态
+	m_bIsAcquiring = true;
+	m_bAcquisitionCompleted = false;
+	m_bWaitingForNextExposure = false;
+
 	FINFO("New session started with timestamp: {$}", m_strCurrentSessionTimestamp);
 
+	// 启动采集完成检测线程
+	StartAcquisitionCheckThread();
+
 	//m_hRadEvent->SetEvent();
 
 	FINFO("TiRayDR PrepareAcquisition Over");
@@ -1381,6 +1395,96 @@ bool Detector_TiRayDR::CloseStatusMonitor()
 	return true;
 }
 
+// 启动采集完成检测线程
+bool Detector_TiRayDR::StartAcquisitionCheckThread()
+{
+	FINFO("---Start Acquisition Check Thread---");
+
+	if (m_hAcquisitionCheckThread != 0)
+	{
+		FINFO("Acquisition check thread already running");
+		return true;
+	}
+
+	m_bAcquisitionCheckThreadRunning = true;
+	int result = pthread_create(&m_hAcquisitionCheckThread, nullptr, AcquisitionCheckThread, this);
+	if (result != 0)
+	{
+		FERROR("Failed to create acquisition check thread, error: {$}", result);
+		m_bAcquisitionCheckThreadRunning = false;
+		return false;
+	}
+
+	FINFO("Acquisition check thread started successfully");
+	return true;
+}
+
+// 采集完成检测线程函数
+void* Detector_TiRayDR::AcquisitionCheckThread(PVOID pvoid)
+{
+	Detector_TiRayDR* pDetector = (Detector_TiRayDR*)pvoid;
+	FINFO("Enter acquisition check thread");
+
+	const int CHECK_INTERVAL_MS = 100; // 每100ms检查一次
+	const int ACQUISITION_TIMEOUT_MS = 1500; // 1.5秒超时
+
+	while (pDetector->m_bAcquisitionCheckThreadRunning)
+	{
+		// 检查是否在采集中且在等待下一次曝光
+		if (pDetector->m_bIsAcquiring &&
+			pDetector->m_bWaitingForNextExposure &&
+			!pDetector->m_bAcquisitionCompleted)
+		{
+			auto now = std::chrono::steady_clock::now();
+			auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
+				now - pDetector->m_lastExposureEndTime).count();
+
+			if (elapsed > ACQUISITION_TIMEOUT_MS)
+			{
+				// 拍摄完成
+				pDetector->m_bAcquisitionCompleted = true;
+				pDetector->m_bIsAcquiring = false;
+				pDetector->m_bWaitingForNextExposure = false;
+
+				FINFO("=== Acquisition completed (timeout) === Total frames: {$}, Timeout: {$}ms",
+					pDetector->m_nSessionFrameCounter, elapsed);
+
+				// 通知上层采集完成
+				pDetector->StatusFeedback(EVT_STATUS_PANEL, PANEL_XRAY_OFF);
+
+				// 停止检测线程
+				pDetector->m_bAcquisitionCheckThreadRunning = false;
+			}
+		}
+
+		// 休眠100ms
+		usleep(CHECK_INTERVAL_MS * 1000); // usleep参数为微秒
+	}
+
+	FINFO("Leave acquisition check thread");
+	return nullptr;
+}
+
+// 停止采集完成检测线程
+bool Detector_TiRayDR::StopAcquisitionCheckThread()
+{
+	FINFO("---Stop Acquisition Check Thread---");
+
+	if (m_hAcquisitionCheckThread == 0)
+	{
+		return true;
+	}
+
+	m_bAcquisitionCheckThreadRunning = false;
+
+	// 等待线程结束
+	pthread_join(m_hAcquisitionCheckThread, nullptr);
+	m_hAcquisitionCheckThread = 0;
+
+	FINFO("Acquisition check thread stopped");
+	return true;
+}
+
 bool Detector_TiRayDR::CloseDetectorScan()
 {
 	m_hExitEvent->SetEvent();
@@ -2282,7 +2386,6 @@ void Detector_TiRayDR::cleanOldFiles(const std::string& dirPath, const std::stri
 
 void Detector_TiRayDR::handleHardwareSyncImage(Detector_TiRayDR& detector, TiRayVariant argv[])
 {
-	detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON);
 	const size_t rawPixelCount = argv[3].DataLen / sizeof(unsigned short);
 	detector.m_pRawImgBuffer = reinterpret_cast<unsigned short*>(argv[3].DataValue);
 	const size_t rawSize = rawPixelCount * sizeof(unsigned short);
@@ -2335,7 +2438,6 @@ void Detector_TiRayDR::handleHardwareSyncImage(Detector_TiRayDR& detector, TiRay
 
 void Detector_TiRayDR::handleSoftwareSyncImage(Detector_TiRayDR& detector, TiRayVariant argv[])
 {
-	detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON);
 	const size_t rawPixelCount = argv[3].DataLen / sizeof(unsigned short);
 	detector.m_pRawImgBuffer = reinterpret_cast<unsigned short*>(argv[3].DataValue);
 	const size_t rawSize = rawPixelCount * sizeof(unsigned short);
@@ -2387,10 +2489,6 @@ void Detector_TiRayDR::handleSoftwareSyncImage(Detector_TiRayDR& detector, TiRay
 
 void Detector_TiRayDR::handleAedSyncImage(Detector_TiRayDR& detector, TiRayVariant argv[])
 {
-	detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_START_ACQ);
-	detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_XRAY_ON);
-	detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON);
-
     const size_t rawPixelCount = argv[3].DataLen / sizeof(unsigned short);
 	detector.m_pRawImgBuffer = reinterpret_cast<unsigned short*>(argv[3].DataValue);
     const size_t rawSize = rawPixelCount * sizeof(unsigned short);
@@ -2718,6 +2816,7 @@ void Detector_TiRayDR::on_event_callback(int detectorId, TiRayEvent eventType, T
 {
 	auto& detector = *g_pDetector;
 	const std::string funcTag = "[Detector_TiRayDR::on_event_callback] ";
+
 	switch (eventType)
 	{
 	case TiRayEvent::Evt_DetectorConnect:
@@ -2765,14 +2864,40 @@ void Detector_TiRayDR::on_event_callback(int detectorId, TiRayEvent eventType, T
 	}
 	case TiRayEvent::Evt_ExposureStatus:
 	{
-		FINFO("Evt_ExposureStatus:argv {$}, argc {$}", argv[0].IntValue, argc);
+		FINFO("Evt_ExposureStatus: argv {$}, argc {$}", argv[0].IntValue, argc);
+
 		if (argv[0].IntValue == 0)
 		{
+			// argv 0 = 曝光结束(图像接收完成)
 			detector.m_bAEDReady = true;
+
+			// 记录最后一次曝光结束时间,开始等待下一次曝光
+			if (detector.m_bIsAcquiring)
+			{
+				detector.m_lastExposureEndTime = std::chrono::steady_clock::now();
+				detector.m_bWaitingForNextExposure = true;
+				FINFO("Exposure ended, waiting for next exposure or timeout");
+			}
 		}
-		if (argv[0].IntValue == 1)
+		else if (argv[0].IntValue == 1)
 		{
+			// argv 1 = 曝光开始(准备接收图像)
 			detector.m_bAEDReady = false;
+			// 只在第一帧时通知状态变化
+			if (detector.m_nSessionFrameCounter == 0)
+			{
+				detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_START_ACQ);
+				detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_XRAY_ON);
+				detector.StatusFeedback(EVT_STATUS_PANEL, PANEL_XWINDOW_ON);
+			}
+
+			// 收到新的曝光开始,取消等待状态
+			if (detector.m_bIsAcquiring)
+			{
+				detector.m_bWaitingForNextExposure = false;
+				detector.m_bAcquisitionCompleted = false; // 有新的曝光,重置完成标志
+				FINFO("Exposure started, frame counter will be: {$}", detector.m_nSessionFrameCounter + 1);
+			}
 		}
 		break;
 	}

+ 13 - 0
Detector/TiRay/CCOS.Dev.FPD.TiRayDR/Detector_TiRayDR.h

@@ -4,6 +4,7 @@
 #include <fstream>
 #include <variant>
 #include <future>
+#include <chrono>
 #include "ResDataObject.h"
 #include "CCOS.Dev.FPD.TiRayDR.h"
 #include "errors.h"
@@ -347,6 +348,12 @@ private:
 	std::string m_strCurrentSessionTimestamp; //当前拍摄会话的时间戳(同一次拍摄的所有图片共享)
 	int m_nSessionFrameCounter; //当前会话的帧计数器
 
+	// 拍摄完成检测相关
+	std::chrono::steady_clock::time_point m_lastExposureEndTime; // 最后一次曝光结束时间
+	bool m_bIsAcquiring; // 是否正在采集
+	bool m_bAcquisitionCompleted; // 采集是否已完成(用于防止重复通知)
+	bool m_bWaitingForNextExposure; // 是否在等待下一次曝光
+
 	WORD* m_pRawImgBuffer; //原始图
 	WORD* m_pImgBuffer; //裁剪后图像
 
@@ -366,6 +373,9 @@ private:
 
 	pthread_t m_hStatusMonitorThread = 0;
 
+	pthread_t m_hAcquisitionCheckThread = 0; // 采集完成检测线程
+	bool m_bAcquisitionCheckThreadRunning = false; // 检测线程是否在运行
+
 	std::shared_ptr<LinuxEvent> m_hExitRadAcqStatus;
 
 	ModelResolveResult ResolveModelType(const std::string& detectorType);
@@ -378,6 +388,9 @@ private:
 	static void* TiRayStatusMonitorThread(PVOID pvoid);
 	bool StatusMonitor();
 	bool CloseStatusMonitor();
+	bool StartAcquisitionCheckThread();
+	static void* AcquisitionCheckThread(PVOID pvoid);
+	bool StopAcquisitionCheckThread();
 	bool CloseDetectorScan();
 	bool LoadCalibrationFiles(int nCalibrationMode);
 	bool TestError(TiRayError nErrorCode);