# X 射线源模块使用指南 | X-Ray Source Module Usage Guide ## 1. 模块概述 | Module Overview XP.Hardware.RaySource 是 XplorePlane X 射线检测系统的核心硬件控制模块,负责与工业 X 射线源设备进行通讯和控制。该模块采用策略模式设计,通过 Named Pipe IPC 进程隔离架构与 .NET Framework 4.8 Host 子进程通信,支持多种 X 射线源型号的统一管理。 ### 核心特性 | Key Features - 支持多种 X 射线源型号(当前支持 Comet 225kV) - 基于 Named Pipe IPC 的进程隔离架构(.NET 8 ↔ .NET Framework 4.8) - 完整的设备生命周期管理(初始化、连接变量、暖机、训机、灯丝校准、自动定心、开关射线) - 电压电流精确控制(20-225kV / 10-1000μA) - TXI 开关控制、功率模式切换(Micro Focus / High Power) - 实时状态监控和错误检测 - 灯丝寿命管理(使用时长记录、累计统计、预警提醒) - 基于 Prism 事件聚合器的松耦合通讯 - 安全机制:紧急关闭优先级、参数范围验证、双重检查锁定 --- ## 2. 模块注册 | Module Registration X 射线源模块已通过 Prism 的模块化系统注册,在应用启动时自动加载。 ### 在 App.xaml.cs 中注册 ```csharp using Prism.Modularity; using XP.Hardware.RaySource.Module; protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog) { // 注册 X 射线源模块 | Register X-Ray Source module moduleCatalog.AddModule(); base.ConfigureModuleCatalog(moduleCatalog); } ``` ### 模块自动注册的服务 | 服务 | 类型 | 生命周期 | 说明 | |------|------|----------|------| | `RaySourceConfig` | 实例 | 单例 | 配置对象(从 App.config 加载) | | `IRaySourceFactory` → `RaySourceFactory` | 接口→实现 | 单例 | 射线源工厂 | | `IRaySourceService` → `RaySourceService` | 接口→实现 | 单例 | 射线源业务服务 | | `IFilamentLifetimeService` → `FilamentLifetimeService` | 接口→实现 | 单例 | 灯丝寿命管理服务 | ### 模块初始化行为 模块 `OnInitialized` 时会自动执行: 1. 初始化灯丝寿命服务(建表、异常恢复、重算累计寿命) 2. 检查灯丝寿命预警(≥90% 弹出模态对话框) --- ## 3. 配置文件设置 | Configuration File Setup 在 `App.config` 中添加 X 射线源配置: ```xml ``` --- ## 4. 在 ViewModel 中使用 | Usage in ViewModel ### 4.1 注入服务 ```csharp using Prism.Commands; using Prism.Events; using Prism.Mvvm; using XP.Common.Logging.Interfaces; using XP.Hardware.RaySource.Abstractions; using XP.Hardware.RaySource.Abstractions.Enums; using XP.Hardware.RaySource.Abstractions.Events; using XP.Hardware.RaySource.Config; using XP.Hardware.RaySource.Services; namespace YourNamespace.ViewModels { public class YourViewModel : BindableBase { private readonly IRaySourceService _raySourceService; private readonly IEventAggregator _eventAggregator; private readonly ILoggerService _logger; public YourViewModel( IRaySourceService raySourceService, IEventAggregator eventAggregator, ILoggerService logger) { _raySourceService = raySourceService; _eventAggregator = eventAggregator; _logger = logger.ForModule("YourViewModel"); // 订阅事件 | Subscribe to events SubscribeEvents(); } private void SubscribeEvents() { _eventAggregator.GetEvent() .Subscribe(OnRaySourceStatusChanged, ThreadOption.UIThread); _eventAggregator.GetEvent() .Subscribe(OnStatusUpdated, ThreadOption.UIThread); _eventAggregator.GetEvent() .Subscribe(OnErrorOccurred, ThreadOption.UIThread); _eventAggregator.GetEvent() .Subscribe(OnOperationResult, ThreadOption.UIThread); _eventAggregator.GetEvent() .Subscribe(OnVariablesConnected, ThreadOption.UIThread); } private void OnRaySourceStatusChanged(RaySourceStatus newStatus) { _logger.Info("射线源状态变化: {Status}", newStatus); } private void OnStatusUpdated(SystemStatusData data) { _logger.Debug("状态更新: 电压={Voltage}kV, 电流={Current}μA", data.ActualVoltage, data.ActualCurrent); } private void OnErrorOccurred(string errorMessage) { _logger.Error(null, "错误发生: {Error}", errorMessage); } private void OnOperationResult(OperationResultData data) { _logger.Info("操作 {Op} {Result}: {Msg}", data.OperationName, data.IsSuccess ? "成功" : "失败", data.Message); } private void OnVariablesConnected(bool isConnected) { _logger.Info("变量连接状态: {Connected}", isConnected); } } } ``` ### 4.2 初始化射线源 ```csharp // 方式一:分步初始化 | Step-by-step initialization public void InitializeRaySource() { // 步骤1:初始化(启动 Host 进程,建立 IPC 连接) XRayResult result = _raySourceService.Initialize(); if (!result.Success) { _logger.Error(null, "初始化失败: {Error}", result.ErrorMessage); return; } // 步骤2:连接变量(创建和激活 PVI 变量) XRayResult connectResult = _raySourceService.ConnectVariables(); if (!connectResult.Success) { _logger.Error(null, "连接变量失败: {Error}", connectResult.ErrorMessage); } } // 方式二:异步一键初始化 | Async one-step initialization public async Task AutoInitializeAsync() { XRayResult result = await _raySourceService.InitializeAndConnectAsync(); if (result.Success) { _logger.Info("自动初始化完成"); } } ``` ### 4.3 开启/关闭射线 ```csharp // 开启射线 | Turn on X-ray public void TurnOnXRay() { if (!_raySourceService.IsInitialized || !_raySourceService.IsConnected) { _logger.Warn("射线源未就绪"); return; } XRayResult result = _raySourceService.TurnOn(); if (result.Success) { _logger.Info("射线已开启"); } } // 关闭射线 | Turn off X-ray public void TurnOffXRay() { XRayResult result = _raySourceService.TurnOff(); if (result.Success) { _logger.Info("射线已关闭"); } } // 紧急关闭(最高优先级,任何状态下可执行)| Emergency shutdown public void EmergencyShutdown() { _raySourceService.EmergencyShutdown(); } // 断开连接(保留实例以便重连)| Disconnect public void Disconnect() { _raySourceService.Disconnect(); } ``` --- ## 5. 电压电流控制 | Voltage and Current Control ```csharp // 设置电压(范围由配置文件定义,默认 20-225kV) XRayResult result = _raySourceService.SetVoltage(100f); // 设置电流(范围由配置文件定义,默认 10-1000μA) XRayResult result = _raySourceService.SetCurrent(500f); // 读取实际电压 XRayResult voltageResult = _raySourceService.ReadVoltage(); if (voltageResult.Success) { float voltage = voltageResult.GetFloat(); } // 读取实际电流 XRayResult currentResult = _raySourceService.ReadCurrent(); if (currentResult.Success) { float current = currentResult.GetFloat(); } ``` --- ## 6. 设备操作 | Device Operations ```csharp // TXI 开启/关闭 _raySourceService.TxiOn(); _raySourceService.TxiOff(); // 暖机 _raySourceService.WarmUp(); // 训机 _raySourceService.Training(); // 灯丝校准 _raySourceService.FilamentCalibration(); // 全部电压自动定心 _raySourceService.AutoCenter(); // 设置功率模式(1=Micro Focus,2=High Power) _raySourceService.SetPowerMode(1); // 微焦点模式 _raySourceService.SetPowerMode(2); // 高功率模式 ``` 注意:TXI、暖机、训机、灯丝校准、自动定心、功率模式切换等操作需要射线源已连接变量(`IsConnected == true`)。 --- ## 7. 状态监控和错误处理 | Status Monitoring and Error Handling ### 7.1 读取系统状态 ```csharp XRayResult result = _raySourceService.ReadSystemStatus(); if (result.Success && result.Data is SystemStatusData statusData) { // statusData 包含全量状态信息: // - SetVoltage / ActualVoltage(设定/实际电压) // - SetCurrent / ActualCurrent(设定/实际电流) // - IsXRayOn(射线开启状态) // - WarmUpStatus / VacuumStatus / StartUpStatus(暖机/真空/启动状态) // - AutoCenterStatus / FilamentAdjustStatus(自动定心/灯丝调整状态) // - IsInterlockActive(连锁状态) // - WatchdogStatus / PowerMode / TxiStatus(看门狗/功率模式/TXI状态) } ``` ### 7.2 检查和清除错误 ```csharp // 检查错误 XRayResult errorResult = _raySourceService.CheckErrors(); // 清除错误 XRayResult clearResult = _raySourceService.ClearErrors(); ``` ### 7.3 状态属性 ```csharp bool isInitialized = _raySourceService.IsInitialized; // 是否已初始化 bool isConnected = _raySourceService.IsConnected; // PVI 变量是否已连接 bool isXRayOn = _raySourceService.IsXRayOn; // 射线是否开启 RaySourceStatus status = _raySourceService.CurrentStatus; // 当前状态(三态) ``` --- ## 8. Prism 事件通讯 | Prism Event Communication 模块使用 Prism 事件聚合器实现跨模块通讯,支持以下事件: ### 8.1 射线源状态变化事件 ```csharp _eventAggregator.GetEvent() .Subscribe(OnRaySourceStatusChanged, ThreadOption.UIThread); private void OnRaySourceStatusChanged(RaySourceStatus newStatus) { // newStatus: Unavailable(-1) / Closed(0) / Opened(1) switch (newStatus) { case RaySourceStatus.Unavailable: // 射线源不可用(未初始化或连接丢失) break; case RaySourceStatus.Closed: // 射线源已连接,射线关闭 break; case RaySourceStatus.Opened: // 射线源已连接,射线开启 break; } } ``` ### 8.2 系统状态更新事件 ```csharp _eventAggregator.GetEvent() .Subscribe(OnStatusUpdated, ThreadOption.UIThread); private void OnStatusUpdated(SystemStatusData data) { // 全量状态数据,由 Host 进程定期推送 float actualVoltage = data.ActualVoltage; float actualCurrent = data.ActualCurrent; bool isXRayOn = data.IsXRayOn; string warmUpStatus = data.WarmUpStatus; // ... 更多字段见 SystemStatusData 定义 } ``` ### 8.3 错误事件 ```csharp _eventAggregator.GetEvent() .Subscribe(OnErrorOccurred, ThreadOption.UIThread); private void OnErrorOccurred(string errorMessage) { _logger.Error(null, "射线源错误: {Error}", errorMessage); } ``` ### 8.4 操作结果事件 ```csharp _eventAggregator.GetEvent() .Subscribe(OnOperationResult, ThreadOption.UIThread); private void OnOperationResult(OperationResultData data) { // data.OperationName - 操作名称 // data.IsSuccess - 是否成功 // data.Message - 结果消息 } ``` ### 8.5 PVI 变量连接状态事件 ```csharp _eventAggregator.GetEvent() .Subscribe(OnVariablesConnected, ThreadOption.UIThread); private void OnVariablesConnected(bool isConnected) { // true = PVI 变量已连接,射线源准备就绪 // false = PVI 变量已断开 } ``` --- ## 9. 灯丝寿命管理 | Filament Lifetime Management ### 9.1 自动联动 灯丝寿命管理与射线源开关自动联动: - 射线源开启(TurnOn)→ 自动开始记录灯丝使用时长 - 射线源关闭(TurnOff / Disconnect / EmergencyShutdown)→ 自动停止记录并累加统计 - 异常断联 → 下次初始化时自动恢复未关闭的记录 ### 9.2 手动查询 ```csharp // 获取实时累计使用秒数(含当前运行时长) double totalSeconds = _filamentLifetimeService.GetCurrentTotalLifeSeconds(); // 获取寿命百分比(0-100) double percentage = _filamentLifetimeService.GetLifetimePercentage(); // 获取阈值秒数 double thresholdSeconds = _filamentLifetimeService.GetThresholdSeconds(); // 检查是否需要预警(≥90%) bool shouldWarn = _filamentLifetimeService.ShouldShowLifetimeWarning(); ``` ### 9.3 数据持久化 灯丝寿命数据通过 SQLite 持久化,包含两张表: - `RaySourceFilamentLifetimeStatistics`:累计统计表(按序列号唯一) - `RaySourceFilamentUsageLogs`:使用流水表(每次开关记录一条) --- ## 10. 在应用退出时释放资源 | Release Resources on Application Exit ```csharp protected override void OnExit(ExitEventArgs e) { Log.Information("XplorePlane 主应用退出"); // 释放射线源资源 | Release X-ray source resources try { var raySourceService = Container.Resolve(); raySourceService?.Dispose(); Log.Information("射线源资源已成功释放"); } catch (Exception ex) { Log.Error(ex, "射线源资源释放失败,忽略该错误继续退出"); } Log.CloseAndFlush(); base.OnExit(e); } ``` --- ## 11. 安全机制 | Safety Mechanisms ### 11.1 参数范围验证 ```csharp // 服务层自动校验参数范围,超出范围返回错误结果 XRayResult result = _raySourceService.SetVoltage(300f); // 超出 225kV 上限 // result.Success == false // result.ErrorMessage == "电压参数超出范围:20-225kV" ``` ### 11.2 紧急关闭优先级 紧急关闭具有最高优先级,可以在任何状态下执行: ```csharp // 紧急关闭:依次关闭射线 → 完全关闭设备 → 状态重置为 Unavailable _raySourceService.EmergencyShutdown(); ``` ### 11.3 业务规则校验 - 未初始化禁止操作(所有操作前检查 `IsInitialized`) - 防重复开启/关闭(双重检查锁定模式) - 异常断联自动检测(状态变为 Unavailable 时重置标志位) ### 11.4 实时调节支持 连接射线源后,无论射线是否开启,都可以实时调节电压和电流。 --- ## 12. 异常处理 | Exception Handling ### 12.1 XRayResult 结果处理 所有操作返回 `XRayResult` 对象: ```csharp XRayResult result = _raySourceService.TurnOn(); if (result.Success) { var data = result.Data; // 获取返回数据 } else { string error = result.ErrorMessage; // 获取错误消息 _logger.Error(null, "操作失败: {Error}", error); } ``` ### 12.2 IPC 通信异常 当 Host 进程崩溃或管道断开时: - `CometIpcClient` 设置 `_isPipeConnected = false`,阻止后续命令发送 - 返回 `null` 响应,服务层转换为错误结果 - 推送 `Disconnected` 状态,触发 UI 更新 --- ## 13. 日志记录 | Logging 模块使用 `ILoggerService` 进行结构化日志记录: ```csharp // 各层日志模块名称 _logger = logger.ForModule("RaySource.Service"); // 服务层 _logger = logger.ForModule("RaySource.Factory"); // 工厂层 _logger = logger.ForModule(); // 适配器层 _logger = logger.ForModule(); // IPC 客户端 _logger = logger.ForModule(); // Host 管理器 _logger = logger.ForModule("RaySource.ViewModel"); // 操作视图模型 _logger = logger.ForModule("RaySource.ConfigVM"); // 配置视图模型 _logger = logger.ForModule(); // 灯丝寿命服务 ``` ### 日志级别 - **Debug**: 详细调试信息(IPC 消息收发、电压电流读取等) - **Info**: 一般信息(初始化成功、射线开启、状态变更等) - **Warn**: 警告信息(参数超出范围、重复操作、异常恢复等) - **Error**: 错误信息(操作失败、通讯异常、IPC 超时等) - **Fatal**: 致命错误(系统崩溃等) --- ## 14. 故障排查 | Troubleshooting ### 14.1 初始化失败 **可能原因**: - Host 可执行文件未找到(检查 `{主程序目录}/Host/XP.Hardware.RaySource.Comet.Host.exe`) - PLC IP 地址或端口配置错误 - PLC 未启动或网络不通 - Named Pipe 连接超时 - 残留的 Host 进程未清理 **解决方案**: 1. 确认 Host 可执行文件和 BR.AN.PviServices.dll 已正确部署 2. 检查 `App.config` 中的 PLC 连接参数 3. 使用 `ping` 命令测试 PLC 网络连接 4. 查看日志中 Host 进程 PID 和管道连接状态 5. 手动终止残留的 `XP.Hardware.RaySource.Comet.Host.exe` 进程 ### 14.2 射线无法开启 **可能原因**: - 射线源未初始化或变量未连接 - 设备处于错误状态 - 互锁信号未满足 **解决方案**: 1. 确认 `IsInitialized == true` 且 `IsConnected == true` 2. 调用 `CheckErrors()` 检查错误状态 3. 检查设备互锁信号 ### 14.3 电压电流设置失败 **可能原因**: - 参数超出配置范围 - 射线源未初始化 - IPC 管道已断开 **解决方案**: 1. 验证参数在有效范围内 2. 检查 `IsInitialized` 状态 3. 查看日志中 IPC 通信状态 ### 14.4 Host 进程异常退出 **可能原因**: - BR.AN.PviServices.dll 缺失或版本不匹配 - PVI Service 未正确安装 - Host 进程内存异常 **解决方案**: 1. 检查 Host 目录下 DLL 文件完整性 2. 确认 B&R Automation Studio 和 PVI Services 已安装 3. 查看 Host 进程 stderr 日志输出 ### 14.5 灯丝寿命数据异常 **可能原因**: - SerialNumber 配置为空 - SQLite 数据库文件损坏 - 异常断电导致未关闭记录 **解决方案**: 1. 确认 `App.config` 中 `RaySource:SerialNumber` 已配置 2. 检查数据库文件完整性 3. 服务初始化时会自动恢复未关闭记录(标记为异常中断,DurationSeconds=0) --- ## 15. 注意事项 | Notes 1. **线程安全**: `IRaySourceService` 是单例,内部使用 `lock` 保护关键操作 2. **同步 API**: 所有 `IXRaySource` 和 `IRaySourceService` 方法为同步方法,ViewModel 中通过 `Task.Run` 包装避免阻塞 UI 3. **InitializeAndConnectAsync**: 唯一的异步便捷方法,内部通过 `Task.Run` 包装同步调用 4. **实时调节**: 连接后可随时调节电压电流,无论射线是否开启 5. **资源释放**: 应用退出时务必调用 `Dispose()` 释放资源(会触发紧急关闭和 Host 进程终止) 6. **事件订阅**: 记得在 ViewModel 销毁时取消事件订阅 7. **配置验证**: 启动前自动验证配置参数的有效性 8. **日志记录**: 所有关键操作都有详细的结构化日志记录 9. **错误处理**: 始终检查 `XRayResult.Success` 并处理错误 10. **Host 进程**: CometHostManager 会自动清理残留进程并管理 Host 生命周期 --- ## 16. 文档索引 | Documentation Index - **[GUIDENCE.md](./GUIDENCE.md)** - 本文档,详细使用指南 - **[README.md](./README.md)** - 项目概述和快速参考 - **[ProjectStructure.md](./ProjectStructure.md)** - 项目结构详解和调用链路 - **[README_RaySourceOperateView.md](./README_RaySourceOperateView.md)** - 操作视图使用说明 - **[App.config.example](./App.config.example)** - 配置文件示例 --- **最后更新 | Last Updated**: 2026-03-26