Browse Source

新增垂直精度检测

KWD 7 months ago
parent
commit
d375802f56

+ 330 - 91
TeamAAS-VM/ViewModels/Product/VisionDynamicAccuracyAnalyzerViewModel.cs

@@ -19,10 +19,12 @@ using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using Team.FFFeederService.Interfaces;
 using Team.FFFeederService.Interfaces;
 using TeamAAS_VP.Core;
 using TeamAAS_VP.Core;
+using TeamAAS_VP.Core.PLCs;
 using TeamAAS_VP.Enums;
 using TeamAAS_VP.Enums;
 using TeamAAS_VP.Interfaces;
 using TeamAAS_VP.Interfaces;
 using TeamAAS_VP.Models;
 using TeamAAS_VP.Models;
 using TeamAAS_VP.Resources.Languages;
 using TeamAAS_VP.Resources.Languages;
+using TeamAAS_VP.Services;
 using static TeamAAS_VP.Core.StabilityAnalyzer;
 using static TeamAAS_VP.Core.StabilityAnalyzer;
 
 
 namespace TeamAAS_VP.ViewModels.Product
 namespace TeamAAS_VP.ViewModels.Product
@@ -39,10 +41,17 @@ namespace TeamAAS_VP.ViewModels.Product
         ISystemDatabaseService _systemDatabaseService;
         ISystemDatabaseService _systemDatabaseService;
         ICalibrationService _calibrationService;
         ICalibrationService _calibrationService;
         IConfigService _configService;
         IConfigService _configService;
+        IPlcService _plcService;
 
 
         //测试过程中控制取消的CTS
         //测试过程中控制取消的CTS
         CancellationTokenSource _cts;
         CancellationTokenSource _cts;
 
 
+        string manualToWork = "ns=4;s=DB_DriveControl|CylCtrl[6].Cmd.ManuToWork";
+        string manualToHome = "ns=4;s=DB_DriveControl|CylCtrl[6].Cmd.ManuToHome";
+        string inWork = "ns=4;s=DB_DriveControl|CylCtrl[6].Status.InWork";
+        string inHome = "ns=4;s=DB_DriveControl|CylCtrl[6].Status.InHome";
+
+
         #region 属性
         #region 属性
 
 
         private ProductModel _SelectProduct;
         private ProductModel _SelectProduct;
@@ -241,8 +250,7 @@ namespace TeamAAS_VP.ViewModels.Product
             get { return _precisionResult; }
             get { return _precisionResult; }
             set { SetProperty(ref _precisionResult, value); }
             set { SetProperty(ref _precisionResult, value); }
         }
         }
-
-        private int _ADelay = 300;
+        private int _ADelay = 3000;
         /// <summary>
         /// <summary>
         /// A点延时时间
         /// A点延时时间
         /// </summary>
         /// </summary>
@@ -252,7 +260,7 @@ namespace TeamAAS_VP.ViewModels.Product
             set { SetProperty(ref _ADelay, value); }
             set { SetProperty(ref _ADelay, value); }
         }
         }
 
 
-        private int _BDelay = 500;
+        private int _BDelay = 3000;
         /// <summary>
         /// <summary>
         /// B点延时时间
         /// B点延时时间
         /// </summary>
         /// </summary>
@@ -272,12 +280,35 @@ namespace TeamAAS_VP.ViewModels.Product
             set { SetProperty(ref _IsTakePhoto, value); }
             set { SetProperty(ref _IsTakePhoto, value); }
         }
         }
 
 
-        private int _ProIndex;
-        public int ProIndex
+        private bool _IsCylCtrl = true;
+        /// <summary>
+        /// 是否启用气缸IsVertical
+        /// </summary>
+        public bool IsCylCtrl
         {
         {
-            get { return _ProIndex; }
-            set { SetProperty(ref _ProIndex, value); }
+            get { return _IsCylCtrl; }
+            set { SetProperty(ref _IsCylCtrl, value); }
         }
         }
+
+        private bool _IsVertical = true;
+        /// <summary>
+        /// 是否启用垂直精度检测
+        /// </summary>
+        public bool IsVertical
+        {
+            get { return _IsVertical; }
+            set { SetProperty(ref _IsVertical, value); }
+        }
+
+        private float _Distance;
+
+        public float Distance
+        {
+            get { return _Distance; }
+            set { SetProperty(ref _Distance, value); }
+        }
+
+
         #endregion
         #endregion
 
 
         #region 命令
         #region 命令
@@ -324,7 +355,7 @@ namespace TeamAAS_VP.ViewModels.Product
 
 
         private DelegateCommand _ProcedureSelectionChangedCommand;
         private DelegateCommand _ProcedureSelectionChangedCommand;
         public DelegateCommand ProcedureSelectionChangedCommand =>
         public DelegateCommand ProcedureSelectionChangedCommand =>
-            _ProcedureSelectionChangedCommand ?? (_ProcedureSelectionChangedCommand = new DelegateCommand(ExecuteProcedureSelectionChangedCommand, () => !IsRunning).ObservesProperty(() => IsRunning));
+            _ProcedureSelectionChangedCommand ?? (_ProcedureSelectionChangedCommand = new DelegateCommand(ExecuteProcedureSelectionChangedCommand, () => !IsRunning).ObservesProperty(() => IsRunning).ObservesProperty(() => SelectProcedure));
 
 
         private DelegateCommand _SingleTestCommand;
         private DelegateCommand _SingleTestCommand;
         public DelegateCommand SingleTestCommand =>
         public DelegateCommand SingleTestCommand =>
@@ -343,7 +374,7 @@ namespace TeamAAS_VP.ViewModels.Product
 
 
         public VisionDynamicAccuracyAnalyzerViewModel(IRegionManager regionManager, IEventAggregator ea, IContainerProvider container, IDialogService dialogService,
         public VisionDynamicAccuracyAnalyzerViewModel(IRegionManager regionManager, IEventAggregator ea, IContainerProvider container, IDialogService dialogService,
             IFeederService feederService, IRobotService robotService, ICameraService cameraService, ISystemDatabaseService systemDatabaseService, ICalibrationService calibrationService,
             IFeederService feederService, IRobotService robotService, ICameraService cameraService, ISystemDatabaseService systemDatabaseService, ICalibrationService calibrationService,
-            IConfigService configService)
+            IConfigService configService, IPlcService plcService)
         {
         {
             _regionManager = regionManager;
             _regionManager = regionManager;
             _eventAggregator = ea;
             _eventAggregator = ea;
@@ -356,6 +387,7 @@ namespace TeamAAS_VP.ViewModels.Product
             MessageQueue = new SnackbarMessageQueue(TimeSpan.FromSeconds(1));
             MessageQueue = new SnackbarMessageQueue(TimeSpan.FromSeconds(1));
             _calibrationService = calibrationService;
             _calibrationService = calibrationService;
             _configService = configService;
             _configService = configService;
+            _plcService = plcService;
         }
         }
 
 
         #region 方法
         #region 方法
