zly hai 1 mes
pai
achega
7e323092cf
Modificáronse 31 ficheiros con 2043 adicións e 339 borrados
  1. 24 12
      TeamAAS-VM/Controls/ParameterEdit.xaml
  2. 1 1
      TeamAAS-VM/Core/ImageHelper.cs
  3. 551 172
      TeamAAS-VM/Core/Management.cs
  4. 1 0
      TeamAAS-VM/Core/PLCs/OPCuaClientPLC.cs
  5. 19 0
      TeamAAS-VM/Core/Robots/XYZU_Robot.cs
  6. 1 1
      TeamAAS-VM/Events/LockFinishNotification.cs
  7. 3 3
      TeamAAS-VM/Interfaces/IMesService.cs
  8. 20 0
      TeamAAS-VM/Interfaces/IRemoteCommandService.cs
  9. 92 2
      TeamAAS-VM/Models/PLC/PlcAddressConfig.cs
  10. 52 0
      TeamAAS-VM/Models/PLC/PlcTemperatureAddress.cs
  11. 25 7
      TeamAAS-VM/Models/Product/ProductGlobalParam.cs
  12. 49 0
      TeamAAS-VM/Models/Product/ProductModel.cs
  13. 68 1
      TeamAAS-VM/Models/SystemConfiguration.cs
  14. 2 2
      TeamAAS-VM/Properties/AssemblyInfo.cs
  15. 9 9
      TeamAAS-VM/Services/MesService.cs
  16. 329 53
      TeamAAS-VM/Services/RemoteCommandService.cs
  17. 2 0
      TeamAAS-VM/TeamAAS-VP.csproj
  18. 25 0
      TeamAAS-VM/ValueConverter/CountToColumnsConverter.cs
  19. 123 0
      TeamAAS-VM/ViewModels/HomeViewModel.cs
  20. 6 6
      TeamAAS-VM/ViewModels/MainWindowViewModel.cs
  21. 215 14
      TeamAAS-VM/ViewModels/Product/PlcPointParamsViewModel.cs
  22. 83 1
      TeamAAS-VM/ViewModels/Product/ProductParamsViewModel.cs
  23. 13 1
      TeamAAS-VM/ViewModels/SettingViewModel.cs
  24. 8 2
      TeamAAS-VM/ViewModels/Statistics/ProductionStatementViewModel.cs
  25. 2 2
      TeamAAS-VM/Views/Home/ShowVisionRender.xaml.cs
  26. 49 5
      TeamAAS-VM/Views/HomeView.xaml
  27. 92 20
      TeamAAS-VM/Views/Product/PlcPointParams.xaml
  28. 67 0
      TeamAAS-VM/Views/Product/PlcPointParams.xaml.cs
  29. 47 23
      TeamAAS-VM/Views/Product/ProductParams.xaml
  30. 25 2
      TeamAAS-VM/Views/SettingView.xaml
  31. 40 0
      TeamAAS-VM/Views/Statistics/ProductionStatement.xaml

+ 24 - 12
TeamAAS-VM/Controls/ParameterEdit.xaml

@@ -37,7 +37,7 @@
                 <TextBlock Text="{Binding ElementName=dg_params,Path=Items.Count}" VerticalAlignment="Center" Margin="5,0" />
             </StackPanel>
         </StackPanel>
-        
+
         <DataGrid x:Name="dg_params" Grid.Row="1" AutoGenerateColumns="False"
                   CanUserAddRows="False"
                   ColumnWidth="*"
@@ -49,26 +49,38 @@
             <DataGrid.Columns>
                 <DataGridTextColumn Header="{lex:Loc 编号}"
                                     IsReadOnly="True"
-                                    MinWidth="60"
+                                    MinWidth="30"
                                     Binding="{Binding Number, Mode=TwoWay}">
                 </DataGridTextColumn>
                 <DataGridTextColumn Header="Name"
-                                    MinWidth="80"
+                                    MinWidth="130"
                                     Binding="{Binding Name, Mode=TwoWay}" />
-                <DataGridTextColumn Header="Param1"
-                                    MinWidth="80"
+                <DataGridTextColumn Header="启用"
+                                    MinWidth="50"
                                     Binding="{Binding Param1, Mode=TwoWay}" />
-                <DataGridTextColumn Header="Param2"
-                                    MinWidth="80"
+                <DataGridTextColumn Header="时间"
+                                    MinWidth="50"
                                     Binding="{Binding Param2, Mode=TwoWay}" />
-                <DataGridTextColumn Header="Param3"
-                                    MinWidth="80"
+                <DataGridTextColumn Header="设定压力"
+                                    MinWidth="50"
                                     Binding="{Binding Param3, Mode=TwoWay}" />
-                <DataGridTextColumn Header="Param4"
-                                    MinWidth="80"
+                <DataGridTextColumn Header="备用"
+                                    MinWidth="50"
                                     Binding="{Binding Param4, Mode=TwoWay}" />
+                <DataGridTextColumn Header="下限"
+                                    MinWidth="50"
+                                    Binding="{Binding Param5, Mode=TwoWay}" />
+                <DataGridTextColumn Header="上限"
+                                    MinWidth="50"
+                                    Binding="{Binding Param6, Mode=TwoWay}" />
+
+                <DataGridTextColumn Header="备注"
+                                    MinWidth="240"
+                                    Binding="{Binding Remark, Mode=TwoWay}" />
+
+
             </DataGrid.Columns>
         </DataGrid>
-        
+
     </Grid>
 </UserControl>

+ 1 - 1
TeamAAS-VM/Core/ImageHelper.cs

@@ -20,7 +20,7 @@ namespace TeamAAS_VP.Core
         /// <param name="bitmap"></param>
         /// <param name="path">目标图像存储路径JPEG</param>
         /// <param name="quality">压缩等级,0到100,0 最差质量,100 最佳</param>
-        public static void CompressImage(Bitmap bitmap, string path, long quality = 100)
+        public static void CompressImage(Bitmap bitmap, string path, long quality = 20)
         {
             ImageCodecInfo codecInfo = GetEncoderInfo("image/jpeg");
             System.Drawing.Imaging.Encoder encoder = System.Drawing.Imaging.Encoder.Quality;

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 551 - 172
TeamAAS-VM/Core/Management.cs


+ 1 - 0
TeamAAS-VM/Core/PLCs/OPCuaClientPLC.cs

@@ -83,6 +83,7 @@ namespace TeamAAS_VP.Core.PLCs
         /// 在未显式传入订阅选项时,`SubscribeNodes` 将使用该模式决定采用 OPC UA 原生订阅还是客户端轮询订阅。
         /// 默认值为 <see cref="OpcUaSubscriptionMode.Native"/>。
         /// </summary>
+        //public OpcUaSubscriptionMode DefaultSubscriptionMode { get; set; } = OpcUaSubscriptionMode.CustomPolling;
         public OpcUaSubscriptionMode DefaultSubscriptionMode { get; set; } = OpcUaSubscriptionMode.Native;
 
         /// <summary>

+ 19 - 0
TeamAAS-VM/Core/Robots/XYZU_Robot.cs

@@ -89,6 +89,18 @@ namespace TeamAAS_VP.Core.Robots
                 Axes.Add(au);
                 Brand = RobotBrand.XYZU_Platform;
             }
+            // R optional
+            if (robot.PlcRobotParameter.AxixList.Count >= 5)
+            {
+                var au = new Axis();
+                au.Name = "R";
+                au.Index = 5;
+                au.Command = robot.PlcRobotParameter.AxixList[4].Command;
+                au.Parameter = robot.PlcRobotParameter.AxixList[4].Parameter;
+                au.State = robot.PlcRobotParameter.AxixList[4].State;
+                Axes.Add(au);
+                Brand = RobotBrand.XYZU_Platform;
+            }
 
             if (Plc.IsConnected)
             {
@@ -113,6 +125,7 @@ namespace TeamAAS_VP.Core.Robots
                                     case "Y": CurrentPosition.Y = v; break;
                                     case "Z": CurrentPosition.Z = v; break;
                                     case "U": CurrentPosition.U = v; break;
+                                    case "R": CurrentPosition.V = v; break;
                                 }
                             }
                         }
@@ -355,6 +368,7 @@ namespace TeamAAS_VP.Core.Robots
                         case "Y": point.Y = v; break;
                         case "Z": point.Z = v; break;
                         case "U": point.U = v; break;
+                        case "R": point.V = v; break;
                         default: break;
                     }
                 }
@@ -408,6 +422,9 @@ namespace TeamAAS_VP.Core.Robots
                 case "U":
                     currentPos.U += (float)distance;
                     break;
+                case "R":
+                    currentPos.V += (float)distance;
+                    break;
                 default:
                     return false;
             }
@@ -520,6 +537,7 @@ namespace TeamAAS_VP.Core.Robots
                         case "Y": value = position.Y; break;
                         case "Z": value = position.Z; break;
                         case "U": value = position.U; break;
+                        case "R": value = position.V; break;
                         default: value = 0; break;
                     }
                     keyValues.Add(nodeid, value);
@@ -781,6 +799,7 @@ namespace TeamAAS_VP.Core.Robots
                     case "Y": targetPos = position.Y; break;
                     case "Z": targetPos = position.Z; break;
                     case "U": targetPos = position.U; break;
+                    case "R": targetPos = position.V; break;
                     default: targetPos = 0; break;
                 }
                 //如果定位完成且位置一致,则此轴完成,如果有错误则失败

+ 1 - 1
TeamAAS-VM/Events/LockFinishNotification.cs

@@ -17,7 +17,7 @@ namespace TeamAAS_VP.Events
     }
 
     //保压完成通知
-    public class PressureFinishNotification : Prism.Events.PubSubEvent<(bool IsSuccess, (DateTime Timestamp, float Value)[] values, string SavePath)>
+    public class PressureFinishNotification : Prism.Events.PubSubEvent<(bool IsSuccess, int Index, (DateTime Timestamp, float Value)[] values, string SavePath)>
     {
 
     }

+ 3 - 3
TeamAAS-VM/Interfaces/IMesService.cs

@@ -29,7 +29,7 @@ namespace TeamAAS_VP.Interfaces
         /// </remarks>
         Task<(bool IsSuccess, string Response)> StationGetAsync(int deviceNo, string sn, string comp, CancellationToken cancellationToken = default);
 
-        Task<(bool IsSuccess, string Response)> StationGetExAsync(string sn, string comp, double timeoutInSeconds);
+        Task<(bool IsSuccess, string Response)> StationGetExAsync(string sn, string comp, double timeoutInSeconds,int index);
 
         /// <summary>
         /// 使用配置的过站(Station)URL 发起 GET 请求,携带序列号(sn)作为查询参数进行过站,并使用指定的超时时间(秒)。
@@ -70,7 +70,7 @@ namespace TeamAAS_VP.Interfaces
         /// - 此重载方便在不使用 <see cref="CancellationToken"/> 的场景中指定超时时间。
         /// - 实现应验证 <paramref name="timeoutInSeconds"/> 为合理值(例如 > 0),否则可抛出 <see cref="ArgumentOutOfRangeException"/>。
         /// </remarks>
-        Task<(bool IsSuccess, string Response)> StationGetAsync(string sn, string comp, double timeoutInSeconds);
+        Task<(bool IsSuccess, string Response)> StationGetAsync(string sn, string comp, double timeoutInSeconds,int index);
 
         /// <summary>
         /// 使用配置的提交(Submit)URL 发起 GET 请求,提交过站结果及时间信息。
@@ -112,7 +112,7 @@ namespace TeamAAS_VP.Interfaces
         /// </remarks>
         Task<(bool IsSuccess, string Response)> SubmitGetAsync(string sn, string comp, Dictionary<string, string> data, bool isSuccess, DateTime start_time, DateTime stop_time, CancellationToken cancellationToken = default);
 
-        Task<(bool IsSuccess, string Response)> SubmitGetExAsync(string sn, string comp, Dictionary<string, string> data, List<string> results, DateTime start_time, DateTime stop_time, CancellationToken cancellationToken = default);
+        Task<(bool IsSuccess, string Response)> SubmitGetExAsync(string sn, string comp, Dictionary<string, string> data, List<string> results, DateTime start_time, DateTime stop_time,int index, CancellationToken cancellationToken = default);
 
 
         /// <summary>

+ 20 - 0
TeamAAS-VM/Interfaces/IRemoteCommandService.cs

@@ -249,6 +249,14 @@ namespace TeamAAS_VP.Interfaces
         /// <returns></returns>
         bool ExecutePhoto(int index, ProcedureModel procedure, out CogToolBlockTerminalCollection outputCollection);
 
+        /// <summary>
+        /// 执行翻转相机拍照流程运行
+        /// </summary>
+        /// <param name="procedure"></param>
+        /// <param name="outputCollection"></param>
+        /// <returns></returns>
+        bool ExecutePhotoGetDistance(ProcedureModel procedure, Dictionary<string, string> InputTerminal);
+
         /// <summary>
         /// 执行相机拍照获取单个点位结果
         /// </summary>
@@ -261,6 +269,18 @@ namespace TeamAAS_VP.Interfaces
         /// <returns></returns>
         Task<(bool IsSucceed,string distance, double X, double Y, double U)> ExecutePhotoGetSinglePoint(ProcedureModel procedure, Dictionary<string, string> InputTerminal, double[] robotCoord, CancellationToken cancellationToken, int positionIndex,int num, string remark, ImageParameters imgPara);
 
+        /// <summary>
+        /// 执行相机拍照获取单个点位结果
+        /// </summary>
+        /// <param name="procedure"></param>
+        /// <param name="InputTerminal"></param>
+        /// <param name="robotCoord"></param>
+        /// <param name="cancellationToken"></param>
+        /// <param name="positionIndex"></param>
+        /// <param name="remark"></param>
+        /// <returns></returns>
+        Task<(bool IsSucceed, string item)> ExecutePhotoGetSinglePoint(ProcedureModel procedure, Dictionary<string, string> InputTerminal, double[] robotCoord, CancellationToken cancellationToken, int positionIndex, int num, string remark);
+
         /// <summary>
         /// 执行相机拍照获取单个点位结果,KB复检
         /// </summary>

+ 92 - 2
TeamAAS-VM/Models/PLC/PlcAddressConfig.cs

@@ -198,7 +198,17 @@ namespace TeamAAS_VP.Models.PLC
             get { return _FixedCameracheckStatus; }
             set { SetProperty(ref _FixedCameracheckStatus, value); }
         }
-    
+
+        private PlcAddress _FzCameraPickStatus = new PlcAddress();
+        /// <summary>
+        /// 固定相机取料拍照结果 =1 拍照OK =2 拍照NG =3 取图拍照OK
+        /// </summary>
+        public PlcAddress Out_FzCameraPickStatus
+        {
+            get { return _FzCameraPickStatus; }
+            set { SetProperty(ref _FzCameraPickStatus, value); }
+        }
+
         private PlcAddress _Out_CameraDone = new PlcAddress();
         /// <summary>
         /// 相机坐标拟合完成
