فهرست منبع

代码本地化

yaoxiaohan 8 ماه پیش
والد
کامیت
4c43745d74
34فایلهای تغییر یافته به همراه2528 افزوده شده و 205 حذف شده
  1. 3 0
      TeamAAS-VM/App.xaml.cs
  2. 44 4
      TeamAAS-VM/Core/Cameras/OptCamera.cs
  3. 15 0
      TeamAAS-VM/Core/FilePath.cs
  4. 365 51
      TeamAAS-VM/Core/Management.cs
  5. 34 26
      TeamAAS-VM/Core/Robots/XYZU_Robot.cs
  6. 5 0
      TeamAAS-VM/Interfaces/IConfigService.cs
  7. 10 0
      TeamAAS-VM/Models/LockResult.cs
  8. 76 0
      TeamAAS-VM/Models/NumberStatistics.cs
  9. 3 3
      TeamAAS-VM/Models/PLC/PlcAddressConfig.cs
  10. 19 0
      TeamAAS-VM/Models/TorqueCheck.cs
  11. 22 0
      TeamAAS-VM/Models/TorqueTest.cs
  12. 2 2
      TeamAAS-VM/Properties/AssemblyInfo.cs
  13. 140 5
      TeamAAS-VM/Resources/Languages/Lang.Designer.cs
  14. 45 3
      TeamAAS-VM/Resources/Languages/Lang.en.resx
  15. 45 3
      TeamAAS-VM/Resources/Languages/Lang.ja-JP.resx
  16. 56 5
      TeamAAS-VM/Resources/Languages/Lang.resx
  17. 46 4
      TeamAAS-VM/Resources/Languages/Lang.zh-TW.resx
  18. 222 57
      TeamAAS-VM/Services/CameraCalibrationService.cs
  19. 15 0
      TeamAAS-VM/Services/ConfigService.cs
  20. 23 5
      TeamAAS-VM/TeamAAS-VP.csproj
  21. 99 0
      TeamAAS-VM/ViewModels/Home/SetAlarmValueViewModel.cs
  22. 458 0
      TeamAAS-VM/ViewModels/Home/TorqueCheckViewModel.cs
  23. 96 2
      TeamAAS-VM/ViewModels/HomeViewModel.cs
  24. 14 4
      TeamAAS-VM/ViewModels/MainWindowViewModel.cs
  25. 4 4
      TeamAAS-VM/ViewModels/SettingViewModel.cs
  26. 26 1
      TeamAAS-VM/Views/Calibration/CalibrationAuto.xaml.cs
  27. 1 1
      TeamAAS-VM/Views/Calibration/CalibrationTeachCenterPoint.xaml
  28. 94 0
      TeamAAS-VM/Views/Home/SetAlarmValue.xaml
  29. 28 0
      TeamAAS-VM/Views/Home/SetAlarmValue.xaml.cs
  30. 369 0
      TeamAAS-VM/Views/Home/TorqueCheck.xaml
  31. 28 0
      TeamAAS-VM/Views/Home/TorqueCheck.xaml.cs
  32. 108 16
      TeamAAS-VM/Views/HomeView.xaml
  33. 6 5
      TeamAAS-VM/Views/SettingView.xaml
  34. 7 4
      TeamAAS-VM/Views/Statistics/LockResultRecoredQuery.xaml

+ 3 - 0
TeamAAS-VM/App.xaml.cs

@@ -36,6 +36,7 @@ using TeamAAS_VP.ViewModels.Product;
 using TeamAAS_VP.Views;
 using TeamAAS_VP.Views.Calibration;
 using TeamAAS_VP.Views.DebugMod;
+using TeamAAS_VP.Views.Home;
 using TeamAAS_VP.Views.Product;
 using TeamAAS_VP.Views.Setting;
 using TeamAAS_VP.Views.User;
@@ -180,6 +181,8 @@ namespace TeamAAS_VP
             containerRegistry.RegisterDialog<LightChannelList>();
             containerRegistry.RegisterDialog<AutoCorrectLockPoint>();
             containerRegistry.RegisterDialog<ImageDisplay>();
+            containerRegistry.RegisterDialog<TorqueCheck>();
+            containerRegistry.RegisterDialog<SetAlarmValue>();
             //**************************************************************************************
 
             // 注册 SQLSugar 客户端(单例模式)

+ 44 - 4
TeamAAS-VM/Core/Cameras/OptCamera.cs

@@ -1,5 +1,6 @@
 using Cognex.VisionPro;
 using Microsoft.Win32;
+using NPOI.POIFS.Crypt.Dsig;
 using NPOI.SS.Formula.Eval;
 using SciCamera.Net;
 using System;
@@ -122,7 +123,7 @@ namespace TeamAAS_VP.Core.Cameras
 
                 if (devTlType == SciCam.SciCamTLType.SciCam_TLType_Gige)
                 {
-                    
+
                     SciCam.SCI_DEVICE_GIGE_INFO gigeDevInfo = (SciCam.SCI_DEVICE_GIGE_INFO)SciCam.ByteToStruct(device.info.gigeInfo, typeof(SciCam.SCI_DEVICE_GIGE_INFO));
                     uint ip1 = gigeDevInfo.ip;
                     int nIp1 = (int)(ip1 & 0x000000ff);
@@ -338,7 +339,7 @@ namespace TeamAAS_VP.Core.Cameras
                         throw new Exception(Lang.没有发现相机);
                     }
                 }
-                SciCam.SCI_DEVICE_INFO sCI_DEVICE_INFO= CameraInfo;
+                SciCam.SCI_DEVICE_INFO sCI_DEVICE_INFO = CameraInfo;
                 nReVal = mvCameraAcq.CreateDevice(ref sCI_DEVICE_INFO);
                 if (nReVal != SciCam.SCI_CAMERA_OK)
                 {
@@ -349,12 +350,22 @@ namespace TeamAAS_VP.Core.Cameras
                 nReVal = mvCameraAcq.OpenDevice();
                 // ch:设置触发模式为off | en:Set trigger mode as off
                 nReVal = mvCameraAcq.SetEnumValueByStringEx(SciCam.SciCamDeviceXmlType.SciCam_DeviceXml_Camera, "TriggerMode", "Off");
+                nReVal = mvCameraAcq.SetEnumValueByString("TriggerSource", "Software");
+                // ch:注册事件回调 | en:Register event callback
+                //nReVal = mvCameraAcq.RegisterPayloadCallBack(new SciCam.fnOnPayloadDelegate(ImageCallBack), IntPtr.Zero, true);
+                // ch:设置采集策略 | en:Set Grab Strategy
+                nReVal = mvCameraAcq.SetGrabStrategy(SciCam.SciCamGrabStrategy.SciCam_GrabStrategy_Latest);
+                if (nReVal != SciCam.SCI_CAMERA_OK)
+                {
+                    Console.WriteLine("Register Event CallBack fail! nRet {0}", nReVal);
+                }
                 if (!IsConnected)
                 {
                     CameraConnectChangedEvent?.Invoke(ID, true);
                 }
+                mvCameraAcq.SetGrabTimeout(2000);
                 IsConnected = mvCameraAcq.IsDeviceOpen();
-                if (IsConnected) 
+                if (IsConnected)
                 {
                     mvCameraAcq.StartGrabbing();
                 }
@@ -416,7 +427,14 @@ namespace TeamAAS_VP.Core.Cameras
                         {
                             OpenDevice();
                         }
+                        //if (!mvCameraAcq.IsGrabbing())
+                        //{
+                        //    mvCameraAcq.StartGrabbing();
+                        //}
                         //nReVal = mvCameraAcq.StartGrabbing();
+                        //mvCameraAcq.ClearPayloadBuffer();
+                        // ch:发送软触发命令 | en:Send Trigger Software command
+                        //nReVal = mvCameraAcq.SetCommandValueEx(SciCam.SciCamDeviceXmlType.SciCam_DeviceXml_Camera, "TriggerSoftware");
                         nReVal = mvCameraAcq.Grab(ref payload);
                         if (nReVal == SciCam.SCI_CAMERA_OK)
                         {
@@ -424,11 +442,12 @@ namespace TeamAAS_VP.Core.Cameras
                             mvCameraAcq.FreePayload(payload);
                             //nReVal = mvCameraAcq.StopGrabbing();
                             TotalTime = sw.Elapsed;
+                            ErrorMessage = $"{i + 1}";
                             return Image;
                         }
                         else
                         {
-                            nReVal = mvCameraAcq.FreePayload(payload);
+                            //nReVal = mvCameraAcq.FreePayload(payload);
                             //nReVal = mvCameraAcq.StopGrabbing();
                             //_operationSemaphore.Release();
                             CloseDevice();
@@ -457,6 +476,27 @@ namespace TeamAAS_VP.Core.Cameras
             }
         }
 
+        // ch:采集回调接口 | en:Grab Callback interface     
+        void ImageCallBack(IntPtr payload, IntPtr tag)
+        {
+            if (payload == IntPtr.Zero) return;
+            uint nReVal = SciCam.SCI_CAMERA_OK;
+
+            SciCam.SCI_CAM_PAYLOAD_ATTRIBUTE attribute = new SciCam.SCI_CAM_PAYLOAD_ATTRIBUTE();
+            nReVal = SciCam.PayloadGetAttribute(payload, ref attribute);
+            if (nReVal != SciCam.SCI_CAMERA_OK || !attribute.isComplete)
+            {
+                Console.WriteLine("Failed to get image attributes or frame is incomplete! nRet:{0}", nReVal);
+            }
+            else
+            {
+                Image = GetConvertedInfo(payload);
+                ImageCallbackEvent?.Invoke(Image, TotalTime, ErrorMessage);
+                //Console.WriteLine("Get One Frame: Width[{0}], Height[{1}], nFrameNum[{2}]",
+                //attribute.imgAttr.width, attribute.imgAttr.height, attribute.frameID);
+            }
+        }
+
         /// <summary>
         /// 开始采集图像
         /// </summary>

+ 15 - 0
TeamAAS-VM/Core/FilePath.cs

@@ -61,5 +61,20 @@ namespace TeamAAS_VP.Core
         /// 后台脚本存放文件夹
         /// </summary>
         public static string BackgroundScriptPath = "..//Background Script";
+
+        /// <summary>
+        /// 扭力点检参数
+        /// </summary>
+        public static string TorqueCheckPath = "..//Config//TorqueCheckParam.cfg";
+
+        /// <summary>
+        /// 数量参数
+        /// </summary>
+        public static string NumberStatisticsPath = "..//Config//NumberStatisticsParam.cfg";
+
+        /// <summary>
+        /// 扭力测量仪路径
+        /// </summary>
+        public static string SignalConfigPath = "..//Config//扭力测量仪配置文件.json";
     }
 }

+ 365 - 51
TeamAAS-VM/Core/Management.cs

@@ -31,6 +31,7 @@ using System.Threading;
 using System.Threading.Tasks;
 using System.Windows;
 using System.Windows.Documents;
+using System.Windows.Forms;
 using System.Windows.Interop;
 using System.Windows.Media;
 using System.Windows.Media.Media3D;
@@ -52,10 +53,12 @@ using TeamAAS_VP.Resources.Languages;
 using TeamAAS_VP.Services;
 using TeamAAS_VP.ViewModels.Home;
 using TouchSocket.Core;
+using TouchSocket.SerialPorts;
 using TouchSocket.Sockets;
 using static MaterialDesignThemes.Wpf.Theme.ToolBar;
 using static Org.BouncyCastle.Math.EC.ECCurve;
 using static System.Windows.Forms.AxHost;
+using Timer = System.Threading.Timer;
 
 namespace TeamAAS_VP.Core
 {
@@ -78,11 +81,10 @@ namespace TeamAAS_VP.Core
 
         Timer yieldtimer;
         private DateTime StartTime = DateTime.Now;
-
+        SerialPortClient client;
         #endregion
 
         #region 属性
-
         private ObservableCollection<ShowRender> _Renders;
 
         /// <summary>
@@ -159,6 +161,45 @@ namespace TeamAAS_VP.Core
 
         public Dictionary<string, object> BackupObject { get; set; } = new Dictionary<string, object>();
 
+        private string _COM;
+        /// <summary>
+        /// 扭力测量仪COM
+        /// </summary>
+        public string COM
+        {
+            get { return _COM; }
+            set { SetProperty(ref _COM, value); }
+        }
+
+        private string _SignalValue;
+        /// <summary>
+        /// 扭力测量仪获取的最大值
+        /// </summary>
+        public string SignalValue
+        {
+            get { return _SignalValue; }
+            set { SetProperty(ref _SignalValue, value); }
+        }
+
+        private double _Value;
+        /// <summary>
+        /// 电批扭力值
+        /// </summary>
+        public double Value
+        {
+            get { return _Value; }
+            set { SetProperty(ref _Value, value); }
+        }
+
+        private NumberStatistics _NumStatistics;
+        /// <summary>
+        /// 数量(批头、吸嘴、供料器)
+        /// </summary>
+        public NumberStatistics NumStatistics
+        {
+            get { return _NumStatistics; }
+            set { SetProperty(ref _NumStatistics, value); }
+        }
         #endregion
 
         #region 命令
@@ -184,13 +225,42 @@ namespace TeamAAS_VP.Core
             _calibrationService = calibrationService;
             yieldtimer = new Timer(DoYieldTime, null, 10000, 1000);
             Renders = new ObservableCollection<ShowRender>();
-            _configService = configService;
             _productService = productService;
             _remoteCommandService = remoteCommandService;
             _systemDatabaseService = systemDatabaseService;
             _lightManagerService = lightManagerService;
         }
 
+        #region 读取配置参数
+        public void ReadConfig()
+        {
+            ReadNumber();
+        }
+        /// <summary>
+        /// 读取数量配置
+        /// </summary>
+        public void ReadNumber()
+        {
+            try
+            {
+                if (File.Exists(FilePath.NumberStatisticsPath))
+                {
+                    NumStatistics = FileHelper.ReadJsonFile<NumberStatistics>(FilePath.NumberStatisticsPath);
+                }
+                else
+                {
+                    NumStatistics = new NumberStatistics();
+                    FileHelper.WriteJsonFile(NumStatistics, FilePath.NumberStatisticsPath);
+                }
+            }
+            catch (Exception ex)
+            {
+                NumStatistics = new NumberStatistics();
+                LogHelper.WriteLogError("加载数量配置文件时出错!", ex);
+            }
+        }
+        #endregion
+
         #region 初始化硬件模块
 
         /// <summary>
@@ -528,13 +598,13 @@ namespace TeamAAS_VP.Core
         {
             try
             {
-                
+
                 var screwDriverConfig = _configService.GetScrewDriverConfig();
                 ScrewDriver = new XYD_ScrewDriver(screwDriverConfig.IPAdress, screwDriverConfig.Port);
                 Status.Add(new StatusInfo(ScrewDriver.Id, Lang.电批未连接, new SolidColorBrush(Colors.Red)));
                 ScrewDriver.ConnectStateChangedEvent += ScrewDriver_ConnectStateChangedEvent;
-                ScrewDriver.SendTimeout= screwDriverConfig.SendTimeout;
-                screwDriverConfig.ReceiveTimeout= screwDriverConfig.ReceiveTimeout;
+                ScrewDriver.SendTimeout = screwDriverConfig.SendTimeout;
+                screwDriverConfig.ReceiveTimeout = screwDriverConfig.ReceiveTimeout;
                 var isConnected = await ScrewDriver.ConnectAsync();
                 if (isConnected)
                 {
@@ -552,8 +622,58 @@ namespace TeamAAS_VP.Core
             }
         }
 
-        
-
+        /// <summary>
+        /// 初始化扭力测量仪
+        /// </summary>
+        /// <returns></returns>
+        public async Task InitSignal()
+        {
+            if (File.Exists(FilePath.SignalConfigPath))
+            {
+                try
+                {
+                    var port = FileHelper.ReadJsonFile<string>(FilePath.SignalConfigPath);
+                    if (port != null)
+                    {
+                        client = new TouchSocket.SerialPorts.SerialPortClient();
+                        client.Connecting = (client1, e) => { return EasyTask.CompletedTask; };//即将连接到端口
+                        client.Connected = (client1, e) => { return EasyTask.CompletedTask; };//成功连接到端口
+                        client.Closing = (client1, e) => { return EasyTask.CompletedTask; };//即将从端口断开连接。此处仅主动断开才有效。
+                        client.Closed = (client1, e) => { return EasyTask.CompletedTask; };//从端口断开连接,当连接不成功时不会触发。
+                        client.Received = async (c, e) =>
+                        {
+                            //await Console.Out.WriteLineAsync(Encoding.UTF8.GetString(e.ByteBlock.Buffer));
+                            await Console.Out.WriteLineAsync(e.ByteBlock.Span.ToString(Encoding.ASCII));
+                        };
+                        client.Received = Sp_DataReceived;
+
+                        await client.SetupAsync(new TouchSocketConfig()
+                             .SetSerialPortOption(new SerialPortOption()
+                             {
+                                 BaudRate = 115200,//波特率
+                                 DataBits = 8,//数据位
+                                 Parity = System.IO.Ports.Parity.None,//校验位
+                                 PortName = port,//COM
+                                 StopBits = System.IO.Ports.StopBits.One//停止位
+                             })
+                             .SetSerialDataHandlingAdapter(() => new PeriodPackageAdapter() { CacheTimeout = TimeSpan.FromMilliseconds(100) })
+                             );
+
+                        await client.ConnectAsync();
+                    }
+                }
+                catch (Exception ex)
+                {
+                    LogHelper.WriteLogError("初始化扭力测量仪时出错!", ex);
+                    SendTaskMessage("初始化扭力测量仪时出错!"+ex.Message, MessageLevel.Error);
+                }
+            }
+            else
+            {
+                COM = "COM1";
+                FileHelper.WriteJsonFile(COM, FilePath.SignalConfigPath);
+            }
+        }
         #endregion
 
         #region 机器人指令执行
@@ -913,6 +1033,31 @@ namespace TeamAAS_VP.Core
         {
             SendTaskMessage($"{Lang.服务器}[{client.ServicePort}]{Lang.客户端}[{client.Id}:{client.IP}]{Lang.连接成功}!", MessageLevel.Debug);
         }
+
+        /// <summary>
+        /// 扭力测量仪接收信息
+        /// </summary>
+        /// <param name="client"></param>
+        /// <param name="e"></param>
+        /// <returns></returns>
+        private async Task Sp_DataReceived(ISerialPortClient client, ReceivedDataEventArgs e)
+        {
+            try
+            {
+                string poname = client.MainSerialPort.PortName;
+                string data = e.ByteBlock.Span.ToString(Encoding.ASCII);
+                await Console.Out.WriteLineAsync(data);
+                string response = data.Split('\r')[0];
+                SendTaskMessage($"{poname}Receive:{response}", MessageLevel.Info);
+                SignalValue = response;
+            }
+            catch (Exception ex)
+            {
+                LogHelper.WriteLogError("扭力测量仪接收信息时出错!", ex);
+                SendTaskMessage("扭力测量仪接收信息时出错!" + ex.Message, MessageLevel.Error);
+                Thread.Sleep(50);
+            }
+        }
         #endregion
 
         #region PLC
@@ -962,12 +1107,15 @@ namespace TeamAAS_VP.Core
                 addressConfig.In_FixedCameracheckExe.Address,
                 addressConfig.In_WorkStart.Address,
                 addressConfig.In_WorkDone.Address,
-                addressConfig.In_MesCheck.Address,
+                //addressConfig.In_MesCheck.Address,
                 addressConfig.In_RequestPosition.Address,
                 addressConfig.In_ScrewTeachExe.Address,
                 addressConfig.In_PickINC.Address,
             };
