以硬件库层面运动硬件轴定义为准,同步修改appstate, 包括CNC 节点属性面板和 XP导出

This commit is contained in:
zhengxuan.zhang
2026-05-06 17:11:35 +08:00
parent 1ef876db2c
commit aeef1feee3
11 changed files with 350 additions and 222 deletions
+22 -18
View File
@@ -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 ─────────────────────────
@@ -30,6 +30,8 @@ namespace XplorePlane.Tests.Services
private readonly Mock<ILinearAxis> _mockSourceZ;
private readonly Mock<ILinearAxis> _mockDetectorZ;
private readonly Mock<IRotaryAxis> _mockDetectorSwing;
private readonly Mock<IRotaryAxis> _mockStageRotation;
private readonly Mock<IRotaryAxis> _mockFixtureRotation;
private readonly Mock<ILoggerService> _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<ILoggerService>();
_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<GeometryUpdatedEvent>()
.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<ILinearAxis> CreateLinearAxis(AxisId axisId, double position)
@@ -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);
+49 -29
View File
@@ -40,69 +40,89 @@ namespace XplorePlane.Models
Guid Id,
int Index,
CncNodeType NodeType,
string Name
);
string Name);
/// <summary>参考点节点 | Reference point node</summary>
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);
/// <summary>保存节点(含图像)| Save node with image</summary>
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);
/// <summary>保存节点(不含图像)| Save node without image</summary>
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);
/// <summary>保存位置节点 | Save position node</summary>
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);
/// <summary>检测模块节点 | Inspection module node</summary>
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);
/// <summary>检测标记节点 | Inspection marker node</summary>
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);
/// <summary>停顿对话框节点 | Pause dialog node</summary>
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);
/// <summary>等待延时节点 | Wait delay node</summary>
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);
/// <summary>完成程序节点 | Complete program node</summary>
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 ────────────────────────────────────────
+49 -47
View File
@@ -1,9 +1,8 @@
using System;
using System.Text.Json.Serialization;
namespace XplorePlane.Models
{
// ── Enumerations ──────────────────────────────────────────────────
/// <summary>系统操作模式</summary>
public enum OperationMode
{
@@ -23,82 +22,86 @@ namespace XplorePlane.Models
Error // 出错
}
// ── State Records ─────────────────────────────────────────────────
// State Records
/// <summary>运动控制状态(不可变)</summary>
/// <summary>
/// 运动控制状态(不可变)。
/// 统一的运动与几何快照,与运动硬件模型对齐。
/// 保留旧版 JSON 字段名以保持向后兼容性。
/// </summary>
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);
}
/// <summary>射线源状态(不可变)</summary>
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);
}
/// <summary>探测器状态(不可变)</summary>
public record DetectorState(
bool IsConnected, // 连接状态
bool IsConnected, // 是否已连接
bool IsAcquiring, // 是否正在采集
double FrameRate, // 当前帧率 (fps)
string Resolution // 分辨率描述,如 "2048x2048"
)
double FrameRate, // 帧率(fps
string Resolution) // 分辨率描述
{
public static readonly DetectorState Default = new(false, false, 0, string.Empty);
}
/// <summary>系统状态(不可变)</summary>
/// <summary>系统整体状态(不可变)</summary>
public record SystemState(
OperationMode OperationMode, // 当前操作模式
bool HasError, // 是否存在系统错误
string ErrorMessage // 错误描述
)
bool HasError, // 是否存在错误
string ErrorMessage) // 错误信息
{
public static readonly SystemState Default = new(OperationMode.Idle, false, string.Empty);
}
/// <summary>摄像头视频流状态(不可变)</summary>
/// <summary>相机状态(不可变)</summary>
public record CameraState(
bool IsConnected, // 连接状态
bool IsConnected, // 是否已连接
bool IsStreaming, // 是否正在推流
object CurrentFrame, // 当前帧数据引用(BitmapSource 或 byte[]Frozen
int Width, // 分辨率宽
int Height, // 分辨率高
double FrameRate // 帧率 (fps)
)
object CurrentFrame, // 当前帧数据
int Width, // 图像宽度(px
int Height, // 图像高度(px
double FrameRate) // 帧率fps
{
public static readonly CameraState Default = new(false, false, null, 0, 0, 0);
}
/// <summary>物理坐标</summary>
/// <summary>物理坐标位置</summary>
public record PhysicalPosition(double X, double Y, double Z);
/// <summary>图像标定矩阵,像素坐标 → 物理坐标映射</summary>
/// <summary>标定矩阵3×3 仿射变换)</summary>
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)
{
/// <summary>将像素坐标换为物理坐标</summary>
/// <summary>将像素坐标换为物理坐标</summary>
public (double X, double Y, double Z) Transform(double pixelX, double pixelY)
{
double x = M11 * pixelX + M12 * pixelY + M13;
@@ -108,12 +111,11 @@ namespace XplorePlane.Models
}
}
/// <summary>画面联动状态(不可变)</summary>
/// <summary>联动视图状态(不可变)</summary>
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);
}
@@ -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)
+11 -7
View File
@@ -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);
}
/// <summary>创建保存节点(含图像)| Create save node with image</summary>
@@ -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);
+128 -60
View File
@@ -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
}
}
}
+28 -12
View File
@@ -489,28 +489,44 @@
Visibility="{Binding SelectedNode.IsMotionSnapshotNode, Converter={StaticResource BoolToVisibilityConverter}}">
<UniformGrid Margin="8,8,8,6" Columns="2">
<StackPanel Margin="0,0,6,0">
<TextBlock Style="{StaticResource LabelStyle}" Text="XM" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.XM, UpdateSourceTrigger=LostFocus}" />
<TextBlock Style="{StaticResource LabelStyle}" Text="StageX" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.StageX, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
<StackPanel>
<TextBlock Style="{StaticResource LabelStyle}" Text="YM" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.YM, UpdateSourceTrigger=LostFocus}" />
<TextBlock Style="{StaticResource LabelStyle}" Text="StageY" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.StageY, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
<StackPanel Margin="0,0,6,0">
<TextBlock Style="{StaticResource LabelStyle}" Text="ZT" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.ZT, UpdateSourceTrigger=LostFocus}" />
<TextBlock Style="{StaticResource LabelStyle}" Text="SourceZ" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.SourceZ, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
<StackPanel>
<TextBlock Style="{StaticResource LabelStyle}" Text="ZD" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.ZD, UpdateSourceTrigger=LostFocus}" />
<TextBlock Style="{StaticResource LabelStyle}" Text="DetectorZ" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.DetectorZ, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
<StackPanel Margin="0,0,6,0">
<TextBlock Style="{StaticResource LabelStyle}" Text="TiltD" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.TiltD, UpdateSourceTrigger=LostFocus}" />
<TextBlock Style="{StaticResource LabelStyle}" Text="DetectorSwing" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.DetectorSwing, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
<StackPanel>
<TextBlock Style="{StaticResource LabelStyle}" Text="Dist" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.Dist, UpdateSourceTrigger=LostFocus}" />
<TextBlock Style="{StaticResource LabelStyle}" Text="StageRotation" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.StageRotation, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
<StackPanel Margin="0,0,6,0">
<TextBlock Style="{StaticResource LabelStyle}" Text="FixtureRotation" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.FixtureRotation, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
<StackPanel>
<TextBlock Style="{StaticResource LabelStyle}" Text="FOD" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.FOD, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
<StackPanel Margin="0,0,6,0">
<TextBlock Style="{StaticResource LabelStyle}" Text="FDD" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.FDD, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
<StackPanel>
<TextBlock Style="{StaticResource LabelStyle}" Text="Magnification" />
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.Magnification, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
</UniformGrid>
</GroupBox>
@@ -53,7 +53,7 @@
Margin="0,0,4,3"
VerticalAlignment="Center"
Foreground="#333333"
Text="XM" />
Text="StageX" />
<TextBox
Grid.Row="0"
Grid.Column="1"
@@ -94,7 +94,7 @@
Margin="0,0,4,3"
VerticalAlignment="Center"
Foreground="#333333"
Text="YM" />
Text="StageY" />
<TextBox
Grid.Row="1"
Grid.Column="1"
@@ -127,7 +127,7 @@
Margin="0,0,4,3"
VerticalAlignment="Center"
Foreground="#333333"
Text="ZT" />
Text="SourceZ" />
<TextBox
Grid.Row="2"
Grid.Column="1"
@@ -151,7 +151,7 @@
Margin="0,0,4,3"
VerticalAlignment="Center"
Foreground="#333333"
Text="ZD" />
Text="DetectorZ" />
<TextBox
Grid.Row="3"
Grid.Column="1"
@@ -175,7 +175,7 @@
Margin="0,0,4,3"
VerticalAlignment="Center"
Foreground="#333333"
Text="TiltD" />
Text="DetectorSwing" />
<TextBox
Grid.Row="4"
Grid.Column="1"
@@ -199,7 +199,7 @@
Margin="0,0,4,0"
VerticalAlignment="Center"
Foreground="#333333"
Text="Dist" />
Text="FDD" />
<TextBox
Grid.Row="5"
Grid.Column="1"