@@ -308,6 +318,16 @@ namespace TeamAAS_VP.Models.PLC
             set { SetProperty(ref _QrCodeCamera, value); }
         }
 
+        private PlcPointAddress _HotMelt = new PlcPointAddress();
+        /// <summary>
+        /// 二维码拍照点位参数
+        /// </summary>
+        public PlcPointAddress Out_HotMelt
+        {
+            get { return _HotMelt; }
+            set { SetProperty(ref _HotMelt, value); }
+        }
+
         private PlcAddress _Out_ScrewTeachOk;
         /// <summary>
         /// 下相机矫正披头的结果,1:OK,2:NG
@@ -772,6 +792,27 @@ namespace TeamAAS_VP.Models.PLC
             set { SetProperty(ref _Fault, value); }
         }
 
+        private PlcAddress _In_FzCameraPixExe = new PlcAddress();
+        /// <summary>
+        /// 翻转相机触发拍照
+        /// </summary>
+        public PlcAddress In_FzCameraPixExe
+        {
+            get { return _In_FzCameraPixExe; }
+            set { SetProperty(ref _In_FzCameraPixExe, value); }
+        }
+
+        private PlcHotMeltAddress _HotMeltTempPre;
+        /// <summary>
+        /// 热熔压力和温度地址
+        /// </summary>
+        public PlcHotMeltAddress HotMeltTempPre
+        {
+            get { return _HotMeltTempPre; }
+            set { SetProperty(ref _HotMeltTempPre, value); }
+        }
+
+
         #endregion
 
         public PlcAddressConfig()
@@ -913,6 +954,11 @@ namespace TeamAAS_VP.Models.PLC
             Check_ScrewTorque.DataType = "Bool";
             Check_ScrewTorque.Description = "电批正转";
 
+            Out_FzCameraPickStatus = Ensure(Out_FzCameraPickStatus);
+            Out_FzCameraPickStatus.Address = "ns=4;s=DB_Communication|FromPC.FzCameraPickStatus";
+            Out_FzCameraPickStatus.DataType = "int16";
+            Out_FzCameraPickStatus.Description = "翻转相机取料拍照结果 =1 拍照OK =2 拍照NG =3 取图拍照OK";
+
             //首先到废料桶上方投料
             //有三个示教的地方
             //
@@ -1105,6 +1151,45 @@ namespace TeamAAS_VP.Models.PLC
             Out_QrCodeCamera.Feeder.Address = "ns=4;s=DB_Communication|FromPC.Photo_Positipn[{0}].Feeder";
             Out_QrCodeCamera.ScrewProNum.Address = "ns=4;s=DB_Communication|FromPC.Photo_Positipn[{0}].ScrewProNum";
 
+            // Out_HotMelt(热熔点位)初始化并赋地址
+            Out_HotMelt = EnsurePoint(Out_HotMelt);
+            Out_HotMelt.Description = "热熔点位参数";
+            Out_HotMelt.X_Position.Address = "ns=4;s=DB_Communication|FromPC.Point_HotMelt[{0}].X_Position";
+            Out_HotMelt.X_Velocity.Address = "ns=4;s=DB_Communication|FromPC.Point_HotMelt[{0}].X_Velocity";
+            Out_HotMelt.Y_Position.Address = "ns=4;s=DB_Communication|FromPC.Point_HotMelt[{0}].Y_Position";
+            Out_HotMelt.Y_Velocity.Address = "ns=4;s=DB_Communication|FromPC.Point_HotMelt[{0}].Y_Velocity";
+            Out_HotMelt.Z_Position_Start.Address = "ns=4;s=DB_Communication|FromPC.Point_HotMelt[{0}].Z_Position_Start";
+            Out_HotMelt.Z_Velocity_Start.Address = "ns=4;s=DB_Communication|FromPC.Point_HotMelt[{0}].Z_Velocity_Start";
+            Out_HotMelt.Z_Position_Stop.Address = "ns=4;s=DB_Communication|FromPC.Point_HotMelt[{0}].Z_Position_Stop";
+            Out_HotMelt.Z_Velocity_Stop.Address = "ns=4;s=DB_Communication|FromPC.Point_HotMelt[{0}].Z_Velocity_Stop";
+            Out_HotMelt.U_Position.Address = "ns=4;s=DB_Communication|FromPC.Point_HotMelt[{0}].U_Position";
+            Out_HotMelt.U_Velocity.Address = "ns=4;s=DB_Communication|FromPC.Point_HotMelt[{0}].U_Velocity";
+            Out_HotMelt.R_Position.Address = "ns=4;s=DB_Communication|FromPC.Point_HotMelt[{0}].R_Position";
+            Out_HotMelt.R_Velocity.Address = "ns=4;s=DB_Communication|FromPC.Point_HotMelt[{0}].R_Velocity";
+            Out_HotMelt.Torque.Address = "ns=4;s=DB_Communication|FromPC.Point_HotMelt[{0}].Torque";
+            Out_HotMelt.Feeder.Address = "ns=4;s=DB_Communication|FromPC.Point_HotMelt[{0}].Feeder";
+            Out_HotMelt.ScrewProNum.Address = "ns=4;s=DB_Communication|FromPC.Point_HotMelt[{0}].ScrewProNum";
+
+            HotMeltTempPre = new PlcHotMeltAddress();
+            HotMeltTempPre.Description = "热熔温度压力地址";
+            HotMeltTempPre.Shield.Address = "ns=4;s=Auto|Temperature.Shield";
+            HotMeltTempPre.Wright_Exe.Address = "ns=4;s=Auto|Temperature.Wright_Exe";
+            HotMeltTempPre.CurentTemperature.Address = "ns=4;s=Auto|Temperature.Read[0]";
+            HotMeltTempPre.DesTemperature.Address = "ns=4;s=Auto|Temperature.Read[1]";
+            HotMeltTempPre.StartTemperature.Address = "ns=4;s=Auto|Temperature.Read[3]";
+            HotMeltTempPre.StopTemperature.Address = "ns=4;s=Auto|Temperature.Read[4]";
+            HotMeltTempPre.WriteTemperature.Address = "ns=4;s=Auto|Temperature.Wright[0]";
+
+            HotMeltTempPre.CurentPressureN.Address = "ns=4;s=Auto|Pressure.User";
+            HotMeltTempPre.CurentPressureKg.Address = "ns=4;s=Auto|Pressure.User_KG";
+            HotMeltTempPre.SetPressure.Address = "ns=4;s=Auto|Pressure.DataMax";
+            HotMeltTempPre.MaxPressure.Address = "ns=4;s=Auto|Pressure.UserMin";
+            HotMeltTempPre.MinPressure.Address = "ns=4;s=Auto|Pressure.UserMax";
+            HotMeltTempPre.StopPressureN.Address = "ns=4;s=Auto|Pressure.UserData";
+            HotMeltTempPre.StopPressureKg.Address = "ns=4;s=Auto|Pressure.UserData_KG";
+            HotMeltTempPre.StableTime.Address = "ns=4;s=Auto|Pressure.Time";
+
+
             Out_ScrewTeachNum = Ensure(Out_ScrewTeachNum);
             Out_ScrewTeachNum.Address = "ns=4;s=DB_Communication|FromPC.ScrewTeachNum";
             Out_ScrewTeachNum.DataType = "int16";
@@ -1123,7 +1208,7 @@ 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|FromPC.Code";
             In_Code.DataType = "string";
             In_Code.Description = Lang.产品编码;
 
@@ -1294,6 +1379,11 @@ namespace TeamAAS_VP.Models.PLC
             Fault.DataType = "Bool";
             Fault.Description = "报警";
 
+            In_FzCameraPixExe = Ensure(In_FzCameraPixExe);
+            In_FzCameraPixExe.Address = "ns=4;s=DB_Communication|ToPC.In_FzCameraPickExe";
+            In_FzCameraPixExe.DataType = "Bool";
+            In_FzCameraPixExe.Description = "翻转相机检测拍照触发";
+
             //ns=4;s=DB_Input|X16_螺丝供料器1螺丝到位
             //ns=4;s=DB_Input|X17_螺丝供料器2螺丝到位
 

+ 52 - 0
TeamAAS-VM/Models/PLC/PlcTemperatureAddress.cs

@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TeamAAS_VP.Resources.Languages;
+
+namespace TeamAAS_VP.Models.PLC
+{
+    public class PlcHotMeltAddress
+    {
+        //描述
+        public string Description { get; set; }
+        public PlcAddress Shield { get; set; }
+        public PlcAddress Wright_Exe { get; set; }
+        public PlcAddress CurentTemperature { get; set; }
+        public PlcAddress DesTemperature { get; set; }
+        public PlcAddress StartTemperature { get; set; }
+        public PlcAddress StopTemperature { get; set; }
+        public PlcAddress WriteTemperature { get; set; }
+
+        public PlcAddress CurentPressureN { get; set; }
+        public PlcAddress CurentPressureKg { get; set; }
+        public PlcAddress SetPressure { get; set; }
+        public PlcAddress MaxPressure { get; set; }
+        public PlcAddress MinPressure { get; set; }
+        public PlcAddress StopPressureN { get; set; }
+        public PlcAddress StopPressureKg { get; set; }
+        public PlcAddress StableTime { get; set; }
+
+        public PlcHotMeltAddress()
+        {
+            Description ="热熔温度压力地址";
+            Shield = new PlcAddress() { Description ="屏蔽温控器", DataType = "Bool" };
+            Wright_Exe = new PlcAddress() { Description = "温度设定写入", DataType = "Bool" };
+            CurentTemperature = new PlcAddress() { Description = "当前温度", DataType = "int16" };
+            DesTemperature = new PlcAddress() { Description = "当前设定温度", DataType = "int16" };
+            StartTemperature = new PlcAddress() { Description = "开始温度", DataType = "int16" };
+            StopTemperature = new PlcAddress() { Description = "结束温度", DataType = "int16" };
+            WriteTemperature = new PlcAddress() { Description = "设置温度", DataType = "int16" };
+
+            CurentPressureN = new PlcAddress() { Description = "当前压力N", DataType = "float" };
+            CurentPressureKg = new PlcAddress() { Description = "当前压力Kg", DataType = "float" };
+            SetPressure = new PlcAddress() { Description = "设定压力", DataType = "float" };
+            MaxPressure = new PlcAddress() { Description = "最大压力", DataType = "float" };
+            MinPressure = new PlcAddress() { Description = "最小压力", DataType = "float" };
+            StopPressureN = new PlcAddress() { Description = "结束压力N", DataType = "float" };
+            StopPressureKg = new PlcAddress() { Description = "结束压力Kg", DataType = "float" };
+            StableTime = new PlcAddress() { Description = "保压时间", DataType = "int32" };
+        }
+    }
+}

+ 25 - 7
TeamAAS-VM/Models/Product/ProductGlobalParam.cs

@@ -9,13 +9,13 @@ namespace TeamAAS_VP.Models.Product
 {
     public class ProductGlobalParam : BindableBase
     {
-		private int _Number;
+        private int _Number;
 
-		public int Number
-		{
-			get { return _Number; }
-			set { SetProperty(ref _Number,value); }
-		}
+        public int Number
+        {
+            get { return _Number; }
+            set { SetProperty(ref _Number, value); }
+        }
 
         private string _Name;
 
@@ -57,6 +57,22 @@ namespace TeamAAS_VP.Models.Product
             set { SetProperty(ref _Param4, value); }
         }
 
+        private string _Param5;
+
+        public string Param5
+        {
+            get { return _Param5; }
+            set { SetProperty(ref _Param5, value); }
+        }
+
+        private string _Param6;
+
+        public string Param6
+        {
+            get { return _Param6; }
+            set { SetProperty(ref _Param6, value); }
+        }
+
         private string _Remark;
         /// <summary>
         /// 备注
@@ -77,6 +93,8 @@ namespace TeamAAS_VP.Models.Product
                 Param2 = this.Param2,
                 Param3 = this.Param3,
                 Param4 = this.Param4,
+                Param5 = this.Param5,
+                Param6 = this.Param6,
                 Remark = this.Remark
             };
         }
@@ -84,7 +102,7 @@ namespace TeamAAS_VP.Models.Product
         public override string ToString()
         {
             //将现在的编号、名称、参数等按照逗号分隔的形式返回
-            return $"{Number},{Name},{Param1},{Param2},{Param3},{Param4}";
+            return $"{Number},{Name},{Param1},{Param2},{Param3},{Param4},{Param5},{Param6}";
         }
     }
 }

+ 49 - 0
TeamAAS-VM/Models/Product/ProductModel.cs

@@ -195,6 +195,16 @@ namespace TeamAAS_VP.Models
             set { SetProperty(ref _MoveDownCameraLockPhotoProcedureId, value); }
         }
 
+        private Guid _FzCameraProcedureId;
+        /// <summary>
+        /// 翻转相机流程ID
+        /// </summary>
+        public Guid FzCameraProcedureId
+        {
+            get { return _FzCameraProcedureId; }
+            set { SetProperty(ref _FzCameraProcedureId, value); }
+        }
+
         // 二维码扫码流程ID
         private Guid _QrCodeProcedureId;
         public Guid QrCodeProcedureId
@@ -203,6 +213,23 @@ namespace TeamAAS_VP.Models
             set { SetProperty(ref _QrCodeProcedureId, value); }
         }
 
+        private Guid _FixedCamera1Procedure;
+        public Guid FixedCamera1Procedure
+        {
+            get { return _FixedCamera1Procedure; }
+            set { SetProperty(ref _FixedCamera1Procedure, value); }
+        }
+
+
+        private Guid _FixedCamera2Procedure;
+        public Guid FixedCamera2Procedure
+        {
+            get { return _FixedCamera2Procedure; }
+            set { SetProperty(ref _FixedCamera2Procedure, value); }
+        }
+
+        
+
         private ObservableCollection<ProductGlobalParam> _GlobalParamListCollection;
         /// <summary>
         /// 产品全局参数集合
@@ -304,6 +331,28 @@ namespace TeamAAS_VP.Models
         }
 
 
+        private ObservableCollection<PlcPoint> _HotMeltPoints = new ObservableCollection<PlcPoint>();
+        /// <summary>
+        /// 二维码拍照点位参数集合
+        /// </summary>
+        public ObservableCollection<PlcPoint> HotMeltPoints
+        {
+            get { return _HotMeltPoints; }
+            set { SetProperty(ref _HotMeltPoints, value); }
+        }
+
+
+        private ObservableCollection<PlcPoint> _HotMeltPoints1 = new ObservableCollection<PlcPoint>();
+        /// <summary>
+        /// 二维码拍照点位参数集合
+        /// </summary>
+        public ObservableCollection<PlcPoint> HotMeltPoints1
+        {
+            get { return _HotMeltPoints1; }
+            set { SetProperty(ref _HotMeltPoints1, value); }
+        }
+
+
         private bool _IsLoad;
         /// <summary>
         /// 是否已加载

