|
|
@@ -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;
|
|
|
}
|