浏览代码

修改TiRay探测器代码增加DRR、CF、PF模式

lwk 3 天之前
父节点
当前提交
b986ba9fcf

+ 228 - 59
Detector/TiRay/CCOS.Dev.FPD.TiRayDR/Detector_TiRayDR.cpp

@@ -108,7 +108,8 @@ Detector_TiRayDR::Detector_TiRayDR()
 	m_bIsMultiFrame(false),
 	m_bIpInitialized(false),
 	m_bFirstConnect(true),
-	m_nXWindow(0)
+	m_nXWindow(0),
+	m_bCustomXWindow(false)
 {
 	m_pDPC2PanelID = new map<FPDDeviceTiRay*, int>();
 	m_pPanelID2DPC = new map<int, FPDDeviceTiRay*>();
@@ -351,18 +352,95 @@ bool Detector_TiRayDR::SetExposureTimes(int nTimes)
 		return false;
 	}
 
-	// 检查探测器连接状态
-	if (!m_pStPanelStatus[m_nCurrentPanelID]->bConnectState)
+	// 保存曝光时间参数
+	m_nXWindow = nTimes;
+	m_bCustomXWindow = true;  // 标记为用户自定义设置
+	FINFO("Custom exposure time set to: {$}", m_nXWindow);
+
+	// 如果探测器已连接,立即写入硬件
+	if (m_pStPanelStatus[m_nCurrentPanelID]->bConnectState)
+	{
+		auto err = write_attribute(Attr_PhotoInterval, m_nXWindow);
+		if (err != Err_Success)
+		{
+			FERROR("Failed to write Attr_PhotoInterval to hardware, error code: {$}", err);
+			FWARN("Value saved, will be applied when SetAcqMode is called");
+		}
+		else
+		{
+			FINFO("Attr_PhotoInterval written to hardware successfully: {$}", m_nXWindow);
+		}
+	}
+	else
+	{
+		FINFO("Detector not connected yet, exposure time will be applied when SetAcqMode is called");
+	}
+
+	return true;
+}
+
+/***
+** 加载指定模式的配置参数
+** modeKey: 模式键名 (如 "RAD", "PF", "DDR", "CF")
+** outXWindow: 输出的XWindow值
+** 返回: 成功返回true,失败返回false
+***/
+bool Detector_TiRayDR::LoadModeConfig(const char* modeKey, int& outXWindow)
+{
+	FINFO("Loading config for mode: {$}", modeKey);
+
+	// 检查配置是否存在
+	if (m_ModeConfig["ModeTable"].GetFirstOf(modeKey) == -1)
 	{
-		FERROR("Detector not connected, cannot set exposure times");
+		FERROR("ModeTable does not have '{$}' config", modeKey);
 		return false;
 	}
 
-	// 保存曝光次数参数
-	m_nXWindow = nTimes;
-	FINFO("Exposure times set to: {$}", m_nXWindow);
+	try
+	{
+		// 从配置读取 XWindow
+		int configXWindow = (int)m_ModeConfig["ModeTable"][modeKey]["XWindow"];
 
-	return true;
+		// 判断是否使用用户自定义值
+		if (m_bCustomXWindow)
+		{
+			outXWindow = m_nXWindow;
+			FINFO("{$} mode: Using custom XWindow: {$} (config value: {$})",
+				modeKey, outXWindow, configXWindow);
+		}
+		else
+		{
+			outXWindow = configXWindow;
+			m_nXWindow = outXWindow;  // 更新成员变量
+			FINFO("{$} mode: Using XWindow from config: {$}", modeKey, outXWindow);
+		}
+
+		// 读取其他参数并更新
+		m_nImageWidth = (int)m_ModeConfig["ModeTable"][modeKey]["ImageWidth"];
+		m_nImageHeight = (int)m_ModeConfig["ModeTable"][modeKey]["ImageHeight"];
+		m_nWidthOffset = (int)m_ModeConfig["ModeTable"][modeKey]["WidthOffset"];
+		m_nHeightOffset = (int)m_ModeConfig["ModeTable"][modeKey]["HeightOffset"];
+
+		FINFO("{$} mode config loaded - ImageSize: {$}x{$}, Offset: ({$},{$})",
+			modeKey, m_nImageWidth, m_nImageHeight, m_nWidthOffset, m_nHeightOffset);
+
+		// 重新分配图像缓冲区
+		if (m_pImgBuffer != nullptr)
+		{
+			delete[] m_pImgBuffer;
+			m_pImgBuffer = nullptr;
+		}
+		m_pImgBuffer = new WORD[(size_t)m_nImageWidth * (size_t)m_nImageHeight];
+		FINFO("{$} mode: Reallocated image buffer for {$}x{$}",
+			modeKey, m_nImageWidth, m_nImageHeight);
+
+		return true;
+	}
+	catch (ResDataObjectExption& e)
+	{
+		FERROR("Failed to read {$} mode config: {$}", modeKey, e.what());
+		return false;
+	}
 }
 
 /***
@@ -426,27 +504,26 @@ bool Detector_TiRayDR::SetAcqMode(int nMode)
 		workMode = WorkMode_DDR;
 		m_bIsMultiFrame = true; // 多帧图
 		modeName = "DDR";
-		nXWindow = 800;
+
+		// 从配置加载DDR模式参数
+		if (!LoadModeConfig("DDR", nXWindow))
+		{
+			FERROR("Failed to load DDR mode config");
+			return false;
+		}
 	}
 	else if (nMode == AcqMode::PF)
 	{
-		workMode = WorkMode_SyncIn;
-		m_bIsMultiFrame = true; // 多帧图
+		workMode = WorkMode_SyncIn;  // 硬件同步输入
+		m_bIsMultiFrame = true;  // 多帧模式
 		modeName = "PF";
 
-		// PF模式下,优先使用SetExposureTimes设置的值,若未设置则使用配置值
-		if (m_nXWindow > 0)
-		{
-			nXWindow = m_nXWindow;
-			FINFO("PF mode: Using custom exposure times from SetExposureTimes: {$}", nXWindow);
-		}
-		else
+		// 从配置加载PF模式参数
+		if (!LoadModeConfig("PF", nXWindow))
 		{
-			FWARN("PF mode: m_nXWindow not set, using config value: {$}", nXWindow);
+			FERROR("Failed to load PF mode config");
+			return false;
 		}
-		//auto err = write_attribute(Attr_PhotoNumber, 8);
-		//if (err != Err_Success)
-			//FERROR("[Detector_TiRayDR::OpenDetector] Failed to write Attr_PhotoNumber. Error code: {$}", err);
 	}
 	else if (nMode == AcqMode::CF)
 	{
@@ -454,19 +531,34 @@ bool Detector_TiRayDR::SetAcqMode(int nMode)
 		m_bIsMultiFrame = true; // 多帧图
 		modeName = "CF";
 
-		// PF模式下,优先使用SetExposureTimes设置的值,若未设置则使用配置值
-		if (m_nXWindow > 0)
+		// 从配置加载CF模式参数
+		if (!LoadModeConfig("CF", nXWindow))
 		{
-			nXWindow = m_nXWindow;
-			FINFO("CF mode: Using custom exposure times from SetExposureTimes: {$}", nXWindow);
+			FERROR("Failed to load CF mode config");
+			return false;
 		}
-		else
+
+		// 读取并设置PhotoNumber
+		try
 		{
-			FWARN("CF mode: m_nXWindow not set, using config value: {$}", nXWindow);
+			int photoNumber = (int)m_ModeConfig["ModeTable"]["CF"]["PhotoNumber"];
+			FINFO("CF mode: Using PhotoNumber from config: {$}", photoNumber);
+
+			auto err = write_attribute(Attr_PhotoNumber, photoNumber);
+			if (err != Err_Success)
+			{
+				FERROR("CF mode: Failed to write Attr_PhotoNumber ({$}), error code: {$}", photoNumber, err);
+			}
+			else
+			{
+				FINFO("CF mode: Attr_PhotoNumber set to {$} successfully", photoNumber);
+			}
+		}
+		catch (ResDataObjectExption& e)
+		{
+			FERROR("Failed to read PhotoNumber from CF config: {$}", e.what());
+			return false;
 		}
-		auto err = write_attribute(Attr_PhotoNumber, 8);
-		if (err != Err_Success)
-			FERROR("[Detector_TiRayDR::OpenDetector] Failed to write Attr_PhotoNumber. Error code: {$}", err);
 	}
 	else
 	{
@@ -1199,12 +1291,12 @@ bool Detector_TiRayDR::OpenDetector()
 	FINFO("Configuration parameters loaded - Wired IP:{$}, Wireless IP:{$}, Local IP:{$}",
 		m_strWiredIP, m_strWirelessIP, m_strLocalIP);
 	FINFO("WiredIP: {$}, LocalIP: {$}, WirelessIP: {$}, SerialNumber:{$}", m_strWiredIP, m_strLocalIP, m_strWirelessIP, m_strSerialNum);
-	// 检查连接状态
-	bool wired = CheckConnect(m_strWiredIP);
-	bool wireless = CheckConnect(m_strWirelessIP);
-	FINFO("[Detector_TiRayDR::OpenDetector] Connection status - Wired:{$}, wireless:{$}",
-		wired ? "Connected" : "Not connected",
-		wireless ? "Connected" : "Not Connected");
+	//// 检查连接状态
+	//bool wired = CheckConnect(m_strWiredIP);
+	//bool wireless = CheckConnect(m_strWirelessIP);
+	//FINFO("[Detector_TiRayDR::OpenDetector] Connection status - Wired:{$}, wireless:{$}",
+	//	wired ? "Connected" : "Not connected",
+	//	wireless ? "Connected" : "Not Connected");
 
 	FINFO("[Detector_TiRayDR::OpenDetector] Start scanning the detector...");
 	std::vector<scan_result> scan_results;
@@ -1323,45 +1415,122 @@ bool Detector_TiRayDR::OpenDetector()
 	{
 		m_bUseGainV2 = true;
 	}
-	m_nImageWidth = (int)m_ModeConfig["ModeTable"][0]["ImageWidth"];
-	m_nImageHeight = (int)m_ModeConfig["ModeTable"][0]["ImageHeight"];
-	m_nRawImgWidth = (int)m_ModeConfig["ModeTable"][0]["RawImgWidth"];
-	m_nRawImgHeight = (int)m_ModeConfig["ModeTable"][0]["RawImgHeight"];
-	FINFO("After crop image width: {$}, height: {$}, WidthOffset: {$}, HeightOffset: {$}", m_nImageWidth, m_nImageHeight, m_nWidthOffset, m_nHeightOffset);
 
-	m_bSaveRaw = (int)m_ModeConfig["ModeTable"][0]["IsSaveRaw"];
+	// 读取当前采集模式
+	std::string modeKey = (std::string)m_ModeConfig["AcqMode"];
+	FINFO("OpenDetector - AcqMode from config: {$}", modeKey);
+
+	// 检查 ModeTable 中是否存在该模式的配置
+	if (m_ModeConfig["ModeTable"].GetFirstOf(modeKey.c_str()) == -1)
+	{
+		FWARN("ModeTable does not have '{$}' config, fallback to RAD", modeKey);
+		modeKey = "RAD";
+	}
+
+	int syncMode = 3;  // 默认 AED 同步模式
+
+	// 从配置读取同步模式
+	try
+	{
+		syncMode = (int)m_ModeConfig["ModeTable"][modeKey.c_str()]["SyncType"];
 
+		// 根据同步模式类型输出日志
+		const char* syncModeStr = "Unknown";
+		switch (syncMode)
+		{
+		case 0: syncModeStr = "SYNC_MANUAL"; break;
+		case 1: syncModeStr = "SYNC_SOFTWARE"; break;
+		case 2: syncModeStr = "SYNC_HARDWARE"; break;
+		case 3: syncModeStr = "SYNC_AED"; break;
+		case 4: syncModeStr = "SYNC_HARDWARE_DIRECT"; break;
+		}
+		FINFO("Mode: {$} - Using sync mode {$} ({$})", modeKey, syncMode, syncModeStr);
+	}
+	catch (ResDataObjectExption& e)
+	{
+		FWARN("Failed to read SyncType from config for mode '{$}': {$}, using default", modeKey, e.what());
+		// 兜底逻辑:根据模式设置默认同步模式
+		if (modeKey == "RAD")
+		{
+			syncMode = 3;  // AED 同步
+		}
+		else
+		{
+			syncMode = 2;  // 硬件同步(带同步盒)
+		}
+		FINFO("Using fallback sync mode: {$}", syncMode);
+	}
+
+	// 从对应模式配置中读取参数
+	try
+	{
+		m_nImageWidth = (int)m_ModeConfig["ModeTable"][modeKey.c_str()]["ImageWidth"];
+		m_nImageHeight = (int)m_ModeConfig["ModeTable"][modeKey.c_str()]["ImageHeight"];
+		m_nWidthOffset = (int)m_ModeConfig["ModeTable"][modeKey.c_str()]["WidthOffset"];
+		m_nHeightOffset = (int)m_ModeConfig["ModeTable"][modeKey.c_str()]["HeightOffset"];
+		m_nRawImgWidth = (int)m_ModeConfig["ModeTable"][modeKey.c_str()]["RawImgWidth"];
+		m_nRawImgHeight = (int)m_ModeConfig["ModeTable"][modeKey.c_str()]["RawImgHeight"];
+		m_bSaveRaw = (int)m_ModeConfig["ModeTable"][modeKey.c_str()]["IsSaveRaw"];
+		m_nXWindow = (int)m_ModeConfig["ModeTable"][modeKey.c_str()]["XWindow"];
+
+		FINFO("Loaded config for mode '{$}' - ImageSize: {$}x{$}, RawSize: {$}x{$}, Offset: ({$},{$}), XWindow: {$}, SaveRaw: {$}",
+			modeKey, m_nImageWidth, m_nImageHeight, m_nRawImgWidth, m_nRawImgHeight,
+			m_nWidthOffset, m_nHeightOffset, m_nXWindow, m_bSaveRaw);
+	}
+	catch (ResDataObjectExption& e)
+	{
+		FERROR("Failed to load ModeTable config for '{$}': {$}", modeKey, e.what());
+		return false;
+	}
+
+	// 分配图像缓冲区
 	if (m_pRawImgBuffer == nullptr)
 	{
 		m_pRawImgBuffer = new WORD[(size_t)m_nRawImgHeight * (size_t)m_nRawImgWidth];
+		FINFO("Allocated raw image buffer: {$}x{$}", m_nRawImgWidth, m_nRawImgHeight);
 	}
-	if (true)
+
+	if (m_pImgBuffer == nullptr)
 	{
-		m_pImgBuffer = new WORD[(size_t)m_nImageWidth * (size_t)m_nImageWidth];
+		m_pImgBuffer = new WORD[(size_t)m_nImageWidth * (size_t)m_nImageHeight];
+		FINFO("Allocated processed image buffer: {$}x{$}", m_nImageWidth, m_nImageHeight);
 	}
 
-	// 加载校准文件
-	SetSyncMode(3);
+	// 设置同步模式
+	SetSyncMode(syncMode);
 
-	// 从配置读取敏感度和曝光间隔参数
-	int nSensitivity = (int)m_ModeConfig["ModeTable"][0]["Sensitivity"];
-	int nXWindow = m_nXWindow = (int)m_ModeConfig["ModeTable"][0]["XWindow"];
-	FINFO("Initialize XWindow from config: {$}", m_nXWindow);
+	// 从配置读取敏感度参数
+	int nSensitivity = (int)m_ModeConfig["ModeTable"][modeKey.c_str()]["Sensitivity"];
+	FINFO("Initialize parameters - XWindow: {$}, Sensitivity: {$}", m_nXWindow, nSensitivity);
 
 	// 设置曝光间隔到硬件
-	err = write_attribute(Attr_PhotoInterval, nXWindow);
+	err = write_attribute(Attr_PhotoInterval, m_nXWindow);
 	if (err != Err_Success)
 	{
 		FERROR("Failed to write Attr_PhotoInterval. Error code: {$}", err);
 	}
 	else
 	{
-		FINFO("Successfully set Attr_PhotoInterval to: {$}", nXWindow);
+		FINFO("Successfully set Attr_PhotoInterval to: {$}", m_nXWindow);
 	}
 
-	err = write_attribute(Attr_PhotoNumber, 1);
+	// 设置拍摄张数(CF 模式需要设置)
+	int nPhotoNumber = 1;  // 默认单张
+	if (modeKey == "CF")
+	{
+		nPhotoNumber = (int)m_ModeConfig["ModeTable"][modeKey.c_str()]["PhotoNumber"];
+		FINFO("CF mode: Setting PhotoNumber to {$}", nPhotoNumber);
+	}
+
+	err = write_attribute(Attr_PhotoNumber, nPhotoNumber);
 	if (err != Err_Success)
-		FINFO("[Detector_TiRayDR::OpenDetector] Failed to write Attr_PhotoNumber. Error code: {$}", err);
+	{
+		FWARN("[Detector_TiRayDR::OpenDetector] Failed to write Attr_PhotoNumber. Error code: {$}", err);
+	}
+	else
+	{
+		FINFO("[Detector_TiRayDR::OpenDetector] Successfully set Attr_PhotoNumber to: {$}", nPhotoNumber);
+	}
 
 	LoadCalibrationFile(4);
 
@@ -2123,7 +2292,7 @@ static std::string generateReadableTimestamp()
 	GlobalTime currentTime = { 0 };
 	GetLocalTime(&currentTime);
 
-	char timestamp[32];
+	char timestamp[64];
 	snprintf(timestamp, sizeof(timestamp), "%04d%02d%02d_%02d%02d%02d_%03d",
 		currentTime.wYear, currentTime.wMonth, currentTime.wDay,
 		currentTime.wHour, currentTime.wMinute, currentTime.wSecond,
@@ -2514,7 +2683,7 @@ void Detector_TiRayDR::handleHardwareSyncImage(Detector_TiRayDR& detector, TiRay
 
 	// 使用会话时间戳 + 帧号生成文件名
 	detector.m_nSessionFrameCounter++;
-	char frameStr[16];
+	char frameStr[32];
 	snprintf(frameStr, sizeof(frameStr), "_frame%03d", detector.m_nSessionFrameCounter);
 	const std::string baseTimestamp = detector.m_strCurrentSessionTimestamp + std::string(frameStr);
 
@@ -2570,7 +2739,7 @@ void Detector_TiRayDR::handleSoftwareSyncImage(Detector_TiRayDR& detector, TiRay
 
 	// 使用会话时间戳 + 帧号生成文件名
 	detector.m_nSessionFrameCounter++;
-	char frameStr[16];
+	char frameStr[32];
 	snprintf(frameStr, sizeof(frameStr), "_frame%03d", detector.m_nSessionFrameCounter);
 	const std::string baseTimestamp = detector.m_strCurrentSessionTimestamp + std::string(frameStr);
 
@@ -2626,7 +2795,7 @@ void Detector_TiRayDR::handleAedSyncImage(Detector_TiRayDR& detector, TiRayVaria
 
 	// 使用会话时间戳 + 帧号生成文件名
 	detector.m_nSessionFrameCounter++;
-	char frameStr[16];
+	char frameStr[32];
 	snprintf(frameStr, sizeof(frameStr), "_frame%03d", detector.m_nSessionFrameCounter);
 	const std::string baseTimestamp = detector.m_strCurrentSessionTimestamp + std::string(frameStr);
 

+ 2 - 78
Detector/TiRay/CCOS.Dev.FPD.TiRayDR/Detector_TiRayDR.h

@@ -164,84 +164,6 @@ public:
 		return err;
 	}
 
-	//template<typename T>
-	//std::tuple<TiRayError, T> read_attribute(TiRayAttribute attribute, std::chrono::seconds timeout = std::chrono::seconds(2)) {
-	//	TiRayVariant param[1]{};
-	//	param[0].Type = TiRayVariant::TiRayInt;
-	//	param[0].IntValue = attribute;
-
-	//	// 执行命令
-	//	auto err = Execute(m_nDetectorID, Cmd_ReadAttribute, param, 1);
-	//	if (err != Err_Success) {
-	//		return { err, {} };
-	//	}
-
-	//	// 处理event_params类型(实际是std::vector<event_param>)
-	//	if constexpr (std::is_same_v<T, event_params>) {
-	//		event_params result;
-
-	//		// 根据参数类型构造对应的event_param并添加到vector中
-	//		switch (param[0].Type) {
-	//		case TiRayVariant::TiRayInt:
-	//			result.emplace_back(param[0].IntValue);
-	//			break;
-	//		case TiRayVariant::TiRayInt64:
-	//			result.emplace_back(param[0].Int64Value);
-	//			break;
-	//		case TiRayVariant::TiRayFloat:
-	//			result.emplace_back(param[0].FloatValue);
-	//			break;
-	//		case TiRayVariant::TiRayBuffer:
-	//			result.emplace_back(std::string(param[0].DataValue, param[0].DataLen));
-	//			break;
-	//		}
-
-	//		return { Err_Success, std::move(result) };
-	//	}
-	//	else {
-	//		T result;
-	//		bool typeMismatch = false;
-
-	//		// 根据参数类型和目标类型进行转换
-	//		if constexpr (std::is_integral_v<T> && sizeof(T) <= 4 || std::is_enum_v<T>) {
-	//			if (param[0].Type == TiRayVariant::TiRayInt) {
-	//				result = static_cast<T>(param[0].IntValue);
-	//			}
-	//			else {
-	//				typeMismatch = true;
-	//			}
-	//		}
-	//		else if constexpr (std::is_integral_v<T> && sizeof(T) > 4) {
-	//			if (param[0].Type == TiRayVariant::TiRayInt64) {
-	//				result = static_cast<T>(param[0].Int64Value);
-	//			}
-	//			else {
-	//				typeMismatch = true;
-	//			}
-	//		}
-	//		else if constexpr (std::is_floating_point_v<T>) {
-	//			if (param[0].Type == TiRayVariant::TiRayFloat) {
-	//				result = static_cast<T>(param[0].FloatValue);
-	//			}
-	//			else {
-	//				typeMismatch = true;
-	//			}
-	//		}
-	//		else {
-	//			// 处理其他类型(如自定义类型)
-	//			typeMismatch = true;
-	//		}
-
-	//		if (typeMismatch) {
-	//			return { err, {} };  // 假设存在类型不匹配的错误码
-	//		}
-
-	//		return { Err_Success, result };
-	//	}
-	//}
-
-
-
 	template<typename T>
 	TiRayError write_attribute(TiRayAttribute attribute, T value, std::chrono::seconds timeout = std::chrono::seconds(2)) {
 		std::cout << "--TiRay Function-- write_attribute Start" << std::endl;
@@ -335,6 +257,7 @@ private:
 	bool m_bFirstConnect;            // IP设置进行中标志
 
 	int m_nXWindow;                  // 曝光间隔时间(PhotoInterval),用于PF模式等多帧采集
+	bool m_bCustomXWindow;           // 标记m_nXWindow是否由SetExposureTimes设置
 
 	bool m_bSaveRaw;
 	bool m_bConnected;
@@ -385,6 +308,7 @@ private:
 	std::shared_ptr<LinuxEvent> m_hExitRadAcqStatus;
 
 	ModelResolveResult ResolveModelType(const std::string& detectorType);
+	bool LoadModeConfig(const char* modeKey, int& outXWindow);
 
 	bool LoadDll(string strWorkPath);
 	bool ReleaseDll();