+ 68 - 1
TeamAAS-VM/Models/SystemConfiguration.cs

@@ -1,5 +1,6 @@
 using Prism.Mvvm;
 using System;
+using System.Collections.ObjectModel;
 using System.Reflection;
 using System.Windows;
 using TeamAAS_VP.Enums;
@@ -99,7 +100,7 @@ namespace TeamAAS_VP.Models
 
         private Int16 _WorkMode = 0;
         /// <summary>
-        /// 工作模式 =1 拍1打1 =2 拍1打所有
+        /// 工作模式 =1 拍1打1 =2 拍1打所有 =3先拍1打1打3颗再拍2打所有
         /// </summary>
         public Int16 WorkMode
         {
@@ -117,6 +118,16 @@ namespace TeamAAS_VP.Models
             set { SetProperty(ref _PickPointNum, value); }
         }
 
+        private double _JumpLimitZ = 0;
+        /// <summary>
+        /// 取料位置 =0 不需要取料 =1 需要取料
+        /// </summary>
+        public double JumpLimitZ
+        {
+            get { return _JumpLimitZ; }
+            set { SetProperty(ref _JumpLimitZ, value); }
+        }
+
         private Int16 _DowmCameraNum = 0;
         /// <summary>
         /// 相机拍照次数
@@ -197,6 +208,16 @@ namespace TeamAAS_VP.Models
             set => SetProperty(ref _ScrewTeachNum, value);
         }
 
+        private ObservableCollection<PressureSensorSettings> _PressureSensorConfig;
+        /// <summary>
+        /// 压力传感器配置列表
+        /// </summary>
+        public ObservableCollection<PressureSensorSettings> PressureSensorConfig
+        {
+            get { return _PressureSensorConfig; }
+            set { SetProperty(ref _PressureSensorConfig, value); }
+        }
+
         private bool _IsSaveScrewCurve = false;
         /// <summary>
         /// 是否保存锁付曲线图
@@ -318,5 +339,51 @@ namespace TeamAAS_VP.Models
             private double _captions4 = 8;
             public double Captions4 { get => _captions4; set => SetProperty(ref _captions4, value); }
         }
+        /// <summary>
+        /// 压力传感器配置
+        /// </summary>
+        public class PressureSensorSettings : BindableBase
+        {
+            private string _sensorName;
+            /// <summary>
+            /// 压力传感器的名称
+            /// </summary>
+            public string SensorName
+            {
+                get => _sensorName;
+                set => SetProperty(ref _sensorName, value);
+            }
+
+            private int _sensorId;
+            /// <summary>
+            /// 压力传感器的编号
+            /// </summary>
+            public int SensorId
+            {
+                get => _sensorId;
+                set => SetProperty(ref _sensorId, value);
+            }
+
+            private bool _IsSavePressureCurve;
+            /// <summary>
+            /// 是否保存压力曲线图
+            /// </summary>
+            public bool IsSavePressureCurve
+            {
+                get => _IsSavePressureCurve;
+                set => SetProperty(ref _IsSavePressureCurve, value);
+            }
+
+            private string _pressureCurvePath;
+            /// <summary>
+            /// 压力曲线图保存路径
+            /// </summary>
+            public string PressureCurvePath
+            {
+                get => _pressureCurvePath;
+                set => SetProperty(ref _pressureCurvePath, value);
+            }
+
+        }
     }
 }

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

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

+ 9 - 9
TeamAAS-VM/Services/MesService.cs

@@ -150,11 +150,11 @@ namespace TeamAAS_VP.Services
             return result;
         }
 
-        public async Task<(bool IsSuccess, string Response)> StationGetExAsync(string sn, string comp, double timeoutInSeconds)
+        public async Task<(bool IsSuccess, string Response)> StationGetExAsync(string sn, string comp, double timeoutInSeconds, int index)
         {
             using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(timeoutInSeconds)))
             {
-                return await StationGetExAsync(sn, comp, cts.Token);
+                return await StationGetExAsync(sn, comp,  index, cts.Token);
             }
         }
 
@@ -165,11 +165,11 @@ namespace TeamAAS_VP.Services
         /// <param name="sn">序列号(SN)。</param>
         /// <param name="timeoutInSeconds">请求超时,单位为秒。</param>
         /// <returns>与 <see cref="StationGetAsync(string, CancellationToken)"/> 相同的返回语义。</returns>
-        public async Task<(bool IsSuccess, string Response)> StationGetAsync(string sn, string comp, double timeoutInSeconds)
+        public async Task<(bool IsSuccess, string Response)> StationGetAsync(string sn, string comp, double timeoutInSeconds, int index)
         {
             using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(timeoutInSeconds)))
             {
-                return await StationGetAsync(sn, comp, cts.Token);
+                return await StationGetAsync(sn, comp, index, cts.Token);
             }
         }
 
@@ -192,12 +192,12 @@ namespace TeamAAS_VP.Services
         /// - 捕获 <see cref="OperationCanceledException"/> 返回 "Canceled",捕获其它异常则返回异常消息。
         /// - 若实例已被释放则抛出 <see cref="ObjectDisposedException"/>。
         /// </remarks>
