From aeef1feee3e4c7f4af57da776910a424ee1cbac7 Mon Sep 17 00:00:00 2001 From: "zhengxuan.zhang" Date: Wed, 6 May 2026 17:11:35 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A5=E7=A1=AC=E4=BB=B6=E5=BA=93=E5=B1=82?= =?UTF-8?q?=E9=9D=A2=E8=BF=90=E5=8A=A8=E7=A1=AC=E4=BB=B6=E8=BD=B4=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E4=B8=BA=E5=87=86=EF=BC=8C=E5=90=8C=E6=AD=A5=E4=BF=AE?= =?UTF-8?q?=E6=94=B9appstate=EF=BC=8C=20=E5=8C=85=E6=8B=ACCNC=20=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E5=B1=9E=E6=80=A7=E9=9D=A2=E6=9D=BF=E5=92=8C=20XP?= =?UTF-8?q?=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- XplorePlane.Tests/Models/StateModelsTests.cs | 42 ++-- .../Services/AppStateServiceTests.cs | 30 +-- .../Services/RecipeServiceTests.cs | 4 +- XplorePlane/Models/CncModels.cs | 78 +++++--- XplorePlane/Models/StateModels.cs | 104 +++++----- .../Services/AppState/AppStateService.cs | 32 +-- XplorePlane/Services/Cnc/CncProgramService.cs | 18 +- .../ViewModels/Cnc/CncEditorViewModel.cs | 22 +- .../ViewModels/Cnc/CncNodeViewModel.cs | 188 ++++++++++++------ XplorePlane/Views/Cnc/CncPageView.xaml | 40 ++-- .../Hardware/MotionControlPanelView.xaml | 14 +- 11 files changed, 350 insertions(+), 222 deletions(-) diff --git a/XplorePlane.Tests/Models/StateModelsTests.cs b/XplorePlane.Tests/Models/StateModelsTests.cs index 6a96afa..f436a04 100644 --- a/XplorePlane.Tests/Models/StateModelsTests.cs +++ b/XplorePlane.Tests/Models/StateModelsTests.cs @@ -20,21 +20,25 @@ namespace XplorePlane.Tests.Models public void MotionState_Default_AllZeros() { var state = MotionState.Default; - _output.WriteLine($"MotionState.Default: XM={state.XM}, YM={state.YM}, ZT={state.ZT}, ZD={state.ZD}, TiltD={state.TiltD}, Dist={state.Dist}"); - _output.WriteLine($" Speeds: XM={state.XMSpeed}, YM={state.YMSpeed}, ZT={state.ZTSpeed}, ZD={state.ZDSpeed}, TiltD={state.TiltDSpeed}, Dist={state.DistSpeed}"); + _output.WriteLine($"MotionState.Default: StageX={state.StageX}, StageY={state.StageY}, SourceZ={state.SourceZ}, DetectorZ={state.DetectorZ}, DetectorSwing={state.DetectorSwing}, FDD={state.FDD}"); + _output.WriteLine($" Speeds: StageX={state.StageXSpeed}, StageY={state.StageYSpeed}, SourceZ={state.SourceZSpeed}, DetectorZ={state.DetectorZSpeed}, DetectorSwing={state.DetectorSwingSpeed}, FDD={state.FDDSpeed}"); - Assert.Equal(0, state.XM); - Assert.Equal(0, state.YM); - Assert.Equal(0, state.ZT); - Assert.Equal(0, state.ZD); - Assert.Equal(0, state.TiltD); - Assert.Equal(0, state.Dist); - Assert.Equal(0, state.XMSpeed); - Assert.Equal(0, state.YMSpeed); - Assert.Equal(0, state.ZTSpeed); - Assert.Equal(0, state.ZDSpeed); - Assert.Equal(0, state.TiltDSpeed); - Assert.Equal(0, state.DistSpeed); + Assert.Equal(0, state.StageX); + Assert.Equal(0, state.StageY); + Assert.Equal(0, state.SourceZ); + Assert.Equal(0, state.DetectorZ); + Assert.Equal(0, state.DetectorSwing); + Assert.Equal(0, state.FDD); + Assert.Equal(0, state.StageXSpeed); + Assert.Equal(0, state.StageYSpeed); + Assert.Equal(0, state.SourceZSpeed); + Assert.Equal(0, state.DetectorZSpeed); + Assert.Equal(0, state.DetectorSwingSpeed); + Assert.Equal(0, state.FDDSpeed); + Assert.Equal(0, state.StageRotation); + Assert.Equal(0, state.FixtureRotation); + Assert.Equal(0, state.FOD); + Assert.Equal(0, state.Magnification); } [Fact] @@ -116,15 +120,15 @@ namespace XplorePlane.Tests.Models public void MotionState_WithExpression_ProducesNewInstance() { var original = MotionState.Default; - var modified = original with { XM = 100 }; - _output.WriteLine($"Original.XM={original.XM}, Modified.XM={modified.XM}, SameRef={ReferenceEquals(original, modified)}"); + var modified = original with { StageX = 100 }; + _output.WriteLine($"Original.StageX={original.StageX}, Modified.StageX={modified.StageX}, SameRef={ReferenceEquals(original, modified)}"); // New instance is different from original Assert.NotSame(original, modified); - Assert.Equal(100, modified.XM); + Assert.Equal(100, modified.StageX); // Original is unchanged - Assert.Equal(0, original.XM); + Assert.Equal(0, original.StageX); } // ── CalibrationMatrix Transform Tests ───────────────────────── @@ -168,4 +172,4 @@ namespace XplorePlane.Tests.Models Assert.Equal(0, z, precision: 10); } } -} \ No newline at end of file +} diff --git a/XplorePlane.Tests/Services/AppStateServiceTests.cs b/XplorePlane.Tests/Services/AppStateServiceTests.cs index 769db21..1a0c058 100644 --- a/XplorePlane.Tests/Services/AppStateServiceTests.cs +++ b/XplorePlane.Tests/Services/AppStateServiceTests.cs @@ -30,6 +30,8 @@ namespace XplorePlane.Tests.Services private readonly Mock _mockSourceZ; private readonly Mock _mockDetectorZ; private readonly Mock _mockDetectorSwing; + private readonly Mock _mockStageRotation; + private readonly Mock _mockFixtureRotation; private readonly Mock _mockLogger; private readonly EventAggregator _eventAggregator; private readonly ITestOutputHelper _output; @@ -51,6 +53,8 @@ namespace XplorePlane.Tests.Services _mockSourceZ = CreateLinearAxis(AxisId.SourceZ, 0); _mockDetectorZ = CreateLinearAxis(AxisId.DetectorZ, 0); _mockDetectorSwing = CreateRotaryAxis(RotaryAxisId.DetectorSwing, 0); + _mockStageRotation = CreateRotaryAxis(RotaryAxisId.StageRotation, 0); + _mockFixtureRotation = CreateRotaryAxis(RotaryAxisId.FixtureRotation, 0); _mockLogger = new Mock(); _eventAggregator = new EventAggregator(); @@ -59,6 +63,8 @@ namespace XplorePlane.Tests.Services _mockMotionSystem.Setup(x => x.GetLinearAxis(AxisId.SourceZ)).Returns(_mockSourceZ.Object); _mockMotionSystem.Setup(x => x.GetLinearAxis(AxisId.DetectorZ)).Returns(_mockDetectorZ.Object); _mockMotionSystem.Setup(x => x.GetRotaryAxis(RotaryAxisId.DetectorSwing)).Returns(_mockDetectorSwing.Object); + _mockMotionSystem.Setup(x => x.GetRotaryAxis(RotaryAxisId.StageRotation)).Returns(_mockStageRotation.Object); + _mockMotionSystem.Setup(x => x.GetRotaryAxis(RotaryAxisId.FixtureRotation)).Returns(_mockFixtureRotation.Object); _mockMotionControlService .Setup(x => x.GetCurrentGeometry()) @@ -82,12 +88,12 @@ namespace XplorePlane.Tests.Services [Fact] public void DefaultState_MotionState_IsHardwareSnapshot() { - Assert.Equal(0, _service.MotionState.XM); - Assert.Equal(0, _service.MotionState.YM); - Assert.Equal(0, _service.MotionState.ZT); - Assert.Equal(0, _service.MotionState.ZD); - Assert.Equal(0, _service.MotionState.TiltD); - Assert.Equal(0, _service.MotionState.Dist); + Assert.Equal(0, _service.MotionState.StageX); + Assert.Equal(0, _service.MotionState.StageY); + Assert.Equal(0, _service.MotionState.SourceZ); + Assert.Equal(0, _service.MotionState.DetectorZ); + Assert.Equal(0, _service.MotionState.DetectorSwing); + Assert.Equal(0, _service.MotionState.FDD); } [Fact] @@ -174,12 +180,12 @@ namespace XplorePlane.Tests.Services _eventAggregator.GetEvent() .Publish(new GeometryData(100, 222.2, 2.22)); - Assert.Equal(12.5, _service.MotionState.XM); - Assert.Equal(34.5, _service.MotionState.YM); - Assert.Equal(56.5, _service.MotionState.ZT); - Assert.Equal(78.5, _service.MotionState.ZD); - Assert.Equal(9.5, _service.MotionState.TiltD); - Assert.Equal(222.2, _service.MotionState.Dist); + Assert.Equal(12.5, _service.MotionState.StageX); + Assert.Equal(34.5, _service.MotionState.StageY); + Assert.Equal(56.5, _service.MotionState.SourceZ); + Assert.Equal(78.5, _service.MotionState.DetectorZ); + Assert.Equal(9.5, _service.MotionState.DetectorSwing); + Assert.Equal(222.2, _service.MotionState.FDD); } private static Mock CreateLinearAxis(AxisId axisId, double position) diff --git a/XplorePlane.Tests/Services/RecipeServiceTests.cs b/XplorePlane.Tests/Services/RecipeServiceTests.cs index a7e24f5..031dcae 100644 --- a/XplorePlane.Tests/Services/RecipeServiceTests.cs +++ b/XplorePlane.Tests/Services/RecipeServiceTests.cs @@ -96,7 +96,7 @@ namespace XplorePlane.Tests.Services var pipeline = new PipelineModel { Name = "TestPipeline" }; var step = _service.RecordCurrentStep(recipe, pipeline); - _output.WriteLine($"RecordCurrentStep: StepIndex={step.StepIndex}, MotionState.XM={step.MotionState.XM}, RaySource.Voltage={step.RaySourceState.Voltage}, Detector.Resolution={step.DetectorState.Resolution}, Pipeline={step.Pipeline.Name}"); + _output.WriteLine($"RecordCurrentStep: StepIndex={step.StepIndex}, MotionState.StageX={step.MotionState.StageX}, RaySource.Voltage={step.RaySourceState.Voltage}, Detector.Resolution={step.DetectorState.Resolution}, Pipeline={step.Pipeline.Name}"); Assert.Equal(0, step.StepIndex); Assert.Same(motionState, step.MotionState); @@ -138,4 +138,4 @@ namespace XplorePlane.Tests.Services } } } -} \ No newline at end of file +} diff --git a/XplorePlane/Models/CncModels.cs b/XplorePlane/Models/CncModels.cs index 3ab9979..1fc4836 100644 --- a/XplorePlane/Models/CncModels.cs +++ b/XplorePlane/Models/CncModels.cs @@ -40,69 +40,89 @@ namespace XplorePlane.Models Guid Id, int Index, CncNodeType NodeType, - string Name - ); + string Name); /// 参考点节点 | Reference point node public record ReferencePointNode( - Guid Id, int Index, string Name, - double XM, double YM, double ZT, double ZD, double TiltD, double Dist, - bool IsRayOn, double Voltage, double Current - ) : CncNode(Id, Index, CncNodeType.ReferencePoint, Name); + Guid Id, + int Index, + string Name, + [property: JsonPropertyName("XM")] double StageX, + [property: JsonPropertyName("YM")] double StageY, + [property: JsonPropertyName("ZT")] double SourceZ, + [property: JsonPropertyName("ZD")] double DetectorZ, + [property: JsonPropertyName("TiltD")] double DetectorSwing, + [property: JsonPropertyName("Dist")] double FDD, + bool IsRayOn, + double Voltage, + double Current, + double StageRotation = 0, + double FixtureRotation = 0, + double FOD = 0, + double Magnification = 0) : CncNode(Id, Index, CncNodeType.ReferencePoint, Name); /// 保存节点(含图像)| Save node with image public record SaveNodeWithImageNode( - Guid Id, int Index, string Name, + Guid Id, + int Index, + string Name, MotionState MotionState, RaySourceState RaySourceState, DetectorState DetectorState, - string ImageFileName - ) : CncNode(Id, Index, CncNodeType.SaveNodeWithImage, Name); + string ImageFileName) : CncNode(Id, Index, CncNodeType.SaveNodeWithImage, Name); /// 保存节点(不含图像)| Save node without image public record SaveNodeNode( - Guid Id, int Index, string Name, + Guid Id, + int Index, + string Name, MotionState MotionState, RaySourceState RaySourceState, - DetectorState DetectorState - ) : CncNode(Id, Index, CncNodeType.SaveNode, Name); + DetectorState DetectorState) : CncNode(Id, Index, CncNodeType.SaveNode, Name); /// 保存位置节点 | Save position node public record SavePositionNode( - Guid Id, int Index, string Name, - MotionState MotionState - ) : CncNode(Id, Index, CncNodeType.SavePosition, Name); + Guid Id, + int Index, + string Name, + MotionState MotionState) : CncNode(Id, Index, CncNodeType.SavePosition, Name); /// 检测模块节点 | Inspection module node public record InspectionModuleNode( - Guid Id, int Index, string Name, - PipelineModel Pipeline - ) : CncNode(Id, Index, CncNodeType.InspectionModule, Name); + Guid Id, + int Index, + string Name, + PipelineModel Pipeline) : CncNode(Id, Index, CncNodeType.InspectionModule, Name); /// 检测标记节点 | Inspection marker node public record InspectionMarkerNode( - Guid Id, int Index, string Name, + Guid Id, + int Index, + string Name, string MarkerType, - double MarkerX, double MarkerY - ) : CncNode(Id, Index, CncNodeType.InspectionMarker, Name); + double MarkerX, + double MarkerY) : CncNode(Id, Index, CncNodeType.InspectionMarker, Name); /// 停顿对话框节点 | Pause dialog node public record PauseDialogNode( - Guid Id, int Index, string Name, + Guid Id, + int Index, + string Name, string DialogTitle, - string DialogMessage - ) : CncNode(Id, Index, CncNodeType.PauseDialog, Name); + string DialogMessage) : CncNode(Id, Index, CncNodeType.PauseDialog, Name); /// 等待延时节点 | Wait delay node public record WaitDelayNode( - Guid Id, int Index, string Name, - int DelayMilliseconds - ) : CncNode(Id, Index, CncNodeType.WaitDelay, Name); + Guid Id, + int Index, + string Name, + int DelayMilliseconds) : CncNode(Id, Index, CncNodeType.WaitDelay, Name); /// 完成程序节点 | Complete program node public record CompleteProgramNode( - Guid Id, int Index, string Name - ) : CncNode(Id, Index, CncNodeType.CompleteProgram, Name); + Guid Id, + int Index, + string Name) : CncNode(Id, Index, CncNodeType.CompleteProgram, Name); // ── CNC 程序 | CNC Program ──────────────────────────────────────── diff --git a/XplorePlane/Models/StateModels.cs b/XplorePlane/Models/StateModels.cs index c9c6dca..76768a7 100644 --- a/XplorePlane/Models/StateModels.cs +++ b/XplorePlane/Models/StateModels.cs @@ -1,9 +1,8 @@ using System; +using System.Text.Json.Serialization; namespace XplorePlane.Models { - // ── Enumerations ────────────────────────────────────────────────── - /// 系统操作模式 public enum OperationMode { @@ -23,82 +22,86 @@ namespace XplorePlane.Models Error // 出错 } - // ── State Records ───────────────────────────────────────────────── + // — State Records — - /// 运动控制状态(不可变) + /// + /// 运动控制状态(不可变)。 + /// 统一的运动与几何快照,与运动硬件模型对齐。 + /// 保留旧版 JSON 字段名以保持向后兼容性。 + /// public record MotionState( - double XM, // X 轴位置 (μm) - double YM, // Y 轴位置 (μm) - double ZT, // Z 上轴位置 (μm) - double ZD, // Z 下轴位置 (μm) - double TiltD, // 倾斜角度 (m°) - double Dist, // 距离 (μm) - double XMSpeed, // X 轴速度 (μm/s) - double YMSpeed, // Y 轴速度 (μm/s) - double ZTSpeed, // Z 上轴速度 (μm/s) - double ZDSpeed, // Z 下轴速度 (μm/s) - double TiltDSpeed, // 倾斜速度 (m°/s) - double DistSpeed // 距离速度 (μm/s) - ) + [property: JsonPropertyName("XM")] double StageX, // X 轴位置(μm) + [property: JsonPropertyName("YM")] double StageY, // Y 轴位置(μm) + [property: JsonPropertyName("ZT")] double SourceZ, // Z 上轴位置(μm) + [property: JsonPropertyName("ZD")] double DetectorZ, // Z 下轴位置(μm) + [property: JsonPropertyName("TiltD")] double DetectorSwing, // 探测器摆角(°) + [property: JsonPropertyName("Dist")] double FDD, // 焦点-探测器距离(μm) + [property: JsonPropertyName("XMSpeed")] double StageXSpeed, // X 轴速度(μm/s) + [property: JsonPropertyName("YMSpeed")] double StageYSpeed, // Y 轴速度(μm/s) + [property: JsonPropertyName("ZTSpeed")] double SourceZSpeed, // Z 上轴速度(μm/s) + [property: JsonPropertyName("ZDSpeed")] double DetectorZSpeed, // Z 下轴速度(μm/s) + [property: JsonPropertyName("TiltDSpeed")] double DetectorSwingSpeed, // 探测器摆角速度(°/s) + [property: JsonPropertyName("DistSpeed")] double FDDSpeed, // 焦点-探测器距离速度(μm/s) + double StageRotation = 0, // 载台旋转角度(°) + double FixtureRotation = 0, // 夹具旋转角度(°) + double FOD = 0, // 焦点-物体距离(μm) + double Magnification = 0, // 放大倍率 + double StageRotationSpeed = 0, // 载台旋转速度(°/s) + double FixtureRotationSpeed = 0) // 夹具旋转速度(°/s) { public static readonly MotionState Default = new(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); } /// 射线源状态(不可变) public record RaySourceState( - bool IsOn, // 开关状态 - double Voltage, // 电压 (kV) - double Power // 功率 (W) - ) + bool IsOn, // 是否开启 + double Voltage, // 电压(kV) + double Power) // 功率(W) { public static readonly RaySourceState Default = new(false, 0, 0); } /// 探测器状态(不可变) public record DetectorState( - bool IsConnected, // 连接状态 - bool IsAcquiring, // 是否正在采集 - double FrameRate, // 当前帧率 (fps) - string Resolution // 分辨率描述,如 "2048x2048" - ) + bool IsConnected, // 是否已连接 + bool IsAcquiring, // 是否正在采集 + double FrameRate, // 帧率(fps) + string Resolution) // 分辨率描述 { public static readonly DetectorState Default = new(false, false, 0, string.Empty); } - /// 系统级状态(不可变) + /// 系统整体状态(不可变) public record SystemState( - OperationMode OperationMode, // 当前操作模式 - bool HasError, // 是否存在系统错误 - string ErrorMessage // 错误描述 - ) + OperationMode OperationMode, // 当前操作模式 + bool HasError, // 是否存在错误 + string ErrorMessage) // 错误信息 { public static readonly SystemState Default = new(OperationMode.Idle, false, string.Empty); } - /// 摄像头视频流状态(不可变) + /// 相机状态(不可变) public record CameraState( - bool IsConnected, // 连接状态 - bool IsStreaming, // 是否正在推流 - object CurrentFrame, // 当前帧数据引用(BitmapSource 或 byte[],Frozen) - int Width, // 分辨率宽 - int Height, // 分辨率高 - double FrameRate // 帧率 (fps) - ) + bool IsConnected, // 是否已连接 + bool IsStreaming, // 是否正在推流 + object CurrentFrame, // 当前帧数据 + int Width, // 图像宽度(px) + int Height, // 图像高度(px) + double FrameRate) // 帧率(fps) { public static readonly CameraState Default = new(false, false, null, 0, 0, 0); } - /// 物理坐标 + /// 物理坐标位置 public record PhysicalPosition(double X, double Y, double Z); - /// 图像标定矩阵,像素坐标 → 物理坐标映射 + /// 标定矩阵(3×3 仿射变换) public record CalibrationMatrix( - double M11, double M12, double M13, // 3x3 仿射变换矩阵 + double M11, double M12, double M13, double M21, double M22, double M23, - double M31, double M32, double M33 - ) + double M31, double M32, double M33) { - /// 将像素坐标转换为物理坐标 + /// 将像素坐标变换为物理坐标 public (double X, double Y, double Z) Transform(double pixelX, double pixelY) { double x = M11 * pixelX + M12 * pixelY + M13; @@ -108,13 +111,12 @@ namespace XplorePlane.Models } } - /// 画面联动状态(不可变) + /// 联动视图状态(不可变) public record LinkedViewState( - PhysicalPosition TargetPosition, // 目标物理坐标 - bool IsExecuting, // 联动是否正在执行 - DateTime LastRequestTime // 最近一次联动请求时间 - ) + PhysicalPosition TargetPosition, // 目标物理位置 + bool IsExecuting, // 是否正在执行移动 + DateTime LastRequestTime) // 最近一次请求时间 { public static readonly LinkedViewState Default = new(new PhysicalPosition(0, 0, 0), false, DateTime.MinValue); } -} \ No newline at end of file +} diff --git a/XplorePlane/Services/AppState/AppStateService.cs b/XplorePlane/Services/AppState/AppStateService.cs index 83579c4..1039fe6 100644 --- a/XplorePlane/Services/AppState/AppStateService.cs +++ b/XplorePlane/Services/AppState/AppStateService.cs @@ -345,20 +345,28 @@ namespace XplorePlane.Services.AppState var sourceZ = _motionSystem.GetLinearAxis(AxisId.SourceZ); var detectorZ = _motionSystem.GetLinearAxis(AxisId.DetectorZ); var detectorSwing = _motionSystem.GetRotaryAxis(RotaryAxisId.DetectorSwing); + var stageRotation = _motionSystem.GetRotaryAxis(RotaryAxisId.StageRotation); + var fixtureRotation = _motionSystem.GetRotaryAxis(RotaryAxisId.FixtureRotation); return new MotionState( - XM: stageX.ActualPosition, - YM: stageY.ActualPosition, - ZT: sourceZ.ActualPosition, - ZD: detectorZ.ActualPosition, - TiltD: detectorSwing.ActualAngle, - Dist: geometry?.FDD ?? 0, - XMSpeed: 0, - YMSpeed: 0, - ZTSpeed: 0, - ZDSpeed: 0, - TiltDSpeed: 0, - DistSpeed: 0); + StageX: stageX.ActualPosition, + StageY: stageY.ActualPosition, + SourceZ: sourceZ.ActualPosition, + DetectorZ: detectorZ.ActualPosition, + DetectorSwing: detectorSwing.ActualAngle, + FDD: geometry?.FDD ?? 0, + StageXSpeed: 0, + StageYSpeed: 0, + SourceZSpeed: 0, + DetectorZSpeed: 0, + DetectorSwingSpeed: 0, + FDDSpeed: 0, + StageRotation: stageRotation.ActualAngle, + FixtureRotation: fixtureRotation.ActualAngle, + FOD: geometry?.FOD ?? 0, + Magnification: geometry?.Magnification ?? 0, + StageRotationSpeed: 0, + FixtureRotationSpeed: 0); } private void SetMotionState(MotionState newState) diff --git a/XplorePlane/Services/Cnc/CncProgramService.cs b/XplorePlane/Services/Cnc/CncProgramService.cs index 8765574..c9c7b65 100644 --- a/XplorePlane/Services/Cnc/CncProgramService.cs +++ b/XplorePlane/Services/Cnc/CncProgramService.cs @@ -389,15 +389,19 @@ namespace XplorePlane.Services.Cnc var raySource = _appStateService.RaySourceState; return new ReferencePointNode( id, index, $"参考点_{index}", - XM: motion.XM, - YM: motion.YM, - ZT: motion.ZT, - ZD: motion.ZD, - TiltD: motion.TiltD, - Dist: motion.Dist, + StageX: motion.StageX, + StageY: motion.StageY, + SourceZ: motion.SourceZ, + DetectorZ: motion.DetectorZ, + DetectorSwing: motion.DetectorSwing, + FDD: motion.FDD, IsRayOn: raySource.IsOn, Voltage: raySource.Voltage, - Current: TryReadCurrent()); + Current: TryReadCurrent(), + StageRotation: motion.StageRotation, + FixtureRotation: motion.FixtureRotation, + FOD: motion.FOD, + Magnification: motion.Magnification); } /// 创建保存节点(含图像)| Create save node with image diff --git a/XplorePlane/ViewModels/Cnc/CncEditorViewModel.cs b/XplorePlane/ViewModels/Cnc/CncEditorViewModel.cs index 9b04275..d2181b7 100644 --- a/XplorePlane/ViewModels/Cnc/CncEditorViewModel.cs +++ b/XplorePlane/ViewModels/Cnc/CncEditorViewModel.cs @@ -417,7 +417,7 @@ namespace XplorePlane.ViewModels.Cnc return; var sb = new StringBuilder(); - sb.AppendLine("Index,NodeType,Name,XM,YM,ZT,ZD,TiltD,Dist,Voltage_kV,Current_uA,Power_W,RayOn,DetectorConnected,FrameRate,Resolution,ImageFile,MarkerType,MarkerX,MarkerY,DialogTitle,DialogMessage,DelayMs,Pipeline"); + sb.AppendLine("Index,NodeType,Name,StageX,StageY,SourceZ,DetectorZ,DetectorSwing,StageRotation,FixtureRotation,FOD,FDD,Magnification,Voltage_kV,Current_uA,Power_W,RayOn,DetectorConnected,FrameRate,Resolution,ImageFile,MarkerType,MarkerX,MarkerY,DialogTitle,DialogMessage,DelayMs,Pipeline"); var inv = CultureInfo.InvariantCulture; @@ -425,16 +425,16 @@ namespace XplorePlane.ViewModels.Cnc { var row = node switch { - ReferencePointNode rp => $"{rp.Index},{rp.NodeType},{Esc(rp.Name)},{rp.XM.ToString(inv)},{rp.YM.ToString(inv)},{rp.ZT.ToString(inv)},{rp.ZD.ToString(inv)},{rp.TiltD.ToString(inv)},{rp.Dist.ToString(inv)},{rp.Voltage.ToString(inv)},{rp.Current.ToString(inv)},,{rp.IsRayOn},,,,,,,,,,", - SaveNodeWithImageNode sni => $"{sni.Index},{sni.NodeType},{Esc(sni.Name)},{sni.MotionState.XM.ToString(inv)},{sni.MotionState.YM.ToString(inv)},{sni.MotionState.ZT.ToString(inv)},{sni.MotionState.ZD.ToString(inv)},{sni.MotionState.TiltD.ToString(inv)},{sni.MotionState.Dist.ToString(inv)},{sni.RaySourceState.Voltage.ToString(inv)},,{sni.RaySourceState.Power.ToString(inv)},{sni.RaySourceState.IsOn},{sni.DetectorState.IsConnected},{sni.DetectorState.FrameRate.ToString(inv)},{Esc(sni.DetectorState.Resolution)},{Esc(sni.ImageFileName)},,,,,,", - SaveNodeNode sn => $"{sn.Index},{sn.NodeType},{Esc(sn.Name)},{sn.MotionState.XM.ToString(inv)},{sn.MotionState.YM.ToString(inv)},{sn.MotionState.ZT.ToString(inv)},{sn.MotionState.ZD.ToString(inv)},{sn.MotionState.TiltD.ToString(inv)},{sn.MotionState.Dist.ToString(inv)},{sn.RaySourceState.Voltage.ToString(inv)},,{sn.RaySourceState.Power.ToString(inv)},{sn.RaySourceState.IsOn},{sn.DetectorState.IsConnected},{sn.DetectorState.FrameRate.ToString(inv)},{Esc(sn.DetectorState.Resolution)},,,,,,,", - SavePositionNode sp => $"{sp.Index},{sp.NodeType},{Esc(sp.Name)},{sp.MotionState.XM.ToString(inv)},{sp.MotionState.YM.ToString(inv)},{sp.MotionState.ZT.ToString(inv)},{sp.MotionState.ZD.ToString(inv)},{sp.MotionState.TiltD.ToString(inv)},{sp.MotionState.Dist.ToString(inv)},,,,,,,,,,,,,,", - InspectionModuleNode im => $"{im.Index},{im.NodeType},{Esc(im.Name)},,,,,,,,,,,,,,,,,,,{Esc(im.Pipeline?.Name ?? string.Empty)}", - InspectionMarkerNode mk => $"{mk.Index},{mk.NodeType},{Esc(mk.Name)},,,,,,,,,,,,,,{Esc(mk.MarkerType)},{mk.MarkerX.ToString(inv)},{mk.MarkerY.ToString(inv)},,,", - PauseDialogNode pd => $"{pd.Index},{pd.NodeType},{Esc(pd.Name)},,,,,,,,,,,,,,,,,{Esc(pd.DialogTitle)},{Esc(pd.DialogMessage)},,", - WaitDelayNode wd => $"{wd.Index},{wd.NodeType},{Esc(wd.Name)},,,,,,,,,,,,,,,,,,,{wd.DelayMilliseconds},", - CompleteProgramNode cp => $"{cp.Index},{cp.NodeType},{Esc(cp.Name)},,,,,,,,,,,,,,,,,,,,", - _ => $"{node.Index},{node.NodeType},{Esc(node.Name)},,,,,,,,,,,,,,,,,,,," + ReferencePointNode rp => $"{rp.Index},{rp.NodeType},{Esc(rp.Name)},{rp.StageX.ToString(inv)},{rp.StageY.ToString(inv)},{rp.SourceZ.ToString(inv)},{rp.DetectorZ.ToString(inv)},{rp.DetectorSwing.ToString(inv)},{rp.StageRotation.ToString(inv)},{rp.FixtureRotation.ToString(inv)},{rp.FOD.ToString(inv)},{rp.FDD.ToString(inv)},{rp.Magnification.ToString(inv)},{rp.Voltage.ToString(inv)},{rp.Current.ToString(inv)},,{rp.IsRayOn},,,,,,,,,,", + SaveNodeWithImageNode sni => $"{sni.Index},{sni.NodeType},{Esc(sni.Name)},{sni.MotionState.StageX.ToString(inv)},{sni.MotionState.StageY.ToString(inv)},{sni.MotionState.SourceZ.ToString(inv)},{sni.MotionState.DetectorZ.ToString(inv)},{sni.MotionState.DetectorSwing.ToString(inv)},{sni.MotionState.StageRotation.ToString(inv)},{sni.MotionState.FixtureRotation.ToString(inv)},{sni.MotionState.FOD.ToString(inv)},{sni.MotionState.FDD.ToString(inv)},{sni.MotionState.Magnification.ToString(inv)},{sni.RaySourceState.Voltage.ToString(inv)},,{sni.RaySourceState.Power.ToString(inv)},{sni.RaySourceState.IsOn},{sni.DetectorState.IsConnected},{sni.DetectorState.FrameRate.ToString(inv)},{Esc(sni.DetectorState.Resolution)},{Esc(sni.ImageFileName)},,,,,,", + SaveNodeNode sn => $"{sn.Index},{sn.NodeType},{Esc(sn.Name)},{sn.MotionState.StageX.ToString(inv)},{sn.MotionState.StageY.ToString(inv)},{sn.MotionState.SourceZ.ToString(inv)},{sn.MotionState.DetectorZ.ToString(inv)},{sn.MotionState.DetectorSwing.ToString(inv)},{sn.MotionState.StageRotation.ToString(inv)},{sn.MotionState.FixtureRotation.ToString(inv)},{sn.MotionState.FOD.ToString(inv)},{sn.MotionState.FDD.ToString(inv)},{sn.MotionState.Magnification.ToString(inv)},{sn.RaySourceState.Voltage.ToString(inv)},,{sn.RaySourceState.Power.ToString(inv)},{sn.RaySourceState.IsOn},{sn.DetectorState.IsConnected},{sn.DetectorState.FrameRate.ToString(inv)},{Esc(sn.DetectorState.Resolution)},,,,,,,", + SavePositionNode sp => $"{sp.Index},{sp.NodeType},{Esc(sp.Name)},{sp.MotionState.StageX.ToString(inv)},{sp.MotionState.StageY.ToString(inv)},{sp.MotionState.SourceZ.ToString(inv)},{sp.MotionState.DetectorZ.ToString(inv)},{sp.MotionState.DetectorSwing.ToString(inv)},{sp.MotionState.StageRotation.ToString(inv)},{sp.MotionState.FixtureRotation.ToString(inv)},{sp.MotionState.FOD.ToString(inv)},{sp.MotionState.FDD.ToString(inv)},{sp.MotionState.Magnification.ToString(inv)},,,,,,,,,,,,,,", + InspectionModuleNode im => $"{im.Index},{im.NodeType},{Esc(im.Name)},,,,,,,,,,,,,,,,,,,,,,{Esc(im.Pipeline?.Name ?? string.Empty)}", + InspectionMarkerNode mk => $"{mk.Index},{mk.NodeType},{Esc(mk.Name)},,,,,,,,,,,,,,,,,{Esc(mk.MarkerType)},{mk.MarkerX.ToString(inv)},{mk.MarkerY.ToString(inv)},,,", + PauseDialogNode pd => $"{pd.Index},{pd.NodeType},{Esc(pd.Name)},,,,,,,,,,,,,,,,,,,{Esc(pd.DialogTitle)},{Esc(pd.DialogMessage)},,", + WaitDelayNode wd => $"{wd.Index},{wd.NodeType},{Esc(wd.Name)},,,,,,,,,,,,,,,,,,,,,{wd.DelayMilliseconds},", + CompleteProgramNode cp => $"{cp.Index},{cp.NodeType},{Esc(cp.Name)},,,,,,,,,,,,,,,,,,,,,,", + _ => $"{node.Index},{node.NodeType},{Esc(node.Name)},,,,,,,,,,,,,,,,,,,,,," }; sb.AppendLine(row); diff --git a/XplorePlane/ViewModels/Cnc/CncNodeViewModel.cs b/XplorePlane/ViewModels/Cnc/CncNodeViewModel.cs index ac46829..3cbb2fe 100644 --- a/XplorePlane/ViewModels/Cnc/CncNodeViewModel.cs +++ b/XplorePlane/ViewModels/Cnc/CncNodeViewModel.cs @@ -116,82 +116,134 @@ namespace XplorePlane.ViewModels.Cnc _ => string.Empty }; - public double XM + public double StageX { get => _model switch { - ReferencePointNode rp => rp.XM, - SaveNodeNode sn => sn.MotionState.XM, - SaveNodeWithImageNode sni => sni.MotionState.XM, - SavePositionNode sp => sp.MotionState.XM, + ReferencePointNode rp => rp.StageX, + SaveNodeNode sn => sn.MotionState.StageX, + SaveNodeWithImageNode sni => sni.MotionState.StageX, + SavePositionNode sp => sp.MotionState.StageX, _ => 0d }; - set => UpdateMotion(value, MotionAxis.XM); + set => UpdateMotion(value, MotionAxis.StageX); } - public double YM + public double StageY { get => _model switch { - ReferencePointNode rp => rp.YM, - SaveNodeNode sn => sn.MotionState.YM, - SaveNodeWithImageNode sni => sni.MotionState.YM, - SavePositionNode sp => sp.MotionState.YM, + ReferencePointNode rp => rp.StageY, + SaveNodeNode sn => sn.MotionState.StageY, + SaveNodeWithImageNode sni => sni.MotionState.StageY, + SavePositionNode sp => sp.MotionState.StageY, _ => 0d }; - set => UpdateMotion(value, MotionAxis.YM); + set => UpdateMotion(value, MotionAxis.StageY); } - public double ZT + public double SourceZ { get => _model switch { - ReferencePointNode rp => rp.ZT, - SaveNodeNode sn => sn.MotionState.ZT, - SaveNodeWithImageNode sni => sni.MotionState.ZT, - SavePositionNode sp => sp.MotionState.ZT, + ReferencePointNode rp => rp.SourceZ, + SaveNodeNode sn => sn.MotionState.SourceZ, + SaveNodeWithImageNode sni => sni.MotionState.SourceZ, + SavePositionNode sp => sp.MotionState.SourceZ, _ => 0d }; - set => UpdateMotion(value, MotionAxis.ZT); + set => UpdateMotion(value, MotionAxis.SourceZ); } - public double ZD + public double DetectorZ { get => _model switch { - ReferencePointNode rp => rp.ZD, - SaveNodeNode sn => sn.MotionState.ZD, - SaveNodeWithImageNode sni => sni.MotionState.ZD, - SavePositionNode sp => sp.MotionState.ZD, + ReferencePointNode rp => rp.DetectorZ, + SaveNodeNode sn => sn.MotionState.DetectorZ, + SaveNodeWithImageNode sni => sni.MotionState.DetectorZ, + SavePositionNode sp => sp.MotionState.DetectorZ, _ => 0d }; - set => UpdateMotion(value, MotionAxis.ZD); + set => UpdateMotion(value, MotionAxis.DetectorZ); } - public double TiltD + public double DetectorSwing { get => _model switch { - ReferencePointNode rp => rp.TiltD, - SaveNodeNode sn => sn.MotionState.TiltD, - SaveNodeWithImageNode sni => sni.MotionState.TiltD, - SavePositionNode sp => sp.MotionState.TiltD, + ReferencePointNode rp => rp.DetectorSwing, + SaveNodeNode sn => sn.MotionState.DetectorSwing, + SaveNodeWithImageNode sni => sni.MotionState.DetectorSwing, + SavePositionNode sp => sp.MotionState.DetectorSwing, _ => 0d }; - set => UpdateMotion(value, MotionAxis.TiltD); + set => UpdateMotion(value, MotionAxis.DetectorSwing); } - public double Dist + public double StageRotation { get => _model switch { - ReferencePointNode rp => rp.Dist, - SaveNodeNode sn => sn.MotionState.Dist, - SaveNodeWithImageNode sni => sni.MotionState.Dist, - SavePositionNode sp => sp.MotionState.Dist, + ReferencePointNode rp => rp.StageRotation, + SaveNodeNode sn => sn.MotionState.StageRotation, + SaveNodeWithImageNode sni => sni.MotionState.StageRotation, + SavePositionNode sp => sp.MotionState.StageRotation, _ => 0d }; - set => UpdateMotion(value, MotionAxis.Dist); + set => UpdateMotion(value, MotionAxis.StageRotation); + } + + public double FixtureRotation + { + get => _model switch + { + ReferencePointNode rp => rp.FixtureRotation, + SaveNodeNode sn => sn.MotionState.FixtureRotation, + SaveNodeWithImageNode sni => sni.MotionState.FixtureRotation, + SavePositionNode sp => sp.MotionState.FixtureRotation, + _ => 0d + }; + set => UpdateMotion(value, MotionAxis.FixtureRotation); + } + + public double FOD + { + get => _model switch + { + ReferencePointNode rp => rp.FOD, + SaveNodeNode sn => sn.MotionState.FOD, + SaveNodeWithImageNode sni => sni.MotionState.FOD, + SavePositionNode sp => sp.MotionState.FOD, + _ => 0d + }; + set => UpdateMotion(value, MotionAxis.FOD); + } + + public double FDD + { + get => _model switch + { + ReferencePointNode rp => rp.FDD, + SaveNodeNode sn => sn.MotionState.FDD, + SaveNodeWithImageNode sni => sni.MotionState.FDD, + SavePositionNode sp => sp.MotionState.FDD, + _ => 0d + }; + set => UpdateMotion(value, MotionAxis.FDD); + } + + public double Magnification + { + get => _model switch + { + ReferencePointNode rp => rp.Magnification, + SaveNodeNode sn => sn.MotionState.Magnification, + SaveNodeWithImageNode sni => sni.MotionState.Magnification, + SavePositionNode sp => sp.MotionState.Magnification, + _ => 0d + }; + set => UpdateMotion(value, MotionAxis.Magnification); } public bool IsRayOn @@ -426,12 +478,16 @@ namespace XplorePlane.ViewModels.Cnc case ReferencePointNode rp: UpdateModel(axis switch { - MotionAxis.XM => rp with { XM = value }, - MotionAxis.YM => rp with { YM = value }, - MotionAxis.ZT => rp with { ZT = value }, - MotionAxis.ZD => rp with { ZD = value }, - MotionAxis.TiltD => rp with { TiltD = value }, - MotionAxis.Dist => rp with { Dist = value }, + MotionAxis.StageX => rp with { StageX = value }, + MotionAxis.StageY => rp with { StageY = value }, + MotionAxis.SourceZ => rp with { SourceZ = value }, + MotionAxis.DetectorZ => rp with { DetectorZ = value }, + MotionAxis.DetectorSwing => rp with { DetectorSwing = value }, + MotionAxis.StageRotation => rp with { StageRotation = value }, + MotionAxis.FixtureRotation => rp with { FixtureRotation = value }, + MotionAxis.FOD => rp with { FOD = value }, + MotionAxis.FDD => rp with { FDD = value }, + MotionAxis.Magnification => rp with { Magnification = value }, _ => rp }); break; @@ -519,12 +575,16 @@ namespace XplorePlane.ViewModels.Cnc { return axis switch { - MotionAxis.XM => state with { XM = value }, - MotionAxis.YM => state with { YM = value }, - MotionAxis.ZT => state with { ZT = value }, - MotionAxis.ZD => state with { ZD = value }, - MotionAxis.TiltD => state with { TiltD = value }, - MotionAxis.Dist => state with { Dist = value }, + MotionAxis.StageX => state with { StageX = value }, + MotionAxis.StageY => state with { StageY = value }, + MotionAxis.SourceZ => state with { SourceZ = value }, + MotionAxis.DetectorZ => state with { DetectorZ = value }, + MotionAxis.DetectorSwing => state with { DetectorSwing = value }, + MotionAxis.StageRotation => state with { StageRotation = value }, + MotionAxis.FixtureRotation => state with { FixtureRotation = value }, + MotionAxis.FOD => state with { FOD = value }, + MotionAxis.FDD => state with { FDD = value }, + MotionAxis.Magnification => state with { Magnification = value }, _ => state }; } @@ -557,12 +617,16 @@ namespace XplorePlane.ViewModels.Cnc RaisePropertyChanged(nameof(IsPositionChild)); RaisePropertyChanged(nameof(IsMotionSnapshotNode)); RaisePropertyChanged(nameof(RelationTag)); - RaisePropertyChanged(nameof(XM)); - RaisePropertyChanged(nameof(YM)); - RaisePropertyChanged(nameof(ZT)); - RaisePropertyChanged(nameof(ZD)); - RaisePropertyChanged(nameof(TiltD)); - RaisePropertyChanged(nameof(Dist)); + RaisePropertyChanged(nameof(StageX)); + RaisePropertyChanged(nameof(StageY)); + RaisePropertyChanged(nameof(SourceZ)); + RaisePropertyChanged(nameof(DetectorZ)); + RaisePropertyChanged(nameof(DetectorSwing)); + RaisePropertyChanged(nameof(StageRotation)); + RaisePropertyChanged(nameof(FixtureRotation)); + RaisePropertyChanged(nameof(FOD)); + RaisePropertyChanged(nameof(FDD)); + RaisePropertyChanged(nameof(Magnification)); RaisePropertyChanged(nameof(IsRayOn)); RaisePropertyChanged(nameof(Voltage)); RaisePropertyChanged(nameof(Current)); @@ -591,12 +655,16 @@ namespace XplorePlane.ViewModels.Cnc private enum MotionAxis { - XM, - YM, - ZT, - ZD, - TiltD, - Dist + StageX, + StageY, + SourceZ, + DetectorZ, + DetectorSwing, + StageRotation, + FixtureRotation, + FOD, + FDD, + Magnification } } } diff --git a/XplorePlane/Views/Cnc/CncPageView.xaml b/XplorePlane/Views/Cnc/CncPageView.xaml index 092a6b7..171cd05 100644 --- a/XplorePlane/Views/Cnc/CncPageView.xaml +++ b/XplorePlane/Views/Cnc/CncPageView.xaml @@ -489,28 +489,44 @@ Visibility="{Binding SelectedNode.IsMotionSnapshotNode, Converter={StaticResource BoolToVisibilityConverter}}"> - - + + - - + + - - + + - - + + - - + + - - + + + + + + + + + + + + + + + + + + diff --git a/XplorePlane/Views/Hardware/MotionControlPanelView.xaml b/XplorePlane/Views/Hardware/MotionControlPanelView.xaml index a632154..f466347 100644 --- a/XplorePlane/Views/Hardware/MotionControlPanelView.xaml +++ b/XplorePlane/Views/Hardware/MotionControlPanelView.xaml @@ -53,7 +53,7 @@ Margin="0,0,4,3" VerticalAlignment="Center" Foreground="#333333" - Text="XM" /> + Text="StageX" /> + Text="StageY" /> + Text="SourceZ" /> + Text="DetectorZ" /> + Text="DetectorSwing" /> + Text="FDD" /> - \ No newline at end of file +