@@ -389,62 +421,141 @@ namespace TeamAAS_VP.ViewModels.Product
         /// </summary>
         /// </summary>
         async void ExecuteSingleTestCommand()
         async void ExecuteSingleTestCommand()
         {
         {
-            if (Robot == null || !Robot.IsConnected)
-            {
-                SendTaskMessage("机器人未连接,无法示教!");
-                return;
-            }
+            IsRunning = true;
+            _cts = new CancellationTokenSource();
+            CurrentProgress = 0;
+            SuccessCount = 0;
+            SuccessRate = 0;
+            FailCount = 0;
+            Message = "测试进行中...";
+            TestResults = new ObservableCollection<DynamicTestResult>();
 
 
-            if (Camera == null || !Camera.IsConnected)
+            try
             {
             {
-                SendTaskMessage("相机未连接,无法示教!");
-                return;
-            }
+                //弹窗提示是否进行连续测试
+                var result = System.Windows.MessageBox.Show("确定进行单次测试吗?", "提示", System.Windows.MessageBoxButton.YesNo, System.Windows.MessageBoxImage.Question);
+                if (result != System.Windows.MessageBoxResult.Yes)
+                {
+                    return;
+                }
 
 
-            //弹窗提示是否进行单次测试
-            var result = System.Windows.MessageBox.Show("确定进行单次测试吗?", "提示", System.Windows.MessageBoxButton.YesNo, System.Windows.MessageBoxImage.Question);
-            if (result != System.Windows.MessageBoxResult.Yes)
-            {
-                return;
-            }
+                var addressConfig = _configService.GetPlcAddresses();
+                var plc = _plcService.GetPlcByNumber(addressConfig.PlcNo) as OpcUaClientPLC;
+
+                if (Robot == null || !Robot.IsConnected)
+                {
+                    SendTaskMessage("机器人未连接,无法示教!");
+                    return;
+                }
+
+                if (IsTakePhoto)
+                {
+                    if (Camera == null || !Camera.IsConnected)
+                    {
+                        SendTaskMessage("相机未连接,无法示教!");
+                        return;
+                    }
+                }
 
 
-            IsRunning = true;
-            try
-            {
-                DateTime startTime = DateTime.Now;
                 //为机器人设置移动速度
                 //为机器人设置移动速度
                 await Robot.CalibParameAsync(new PickInfo(), MoveSpeed, 0, false, 0, 0);
                 await Robot.CalibParameAsync(new PickInfo(), MoveSpeed, 0, false, 0, 0);
 
 
-                //移动机器人至A点
-                bool isSuccess1 = await Robot.CalibMotionAsync(PointA, null);
-                if (!isSuccess1)
+
+                if (_cts.Token.IsCancellationRequested)
                 {
                 {
-                    SendTaskMessage("机器人移动到A点失败!");
+                    Message = "测试已取消!";
                     return;
                     return;
                 }
                 }
-                await Task.Delay(ADelay);
+                DateTime startTime = DateTime.Now;
 
 
-                //移动机器人至B点
-                isSuccess1 = await Robot.CalibMotionAsync(PointB, null);
-                if (!isSuccess1)
+                if (!IsCylCtrl)
                 {
                 {
-                    SendTaskMessage("机器人移动到B点失败!");
-                    return;
+                    //移动机器人至A点
+                    bool isSuccess1 = await Robot.CalibMotionAsync(PointA, null);
+                    if (!isSuccess1)
+                    {
+                        SendTaskMessage("机器人移动到A点失败!");
+                        return;
+                    }
+                    await Task.Delay(ADelay);
+                    if (_cts.Token.IsCancellationRequested)
+                    {
+                        Message = "测试已取消!";
+                        return;
+                    }
+
+                    //移动机器人至B点
+                    isSuccess1 = await Robot.CalibMotionAsync(PointB, null);
+                    if (!isSuccess1)
+                    {
+                        SendTaskMessage("机器人移动到B点失败!");
+                        return;
+                    }
+                    await Task.Delay(BDelay);
+                    if (_cts.Token.IsCancellationRequested)
+                    {
+                        Message = "测试已取消!";
+                        return;
+                    }
                 }
                 }
-                await Task.Delay(BDelay);
+                else
+                {
+                    //气缸升上去
+                    await plc.WriteNodeAsync(manualToWork, true);
+                    await Task.Delay(BDelay);
+                    await plc.ReadNodeAsync<bool>(inWork);
 
 
+                    if (_cts.Token.IsCancellationRequested)
+                    {
+                        Message = "测试已取消!";
+                        return;
+                    }
+                }
                 if (IsTakePhoto)
                 if (IsTakePhoto)
                 {
                 {
                     //相机拍照并处理
                     //相机拍照并处理
                     (bool isSuccess, double pixelX, double pixelY, double angleU, double transformX, double transformY) = await ExecutePhotoEx(CurrentProgress);
                     (bool isSuccess, double pixelX, double pixelY, double angleU, double transformX, double transformY) = await ExecutePhotoEx(CurrentProgress);
-                }
 
 
-                CycleTime = DateTime.Now.Subtract(startTime).TotalSeconds;
+                    CycleTime = DateTime.Now.Subtract(startTime).TotalSeconds;
+
+                    if (isSuccess)
+                    {
+                        SuccessCount++;
+                    }
+                    else
+                    {
+                        FailCount++;
+                    }
+                    TestResults.Add(new DynamicTestResult(CurrentProgress, isSuccess, PointB, CycleTime, pixelX, pixelY, angleU, transformX, transformY));
+                    OnTestResultAdded();
+
+                    CurrentProgress++;
+                    SuccessRate = (double)SuccessCount / CurrentProgress * 100;
+                }
+                else
+                {
+                    CycleTime = DateTime.Now.Subtract(startTime).TotalSeconds;
+                    SuccessCount++;
+                    CurrentProgress++;
+                    SuccessRate = (double)SuccessCount / CurrentProgress * 100;
+                }
+                if (IsCylCtrl)
+                {
+                    await plc.WriteNodeAsync(manualToHome, true);
+                    await Task.Delay(ADelay);
+                    //inHome 气杆在底部  InWork在上面
+                    await plc.ReadNodeAsync<bool>(inHome);
+                    if (_cts.Token.IsCancellationRequested)
+                    {
+                        Message = "测试已取消!";
+                        return;
+                    }
+                }
+                Message = "测试完成!";
             }
             }
             catch (Exception ex)
             catch (Exception ex)
             {
             {
-                LogHelper.WriteLogError("机器人移动到A点失败!", ex);
-                SendTaskMessage("机器人移动到A点失败!");
+                LogHelper.WriteLogError("视觉动态重复测试时出错!", ex);
             }
             }
             finally
             finally
             {
             {
@@ -465,6 +576,8 @@ namespace TeamAAS_VP.ViewModels.Product
             SuccessRate = 0;
             SuccessRate = 0;
             FailCount = 0;
             FailCount = 0;
             Message = "测试进行中...";
             Message = "测试进行中...";
+            int up = 1;
+            int down = 0;
             TestResults = new ObservableCollection<DynamicTestResult>();
             TestResults = new ObservableCollection<DynamicTestResult>();
 
 
             try
             try
@@ -476,16 +589,22 @@ namespace TeamAAS_VP.ViewModels.Product
                     return;
                     return;
                 }
                 }
 
 
+                var addressConfig = _configService.GetPlcAddresses();
+                var plc = _plcService.GetPlcByNumber(addressConfig.PlcNo) as OpcUaClientPLC;
+
                 if (Robot == null || !Robot.IsConnected)
                 if (Robot == null || !Robot.IsConnected)
                 {
                 {
                     SendTaskMessage("机器人未连接,无法示教!");
                     SendTaskMessage("机器人未连接,无法示教!");
                     return;
                     return;
                 }
                 }
 
 
-                if (Camera == null || !Camera.IsConnected)
+                if (IsTakePhoto)
                 {
                 {
-                    SendTaskMessage("相机未连接,无法示教!");
-                    return;
+                    if (Camera == null || !Camera.IsConnected)
+                    {
+                        SendTaskMessage("相机未连接,无法示教!");
+                        return;
+                    }
                 }
                 }
 
 
                 //为机器人设置移动速度
                 //为机器人设置移动速度
@@ -500,34 +619,75 @@ namespace TeamAAS_VP.ViewModels.Product
                     }
                     }
                     DateTime startTime = DateTime.Now;
                     DateTime startTime = DateTime.Now;
 
 
-                    //移动机器人至A点
-                    bool isSuccess1 = await Robot.CalibMotionAsync(PointA, null);
-                    if (!isSuccess1)
+                    if (IsVertical)
                     {
                     {
-                        SendTaskMessage("机器人移动到A点失败!");
-                        return;
+                        RPoint verticalPosition = PointB.Clone();
+                        if (CurrentProgress > (RepeatCount / 2))
+                        {
+                            verticalPosition.Z += up++ * Distance;
+                        }
+                        else
+                        {
+                            verticalPosition.Z -= down++ * Distance;
+                        }
+                        //移动机器人至B点
+                        bool isSuccess1 = await Robot.GoAsync(verticalPosition);
+                        if (!isSuccess1)
+                        {
+                            SendTaskMessage("机器人移动到B点失败!");
+                            return;
+                        }
+                        await Task.Delay(BDelay);
+                        if (_cts.Token.IsCancellationRequested)
+                        {
+                            Message = "测试已取消!";
+                            break;
+                        }
                     }
                     }