-        public async Task<(bool IsSuccess, string Response)> StationGetExAsync(string sn, string comp, CancellationToken cancellationToken = default)
+        public async Task<(bool IsSuccess, string Response)> StationGetExAsync(string sn, string comp, int index, CancellationToken cancellationToken = default)
         {
             // 如果已经释放,则抛出异常,防止在已释放资源上继续操作。
             if (_disposed) throw new ObjectDisposedException(nameof(MesService));
 
-            var device = _configService.GetDeviceInfo();
+            var device = _configService.GetDeviceInfo(index);
             if (device == null || !device.EnableMES)
             {
                 return (true, "MES功能未启用!");
@@ -266,12 +266,12 @@ namespace TeamAAS_VP.Services
         /// - 捕获 <see cref="OperationCanceledException"/> 返回 "Canceled",捕获其它异常则返回异常消息。
         /// - 若实例已被释放则抛出 <see cref="ObjectDisposedException"/>。
         /// </remarks>
-        public async Task<(bool IsSuccess, string Response)> StationGetAsync(string sn, string comp, CancellationToken cancellationToken = default)
+        public async Task<(bool IsSuccess, string Response)> StationGetAsync(string sn, string comp,int index, CancellationToken cancellationToken = default)
         {
             // 如果已经释放,则抛出异常,防止在已释放资源上继续操作。
             if (_disposed) throw new ObjectDisposedException(nameof(MesService));
 
-            var device = _configService.GetDeviceInfo();
+            var device = _configService.GetDeviceInfo(index);
             if (device == null || !device.EnableMES)
             {
                 return (true, "MES功能未启用!");
@@ -641,7 +641,7 @@ namespace TeamAAS_VP.Services
             return result;
         }
 
-        public async Task<(bool IsSuccess, string Response)> SubmitGetExAsync(string sn, string comp, Dictionary<string, string> data, List<string> results, DateTime start_time, DateTime stop_time, CancellationToken cancellationToken = default)
+        public async Task<(bool IsSuccess, string Response)> SubmitGetExAsync(string sn, string comp, Dictionary<string, string> data, List<string> results, DateTime start_time, DateTime stop_time, int index, CancellationToken cancellationToken = default)
         {
             // 如果已经释放,则抛出异常,防止在已释放资源上继续操作。
             if (_disposed) throw new ObjectDisposedException(nameof(MesService));

+ 329 - 53
TeamAAS-VM/Services/RemoteCommandService.cs

@@ -1456,7 +1456,7 @@ namespace TeamAAS_VP.Services
         /// 执行相机拍照并运行 ToolBlock,返回是否成功并通过 out 参数返回 Outputs。
         /// 该方法会发布 RenderUpdateNotification 以更新 UI。
         /// </summary>
-        public bool ExecutePhoto(int index, ProcedureModel procedure, Dictionary<string, string> InputTerminal, out CogToolBlockTerminalCollection outputCollection, ImageParameters imgPara,int ScrewNum=1)
+        public bool ExecutePhoto(int index, ProcedureModel procedure, Dictionary<string, string> InputTerminal, out CogToolBlockTerminalCollection outputCollection, ImageParameters imgPara, int ScrewNum = 1)
         {
             try
             {
@@ -1610,6 +1610,223 @@ namespace TeamAAS_VP.Services
                 return false;
             }
         }
+
+        /// <summary>
+        /// 执行翻转相机拍照流程运行
+        /// </summary>
+        /// <param name="procedure"></param>
+        /// <param name="outputCollection"></param>
+        /// <returns></returns>
+        public bool ExecutePhotoGetDistance(ProcedureModel procedure, Dictionary<string, string> InputTerminal)
+        {
+            try
+            {
+                //string dis = "";
+                //拍照失败时,需要多次拍照
+                for (int i = 0; i < procedure.FeederFailLimit; i++)
+                {
+                    SendTaskMessage(Lang.开始执行视觉流程.Replace("{0}", $"{i + 1}").Replace("{1}", procedure.Name), MessageLevel.Info);
+
+                    // 1. 执行相机拍照并运行视觉工具
+                    bool visionSucceed = ExecutePhotos(procedure, InputTerminal, out CogToolBlockTerminalCollection outputCollection);
+                    if (!visionSucceed)
+                    {
+                        SendTaskMessage(Lang.视觉任务执行失败, MessageLevel.Error);
+                        return false;
+                    }
+
+                    if (!outputCollection.Contains("Found"))
+                    {
+                        SendTaskMessage(Lang.未找到视觉输出结果, MessageLevel.Error);
+                        return false;
+                    }
+
+                    // 2. 获取视觉输出结果NA
+                    bool Found = (bool)(outputCollection["Found"].Value);
+                    if (!Found)
+                    {
+                        SendTaskMessage(Lang.拍照NG, MessageLevel.Debug);
+                        //dis = (string)(outputCollection["dis"].Value);
+                        return false;
+                    }
+
+                    SendTaskMessage(Lang.拍照OK, MessageLevel.Debug);
+
+                    LogHelper.WriteLogInfo("开始获取视觉输出结果");
+                    //dis = (string)(outputCollection["dis"].Value);
+                    return true;
+                }
+                SendTaskMessage(Lang.多次拍照失败, MessageLevel.Alarm);
+                return false;
+            }
+            catch (Exception ex)
+            {
+                LogHelper.WriteLogError("执行相机取图并获取单点位时出错!", ex);
+                return false;
+            }
+        }
+
+
+        /// <summary>
+        /// 翻转相机拍照方法
+        /// 该方法会发布 RenderUpdateNotification 以更新 UI。
+        /// </summary>
+        public bool ExecutePhotos(ProcedureModel procedure, Dictionary<string, string> InputTerminal, out CogToolBlockTerminalCollection outputCollection)
+        {
+            try
+            {
+                // 1. 采集图像
+                var camera = _cameraService.GetCamera(procedure.CameraId);
+                bool succed = camera.SetExposureTime(procedure.ExposureTime);
+                if (!succed)
+                {
+                    SendTaskMessage($"相机曝光设置失败!", MessageLevel.Error);
+                }
+                succed = camera.SetGain(procedure.Gain);
+                if (!succed)
+                {
+                    SendTaskMessage($"相机增益设置失败!", MessageLevel.Error);
+                }
+                DateTime nowtime = DateTime.Now;
+                LogHelper.WriteLogInfo("开始采集图像");
+                //var image = camera.Grab();
+                var image = camera.Grab();
+
+                if (image == null)
+                {
+
+                    SendTaskMessage(Lang.图像采集失败, MessageLevel.Error);
+                    outputCollection = null;
+                    return false;
+                }
+                procedure.ToolBlock.Inputs["InputImage"].Value = image;
+                LogHelper.WriteLogInfo($"采集图像完成;用时:{(DateTime.Now - nowtime).Milliseconds}ms");
+
+                // 2. 为ToolBlock传入其他输入终端
+                if (InputTerminal != null)
+                {
+                    LogHelper.WriteLogInfo($"为ToolBlock传入输入终端");
+                    foreach (var item in InputTerminal)
+                    {
+                        if (procedure.ToolBlock.Inputs.Contains(item.Key))
+                        {
+                            LogHelper.WriteLogInfo($"传入[{item.Key}]={item.Value}");
+                            procedure.ToolBlock.Inputs[item.Key].Value = item.Value;
+                        }
+                        else
+                        {
+                            LogHelper.WriteLogInfo($"创建并传入[{item.Key}]={item.Value}");
+                            procedure.ToolBlock.Inputs.Add(new CogToolBlockTerminal(item.Key, item.Value));
+                        }
+                    }
+                }
+
+                LogHelper.WriteLogInfo(Lang.开始运行视觉工具);
+                procedure.ToolBlock.Run();      //运行ToolBlock
+
+                if (procedure.ToolBlock.RunStatus.Result == CogToolResultConstants.Accept)
+                {
+                    SendTaskMessage(Lang.视觉流程执行耗时.Replace("{0}", procedure.Name).Replace("{1}", $"{procedure.ToolBlock.RunStatus.ProcessingTime:F1}"), MessageLevel.Info);
+                    outputCollection = procedure.ToolBlock.Outputs;     //获取输出终端集合
+                    DatabaseHelper.AddCameraRecords(_productService.GetCurrentProduct().Name, procedure.Name, outputCollection);
+                    ICogRecord record = null;
+                    foreach (CogToolBlockTerminal item in outputCollection)
+                    {
+                        if (item.Value is ICogRecord)
+                            record = item.Value as ICogRecord;
+                    }
+                    bool Found = (bool)(outputCollection["Found"].Value);
+                    //获取图片存储的图片文件名
+                    string imgName = string.Empty;
+                    if (procedure.IsSaveImage && !string.IsNullOrEmpty(procedure.ImageFileNameFormat))
+                    {
+                        // 创建模板,使用 {变量名:格式} 语法
+                        var template = new FileNameTemplate(procedure.ImageFileNameFormat);
+
+                        // 注册变量
+                        template.RegisterVariable("ProductSN", () => _productService.CurrentProductCode);
+                        template.RegisterVariable("CameraName", () => procedure.CameraName);
+                        //template.RegisterVariable("ShotCount", () => 1);
+                        template.RegisterVariable("Result", () => Found ? "OK" : "NG");
+                        //template.RegisterVariable("Number", () => 1);
+                        template.RegisterVariable("DateTime", () => DateTime.Now);
+
+                        // 生成文件名
+                        imgName = template.Generate();
+                    }
+
+                    _eventAggregator.GetEvent<RenderUpdateNotification>().Publish(new ShowRender()
+                    {
+                        Id = procedure.Id,
+                        Image = (ICogImage)procedure.ToolBlock.Inputs["InputImage"].Value,
+                        Graphic = outputCollection["Graphic"].Value as CogGraphicCollection,
+                        Record = record,
+                        Result = Found,
+                        IsShow = true,
+                        IsSaveImage = procedure.IsSaveImage,
+                        SaveImageModel = procedure.SaveImageModel,
+                        SaveImagePathModel = procedure.SaveImagePathModel,
+                        SavePath = procedure.SavePath,
+                        IsCompress = procedure.IsCompress,
+                        IsDelaySaveImage = procedure.IsDelaySaveImage,
+                        //ImgPara = imgPara,
+                        ImageFileName = imgName,
+                        ProceductName = procedure.Name,
+                    });
+                    SendTaskMessage($"{procedure.CameraName},{procedure.CameraId}", MessageLevel.Info);
+                    return true;
+                }
+                else
+                {
+                    SendTaskMessage(Lang.视觉流程执行出错耗时.Replace("{0}", procedure.Name).Replace("{1}", $"{procedure.ToolBlock.RunStatus.ProcessingTime:F1}"), MessageLevel.Error);
+                    SendTaskMessage(procedure.ToolBlock.RunStatus.Message, MessageLevel.Error);
+                    outputCollection = null;
+
+                    //获取图片存储的图片文件名
+                    string imgName = string.Empty;
+                    if (procedure.IsSaveImage && !string.IsNullOrEmpty(procedure.ImageFileNameFormat))
+                    {
+                        // 创建模板,使用 {变量名:格式} 语法
+                        var template = new FileNameTemplate(procedure.ImageFileNameFormat);
+
+                        // 注册变量
+                        template.RegisterVariable("ProductSN", () => _productService.CurrentProductCode);
+                        template.RegisterVariable("CameraName", () => procedure.CameraName);
+                        //template.RegisterVariable("ShotCount", () => index);
+                        template.RegisterVariable("Result", () => "NG");
+                        template.RegisterVariable("DateTime", () => DateTime.Now);
+
+                        // 生成文件名
+                        imgName = template.Generate();
+                    }
+                    _eventAggregator.GetEvent<RenderUpdateNotification>().Publish(new ShowRender()
+                    {
+                        Id = procedure.Id,
+                        Image = (ICogImage)procedure.ToolBlock.Inputs["InputImage"].Value,
+                        Graphic = new CogGraphicCollection(),
+                        Result = false,
+                        IsShow = true,
+                        IsSaveImage = procedure.IsSaveImage,
+                        SaveImageModel = procedure.SaveImageModel,
+                        SaveImagePathModel = procedure.SaveImagePathModel,
+                        SavePath = procedure.SavePath,
+                        IsCompress = procedure.IsCompress,
+                        IsDelaySaveImage = procedure.IsDelaySaveImage,
+                        ProceductName = procedure.Name,
+                        ImageFileName = imgName
+                    });
+                    return false;
+                }
+            }
+            catch (Exception ex)
+            {
+                SendTaskMessage(ex.Message, MessageLevel.Error);
+                LogHelper.WriteLogError("执行相机取图并执行视觉工具组时出错!", ex);
+                outputCollection = null;
+                return false;
+            }
+        }
+
         /// <summary>
         /// 执行拍照二维码流程运行
         /// </summary>
@@ -1858,14 +2075,14 @@ namespace TeamAAS_VP.Services
         /// <param name="positionIndex"></param>
         /// <param name="remark"></param>
         /// <returns></returns>
-        public async Task<(bool IsSucceed, string distance, double X, double Y, double U)> ExecutePhotoGetSinglePoint(ProcedureModel procedure, Dictionary<string, string> InputTerminal, double[] robotCoord, CancellationToken cancellationToken, int positionIndex,int num, string remark, ImageParameters imgPara)
+        public async Task<(bool IsSucceed, string distance, double X, double Y, double U)> ExecutePhotoGetSinglePoint(ProcedureModel procedure, Dictionary<string, string> InputTerminal, double[] robotCoord, CancellationToken cancellationToken, int positionIndex, int num, string remark, ImageParameters imgPara)
         {
             var systemConfig = _configService.GetSystemConfiguration();
             DateTime nowtime = DateTime.Now;
             string cc = "999";
             if (systemConfig.IsBasePartOpenLight)
             {
-                if (positionIndex == 0|| positionIndex==1)
+                if (positionIndex == 0 || positionIndex == 1)
                 {
                     await SetLightBeforePhoto(procedure);
                 }
@@ -1875,6 +2092,105 @@ namespace TeamAAS_VP.Services
                 await SetLightBeforePhoto(procedure);
             }
 
+            try
+            {
+                //拍照失败时,需要多次拍照
+                for (int i = 0; i < procedure.FeederFailLimit; i++)
+                {
+                    SendTaskMessage(Lang.开始执行视觉流程.Replace("{0}", $"{i + 1}").Replace("{1}", procedure.Name), MessageLevel.Info);
+
+                    // 1. 执行相机拍照并运行视觉工具
+                    bool visionSucceed = ExecutePhoto(i + 1, procedure, InputTerminal, out CogToolBlockTerminalCollection outputCollection, imgPara);
+                    if (!visionSucceed)
+                    {
+                        SendTaskMessage(Lang.视觉任务执行失败, MessageLevel.Error);
+                        continue;
+                    }
+
+                    if (!outputCollection.Contains("Found"))
+                    {
+                        SendTaskMessage(Lang.未找到视觉输出结果, MessageLevel.Error);
+                        await RecordPhotoCaptureAsync(procedure, robotCoord, false, new double[] { 0, 0, 0 }, new double[] { 0, 0, 0 }, string.Empty, positionIndex, remark);
+                        return (false, cc, 0, 0, 0);
+                    }
+                    // 2. 获取视觉输出结果
+                    bool Found = (bool)(outputCollection["Found"].Value);
+                    if (!Found)
+                    {
+                        SendTaskMessage(Lang.拍照NG, MessageLevel.Debug);
+                        continue;
+                    }
+                    if (outputCollection.Contains("CC"))
+                    {
+                        cc = outputCollection["CC"].Value.ToString();
+                    }
+
+
+                    SendTaskMessage(Lang.拍照OK, MessageLevel.Debug);
+
+                    if (procedure.CalibrationId == Guid.Empty)
+                    {
+                        //没有关联校准时,则执行检测任务
+                        await RecordPhotoCaptureAsync(procedure, robotCoord, true, new double[] { 0, 0, 0 }, new double[] { 0, 0, 0 }, string.Empty, positionIndex, remark);
+                        return (true, cc, 0, 0, 0);
+                    }
+
+                    // 3. 获取视觉输出结果
+                    LogHelper.WriteLogInfo(Lang.开始获取视觉输出结果);
+                    //获取相机校准
+                    var calib = _calibrationService.GetCalibration(procedure.CalibrationId);
+                    string points = (string)(outputCollection["Point"].Value);
+                    string[] strpoints = points.Split(';');
+                    //先将pos按照逗号进行分隔,拿到数组
+                    var posParts = strpoints[0].Split(',');
+                    double _pixel_x = double.Parse(posParts[0]);
+                    double _pixel_y = double.Parse(posParts[1]);
+                    double _pixel_u = double.Parse(posParts[2]);
+                    //转换点位-像素转换成机器人绝对坐标
+                    var calibResult = _calibrationService.ConvertPixelToPosition((_pixel_x, _pixel_y, _pixel_u), robotCoord, calib, RobotBrand.XYZ_Platform);
+                    if (!calibResult.IsSucceed)
+                    {
+                        await RecordPhotoCaptureAsync(procedure, robotCoord, false, new double[] { _pixel_x, _pixel_y, _pixel_u }, new double[] { 0, 0, 0 }, string.Empty, positionIndex, remark);
+                        return (false, cc, 0, 0, 0);
+                    }
+                    await RecordPhotoCaptureAsync(procedure, robotCoord, true, new double[] { _pixel_x, _pixel_y, _pixel_u }, new double[] { calibResult.X, calibResult.Y, calibResult.U }, string.Empty, positionIndex, remark);
+                    return (true, cc, calibResult.X, calibResult.Y, calibResult.U);
+                }
+                SendTaskMessage(Lang.多次拍照失败, MessageLevel.Alarm);
+                await RecordPhotoCaptureAsync(procedure, robotCoord, false, new double[] { 0, 0, 0 }, new double[] { 0, 0, 0 }, string.Empty, positionIndex, remark);
+                return (false, cc, 0, 0, 0);
+            }
+            catch (Exception ex)
+            {
+                LogHelper.WriteLogError(Lang.执行相机取图并获取单点位时出错, ex);
+                await RecordPhotoCaptureAsync(procedure, robotCoord, false, new double[] { 0, 0, 0 }, new double[] { 0, 0, 0 }, string.Empty, positionIndex, remark);
+                return (false, cc, 0, 0, 0);
+            }
+            finally
+            {
+                if (systemConfig.IsBasePartOpenLight)
+                {
+                    if (positionIndex == num)
+                    {
+                        await TurnOffLightAfterPhoto(procedure);
+                    }
+                }
+                else
+                {
+                    await TurnOffLightAfterPhoto(procedure);
+                }
+
+            }
+        }
+
+        public async Task<(bool IsSucceed, string item)> ExecutePhotoGetSinglePoint(ProcedureModel procedure, Dictionary<string, string> InputTerminal, double[] robotCoord, CancellationToken cancellationToken, int positionIndex, int num, string remark)
+        {
+            var systemConfig = _configService.GetSystemConfiguration();
+            DateTime nowtime = DateTime.Now;
+            string result = "";
+            return await Task.Run(async () =>
+            {
+                await SetLightBeforePhoto(procedure);
                 try
                 {
                     //拍照失败时,需要多次拍照
@@ -1883,7 +2199,7 @@ namespace TeamAAS_VP.Services
                         SendTaskMessage(Lang.开始执行视觉流程.Replace("{0}", $"{i + 1}").Replace("{1}", procedure.Name), MessageLevel.Info);
 
                         // 1. 执行相机拍照并运行视觉工具
-                        bool visionSucceed = ExecutePhoto(i + 1, procedure, InputTerminal, out CogToolBlockTerminalCollection outputCollection, imgPara);
+                        bool visionSucceed = ExecutePhoto(i + 1, procedure, InputTerminal, out CogToolBlockTerminalCollection outputCollection, new ImageParameters());
                         if (!visionSucceed)
                         {
                             SendTaskMessage(Lang.视觉任务执行失败, MessageLevel.Error);
@@ -1893,80 +2209,40 @@ namespace TeamAAS_VP.Services
                         if (!outputCollection.Contains("Found"))
                         {
                             SendTaskMessage(Lang.未找到视觉输出结果, MessageLevel.Error);
-                            await RecordPhotoCaptureAsync(procedure, robotCoord, false, new double[] { 0, 0, 0 }, new double[] { 0, 0, 0 }, string.Empty, positionIndex, remark);
-                            return (false,cc, 0, 0, 0);
-                        }                       
+                            return (false, "");
+                        }
                         // 2. 获取视觉输出结果
                         bool Found = (bool)(outputCollection["Found"].Value);
                         if (!Found)
                         {
                             SendTaskMessage(Lang.拍照NG, MessageLevel.Debug);
+                            result = (string)(outputCollection["Point"].Value);
                             continue;
                         }
-                        if (outputCollection.Contains("CC"))
-                        {
-                             cc = outputCollection["CC"].Value.ToString();
-                        }
-                        
 
                         SendTaskMessage(Lang.拍照OK, MessageLevel.Debug);
 
-                        if (procedure.CalibrationId == Guid.Empty)
-                        {
-                            //没有关联校准时,则执行检测任务
-                            await RecordPhotoCaptureAsync(procedure, robotCoord, true, new double[] { 0, 0, 0 }, new double[] { 0, 0, 0 }, string.Empty, positionIndex, remark);
-                            return (true,cc, 0, 0, 0);
-                        }
 
                         // 3. 获取视觉输出结果
                         LogHelper.WriteLogInfo(Lang.开始获取视觉输出结果);
                         //获取相机校准
-                        var calib = _calibrationService.GetCalibration(procedure.CalibrationId);
-                        string points = (string)(outputCollection["Point"].Value);
-                        string[] strpoints = points.Split(';');
-                        //先将pos按照逗号进行分隔,拿到数组
-                        var posParts = strpoints[0].Split(',');
-                        double _pixel_x = double.Parse(posParts[0]);
-                        double _pixel_y = double.Parse(posParts[1]);
-                        double _pixel_u = double.Parse(posParts[2]);
-                        //转换点位-像素转换成机器人绝对坐标
-                        var calibResult = _calibrationService.ConvertPixelToPosition((_pixel_x, _pixel_y, _pixel_u), robotCoord, calib, RobotBrand.XYZ_Platform);
-                        if (!calibResult.IsSucceed)
-                        {
-                            await RecordPhotoCaptureAsync(procedure, robotCoord, false, new double[] { _pixel_x, _pixel_y, _pixel_u }, new double[] { 0, 0, 0 }, string.Empty, positionIndex, remark);
-                            return (false,cc, 0, 0, 0);
-                        }
-                        await RecordPhotoCaptureAsync(procedure, robotCoord, true, new double[] { _pixel_x, _pixel_y, _pixel_u }, new double[] { calibResult.X, calibResult.Y, calibResult.U }, string.Empty, positionIndex, remark);
-                        return (true,cc, calibResult.X, calibResult.Y, calibResult.U);
+                        result = (string)(outputCollection["Point"].Value);
+                        return (true, result);
                     }
                     SendTaskMessage(Lang.多次拍照失败, MessageLevel.Alarm);
-                    await RecordPhotoCaptureAsync(procedure, robotCoord, false, new double[] { 0, 0, 0 }, new double[] { 0, 0, 0 }, string.Empty, positionIndex, remark);
-                    return (false, cc, 0, 0, 0);
+                    return (false, result);
                 }
                 catch (Exception ex)
                 {
-                    LogHelper.WriteLogError(Lang.执行相机取图并获取单点位时出错, ex);
-                    await RecordPhotoCaptureAsync(procedure, robotCoord, false, new double[] { 0, 0, 0 }, new double[] { 0, 0, 0 }, string.Empty, positionIndex, remark);
-                    return (false, cc, 0, 0, 0);
+                    return (false, "");
                 }
                 finally
                 {
-                    if (systemConfig.IsBasePartOpenLight)
-                    {
-                        if (positionIndex == num)
-                        {
-                            await TurnOffLightAfterPhoto(procedure);
-                        }
-                    }
-                    else
-                    {
-                        await TurnOffLightAfterPhoto(procedure);
-                    }
-                    
+                    await TurnOffLightAfterPhoto(procedure);
                 }
+            });
         }
 
-
         /// <summary>
         /// 记录拍照结果数据至数据库
         /// </summary>

+ 2 - 0
TeamAAS-VM/TeamAAS-VP.csproj

@@ -557,6 +557,7 @@
     <Compile Include="Models\ImageParameters.cs" />
     <Compile Include="Models\NozzleChangeRecord.cs" />
     <Compile Include="Models\NumberStatistics.cs" />
+    <Compile Include="Models\PLC\PlcTemperatureAddress.cs" />
     <Compile Include="Models\ProductWithMes.cs" />
     <Compile Include="Models\Product\ProductGlobalParamEx.cs" />
     <Compile Include="Models\ThrowRecord.cs" />
@@ -576,6 +577,7 @@
     </Compile>
     <Compile Include="Services\MesService.cs" />
     <Compile Include="Services\ShiftWatcherService.cs" />
+    <Compile Include="ValueConverter\CountToColumnsConverter.cs" />
     <Compile Include="ValueConverter\ImageFileNameFormatConverter.cs" />
     <Compile Include="ViewModels\Home\ImagePreviewWindowViewModel.cs" />
     <Compile Include="ViewModels\Home\PickScrewAccuracyAnalyzerViewModel.cs" />

+ 25 - 0
TeamAAS-VM/ValueConverter/CountToColumnsConverter.cs

@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace TeamAAS_VP.ValueConverter
+{
+    public class CountToColumnsConverter : IValueConverter
+    {
+        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            if (value == null) return 1;
+            if (!int.TryParse(value.ToString(), out int count)) return 1;
+            if (count <= 1) return 1;
+            if (count == 2) return 2;
+            return 3; // 3 或更多时按 3 列分布(UniformGrid 会自动换行)
+        }
+
+        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+            => throw new NotSupportedException();
+    }
+}

+ 123 - 0
TeamAAS-VM/ViewModels/HomeViewModel.cs

@@ -33,6 +33,7 @@ using TeamAAS_VP.Services;
 using TeamAAS_VP.ViewModels.DebugMod;
 using TeamAAS_VP.Views.DebugMod;
 using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;
+using static TeamAAS_VP.Models.SystemConfiguration;
 
 namespace TeamAAS_VP.ViewModels
 {
@@ -138,6 +139,16 @@ namespace TeamAAS_VP.ViewModels
             set { SetProperty(ref _CurrentProduct, value); }
         }
 
+        private ObservableCollection<PlotModel> _PressurePlotModels = new ObservableCollection<PlotModel>();
+        /// <summary>
+        /// 每个元素是一个 PlotModel,对应一个压力传感器
+        /// </summary>
+        public ObservableCollection<PlotModel> PressurePlotModels
+        {
+            get { return _PressurePlotModels; }
+            set { SetProperty(ref _PressurePlotModels, value); }
+        }
+
         private PlotModel _LockCurvePlotModel;
         /// <summary>
         /// 锁付曲线
@@ -240,6 +251,13 @@ namespace TeamAAS_VP.ViewModels
             _eventAggregator.GetEvent<PressureFinishNotification>().Subscribe(OnPressureFinish);
 
             InitPressurePlots();
+
+            //获取所有的压力和温度传感器配置,初始化曲线图
+            var systemConfig = _configService.GetSystemConfiguration();
+            if (systemConfig.PressureSensorConfig != null)
+            {
+                InitPressurePlots(systemConfig.PressureSensorConfig.ToArray());
+            }
         }
 
         private void _remoteCommandService_CycleTimingTicked(object sender, TimeSpan e)
@@ -627,6 +645,8 @@ namespace TeamAAS_VP.ViewModels
                     _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = Lang.完成, Duration = 1 });
                 }
             });