-
+            for (int i = 0; i < 10; i++)
+            {
+                monitorNodeIds.Add(string.Format(addressConfig.In_MesCheck.Address, i));
+            }
             //订阅PLC地址变化
             plc.SubscribeNodes("AutoSensor", monitorNodeIds, PlcCommandTrigger);
         }
@@ -1029,10 +1177,22 @@ namespace TeamAAS_VP.Core
             }
         }
 
-        PointF[] DowmCameraResults= new PointF[10];
+        PointF[] DowmCameraResults = new PointF[10];
         PointF[] UpCameraPutResults = new PointF[10];
-        
 
+        bool _LastDowmCameraExe = false;
+        bool _LastScrewTeachExe = false;
+        bool _LastUpCameraPickExe = false;
+        bool _LastUpCameraPutExe = false;
+        bool _LastUPCameracheckExe = false;
+        bool _LastFixedCameraPickExe = false;
+        bool _LastFixedCameraPutExe = false;
+        bool _LastFixedCameracheckExe = false;
+        Int16 _LastWorkStart = 0;
+        Int16 _LastWorkDone = 0;
+        Int16 _LastRequestPosition = 0;
+        Int16[] _LastMesCheck = new Int16[10];
+        Int16 _LastPickINC = 0;
         /// <summary>
         /// PLC命令触发时
         /// </summary>