-                    await Task.Delay(ADelay);
-                    if (_cts.Token.IsCancellationRequested)
+                    else if (!IsCylCtrl)
                     {
                     {
-                        Message = "测试已取消!";
-                        break;
-                    }
+                        IsVertical = false;
+                        //移动机器人至A点
+                        bool isSuccess1 = await Robot.CalibMotionAsync(PointA, null);
+                        if (!isSuccess1)
+                        {
+                            SendTaskMessage("机器人移动到A点失败!");
+                            return;
+                        }
+                        await Task.Delay(ADelay);
+                        if (_cts.Token.IsCancellationRequested)
+                        {
+                            Message = "测试已取消!";
+                            break;
+                        }
 
 
-                    //移动机器人至B点
-                    isSuccess1 = await Robot.CalibMotionAsync(PointB, null);
-                    if (!isSuccess1)
-                    {
-                        SendTaskMessage("机器人移动到B点失败!");
-                        return;
+                        //移动机器人至B点
+                        isSuccess1 = await Robot.CalibMotionAsync(PointB, null);
+                        if (!isSuccess1)
+                        {
+                            SendTaskMessage("机器人移动到B点失败!");
+                            return;
+                        }
+                        await Task.Delay(BDelay);
+                        if (_cts.Token.IsCancellationRequested)
+                        {
+                            Message = "测试已取消!";
+                            break;
+                        }
                     }
                     }
-                    await Task.Delay(BDelay);
-                    if (_cts.Token.IsCancellationRequested)
+                    else
                     {
                     {
-                        Message = "测试已取消!";
-                        break;
-                    }
+                        //气缸升上去
+                        await plc.WriteNodeAsync(manualToWork, true);
+                        await Task.Delay(BDelay);
+                        await plc.ReadNodeAsync<bool>(inWork);
 
 
+                        if (_cts.Token.IsCancellationRequested)
+                        {
+                            Message = "测试已取消!";
+                            break;
+                        }
+                    }
                     if (IsTakePhoto)
                     if (IsTakePhoto)
                     {
                     {
                         //相机拍照并处理
                         //相机拍照并处理
@@ -556,6 +716,18 @@ namespace TeamAAS_VP.ViewModels.Product
                         CurrentProgress++;
                         CurrentProgress++;
                         SuccessRate = (double)SuccessCount / CurrentProgress * 100;
                         SuccessRate = (double)SuccessCount / CurrentProgress * 100;
                     }
                     }
+                    if (IsCylCtrl)
+                    {
+                        await plc.WriteNodeAsync(manualToHome, true);
+                        await Task.Delay(ADelay);
+                        //inHome 气杆在底部  InWork在上面
+                        await plc.ReadNodeAsync<bool>(inHome);
+                        if (_cts.Token.IsCancellationRequested)
+                        {
+                            Message = "测试已取消!";
+                            break;
+                        }
+                    }
                     SendTaskMessage($"测试进行中... {CurrentProgress}/{RepeatCount}");
                     SendTaskMessage($"测试进行中... {CurrentProgress}/{RepeatCount}");
                 }
                 }
                 if (CurrentProgress >= RepeatCount)
                 if (CurrentProgress >= RepeatCount)