+
+            //management.Test();
         }
 
         void ExecuteTorqueInspectionCommand()
@@ -745,6 +765,109 @@ namespace TeamAAS_VP.ViewModels
             model.Series.Add(series);
             return model;
         }
+
+
+        /// <summary>
+        /// 保压完成时调用
+        /// </summary>
+        /// <param name="tuple"></param>
+        private void OnPressureFinish((bool IsSuccess, int Index, (DateTime Timestamp, float Value)[] values, string SavePath) tuple)
+        {
+            //更新对应传感器的曲线图
+            if (_sensorIdToIndex.TryGetValue(tuple.Index.ToString(), out int index))
+            {
+                App.Current.Dispatcher.BeginInvoke(new Action(() => {
+                    var model = PressurePlotModels[index];
+                    var series = model.Series[0] as LineSeries;
+                    series.Points.Clear();
+                    //第一个点的时间作为X轴起点
+                    DateTime xAxisStart = tuple.values[0].Timestamp;
+                    foreach (var dataPoint in tuple.values)
+                    {
+                        // 计算相对于起点的秒数作为X轴坐标
+                        double xValue = (dataPoint.Timestamp - xAxisStart).TotalSeconds;
+                        series.Points.Add(new OxyPlot.DataPoint(xValue, dataPoint.Value));
+                    }
+                    // 重置所有轴的范围以适应新数据
+                    model.ResetAllAxes();
+                    model.InvalidatePlot(true);
+                    if (!string.IsNullOrEmpty(tuple.SavePath))
+                    {
+                        if (!Directory.Exists(Path.GetDirectoryName(tuple.SavePath)))
+                        {
+                            Directory.CreateDirectory(Path.GetDirectoryName(tuple.SavePath));
+                        }
+                        PngExporter.Export(model, tuple.SavePath, (int)model.Width, (int)model.Height);
+                    }
+                }));
+            }
+        }
+
+
+
+        // 初始化由配置决定的曲线数量(在读取 SystemConfiguration 后调用)
+        public void InitPressurePlots(IEnumerable<PressureSensorSettings> sensors)
+        {
+            PressurePlotModels.Clear();
+            _sensorIdToIndex.Clear();
+
+            int idx = 0;
+            foreach (var s in sensors)
+            {
+                var model = CreatePlotModelForSensor(s);
+                PressurePlotModels.Add(model);
+                // 假设 PressureSensorConfig 有唯一 Id(string 或 int)
+                _sensorIdToIndex[s.SensorId.ToString()] = idx++;
+            }
+        }
+
+        private PlotModel CreatePlotModelForSensor(PressureSensorSettings sensor)
+        {
+            var model = new PlotModel { Title = sensor.SensorName ?? $"Sensor {sensor.SensorId}", TitleFontSize = 16 };
+            // 设置图例
+            var legend = new Legend
+            {
+                LegendPosition = LegendPosition.TopRight,
+                LegendPlacement = LegendPlacement.Outside,
+                LegendOrientation = LegendOrientation.Vertical,
+                LegendBorderThickness = 0
+            };
+            model.Legends.Add(legend);
+            // 设置X轴
+            var xAxis = new LinearAxis
+            {
+                Key = "X",
+                Position = AxisPosition.Bottom,
+                Title = "Time (s)",
+                Minimum = 0,
+                MajorGridlineStyle = LineStyle.Solid,
+                MinorGridlineStyle = LineStyle.Dot
+            };
+            model.Axes.Add(xAxis);
+            // 设置Y轴
+            var yAxis = new LinearAxis
+            {
+                Key = "Y",
+                Position = AxisPosition.Left,
+                Title = sensor.SensorName.Contains("压力") ?"Pressure": "Temperature",
+                MajorGridlineStyle = LineStyle.Solid,
+                MinorGridlineStyle = LineStyle.Dot
+            };
+            model.Axes.Add(yAxis);
+            // 添加示例数据系列
+            var series = new LineSeries
+            {
+                Title = sensor.SensorName ?? $"Sensor {sensor.SensorId}",
+                StrokeThickness = 2,
+                MarkerSize = 3,
+                MarkerType = MarkerType.Circle,
+                CanTrackerInterpolatePoints = false,
+            };
+            model.Series.Add(series);
+            return model;
+        }
+
+
         #endregion
 
         #region 继承

+ 6 - 6
TeamAAS-VM/ViewModels/MainWindowViewModel.cs

@@ -305,12 +305,12 @@ namespace TeamAAS_VP.ViewModels
             await management.InitLightControllers();
 
             //-------------------SETP 7: 初始化电批-----------------------------------------------------------------------
-            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.InitScrewDriver();
+            //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.InitScrewDriver();
 
             //-------------------SETP 8: 加载所有产品-----------------------------------------------------------------------
             curvalue += 1;

+ 215 - 14
TeamAAS-VM/ViewModels/Product/PlcPointParamsViewModel.cs

@@ -410,6 +410,14 @@ namespace TeamAAS_VP.ViewModels.Product
         public DelegateCommand<object> ExecuteMotion =>
             _ExecuteMotion ?? (_ExecuteMotion = new DelegateCommand<object>(ExecuteExecuteMotion).ObservesCanExecute(() => CanExecutePointCommand).ObservesProperty(() => Robot).ObservesProperty(() => Robot.CanExecute).ObservesProperty(() => SelectedPointInDataGrid));
 
+        private DelegateCommand<object> _ExecuteMotionY;
+        public DelegateCommand<object> ExecuteMotionY =>
+            _ExecuteMotionY ?? (_ExecuteMotionY = new DelegateCommand<object>(ExecuteExecuteMotionY).ObservesCanExecute(() => CanExecutePointCommand).ObservesProperty(() => Robot).ObservesProperty(() => Robot.CanExecute).ObservesProperty(() => SelectedPointInDataGrid));
+
+        private DelegateCommand<object> _ExecuteMotionZ;
+        public DelegateCommand<object> ExecuteMotionZ =>
+            _ExecuteMotionZ ?? (_ExecuteMotionZ = new DelegateCommand<object>(ExecuteExecuteMotionZ).ObservesCanExecute(() => CanExecutePointCommand).ObservesProperty(() => Robot).ObservesProperty(() => Robot.CanExecute).ObservesProperty(() => SelectedPointInDataGrid));
+
         private DelegateCommand<object> _JogCommand;
         public DelegateCommand<object> JogCommand =>
              _JogCommand ?? (_JogCommand = new DelegateCommand<object>(ExecuteJogCommand).ObservesCanExecute(() => CanExecute).ObservesProperty(() => Robot).ObservesProperty(() => Robot.CanExecute));
@@ -602,11 +610,11 @@ namespace TeamAAS_VP.ViewModels.Product
                     case "U-":
                         await Robot.JogAsync("U", -distance);
                         break;
-                    case "V+":
-                        await Robot.JogAsync("V", distance);
+                    case "R+":
+                        await Robot.JogAsync("R", distance);
                         break;
-                    case "V-":
-                        await Robot.JogAsync("V", -distance);
+                    case "R-":
+                        await Robot.JogAsync("R", -distance);
                         break;
                     case "W+":
                         await Robot.JogAsync("W", distance);
@@ -644,14 +652,41 @@ namespace TeamAAS_VP.ViewModels.Product
                 return;
             }
             var values = (object[])parameter;
+            var curpos = await Robot.GetRobotPosAsync();
+            if (curpos == null) return;
+            var sysConfig = _configService.GetSystemConfiguration();
+            if (sysConfig == null) return;
+            if (SelectedIndex == 8)// 热熔压合点单独点动
+            {
+                _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = $"此按钮不执行热熔压合点", Duration = 0.4 });
+                return;
+            }
             var point = new RPoint()
             {
                 X = SelectedPoint.X_Position,
                 Y = SelectedPoint.Y_Position,
                 Z = SelectedPoint.Z_Position_Start,
-                U = SelectedPoint.U_Position,
-                V = SelectedPoint.R_Position,
+                U = curpos.U,
+                V = curpos.V,
             };
+            
+            //if (SelectedIndex == 8)//热熔压合点只动热熔Y轴
+            //{
+            //    point.X = curpos.X;
+            //    point.Y = curpos.Y;
+            //    point.Z = curpos.Z;
+            //    point.U = SelectedPoint.U_Position;
+            //    point.V = curpos.V;
+            //}
+            //else
+            //{
+            //    point.X = SelectedPoint.X_Position;
+            //    point.Y = SelectedPoint.Y_Position;
+            //    point.Z = SelectedPoint.Z_Position_Start;
+            //    point.U = curpos.U;
+            //    point.V = curpos.V;
+            //}
+
             MotionCommand motionCmd = (MotionCommand)values[1];
             if (Robot == null || !Robot.IsConnected) return;
             try
@@ -675,7 +710,7 @@ namespace TeamAAS_VP.ViewModels.Product
                             await Robot.GoAsync(point);
                             break;
                         case MotionCommand.Jump:
-                            await Robot.JumpAsync(point, 0);
+                            await Robot.JumpAsync(point, sysConfig.JumpLimitZ);
                             break;
                         case MotionCommand.Move:
                             await Robot.MoveAsync(point);
@@ -695,6 +730,148 @@ namespace TeamAAS_VP.ViewModels.Product
             }
         }
 
+        /// <summary>
+        /// 执行运动
+        /// </summary>
+        /// <param name="obj"></param>
+        async void ExecuteExecuteMotionY(object parameter)
+        {
+            if (parameter == null)
+            {
+                return;
+            }
+            if (SelectedPoint == null)
+            {
+                return;
+            }
+            var values = (object[])parameter;
+            var curpos = await Robot.GetRobotPosAsync();
+            if (curpos == null) return;
+            var sysConfig = _configService.GetSystemConfiguration();
+            if (sysConfig == null) return;
+            if (SelectedIndex != 8)// 热熔压合点单独点动
+            {
+                _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = $"此按钮只执行热熔压合点", Duration = 0.4 });
+                return;
+            }
+
+            var point = new RPoint()
+            {
+                X = curpos.X,
+                Y = curpos.Y,
+                Z = curpos.Z,
+                U = SelectedPoint.U_Position,
+                V = curpos.V,
+            };
+
+
+            MotionCommand motionCmd = (MotionCommand)values[1];
+            if (Robot == null || !Robot.IsConnected) return;
+            try
+            {
+                //确认要执行该点位的该运动指令吗
+                if (MessageBox.Show(string.Format(Lang.确认要执行点位0的1指令吗, SelectedPoint.Number, motionCmd), Lang.执行点位, MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
+                {
+                    return;
+                }
+
+                //Robot.Timeout = 6000000;
+                switch (motionCmd)
+                {
+                    case MotionCommand.Go:
+                        await Robot.GoAsync(point);
+                        break;
+                    case MotionCommand.Jump:
+                        await Robot.JumpAsync(point, sysConfig.JumpLimitZ);
+                        break;
+                    case MotionCommand.Move:
+                        await Robot.MoveAsync(point);
+                        break;
+                }
+                //Robot.Timeout = 5000;
+
+                point.Z = SelectedPoint.Z_Position_Stop;
+                await Robot.GoAsync(point);
+                _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = $"{Lang.完成}!", Duration = 0.4 });
+            }
+            catch (Exception ex)
+            {
+                LogHelper.WriteLogError(Lang.机器人点位执行点位时出错, ex);
+                _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = ex.Message, Duration = 1 });
+            }
+        }
+
+        /// <summary>
+        /// 执行运动
+        /// </summary>
+        /// <param name="obj"></param>
+        async void ExecuteExecuteMotionZ(object parameter)
+        {
+            if (parameter == null)
+            {
+                return;
+            }
+            if (SelectedPoint == null)
+            {
+                return;
+            }
+            var values = (object[])parameter;
+            var curpos = await Robot.GetRobotPosAsync();
+            if (curpos == null) return;
+            var sysConfig = _configService.GetSystemConfiguration();
+            if (sysConfig == null) return;
+            if (SelectedIndex != 8)// 热熔压合点单独点动
+            {
+                _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = $"此按钮只执行热熔压合点", Duration = 0.4 });
+                return;
+            }
+
+            var point = new RPoint()
+            {
+                X = curpos.X,
+                Y = curpos.Y,
+                Z = curpos.Z,
+                U = curpos.U,
+                V = SelectedPoint.R_Position,
+            };
+
+
+            MotionCommand motionCmd = (MotionCommand)values[1];
+            if (Robot == null || !Robot.IsConnected) return;
+            try
+            {
+                //确认要执行该点位的该运动指令吗
+                if (MessageBox.Show(string.Format(Lang.确认要执行点位0的1指令吗, SelectedPoint.Number, motionCmd), Lang.执行点位, MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
+                {
+                    return;
+                }
+
+                //Robot.Timeout = 6000000;
+                switch (motionCmd)
+                {
+                    case MotionCommand.Go:
+                        await Robot.GoAsync(point);
+                        break;
+                    case MotionCommand.Jump:
+                        await Robot.JumpAsync(point, sysConfig.JumpLimitZ);
+                        break;
+                    case MotionCommand.Move:
+                        await Robot.MoveAsync(point);
+                        break;
+                }
+                //Robot.Timeout = 5000;
+
+                point.Z = SelectedPoint.Z_Position_Stop;
+                await Robot.GoAsync(point);
+                _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = $"{Lang.完成}!", Duration = 0.4 });
+            }
+            catch (Exception ex)
+            {
+                LogHelper.WriteLogError(Lang.机器人点位执行点位时出错, ex);
+                _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = ex.Message, Duration = 1 });
+            }
+        }
+
         /// <summary>
         /// 示教点位
         /// </summary>