@@ -1041,7 +1201,7 @@ namespace TeamAAS_VP.Core
         {
             try
             {
-                if (tuple.key!= "AutoSensor")
+                if (tuple.key != "AutoSensor")
                 {
                     return;
                 }
@@ -1051,7 +1211,7 @@ namespace TeamAAS_VP.Core
                 if (plc == null || !plc.IsConnected) return;
                 // 获取当前产品
                 var currentProduct = _productService.GetCurrentProduct();
-                if (currentProduct==null)
+                if (currentProduct == null)
                 {
                     return;
                 }
@@ -1069,6 +1229,15 @@ namespace TeamAAS_VP.Core
                 {
                     if (tuple.value is bool state)
                     {
+                        if (_LastDowmCameraExe != state)
+                        {
+                            _LastDowmCameraExe = state;
+                        }
+                        else
+                        {
+                            return;
+                        }
+
                         if (state)
                         {
                             SendTaskMessage(Lang.触发下相机拍照, MessageLevel.Debug);
@@ -1098,7 +1267,7 @@ namespace TeamAAS_VP.Core
 
                             // 执行视觉任务
                             var _cts = new CancellationTokenSource();
-                            var visionResult =await _remoteCommandService.ExecutePhotoGetSinglePoint(process, null,null, _cts.Token);
+                            var visionResult = await _remoteCommandService.ExecutePhotoGetSinglePoint(process, null, null, _cts.Token);
                             if (visionResult.IsSucceed)
                             {
                                 //披头偏差
@@ -1127,6 +1296,15 @@ namespace TeamAAS_VP.Core
                 {
                     if (tuple.value is bool state)
                     {
+                        if (_LastScrewTeachExe != state)
+                        {
+                            _LastScrewTeachExe = state;
+                        }
+                        else
+                        {
+                            return;
+                        }
+
                         if (state)
                         {
                             SendTaskMessage(Lang.触发下相机拍照, MessageLevel.Debug);
@@ -1185,6 +1363,15 @@ namespace TeamAAS_VP.Core
                 {
                     if (tuple.value is bool state)
                     {
+                        if (_LastUpCameraPickExe != state)
+                        {
+                            _LastUpCameraPickExe = state;
+                        }
+                        else
+                        {
+                            return;
+                        }
+
                         if (state)
                         {
                             SendTaskMessage(Lang.触发上相机取料拍照, MessageLevel.Debug);
@@ -1206,6 +1393,15 @@ namespace TeamAAS_VP.Core
                 {
                     if (tuple.value is bool state)
                     {
+                        if (_LastUpCameraPutExe != state)
+                        {
+                            _LastUpCameraPutExe = state;
+                        }
+                        else
+                        {
+                            return;
+                        }
+
                         if (state)
                         {
                             SendTaskMessage(Lang.触发上相机锁附组装拍照, MessageLevel.Debug);
@@ -1235,12 +1431,12 @@ namespace TeamAAS_VP.Core
 
                             // 执行视觉任务
                             var _cts = new CancellationTokenSource();
-                            var visionResult =await _remoteCommandService.ExecutePhotoGetSinglePoint(process, null, new double[] { currentPosition.X , currentPosition.Y, currentPosition.U}, _cts.Token);
+                            var visionResult = await _remoteCommandService.ExecutePhotoGetSinglePoint(process, null, new double[] { currentPosition.X, currentPosition.Y, currentPosition.U }, _cts.Token);
                             if (visionResult.IsSucceed)
                             {
-                                UpCameraPutResults[cameraIndex]=new PointF((float)visionResult.X, (float)visionResult.Y);
+                                UpCameraPutResults[cameraIndex] = new PointF((float)visionResult.X, (float)visionResult.Y);
+
 
-                                
                                 await plc.WriteNodeAsync(addressConfig.Out_UpCameraPutStatus.Address, (Int16)1);
                             }
                             else
@@ -1260,6 +1456,14 @@ namespace TeamAAS_VP.Core
                 {
                     if (tuple.value is bool state)
                     {
+                        if (_LastUPCameracheckExe != state)
+                        {
+                            _LastUPCameracheckExe = state;
+                        }
+                        else
+                        {
+                            return;
+                        }
                         if (state)
                         {
                             SendTaskMessage(Lang.触发上相机检测拍照, MessageLevel.Debug);
@@ -1282,6 +1486,14 @@ namespace TeamAAS_VP.Core
                 {
                     if (tuple.value is bool state)
                     {
+                        if (_LastFixedCameraPickExe != state)
+                        {
+                            _LastFixedCameraPickExe = state;
+                        }
+                        else
+                        {
+                            return;
+                        }
                         if (state)
                         {
                             SendTaskMessage(Lang.触发固定相机取料拍照, MessageLevel.Debug);
@@ -1304,6 +1516,14 @@ namespace TeamAAS_VP.Core
                 {
                     if (tuple.value is bool state)
                     {
+                        if (_LastFixedCameraPutExe != state)
+                        {
+                            _LastFixedCameraPutExe = state;
+                        }
+                        else
+                        {
+                            return;
+                        }
                         if (state)
                         {
                             SendTaskMessage(Lang.触发固定相机锁附组装拍照, MessageLevel.Debug);
@@ -1325,6 +1545,14 @@ namespace TeamAAS_VP.Core
                 {
                     if (tuple.value is bool state)
                     {
+                        if (_LastFixedCameracheckExe != state)
+                        {
+                            _LastFixedCameracheckExe = state;
+                        }
+                        else
+                        {
+                            return;
+                        }
                         if (state)
                         {
                             SendTaskMessage(Lang.触发固定相机检测拍照, MessageLevel.Debug);
@@ -1346,7 +1574,15 @@ namespace TeamAAS_VP.Core
                 {
                     if (tuple.value is Int16 state)
                     {
-                        if (state==1)
+                        if (_LastWorkStart != state)
+                        {
+                            _LastWorkStart = state;
+                        }
+                        else
+                        {
+                            return;
+                        }
+                        if (state == 1)
                         {
                             SendTaskMessage(Lang.收到开始锁付信号, MessageLevel.Debug);
                             //位置编号
@@ -1365,7 +1601,15 @@ namespace TeamAAS_VP.Core
                 {
                     if (tuple.value is Int16 state)
                     {
-                        if (state==1 || state == 2)
+                        if (_LastWorkDone != state)
+                        {
+                            _LastWorkDone = state;
+                        }
+                        else
+                        {
+                            return;
+                        }
+                        if (state == 1 || state == 2)
                         {
                             SendTaskMessage(Lang.收到停止锁付信号, MessageLevel.Debug);
                             //位置编号
@@ -1382,11 +1626,12 @@ namespace TeamAAS_VP.Core
 
                             await Task.Delay(60);
                             //获取电批结果
-                            bool isSucced= ScrewDriver.GetData();
+                            bool isSucced = ScrewDriver.GetData();
                             LockResult lockResult = new LockResult();
                             lockResult.ScrewdriverGetDataSucceed = isSucced;
                             lockResult.Number = positionIndex;
                             lockResult.LockPassed = ScrewDriver.Success;
+                            lockResult.ProductName = currentProduct.Name;
                             lockResult.ProductNumber = _productService.CurrentProductCode;
                             lockResult.LockTurns = (float)ScrewDriver.Truns;
                             lockResult.LockTorque = (float)ScrewDriver.TorqueValue;
@@ -1414,6 +1659,20 @@ namespace TeamAAS_VP.Core
                             });
                             await _systemDatabaseService.RecordLockResultAsync(lockResult);
                             await plc.WriteNodeAsync(addressConfig.In_WorkDone.Address, (Int16)0);
+
+                            Value = lockResult.LockTorque;
+                            //电批吸嘴报警
+                            NumStatistics.HeaderNum++;//批头数量
+                            NumStatistics.NozzleNum++;//吸嘴数量
+                            FileHelper.WriteJsonFile(NumStatistics, FilePath.NumberStatisticsPath);
+                            if (NumStatistics.HeaderNum < NumStatistics.HeaderAlarmValue)
+                            {
+                                System.Windows.MessageBox.Show("Electric Screwdriver Alarm!", "Alarm", MessageBoxButton.OK, MessageBoxImage.Warning);
+                            }
+                            if (NumStatistics.NozzleNum < NumStatistics.NozzleAlarmValue)
+                            {
+                                System.Windows.MessageBox.Show("Nozzle Alarm!", "Alarm", MessageBoxButton.OK, MessageBoxImage.Warning);
+                            }
                         }
                         else
                         {
@@ -1426,6 +1685,14 @@ namespace TeamAAS_VP.Core
                 {
                     if (tuple.value is Int16 state)
                     {
+                        if (_LastRequestPosition != state)
+                        {
+                            _LastRequestPosition = state;
+                        }
+                        else
+                        {
+                            return;
+                        }
                         if (state == 1)
                         {
                             SendTaskMessage(Lang.收到多相机坐标合并请求开始合并, MessageLevel.Debug);
@@ -1434,7 +1701,7 @@ namespace TeamAAS_VP.Core
                             //拍1打1 
                             if (systemConfig.WorkMode == 1)
                             {
-                                currentProduct.ScrewPoints[0].X_Position = UpCameraPutResults[1].X+ DowmCameraResults[0].X;
+                                currentProduct.ScrewPoints[0].X_Position = UpCameraPutResults[1].X + DowmCameraResults[0].X;
                                 currentProduct.ScrewPoints[0].Y_Position = UpCameraPutResults[1].Y + DowmCameraResults[0].Y;
                                 await currentProduct.ScrewPoints[0].WriteToPlcAddress(addressConfig.Out_Screw, plc);
                             }
@@ -1442,16 +1709,16 @@ namespace TeamAAS_VP.Core
                             else if (systemConfig.WorkMode == 2)
                             {
                                 //根据UpCameraPutResults[]中的索引1、2,和拍照点对应的Local下的坐标,从创建Local坐标系
-                                PointF worldP1=new PointF(UpCameraPutResults[1].X, UpCameraPutResults[1].Y);
-                                PointF worldP2= new PointF(UpCameraPutResults[2].X, UpCameraPutResults[2].Y);
-                                PointF localP1= new PointF(currentProduct.ScrewCameraLocalPos1.X_Position, currentProduct.ScrewCameraLocalPos1.Y_Position);
-                                PointF localP2= new PointF(currentProduct.ScrewCameraLocalPos2.X_Position, currentProduct.ScrewCameraLocalPos2.Y_Position);
-                                CoordinateTransformer local= new CoordinateTransformer(worldP1, worldP2, localP1, localP2);
+                                PointF worldP1 = new PointF(UpCameraPutResults[1].X, UpCameraPutResults[1].Y);
+                                PointF worldP2 = new PointF(UpCameraPutResults[2].X, UpCameraPutResults[2].Y);
+                                PointF localP1 = new PointF(currentProduct.ScrewCameraLocalPos1.X_Position, currentProduct.ScrewCameraLocalPos1.Y_Position);
+                                PointF localP2 = new PointF(currentProduct.ScrewCameraLocalPos2.X_Position, currentProduct.ScrewCameraLocalPos2.Y_Position);
+                                CoordinateTransformer local = new CoordinateTransformer(worldP1, worldP2, localP1, localP2);
 
                                 for (int i = 0; i < currentProduct.ScrewPoints.Count; i++)
                                 {
                                     var localPoint = new PointF(currentProduct.ScrewPoints[i].X_Position, currentProduct.ScrewPoints[i].Y_Position);
-                                    var worldPoint= local.ToOldCoord(localPoint.X, localPoint.Y);
+                                    var worldPoint = local.ToOldCoord(localPoint.X, localPoint.Y);
                                     var point = currentProduct.ScrewPoints[i].Clone();
                                     point.X_Position = (float)worldPoint[0];
                                     point.Y_Position = (float)worldPoint[1];
@@ -1469,45 +1736,92 @@ namespace TeamAAS_VP.Core
                         }
                     }
                 }
-                // 过站检查
-                else if (addressConfig.In_MesCheck.Address.Contains(tuple.nodeId))
+                
+                // 螺丝供料器螺丝递减
+                else if (addressConfig.In_PickINC.Address.Contains(tuple.nodeId))
                 {
                     if (tuple.value is Int16 state)
                     {
-                        if (state == 1)
+                        if (_LastPickINC != state)
                         {
-                            SendTaskMessage(Lang.收到过站检查请求当站是否生产, MessageLevel.Debug);
-
-                            //产品发生改变并且供料器发生了变化时,需要通知PLC进行取料更改
-                            await plc.WriteNodeAsync(addressConfig.Out_ScrewFeederIsChanged.Address, (Int16)1); //不发生改变
-
-                            await plc.WriteNodeAsync(addressConfig.Out_MesStatus.Address, (Int16)1);
+                            _LastPickINC = state;
                         }
-                        // 上传本站数据
-                        else if (state == 2)
+                        else
                         {
-                            SendTaskMessage(Lang.收到上传本站数据请求, MessageLevel.Debug);
-                            await plc.WriteNodeAsync(addressConfig.Out_MesStatus.Address, (Int16)3);
+                            return;
                         }
-                        else
+                        if (state != 0)
                         {
-                            SendTaskMessage(string.Format(Lang.过站检查信号state0处理为默认状态, state), MessageLevel.Alarm);
-                            await plc.WriteNodeAsync(addressConfig.Out_MesStatus.Address, (Int16)0);
+                            SendTaskMessage($"螺丝供料器...", MessageLevel.Info);
+                            await plc.WriteNodeAsync(addressConfig.In_PickINC.Address, (Int16)0);
+
+                            var feeders = _configService.GetRemainingCountByFeederNumber(state);
+                            if (state == 1)
+                            {
+                                NumStatistics.Feeder1Num = feeders;
+                            }
+                            else if (state == 2)
+                            {
+                                NumStatistics.Feeder2Num = feeders;
+                            }
+                            FileHelper.WriteJsonFile(NumStatistics, FilePath.NumberStatisticsPath);
+                            var res = _configService.CheckAlarm(state);
+                            if (res)
+                            {
+                                System.Windows.MessageBox.Show("Screw feeder alarm!", "Alarm", MessageBoxButton.OK, MessageBoxImage.Warning);
+                            }
                         }
                     }
                 }
-                // 螺丝供料器螺丝递减
-                else if (addressConfig.In_PickINC.Address.Contains(tuple.nodeId))
+                // 过站检查
+                else 
                 {
-                    if (tuple.value is Int16 state)
+                    for (int i = 0; i < 10; i++)
                     {
-                        if (state!=0)
+                        if (string.Format(addressConfig.In_MesCheck.Address,i).Contains(tuple.nodeId))
                         {
-                            SendTaskMessage(Lang.螺丝供料器, MessageLevel.Info);
-                            await plc.WriteNodeAsync(addressConfig.In_PickINC.Address, (Int16)0);
+                            if (tuple.value is Int16 state)
+                            {
+                                if (_LastMesCheck[i] != state)
+                                {
+                                    _LastMesCheck[i] = state;
+                                }
+                                else
+                                {
+                                    return;
+                                }
+
+                                if (state == 1)
+                                {
+                                    if(i == 0)
+                                    {
+                                        SendTaskMessage($"收到当前过站检查请求(当站是否生产)...", MessageLevel.Debug);
+                                    }
+                                    else
+                                    {
+                                        SendTaskMessage($"收到{i}过站检查请求(当站是否生产)...", MessageLevel.Debug);
+                                    }                                    
+
+                                    //产品发生改变并且供料器发生了变化时,需要通知PLC进行取料更改
+                                    await plc.WriteNodeAsync(addressConfig.Out_ScrewFeederIsChanged.Address, (Int16)1); //不发生改变
+
+                                    await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address,i), (Int16)1);
+                                }
+                                // 上传本站数据
+                                else if (state == 2)
+                                {
+                                    SendTaskMessage($"收到{i}上传本站数据请求...", MessageLevel.Debug);
+                                    await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)3);
+                                }
+                                else
+                                {
+                                    SendTaskMessage($"{i}过站检查信号:state={state},处理为默认状态", MessageLevel.Alarm);
+                                    await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)0);
+                                }
+                            }
                         }
-                        
                     }
+                    
                 }
             }
             catch (Exception ex)

+ 34 - 26
TeamAAS-VM/Core/Robots/XYZU_Robot.cs

@@ -588,7 +588,7 @@ namespace TeamAAS_VP.Core.Robots
                     }
 
                     // 判断是否至少有一个轴在最近 Timeout 时间内发生过变化(即认为还在运动)
-                    bool anyAxisMovedRecently = actNodes.Any(node => (now - lastChange[node]).TotalMilliseconds <= 1000);
+                    bool anyAxisMovedRecently = actNodes.Any(node => (now - lastChange[node]).TotalMilliseconds <= 500);
 
                     // 如果没有任何轴在最近 Timeout 时间内发生变化,则认为出现停滞异常
                     if (!anyAxisMovedRecently && actNodes.Length > 0)
@@ -610,6 +610,14 @@ namespace TeamAAS_VP.Core.Robots
                         }
                         return true;
                     }
+                        return true;
+                    }
+                    if (isError)
+                    {
+                        StopMove();
+                        LogHelper.WriteLogInfo($"机器人执行移动时发生错误,位置:X={position.X},Y={position.Y},Z={position.Z},U={position.U}");
+                        return false;
+                    }
 
                     // 检查整体超时(防止一直有抖动导致 anyAxisMovedRecently 一直为 true)
                     if (sw.ElapsedMilliseconds > 60000) // 保守超时,一分钟,可根据需求调整
@@ -668,10 +676,10 @@ namespace TeamAAS_VP.Core.Robots
                 {
                     keyValues.Add(axis.Command.ManuPositionNode, false);
                 }
-                if (!string.IsNullOrWhiteSpace(axis.Command.StopNode))
-                {
-                    keyValues.Add(axis.Command.StopNode, true);
-                }
+                //if (!string.IsNullOrWhiteSpace(axis.Command.StopNode))
+                //{
+                //    keyValues.Add(axis.Command.StopNode, true);
+                //}
             }
             bool result = Plc.WriteNodes(keyValues);
 
@@ -679,16 +687,16 @@ namespace TeamAAS_VP.Core.Robots
             //Task.Run(async () =>
             //{
             //    await Task.Delay(100);
-            Thread.Sleep(50);
-            Dictionary<string, object> resetValues = new Dictionary<string, object>();
-            foreach (var axis in Axes)
-            {
-                if (!string.IsNullOrWhiteSpace(axis.Command.StopNode))
-                {
-                    resetValues.Add(axis.Command.StopNode, false);
-                }
-            }
-            Plc.WriteNodes(resetValues);
+            //Thread.Sleep(50);
+            //Dictionary<string, object> resetValues = new Dictionary<string, object>();
+            //foreach (var axis in Axes)
+            //{
+            //    if (!string.IsNullOrWhiteSpace(axis.Command.StopNode))
+            //    {
+            //        resetValues.Add(axis.Command.StopNode, false);
+            //    }
+            //}
+            //Plc.WriteNodes(resetValues);
             //});
             return result;
         }
@@ -747,11 +755,11 @@ namespace TeamAAS_VP.Core.Robots
                 {
                     isError = (bool)res[axis.State.PausedNode];
                 }
-                if (isError)
-                {
-                    isAnyError = true;
-                    break;
-                }
+                //if (isError)
+                //{
+                //    isAnyError = true;
+                //    break;
+                //}
                 //检查是否到位和位置一致
                 float targetPos = 0;
                 switch (axis.Name)
@@ -763,13 +771,13 @@ namespace TeamAAS_VP.Core.Robots
                     default: targetPos = 0; break;
                 }
                 //如果定位完成且位置一致,则此轴完成,如果有错误则失败
-                if (!(posOk && Math.Abs(actualPos - targetPos) < 0.02))
+                if (!(Math.Abs(actualPos - targetPos) < 0.02))
                 {
-                    if (isError)
-                    {
-                        isAnyError = true;
-                        break;
-                    }
+                    //if (isError)
+                    //{
+                    //    isAnyError = true;
+                    //    break;
+                    //}
                     allOk = false;
                     break;
                 }

+ 5 - 0
TeamAAS-VM/Interfaces/IConfigService.cs

@@ -466,5 +466,10 @@ namespace TeamAAS_VP.Interfaces
         /// 记录一次螺丝供料器批次更换记录(写入数据库)。
         /// </summary>
         Task RecordScrewFeederBatchAsync(ScrewFeederBatchRecord record);
+
+        /// <summary>
+        /// 检查剩余螺丝是否报警
+        /// </summary>
+        bool CheckAlarm(int feederNumber);
     }
 }

+ 10 - 0
TeamAAS-VM/Models/LockResult.cs

@@ -11,6 +11,16 @@ namespace TeamAAS_VP.Models
         [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
         public int Id { get; set; }
 
+        private string _ProductName;
+        /// <summary>
+        /// 产品名称
+        /// </summary>
+        public string ProductName
+        {
+            get { return _ProductName; }
+            set { SetProperty(ref _ProductName, value); }
+        }
+
         private int __Number;
         /// <summary>
         /// 螺丝编号

+ 76 - 0
TeamAAS-VM/Models/NumberStatistics.cs

@@ -0,0 +1,76 @@
+using Prism.Mvvm;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TeamAAS_VP.Models
+{
+    /// <summary>
+    /// 数量(批头、吸嘴、供料器)
+    /// </summary>
+    public class NumberStatistics:BindableBase
+    {
+        private int _NozzleNum;
+        /// <summary>
+        /// 吸嘴数量
+        /// </summary>
+        public int NozzleNum
+        {
+            get { return _NozzleNum; }
+            set { SetProperty(ref _NozzleNum, value); }
+        }
+
+        private int _HeaderNum;
+        /// <summary>
+        /// 批头数量
+        /// </summary>
+        public int HeaderNum
+        {
+            get { return _HeaderNum; }
+            set { SetProperty(ref _HeaderNum, value); }
+        }
+
+        private int _Feeder1Num;
+        /// <summary>
+        /// 供料器1数量
+        /// </summary>
+        public int Feeder1Num
+        {
+            get { return _Feeder1Num; }
+            set { SetProperty(ref _Feeder1Num, value); }
+        }
+
+        private int _Feeder2Num;
+        /// <summary>
+        /// 供料器2数量
+        /// </summary>
+        public int Feeder2Num
+        {
+            get { return _Feeder2Num; }
+            set { SetProperty(ref _Feeder2Num, value); }
+        }
+
+        private int _NozzleAlarmValue;
+        /// <summary>
+        /// 吸嘴报警值
+        /// </summary>
+        public int NozzleAlarmValue
+        {
+            get { return _NozzleAlarmValue; }
+            set { SetProperty(ref _NozzleAlarmValue, value); }
+        }
+
+        private int _HeaderAlarmValue;
+        /// <summary>
+        /// 批头报警值
+        /// </summary>
+        public int HeaderAlarmValue
+        {
+            get { return _HeaderAlarmValue; }
+            set { SetProperty(ref _HeaderAlarmValue, value); }
+        }
+    }
+}

+ 3 - 3
TeamAAS-VM/Models/PLC/PlcAddressConfig.cs

@@ -654,7 +654,7 @@ namespace TeamAAS_VP.Models.PLC
             Out_CameraDone.Description = Lang.相机坐标拟合完成;
 
             Out_MesStatus = Ensure(Out_MesStatus);
-            Out_MesStatus.Address = "ns=4;s=DB_Communication|FromPC.MesStatus[0]";
+            Out_MesStatus.Address = "ns=4;s=DB_Communication|FromPC.MesStatus[{0}]";
             Out_MesStatus.DataType = "int16";
             Out_MesStatus.Description = Lang.过站信息1允许工作2本站放行3数据上传完成;
 
@@ -791,12 +791,12 @@ namespace TeamAAS_VP.Models.PLC
 
             // 4. In_* 默认(假定从 PLC 读到 PC,使用 ToPC 前缀)
             In_Code = Ensure(In_Code);
-            In_Code.Address = "ns=4;s=DB_Communication|ToPC.Mes[0].Code";
+            In_Code.Address = "ns=4;s=DB_Communication|ToPC.Mes[{0}].Code";
             In_Code.DataType = "string";
             In_Code.Description = Lang.产品编码;
 
             In_MesCheck = Ensure(In_MesCheck);
-            In_MesCheck.Address = "ns=4;s=DB_Communication|ToPC.Mes[0].Check";
+            In_MesCheck.Address = "ns=4;s=DB_Communication|ToPC.Mes[{0}].Check";
             In_MesCheck.DataType = "int16";
             In_MesCheck.Description = Lang.Mes交互1获取过站信息当站是否生产2上传本站数据;
 

+ 19 - 0
TeamAAS-VM/Models/TorqueCheck.cs

@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TeamAAS_VP.Models
+{
+    /// <summary>
+    /// 扭力点检参数
+    /// </summary>
+    public class TorqueCheck
+    {
+        public double Xpoint { get; set; }
+        public double Ypoint { get; set; }
+        public double Zpoint { get; set; }
+        public double TorqueValue { get; set; }
+    }
+}

+ 22 - 0
TeamAAS-VM/Models/TorqueTest.cs

@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TeamAAS_VP.Models
+{
+    /// <summary>
+    /// 扭力点检参数
+    /// </summary>
+    public class TorqueTest
+    {
+        public double Xpoint { get; set; }
+        public double Ypoint { get; set; }
+        public double Zpoint { get; set; }
+        /// <summary>
+        /// 扭力阈值
+        /// </summary>
+        public double TorqueValue { get; set; }
+    }
+}

+ 2 - 2
TeamAAS-VM/Properties/AssemblyInfo.cs

@@ -51,5 +51,5 @@ using System.Windows;
 //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
 //通过使用 "*",如下所示:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.2.0.2")]
-[assembly: AssemblyFileVersion("1.2.0.2")]
+[assembly: AssemblyVersion("1.2.0.5")]
+[assembly: AssemblyFileVersion("1.2.0.5")]

+ 140 - 5
TeamAAS-VM/Resources/Languages/Lang.Designer.cs

@@ -2356,11 +2356,20 @@ namespace TeamAAS_VP.Resources.Languages {
         }
         
         /// <summary>
-        ///   查找类似 供料器发生改变 的本地化字符串。
+        ///   查找类似 供料器1 的本地化字符串。
         /// </summary>
-        public static string 供料器发生改变 {
+        public static string 供料器1 {
             get {
-                return ResourceManager.GetString("供料器发生改变", resourceCulture);
+                return ResourceManager.GetString("供料器1", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   查找类似 供料器2 的本地化字符串。
+        /// </summary>
+        public static string 供料器2 {
+            get {
+                return ResourceManager.GetString("供料器2", resourceCulture);
             }
         }
         
@@ -2571,6 +2580,15 @@ namespace TeamAAS_VP.Resources.Languages {
             }
         }
         
+        /// <summary>
+        ///   查找类似 修改 的本地化字符串。
+        /// </summary>
+        public static string 修改 {
+            get {
+                return ResourceManager.GetString("修改", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   查找类似 修改IP 的本地化字符串。
         /// </summary>
@@ -3525,6 +3543,15 @@ namespace TeamAAS_VP.Resources.Languages {
             }
         }
         
+        /// <summary>
+        ///   查找类似 吸嘴 的本地化字符串。
+        /// </summary>
+        public static string 吸嘴 {
+            get {
+                return ResourceManager.GetString("吸嘴", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   查找类似 吸真空 的本地化字符串。
         /// </summary>
@@ -4416,6 +4443,15 @@ namespace TeamAAS_VP.Resources.Languages {
             }
         }
         
+        /// <summary>
+        ///   查找类似 差值 的本地化字符串。
+        /// </summary>
+        public static string 差值 {
+            get {
+                return ResourceManager.GetString("差值", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   查找类似 已关闭! 的本地化字符串。
         /// </summary>
@@ -5271,6 +5307,33 @@ namespace TeamAAS_VP.Resources.Languages {
             }
         }
         
+        /// <summary>
+        ///   查找类似 扭力测量仪值 的本地化字符串。
+        /// </summary>
+        public static string 扭力测量仪值 {
+            get {
+                return ResourceManager.GetString("扭力测量仪值", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   查找类似 扭力点检 的本地化字符串。
+        /// </summary>
+        public static string 扭力点检 {
+            get {
+                return ResourceManager.GetString("扭力点检", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   查找类似 扭力阈值 的本地化字符串。
+        /// </summary>
+        public static string 扭力阈值 {
+            get {
+                return ResourceManager.GetString("扭力阈值", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   查找类似 执行视觉处理脚本时出错! 的本地化字符串。
         /// </summary>
@@ -5289,6 +5352,33 @@ namespace TeamAAS_VP.Resources.Languages {
             }
         }
         
+        /// <summary>
+        ///   查找类似 批头 的本地化字符串。
+        /// </summary>
+        public static string 批头 {
+            get {
+                return ResourceManager.GetString("批头", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   查找类似 批头吸嘴计数清零 的本地化字符串。
+        /// </summary>
+        public static string 批头吸嘴计数清零 {
+            get {
+                return ResourceManager.GetString("批头吸嘴计数清零", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   查找类似 批头矫正的模式: 的本地化字符串。
+        /// </summary>
+        public static string 批头矫正的模式 {
+            get {
+                return ResourceManager.GetString("批头矫正的模式", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   查找类似 扭矩地址 的本地化字符串。
         /// </summary>
@@ -7926,6 +8016,15 @@ namespace TeamAAS_VP.Resources.Languages {
             }
         }
         
+        /// <summary>
+        ///   查找类似 电批测量值 的本地化字符串。
+        /// </summary>
+        public static string 电批测量值 {
+            get {
+                return ResourceManager.GetString("电批测量值", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   查找类似 电批程序号 的本地化字符串。
         /// </summary>
@@ -8538,6 +8637,15 @@ namespace TeamAAS_VP.Resources.Languages {
             }
         }
         
+        /// <summary>
+        ///   查找类似 确认要从点位编号 {0} 开始导入 {1} 个点位吗? 的本地化字符串。
+        /// </summary>
+        public static string 确认要从点位编号0开始导入1个点位吗 {
+            get {
+                return ResourceManager.GetString("确认要从点位编号0开始导入1个点位吗", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   查找类似 示教 的本地化字符串。
         /// </summary>
@@ -9449,7 +9557,7 @@ namespace TeamAAS_VP.Resources.Languages {
         }
         
         /// <summary>
-        ///   查找类似 螺丝编号: 的本地化字符串。
+        ///   查找类似 螺丝编号 的本地化字符串。
         /// </summary>
         public static string 螺丝编号 {
             get {
@@ -9988,6 +10096,33 @@ namespace TeamAAS_VP.Resources.Languages {
             }
         }
         
+        /// <summary>
+        ///   查找类似 设置吸嘴报警值 的本地化字符串。
+        /// </summary>
+        public static string 设置吸嘴报警值 {
+            get {
+                return ResourceManager.GetString("设置吸嘴报警值", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   查找类似 设置批头吸嘴报警值 的本地化字符串。
+        /// </summary>
+        public static string 设置批头吸嘴报警值 {
+            get {
+                return ResourceManager.GetString("设置批头吸嘴报警值", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   查找类似 设置批头报警值 的本地化字符串。
+        /// </summary>
+        public static string 设置批头报警值 {
+            get {
+                return ResourceManager.GetString("设置批头报警值", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   查找类似 设置光源通道{0}亮度{1}失败! 的本地化字符串。
         /// </summary>
@@ -11267,7 +11402,7 @@ namespace TeamAAS_VP.Resources.Languages {
         }
         
         /// <summary>
-        ///   查找类似 锁付结果: 的本地化字符串。
+        ///   查找类似 锁付结果 的本地化字符串。
         /// </summary>
         public static string 锁付结果 {
             get {

+ 45 - 3
TeamAAS-VM/Resources/Languages/Lang.en.resx

@@ -2326,7 +2326,7 @@
     <value>Automatic Shooting</value>
   </data>
   <data name="螺丝编号" xml:space="preserve">
-    <value>Screw Number:</value>
+    <value>Screw Number</value>
   </data>
   <data name="开始" xml:space="preserve">
     <value>Start:</value>
@@ -2404,7 +2404,7 @@
     <value>Next Page</value>
   </data>
   <data name="锁付结果" xml:space="preserve">
-    <value>Fastening Result:</value>
+    <value>Fastening Result</value>
   </data>
   <data name="程序号" xml:space="preserve">
     <value>Program number</value>
@@ -2460,7 +2460,7 @@
   <data name="取料位置" xml:space="preserve">
     <value>Pick-up Position:</value>
   </data>
-  <data name="披头矫正的模式" xml:space="preserve">
+  <data name="批头矫正的模式" xml:space="preserve">
     <value>Bit Correction Mode:</value>
   </data>
   <data name="保存系统参数" xml:space="preserve">
@@ -3924,4 +3924,46 @@
   <data name="移动至" xml:space="preserve">
     <value>Move to</value>
   </data>
+  <data name="扭力点检" xml:space="preserve">
+    <value>Torque Inspection</value>
+  </data>
+  <data name="修改" xml:space="preserve">
+    <value>modify</value>
+  </data>
+  <data name="批头" xml:space="preserve">
+    <value>Screwdriver bit</value>
+  </data>
+  <data name="吸嘴" xml:space="preserve">
+    <value>Nozzle</value>
+  </data>
+  <data name="供料器1" xml:space="preserve">
+    <value>Feeder1</value>
+  </data>
+  <data name="供料器2" xml:space="preserve">
+    <value>Feeder2</value>
+  </data>
+  <data name="扭力阈值" xml:space="preserve">
+    <value>Torque threshold</value>
+  </data>
+  <data name="扭力测量仪值" xml:space="preserve">
+    <value>Torque meter reading</value>
+  </data>
+  <data name="差值" xml:space="preserve">
+    <value>Difference</value>
+  </data>
+  <data name="电批测量值" xml:space="preserve">
+    <value>Electric screwdriver torque reading</value>
+  </data>
+  <data name="批头吸嘴计数清零" xml:space="preserve">
+    <value>Bit/Nozzle Counter Reset</value>
+  </data>
+  <data name="设置批头吸嘴报警值" xml:space="preserve">
+    <value>Set Bit/Nozzle Alarm Value</value>
+  </data>
+  <data name="设置批头报警值" xml:space="preserve">
+    <value>Set Bit Alarm Value</value>
+  </data>
+  <data name="设置吸嘴报警值" xml:space="preserve">
+    <value>Set Nozzle Alarm Value</value>
+  </data>
 </root>

+ 45 - 3
TeamAAS-VM/Resources/Languages/Lang.ja-JP.resx

@@ -2326,7 +2326,7 @@
     <value>自動撮影</value>
   </data>
   <data name="螺丝编号" xml:space="preserve">
-    <value>ネジ番号:</value>
+    <value>ネジ番号</value>
   </data>
   <data name="开始" xml:space="preserve">
     <value>開始:</value>
@@ -2404,7 +2404,7 @@
     <value>次ページ</value>
   </data>
   <data name="锁付结果" xml:space="preserve">
-    <value>締付け結果:</value>
+    <value>締付け結果</value>
   </data>
   <data name="程序号" xml:space="preserve">
     <value>プログラム番号</value>
@@ -2460,7 +2460,7 @@
   <data name="取料位置" xml:space="preserve">
     <value>部品取出し位置 :</value>
   </data>
-  <data name="披头矫正的模式" xml:space="preserve">
+  <data name="批头矫正的模式" xml:space="preserve">
     <value>ビット補正モード:</value>
   </data>
   <data name="保存系统参数" xml:space="preserve">
@@ -3924,4 +3924,46 @@
   <data name="移动至" xml:space="preserve">
     <value>移動先</value>
   </data>
+  <data name="扭力点检" xml:space="preserve">
+    <value>トルク点検</value>
+  </data>
+  <data name="修改" xml:space="preserve">
+    <value>修正</value>
+  </data>
+  <data name="批头" xml:space="preserve">
+    <value>ドライバービット</value>
+  </data>
+  <data name="吸嘴" xml:space="preserve">
+    <value>ノズル</value>
+  </data>
+  <data name="供料器1" xml:space="preserve">
+    <value>フィーダー1</value>
+  </data>
+  <data name="供料器2" xml:space="preserve">
+    <value>フィーダー2</value>
+  </data>
+  <data name="扭力阈值" xml:space="preserve">
+    <value>トルク閾値</value>
+  </data>
+  <data name="扭力测量仪值" xml:space="preserve">
+    <value>トルク計の値</value>
+  </data>
+  <data name="电批测量值" xml:space="preserve">
+    <value>電動ドライバー測定値</value>
+  </data>
+  <data name="差值" xml:space="preserve">
+    <value>差値</value>
+  </data>
+  <data name="批头吸嘴计数清零" xml:space="preserve">
+    <value>ビット/ノズルカウンターリセット</value>
+  </data>
+  <data name="设置批头吸嘴报警值" xml:space="preserve">
+    <value>ビット/ノズルのアラーム値設定</value>
+  </data>
+  <data name="设置批头报警值" xml:space="preserve">
+    <value>ビットのアラーム値設定</value>
+  </data>
+  <data name="设置吸嘴报警值" xml:space="preserve">
+    <value>ノズルのアラーム値設定</value>
+  </data>
 </root>

+ 56 - 5
TeamAAS-VM/Resources/Languages/Lang.resx

@@ -2418,7 +2418,7 @@
     <value>自动拍照</value>
   </data>
   <data name="螺丝编号" xml:space="preserve">
-    <value>螺丝编号:</value>
+    <value>螺丝编号</value>
   </data>
   <data name="开始" xml:space="preserve">
     <value>开始:</value>
@@ -2496,7 +2496,7 @@
     <value>下一页</value>
   </data>
   <data name="锁付结果" xml:space="preserve">
-    <value>锁付结果:</value>
+    <value>锁付结果</value>
   </data>
   <data name="程序号" xml:space="preserve">
     <value>程序号</value>
@@ -2517,7 +2517,7 @@
     <value>每包螺丝的数量:</value>
   </data>
   <data name="低量报警阈值" xml:space="preserve">
-    <value>低量报警阈值:</value>
+    <value>低量报警阈值:</value>
   </data>
   <data name="是否启用低量报警" xml:space="preserve">
     <value>是否启用低量报警:</value>
@@ -2552,8 +2552,8 @@
   <data name="取料位置" xml:space="preserve">
     <value>取料位置:</value>
   </data>
-  <data name="披头矫正的模式" xml:space="preserve">
-    <value>披头矫正的模式:</value>
+  <data name="批头矫正的模式" xml:space="preserve">
+    <value>批头矫正的模式:</value>
   </data>
   <data name="保存系统参数" xml:space="preserve">
     <value>保存系统参数</value>
@@ -4016,4 +4016,55 @@
   <data name="移动至" xml:space="preserve">
     <value>移动至</value>
   </data>
+  <data name="扭力点检" xml:space="preserve">
+    <value>扭力点检</value>
+  </data>
+  <data name="修改" xml:space="preserve">
+    <value>修改</value>
+  </data>
+  <data name="批头" xml:space="preserve">
+    <value>批头</value>
+  </data>
+  <data name="吸嘴" xml:space="preserve">
+    <value>吸嘴</value>
+  </data>
+  <data name="供料器1" xml:space="preserve">
+    <value>供料器1</value>
+  </data>
+  <data name="供料器2" xml:space="preserve">
+    <value>供料器2</value>
+  </data>
+  <data name="扭力阈值" xml:space="preserve">
+    <value>扭力阈值</value>
+  </data>
+  <data name="扭力测量仪值" xml:space="preserve">
+    <value>扭力测量仪值</value>
+  </data>
+  <data name="电批测量值" xml:space="preserve">
+    <value>电批测量值</value>
+  </data>
+  <data name="差值" xml:space="preserve">
+    <value>差值</value>
+  </data>
+  <data name="批头吸嘴计数清零" xml:space="preserve">
+    <value>批头吸嘴计数清零</value>
+  </data>
+  <data name="设置批头吸嘴报警值" xml:space="preserve">
+    <value>设置批头吸嘴报警值</value>
+  </data>
+  <data name="设置批头报警值" xml:space="preserve">
+    <value>设置批头报警值</value>
+  </data>
+  <data name="设置吸嘴报警值" xml:space="preserve">
+    <value>设置吸嘴报警值</value>
+  </data>
+  <data name="为PLC写入系统参数和订阅变量时出错" xml:space="preserve">
+    <value>为PLC写入系统参数和订阅变量时出错</value>
+  </data>
+  <data name="确认要从点位编号0开始导入1个点位吗" xml:space="preserve">
+    <value>确认要从点位编号 {0} 开始导入 {1} 个点位吗?</value>
+  </data>
+  <data name="导入点位" xml:space="preserve">
+    <value>导入点位</value>
+  </data>
 </root>

+ 46 - 4
TeamAAS-VM/Resources/Languages/Lang.zh-TW.resx

@@ -2326,7 +2326,7 @@
     <value>自動拍照</value>
   </data>
   <data name="螺丝编号" xml:space="preserve">
-    <value>螺絲編號:</value>
+    <value>螺絲編號</value>
   </data>
   <data name="开始" xml:space="preserve">
     <value>開始:</value>
@@ -2404,7 +2404,7 @@
     <value>下一頁</value>
   </data>
   <data name="锁付结果" xml:space="preserve">
-    <value>鎖付結果:</value>
+    <value>鎖付結果</value>
   </data>
   <data name="程序号" xml:space="preserve">
     <value>程式號</value>
@@ -2460,8 +2460,8 @@
   <data name="取料位置" xml:space="preserve">
     <value>取料位置:</value>
   </data>
-  <data name="披头矫正的模式" xml:space="preserve">
-    <value>披頭矯正的模式:</value>
+  <data name="批头矫正的模式" xml:space="preserve">
+    <value>批頭矯正的模式:</value>
   </data>
   <data name="保存系统参数" xml:space="preserve">
     <value>保存系統參數</value>
@@ -3924,4 +3924,46 @@
   <data name="移动至" xml:space="preserve">
     <value>移動至</value>
   </data>
+  <data name="扭力点检" xml:space="preserve">
+    <value>扭力點檢</value>
+  </data>
+  <data name="修改" xml:space="preserve">
+    <value>修改</value>
+  </data>
+  <data name="批头" xml:space="preserve">
+    <value>批頭</value>
+  </data>
+  <data name="吸嘴" xml:space="preserve">
+    <value>吸嘴</value>
+  </data>
+  <data name="供料器1" xml:space="preserve">
+    <value>供料器1</value>
+  </data>
+  <data name="供料器2" xml:space="preserve">
+    <value>供料器2</value>
+  </data>
+  <data name="扭力阈值" xml:space="preserve">
+    <value>扭力閾值</value>
+  </data>
+  <data name="扭力测量仪值" xml:space="preserve">
+    <value>扭力計讀數</value>
+  </data>
+  <data name="电批测量值" xml:space="preserve">
+    <value>電動起子測量值</value>
+  </data>
+  <data name="差值" xml:space="preserve">
+    <value>差值</value>
+  </data>
+  <data name="批头吸嘴计数清零" xml:space="preserve">
+    <value>批頭吸嘴計數歸零</value>
+  </data>
+  <data name="设置批头吸嘴报警值" xml:space="preserve">
+    <value>設定批頭吸嘴警報值</value>
+  </data>
+  <data name="设置批头报警值" xml:space="preserve">
+    <value>設定批頭警報值</value>
+  </data>
+  <data name="设置吸嘴报警值" xml:space="preserve">
+    <value>設定吸嘴警報值</value>
+  </data>
 </root>

+ 222 - 57
TeamAAS-VM/Services/CameraCalibrationService.cs

@@ -62,7 +62,11 @@ namespace TeamAAS_VP.Services
             Matrix<double> RobotCameraRotationMatrix = null;
 
             //移动机器人至待机位置
-            await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+            bool isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+            if (!isSuccess)
+            {
+                return (false, null, 0, 0, 0, 0);
+            }
             if (cancellationToken.IsCancellationRequested)
             {
                 return (false, null, 0, 0, 0, 0);
@@ -108,7 +112,11 @@ namespace TeamAAS_VP.Services
             RPoint RobotU = calibrationInfo.CenterPoint.Clone();
             RobotU.U += (float)calibrationInfo.Angle;
             //移动机器人中心点
-            await robot.CalibMotionAsync(calibrationInfo.CenterPoint, 0);
+            isSuccess = await robot.CalibMotionAsync(calibrationInfo.CenterPoint, 0);
+            if (!isSuccess)
+            {
+                return (false, null, 0, 0, 0, 0);
+            }
             if (cancellationToken.IsCancellationRequested)
             {
                 return (false, null, 0, 0, 0, 0);
@@ -117,7 +125,11 @@ namespace TeamAAS_VP.Services
             await robot.CalibOutIOAsync(true);
 
             //机器人U轴旋转
-            await robot.CalibMotionAsync(RobotU, 0);
+            isSuccess = await robot.CalibMotionAsync(RobotU, 0);
+            if (!isSuccess)
+            {
+                return (false, null, 0, 0, 0, 0);
+            }
             if (cancellationToken.IsCancellationRequested)
             {
                 return (false, null, 0, 0, 0, 0);
@@ -126,7 +138,11 @@ namespace TeamAAS_VP.Services
             //关闭吸气
             await robot.CalibOutIOAsync(false);
             //移动机器人至待机位置
-            await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+            isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+            if (!isSuccess)
+            {
+                return (false, null, 0, 0, 0, 0);
+            }
             if (cancellationToken.IsCancellationRequested)
             {
                 return (false, null, 0, 0, 0, 0);
@@ -148,7 +164,11 @@ namespace TeamAAS_VP.Services
                 double offsety = (P0.Y - curPixel.Y) * pixelScaleY;
                 var pos = RobotCameraRotationMatrix.Inverse() * Vector<double>.Build.Dense(new double[] { offsetx, offsety });
                 //移动机器人取标定块
-                await robot.CalibMotionAsync(RobotU, 0);
+                isSuccess = await robot.CalibMotionAsync(RobotU, 0);
+                if (!isSuccess)
+                {
+                    return (false, null, 0, 0, 0, 0);
+                }
                 if (cancellationToken.IsCancellationRequested)
                 {
                     return (false, null, 0, 0, 0, 0);
@@ -159,7 +179,11 @@ namespace TeamAAS_VP.Services
                 RobotU.X += (float)pos[0];
                 RobotU.Y += (float)pos[1];
                 //机器人移动
-                await robot.CalibMotionAsync(RobotU, 0);
+                isSuccess = await robot.CalibMotionAsync(RobotU, 0);
+                if (!isSuccess)
+                {
+                    return (false, null, 0, 0, 0, 0);
+                }
                 if (cancellationToken.IsCancellationRequested)
                 {
                     return (false, null, 0, 0, 0, 0);
@@ -168,7 +192,11 @@ namespace TeamAAS_VP.Services
                 //关闭吸气
                 await robot.CalibOutIOAsync(false);
                 //移动机器人至待机位置
-                await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                if (!isSuccess)
+                {
+                    return (false, null, 0, 0, 0, 0);
+                }
                 if (cancellationToken.IsCancellationRequested)
                 {
                     return (false, null, 0, 0, 0, 0);
@@ -186,7 +214,11 @@ namespace TeamAAS_VP.Services
                 if (Math.Abs(offsetx) < 1 && Math.Abs(offsetx) < 1)
                 {
                     //移动机器人取标定块
-                    await robot.CalibMotionAsync(RobotU, 0);
+                    isSuccess = await robot.CalibMotionAsync(RobotU, 0);
+                    if (!isSuccess)
+                    {
+                        return (false, null, 0, 0, 0, 0);
+                    }
                     if (cancellationToken.IsCancellationRequested)
                     {
                         return (false, null, 0, 0, 0, 0);
@@ -194,7 +226,11 @@ namespace TeamAAS_VP.Services
                     //打开吸气
                     await robot.CalibOutIOAsync(true);
                     //移动机器人至待机位置
-                    await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                    isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                    if (!isSuccess)
+                    {
+                        return (false, null, 0, 0, 0, 0);
+                    }
                     IsFinish = true;
                     break;
                 }
@@ -246,7 +282,11 @@ namespace TeamAAS_VP.Services
             Matrix<double> RobotCameraRotationMatrix = null;
 
             //移动机器人至中心位置
-            await robot.CalibMotionAsync(calibrationInfo.CenterPoint, 0);
+            bool isSuccess = await robot.CalibMotionAsync(calibrationInfo.CenterPoint, 0);
+            if (!isSuccess)
+            {
+                return (false, null, 0, 0, 0, 0);
+            }
 
             //计算相机与机器人坐标系的旋转矩阵
             var robotCameraRotationMatrix = await AutoIdentifyRobotCameraRotationMatrix(calibrationInfo, robot, cancellationToken);
@@ -271,7 +311,11 @@ namespace TeamAAS_VP.Services
             RobotU.U += (float)calibrationInfo.Angle;
 
             //机器人U轴旋转
-            await robot.CalibMotionAsync(RobotU, RobotU.Z);
+            isSuccess = await robot.CalibMotionAsync(RobotU, RobotU.Z);
+            if (!isSuccess)
+            {
+                return (false, null, 0, 0, 0, 0);
+            }
             if (cancellationToken.IsCancellationRequested)
             {
                 return (false, null, 0, 0, 0, 0);
@@ -330,7 +374,11 @@ namespace TeamAAS_VP.Services
             Matrix<double> RobotCameraRotationMatrix = null;
 
             //移动机器人至中心位置
-            await robot.CalibMotionAsync(calibrationInfo.CenterPoint, 0);
+            bool isSuccess = await robot.CalibMotionAsync(calibrationInfo.CenterPoint, 0);
+            if (!isSuccess)
+            {
+                return (false, null, 0, 0, 0, 0);
+            }
 
             if (calibrationInfo.Pick.PickPlaceModel == Enums.PickPlaceModel.Inhal)
             {
@@ -353,14 +401,14 @@ namespace TeamAAS_VP.Services
             }
 
             //计算相机与机器人坐标系的旋转矩阵
-            var robotCameraRotationMatrix= await AutoIdentifyRobotCameraRotationMatrix(calibrationInfo, robot, cancellationToken);
+            var robotCameraRotationMatrix = await AutoIdentifyRobotCameraRotationMatrix(calibrationInfo, robot, cancellationToken);
             if (!robotCameraRotationMatrix.IsSuccess)
             {
                 return (false, null, 0, 0, 0, 0);
             }
-            pixelScaleX= robotCameraRotationMatrix.PixelScaleX;
-            pixelScaleY= robotCameraRotationMatrix.PixelScaleY;
-            RobotCameraRotationMatrix= robotCameraRotationMatrix.Item2;
+            pixelScaleX = robotCameraRotationMatrix.PixelScaleX;
+            pixelScaleY = robotCameraRotationMatrix.PixelScaleY;
+            RobotCameraRotationMatrix = robotCameraRotationMatrix.Item2;
 
             //自动移动机器人至图像中心点位置
             var autoMoveResult = await AutoMoveRobotToImageCenter(robot, RobotCameraRotationMatrix, pixelScaleX, pixelScaleY, cancellationToken);
@@ -368,16 +416,20 @@ namespace TeamAAS_VP.Services
             {
                 return (false, null, 0, 0, 0, 0);
             }
-            calibrationInfo.CenterPoint.X= (float)autoMoveResult.X;
-            calibrationInfo.CenterPoint.Y= (float)autoMoveResult.Y;
+            calibrationInfo.CenterPoint.X = (float)autoMoveResult.X;
+            calibrationInfo.CenterPoint.Y = (float)autoMoveResult.Y;
 
 
             RPoint RobotU = calibrationInfo.CenterPoint.Clone();
             RobotU.U += (float)calibrationInfo.Angle;
 
             //机器人U轴旋转
-            await robot.CalibMotionAsync(RobotU, RobotU.Z);
-            if(cancellationToken.IsCancellationRequested)
+            isSuccess = await robot.CalibMotionAsync(RobotU, RobotU.Z);
+            if (!isSuccess)
+            {
+                return (false, null, 0, 0, 0, 0);
+            }
+            if (cancellationToken.IsCancellationRequested)
             {
                 return (false, null, 0, 0, 0, 0);
             }
@@ -442,7 +494,7 @@ namespace TeamAAS_VP.Services
             (bool IsSuccess, Matrix<double> RotationMatrix, double ToolX, double ToolY, double PixelScaleX, double PixelScaleY) calibresult;
             if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
             {
-                calibresult = await CalibrateFixedDownCameraTool(calibrationInfo,robot,cancellationToken);
+                calibresult = await CalibrateFixedDownCameraTool(calibrationInfo, robot, cancellationToken);
             }
             else if (calibrationInfo.CameraMount == Enums.CameraMount.FixedUp)
             {
@@ -460,10 +512,10 @@ namespace TeamAAS_VP.Services
             {
                 return (false, null, 0, 0, 0, 0);
             }
-            
-            pixelScaleX= calibresult.PixelScaleX;
-            pixelScaleY= calibresult.PixelScaleY;
-            RobotCameraRotationMatrix= calibresult.RotationMatrix;
+
+            pixelScaleX = calibresult.PixelScaleX;
+            pixelScaleY = calibresult.PixelScaleY;
+            RobotCameraRotationMatrix = calibresult.RotationMatrix;
 
             return (true, RobotCameraRotationMatrix, calibresult.ToolX, calibresult.ToolY, pixelScaleX, pixelScaleY);
         }
@@ -489,16 +541,24 @@ namespace TeamAAS_VP.Services
 
             //-------------------------------------------P0-----------------------------------
             //移动机器人至中心点
-
+            bool isSuccess = false;
             if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
             {
-                await robot.CalibMotionAsync(calibrationInfo.CenterPoint, 0);
+                isSuccess = await robot.CalibMotionAsync(calibrationInfo.CenterPoint, 0);
+                if (!isSuccess)
+                {
+                    return (false, null, 0, 0);
+                }
                 //关闭吸气
                 await robot.CalibOutIOAsync(false);
             }
             else
             {
-                await robot.CalibMotionAsync(calibrationInfo.CenterPoint, calibrationInfo.CenterPoint.Z);
+                isSuccess = await robot.CalibMotionAsync(calibrationInfo.CenterPoint, calibrationInfo.CenterPoint.Z);
+                if (!isSuccess)
+                {
+                    return (false, null, 0, 0);
+                }
             }
 
 
@@ -511,7 +571,11 @@ namespace TeamAAS_VP.Services
             if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
             {
                 //移动机器人至待机位置
-                await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                if (!isSuccess)
+                {
+                    return (false, null, 0, 0);
+                }
             }
 
             //相机拍照并处理图像
@@ -526,15 +590,23 @@ namespace TeamAAS_VP.Services
             if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
             {
                 //移动机器人至P0
-                await robot.CalibMotionAsync(RobotP0, 0);
-                if(cancellationToken.IsCancellationRequested)
+                isSuccess = await robot.CalibMotionAsync(RobotP0, 0);
+                if (!isSuccess)
+                {
+                    return (false, null, 0, 0);
+                }
+                if (cancellationToken.IsCancellationRequested)
                 {
                     return (false, null, 0, 0);
                 }
                 //打开吸气
                 await robot.CalibOutIOAsync(true);
                 //移动机器人至P1
-                await robot.CalibMotionAsync(RobotP1, 0);
+                isSuccess = await robot.CalibMotionAsync(RobotP1, 0);
+                if (!isSuccess)
+                {
+                    return (false, null, 0, 0);
+                }
                 if (cancellationToken.IsCancellationRequested)
                 {
                     return (false, null, 0, 0);
@@ -542,12 +614,20 @@ namespace TeamAAS_VP.Services
                 //关闭吸气
                 await robot.CalibOutIOAsync(false);
                 //移动机器人至待机位置
-                await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                if (!isSuccess)
+                {
+                    return (false, null, 0, 0);
+                }
             }
             else
             {
                 //移动机器人至P1
-                await robot.CalibMotionAsync(RobotP1, RobotP1.Z);
+                isSuccess = await robot.CalibMotionAsync(RobotP1, RobotP1.Z);
+                if (!isSuccess)
+                {
+                    return (false, null, 0, 0);
+                }
             }
 
             if (cancellationToken.IsCancellationRequested)
@@ -567,7 +647,11 @@ namespace TeamAAS_VP.Services
             if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
             {
                 //移动机器人至P1
-                await robot.CalibMotionAsync(RobotP1, 0);
+                isSuccess = await robot.CalibMotionAsync(RobotP1, 0);
+                if (!isSuccess)
+                {
+                    return (false, null, 0, 0);
+                }
                 if (cancellationToken.IsCancellationRequested)
                 {
                     return (false, null, 0, 0);
@@ -575,7 +659,11 @@ namespace TeamAAS_VP.Services
                 //打开吸气
                 await robot.CalibOutIOAsync(true);
                 //移动机器人至P2
-                await robot.CalibMotionAsync(RobotP2, 0);
+                isSuccess = await robot.CalibMotionAsync(RobotP2, 0);
+                if (!isSuccess)
+                {
+                    return (false, null, 0, 0);
+                }
                 if (cancellationToken.IsCancellationRequested)
                 {
                     return (false, null, 0, 0);
@@ -583,12 +671,20 @@ namespace TeamAAS_VP.Services
                 //关闭吸气
                 await robot.CalibOutIOAsync(false);
                 //移动机器人至待机位置
-                await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                if (!isSuccess)
+                {
+                    return (false, null, 0, 0);
+                }
             }
             else
             {
                 //移动机器人至P2
-                await robot.CalibMotionAsync(RobotP2, RobotP2.Z);
+                isSuccess = await robot.CalibMotionAsync(RobotP2, RobotP2.Z);
+                if (!isSuccess)
+                {
+                    return (false, null, 0, 0);
+                }
             }
             if (cancellationToken.IsCancellationRequested)
             {
@@ -608,7 +704,11 @@ namespace TeamAAS_VP.Services
             if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
             {
                 //移动机器人至P2
-                await robot.CalibMotionAsync(RobotP2, 0);
+                isSuccess = await robot.CalibMotionAsync(RobotP2, 0);
+                if (!isSuccess)
+                {
+                    return (false, null, 0, 0);
+                }
                 if (cancellationToken.IsCancellationRequested)
                 {
                     return (false, null, 0, 0);
@@ -616,7 +716,11 @@ namespace TeamAAS_VP.Services
                 //打开吸气
                 await robot.CalibOutIOAsync(true);
                 //移动机器人至P0
-                await robot.CalibMotionAsync(RobotP0, 0);
+                isSuccess = await robot.CalibMotionAsync(RobotP0, 0);
+                if (!isSuccess)
+                {
+                    return (false, null, 0, 0);
+                }
                 if (cancellationToken.IsCancellationRequested)
                 {
                     return (false, null, 0, 0);
@@ -624,12 +728,20 @@ namespace TeamAAS_VP.Services
                 //关闭吸气
                 await robot.CalibOutIOAsync(false);
                 //移动机器人至待机位置
-                await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                if (!isSuccess)
+                {
+                    return (false, null, 0, 0);
+                }
             }
             else
             {
                 //移动机器人至P0
-                await robot.CalibMotionAsync(RobotP0, RobotP0.Z);
+                isSuccess = await robot.CalibMotionAsync(RobotP0, RobotP0.Z);
+                if (!isSuccess)
+                {
+                    return (false, null, 0, 0);
+                }
             }
             if (cancellationToken.IsCancellationRequested)
             {
@@ -713,7 +825,11 @@ namespace TeamAAS_VP.Services
                 curpos.X += (float)pos[0];
                 curpos.Y += (float)pos[1];
                 //机器人移动
-                await robot.CalibMotionAsync(curpos, curpos.Z);
+                bool isSuccess = await robot.CalibMotionAsync(curpos, curpos.Z);
+                if (!isSuccess)
+                {
+                    return (false, 0, 0, 0);
+                }
 
                 result = await CaptureAndProcessCallback();
                 if (!result.IsSuccess)
@@ -780,12 +896,17 @@ namespace TeamAAS_VP.Services
             //发送校准的参数
             await robot.CalibParameAsync(calibrationInfo.Pick, calibrationInfo.Speed, calibrationInfo.Accel, calibrationInfo.Power, calibrationInfo.WaitSuction, calibrationInfo.WaitBlow);
 
+            bool isSuccess = false;
             var P0 = Vector<double>.Build.Dense(new double[] { calibrationInfo.CenterPoint.X, calibrationInfo.CenterPoint.Y });
             if (robot.Brand == Enums.RobotBrand.XYZ_Platform)
             {
 
                 //移动机器人至中心位置
-                await robot.CalibMotionAsync(calibrationInfo.CenterPoint, 0);
+                isSuccess=await robot.CalibMotionAsync(calibrationInfo.CenterPoint, 0);
+                if (!isSuccess)
+                {
+                    return (false, null, null, null);
+                }
                 if (cancellationToken.IsCancellationRequested)
                 {
                     return (false, null, null, null);
@@ -808,7 +929,7 @@ namespace TeamAAS_VP.Services
                 {
                     calibrationInfo.MarkPoint = calibrationInfo.CenterPoint.Clone();
                 }
-                
+
                 calibrationInfo.RobotCameraRotationMatrix = robotCameraRotationMatrix.RotationMatrix.ToArray();
             }
 
@@ -967,7 +1088,11 @@ namespace TeamAAS_VP.Services
             if (calibrationInfo.CameraMount == Enums.CameraMount.MobileJ4)
             {
                 //移动机器人至中心位置
-                await robot.CalibMotionAsync(calibrationInfo.CenterPoint, 0);
+                isSuccess= await robot.CalibMotionAsync(calibrationInfo.CenterPoint, 0);
+                if (!isSuccess)
+                {
+                    return (false, null, null, null);
+                }
                 if (cancellationToken.IsCancellationRequested)
                 {
                     return (false, null, null, null);
@@ -993,7 +1118,11 @@ namespace TeamAAS_VP.Services
                 //移动机器人至i
                 if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
                 {
-                    await robot.CalibMotionAsync(rPoints[i], 0);
+                    isSuccess= await robot.CalibMotionAsync(rPoints[i], 0);
+                    if (!isSuccess)
+                    {
+                        return (false, null, null, null);
+                    }
                     if (cancellationToken.IsCancellationRequested)
                     {
                         return (false, null, null, null);
@@ -1001,11 +1130,19 @@ namespace TeamAAS_VP.Services
                     //关闭吸气
                     await robot.CalibOutIOAsync(false);
                     //移动机器人至待机位置
-                    await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                    isSuccess= await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                    if (!isSuccess)
+                    {
+                        return (false, null, null, null);
+                    }
                 }
                 else
                 {
-                    await robot.CalibMotionAsync(rPoints[i], rPoints[i].Z);
+                    isSuccess= await robot.CalibMotionAsync(rPoints[i], rPoints[i].Z);
+                    if (!isSuccess)
+                    {
+                        return (false, null, null, null);
+                    }
                 }
                 if (cancellationToken.IsCancellationRequested)
                 {
@@ -1024,7 +1161,11 @@ namespace TeamAAS_VP.Services
                 if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
                 {
                     //移动机器人至i
-                    await robot.CalibMotionAsync(rPoints[i], 0);
+                    isSuccess= await robot.CalibMotionAsync(rPoints[i], 0);
+                    if (!isSuccess)
+                    {
+                        return (false, null, null, null);
+                    }
                     if (cancellationToken.IsCancellationRequested)
                     {
                         return (false, null, null, null);
@@ -1047,7 +1188,11 @@ namespace TeamAAS_VP.Services
             if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
             {
                 //移动机器人至待机位置
-                await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                isSuccess = await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                if (!isSuccess)
+                {
+                    return (false, null, null, null);
+                }
             }
 
             if (cancellationToken.IsCancellationRequested)
@@ -1285,14 +1430,18 @@ namespace TeamAAS_VP.Services
                 Local = calibrationInfo.CenterPoint.Local,
                 Tool = calibrationInfo.CenterPoint.Tool
             });
-
+            bool isSuccess = false;
             List<Vector<double>> TestPos = new List<Vector<double>>();
             for (int i = 0; i < rPoints.Count; i++)
             {
                 if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
                 {
                     //移动机器人至i
-                    await robot.CalibMotionAsync(rPoints[i], 0);
+                    isSuccess= await robot.CalibMotionAsync(rPoints[i], 0);
+                    if (!isSuccess)
+                    {
+                        return (false, null);
+                    }
                     if (cancellationToken.IsCancellationRequested)
                     {
                         return (false, null);
@@ -1300,12 +1449,20 @@ namespace TeamAAS_VP.Services
                     //关闭吸气
                     await robot.CalibOutIOAsync(false);
                     //移动机器人至待机位置
-                    await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                    isSuccess= await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                    if (!isSuccess)
+                    {
+                        return (false, null);
+                    }
                 }
                 else
                 {
                     //移动机器人至i
-                    await robot.CalibMotionAsync(rPoints[i], rPoints[i].Z);
+                     isSuccess = await robot.CalibMotionAsync(rPoints[i], rPoints[i].Z);
+                    if (!isSuccess)
+                    {
+                        return (false, null);
+                    }
                 }
                 if (cancellationToken.IsCancellationRequested)
                 {
@@ -1326,7 +1483,11 @@ namespace TeamAAS_VP.Services
                 if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
                 {
                     //移动机器人至i
-                    await robot.CalibMotionAsync(rPoints[i], 0);
+                    isSuccess = await robot.CalibMotionAsync(rPoints[i], 0);
+                    if (!isSuccess)
+                    {
+                        return (false, null);
+                    }
                     //打开吸气
                     await robot.CalibOutIOAsync(true);
                 }
@@ -1340,7 +1501,11 @@ namespace TeamAAS_VP.Services
             if (calibrationInfo.CameraMount == Enums.CameraMount.FixedDown)
             {
                 //移动机器人至待机位置
-                await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                isSuccess= await robot.CalibMotionAsync(calibrationInfo.HomePoint, 0);
+                if (!isSuccess)
+                {
+                    return (false, null);
+                }
             }
 
             //RMS(均方根值) 标定偏差

+ 15 - 0
TeamAAS-VM/Services/ConfigService.cs

@@ -1235,6 +1235,21 @@ namespace TeamAAS_VP.Services
                 // ignore any error creating/recording the batch record
             }
         }
+
+        /// <summary>
+        /// ¼ì²éÊ£ÓàÂÝË¿ÊÇ·ñ±¨¾¯
+        /// </summary>
+        public bool CheckAlarm(int feederNumber)
+        {
+            lock (_sync)
+            {
+                var f = ScrewFeeders.FirstOrDefault(s => s.FeederNumber == feederNumber);
+                if (f == null) return false;
+                // check alarm
+                CheckAndTriggerLowLevelAlarm(f);
+                return f.IsLowLevelAlarmActive;
+            }
+        }
         #endregion
 
         /// <summary>

+ 23 - 5
TeamAAS-VM/TeamAAS-VP.csproj

@@ -528,7 +528,16 @@
     </Compile>
     <Compile Include="Events\MainTabSwitchNotification.cs" />
     <Compile Include="Models\Feeder\ScrewFeederInfo.cs" />
+    <Compile Include="Models\NumberStatistics.cs" />
     <Compile Include="Models\ScrewFeederBatchRecord.cs" />
+    <Compile Include="Models\TorqueTest.cs" />
+    <Compile Include="Resources\Languages\Lang.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Lang.resx</DependentUpon>
+    </Compile>
+    <Compile Include="ViewModels\Home\SetAlarmValueViewModel.cs" />
+    <Compile Include="ViewModels\Home\TorqueCheckViewModel.cs" />
     <Compile Include="ViewModels\Product\ImageDisplayViewModel.cs" />
     <Compile Include="ViewModels\Setting\AddScrewFeederViewModel.cs" />
     <Compile Include="ViewModels\Statistics\LockResultRecoredQueryViewModel.cs" />
@@ -757,11 +766,6 @@
     <Compile Include="Models\User.cs" />
     <Compile Include="Models\UserInching.cs" />
     <Compile Include="Models\Yield.cs" />
-    <Compile Include="Resources\Languages\Lang.Designer.cs">
-      <AutoGen>True</AutoGen>
-      <DesignTime>True</DesignTime>
-      <DependentUpon>Lang.resx</DependentUpon>
-    </Compile>
     <Compile Include="Resources\Script Template\Background Template.cs" />
     <Compile Include="Resources\Script Template\Vision Template.cs" />
     <Compile Include="Team.SoftKey.cs" />
@@ -924,9 +928,15 @@
     <Compile Include="Views\DebugView.xaml.cs">
       <DependentUpon>DebugView.xaml</DependentUpon>
     </Compile>
+    <Compile Include="Views\Home\SetAlarmValue.xaml.cs">
+      <DependentUpon>SetAlarmValue.xaml</DependentUpon>
+    </Compile>
     <Compile Include="Views\Home\ShowVisionRender.xaml.cs">
       <DependentUpon>ShowVisionRender.xaml</DependentUpon>
     </Compile>
+    <Compile Include="Views\Home\TorqueCheck.xaml.cs">
+      <DependentUpon>TorqueCheck.xaml</DependentUpon>
+    </Compile>
     <Compile Include="Views\ProductsView.xaml.cs">
       <DependentUpon>ProductsView.xaml</DependentUpon>
     </Compile>
@@ -1234,10 +1244,18 @@
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </Page>
+    <Page Include="Views\Home\SetAlarmValue.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
     <Page Include="Views\Home\ShowVisionRender.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </Page>
+    <Page Include="Views\Home\TorqueCheck.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
     <Page Include="Views\MainWindowView.xaml">
       <Generator>MSBuild:Compile</Generator>
       <SubType>Designer</SubType>

+ 99 - 0
TeamAAS-VM/ViewModels/Home/SetAlarmValueViewModel.cs

@@ -0,0 +1,99 @@
+using Prism.Commands;
+using Prism.Mvvm;
+using Prism.Services.Dialogs;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TeamAAS_VP.Core;
+using TeamAAS_VP.Models;
+
+namespace TeamAAS_VP.ViewModels.Home
+{
+    public class SetAlarmValueViewModel : BindableBase, IDialogAware
+    {
+        #region 属性
+        private int _BitAlarmValue;
+        public int BitAlarmValue
+        {
+            get { return _BitAlarmValue; }
+            set { SetProperty(ref _BitAlarmValue, value); }
+        }
+
+        private int _NozzleAlarmValue;
+        public int NozzleAlarmValue
+        {
+            get { return _NozzleAlarmValue; }
+            set { SetProperty(ref _NozzleAlarmValue, value); }
+        }
+
+        private NumberStatistics _NumStatistics = new NumberStatistics();
+        /// <summary>
+        /// 数量(批头、吸嘴、供料器)
+        /// </summary>
+        public NumberStatistics NumStatistics
+        {
+            get { return _NumStatistics; }
+            set { SetProperty(ref _NumStatistics, value); }
+        }
+        #endregion
+
+        #region 命令
+        private DelegateCommand _ConfirmCommand;
+        public DelegateCommand ConfirmCommand =>
+            _ConfirmCommand ?? (_ConfirmCommand = new DelegateCommand(ExecuteConfirmCommand));
+
+        private DelegateCommand _CancelCommand;
+        public DelegateCommand CancelCommand =>
+            _CancelCommand ?? (_CancelCommand = new DelegateCommand(ExecuteCancelCommand));
+
+        #endregion
+
+        void ExecuteCancelCommand()
+        {
+            IDialogParameters parameters = new DialogParameters();
+            RequestClose?.Invoke(new DialogResult(ButtonResult.Cancel, parameters));
+        }
+        void ExecuteConfirmCommand()
+        {
+            NumStatistics.NozzleAlarmValue = NozzleAlarmValue;
+            NumStatistics.HeaderAlarmValue = BitAlarmValue;
+            FileHelper.WriteJsonFile(NumStatistics, FilePath.NumberStatisticsPath);
+            IDialogParameters parameters = new DialogParameters();
+            RequestClose?.Invoke(new DialogResult(ButtonResult.OK, parameters));
+        }
+
+
+        public string Title => "Set Bit/Nozzle Alarm Value";
+
+        public event Action<IDialogResult> RequestClose;
+
+        public bool CanCloseDialog()
+        {
+            return true;
+        }
+
+        public void OnDialogClosed()
+        {
+            
+        }
+
+        public void OnDialogOpened(IDialogParameters parameters)
+        {
+            try
+            {
+                var res = FileHelper.ReadJsonFile<NumberStatistics>(FilePath.NumberStatisticsPath);
+                if (res != null)
+                {
+                    BitAlarmValue = res.HeaderAlarmValue;
+                    NozzleAlarmValue = res.NozzleAlarmValue;
+                }
+            }
+            catch (Exception)
+            {
+
+            }
+        }
+    }
+}

+ 458 - 0
TeamAAS-VM/ViewModels/Home/TorqueCheckViewModel.cs

@@ -0,0 +1,458 @@
+using NPOI.OpenXml4Net.OPC.Internal;
+using NPOI.SS.Formula.Functions;
+using Prism.Commands;
+using Prism.Events;
+using Prism.Ioc;
+using Prism.Mvvm;
+using Prism.Services.Dialogs;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows;
+using TeamAAS_VP.Core;
+using TeamAAS_VP.Enums;
+using TeamAAS_VP.Events;
+using TeamAAS_VP.Interfaces;
+using TeamAAS_VP.Models;
+using TeamAAS_VP.Resources.Languages;
+using TeamAAS_VP.Services;
+using FileHelper = TeamAAS_VP.Core.FileHelper;
+
+namespace TeamAAS_VP.ViewModels.Home
+{
+    public class TorqueCheckViewModel : BindableBase, IDialogAware
+    {
+        IEventAggregator _eventAggregator;
+        IConfigService _configService;
+        IContainerProvider _container;
+        IRobotService _robotService;
+
+        #region 属性
+        private Management _management;
+        public Management management
+        {
+            get { return _management; }
+            set { SetProperty(ref _management, value); }
+        }
+
+        private bool CanExecute
+        {
+            get
+            {
+                // 命令可执行仅当机器人可执行且已选择点位
+                if (Robot != null && Robot.IsConnected && Robot.CanExecute)
+                {
+                    return true;
+                }
+                return false;
+            }
+        }
+
+        private IRobot _Robot;
+        public IRobot Robot
+        {
+            get { return _Robot; }
+            set { SetProperty(ref _Robot, value); }
+        }
+
+        private double _Distance = 1;
+        public double Distance
+        {
+            get { return _Distance; }
+            set
+            {
+                SetProperty(ref _Distance, value);
+                try
+                {
+                    if (Robot == null)
+                    {
+                        return;
+                    }
+                    _configService.UpdateRobotStepDistance(Robot.Id, value);
+                }
+                catch (Exception)
+                {
+
+                }
+            }
+        }
+
+        private TorqueTest _tc = new TorqueTest();
+        public TorqueTest Tc
+        {
+            get { return _tc; }
+            set { SetProperty(ref _tc, value); }
+        }
+
+        private double _torqueValue;
+        public double torqueValue
+        {
+            get { return _torqueValue; }
+            set { SetProperty(ref _torqueValue, value); }
+        }
+
+        private string _TValue;
+        public string TValue
+        {
+            get { return _TValue; }
+            set
+            {
+                SetProperty(ref _TValue, value);
+            }
+        }
+
+        private string _PValue;
+        public string PValue
+        {
+            get { return _PValue; }
+            set
+            {
+                SetProperty(ref _PValue, value);
+            }
+        }
+
+        private string _SubValue;
+        public string SubValue
+        {
+            get { return _SubValue; }
+            set { SetProperty(ref _SubValue, value); }
+        }
+
+        private string _Result;
+        public string Result
+        {
+            get { return _Result; }
+            set { SetProperty(ref _Result, value); }
+        }
+
+        private string _FontColor;
+        public string FontColor
+        {
+            get { return _FontColor; }
+            set { SetProperty(ref _FontColor, value); }
+        }
+        #endregion
+
+        #region 命令
+        private DelegateCommand _CancelCommand;
+        public DelegateCommand CancelCommand =>
+            _CancelCommand ?? (_CancelCommand = new DelegateCommand(ExecuteCancelCommand));
+
+        private DelegateCommand _ConfirmCommand;
+        public DelegateCommand ConfirmCommand =>
+            _ConfirmCommand ?? (_ConfirmCommand = new DelegateCommand(ExecuteConfirmCommand));
+
+        private DelegateCommand<string> _MotorCommand;
+        public DelegateCommand<string> MotorCommand =>
+            _MotorCommand ?? (_MotorCommand = new DelegateCommand<string>(ExecuteMotorCommand).ObservesCanExecute(() => CanExecute).ObservesProperty(() => Robot).ObservesProperty(() => Robot.CanExecute));
+
+        private DelegateCommand<object> _JogCommand;
+        public DelegateCommand<object> JogCommand =>
+             _JogCommand ?? (_JogCommand = new DelegateCommand<object>(ExecuteJogCommand).ObservesCanExecute(() => CanExecute).ObservesProperty(() => Robot).ObservesProperty(() => Robot.CanExecute));
+
+        private DelegateCommand _TechPointCommand;
+        public DelegateCommand TechPointCommand =>
+            _TechPointCommand ?? (_TechPointCommand = new DelegateCommand(ExecuteTechPointCommand));
+
+        private DelegateCommand _ModifyCommand;
+        public DelegateCommand ModifyCommand =>
+            _ModifyCommand ?? (_ModifyCommand = new DelegateCommand(ExecuteModifyCommand));
+
+        private DelegateCommand _WorkCommand;
+        public DelegateCommand WorkCommand =>
+            _WorkCommand ?? (_WorkCommand = new DelegateCommand(ExecuteWorkCommand));
+
+        #endregion
+
+        #region 方法
+        public TorqueCheckViewModel(IEventAggregator ea, IConfigService configService, IContainerProvider container, IRobotService robotService)
+        {
+            _eventAggregator = ea;
+            _configService = configService;
+            _container = container;
+            _robotService = robotService;
+            management = _container.Resolve<Management>();
+        }
+
+        void ExecuteCancelCommand()
+        {
+            IDialogParameters parameters = new DialogParameters();
+            RequestClose?.Invoke(new DialogResult(ButtonResult.Cancel, parameters));
+        }
+
+        void ExecuteConfirmCommand()
+        {
+            IDialogParameters parameters = new DialogParameters();
+            RequestClose?.Invoke(new DialogResult(ButtonResult.OK, parameters));
+        }
+
+        /// <summary>
+        /// 电机
+        /// </summary>
+        /// <param name="obj"></param>
+        private async void ExecuteMotorCommand(string obj)
+        {
+            if (Robot == null || !Robot.IsConnected) return;
+            try
+            {
+                await Robot.MotorAsync(Convert.ToBoolean(obj));
+                _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = $"{Lang.完成}!", Duration = 0.4 });
+            }
+            catch (Exception ex)
+            {
+                LogHelper.WriteLogError("机器人点击操作时出错!", ex);
+                _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = ex.Message, Duration = 1 });
+            }
+        }
+
+        /// <summary>
+        /// 点动
+        /// </summary>
+        /// <param name="obj"></param>
+        private async void ExecuteJogCommand(object obj)
+        {
+            if (Robot == null || !Robot.IsConnected) return;
+            try
+            {
+                var items = ((string)obj).Split(':');
+                //如果移动距离大于10mm,则提示用户确认
+                double distance = double.Parse(items[1]);
+                if (Math.Abs(distance) >= 10)
+                {
+                    if (MessageBox.Show($"确认要点动距离 {distance} mm 吗?", "确认点动", MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
+                    {
+                        return;
+                    }
+                }
+
+                Robot.Timeout = 6000000;
+
+                switch (items[0])
+                {
+                    case "X+":
+                        await Robot.JogAsync("X", distance);
+                        break;
+                    case "X-":
+                        await Robot.JogAsync("X", -distance);
+                        break;
+                    case "Y+":
+                        await Robot.JogAsync("Y", distance);
+                        break;
+                    case "Y-":
+                        await Robot.JogAsync("Y", -distance);
+                        break;
+                    case "Z+":
+                        await Robot.JogAsync("Z", distance);
+                        break;
+                    case "Z-":
+                        await Robot.JogAsync("Z", -distance);
+                        break;
+                    case "U+":
+                        await Robot.JogAsync("U", distance);
+                        break;
+                    case "U-":
+                        await Robot.JogAsync("U", -distance);
+                        break;
+                    case "V+":
+                        await Robot.JogAsync("V", distance);
+                        break;
+                    case "V-":
+                        await Robot.JogAsync("V", -distance);
+                        break;
+                    case "W+":
+                        await Robot.JogAsync("W", distance);
+                        break;
+                    case "W-":
+                        await Robot.JogAsync("W", -distance);
+                        break;
+                    default:
+                        break;
+                }
+                Robot.Timeout = 5000;
+
+                _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = $"{Lang.完成}!", Duration = 0.4 });
+
+            }
+            catch (Exception ex)
+            {
+                LogHelper.WriteLogError("机器人点位-机器人点动时出错", ex);
+                _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = ex.Message, Duration = 1 });
+            }
+        }
+
+        /// <summary>
+        /// 示教点位
+        /// </summary>
+        async void ExecuteTechPointCommand()
+        {
+            //弹窗用户是否确认要示教该点位
+            if (MessageBox.Show($"确认要示教点位吗?", "示教点位", MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
+            {
+                return;
+            }
+
+            var curpos = await Robot.GetRobotPosAsync();
+            Tc.Xpoint = curpos.X;
+            Tc.Ypoint = curpos.Y;
+            Tc.Zpoint = curpos.Z;
+            FileHelper.WriteJsonFile(Tc, FilePath.TorqueCheckPath);
+            _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = $"{Lang.完成}!", Duration = 0.4 });
+        }
+
+        /// <summary>
+        /// 修改
+        /// </summary>
+        void ExecuteModifyCommand()
+        {
+            if (MessageBox.Show($"确认要修改扭力阈值吗?", "修改", MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
+            {
+                return;
+            }
+            Tc.TorqueValue = torqueValue;
+            FileHelper.WriteJsonFile(Tc, FilePath.TorqueCheckPath);
+            _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = Lang.完成, Duration = 0.4 });
+        }
+
+        void ExecuteWorkCommand()
+        {
+            try
+            {
+                MoveRobot();
+                Thread.Sleep(500);
+                DisplayResult();
+            }
+            catch (Exception ex)
+            {
+                LogHelper.WriteLogError("执行点检时出错!", ex);
+            }
+        }
+        public async void MoveRobot()
+        {
+            if (!File.Exists(FilePath.TorqueCheckPath))
+            {
+                MessageBox.Show("还未示教,请先示教");
+                return;
+            }
+            var res = FileHelper.ReadJsonFile<TorqueTest>(FilePath.TorqueCheckPath);
+
+            var point = new RPoint()
+            {
+                X = (float)res.Xpoint,
+                Y = (float)res.Ypoint,
+                Z = (float)res.Zpoint,
+            };
+            if (Robot == null || !Robot.IsConnected) return;
+            try
+            {
+                //确认要执行该点位的该运动指令吗
+                if (MessageBox.Show($"确认要进行点检吗?", "执行点位", MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
+                {
+                    return;
+                }
+                await Robot.JumpAsync(point, 0);
+            }
+            catch (Exception ex)
+            {
+                LogHelper.WriteLogError("执行点检移动时出错!", ex);
+            }
+        }
+        public void DisplayResult()
+        {
+            try
+            {
+                TValue = management.SignalValue;
+                double tvalue = double.Parse(TValue.Split(' ')[0]);
+                PValue = $"{management.Value} N.m";
+                double pvalue = management.Value;
+                SubValue = $"{Math.Abs(tvalue - pvalue)} N.m";
+                double sub = Math.Abs(tvalue - pvalue);
+
+                var res = FileHelper.ReadJsonFile<TorqueTest>(FilePath.TorqueCheckPath);
+                if (res != null)
+                {
+                    if (sub <= res.TorqueValue)
+                    {
+                        FontColor = "Green";
+                        Result = "OK";
+                    }
+                    else
+                    {
+                        FontColor = "Red";
+                        Result = "NG";
+                    }
+                }
+                else
+                {
+                    if (sub <= torqueValue)
+                    {
+                        FontColor = "Green";
+                        Result = "OK";
+                    }
+                    else
+                    {
+                        FontColor = "Red";
+                        Result = "NG";
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                LogHelper.WriteLogError("执行点检显示时出错!", ex);
+            }
+        }
+        #endregion
+
+        public string Title { get; set; } = "扭力点检";
+
+        public event Action<IDialogResult> RequestClose;
+
+        public bool CanCloseDialog()
+        {
+            return true;
+        }
+
+        public void OnDialogClosed()
+        {
+
+        }
+
+        public void OnDialogOpened(IDialogParameters parameters)
+        {
+            try
+            {
+                var res = FileHelper.ReadJsonFile<TorqueTest>(FilePath.TorqueCheckPath);
+                if (res != null)
+                {
+                    res.TorqueValue = torqueValue;
+                }
+                else
+                {
+                    MessageBox.Show("还未示教,请先示教");
+                }
+            }
+            catch (Exception ex)
+            {
+                MessageBox.Show("还未示教,请先示教");
+            }
+
+            if (Robot == null)
+            {
+                Robot = _robotService.GetRobotByNumber(1);
+            }
+
+            if (Robot != null && Robot.IsConnected)
+            {
+                this.Distance = _configService.GetRobotStepDistance(Robot.Id);
+                Robot.EnterDebugMode = true;
+            }
+            else if (Robot != null)
+            {
+                Robot.EnterDebugMode = true;
+            }
+        }
+    }
+}

+ 96 - 2
TeamAAS-VM/ViewModels/HomeViewModel.cs

@@ -5,14 +5,17 @@ using OxyPlot;
 using OxyPlot.Axes;
 using OxyPlot.Legends;
 using OxyPlot.Series;
+using OxyPlot.Wpf;
 using Prism.Commands;
 using Prism.Events;
 using Prism.Ioc;
 using Prism.Mvvm;
 using Prism.Regions;
+using Prism.Services.Dialogs;
 using System;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
+using System.IO;
 using System.Linq;
 using System.Threading.Tasks;
 using System.Windows;
@@ -29,6 +32,7 @@ using TeamAAS_VP.Resources.Languages;
 using TeamAAS_VP.Services;
 using TeamAAS_VP.ViewModels.DebugMod;
 using TeamAAS_VP.Views.DebugMod;
+using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;
 
 namespace TeamAAS_VP.ViewModels
 {
@@ -40,6 +44,7 @@ namespace TeamAAS_VP.ViewModels
         IConfigService _configService;
         IRemoteCommandService _remoteCommandService;
         ISystemDatabaseService _systemDatabaseService;
+        IDialogService _dialogService;
 
         #region 属性
 
@@ -145,6 +150,12 @@ namespace TeamAAS_VP.ViewModels
             set { SetProperty(ref _LockResults, value); }
         }
 
+        private bool _IsAllowEdit = false;
+        public bool IsAllowEdit
+        {
+            get { return _IsAllowEdit; }
+            set { SetProperty(ref _IsAllowEdit, value); }
+        }
         #endregion
 
         #region 命令
@@ -165,6 +176,19 @@ namespace TeamAAS_VP.ViewModels
         private DelegateCommand<string> _CopyCommand;
         public DelegateCommand<string> CopyCommand =>
             _CopyCommand ?? (_CopyCommand = new DelegateCommand<string>(ExecuteCopyCommand));
+
+        private DelegateCommand _TorqueInspectionCommand;
+        public DelegateCommand TorqueInspectionCommand =>
+            _TorqueInspectionCommand ?? (_TorqueInspectionCommand = new DelegateCommand(ExecuteTorqueInspectionCommand));
+
+        private DelegateCommand _NozzleCounterResetCommand;
+        public DelegateCommand NozzleCounterResetCommand =>
+            _NozzleCounterResetCommand ?? (_NozzleCounterResetCommand = new DelegateCommand(ExecuteNozzleCounterResetCommand));
+
+        private DelegateCommand _SetAlarmValueCommand;
+        public DelegateCommand SetAlarmValueCommand =>
+            _SetAlarmValueCommand ?? (_SetAlarmValueCommand = new DelegateCommand(ExecuteSetAlarmValueCommand));
+
         #endregion
 
         #region 事件
@@ -172,10 +196,11 @@ namespace TeamAAS_VP.ViewModels
         #endregion
 
         public HomeViewModel(IEventAggregator ea, IContainerProvider container, IProductService productService, IConfigService configService, IRemoteCommandService remoteCommandService
-            , ISystemDatabaseService systemDatabaseService)
+            , ISystemDatabaseService systemDatabaseService,IDialogService dialogService)
         {
             _eventAggregator = ea;
             _container = container;
+            _dialogService = dialogService;
             _productService = productService;
             LoadedCommand = new DelegateCommand(OnLoad);
             _eventAggregator.GetEvent<TaskMessageNotification>().Subscribe(AddMessageInvoke);
@@ -218,6 +243,15 @@ namespace TeamAAS_VP.ViewModels
             }
             InitLockCurvePlotModel();
             isFirst = false;
+
+            if (_systemDatabaseService.GetCurrentUser().userPart == Enums.UserPart.Operator)
+            {
+                IsAllowEdit = false;
+            }
+            else
+            {
+                IsAllowEdit = true;
+            }
         }
 
         async void ExecuteLoadProductCommand(ProductModel product)
@@ -253,6 +287,20 @@ namespace TeamAAS_VP.ViewModels
             Clipboard.SetText(textToCopy);
         }
 
+        void ExecuteTorqueInspectionCommand()
+        {
+            _dialogService.ShowDialog("TorqueCheck", rst =>
+            {
+                //对话框关闭之后的回调函数,可以在这解析结果。
+                ButtonResult result1 = rst.Result;
+
+                if (result1 == ButtonResult.OK)
+                {
+                    _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = Lang.完成, Duration = 1 });
+                }
+            });
+        }
+
         /// <summary>
         /// 添加消息至消息队列
         /// </summary>
@@ -342,7 +390,14 @@ namespace TeamAAS_VP.ViewModels
 
         private void LoginChange(Models.User user)
         {
-            
+            if (user.userPart == Enums.UserPart.Operator)
+            {
+                IsAllowEdit = false;
+            }
+            else
+            {
+                IsAllowEdit = true;
+            }
         }
 
         /// <summary>
@@ -440,6 +495,45 @@ namespace TeamAAS_VP.ViewModels
             }));
 
         }
+        private void SaveAsPng(PlotModel LockCurvePlotModel)
+        {
+            string savePath = $"E:\\Data\\螺丝锁付曲线图\\{DateTime.Now:yyyyMMdd_HHmmss}.png";
+
+            Application.Current.Dispatcher.Invoke(() =>
+            {
+                try
+                {
+                    var exporter = new PngExporter { Width = 1200, Height = 800 };
+                    exporter.ExportToFile(LockCurvePlotModel, savePath);
+                    //SaveStatus = $"已保存到:{savePath}";
+                }
+                catch (Exception ex)
+                {
+                    //SaveStatus = $"保存失败:{ex.Message}";
+                }
+            });
+        }
+
+        void ExecuteSetAlarmValueCommand()
+        {
+            _dialogService.ShowDialog("SetAlarmValue", rst =>
+            {
+                //对话框关闭之后的回调函数,可以在这解析结果。
+                ButtonResult result1 = rst.Result;
+
+                if (result1 == ButtonResult.OK)
+                {
+                    _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = Lang.完成, Duration = 1 });
+                }
+            });
+        }
+        void ExecuteNozzleCounterResetCommand()
+        {
+            management.NumStatistics.NozzleNum = 0;
+            management.NumStatistics.HeaderNum = 0;
+            FileHelper.WriteJsonFile(management.NumStatistics, FilePath.NumberStatisticsPath);
+            _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = Lang.完成, Duration = 1 });
+        }
         #endregion
 
         #region 继承

+ 14 - 4
TeamAAS-VM/ViewModels/MainWindowViewModel.cs

@@ -159,7 +159,7 @@ namespace TeamAAS_VP.ViewModels
                 LogHelper.WriteLogError("Database initialization failed during application startup", ex);
             }
 
-            
+
         }
 
         #region 方法
@@ -167,7 +167,7 @@ namespace TeamAAS_VP.ViewModels
         string lastNavigationName = string.Empty;
         private void NavigationVoid(string obj)
         {
-            if(!string.IsNullOrEmpty(lastNavigationName))
+            if (!string.IsNullOrEmpty(lastNavigationName))
             {
                 if (lastNavigationName == obj)
                 {
@@ -283,7 +283,7 @@ namespace TeamAAS_VP.ViewModels
             currentUser = Guid.NewGuid();
             Status.Add(new StatusInfo(currentUser, $"{Lang.当前用户}:{_systemDatabaseService.GetCurrentUser().UserName}[{_systemDatabaseService.GetCurrentUser().userPart.ToString()}]", new SolidColorBrush(Colors.White)));
 
-            var _= Application.Current.Dispatcher.BeginInvoke(new Action(() => { _dialogService.ShowDialog("UProgressBar", rst => { }); }));
+            var _ = Application.Current.Dispatcher.BeginInvoke(new Action(() => { _dialogService.ShowDialog("UProgressBar", rst => { }); }));
 
             _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
             {
@@ -352,7 +352,7 @@ namespace TeamAAS_VP.ViewModels
             {
                 _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = max, Minimum = 0, SubTitle = $"{Lang.初始化中}...", Message = $"{Lang.加载所有产品}...", Value = curvalue });
             }));
-             await _productService.InitializeAsync();
+            await _productService.InitializeAsync();
 
             //-------------------SETP 9: 开启服务器监听-----------------------------------------------------------------------
             curvalue += 1;
@@ -378,6 +378,16 @@ namespace TeamAAS_VP.ViewModels
             }));
             management.InitBackgroundcript();
 
+
+            //-------------------SETP 12: 开启扭力测量仪-----------------------------------------------------------------------
+            curvalue += 1;
+            _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
+            {
+                _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = max, Minimum = 0, SubTitle = $"{Lang.初始化中}...", Message = $"{Lang.正在开启}...", Value = curvalue });
+            }));
+            await management.InitSignal();
+            management.ReadConfig();
+
             //当前日期
             CurrentTime = Guid.NewGuid();
             Status.Add(new StatusInfo(CurrentTime, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), new SolidColorBrush(Colors.White)));

+ 4 - 4
TeamAAS-VM/ViewModels/SettingViewModel.cs

@@ -414,7 +414,7 @@ namespace TeamAAS_VP.ViewModels
         public DelegateCommand SaveScrewFeedersCommand =>
             _SaveScrewFeedersCommand ?? (_SaveScrewFeedersCommand = new DelegateCommand(ExecuteSaveScrewFeedersCommand));
 
-       
+
         #endregion
 
         #region 事件
@@ -1040,7 +1040,7 @@ namespace TeamAAS_VP.ViewModels
 
                         try
                         {
-                            param=_configService.AddOrUpdateScrewFeeder(param);
+                            param = _configService.AddOrUpdateScrewFeeder(param);
                             // 直接添加对话框返回的对象(也可以根据需要映射字段)
                             ScrewFeederList.Add(param);
                         }
@@ -1498,7 +1498,7 @@ namespace TeamAAS_VP.ViewModels
                     sysConfig.FixedCameraPickNum = FixedCameraPickNum;
                     sysConfig.FixedCameraPutNum = FixedCameraPutNum;
                     sysConfig.FixedCameracheckNum = FixedCameracheckNum;
-                    sysConfig.ScrewTeachNum= ScrewTeachNum;
+                    sysConfig.ScrewTeachNum = ScrewTeachNum;
 
                     _configService.SaveSystemConfiguration(sysConfig);
                     await management.WriteSystemParameterToPlcAsync(sysConfig);
@@ -1506,7 +1506,7 @@ namespace TeamAAS_VP.ViewModels
                 }
                 catch (Exception ex)
                 {
-                    _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg =ex.Message, Duration = 1 });
+                    _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = ex.Message, Duration = 1 });
                 }
             }
         }

+ 26 - 1
TeamAAS-VM/Views/Calibration/CalibrationAuto.xaml.cs

@@ -1,4 +1,7 @@
-using System.Windows.Controls;
+using Cognex.VisionPro;
+using Cognex.VisionPro.Dimensioning;
+using System;
+using System.Windows.Controls;
 using TeamAAS_VP.ViewModels.Calibration;
 
 namespace TeamAAS_VP.Views.Calibration
@@ -20,6 +23,8 @@ namespace TeamAAS_VP.Views.Calibration
             this.display.BackColor = System.Drawing.SystemColors.ActiveCaption;
         }
 
+        private int _imageWidth;
+        private int _imageHeight;
         private void VM_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
         {
             try
@@ -27,10 +32,30 @@ namespace TeamAAS_VP.Views.Calibration
                 if (e.PropertyName == "Image")
                 {
                     this.display.Image = VM.Image;
+                    //图像中心点坐标
+                    _imageWidth = this.display.Image.Width;
+                    _imageHeight = this.display.Image.Height;
                 }
                 else if (e.PropertyName == "Graphic")
                 {
                     this.display.StaticGraphics.Clear();
+                    CogGraphicCollection graphic = new CogGraphicCollection();
+                    CogCreateLineTool line1 = new CogCreateLineTool();
+                    CogCreateLineTool line2 = new CogCreateLineTool();
+                    line1.InputImage = this.display.Image;
+                    line2.InputImage = this.display.Image;
+                    line1.Line.X = _imageWidth / 2;
+                    line1.Line.Y = _imageHeight / 2;
+                    line1.Line.Rotation = 0;
+                    line2.Line.X = _imageWidth / 2;
+                    line2.Line.Y = _imageHeight / 2;
+                    line2.Line.Rotation = Math.PI / 180 * 90;
+                    line1.Run();
+                    line2.Run();
+                    graphic.Add(line1.GetOutputLine());
+                    graphic.Add(line2.GetOutputLine());
+                    this.display.StaticGraphics.Clear();
+                    this.display.StaticGraphics.AddList(graphic, "");
                     if (VM.Graphic!=null)
                     {
                         this.display.StaticGraphics.AddList(VM.Graphic, "");

+ 1 - 1
TeamAAS-VM/Views/Calibration/CalibrationTeachCenterPoint.xaml

@@ -132,7 +132,7 @@
                            Grid.ColumnSpan="2"
                            Foreground="{DynamicResource PrimaryHueMidForegroundBrush}">
                     <TextBlock.Text>
-                        <MultiBinding StringFormat="{}X:{0:F3} mm Y:{1:F3} mm Z:{1:F3} mm">
+                        <MultiBinding StringFormat="{}X:{0:F3} mm Y:{1:F3} mm Z:{2:F3} mm">
                             <Binding Path="SelectCalibration.CenterPoint.X"
                                      TargetNullValue="0.000"
                                      FallbackValue="0.000" />

+ 94 - 0
TeamAAS-VM/Views/Home/SetAlarmValue.xaml

@@ -0,0 +1,94 @@
+<UserControl x:Class="TeamAAS_VP.Views.Home.SetAlarmValue"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:local="clr-namespace:TeamAAS_VP.Views.Home"
+             mc:Ignorable="d" 
+             xmlns:prism="http://prismlibrary.com/"
+             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+             xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
+             xmlns:sys="clr-namespace:System;assembly=mscorlib"
+             xmlns:enums="clr-namespace:TeamAAS_VP.Enums"
+             xmlns:uControl="clr-namespace:TeamAAS_VP.Controls"
+             xmlns:convert="clr-namespace:TeamAAS_VP.ValueConverter"
+             xmlns:valRules="clr-namespace:TeamAAS_VP.Identity"
+             xmlns:validationRule="clr-namespace:TeamAAS_VP.ValidationRules"
+             xmlns:ext="clr-namespace:TeamAAS_VP.Extension"
+             xmlns:lex="http://wpflocalizeextension.codeplex.com"
+             xmlns:vm="clr-namespace:TeamAAS_VP.ViewModels.Home"
+             lex:LocalizeDictionary.DesignCulture="zh-CN"
+             lex:ResxLocalizationProvider.DefaultAssembly="TeamAAS-VP"
+             lex:ResxLocalizationProvider.DefaultDictionary="Lang"
+             d:Background="White"
+             d:DataContext="{d:DesignInstance Type=vm:SetAlarmValueViewModel}"
+             prism:ViewModelLocator.AutoWireViewModel="True"
+             FontFamily="{DynamicResource DefaultFont}">
+    <Grid HorizontalAlignment="Center">
+        <Grid.RowDefinitions>
+            <RowDefinition />
+            <RowDefinition />
+            <RowDefinition />
+            <RowDefinition />
+        </Grid.RowDefinitions>
+        <Grid.ColumnDefinitions>
+            <ColumnDefinition />
+            <ColumnDefinition />
+        </Grid.ColumnDefinitions>
+        <TextBlock Text="{lex:Loc 设置批头吸嘴报警值}"
+                   FontSize="20" 
+                   HorizontalAlignment="Center"
+                   Margin="50,30"
+                   Grid.ColumnSpan="2"/>
+
+        <TextBlock Text="{lex:Loc 设置批头报警值}"
+                   FontSize="14"
+                   HorizontalAlignment="Right"
+                   Margin="10"
+                   Grid.Row="1"
+                   Grid.Column="0"/>
+
+        <TextBlock Text="{lex:Loc 设置吸嘴报警值}"
+                   FontSize="14"
+                   HorizontalAlignment="Right"
+                   Margin="10"
+                   Grid.Row="2"
+                   Grid.Column="0" />
+
+        <TextBox Text="{Binding BitAlarmValue}"
+                 FontSize="14"
+                 HorizontalAlignment="Left"
+                 Margin="10"
+                 Grid.Row="1"
+                 Grid.Column="1"
+                 Width="100"/>
+
+        <TextBox Text="{Binding NozzleAlarmValue}"
+                 FontSize="14"
+                 HorizontalAlignment="Left"
+                 Margin="10"
+                 Grid.Row="2"
+                 Grid.Column="1"
+                 Width="100" />
+
+        <StackPanel Orientation="Horizontal"
+                    Margin="10,3"
+                    HorizontalAlignment="Right"
+                    Grid.Row="3"
+                    Grid.ColumnSpan="2">
+            <Button Content="{lex:Loc 确定}"
+                    VerticalContentAlignment="Center"
+                    materialDesign:ButtonAssist.CornerRadius="10"
+                    Style="{StaticResource MaterialDesignRaisedDarkButton}"
+                    Command="{Binding ConfirmCommand}"
+                    Margin="10,3" />
+            <Button Content="{lex:Loc 取消}"
+                    VerticalContentAlignment="Center"
+                    materialDesign:ButtonAssist.CornerRadius="10"
+                    Style="{StaticResource MaterialDesignRaisedDarkButton}"
+                    Command="{Binding CancelCommand}"
+                    Margin="10,3" />
+        </StackPanel>
+
+    </Grid>
+</UserControl>

+ 28 - 0
TeamAAS-VM/Views/Home/SetAlarmValue.xaml.cs

@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace TeamAAS_VP.Views.Home
+{
+    /// <summary>
+    /// SetAlarmValue.xaml 的交互逻辑
+    /// </summary>
+    public partial class SetAlarmValue : UserControl
+    {
+        public SetAlarmValue()
+        {
+            InitializeComponent();
+        }
+    }
+}

+ 369 - 0
TeamAAS-VM/Views/Home/TorqueCheck.xaml

@@ -0,0 +1,369 @@
+<UserControl x:Class="TeamAAS_VP.Views.Home.TorqueCheck"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+             xmlns:local="clr-namespace:TeamAAS_VP.Views.Home"
+             mc:Ignorable="d"
+             xmlns:prism="http://prismlibrary.com/"
+             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+             xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
+             xmlns:sys="clr-namespace:System;assembly=mscorlib"
+             xmlns:enums="clr-namespace:TeamAAS_VP.Enums"
+             xmlns:uControl="clr-namespace:TeamAAS_VP.Controls"
+             xmlns:convert="clr-namespace:TeamAAS_VP.ValueConverter"
+             xmlns:valRules="clr-namespace:TeamAAS_VP.Identity"
+             xmlns:validationRule="clr-namespace:TeamAAS_VP.ValidationRules"
+             xmlns:ext="clr-namespace:TeamAAS_VP.Extension"
+             xmlns:lex="http://wpflocalizeextension.codeplex.com"
+             xmlns:vm="clr-namespace:TeamAAS_VP.ViewModels.Home"
+             lex:LocalizeDictionary.DesignCulture="zh-CN"
+             lex:ResxLocalizationProvider.DefaultAssembly="TeamAAS-VP"
+             lex:ResxLocalizationProvider.DefaultDictionary="Lang"
+             d:Background="White"
+             d:DataContext="{d:DesignInstance Type=vm:TorqueCheckViewModel}"
+             prism:ViewModelLocator.AutoWireViewModel="True"
+             FontFamily="{DynamicResource DefaultFont}">
+    <b:Interaction.Triggers>
+        <b:EventTrigger EventName="Loaded">
+            <b:InvokeCommandAction Command="{Binding LoadedCommand}" />
+        </b:EventTrigger>
+    </b:Interaction.Triggers>
+
+    <UserControl.Resources>
+        <convert:JogConverter x:Key="JogConverter" />
+        <convert:MultiParameterConverter x:Key="MultiParameterConverter" />
+        <convert:RobotConverter x:Key="RobotConverter" />
+    </UserControl.Resources>
+
+    <prism:Dialog.WindowStyle>
+        <Style TargetType="Window">
+            <Setter Property="prism:Dialog.WindowStartupLocation"
+                    Value="CenterScreen" />
+            <!--<Setter Property="WindowChrome.WindowChrome">
+        <Setter.Value>
+            <WindowChrome CaptionHeight="0"
+                          ResizeBorderThickness="1" />
+        </Setter.Value>
+    </Setter>-->
+            <Setter Property="WindowStyle"
+                    Value="None" />
+            <Setter Property="AllowDrop"
+                    Value="True" />
+            <Setter Property="BorderThickness"
+                    Value="0" />
+            <Setter Property="ShowInTaskbar"
+                    Value="False" />
+            <Setter Property="SizeToContent"
+                    Value="WidthAndHeight" />
+            <Setter Property="WindowState"
+                    Value="Normal" />
+            <Setter Property="Topmost"
+                    Value="True" />
+        </Style>
+    </prism:Dialog.WindowStyle>
+
+    <Grid HorizontalAlignment="Center">
+        <Grid.ColumnDefinitions>
+            <ColumnDefinition />
+            <ColumnDefinition />
+        </Grid.ColumnDefinitions>
+        <materialDesign:DrawerHost Grid.Column="0"
+                                   OpenMode="Standard"
+                                   x:Name="DrawerHost"
+                                   IsLeftDrawerOpen="{Binding IsLeftDrawerOpen,Mode=TwoWay}"
+                                   d:IsLeftDrawerOpen="true"
+                                   IsEnabled="{Binding IsAllowEdit}">
+            <materialDesign:DrawerHost.LeftDrawerContent>
+                <Grid Width="auto">
+                    <Grid.RowDefinitions>
+                        <RowDefinition Height="*" />
+                        <RowDefinition Height="*" />
+                        <RowDefinition Height="*" />
+                    </Grid.RowDefinitions>
+                    <StackPanel Orientation="Horizontal"
+                                HorizontalAlignment="Center"
+                                VerticalAlignment="Center"
+                                Margin="5">
+                        <Button Content="{lex:Loc 上使能}"
+                                materialDesign:ButtonAssist.CornerRadius="10"
+                                Style="{StaticResource MaterialDesignRaisedDarkButton}"
+                                Command="{Binding DataContext.MotorCommand,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
+                                CommandParameter="True"
+                                Margin="10,0" />
+                        <Button Content="{lex:Loc 下使能}"
+                                Margin="10,0"
+                                materialDesign:ButtonAssist.CornerRadius="10"
+                                Style="{StaticResource MaterialDesignRaisedDarkButton}"
+                                Command="{Binding DataContext.MotorCommand,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
+                                CommandParameter="False" />
+                    </StackPanel>
+
+                    <Grid Grid.Row="1">
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition Width="auto" />
+                            <ColumnDefinition Width="auto" />
+                            <ColumnDefinition Width="auto" />
+                            <ColumnDefinition Width="auto" />
+                        </Grid.ColumnDefinitions>
+                        <Grid.RowDefinitions>
+                            <RowDefinition Height="auto" />
+                            <RowDefinition Height="auto" />
+                            <RowDefinition Height="auto" />
+                        </Grid.RowDefinitions>
+                        <Grid.Resources>
+                            <Style TargetType="Button"
+                                   BasedOn="{StaticResource MaterialDesignRaisedDarkButton}">
+                                <Setter Property="Width"
+                                        Value="60" />
+                                <Setter Property="Height"
+                                        Value="60" />
+                                <Setter Property="FontSize"
+                                        Value="13" />
+                                <Setter Property="Padding"
+                                        Value="0" />
+                                <Setter Property="HorizontalAlignment"
+                                        Value="Center" />
+                                <Setter Property="VerticalAlignment"
+                                        Value="Center" />
+                                <Setter Property="Margin"
+                                        Value="2" />
+                                <Setter Property="materialDesign:ButtonAssist.CornerRadius"
+                                        Value="10" />
+                            </Style>
+                        </Grid.Resources>
+                        <Button Grid.Row="1"
+                                Grid.Column="0"
+                                Command="{Binding DataContext.JogCommand,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
+                                CommandParameter="{Binding ElementName=txtDistance,Path=Value,Converter={StaticResource JogConverter}, ConverterParameter=X-}">
+                            <StackPanel Orientation="Vertical">
+                                <materialDesign:PackIcon Kind="ArrowLeftBold"
+                                                         Width="26"
+                                                         Height="26" />
+                                <TextBlock Text="-X"
+                                           HorizontalAlignment="Center" />
+                            </StackPanel>
+                        </Button>
+                        <Button Grid.Row="1"
+                                Grid.Column="2"
+                                Command="{Binding DataContext.JogCommand,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
+                                CommandParameter="{Binding ElementName=txtDistance,Path=Value,Converter={StaticResource JogConverter}, ConverterParameter=X+}">
+                            <StackPanel Orientation="Vertical">
+                                <materialDesign:PackIcon Kind="ArrowRightBold"
+                                                         Width="26"
+                                                         Height="26" />
+                                <TextBlock Text="+X"
+                                           HorizontalAlignment="Center" />
+                            </StackPanel>
+                        </Button>
+                        <Button Grid.Row="0"
+                                Grid.Column="1"
+                                Command="{Binding DataContext.JogCommand,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
+                                CommandParameter="{Binding ElementName=txtDistance,Path=Value,Converter={StaticResource JogConverter}, ConverterParameter=Y+}">
+                            <StackPanel Orientation="Vertical">
+                                <materialDesign:PackIcon Kind="ArrowTopBold"
+                                                         Width="26"
+                                                         Height="26" />
+                                <TextBlock Text="+Y"
+                                           HorizontalAlignment="Center" />
+                            </StackPanel>
+                        </Button>
+                        <Button Grid.Row="2"
+                                Grid.Column="1"
+                                Command="{Binding DataContext.JogCommand,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
+                                CommandParameter="{Binding ElementName=txtDistance,Path=Value,Converter={StaticResource JogConverter}, ConverterParameter=Y-}">
+                            <StackPanel Orientation="Vertical">
+                                <materialDesign:PackIcon Kind="ArrowBottomBold"
+                                                         Width="26"
+                                                         Height="26" />
+                                <TextBlock Text="-Y"
+                                           HorizontalAlignment="Center" />
+                            </StackPanel>
+                        </Button>
+                        <Button Grid.Row="0"
+                                Grid.Column="3"
+                                Command="{Binding DataContext.JogCommand,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
+                                CommandParameter="{Binding ElementName=txtDistance,Path=Value,Converter={StaticResource JogConverter}, ConverterParameter=Z+}">
+                            <StackPanel Orientation="Vertical">
+                                <materialDesign:PackIcon Kind="ArrowTopBold"
+                                                         Width="26"
+                                                         Height="26" />
+                                <TextBlock Text="+Z"
+                                           HorizontalAlignment="Center" />
+                            </StackPanel>
+                        </Button>
+                        <Button Grid.Row="2"
+                                Grid.Column="3"
+                                Command="{Binding DataContext.JogCommand,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
+                                CommandParameter="{Binding ElementName=txtDistance,Path=Value,Converter={StaticResource JogConverter}, ConverterParameter=Z-}">
+                            <StackPanel Orientation="Vertical">
+                                <materialDesign:PackIcon Kind="ArrowBottomBold"
+                                                         Width="26"
+                                                         Height="26" />
+                                <TextBlock Text="-Z"
+                                           HorizontalAlignment="Center" />
+                            </StackPanel>
+                        </Button>
+                    </Grid>
+
+                    <Grid Grid.Row="2">
+                        <Grid.RowDefinitions>
+                            <RowDefinition />
+                            <RowDefinition />
+                            <RowDefinition />
+                        </Grid.RowDefinitions>
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition />
+                            <ColumnDefinition />
+                        </Grid.ColumnDefinitions>
+                        <TextBlock VerticalAlignment="Center"
+                                   Margin="5"
+                                   Grid.ColumnSpan="2">
+                            <TextBlock.Text>
+                                <MultiBinding StringFormat="{}CurPos X: {0:F3} mm Y: {1:F3} mm Z: {2:F3} mm">
+                                    <Binding Path="Robot.CurrentPosition.X" />
+                                    <Binding Path="Robot.CurrentPosition.Y" />
+                                    <Binding Path="Robot.CurrentPosition.Z" />
+                                </MultiBinding>
+                            </TextBlock.Text>
+                        </TextBlock>
+
+                        <TextBlock Grid.Row="1"
+                                   Grid.Column="0"
+                                   Text="{lex:Loc 步进距离,Converter={StaticResource StringFormatConverter},ConverterParameter='{}{0}: '}"
+                                   Margin="10"
+                                   VerticalAlignment="Center"
+                                   HorizontalAlignment="Right" />
+                        <uControl:myNumericUpDowm x:Name="txtDistance"
+                                                  Grid.Row="1"
+                                                  Grid.Column="1"
+                                                  MinWidth="100"
+                                                  Value="{Binding DataContext.Distance,RelativeSource={RelativeSource AncestorType={x:Type UserControl}},Mode=TwoWay}"
+                                                  Interval="0.1"
+                                                  Minimum="0"
+                                                  Maximum="100"
+                                                  StringFormat="{}{0:N3} mm"
+                                                  Margin="10"
+                                                  materialDesign:HintAssist.Hint="{lex:Loc 步进距离}" />
+
+
+                        <Button Grid.Row="2"
+                                Grid.ColumnSpan="2"
+                                Content="{lex:Loc 示教}"
+                                Margin="0,10"
+                                HorizontalAlignment="Center"
+                                materialDesign:ButtonAssist.CornerRadius="10"
+                                Style="{StaticResource MaterialDesignRaisedDarkButton}"
+                                Command="{Binding TechPointCommand}" />
+                    </Grid>
+                </Grid>
+            </materialDesign:DrawerHost.LeftDrawerContent>
+
+            <Grid Grid.Column="1">
+                <Grid.RowDefinitions>
+                    <RowDefinition Height="auto" />
+                    <RowDefinition />
+                    <RowDefinition />
+                    <RowDefinition Height="auto" />
+                    <RowDefinition />
+                    <RowDefinition Height="auto" />
+                </Grid.RowDefinitions>
+                <ToggleButton HorizontalAlignment="Left"
+                              VerticalAlignment="Top"
+                              materialDesign:ToggleButtonAssist.OnContent="{materialDesign:PackIcon Kind=ArrowLeft}"
+                              Content="{materialDesign:PackIcon Kind=ArrowAll}"
+                              Style="{StaticResource MaterialDesignActionToggleButton}"
+                              ToolTip="轴操作"
+                              Margin="5,0"
+                              IsChecked="{Binding IsLeftDrawerOpen,ElementName=DrawerHost}" />
+
+                <StackPanel Orientation="Horizontal"
+                            HorizontalAlignment="Left"
+                            VerticalAlignment="Center"
+                            Grid.Row="1"
+                            Margin="5,2">
+                    <TextBlock Text="{lex:Loc 扭力阈值}"
+                               VerticalAlignment="Center"
+                               Margin="5,2" />
+                    <TextBox Text="{Binding torqueValue}"
+                             VerticalAlignment="Center"
+                             HorizontalAlignment="Center"
+                             Width="80"
+                             Margin="5,2" />
+                    <Button Content="{lex:Loc 修改}"
+                            Margin="15,2"
+                            HorizontalAlignment="Center"
+                            materialDesign:ButtonAssist.CornerRadius="10"
+                            Style="{StaticResource MaterialDesignRaisedDarkButton}"
+                            Command="{Binding ModifyCommand}" />
+                </StackPanel>
+
+                <Grid Grid.Row="2">
+                    <Grid.ColumnDefinitions>
+                        <ColumnDefinition Width="auto" />
+                        <ColumnDefinition />
+                    </Grid.ColumnDefinitions>
+                    <StackPanel Orientation="Vertical"
+                                HorizontalAlignment="Left"
+                                VerticalAlignment="Center"
+                                Margin="5,2">
+                        <TextBlock Text="{lex:Loc 扭力测量仪值}"
+                                   Margin="5,3,10,3" />
+                        <TextBlock Text="{lex:Loc 电批测量值}"
+                                   Margin="5,3,10,3" />
+                        <TextBlock Text="{lex:Loc 差值}"
+                                   Margin="5,3,10,3" />
+                    </StackPanel>
+                    <StackPanel Orientation="Vertical"
+                                HorizontalAlignment="Left"
+                                VerticalAlignment="Center"
+                                Margin="2"
+                                Grid.Column="1">
+                        <TextBlock Text="{Binding TValue}"
+                                   Margin="3" />
+                        <TextBlock Text="{Binding PValue}"
+                                   Margin="3" />
+                        <TextBlock Text="{Binding SubValue}"
+                                   Margin="3" />
+                    </StackPanel>
+                </Grid>
+
+                <Button Content="{lex:Loc 执行}"
+                        VerticalContentAlignment="Center"
+                        materialDesign:ButtonAssist.CornerRadius="10"
+                        Style="{StaticResource MaterialDesignRaisedDarkButton}"
+                        Command="{Binding WorkCommand}"
+                        Margin="10,5"
+                        Grid.Row="3"/>
+
+                <TextBlock Text="{Binding Result}"
+                           HorizontalAlignment="Center"
+                           VerticalAlignment="Center"
+                           Grid.Row="4"
+                           FontSize="30"
+                           Foreground="{Binding FontColor}" />
+
+                <StackPanel Orientation="Horizontal"
+                            Margin="10,3"
+                            HorizontalAlignment="Right"
+                            Grid.Row="5">
+                    <Button Content="{lex:Loc 确定}"
+                            VerticalContentAlignment="Center"
+                            materialDesign:ButtonAssist.CornerRadius="10"
+                            Style="{StaticResource MaterialDesignRaisedDarkButton}"
+                            Command="{Binding ConfirmCommand}"
+                            Margin="10,3" />
+                    <Button Content="{lex:Loc 取消}"
+                            VerticalContentAlignment="Center"
+                            materialDesign:ButtonAssist.CornerRadius="10"
+                            Style="{StaticResource MaterialDesignRaisedDarkButton}"
+                            Command="{Binding CancelCommand}"
+                            Margin="10,3" />
+                </StackPanel>
+
+            </Grid>
+
+        </materialDesign:DrawerHost>
+
+    </Grid>
+</UserControl>

+ 28 - 0
TeamAAS-VM/Views/Home/TorqueCheck.xaml.cs

@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace TeamAAS_VP.Views.Home
+{
+    /// <summary>
+    /// TorqueCheck.xaml 的交互逻辑
+    /// </summary>
+    public partial class TorqueCheck : UserControl
+    {
+        public TorqueCheck()
+        {
+            InitializeComponent();
+        }
+    }
+}

+ 108 - 16
TeamAAS-VM/Views/HomeView.xaml

@@ -51,7 +51,8 @@
               Grid.Column="1">
             <Grid.RowDefinitions>
                 <RowDefinition Height="60*" />
-                <RowDefinition Height="40*" />
+                <RowDefinition Height="5*" />
+                <RowDefinition Height="35*" />
             </Grid.RowDefinitions>
             <Grid>
                 <Grid.RowDefinitions>
@@ -89,6 +90,10 @@
                                                     Binding="{Binding Number}"
                                                     Width="auto"
                                                     IsReadOnly="True" />
+                                <DataGridTextColumn Header="{lex:Loc 产品名称}"
+                                                    Binding="{Binding ProductName}"
+                                                    Width="auto"
+                                                    IsReadOnly="True" />
                                 <DataGridTextColumn Header="{lex:Loc 产品编号}"
                                                     Binding="{Binding ProductNumber}"
                                                     Width="auto"
@@ -315,7 +320,6 @@
                     </materialDesign:Card>
                 </Grid>
 
-
                 <StackPanel Grid.Row="2"
                             Orientation="Horizontal"
                             VerticalAlignment="Bottom"
@@ -329,19 +333,107 @@
                                VerticalAlignment="Center"
                                Margin="10,0" />
                 </StackPanel>
-                <Button Grid.Row="2"
-                        Content="{lex:Loc 计数清零}"
-                        VerticalAlignment="Bottom"
-                        Margin=" 10,3"
-                        HorizontalAlignment="Right"
-                        materialDesign:ButtonAssist.CornerRadius="10"
-                        Style="{StaticResource MaterialDesignRaisedButton}"
-                        Command="{Binding ResetCounterCommand}" />
+
+                <StackPanel Grid.Row="2"
+                            Orientation="Horizontal"
+                            VerticalAlignment="Bottom"
+                            HorizontalAlignment="Right"
+                            Margin="10,3">
+                    <Button Content="{lex:Loc 扭力点检}"
+                            Margin="3"
+                            materialDesign:ButtonAssist.CornerRadius="10"
+                            Style="{StaticResource MaterialDesignRaisedButton}"
+                            Command="{Binding TorqueInspectionCommand}"
+                            IsEnabled="{Binding IsAllowEdit}" />
+                    <Button Content="{lex:Loc 计数清零}"
+                            Margin="3"
+                            materialDesign:ButtonAssist.CornerRadius="10"
+                            Style="{StaticResource MaterialDesignRaisedButton}"
+                            Command="{Binding ResetCounterCommand}"
+                            IsEnabled="{Binding IsAllowEdit}" />
+                    <Button Content="{lex:Loc 批头吸嘴计数清零}"
+                            Margin="3"
+                            materialDesign:ButtonAssist.CornerRadius="10"
+                            Style="{StaticResource MaterialDesignRaisedButton}"
+                            Command="{Binding NozzleCounterResetCommand}"
+                            IsEnabled="{Binding IsAllowEdit}" />
+                    <Button Content="{lex:Loc 设置批头吸嘴报警值}"
+                            Margin="3"
+                            materialDesign:ButtonAssist.CornerRadius="10"
+                            Style="{StaticResource MaterialDesignRaisedButton}"
+                            Command="{Binding SetAlarmValueCommand}"
+                            IsEnabled="{Binding IsAllowEdit}" />
+                </StackPanel>
+
             </Grid>
-            <Border Grid.Row="1"
-                    CornerRadius="20"
-                    BorderBrush="#787878"
-                    BorderThickness="1">
+            
+            <materialDesign:Card Grid.Row="1"
+                                 UniformCornerRadius="10"
+                                 BorderBrush="LightGray"
+                                 BorderThickness="1"
+                                 Margin="0,0,0,2">
+                <Grid>
+                    <Grid.ColumnDefinitions>
+                        <ColumnDefinition />
+                        <ColumnDefinition />
+                        <ColumnDefinition />
+                        <ColumnDefinition />
+                    </Grid.ColumnDefinitions>
+
+                    <StackPanel Orientation="Horizontal"
+                                HorizontalAlignment="Left"
+                                VerticalAlignment="Center"
+                                Margin="3">
+                        <TextBlock Text="{lex:Loc 批头}"
+                                   Margin="0,0,10,0"
+                                   FontSize="14" />
+                        <TextBlock Text="{Binding management.NumStatistics.HeaderNum}"
+                                   FontSize="14" />
+                    </StackPanel>
+
+                    <StackPanel Orientation="Horizontal"
+                                HorizontalAlignment="Left"
+                                VerticalAlignment="Center"
+                                Margin="3"
+                                Grid.Column="1">
+                        <TextBlock Text="{lex:Loc 吸嘴}"
+                                   Margin="0,0,10,0"
+                                   FontSize="14" />
+                        <TextBlock Text="{Binding management.NumStatistics.NozzleNum}"
+                                   FontSize="14" />
+                    </StackPanel>
+
+                    <StackPanel Orientation="Horizontal"
+                                HorizontalAlignment="Left"
+                                VerticalAlignment="Center"
+                                Margin="3"
+                                Grid.Column="2">
+                        <TextBlock Text="{lex:Loc 供料器1}"
+                                   Margin="0,0,10,0"
+                                   FontSize="14" />
+                        <TextBlock Text="{Binding management.NumStatistics.Feeder1Num}"
+                                   FontSize="14" />
+                    </StackPanel>
+
+                    <StackPanel Orientation="Horizontal"
+                                HorizontalAlignment="Left"
+                                VerticalAlignment="Center"
+                                Margin="3"
+                                Grid.Column="3">
+                        <TextBlock Text="{lex:Loc 供料器2}"
+                                   Margin="0,0,10,0"
+                                   FontSize="14" />
+                        <TextBlock Text="{Binding management.NumStatistics.Feeder2Num}"
+                                   FontSize="14" />
+                    </StackPanel>
+                </Grid>
+            </materialDesign:Card>
+            
+            <materialDesign:Card Grid.Row="2"
+                                 UniformCornerRadius="10"
+                                 BorderBrush="LightGray"
+                                 BorderThickness="1"
+                                 Margin="0,2,0,0">
                 <DockPanel LastChildFill="True"
                            Margin="10">
                     <TextBlock Text="{lex:Loc 运行信息,Converter={StaticResource StringFormatConverter},ConverterParameter='{}{0}: '}"
@@ -373,7 +465,7 @@
                             <DataTemplate>
                                 <Border BorderThickness="0"
                                         HorizontalAlignment="Left">
-                                    <Label MaxWidth="300"
+                                    <Label MaxWidth="600"
                                            BorderThickness="0"
                                            Background="Transparent"
                                            Margin="0"
@@ -406,7 +498,7 @@
                         </ListView.ItemTemplate>
                     </ListView>
                 </DockPanel>
-            </Border>
+            </materialDesign:Card>
         </Grid>
     </Grid>
 </UserControl>

+ 6 - 5
TeamAAS-VM/Views/SettingView.xaml

@@ -1763,7 +1763,8 @@
                                        Grid.Column="0"
                                        Style="{StaticResource MaterialDesignSubtitle1TextBlock}"
                                        HorizontalAlignment="Right"
-                                       VerticalAlignment="Center" />
+                                       VerticalAlignment="Center"
+                                       Text="是否启用低量报警:"/>
                             <CheckBox Grid.Row="5"
                                       Grid.Column="1"
                                       Margin="10,0"
@@ -2048,7 +2049,7 @@
                             <RowDefinition Height="Auto" />
                             <RowDefinition Height="Auto" />
                             <RowDefinition Height="Auto" />
-                            <RowDefinition Height="40" />
+                            <RowDefinition Height="Auto" />
                         </Grid.RowDefinitions>
 
                         <!-- 相机拍照次数 -->
@@ -2200,7 +2201,7 @@
                                    VerticalAlignment="Center"
                                    HorizontalAlignment="Right"
                                    Margin="0,6,10,6"
-                                   Text="{lex:Loc 披头矫正的模式}" />
+                                   Text="{lex:Loc 批头矫正的模式}" />
                         <mah:NumericUpDown Grid.Row="9"
                                            Grid.Column="1"
                                            Margin="0,6"
@@ -2211,11 +2212,11 @@
 
                         <!-- 保存按钮 -->
                         <StackPanel Grid.Row="10"
-                                    Grid.ColumnSpan="3"
+                                    Grid.ColumnSpan="2"
                                     Orientation="Horizontal"
                                     HorizontalAlignment="Right"
                                     VerticalAlignment="Center"
-                                    Margin="0,10,0,0">
+                                    Margin="5">
                             <Button Style="{StaticResource MaterialDesignRaisedButton}"
                                     materialDesign:ButtonAssist.CornerRadius="10"
                                     MinWidth="120"

+ 7 - 4
TeamAAS-VM/Views/Statistics/LockResultRecoredQuery.xaml

@@ -78,19 +78,22 @@
                                     Width="60" />
                 <DataGridTextColumn Header="{lex:Loc 时间}"
                                     Binding="{Binding Timestamp, StringFormat=yyyy-MM-dd HH:mm:ss}"
-                                    Width="160" />
+                                    Width="auto" />
+                <DataGridTextColumn Header="{lex:Loc 产品名称}"
+                                    Binding="{Binding ProductName}"
+                                    Width="auto" />
                 <DataGridTextColumn Header="{lex:Loc 产品编号}"
                                     Binding="{Binding ProductNumber}"
                                     Width="150" />
                 <DataGridTextColumn Header="{lex:Loc 螺丝编号}"
                                     Binding="{Binding Number}"
-                                    Width="80" />
+                                    Width="auto" />
                 <DataGridTextColumn Header="{lex:Loc 电批程序号}"
                                     Binding="{Binding ScrewdriverProgramNumber}"
-                                    Width="110" />
+                                    Width="auto" />
                 <DataGridTextColumn Header="{lex:Loc 锁付圈数}"
                                     Binding="{Binding LockTurns}"
-                                    Width="90" />
+                                    Width="100" />
                 <DataGridTextColumn Header="{lex:Loc 锁付扭矩}"
                                     Binding="{Binding LockTorque}"
                                     Width="90" />