@@ -565,7 +737,7 @@ namespace TeamAAS_VP.ViewModels.Product
             }
             }
             catch (Exception ex)
             catch (Exception ex)
             {
             {
-                LogHelper.WriteLogError("视觉态重复测试时出错!", ex);
+                LogHelper.WriteLogError("视觉态重复测试时出错!", ex);
             }
             }
             finally
             finally
             {
             {
@@ -1124,15 +1296,15 @@ namespace TeamAAS_VP.ViewModels.Product
                     bool succed = Camera.SetExposureTime(SelectProcedure.ExposureTime);
                     bool succed = Camera.SetExposureTime(SelectProcedure.ExposureTime);
                     if (!succed)
                     if (!succed)
                     {
                     {
-                        SendTaskMessage(Lang.相机曝光设置失败);
+                        SendTaskMessage("相机曝光设置失败");
                     }
                     }
                     succed = Camera.SetGain(SelectProcedure.Gain);
                     succed = Camera.SetGain(SelectProcedure.Gain);
                     if (!succed)
                     if (!succed)
                     {
                     {
-                        SendTaskMessage(Lang.相机增益设置失败);
+                        SendTaskMessage("相机增益设置失败");
                     }
                     }
                     DateTime nowtime = DateTime.Now;
                     DateTime nowtime = DateTime.Now;
-                    LogHelper.WriteLogInfo(Lang.开始采集图像);
+                    LogHelper.WriteLogInfo("开始采集图像");
                     var image = Camera.Grab();
                     var image = Camera.Grab();
                     if (image == null)
                     if (image == null)
                     {
                     {
@@ -1165,7 +1337,7 @@ namespace TeamAAS_VP.ViewModels.Product
                     //}
                     //}
                     Image = VisionTool.Inputs["InputImage"].Value as ICogImage;
                     Image = VisionTool.Inputs["InputImage"].Value as ICogImage;
                     // 3. 运行视觉工具
                     // 3. 运行视觉工具
-                    LogHelper.WriteLogInfo(Lang.开始运行视觉工具);
+                    LogHelper.WriteLogInfo("开始运行视觉工具");
                     VisionTool.Run();      //运行ToolBlock
                     VisionTool.Run();      //运行ToolBlock
 
 
                     if (VisionTool.RunStatus.Result == CogToolResultConstants.Accept)
                     if (VisionTool.RunStatus.Result == CogToolResultConstants.Accept)
@@ -1237,7 +1409,7 @@ namespace TeamAAS_VP.ViewModels.Product
                 catch (Exception ex)
                 catch (Exception ex)
                 {
                 {
                     SendTaskMessage(ex.Message);
                     SendTaskMessage(ex.Message);
-                    LogHelper.WriteLogError(Lang.执行相机取图并执行视觉工具组时出错, ex);
+                    LogHelper.WriteLogError("执行相机取图并执行视觉工具组时出错", ex);
                     outputCollection = null;
                     outputCollection = null;
                     return (false, 0d, 0d, 0d, 0d, 0d);
                     return (false, 0d, 0d, 0d, 0d, 0d);
                 }
                 }
@@ -1502,24 +1674,33 @@ namespace TeamAAS_VP.ViewModels.Product
         private void LoadConfig()
         private void LoadConfig()
         {
         {
             //配置文件路径:FilePath.ProductsPath//productName//VisionDynamicAccuracyAnalyzerConfig.json
             //配置文件路径:FilePath.ProductsPath//productName//VisionDynamicAccuracyAnalyzerConfig.json
-            string configPath = System.IO.Path.Combine(FilePath.ProductsPath, SelectProduct.Name, "VisionDynamicAccuracyAnalyzerConfig.json");
-            if (System.IO.File.Exists(configPath))
+            string configPath = Path.Combine(FilePath.ProductsPath, SelectProduct.Name, "VisionDynamicAccuracyAnalyzerConfig.json");
+            if (File.Exists(configPath))
             {
             {
                 try
                 try
                 {
                 {
-                    string json = System.IO.File.ReadAllText(configPath);
+                    string json = File.ReadAllText(configPath);
                     var ConfigModel = JsonConvert.DeserializeObject<VisionDynamicAccuracyAnalyzerConfigModel>(json);
                     var ConfigModel = JsonConvert.DeserializeObject<VisionDynamicAccuracyAnalyzerConfigModel>(json);
-                    //加载点位A、B
-                    PointA = ConfigModel.PointA;
-                    PointB = ConfigModel.PointB;
+                    //加载点位界面参数
+                    this.PointA = ConfigModel.PointA;
+                    this.PointB = ConfigModel.PointB;
+                    this.MoveSpeed = ConfigModel.RobotMoveSpeed;
+                    this.RepeatCount = ConfigModel.TestCount;
+                    this.ADelay = ConfigModel.ADelay;
+                    this.BDelay = ConfigModel.BDelay;
+                    this.IsCylCtrl = ConfigModel.IsCylCtrl;
+                    this.IsTakePhoto = ConfigModel.IsTakePhoto;
+                    this.IsVertical = ConfigModel.IsVertical;
+                    this.Distance = ConfigModel.Distance;
+
                     //加载选中视觉流程
                     //加载选中视觉流程
                     var procedure = ProcedureModels.FirstOrDefault(p => p.Id == ConfigModel.SelectProcedureId);
                     var procedure = ProcedureModels.FirstOrDefault(p => p.Id == ConfigModel.SelectProcedureId);
                     if (procedure != null)
                     if (procedure != null)
                     {
                     {
-                        SelectProcedure = procedure;
+                        this.SelectProcedure = procedure;
+                        this.Camera = _cameraService.GetCamera(SelectProcedure.CameraId);
                     }
                     }
-                    MoveSpeed = ConfigModel.RobotMoveSpeed;
-                    RepeatCount = ConfigModel.TestCount;
+
                 }
                 }
                 catch (Exception ex)
                 catch (Exception ex)
                 {
                 {
@@ -1536,25 +1717,31 @@ namespace TeamAAS_VP.ViewModels.Product
             try
             try
             {
             {
                 //配置文件路径:FilePath.ProductsPath//productName//VisionDynamicAccuracyAnalyzerConfig.json
                 //配置文件路径:FilePath.ProductsPath//productName//VisionDynamicAccuracyAnalyzerConfig.json
-                string configPath = System.IO.Path.Combine(FilePath.ProductsPath, SelectProduct.Name, "VisionDynamicAccuracyAnalyzerConfig.json");
+                string configPath = Path.Combine(FilePath.ProductsPath, SelectProduct.Name, "VisionDynamicAccuracyAnalyzerConfig.json");
                 var ConfigModel = new VisionDynamicAccuracyAnalyzerConfigModel
                 var ConfigModel = new VisionDynamicAccuracyAnalyzerConfigModel
                 {
                 {
-                    PointA = PointA,
-                    PointB = PointB,
-                    SelectProcedureId = SelectProcedure?.Id ?? Guid.Empty,
-                    SelectProcedureName = SelectProcedure?.Name ?? "",
-                    RobotMoveSpeed = MoveSpeed,
-                    TestCount = RepeatCount
+                    PointA = this.PointA,
+                    PointB = this.PointB,
+                    SelectProcedureId = this.SelectProcedure?.Id ?? Guid.Empty,
+                    SelectProcedureName = this.SelectProcedure?.Name ?? "",
+                    RobotMoveSpeed = this.MoveSpeed,
+                    TestCount = this.RepeatCount,
+                    ADelay = this.ADelay,
+                    BDelay = this.BDelay,
+                    IsCylCtrl = this.IsCylCtrl,
+                    IsTakePhoto = this.IsTakePhoto,
+                    IsVertical = this.IsVertical,
+                    Distance = this.Distance,
                 };
                 };
                 //如果配置文件夹不存在则创建
                 //如果配置文件夹不存在则创建
-                var configDir = System.IO.Path.GetDirectoryName(configPath);
+                var configDir = Path.GetDirectoryName(configPath);
                 if (!Directory.Exists(configDir))
                 if (!Directory.Exists(configDir))
                 {
                 {
                     Directory.CreateDirectory(configDir);
                     Directory.CreateDirectory(configDir);
                 }
                 }
 
 
                 string json = JsonConvert.SerializeObject(ConfigModel, Formatting.Indented);
                 string json = JsonConvert.SerializeObject(ConfigModel, Formatting.Indented);
-                System.IO.File.WriteAllText(configPath, json);
+                File.WriteAllText(configPath, json);
             }
             }
             catch (Exception ex)
             catch (Exception ex)
             {
             {
@@ -1626,6 +1813,58 @@ namespace TeamAAS_VP.ViewModels.Product
                 set { SetProperty(ref _SelectProcedureName, value); }
                 set { SetProperty(ref _SelectProcedureName, value); }
             }
             }
 
 
+            private int _ADelay;
+
+            public int ADelay
+            {
+                get { return _ADelay; }
+                set { _ADelay = value; }
+            }
+
+            private int _BDelay;
+
+            public int BDelay
+            {
+                get { return _BDelay; }
+                set { _BDelay = value; }
+            }
+
+            private bool _IsCylCtrl;
+
+            public bool IsCylCtrl
+            {
+                get { return _IsCylCtrl; }
+                set { _IsCylCtrl = value; }
+            }
+
+            private bool _IsTakePhoto;
+
+            public bool IsTakePhoto
+            {
+                get { return _IsTakePhoto; }
+                set { _IsTakePhoto = value; }
+            }
+
+            private bool _IsVertical = true;
+            /// <summary>
+            /// 是否启用垂直精度检测
+            /// </summary>
+            public bool IsVertical
+            {
+                get { return _IsVertical; }
+                set { SetProperty(ref _IsVertical, value); }
+            }
+
+            private float _Distance;
+
+            public float Distance
+            {
+                get { return _Distance; }
+                set { SetProperty(ref _Distance, value); }
+            }
+
+
+
         }
         }
 
 
     }
     }

+ 244 - 218
TeamAAS-VM/Views/Product/VisionDynamicAccuracyAnalyzer.xaml

@@ -27,6 +27,7 @@
              HorizontalAlignment="Stretch"
              HorizontalAlignment="Stretch"
              VerticalAlignment="Stretch"
              VerticalAlignment="Stretch"
              FontFamily="{DynamicResource DefaultFont}">
              FontFamily="{DynamicResource DefaultFont}">
+
     <prism:Dialog.WindowStyle>
     <prism:Dialog.WindowStyle>
         <Style TargetType="Window">
         <Style TargetType="Window">
             <Setter Property="prism:Dialog.WindowStartupLocation"
             <Setter Property="prism:Dialog.WindowStartupLocation"
@@ -112,10 +113,10 @@
         </Grid.ColumnDefinitions>
         </Grid.ColumnDefinitions>
 
 
         <!-- 左侧控制面板 -->
         <!-- 左侧控制面板 -->
-        <ScrollViewer >
+        <ScrollViewer>
             <Border Grid.Column="0"
             <Border Grid.Column="0"
-        BorderBrush="#BDC3C7"
-        BorderThickness="0 0 1 0">
+                    BorderBrush="#BDC3C7"
+                    BorderThickness="0 0 1 0">
                 <Grid>
                 <Grid>
                     <Grid.RowDefinitions>
                     <Grid.RowDefinitions>
                         <RowDefinition Height="Auto" />
                         <RowDefinition Height="Auto" />
@@ -123,17 +124,17 @@
                         <RowDefinition Height="Auto" />
                         <RowDefinition Height="Auto" />
                         <RowDefinition Height="Auto" />
                         <RowDefinition Height="Auto" />
                         <RowDefinition Height="*"
                         <RowDefinition Height="*"
-                           MinHeight="150" />
+                                       MinHeight="150" />
                         <RowDefinition Height="Auto" />
                         <RowDefinition Height="Auto" />
                     </Grid.RowDefinitions>
                     </Grid.RowDefinitions>
 
 
                     <!-- 机器人位置设置 -->
                     <!-- 机器人位置设置 -->
                     <Border Grid.Row="0"
                     <Border Grid.Row="0"
-                Background="#ECF0F1"
-                Padding="10">
+                            Background="#ECF0F1"
+                            Padding="10">
                         <StackPanel>
                         <StackPanel>
                             <TextBlock Style="{StaticResource TitleStyle}"
                             <TextBlock Style="{StaticResource TitleStyle}"
-                           Text="机器人位置设置" />
+                                       Text="机器人位置设置" />
 
 
                             <Grid Margin="0 10 0 0">
                             <Grid Margin="0 10 0 0">
                                 <Grid.RowDefinitions>
                                 <Grid.RowDefinitions>
@@ -144,7 +145,7 @@
 
 
                                 <!-- A点坐标 -->
                                 <!-- A点坐标 -->
                                 <Grid Grid.Row="0"
                                 <Grid Grid.Row="0"
-                          Margin="0 0 0 10">
+                                      Margin="0 0 0 10">
                                     <Grid.ColumnDefinitions>
                                     <Grid.ColumnDefinitions>
                                         <ColumnDefinition Width="Auto" />
                                         <ColumnDefinition Width="Auto" />
                                         <ColumnDefinition Width="*" />
                                         <ColumnDefinition Width="*" />
@@ -152,36 +153,36 @@
                                     </Grid.ColumnDefinitions>
                                     </Grid.ColumnDefinitions>
 
 
                                     <TextBlock Text="A点坐标:"
                                     <TextBlock Text="A点坐标:"
-                                   Grid.Column="0"
-                                   VerticalAlignment="Center" />
+                                               Grid.Column="0"
+                                               VerticalAlignment="Center" />
                                     <TextBox Grid.Column="1"
                                     <TextBox Grid.Column="1"
-                                 d:Text="X:0.000 Y:0.000 Z:0.000 U:0.000 V:0.000 W:0.000"
-                                 ToolTip="机器人A点位置坐标"
-                                 IsReadOnly="True"
-                                 Background="#F8F9FA">
+                                             d:Text="X:0.000 Y:0.000 Z:0.000 U:0.000 V:0.000 W:0.000"
+                                             ToolTip="机器人A点位置坐标"
+                                             IsReadOnly="True"
+                                             Background="#F8F9FA">
                                         <TextBox.Text>
                                         <TextBox.Text>
                                             <MultiBinding StringFormat="X:{0:f3} Y:{1:f3} Z:{2:f3} U:{3:f3} V:{4:f3} W:{5:f3}">
                                             <MultiBinding StringFormat="X:{0:f3} Y:{1:f3} Z:{2:f3} U:{3:f3} V:{4:f3} W:{5:f3}">
-                                                <Binding Path="PointA.X"/>
-                                                <Binding Path="PointA.Y"/>
-                                                <Binding Path="PointA.Z"/>
-                                                <Binding Path="PointA.U"/>
-                                                <Binding Path="PointA.V"/>
-                                                <Binding Path="PointA.W"/>
+                                                <Binding Path="PointA.X" />
+                                                <Binding Path="PointA.Y" />
+                                                <Binding Path="PointA.Z" />
+                                                <Binding Path="PointA.U" />
+                                                <Binding Path="PointA.V" />
+                                                <Binding Path="PointA.W" />
                                             </MultiBinding>
                                             </MultiBinding>
                                         </TextBox.Text>
                                         </TextBox.Text>
                                     </TextBox>
                                     </TextBox>
                                     <Button Grid.Column="2"
                                     <Button Grid.Column="2"
-                                Content="示教"
-                                Command="{Binding TeachPointACommand}"
-                                Background="#3498DB"
-                                Foreground="White"
-                                Width="60"
-                                Margin="5,0,0,0" />
+                                            Content="示教"
+                                            Command="{Binding TeachPointACommand}"
+                                            Background="#3498DB"
+                                            Foreground="White"
+                                            Width="60"
+                                            Margin="5,0,0,0" />
                                 </Grid>
                                 </Grid>
 
 
                                 <!-- B点坐标 -->
                                 <!-- B点坐标 -->
                                 <Grid Grid.Row="1"
                                 <Grid Grid.Row="1"
-                          Margin="0 0 0 10">
+                                      Margin="0 0 0 10">
                                     <Grid.ColumnDefinitions>
                                     <Grid.ColumnDefinitions>
                                         <ColumnDefinition Width="Auto" />
                                         <ColumnDefinition Width="Auto" />
                                         <ColumnDefinition Width="*" />
                                         <ColumnDefinition Width="*" />
@@ -189,31 +190,31 @@
                                     </Grid.ColumnDefinitions>
                                     </Grid.ColumnDefinitions>
 
 
                                     <TextBlock Text="B点坐标:"
                                     <TextBlock Text="B点坐标:"
-                                   Grid.Column="0"
-                                   VerticalAlignment="Center" />
+                                               Grid.Column="0"
+                                               VerticalAlignment="Center" />
                                     <TextBox Grid.Column="1"
                                     <TextBox Grid.Column="1"
-                                 d:Text="X:100.000 Y:50.000 Z:0.000 U:0.000 V:0.000 W:0.000"
-                                 ToolTip="机器人B点拍照位置坐标"
-                                 IsReadOnly="True"
-                                 Background="#F8F9FA" >
+                                             d:Text="X:100.000 Y:50.000 Z:0.000 U:0.000 V:0.000 W:0.000"
+                                             ToolTip="机器人B点拍照位置坐标"
+                                             IsReadOnly="True"
+                                             Background="#F8F9FA">
                                         <TextBox.Text>
                                         <TextBox.Text>
                                             <MultiBinding StringFormat="X:{0:f3} Y:{1:f3} Z:{2:f3} U:{3:f3} V:{4:f3} W:{5:f3}">
                                             <MultiBinding StringFormat="X:{0:f3} Y:{1:f3} Z:{2:f3} U:{3:f3} V:{4:f3} W:{5:f3}">
-                                                <Binding Path="PointB.X"/>
-                                                <Binding Path="PointB.Y"/>
-                                                <Binding Path="PointB.Z"/>
-                                                <Binding Path="PointB.U"/>
-                                                <Binding Path="PointB.V"/>
-                                                <Binding Path="PointB.W"/>
+                                                <Binding Path="PointB.X" />
+                                                <Binding Path="PointB.Y" />
+                                                <Binding Path="PointB.Z" />
+                                                <Binding Path="PointB.U" />
+                                                <Binding Path="PointB.V" />
+                                                <Binding Path="PointB.W" />
                                             </MultiBinding>
                                             </MultiBinding>
                                         </TextBox.Text>
                                         </TextBox.Text>
                                     </TextBox>
                                     </TextBox>
                                     <Button Grid.Column="2"
                                     <Button Grid.Column="2"
-                                Content="示教"
-                                Command="{Binding TeachPointBCommand}"
-                                Background="#3498DB"
-                                Foreground="White"
-                                Width="60"
-                                Margin="5,0,0,0" />
+                                            Content="示教"
+                                            Command="{Binding TeachPointBCommand}"
+                                            Background="#3498DB"
+                                            Foreground="White"
+                                            Width="60"
+                                            Margin="5,0,0,0" />
                                 </Grid>
                                 </Grid>
 
 
                                 <!-- 视觉流程选择 -->
                                 <!-- 视觉流程选择 -->
@@ -224,12 +225,12 @@
                                     </Grid.ColumnDefinitions>
                                     </Grid.ColumnDefinitions>
 
 
                                     <TextBlock Text="视觉流程:"
                                     <TextBlock Text="视觉流程:"
-                                   Grid.Column="0"
-                                   VerticalAlignment="Center" />
+                                               Grid.Column="0"
+                                               VerticalAlignment="Center" />
                                     <ComboBox Grid.Column="1"
                                     <ComboBox Grid.Column="1"
-                                  ItemsSource="{Binding ProcedureModels, Mode=TwoWay}"
-                                  SelectedItem="{Binding SelectProcedure, Mode=TwoWay}"
-                                  ToolTip="选择视觉处理流程">
+                                              ItemsSource="{Binding ProcedureModels, Mode=TwoWay}"
+                                              SelectedItem="{Binding SelectProcedure, Mode=TwoWay}"
+                                              ToolTip="选择视觉处理流程">
                                         <ComboBox.ItemTemplate>
                                         <ComboBox.ItemTemplate>
                                             <DataTemplate>
                                             <DataTemplate>
                                                 <TextBlock Text="{Binding Name}" />
                                                 <TextBlock Text="{Binding Name}" />
@@ -248,11 +249,11 @@
 
 
                     <!-- 测试参数设置 -->
                     <!-- 测试参数设置 -->
                     <Border Grid.Row="1"
                     <Border Grid.Row="1"
-                Background="#F8F9FA"
-                Padding="10">
+                            Background="#F8F9FA"
+                            Padding="10">
                         <StackPanel>
                         <StackPanel>
                             <TextBlock Style="{StaticResource TitleStyle}"
                             <TextBlock Style="{StaticResource TitleStyle}"
-                           Text="测试参数设置" />
+                                       Text="测试参数设置" />
 
 
                             <Grid Margin="0 10 0 0">
                             <Grid Margin="0 10 0 0">
                                 <Grid.ColumnDefinitions>
                                 <Grid.ColumnDefinitions>
@@ -260,19 +261,20 @@
                                     <ColumnDefinition Width="*" />
                                     <ColumnDefinition Width="*" />
                                     <ColumnDefinition Width="*" />
                                     <ColumnDefinition Width="*" />
                                     <ColumnDefinition Width="*" />
                                     <ColumnDefinition Width="*" />
+                                    <ColumnDefinition Width="*" />
                                 </Grid.ColumnDefinitions>
                                 </Grid.ColumnDefinitions>
 
 
                                 <!-- 重复次数 -->
                                 <!-- 重复次数 -->
                                 <StackPanel Grid.Column="0">
                                 <StackPanel Grid.Column="0">
                                     <TextBlock Text="重复次数:" />
                                     <TextBlock Text="重复次数:" />
                                     <mah:NumericUpDown Value="{Binding RepeatCount, Mode=TwoWay}"
                                     <mah:NumericUpDown Value="{Binding RepeatCount, Mode=TwoWay}"
-                                           Minimum="1"
-                                           Maximum="1000"
-                                           d:Value="50"
-                                           TextAlignment="Center"
-                                           HorizontalContentAlignment="Center"
-                                           HorizontalAlignment="Stretch"
-                                           IsEnabled="{Binding IsRunning, Converter={StaticResource InvertBooleanConverter}}" />
+                                                       Minimum="1"
+                                                       Maximum="1000"
+                                                       d:Value="50"
+                                                       TextAlignment="Center"
+                                                       HorizontalContentAlignment="Center"
+                                                       HorizontalAlignment="Stretch"
+                                                       IsEnabled="{Binding IsRunning, Converter={StaticResource InvertBooleanConverter}}" />
                                 </StackPanel>
                                 </StackPanel>
 
 
                                 <!-- 移动速度 -->
                                 <!-- 移动速度 -->
@@ -280,15 +282,14 @@
                                             Margin="10,0,0,0">
                                             Margin="10,0,0,0">
                                     <TextBlock Text="移动速度(%):" />
                                     <TextBlock Text="移动速度(%):" />
                                     <mah:NumericUpDown Value="{Binding MoveSpeed, Mode=TwoWay}"
                                     <mah:NumericUpDown Value="{Binding MoveSpeed, Mode=TwoWay}"
-                                           Minimum="1"
-                                           Maximum="100"
-                                           d:Value="50"
-                                           TextAlignment="Center"
-                                           HorizontalContentAlignment="Center"
-                                           HorizontalAlignment="Stretch"
-                                           IsEnabled="{Binding IsRunning, Converter={StaticResource InvertBooleanConverter}}" />
+                                                       Minimum="1"
+                                                       Maximum="100"
+                                                       d:Value="50"
+                                                       TextAlignment="Center"
+                                                       HorizontalContentAlignment="Center"
+                                                       HorizontalAlignment="Stretch"
+                                                       IsEnabled="{Binding IsRunning, Converter={StaticResource InvertBooleanConverter}}" />
                                 </StackPanel>
                                 </StackPanel>
-
                                 <!-- A点延时 -->
                                 <!-- A点延时 -->
                                 <StackPanel Grid.Column="2"
                                 <StackPanel Grid.Column="2"
                                             Margin="10,0,0,0">
                                             Margin="10,0,0,0">
@@ -313,6 +314,18 @@
                                                        HorizontalContentAlignment="Center"
                                                        HorizontalContentAlignment="Center"
                                                        HorizontalAlignment="Stretch"
                                                        HorizontalAlignment="Stretch"
                                                        IsEnabled="{Binding IsRunning, Converter={StaticResource InvertBooleanConverter}}" />
                                                        IsEnabled="{Binding IsRunning, Converter={StaticResource InvertBooleanConverter}}" />
+
+                                </StackPanel>
+                                <StackPanel Grid.Column="4"
+                                            Margin="10,0,0,0">
+                                    <TextBlock Text="垂直步进距离(ms):" />
+                                    <uControl:myNumericUpDowm MinWidth="100"
+                                                              Interval="0.1"
+                                                              Maximum="10"
+                                                              Minimum="0"
+                                                              StringFormat="{}{0:N3} mm"
+                                                              Value="{Binding Distance,Mode=TwoWay}"
+                                                              Margin="10,0" />
                                 </StackPanel>
                                 </StackPanel>
                             </Grid>
                             </Grid>
 
 
@@ -322,63 +335,76 @@
 
 
                     <!-- 测试控制区域 -->
                     <!-- 测试控制区域 -->
                     <Border Grid.Row="2"
                     <Border Grid.Row="2"
-                Background="#ECF0F1"
-                Padding="10">
+                            Background="#ECF0F1"
+                            Padding="10">
                         <StackPanel>
                         <StackPanel>
                             <TextBlock Style="{StaticResource TitleStyle}"
                             <TextBlock Style="{StaticResource TitleStyle}"
-                           Text="测试控制" />
+                                       Text="测试控制" />
 
 
                             <WrapPanel HorizontalAlignment="Center"
                             <WrapPanel HorizontalAlignment="Center"
                                        Margin="0 10 0 0">
                                        Margin="0 10 0 0">
+                                <CheckBox Content="启用垂直检测"
+                                          Foreground="Black"
+                                          Style="{StaticResource MaterialDesignCheckBox}"
+                                          VerticalAlignment="Center"
+                                          IsChecked="{Binding IsVertical}"
+                                          Margin="10,0"
+                                          FontSize="15" />
+                                <CheckBox Content="启用气缸"
+                                          Foreground="Black"
+                                          Style="{StaticResource MaterialDesignCheckBox}"
+                                          VerticalAlignment="Center"
+                                          IsChecked="{Binding IsCylCtrl}"
+                                          Margin="10,0"
+                                          FontSize="15" />
                                 <CheckBox Content="启用拍照"
                                 <CheckBox Content="启用拍照"
                                           Foreground="Black"
                                           Foreground="Black"
                                           Style="{StaticResource MaterialDesignCheckBox}"
                                           Style="{StaticResource MaterialDesignCheckBox}"
                                           VerticalAlignment="Center"
                                           VerticalAlignment="Center"
                                           IsChecked="{Binding IsTakePhoto}"
                                           IsChecked="{Binding IsTakePhoto}"
                                           Margin="10,0"
                                           Margin="10,0"
-                                          FontSize="15"/>
-
+                                          FontSize="15" />
                                 <Button Content="单次测试"
                                 <Button Content="单次测试"
-                            Background="#3498DB"
-                            Foreground="White"
-                            MinWidth="100"
-                            Height="35"
-                            FontWeight="Bold"
-                            Command="{Binding SingleTestCommand}"
-                            IsEnabled="{Binding IsRunning, Converter={StaticResource InvertBooleanConverter}}" />
+                                        Background="#3498DB"
+                                        Foreground="White"
+                                        MinWidth="100"
+                                        Height="35"
+                                        FontWeight="Bold"
+                                        Command="{Binding SingleTestCommand}"
+                                        IsEnabled="{Binding IsRunning, Converter={StaticResource InvertBooleanConverter}}" />
 
 
                                 <Button Content="连续测试"
                                 <Button Content="连续测试"
-                            Background="#27AE60"
-                            Foreground="White"
-                            MinWidth="100"
-                            Height="35"
-                            FontWeight="Bold"
-                            Command="{Binding StartTestCommand}" />
+                                        Background="#27AE60"
+                                        Foreground="White"
+                                        MinWidth="100"
+                                        Height="35"
+                                        FontWeight="Bold"
+                                        Command="{Binding StartTestCommand}" />
 
 
                                 <Button Content="停止"
                                 <Button Content="停止"
-                            Background="#E74C3C"
-                            Foreground="White"
-                            MinWidth="100"
-                            Height="35"
-                            Command="{Binding StopTestCommand}" />
+                                        Background="#E74C3C"
+                                        Foreground="White"
+                                        MinWidth="100"
+                                        Height="35"
+                                        Command="{Binding StopTestCommand}" />
 
 
                                 <Button Content="暂停"
                                 <Button Content="暂停"
-                            Background="#F39C12"
-                            Foreground="White"
-                            MinWidth="100"
-                            Height="35"
-                            Command="{Binding PauseTestCommand}" />
+                                        Background="#F39C12"
+                                        Foreground="White"
+                                        MinWidth="100"
+                                        Height="35"
+                                        Command="{Binding PauseTestCommand}" />
                             </WrapPanel>
                             </WrapPanel>
                         </StackPanel>
                         </StackPanel>
                     </Border>
                     </Border>
 
 
                     <!-- 进度显示 -->
                     <!-- 进度显示 -->
                     <Border Grid.Row="3"
                     <Border Grid.Row="3"
-                Background="White"
-                Padding="10">
+                            Background="White"
+                            Padding="10">
                         <StackPanel>
                         <StackPanel>
                             <TextBlock Style="{StaticResource TitleStyle}"
                             <TextBlock Style="{StaticResource TitleStyle}"
-                           Text="测试进度" />
+                                       Text="测试进度" />
 
 
                             <Grid Margin="0 10 0 0">
                             <Grid Margin="0 10 0 0">
                                 <Grid.RowDefinitions>
                                 <Grid.RowDefinitions>
@@ -387,74 +413,74 @@
                                 </Grid.RowDefinitions>
                                 </Grid.RowDefinitions>
 
 
                                 <ProgressBar Grid.Row="0"
                                 <ProgressBar Grid.Row="0"
-                                 Height="25"
-                                 Margin="5"
-                                 Minimum="0"
-                                 Maximum="{Binding RepeatCount}"
-                                 Value="{Binding CurrentProgress}"
-                                 IsEnabled="False"
-                                 d:Maximum="100"
-                                 d:Value="50" />
+                                             Height="25"
+                                             Margin="5"
+                                             Minimum="0"
+                                             Maximum="{Binding RepeatCount}"
+                                             Value="{Binding CurrentProgress}"
+                                             IsEnabled="False"
+                                             d:Maximum="100"
+                                             d:Value="50" />
 
 
                                 <TextBlock Grid.Row="1"
                                 <TextBlock Grid.Row="1"
-                               HorizontalAlignment="Center"
-                               FontSize="12"
-                               Foreground="#7F8C8D"
-                               d:Text="等待开始..."
-                               Text="{Binding Message}" />
+                                           HorizontalAlignment="Center"
+                                           FontSize="12"
+                                           Foreground="#7F8C8D"
+                                           d:Text="等待开始..."
+                                           Text="{Binding Message}" />
                             </Grid>
                             </Grid>
 
 
                             <!-- 实时统计信息 -->
                             <!-- 实时统计信息 -->
                             <WrapPanel Margin="0 15 0 0"
                             <WrapPanel Margin="0 15 0 0"
-                           HorizontalAlignment="Center">
+                                       HorizontalAlignment="Center">
                                 <Border Background="#3498DB"
                                 <Border Background="#3498DB"
-                            Padding="10 5"
-                            Margin="5"
-                            CornerRadius="3">
+                                        Padding="10 5"
+                                        Margin="5"
+                                        CornerRadius="3">
                                     <StackPanel>
                                     <StackPanel>
                                         <TextBlock Text="当前循环"
                                         <TextBlock Text="当前循环"
-                                       Foreground="White"
-                                       FontSize="11" />
+                                                   Foreground="White"
+                                                   FontSize="11" />
                                         <TextBlock Text="{Binding CurrentProgress}"
                                         <TextBlock Text="{Binding CurrentProgress}"
-                                       d:Text="1"
-                                       Foreground="White"
-                                       FontSize="16"
-                                       FontWeight="Bold"
-                                       HorizontalAlignment="Center" />
+                                                   d:Text="1"
+                                                   Foreground="White"
+                                                   FontSize="16"
+                                                   FontWeight="Bold"
+                                                   HorizontalAlignment="Center" />
                                     </StackPanel>
                                     </StackPanel>
                                 </Border>
                                 </Border>
 
 
                                 <Border Background="#2ECC71"
                                 <Border Background="#2ECC71"
-                            Padding="10 5"
-                            Margin="5"
-                            CornerRadius="3">
+                                        Padding="10 5"
+                                        Margin="5"
+                                        CornerRadius="3">
                                     <StackPanel>
                                     <StackPanel>
                                         <TextBlock Text="成功率"
                                         <TextBlock Text="成功率"
-                                       Foreground="White"
-                                       FontSize="11" />
+                                                   Foreground="White"
+                                                   FontSize="11" />
                                         <TextBlock Text="{Binding SuccessRate, StringFormat={}{0:F1}%}"
                                         <TextBlock Text="{Binding SuccessRate, StringFormat={}{0:F1}%}"
-                                       d:Text="100%"
-                                       Foreground="White"
-                                       FontSize="16"
-                                       FontWeight="Bold"
-                                       HorizontalAlignment="Center" />
+                                                   d:Text="100%"
+                                                   Foreground="White"
+                                                   FontSize="16"
+                                                   FontWeight="Bold"
+                                                   HorizontalAlignment="Center" />
                                     </StackPanel>
                                     </StackPanel>
                                 </Border>
                                 </Border>
 
 
                                 <Border Background="#9B59B6"
                                 <Border Background="#9B59B6"
-                            Padding="10 5"
-                            Margin="5"
-                            CornerRadius="3">
+                                        Padding="10 5"
+                                        Margin="5"
+                                        CornerRadius="3">
                                     <StackPanel>
                                     <StackPanel>
                                         <TextBlock Text="往返时间"
                                         <TextBlock Text="往返时间"
-                                       Foreground="White"
-                                       FontSize="11" />
+                                                   Foreground="White"
+                                                   FontSize="11" />
                                         <TextBlock Text="{Binding CycleTime, StringFormat={}{0:F2}s}"
                                         <TextBlock Text="{Binding CycleTime, StringFormat={}{0:F2}s}"
-                                       d:Text="2.34s"
-                                       Foreground="White"
-                                       FontSize="16"
-                                       FontWeight="Bold"
-                                       HorizontalAlignment="Center" />
+                                                   d:Text="2.34s"
+                                                   Foreground="White"
+                                                   FontSize="16"
+                                                   FontWeight="Bold"
+                                                   HorizontalAlignment="Center" />
                                     </StackPanel>
                                     </StackPanel>
                                 </Border>
                                 </Border>
                             </WrapPanel>
                             </WrapPanel>
@@ -463,8 +489,8 @@
 
 
                     <!-- 测试结果列表 -->
                     <!-- 测试结果列表 -->
                     <Border Grid.Row="4"
                     <Border Grid.Row="4"
-                Background="White"
-                Padding="10">
+                            Background="White"
+                            Padding="10">
                         <Grid>
                         <Grid>
                             <Grid.RowDefinitions>
                             <Grid.RowDefinitions>
                                 <RowDefinition Height="Auto" />
                                 <RowDefinition Height="Auto" />
@@ -472,51 +498,51 @@
                             </Grid.RowDefinitions>
                             </Grid.RowDefinitions>
 
 
                             <StackPanel Grid.Row="0"
                             <StackPanel Grid.Row="0"
-                            Orientation="Horizontal">
+                                        Orientation="Horizontal">
                                 <TextBlock Style="{StaticResource TitleStyle}"
                                 <TextBlock Style="{StaticResource TitleStyle}"
-                               Text="测试结果列表" />
+                                           Text="测试结果列表" />
                                 <TextBlock Margin="10,0,0,0"
                                 <TextBlock Margin="10,0,0,0"
-                               VerticalAlignment="Center"
-                               Foreground="#7F8C8D"
-                               Text="(显示最近20次结果)" />
+                                           VerticalAlignment="Center"
+                                           Foreground="#7F8C8D"
+                                           Text="(显示最近20次结果)" />
                             </StackPanel>
                             </StackPanel>
 
 
                             <DataGrid x:Name="dgResults"
                             <DataGrid x:Name="dgResults"
-                          Grid.Row="1"
-                          Style="{StaticResource DataGridStyle}"
-                          MaxHeight="250"
-                          AutoGenerateColumns="False"
-                          CanUserAddRows="False"
-                          IsReadOnly="True"
-                          ItemsSource="{Binding TestResults}">
+                                      Grid.Row="1"
+                                      Style="{StaticResource DataGridStyle}"
+                                      MaxHeight="250"
+                                      AutoGenerateColumns="False"
+                                      CanUserAddRows="False"
+                                      IsReadOnly="True"
+                                      ItemsSource="{Binding TestResults}">
                                 <DataGrid.Columns>
                                 <DataGrid.Columns>
                                     <DataGridTextColumn Header="序号"
                                     <DataGridTextColumn Header="序号"
-                                            Binding="{Binding Index}"
-                                            MinWidth="50" />
+                                                        Binding="{Binding Index}"
+                                                        MinWidth="50" />
                                     <DataGridTextColumn Header="状态"
                                     <DataGridTextColumn Header="状态"
-                                            Binding="{Binding IsPhotoSuccess}"
-                                            MinWidth="60" />
+                                                        Binding="{Binding IsPhotoSuccess}"
+                                                        MinWidth="60" />
                                     <DataGridTextColumn Header="像素X"
                                     <DataGridTextColumn Header="像素X"
-                                            Binding="{Binding PixelX, StringFormat={}{0:F3}}"
-                                            MinWidth="70" />
+                                                        Binding="{Binding PixelX, StringFormat={}{0:F3}}"
+                                                        MinWidth="70" />
                                     <DataGridTextColumn Header="像素Y"
                                     <DataGridTextColumn Header="像素Y"
-                                            Binding="{Binding PixelY, StringFormat={}{0:F3}}"
-                                            MinWidth="70" />
+                                                        Binding="{Binding PixelY, StringFormat={}{0:F3}}"
+                                                        MinWidth="70" />
                                     <DataGridTextColumn Header="角度"
                                     <DataGridTextColumn Header="角度"
-                                            Binding="{Binding AngleU, StringFormat={}{0:F2}}"
-                                            MinWidth="60" />
+                                                        Binding="{Binding AngleU, StringFormat={}{0:F2}}"
+                                                        MinWidth="60" />
                                     <DataGridTextColumn Header="绝对X"
                                     <DataGridTextColumn Header="绝对X"
-                                            Binding="{Binding TransformX, StringFormat={}{0:F3}}"
-                                            MinWidth="70" />
+                                                        Binding="{Binding TransformX, StringFormat={}{0:F3}}"
+                                                        MinWidth="70" />
                                     <DataGridTextColumn Header="绝对Y"
                                     <DataGridTextColumn Header="绝对Y"
-                                            Binding="{Binding TransformY, StringFormat={}{0:F3}}"
-                                            MinWidth="70" />
+                                                        Binding="{Binding TransformY, StringFormat={}{0:F3}}"
+                                                        MinWidth="70" />
                                     <DataGridTextColumn Header="循环时间"
                                     <DataGridTextColumn Header="循环时间"
-                                            Binding="{Binding CycleTime, StringFormat={}{0:F2}s}"
-                                            MinWidth="80" />
+                                                        Binding="{Binding CycleTime, StringFormat={}{0:F2}s}"
+                                                        MinWidth="80" />
                                     <DataGridTextColumn Header="时间戳"
                                     <DataGridTextColumn Header="时间戳"
-                                            Binding="{Binding Timestamp}"
-                                            MinWidth="120" />
+                                                        Binding="{Binding Timestamp}"
+                                                        MinWidth="120" />
                                 </DataGrid.Columns>
                                 </DataGrid.Columns>
                             </DataGrid>
                             </DataGrid>
                         </Grid>
                         </Grid>
@@ -524,39 +550,39 @@
 
 
                     <!-- 导出和精度分析 -->
                     <!-- 导出和精度分析 -->
                     <Border Grid.Row="5"
                     <Border Grid.Row="5"
-                Background="#ECF0F1"
-                Padding="10">
+                            Background="#ECF0F1"
+                            Padding="10">
                         <StackPanel>
                         <StackPanel>
                             <!-- 导出按钮 -->
                             <!-- 导出按钮 -->
                             <WrapPanel HorizontalAlignment="Right">
                             <WrapPanel HorizontalAlignment="Right">
                                 <Button Content="导出CSV"
                                 <Button Content="导出CSV"
-                            Background="#3498DB"
-                            Foreground="White"
-                            MinWidth="100"
-                            Command="{Binding ExportCSVCommand}" />
+                                        Background="#3498DB"
+                                        Foreground="White"
+                                        MinWidth="100"
+                                        Command="{Binding ExportCSVCommand}" />
 
 
                                 <Button Content="生成报告"
                                 <Button Content="生成报告"
-                            Background="#9B59B6"
-                            Foreground="White"
-                            MinWidth="100"
-                            Command="{Binding ExportReportCommand}" />
+                                        Background="#9B59B6"
+                                        Foreground="White"
+                                        MinWidth="100"
+                                        Command="{Binding ExportReportCommand}" />
 
 
                                 <Button Content="清空数据"
                                 <Button Content="清空数据"
-                            Background="#95A5A6"
-                            Foreground="White"
-                            MinWidth="100"
-                            Command="{Binding ClearDataCommand}" />
+                                        Background="#95A5A6"
+                                        Foreground="White"
+                                        MinWidth="100"
+                                        Command="{Binding ClearDataCommand}" />
                             </WrapPanel>
                             </WrapPanel>
 
 
                             <!-- 动态精度分析 -->
                             <!-- 动态精度分析 -->
                             <Border Margin="0 10 0 0"
                             <Border Margin="0 10 0 0"
-                        Background="#F8F9FA"
-                        Padding="10"
-                        CornerRadius="5">
+                                    Background="#F8F9FA"
+                                    Padding="10"
+                                    CornerRadius="5">
                                 <StackPanel>
                                 <StackPanel>
                                     <TextBlock Text="动态重复精度分析"
                                     <TextBlock Text="动态重复精度分析"
-                                   FontWeight="Bold"
-                                   Margin="0 0 0 5" />
+                                               FontWeight="Bold"
+                                               Margin="0 0 0 5" />
 
 
                                     <Grid Margin="0 5 0 0">
                                     <Grid Margin="0 5 0 0">
                                         <Grid.ColumnDefinitions>
                                         <Grid.ColumnDefinitions>
@@ -568,23 +594,23 @@
                                             <TextBlock>
                                             <TextBlock>
                                     <Run Text="X方向精度: " />
                                     <Run Text="X方向精度: " />
                                     <Run Text="{Binding PrecisionResult.XPrecision, StringFormat={}{0:F3}mm}"
                                     <Run Text="{Binding PrecisionResult.XPrecision, StringFormat={}{0:F3}mm}"
-                                         d:Text="0.023mm"
-                                         Foreground="#2C3E50"
-                                         FontWeight="Bold" />
+                                                d:Text="0.023mm"
+                                                Foreground="#2C3E50"
+                                                FontWeight="Bold" />
                                             </TextBlock>
                                             </TextBlock>
                                             <TextBlock>
                                             <TextBlock>
                                     <Run Text="Y方向精度: " />
                                     <Run Text="Y方向精度: " />
                                     <Run Text="{Binding PrecisionResult.YPrecision, StringFormat={}{0:F3}mm}"
                                     <Run Text="{Binding PrecisionResult.YPrecision, StringFormat={}{0:F3}mm}"
-                                         d:Text="0.018mm"
-                                         Foreground="#2C3E50"
-                                         FontWeight="Bold" />
+                                                d:Text="0.018mm"
+                                                Foreground="#2C3E50"
+                                                FontWeight="Bold" />
                                             </TextBlock>
                                             </TextBlock>
                                             <TextBlock>
                                             <TextBlock>
                                     <Run Text="角度精度: " />
                                     <Run Text="角度精度: " />
                                     <Run Text="{Binding PrecisionResult.AnglePrecision, StringFormat={}{0:F2}°}"
                                     <Run Text="{Binding PrecisionResult.AnglePrecision, StringFormat={}{0:F2}°}"
-                                         d:Text="0.12°"
-                                         Foreground="#2C3E50"
-                                         FontWeight="Bold" />
+                                                d:Text="0.12°"
+                                                Foreground="#2C3E50"
+                                                FontWeight="Bold" />
                                             </TextBlock>
                                             </TextBlock>
                                         </StackPanel>
                                         </StackPanel>
 
 
@@ -592,35 +618,35 @@
                                             <TextBlock>
                                             <TextBlock>
                                     <Run Text="3σ范围: " />
                                     <Run Text="3σ范围: " />
                                     <Run Text="{Binding PrecisionResult.OverallThreeSigmaRange, StringFormat={}±{0:F3}mm}"
                                     <Run Text="{Binding PrecisionResult.OverallThreeSigmaRange, StringFormat={}±{0:F3}mm}"
-                                         d:Text="±0.065mm"
-                                         Foreground="#2C3E50"
-                                         FontWeight="Bold" />
+                                                d:Text="±0.065mm"
+                                                Foreground="#2C3E50"
+                                                FontWeight="Bold" />
                                             </TextBlock>
                                             </TextBlock>
                                             <TextBlock>
                                             <TextBlock>
                                     <Run Text="CPK: " />
                                     <Run Text="CPK: " />
                                     <Run Text="{Binding PrecisionResult.OverallPrecision, StringFormat={}{0:F2}}"
                                     <Run Text="{Binding PrecisionResult.OverallPrecision, StringFormat={}{0:F2}}"
-                                         d:Text="1.85"
-                                         Foreground="#2C3E50"
-                                         FontWeight="Bold" />
+                                                d:Text="1.85"
+                                                Foreground="#2C3E50"
+                                                FontWeight="Bold" />
                                             </TextBlock>
                                             </TextBlock>
                                             <TextBlock>
                                             <TextBlock>
                                     <Run Text="评级: " />
                                     <Run Text="评级: " />
                                     <Run Text="{Binding ProcessRating}"
                                     <Run Text="{Binding ProcessRating}"
-                                         d:Text="优秀"
-                                         Foreground="#27AE60"
-                                         FontWeight="Bold" />
+                                                d:Text="优秀"
+                                                Foreground="#27AE60"
+                                                FontWeight="Bold" />
                                             </TextBlock>
                                             </TextBlock>
                                         </StackPanel>
                                         </StackPanel>
                                     </Grid>
                                     </Grid>
 
 
                                     <!-- 趋势图按钮 -->
                                     <!-- 趋势图按钮 -->
                                     <Button Content="显示趋势图"
                                     <Button Content="显示趋势图"
-                                Background="#E67E22"
-                                Foreground="White"
-                                HorizontalAlignment="Right"
-                                Margin="0 10 0 0"
-                                MinWidth="100"
-                                Command="{Binding ShowTrendChartCommand}" />
+                                            Background="#E67E22"
+                                            Foreground="White"
+                                            HorizontalAlignment="Right"
+                                            Margin="0 10 0 0"
+                                            MinWidth="100"
+                                            Command="{Binding ShowTrendChartCommand}" />
                                 </StackPanel>
                                 </StackPanel>
                             </Border>
                             </Border>
                         </StackPanel>
                         </StackPanel>