@@ -740,13 +917,32 @@ namespace TeamAAS_VP.ViewModels.Product
                     {
                         return;
                     }
-
                     var curpos = await Robot.GetRobotPosAsync();
-                    SelectedPoint.X_Position = curpos.X;
-                    SelectedPoint.Y_Position = curpos.Y;
-                    SelectedPoint.Z_Position_Start = curpos.Z;
-                    SelectedPoint.U_Position = curpos.U;
-                    SelectedPoint.R_Position = curpos.V;
+                   
+                    if (SelectedIndex==7)// 7 热熔搬运
+                    {
+                        SelectedPoint.X_Position = curpos.X;
+                        SelectedPoint.Y_Position = curpos.Y;
+                        SelectedPoint.Z_Position_Start = curpos.Z;
+                        SelectedPoint.U_Position = 0;
+                        SelectedPoint.R_Position = 0;
+                    }
+                    else if(SelectedIndex == 8)//8 热熔压合
+                    {
+                        SelectedPoint.X_Position = 0;
+                        SelectedPoint.Y_Position = 0;
+                        SelectedPoint.Z_Position_Start = 0;
+                        SelectedPoint.U_Position = curpos.U;
+                        SelectedPoint.R_Position = curpos.V;
+                    }
+                    else//螺丝机点位
+                    {
+                        SelectedPoint.X_Position = curpos.X;
+                        SelectedPoint.Y_Position = curpos.Y;
+                        SelectedPoint.Z_Position_Start = curpos.Z;
+                        SelectedPoint.U_Position = 0;
+                        SelectedPoint.R_Position = 0;
+                    }
                     _eventAggregator.GetEvent<SnackbarMessageNotification>().Publish(new MessageParameter() { Msg = $"{Lang.完成}!", Duration = 0.4 });
                 }
             }
@@ -876,7 +1072,6 @@ namespace TeamAAS_VP.ViewModels.Product
             switch (SelectedIndex)
             {
                 case 0:
-
                     Points = SelectProduct.PickCameraPoints;
                     PickPoints = SelectProduct.PickPoints;
                     break;
@@ -898,6 +1093,12 @@ namespace TeamAAS_VP.ViewModels.Product
                 case 6:
                     Points = SelectProduct.QrCodePoints;
                     break;
+                case 7:
+                    Points = SelectProduct.HotMeltPoints;
+                    break;
+                case 8:
+                    Points = SelectProduct.HotMeltPoints1;
+                    break;
                 default:
                     break;
             }

+ 83 - 1
TeamAAS-VM/ViewModels/Product/ProductParamsViewModel.cs

@@ -132,9 +132,44 @@ namespace TeamAAS_VP.ViewModels.Product
             }
         }
 
+        private ProcedureModel _FixedCameraProcedure;
+        /// <summary>
+        /// 固定相机复检拍照流程ID
+        /// </summary>
+        public ProcedureModel FixedCamera1Procedure
+        {
+            get { return _FixedCameraProcedure; }
+            set
+            {
+                SetProperty(ref _FixedCameraProcedure, value);
+                if (value != null)
+                {
+                    SelectProduct.FixedCamera1Procedure = value.Id;
+                }
+            }
+        }
+
+        private ProcedureModel _FixedCamera2Procedure;
+        /// <summary>
+        /// 固定相机复检拍照流程ID
+        /// </summary>
+        public ProcedureModel FixedCamera2Procedure
+        {
+            get { return _FixedCamera2Procedure; }
+            set
+            {
+                SetProperty(ref _FixedCamera2Procedure, value);
+                if (value != null)
+                {
+                    SelectProduct.FixedCamera2Procedure = value.Id;
+                }
+            }
+        }
+
+
         private ProcedureModel _QrCodePhotoProcedure;
         /// <summary>
-        /// 移动向下相机锁付拍照流程ID
+        /// 移动扫码拍照流程ID
         /// </summary>
         public ProcedureModel QrCodePhotoProcedure
         {
@@ -149,6 +184,24 @@ namespace TeamAAS_VP.ViewModels.Product
             }
         }
 
+        private ProcedureModel _FzCameraProcedure;
+        /// <summary>
+        /// 移动扫码拍照流程ID
+        /// </summary>
+        public ProcedureModel FzCameraProcedure
+        {
+            get { return _FzCameraProcedure; }
+            set
+            {
+                SetProperty(ref _FzCameraProcedure, value);
+                if (value != null)
+                {
+                    SelectProduct.FzCameraProcedureId = value.Id;
+                }
+            }
+        }
+
+
         #endregion
 
         #region 命令
@@ -242,6 +295,22 @@ namespace TeamAAS_VP.ViewModels.Product
             {
                 SelectProduct.MoveDownCameraLockPhotoProcedureId = Guid.Empty;
             }
+            if (FixedCamera1Procedure == null)
+            {
+                SelectProduct.FixedCamera1Procedure = Guid.Empty;
+            }
+            if (FixedCamera2Procedure == null)
+            {
+                SelectProduct.FixedCamera2Procedure = Guid.Empty;
+            }
+            if (QrCodePhotoProcedure==null)
+            {
+                SelectProduct.QrCodeProcedureId= Guid.Empty;
+            }
+            if (FzCameraProcedure==null)
+            {
+                SelectProduct.FzCameraProcedureId = Guid.Empty;
+            }
         }
         /// <summary>
         /// 上一步
@@ -312,10 +381,23 @@ namespace TeamAAS_VP.ViewModels.Product
                 {
                     MoveDownCameraLockPhotoProcedure = ProcedureModels.FirstOrDefault(p => p.Id == SelectProduct.MoveDownCameraLockPhotoProcedureId);
                 }
+                if (SelectProduct.FixedCamera1Procedure != Guid.Empty)
+                {
+                    FixedCamera1Procedure = ProcedureModels.FirstOrDefault(p => p.Id == SelectProduct.FixedCamera1Procedure);
+                }
+                if (SelectProduct.FixedCamera2Procedure != Guid.Empty)
+                {
+                    FixedCamera2Procedure = ProcedureModels.FirstOrDefault(p => p.Id == SelectProduct.FixedCamera2Procedure);
+                }
                 if (SelectProduct.QrCodeProcedureId != Guid.Empty)
                 {
                     QrCodePhotoProcedure = ProcedureModels.FirstOrDefault(p => p.Id == SelectProduct.QrCodeProcedureId);
                 }
+                if (SelectProduct.FzCameraProcedureId != Guid.Empty)
+                {
+                    FzCameraProcedure = ProcedureModels.FirstOrDefault(p => p.Id == SelectProduct.FzCameraProcedureId);
+                }
+
             }
             catch (Exception ex)
             {

+ 13 - 1
TeamAAS-VM/ViewModels/SettingViewModel.cs

@@ -1509,6 +1509,7 @@ namespace TeamAAS_VP.ViewModels
                 DowmCameraNum = sys.DowmCameraNum;
                 WorkMode = sys.WorkMode;
                 PickPointNum = sys.PickPointNum;
+                JumpLimitZ= sys.JumpLimitZ;
                 DowmCameraNum = sys.DowmCameraNum;
                 UpCameraPickNum = sys.UpCameraPickNum;
                 UpCameraPutNum = sys.UpCameraPutNum;
@@ -1646,7 +1647,7 @@ namespace TeamAAS_VP.ViewModels
 
         private Int16 _WorkMode = 0;
         /// <summary>
-        /// 工作模式 =1 拍1打1 =2 拍1打所有
+        /// 工作模式 =1 拍1打1 =2 拍1打所有,=3:先拍1打1打3颗再拍2打所有  
         /// </summary>
         public Int16 WorkMode
         {
@@ -1664,6 +1665,16 @@ namespace TeamAAS_VP.ViewModels
             set { SetProperty(ref _PickPointNum, value); }
         }
 
+        private double _JumpLimitZ = 0;
+        /// <summary>
+        /// 取料位置 =0 不需要取料 =1 需要取料
+        /// </summary>
+        public double JumpLimitZ
+        {
+            get { return _JumpLimitZ; }
+            set { SetProperty(ref _JumpLimitZ, value); }
+        }
+
         private Int16 _DowmCameraNum = 0;
         /// <summary>
         /// 下相机拍照次数
@@ -1803,6 +1814,7 @@ namespace TeamAAS_VP.ViewModels
                     var sysConfig = _configService.GetSystemConfiguration();
                     sysConfig.WorkMode = WorkMode;
                     sysConfig.PickPointNum = PickPointNum;
+                    sysConfig.JumpLimitZ= JumpLimitZ;
                     sysConfig.DowmCameraNum = DowmCameraNum;
                     sysConfig.UpCameraPickNum = UpCameraPickNum;
                     sysConfig.UpCameraPutNum = UpCameraPutNum;

+ 8 - 2
TeamAAS-VM/ViewModels/Statistics/ProductionStatementViewModel.cs

@@ -25,9 +25,14 @@ namespace TeamAAS_VP.ViewModels.Statistics
         ISystemDatabaseService _systemDatabaseService;
         IProductService _productService;
 
-        Management management;
-
         #region 属性
+        private Management _management;
+
+        public Management management
+        {
+            get { return _management; }
+            set { SetProperty(ref _management, value); }
+        }
         private Int64 _TotalCount;
         /// <summary>
         /// 总产能
@@ -126,6 +131,7 @@ namespace TeamAAS_VP.ViewModels.Statistics
             _container = container;
             _systemDatabaseService = systemDatabaseService;
             _productService = productService;
+            management = _container.Resolve<Management>();
         }
 
         #region 方法

+ 2 - 2
TeamAAS-VM/Views/Home/ShowVisionRender.xaml.cs

