diff --git a/README.md b/README.md index 6d8de7a..f1d6278 100644 --- a/README.md +++ b/README.md @@ -108,3 +108,4 @@ dotnet build XplorePlane.sln -c Release - [x] 主界面硬件栏相机设置按钮 - [x] 打通与硬件层的调用流程 - [x] 打通与图像层的调用流程 +- [ ] CNC的执行、存储逻辑的开发测试 diff --git a/XP.Hardware.MotionControl/Module/MotionControlModule.cs b/XP.Hardware.MotionControl/Module/MotionControlModule.cs index 2c84fcb..7770809 100644 --- a/XP.Hardware.MotionControl/Module/MotionControlModule.cs +++ b/XP.Hardware.MotionControl/Module/MotionControlModule.cs @@ -69,17 +69,19 @@ namespace XP.Hardware.MotionControl.Module // Initialize LocalizationHelper to use ILocalizationService for string lookup (supports Fallback Chain) LocalizationHelper.Initialize(localizationService); - // 仅在非虚拟模式下启动 PLC 状态轮询 | Only start PLC polling when not in simulated mode + // 启动状态轮询(虚拟模式和 PLC 模式均需要,用于驱动 UI 位置更新事件) + // Start status polling (needed for both simulated and PLC modes to drive UI position update events) + var motionService = containerProvider.Resolve(); + motionService.StartPolling(); + var motionSystem = containerProvider.Resolve(); - if (motionSystem is not SimulatedMotionSystem) + if (motionSystem is SimulatedMotionSystem) { - var motionService = containerProvider.Resolve(); - motionService.StartPolling(); - System.Console.WriteLine("[MotionControlModule] PLC 轮询已启动 | PLC polling started"); + System.Console.WriteLine("[MotionControlModule] [Simulated] 轮询已启动(虚拟模式)| Polling started (simulated mode)"); } else { - System.Console.WriteLine("[MotionControlModule] [Simulated] 跳过 PLC 轮询 | Skipping PLC polling (simulated mode)"); + System.Console.WriteLine("[MotionControlModule] PLC 轮询已启动 | PLC polling started"); } System.Console.WriteLine("[MotionControlModule] 模块已初始化 | Module initialized"); diff --git a/XP.Hardware.MotionControl/Services/MotionControlService.cs b/XP.Hardware.MotionControl/Services/MotionControlService.cs index 97fe3a1..d26b701 100644 --- a/XP.Hardware.MotionControl/Services/MotionControlService.cs +++ b/XP.Hardware.MotionControl/Services/MotionControlService.cs @@ -11,6 +11,7 @@ using XP.Hardware.MotionControl.Abstractions; using XP.Hardware.MotionControl.Abstractions.Enums; using XP.Hardware.MotionControl.Abstractions.Events; using XP.Hardware.MotionControl.Config; +using XP.Hardware.MotionControl.Implementations; using XP.Hardware.Plc.Abstractions; namespace XP.Hardware.MotionControl.Services @@ -105,8 +106,11 @@ namespace XP.Hardware.MotionControl.Services /// private void OnPollingTick(object state) { - // PLC 未连接时跳过轮询 | Skip polling when PLC is not connected - if (!_plcService.IsConnected) return; + // 虚拟运动系统不依赖 PLC 连接 | Simulated motion system does not depend on PLC connection + bool isSimulated = _motionSystem is SimulatedMotionSystem; + + // PLC 未连接时跳过轮询(虚拟模式除外)| Skip polling when PLC is not connected (except simulated mode) + if (!isSimulated && !_plcService.IsConnected) return; // 连续错误过多时降频:每50次轮询才尝试一次 | Throttle when too many consecutive errors if (_pollErrorCount > 3) diff --git a/XP.Hardware.RaySource/Implementations/SimulatedXRaySource.cs b/XP.Hardware.RaySource/Implementations/SimulatedXRaySource.cs index a6d4c2a..e696540 100644 --- a/XP.Hardware.RaySource/Implementations/SimulatedXRaySource.cs +++ b/XP.Hardware.RaySource/Implementations/SimulatedXRaySource.cs @@ -65,6 +65,8 @@ namespace XP.Hardware.RaySource.Implementations public override XRayResult ConnectVariables() { _isConnected = true; + _eventAggregator.GetEvent().Publish(true); + _eventAggregator.GetEvent().Publish(RaySourceStatus.Closed); _logger.Info("[Simulated] PVI 变量连接成功"); return XRayResult.Ok(); } diff --git a/XP.Hardware.RaySource/ViewModels/RaySourceOperateViewModel.cs b/XP.Hardware.RaySource/ViewModels/RaySourceOperateViewModel.cs index 6f1e3a4..5d1fae1 100644 --- a/XP.Hardware.RaySource/ViewModels/RaySourceOperateViewModel.cs +++ b/XP.Hardware.RaySource/ViewModels/RaySourceOperateViewModel.cs @@ -70,11 +70,14 @@ namespace XP.Hardware.RaySource.ViewModels { get { + var isSimulated = _config.SourceType.Equals("Simulated", System.StringComparison.OrdinalIgnoreCase); + var suffix = isSimulated ? "\n(虚拟模式)" : ""; + return RaySourceStatus switch { RaySourceStatus.Unavailable => $"{_localizationService.GetString("RaySource_StatusUnavailable")}", - RaySourceStatus.Closed => _localizationService.GetString("RaySource_StatusClosed"), - RaySourceStatus.Opened => _localizationService.GetString("RaySource_StatusOpened"), + RaySourceStatus.Closed => (_localizationService.GetString("RaySource_StatusClosed") ?? "已关闭") + suffix, + RaySourceStatus.Opened => (_localizationService.GetString("RaySource_StatusOpened") ?? "已开启") + suffix, _ => _localizationService.GetString("RaySource_StatusUnavailable") }; } @@ -477,11 +480,14 @@ namespace XP.Hardware.RaySource.ViewModels } /// - /// 开启命令是否可执行(仅关闭状态且连锁激活时可执行)| Can execute turn on command (only when closed and interlock active) + /// 开启命令是否可执行(仅关闭状态且连锁激活时可执行,虚拟模式跳过联锁检查) + /// Can execute turn on command (only when closed and interlock active; simulated mode skips interlock check) /// private bool CanExecuteTurnOn() { - return !_isOperating && _isVariablesConnected && IsInterlockActive && RaySourceStatus == RaySourceStatus.Closed && _raySourceService.IsInitialized; + var isSimulated = _config.SourceType.Equals("Simulated", System.StringComparison.OrdinalIgnoreCase); + var interlockOk = isSimulated || IsInterlockActive; + return !_isOperating && _isVariablesConnected && interlockOk && RaySourceStatus == RaySourceStatus.Closed && _raySourceService.IsInitialized; } ///