@@ -526,7 +526,7 @@ namespace TeamAAS_VP.Views.Home
 
                         if (isCompress)
                         {
-                            ImageHelper.CompressImage(reimage, Recordedpath, 100);
+                            ImageHelper.CompressImage(reimage, Recordedpath, 20);
                         }
                         else
                         {
@@ -608,7 +608,7 @@ namespace TeamAAS_VP.Views.Home
 
                         if (isCompress)
                         {
-                            ImageHelper.CompressImage(reimage, Recordedpath, 100);
+                            ImageHelper.CompressImage(reimage, Recordedpath, 20);
                         }
                         else
                         {

+ 49 - 5
TeamAAS-VM/Views/HomeView.xaml

@@ -14,6 +14,7 @@
              lex:ResxLocalizationProvider.DefaultAssembly="TeamAAS-VP"
              lex:ResxLocalizationProvider.DefaultDictionary="Lang"
              prism:ViewModelLocator.AutoWireViewModel="True"
+             xmlns:conv="clr-namespace:TeamAAS_VP.ValueConverter"
              mc:Ignorable="d"
              d:Height="1080"
              d:Width="1920"
@@ -21,6 +22,9 @@
              d:DataContext="{d:DesignInstance Type=vm:HomeViewModel}"
              Background="Transparent"
              FontFamily="{DynamicResource DefaultFont}">
+    <UserControl.Resources>
+        <conv:CountToColumnsConverter x:Key="CountToColumnsConverter" />
+    </UserControl.Resources>
     <b:Interaction.Triggers>
         <b:EventTrigger EventName="Loaded">
             <b:InvokeCommandAction Command="{Binding LoadedCommand}" />
@@ -34,8 +38,8 @@
 
         <Grid Grid.Row="0">
             <Grid.RowDefinitions>
-                <RowDefinition Height="0.65*" />
-                <!--<RowDefinition Height="0.4*" />-->
+                <RowDefinition Height="2*" />
+                <RowDefinition Height="1*" />
             </Grid.RowDefinitions>
             <!--图像-->
             <local:ShowVisionRender Grid.Row="0"
@@ -60,6 +64,46 @@
                       Margin="0" />
             </Grid>-->
 
+            <!-- 动态压力曲线集合 -->
+            <ItemsControl x:Name="pressureItems"
+                          Grid.Row="1"
+                          Grid.Column="0"
+                          ItemsSource="{Binding PressurePlotModels}">
+                <ItemsControl.ItemsPanel>
+                    <ItemsPanelTemplate>
+                        <!-- 一行显示,列数由转换器根据 Count 决定(1 / 2 / 3) -->
+                        <UniformGrid Rows="1"
+                                     Columns="{Binding PressurePlotModels.Count, RelativeSource={RelativeSource AncestorType=UserControl}, Converter={StaticResource CountToColumnsConverter}}" />
+                    </ItemsPanelTemplate>
+                </ItemsControl.ItemsPanel>
+
+                <!-- 保证每个项填充单元格 -->
+                <ItemsControl.ItemContainerStyle>
+                    <Style TargetType="ContentPresenter">
+                        <Setter Property="HorizontalAlignment"
+                                Value="Stretch" />
+                        <Setter Property="VerticalAlignment"
+                                Value="Stretch" />
+                        <Setter Property="Margin"
+                                Value="6" />
+                    </Style>
+                </ItemsControl.ItemContainerStyle>
+
+                <ItemsControl.ItemTemplate>
+                    <DataTemplate>
+                        <Border BorderBrush="LightGray"
+                                BorderThickness="1"
+                                CornerRadius="6"
+                                HorizontalAlignment="Stretch"
+                                VerticalAlignment="Stretch">
+                            <oxy:PlotView Model="{Binding}"
+                                          HorizontalAlignment="Stretch"
+                                          VerticalAlignment="Stretch" />
+                        </Border>
+                    </DataTemplate>
+                </ItemsControl.ItemTemplate>
+            </ItemsControl>
+
         </Grid>
         <Grid Grid.Row="1"
               Grid.Column="1">
@@ -186,7 +230,7 @@
                     <Grid.ColumnDefinitions>
                         <ColumnDefinition Width="*" />
                         <ColumnDefinition Width="*" />
-                        <ColumnDefinition Width="*" />
+                        <!--<ColumnDefinition Width="*" />-->
                     </Grid.ColumnDefinitions>
                     <!--加载产品-->
                     <materialDesign:Card Grid.Row="0"
@@ -335,7 +379,7 @@
                         </Grid>
                     </materialDesign:Card>
                     <!--生产数量2-->
-                    <materialDesign:Card Grid.Row="0"
+                    <!--<materialDesign:Card Grid.Row="0"
                       Grid.Column="2"
                       UniformCornerRadius="10"
                       BorderBrush="LightGray"
@@ -408,7 +452,7 @@
                     Grid.Column="1"
                     Text="{Binding management.Yield,StringFormat={}{0:F2}%}" />
                         </Grid>
-                    </materialDesign:Card>
+                    </materialDesign:Card>-->
                 </Grid>
 
                 <StackPanel Grid.Row="2"

+ 92 - 20
TeamAAS-VM/Views/Product/PlcPointParams.xaml

@@ -295,6 +295,32 @@
                                 </ListBoxItem.Style>
                                 <TextBlock Text="{lex:Loc 二维码拍照点位}" />
                             </ListBoxItem>
+                            <ListBoxItem>
+                                <ListBoxItem.Style>
+                                    <Style TargetType="ListBoxItem"
+                                           BasedOn="{StaticResource MaterialDesign3.NavigationBarPrimaryListBoxItem}">
+                                        <Setter Property="materialDesign:NavigationBarAssist.SelectedIcon"
+                                                Value="Circle" />
+                                        <Setter Property="materialDesign:NavigationBarAssist.UnselectedIcon"
+                                                Value="CircleOutline" />
+                                    </Style>
+                                </ListBoxItem.Style>
+                                <TextBlock Text="热熔搬运" />
+                            </ListBoxItem>
+                            <ListBoxItem>
+                                <ListBoxItem.Style>
+                                    <Style TargetType="ListBoxItem"
+                                           BasedOn="{StaticResource MaterialDesign3.NavigationBarPrimaryListBoxItem}">
+                                        <Setter Property="materialDesign:NavigationBarAssist.SelectedIcon"
+                                                Value="Circle" />
+                                        <Setter Property="materialDesign:NavigationBarAssist.UnselectedIcon"
+                                                Value="CircleOutline" />
+                                    </Style>
+                                </ListBoxItem.Style>
+                                <TextBlock Text="热熔压合" />
+                            </ListBoxItem>
+
+
                         </ListBox>
                         <!--点位列表操作按钮面板-->
                         <StackPanel DockPanel.Dock="Bottom"
@@ -995,7 +1021,8 @@
                                                         Width="Auto"
                                                         Binding="{Binding Label, Mode=TwoWay}" />
                                     <!--X 坐标-->
-                                    <DataGridTemplateColumn Header="X位置"
+                                    <DataGridTemplateColumn x:Name="colPosX"
+                                                            Header="X位置"
                                                             MinWidth="60"
                                                             Width="Auto">
                                         <DataGridTemplateColumn.CellTemplate>
@@ -1020,7 +1047,8 @@
                                         </DataGridTemplateColumn.CellEditingTemplate>
                                     </DataGridTemplateColumn>
                                     <!--X 速度-->
-                                    <DataGridTemplateColumn Header="{lex:Loc X速度}"
+                                    <DataGridTemplateColumn x:Name="colSpeedX"
+                                                            Header="{lex:Loc X速度}"
                                                             MinWidth="60"
                                                             Width="Auto">
                                         <DataGridTemplateColumn.CellTemplate>
@@ -1045,7 +1073,8 @@
                                         </DataGridTemplateColumn.CellEditingTemplate>
                                     </DataGridTemplateColumn>
                                     <!--Y 坐标-->
-                                    <DataGridTemplateColumn Header="{lex:Loc Y位置}"
+                                    <DataGridTemplateColumn x:Name="colPosY"
+                                                            Header="{lex:Loc Y位置}"
                                                             MinWidth="60"
                                                             Width="Auto">
                                         <DataGridTemplateColumn.CellTemplate>
@@ -1070,7 +1099,8 @@
                                         </DataGridTemplateColumn.CellEditingTemplate>
                                     </DataGridTemplateColumn>
                                     <!--Y 速度-->
-                                    <DataGridTemplateColumn Header="{lex:Loc Y速度}"
+                                    <DataGridTemplateColumn x:Name="colSpeedY"
+                                                            Header="{lex:Loc Y速度}"
                                                             MinWidth="60"
                                                             Width="Auto">
                                         <DataGridTemplateColumn.CellTemplate>
@@ -1095,7 +1125,8 @@
                                         </DataGridTemplateColumn.CellEditingTemplate>
                                     </DataGridTemplateColumn>
                                     <!--Z 起点坐标-->
-                                    <DataGridTemplateColumn Header="{lex:Loc Z起点位置}"
+                                    <DataGridTemplateColumn x:Name="colPosZ1"
+                                                            Header="{lex:Loc Z起点位置}"
                                                             MinWidth="60"
                                                             Width="Auto">
                                         <DataGridTemplateColumn.CellTemplate>
@@ -1120,7 +1151,8 @@
                                         </DataGridTemplateColumn.CellEditingTemplate>
                                     </DataGridTemplateColumn>
                                     <!--Z 起点速度-->
-                                    <DataGridTemplateColumn Header="{lex:Loc Z起点速度}"
+                                    <DataGridTemplateColumn x:Name="colSpeedZ1"
+                                                            Header="{lex:Loc Z起点速度}"
                                                             MinWidth="60"
                                                             Width="Auto">
                                         <DataGridTemplateColumn.CellTemplate>
@@ -1145,7 +1177,8 @@
                                         </DataGridTemplateColumn.CellEditingTemplate>
                                     </DataGridTemplateColumn>
                                     <!--Z 终点坐标-->
-                                    <DataGridTemplateColumn Header="{lex:Loc Z终点位置}"
+                                    <DataGridTemplateColumn x:Name="colPosZ2" 
+                                                            Header="{lex:Loc Z终点位置}"
                                                             MinWidth="60"
                                                             Width="Auto">
                                         <DataGridTemplateColumn.CellTemplate>
@@ -1170,7 +1203,8 @@
                                         </DataGridTemplateColumn.CellEditingTemplate>
                                     </DataGridTemplateColumn>
                                     <!--Z 终点速度-->
-                                    <DataGridTemplateColumn Header="{lex:Loc Z终点速度}"
+                                    <DataGridTemplateColumn x:Name="colSpeedZ2"
+                                                            Header="{lex:Loc Z终点速度}"
                                                             MinWidth="60"
                                                             Width="Auto">
                                         <DataGridTemplateColumn.CellTemplate>
@@ -1195,7 +1229,8 @@
                                         </DataGridTemplateColumn.CellEditingTemplate>
                                     </DataGridTemplateColumn>
                                     <!--U 坐标-->
-                                    <DataGridTemplateColumn Header="{lex:Loc U位置}"
+                                    <DataGridTemplateColumn x:Name="colPosU"
+                                                            Header="热熔Y轴位置"
                                                             MinWidth="60"
                                                             Width="Auto">
                                         <DataGridTemplateColumn.CellTemplate>
@@ -1220,7 +1255,8 @@
                                         </DataGridTemplateColumn.CellEditingTemplate>
                                     </DataGridTemplateColumn>
                                     <!--U 速度-->
-                                    <DataGridTemplateColumn Header="{lex:Loc U速度}"
+                                    <DataGridTemplateColumn x:Name="colSpeedU"
+                                                            Header="热熔Y轴速度"
                                                             MinWidth="60"
                                                             Width="Auto">
                                         <DataGridTemplateColumn.CellTemplate>
@@ -1245,7 +1281,8 @@
                                         </DataGridTemplateColumn.CellEditingTemplate>
                                     </DataGridTemplateColumn>
                                     <!--R 坐标-->
-                                    <DataGridTemplateColumn Header="{lex:Loc R位置}"
+                                    <DataGridTemplateColumn x:Name="colPosR"
+                                                            Header="热熔Z轴位置"
                                                             MinWidth="60"
                                                             Width="Auto">
                                         <DataGridTemplateColumn.CellTemplate>
@@ -1270,7 +1307,8 @@
                                         </DataGridTemplateColumn.CellEditingTemplate>
                                     </DataGridTemplateColumn>
                                     <!--R 速度-->
-                                    <DataGridTemplateColumn Header="{lex:Loc R速度}"
+                                    <DataGridTemplateColumn x:Name="colSpeedR"
+                                                            Header="热熔Z轴速度"
                                                             MinWidth="60"
                                                             Width="Auto">
                                         <DataGridTemplateColumn.CellTemplate>
@@ -1295,7 +1333,8 @@
                                         </DataGridTemplateColumn.CellEditingTemplate>
                                     </DataGridTemplateColumn>
                                     <!--扭矩-->
-                                    <DataGridTemplateColumn Header="{lex:Loc 扭矩}"
+                                    <DataGridTemplateColumn x:Name="colTorque"
+                                                            Header="{lex:Loc 扭矩}"
                                                             MinWidth="60"
                                                             Width="Auto">
                                         <DataGridTemplateColumn.CellTemplate>
@@ -1320,7 +1359,8 @@
                                         </DataGridTemplateColumn.CellEditingTemplate>
                                     </DataGridTemplateColumn>
                                     <!--供料器-->
-                                    <DataGridTemplateColumn Header="{lex:Loc 供料器}"
+                                    <DataGridTemplateColumn x:Name="colFeeder"
+                                                            Header="{lex:Loc 供料器}"
                                                             MinWidth="60"
                                                             Width="Auto">
                                         <DataGridTemplateColumn.CellTemplate>
@@ -1345,7 +1385,8 @@
                                         </DataGridTemplateColumn.CellEditingTemplate>
                                     </DataGridTemplateColumn>
                                     <!--电批程序号-->
-                                    <DataGridTemplateColumn Header="{lex:Loc 电批程序号}"
+                                    <DataGridTemplateColumn x:Name="colScrewDrive"
+                                                            Header="{lex:Loc 电批程序号}"
                                                             MinWidth="60"
                                                             Width="Auto">
                                         <DataGridTemplateColumn.CellTemplate>
@@ -1493,11 +1534,12 @@
                                 <TextBlock VerticalAlignment="Center"
                                            Margin="10,0">
                                     <TextBlock.Text>
-                                        <MultiBinding StringFormat="{}CurPos X: {0:F3} mm Y: {1:F3} mm Z: {2:F3} mm U: {3:F3} mm">
+                                        <MultiBinding StringFormat="{}CurPos X: {0:F3} mm Y: {1:F3} mm Z: {2:F3} mm 热熔Y: {3:F3} mm 热熔Z: {4:F3} mm">
                                             <Binding Path="Robot.CurrentPosition.X" />
                                             <Binding Path="Robot.CurrentPosition.Y" />
                                             <Binding Path="Robot.CurrentPosition.Z" />
                                             <Binding Path="Robot.CurrentPosition.U" />
+                                            <Binding Path="Robot.CurrentPosition.V" />
                                         </MultiBinding>
                                     </TextBlock.Text>
                                 </TextBlock>
@@ -1621,7 +1663,7 @@
                                             <materialDesign:PackIcon Kind="AxisZRotateCounterclockwise"
                                                                      Width="26"
                                                                      Height="26" />
-                                            <TextBlock Text="+U"
+                                            <TextBlock Text="+热熔Y"
                                                        HorizontalAlignment="Center" />
                                         </StackPanel>
                                     </Button>
@@ -1633,7 +1675,7 @@
                                             <materialDesign:PackIcon Kind="AxisZRotateClockwise"
                                                                      Width="26"
                                                                      Height="26" />
-                                            <TextBlock Text="-U"
+                                            <TextBlock Text="-热熔Y"
                                                        HorizontalAlignment="Center" />
                                         </StackPanel>
                                     </Button>
@@ -1646,7 +1688,7 @@
                                             <materialDesign:PackIcon Kind="AxisZRotateCounterclockwise"
                                                                      Width="26"
                                                                      Height="26" />
-                                            <TextBlock Text="+R"
+                                            <TextBlock Text="+热熔Z"
                                                        HorizontalAlignment="Center" />
                                         </StackPanel>
                                     </Button>
@@ -1659,7 +1701,7 @@
                                             <materialDesign:PackIcon Kind="AxisZRotateClockwise"
                                                                      Width="26"
                                                                      Height="26" />
-                                            <TextBlock Text="-R"
+                                            <TextBlock Text="-热熔Z"
                                                        HorizontalAlignment="Center" />
                                         </StackPanel>
                                     </Button>
@@ -1748,6 +1790,36 @@
                                                 </MultiBinding>
                                             </Button.CommandParameter>
                                         </Button>
+                                        
+                                        <Button Grid.Row="3"
+                                                Grid.Column="1"
+                                                Content="执行热熔Y"
+                                                Margin="2"
+                                                Command="{Binding DataContext.ExecuteMotionY,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}">
+                                            <Button.CommandParameter>
+                                                <MultiBinding Converter="{StaticResource MultiParameterConverter}">
+                                                    <Binding ElementName="cmbSelectPoint"
+                                                             Path="SelectedItem" />
+                                                    <Binding ElementName="cmbSelectMotioncmd"
+                                                             Path="SelectedItem" />
+                                                </MultiBinding>
+                                            </Button.CommandParameter>
+                                        </Button>
+                                        
+                                        <Button Grid.Row="3"
+                                                Grid.Column="2"
+                                                Content="执行热熔Z"
+                                                Margin="2"
+                                                Command="{Binding DataContext.ExecuteMotionZ,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}">
+                                            <Button.CommandParameter>
+                                                <MultiBinding Converter="{StaticResource MultiParameterConverter}">
+                                                    <Binding ElementName="cmbSelectPoint"
+                                                             Path="SelectedItem" />
+                                                    <Binding ElementName="cmbSelectMotioncmd"
+                                                             Path="SelectedItem" />
+                                                </MultiBinding>
+                                            </Button.CommandParameter>
+                                        </Button>
 
                                         <Button Grid.Row="3"
                                                 Grid.Column="0"

+ 67 - 0
TeamAAS-VM/Views/Product/PlcPointParams.xaml.cs

@@ -1,5 +1,6 @@
 using Cognex.VisionPro;
 using Cognex.VisionPro.Dimensioning;
+using NPOI.SS.Formula.Functions;
 using OxyPlot;
 using System;
 using System.Windows.Controls;
@@ -42,12 +43,78 @@ namespace TeamAAS_VP.Views.Product
                 {
                     var visible = VM.SelectedIndex == 3|| VM.SelectedIndex == 5 ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
                     var Usevisible = VM.SelectedIndex == 3 || VM.SelectedIndex == 4 || VM.SelectedIndex == 5 ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
+
+                    var Torque = VM.SelectedIndex == 7 || VM.SelectedIndex == 8 ? System.Windows.Visibility.Collapsed: System.Windows.Visibility.Visible;
+                    var Feeder = VM.SelectedIndex == 7 || VM.SelectedIndex == 8 ? System.Windows.Visibility.Collapsed : System.Windows.Visibility.Visible;
+                    var ScrewDrive = VM.SelectedIndex == 7 ? System.Windows.Visibility.Collapsed : System.Windows.Visibility.Visible;
+
                     this.Dispatcher.BeginInvoke(new Action(() =>
                     {
                         if (colProcedure != null)
                             colProcedure.Visibility = visible;
                         if (colIsUse != null)
                             colIsUse.Visibility = Usevisible;
+                        if (colTorque != null)
+                            colTorque.Visibility = Torque;
+                        if (colFeeder != null)
+                            colFeeder.Visibility = Feeder;
+                        if (colScrewDrive != null)
+                            colScrewDrive.Visibility = ScrewDrive;
+
+                        if (VM.SelectedIndex == 7)
+                        {
+                            colPosX.Visibility = System.Windows.Visibility.Visible;
+                            colPosY.Visibility = System.Windows.Visibility.Visible;
+                            colPosZ1.Visibility = System.Windows.Visibility.Visible;
+                            colPosZ2.Visibility = System.Windows.Visibility.Visible;
+
+                            colPosU.Visibility = System.Windows.Visibility.Collapsed;
+                            colPosR.Visibility = System.Windows.Visibility.Collapsed;
+
+                            colSpeedX.Visibility = System.Windows.Visibility.Visible;
+                            colSpeedY.Visibility = System.Windows.Visibility.Visible;
+                            colSpeedZ1.Visibility = System.Windows.Visibility.Visible;
+                            colSpeedZ2.Visibility = System.Windows.Visibility.Visible;
+
+                            colSpeedU.Visibility = System.Windows.Visibility.Collapsed;
+                            colSpeedR.Visibility = System.Windows.Visibility.Collapsed;
+
+                        }
+                        else if(VM.SelectedIndex == 8)
+                        {
+                            colPosX.Visibility = System.Windows.Visibility.Collapsed;
+                            colPosY.Visibility = System.Windows.Visibility.Collapsed;
+                            colPosZ1.Visibility = System.Windows.Visibility.Collapsed;
+                            colPosZ2.Visibility = System.Windows.Visibility.Collapsed;
+
+                            colPosU.Visibility = System.Windows.Visibility.Visible;
+                            colPosR.Visibility = System.Windows.Visibility.Visible;
+
+                            colSpeedX.Visibility = System.Windows.Visibility.Collapsed;
+                            colSpeedY.Visibility = System.Windows.Visibility.Collapsed;
+                            colSpeedZ1.Visibility = System.Windows.Visibility.Collapsed;
+                            colSpeedZ2.Visibility = System.Windows.Visibility.Collapsed;
+
+                            colSpeedU.Visibility = System.Windows.Visibility.Visible;
+                            colSpeedR.Visibility = System.Windows.Visibility.Visible;
+                        }
+                        else
+                        {
+                            colPosX.Visibility = System.Windows.Visibility.Visible;
+                            colPosY.Visibility = System.Windows.Visibility.Visible;
+                            colPosZ1.Visibility = System.Windows.Visibility.Visible;
+                            colPosZ2.Visibility = System.Windows.Visibility.Visible;
+                            colPosU.Visibility = System.Windows.Visibility.Visible;
+                            colPosR.Visibility = System.Windows.Visibility.Visible;
+
+                            colSpeedX.Visibility = System.Windows.Visibility.Visible;
+                            colSpeedY.Visibility = System.Windows.Visibility.Visible;
+                            colSpeedZ1.Visibility = System.Windows.Visibility.Visible;
+                            colSpeedZ2.Visibility = System.Windows.Visibility.Visible;
+                            colSpeedU.Visibility = System.Windows.Visibility.Visible;
+                            colSpeedR.Visibility = System.Windows.Visibility.Visible;
+                        }
+
                     }));
                 }
                 catch { }

+ 47 - 23
TeamAAS-VM/Views/Product/ProductParams.xaml

@@ -73,7 +73,7 @@
                                    x:Name="DrawerHost"
                                    IsEnabled="{Binding IsAllowEdit}">
             <materialDesign:DrawerHost.RightDrawerContent>
-                <uControl:ParameterEdit x:Name="parameterEdit"/>
+                <uControl:ParameterEdit x:Name="parameterEdit" Width="1200"/>
             </materialDesign:DrawerHost.RightDrawerContent>
 
             <Grid>
@@ -116,8 +116,8 @@
                     <ScrollViewer VerticalScrollBarVisibility="Auto"
               HorizontalScrollBarVisibility="Disabled"
               CanContentScroll="True">
-                        <StackPanel Orientation="Vertical"
-                Margin="0">
+                        <StackPanel Orientation="Vertical" Visibility="Collapsed"  Margin="0">
+               
                             <GroupBox Header="复检配置"
                   Margin="5"
                   Width="200">
@@ -322,52 +322,53 @@
                               Grid.Column="1"
                               Content="{lex:Loc 启用二次定位相机}"
                               IsChecked="{Binding SelectProduct.IsUserUpCamera}" />-->
-                    <!--固定向上相机1视觉流程-->
+
+
                     <TextBlock Grid.Row="1"
-                               Grid.Column="0"
-                               Text="{lex:Loc 固定向上相机1视觉流程ID}" />
+                        Grid.Column="0"
+                        Text="固定相机1复检拍照流程ID" />
                     <ComboBox Grid.Row="1"
-                              Grid.Column="1"
-                              ItemsSource="{Binding ProcedureModels}"
-                              SelectedItem="{Binding FixedUpCamera1Procedure}"
-                              materialDesign:TextFieldAssist.HasClearButton="True"
-                              materialDesign:HintAssist.Hint="{lex:Loc 选择需要配置的流程}">
+                        Grid.Column="1"
+                        ItemsSource="{Binding ProcedureModels}"
+                        SelectedItem="{Binding FixedCamera1Procedure}"
+                        materialDesign:TextFieldAssist.HasClearButton="True"
+                        materialDesign:HintAssist.Hint="{lex:Loc 选择需要配置的流程}">
                         <ComboBox.ItemTemplate>
                             <DataTemplate>
                                 <StackPanel Orientation="Horizontal">
                                     <materialDesign:PackIcon Kind="VideoOutline" />
                                     <TextBlock Text="{Binding CameraName}"
-                                               Margin="6,0" />
+                           Margin="6,0" />
                                     <materialDesign:PackIcon Kind="ProgressWrench" />
                                     <TextBlock Text="{Binding Name}"
-                                               Margin="6,0" />
+                           Margin="6,0" />
                                 </StackPanel>
                             </DataTemplate>
                         </ComboBox.ItemTemplate>
                     </ComboBox>
-                    <!--固定向上相机2视觉流程-->
                     <TextBlock Grid.Row="2"
-                               Grid.Column="0"
-                               Text="{lex:Loc 固定向上相机2视觉流程ID}" />
+                             Grid.Column="0"
+                             Text="固定相机2复检拍照流程ID" />
                     <ComboBox Grid.Row="2"
-                              Grid.Column="1"
-                              ItemsSource="{Binding ProcedureModels}"
-                              SelectedItem="{Binding FixedUpCamera2Procedure}"
-                              materialDesign:TextFieldAssist.HasClearButton="True"
-                              materialDesign:HintAssist.Hint="{lex:Loc 选择需要配置的流程}">
+                            Grid.Column="1"
+                            ItemsSource="{Binding ProcedureModels}"
+                            SelectedItem="{Binding FixedCamera2Procedure}"
+                            materialDesign:TextFieldAssist.HasClearButton="True"
+                            materialDesign:HintAssist.Hint="{lex:Loc 选择需要配置的流程}">
                         <ComboBox.ItemTemplate>
                             <DataTemplate>
                                 <StackPanel Orientation="Horizontal">
                                     <materialDesign:PackIcon Kind="VideoOutline" />
                                     <TextBlock Text="{Binding CameraName}"
-                                               Margin="6,0" />
+                                    Margin="6,0" />
                                     <materialDesign:PackIcon Kind="ProgressWrench" />
                                     <TextBlock Text="{Binding Name}"
-                                               Margin="6,0" />
+                                    Margin="6,0" />
                                 </StackPanel>
                             </DataTemplate>
                         </ComboBox.ItemTemplate>
                     </ComboBox>
+
                     <!--固定向下相机取料流程-->
                     <TextBlock Grid.Row="3"
                                Grid.Column="0"
@@ -437,6 +438,29 @@
                             </DataTemplate>
                         </ComboBox.ItemTemplate>
                     </ComboBox>
+                    <!--翻转相机流程id-->
+                    <TextBlock Grid.Row="6"
+                               Grid.Column="0"
+                               Text="翻转相机流程ID: " />
+                    <ComboBox Grid.Row="6"
+                              Grid.Column="1"
+                              ItemsSource="{Binding ProcedureModels}"
+                              SelectedItem="{Binding FzCameraProcedure}"
+                              materialDesign:TextFieldAssist.HasClearButton="True"
+                              materialDesign:HintAssist.Hint="{lex:Loc 选择需要配置的流程}">
+                        <ComboBox.ItemTemplate>
+                            <DataTemplate>
+                                <StackPanel Orientation="Horizontal">
+                                    <materialDesign:PackIcon Kind="VideoOutline" />
+                                    <TextBlock Text="{Binding CameraName}"
+                                               Margin="6,0" />
+                                    <materialDesign:PackIcon Kind="ProgressWrench" />
+                                    <TextBlock Text="{Binding Name}"
+                                               Margin="6,0" />
+                                </StackPanel>
+                            </DataTemplate>
+                        </ComboBox.ItemTemplate>
+                    </ComboBox>
                 </Grid>
             </Grid>
 

+ 25 - 2
TeamAAS-VM/Views/SettingView.xaml

@@ -2497,6 +2497,7 @@
                             <RowDefinition Height="Auto" />
                             <RowDefinition Height="Auto" />
                             <RowDefinition Height="Auto" />
+                            <RowDefinition Height="Auto" />
                         </Grid.RowDefinitions>
 
                         <!-- 相机拍照次数 -->
@@ -2626,7 +2627,7 @@
                                            Maximum="100"
                                            FontSize="{DynamicResource Font.Size.Body3}"
                                            materialDesign:HintAssist.HelperTextFontSize="10"
-                                           materialDesign:HintAssist.HelperText="1:拍1打1 - 2:拍1打所有" />
+                                           materialDesign:HintAssist.HelperText="1:拍1打1 - 2:拍2打所有 - 3:先拍1打1打3颗再拍2打所有" />
 
                         <!-- 取料位置 -->
                         <TextBlock Grid.Row="8"
@@ -2728,7 +2729,26 @@
                                      ToolTip="螺丝型号判断,如******123**,*为忽略字符" />
 
                         </StackPanel>
-                        <Button Grid.Row="12"
+
+                        <!-- Z轴JUMP位置 -->
+                        <TextBlock Grid.Row="12"
+                                   Grid.Column="0"
+                                   Style="{StaticResource MaterialDesignSubtitle1TextBlock}"
+                                   VerticalAlignment="Center"
+                                   HorizontalAlignment="Right"
+                                   Margin="0,6,10,6"
+                                   Text="Z轴JUMP位置" />
+                        <mah:NumericUpDown Grid.Row="12"
+                                           Grid.Column="1"
+                                           Margin="0,6"
+                                           Value="{Binding PickPointNum,Mode=TwoWay}"
+                                           Minimum="0"
+                                           Maximum="100"
+                                           FontSize="{DynamicResource Font.Size.Body3}"
+                                           materialDesign:HintAssist.HelperTextFontSize="10"
+                                           materialDesign:HintAssist.HelperText="JUMP运动时,Z轴先到达的高度" />
+                        
+                        <Button Grid.Row="13"
                                 Grid.Column="1"
                                 Margin="0,6"
                                 Style="{StaticResource MaterialDesignRaisedButton}"
@@ -2744,6 +2764,9 @@
                                            Text="{lex:Loc 保存系统参数}" />
                             </StackPanel>
                         </Button>
+
+
+
                     </Grid>
                     <StackPanel Grid.Row="5"
                                 Margin="0,12,0,0"

+ 40 - 0
TeamAAS-VM/Views/Statistics/ProductionStatement.xaml

@@ -47,6 +47,10 @@
                     <RowDefinition Height="auto" />
                     <RowDefinition Height="auto" />
                     <RowDefinition Height="auto" />
+                    <RowDefinition Height="auto" />
+                    <RowDefinition Height="auto" />
+                    <RowDefinition Height="auto" />
+
                 </Grid.RowDefinitions>
                 <oxy:PlotView Grid.Row="0"
                               Grid.Column="0"
@@ -103,6 +107,42 @@
                          TextAlignment="Center"
                          BorderThickness="1"
                          Margin="5" />
+                <TextBlock Grid.Row="5"
+                           Text="抛料数:"
+                           VerticalAlignment="Center"
+                           Margin="5" />
+                <TextBox Grid.Row="5"
+                         Grid.Column="1"
+                         Text="{Binding management.ThrowNumber}"
+                         IsReadOnly="True"
+                         BorderBrush="Gray"
+                         TextAlignment="Center"
+                         BorderThickness="1"
+                         Margin="5" />
+                <TextBlock Grid.Row="6"
+                           Text="NG数量:"
+                           VerticalAlignment="Center"
+                           Margin="5" />
+                <TextBox Grid.Row="6"
+                         Grid.Column="1"
+                         Text="{Binding management.NgNumber}"
+                         IsReadOnly="True"
+                         BorderBrush="Gray"
+                         TextAlignment="Center"
+                         BorderThickness="1"
+                         Margin="5" />
+                <TextBlock Grid.Row="7"
+                           Text="良率:"
+                           VerticalAlignment="Center"
+                           Margin="5" />
+                <TextBox Grid.Row="7"
+                         Grid.Column="1"
+                         Text="{Binding management.Yield,StringFormat={}{0:F2}%}"
+                         IsReadOnly="True"
+                         BorderBrush="Gray"
+                         TextAlignment="Center"
+                         BorderThickness="1"
+                         Margin="5" />
             </Grid>
             <Button Content="{lex:Loc 生成报表}"
                     Margin="10"

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio