Переглянути джерело

锁付结果采集与事件通知及前端展示实现

新增 LockResult 模型与 LockFinishNotification 事件,实现锁付完成后结果的采集、事件分发与前端 DataGrid 展示。完善锁付曲线联动,支持多螺丝结果追踪。补充电批数据属性与注释,调整界面细节。为后续数据分析与追溯提供基础。
孝锋 徐 8 місяців тому
батько
коміт
d80c7af278

+ 35 - 2
TeamAAS-VM/Core/Management.cs

@@ -1290,8 +1290,41 @@ namespace TeamAAS_VP.Core
                         {
                             SendTaskMessage($"收到停止锁付信号...", MessageLevel.Debug);
                             //位置编号
-                            //Int16 positionIndex = plc.ReadNode<Int16>(addressConfig.In_ProductNum.Address);
-                            
+                            Int16 positionIndex = plc.ReadNode<Int16>(addressConfig.In_ProductNum.Address);
+                            //获取当前锁付点
+                            var screwPoint = currentProduct.ScrewPoints.FirstOrDefault(p=>p.Number== positionIndex);
+                            //获取当前的机器人点位
+                            var robot = _robotService.GetAllRobots().FirstOrDefault();
+                            var currentPosition = robot.GetRobotPos();
+
+
+                            await Task.Delay(60);
+                            //获取电批结果
+                            ScrewDriver.GetData();
+                            LockResult lockResult=new LockResult();
+                            lockResult.Number = positionIndex;
+                            lockResult.LockPassed = ScrewDriver.Success;
+                            lockResult.ProductNumber = "";
+                            lockResult.LockTurns= (float)ScrewDriver.Truns;
+                            lockResult.LockTorque= (float)ScrewDriver.TorqueValue;
+                            lockResult.LockDuration= (float)ScrewDriver.FinalTime;
+                            lockResult.ScrewdriverProgramNumber= ScrewDriver.ProgramNumber;
+                            lockResult.ResultDetails = ScrewDriver.ErrorInfo;
+                            lockResult.Pressure= 0;
+                            lockResult.TargetTorque= 0;
+                            lockResult.TargetTurnsUpperLimit= 0;
+                            lockResult.TargetTurnsLowerLimit= 0;
+                            lockResult.TargetLockSpeed= 0;
+                            lockResult.StartPositionX= currentPosition.X;
+                            lockResult.StartPositionY= currentPosition.Y;
+                            lockResult.StartPositionZ= screwPoint.Z_Position_Start;
+                            lockResult.EndPositionZ= currentPosition.Z;
+                            lockResult.LockDescentSpeed= screwPoint.Z_Velocity_Stop;
+                            lockResult.FeederNumber= screwPoint!=null?screwPoint.Feeder:0;
+                            lockResult.NozzleNumber = "";
+                            lockResult.OperatorName = "";
+                            lockResult.WaveDatas= ScrewDriver.WaveDatas;
+                            _eventAggregator.GetEvent<LockFinishNotification>().Publish(lockResult);
                         }
                         else
                         {

+ 3 - 9
TeamAAS-VM/Core/ScrewDriver/XYD_ScrewDriver.cs

@@ -9,15 +9,6 @@ using TeamAAS_VP.Interfaces;
 
 namespace TeamAAS_VP.Core.ScrewDriver
 {
-    /*
-     计划(伪代码):
-     1. 为类添加 XML 文档注释,描述此驱动器的用途与协议相关信息。
-     2. 为构造函数、属性、事件、公开方法(Connect/ConnectAsync/GetData/GetDataAsync/Dispose)添加注释,说明用途与返回值。
-     3. 为内部重要方法(EnsureSocket/SendGetTspc/ReceiveOnce/UpdateConnectState/DataAnalysis/ToInt16/ToInt32N)添加注释,解释实现细节与特殊字节序处理。
-     4. 在 DataAnalysis 中为每个解析字段添加注释,标明字节偏移与单位转换,保留对异常与边界检查的说明。
-     5. 保持原有逻辑不变,只增加注释,保证与现有代码风格一致并能通过编译。
-    */
-
     /// <summary>
     /// XYD 系列电动螺丝刀数据读取与解析器。
     /// 通过 UDP 向设备发送 "GET_TSPC" 探测命令并接收包含 TSPB/TSPA 数据包的响应,
@@ -159,6 +150,9 @@ namespace TeamAAS_VP.Core.ScrewDriver
         /// </summary>
         public double TorqueValue { get; private set; }
 
+        /// <summary>
+        /// 锁付时长(单位:秒)。
+        /// </summary>
         public int FinalTime { get; private set; }
 
         /// <summary>

+ 13 - 0
TeamAAS-VM/Events/LockFinishNotification.cs

@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TeamAAS_VP.Models;
+
+namespace TeamAAS_VP.Events
+{
+    public class LockFinishNotification: Prism.Events.PubSubEvent<LockResult>
+    {
+    }
+}

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

@@ -0,0 +1,279 @@
+using Prism.Mvvm;
+using System;
+using System.Collections.Generic;
+using static TeamAAS_VP.Core.ScrewDriver.XYD_ScrewDriver;
+
+namespace TeamAAS_VP.Models
+{
+    public class LockResult : BindableBase
+    {
+        private int __Number;
+        /// <summary>
+        /// 螺丝编号
+        /// </summary>
+        public int Number
+        {
+            get { return __Number; }
+            set { SetProperty(ref __Number, value); }
+        }
+
+        private string __ProductNumber;
+        /// <summary>
+        /// 产品编号
+        /// </summary>
+        public string ProductNumber
+        {
+            get { return __ProductNumber; }
+            set { SetProperty(ref __ProductNumber, value); }
+        }
+
+        private DateTime __Timestamp;
+        /// <summary>
+        /// 时间戳
+        /// </summary>
+        public DateTime Timestamp
+        {
+            get { return __Timestamp; }
+            set { SetProperty(ref __Timestamp, value); }
+        }
+
+        private float __LockTurns;
+        /// <summary>
+        /// 锁付圈数
+        /// </summary>
+        public float LockTurns
+        {
+            get { return __LockTurns; }
+            set { SetProperty(ref __LockTurns, value); }
+        }
+
+        private float __LockTorque;
+        /// <summary>
+        /// 锁付扭矩
+        /// </summary>
+        public float LockTorque
+        {
+            get { return __LockTorque; }
+            set { SetProperty(ref __LockTorque, value); }
+        }
+
+        private float __LockDuration;
+        /// <summary>
+        /// 锁付用时
+        /// </summary>
+        public float LockDuration
+        {
+            get { return __LockDuration; }
+            set { SetProperty(ref __LockDuration, value); }
+        }
+
+        private bool __LockPassed;
+        /// <summary>
+        /// 锁付结果(是否通过)
+        /// </summary>
+        public bool LockPassed
+        {
+            get { return __LockPassed; }
+            set { SetProperty(ref __LockPassed, value); }
+        }
+
+        //
+        private string _ResultDetails;
+        /// <summary>
+        /// 结果详情
+        /// </summary>
+        public string ResultDetails
+        {
+            get { return _ResultDetails; }
+            set { SetProperty(ref _ResultDetails, value); }
+        }
+
+        private int __ScrewdriverProgramNumber;
+        /// <summary>
+        /// 电批程序号
+        /// </summary>
+        public int ScrewdriverProgramNumber
+        {
+            get { return __ScrewdriverProgramNumber; }
+            set { SetProperty(ref __ScrewdriverProgramNumber, value); }
+        }
+
+        private float __Pressure;
+        /// <summary>
+        /// 压力值
+        /// </summary>
+        public float Pressure
+        {
+            get { return __Pressure; }
+            set { SetProperty(ref __Pressure, value); }
+        }
+
+        private float __TargetTorque;
+        /// <summary>
+        /// 目标扭矩
+        /// </summary>
+        public float TargetTorque
+        {
+            get { return __TargetTorque; }
+            set { SetProperty(ref __TargetTorque, value); }
+        }
+
+        private float __TargetTurnsUpperLimit;
+        /// <summary>
+        /// 目标圈数上限
+        /// </summary>
+        public float TargetTurnsUpperLimit
+        {
+            get { return __TargetTurnsUpperLimit; }
+            set { SetProperty(ref __TargetTurnsUpperLimit, value); }
+        }
+
+        private float __TargetTurnsLowerLimit;
+        /// <summary>
+        /// 目标圈数下限
+        /// </summary>
+        public float TargetTurnsLowerLimit
+        {
+            get { return __TargetTurnsLowerLimit; }
+            set { SetProperty(ref __TargetTurnsLowerLimit, value); }
+        }
+
+        private float __TargetLockSpeed;
+        /// <summary>
+        /// 目标锁付速度
+        /// </summary>
+        public float TargetLockSpeed
+        {
+            get { return __TargetLockSpeed; }
+            set { SetProperty(ref __TargetLockSpeed, value); }
+        }
+
+        private float __StartPositionX;
+        /// <summary>
+        /// 锁付位置坐标 X 起始值
+        /// </summary>
+        public float StartPositionX
+        {
+            get { return __StartPositionX; }
+            set { SetProperty(ref __StartPositionX, value); }
+        }
+
+        private float __StartPositionY;
+        /// <summary>
+        /// 锁付位置坐标 Y 起始值
+        /// </summary>
+        public float StartPositionY
+        {
+            get { return __StartPositionY; }
+            set { SetProperty(ref __StartPositionY, value); }
+        }
+
+        private float __StartPositionZ;
+        /// <summary>
+        /// 锁付位置坐标 Z 起始值
+        /// </summary>
+        public float StartPositionZ
+        {
+            get { return __StartPositionZ; }
+            set { SetProperty(ref __StartPositionZ, value); }
+        }
+
+        private float __EndPositionZ;
+        /// <summary>
+        /// Z 终点值
+        /// </summary>
+        public float EndPositionZ
+        {
+            get { return __EndPositionZ; }
+            set { SetProperty(ref __EndPositionZ, value); }
+        }
+
+        private float __LockDescentSpeed;
+        /// <summary>
+        /// 锁付下降速度
+        /// </summary>
+        public float LockDescentSpeed
+        {
+            get { return __LockDescentSpeed; }
+            set { SetProperty(ref __LockDescentSpeed, value); }
+        }
+
+        private int __FeederNumber;
+        /// <summary>
+        /// 供料器编号
+        /// </summary>
+        public int FeederNumber
+        {
+            get { return __FeederNumber; }
+            set { SetProperty(ref __FeederNumber, value); }
+        }
+
+        private string __NozzleNumber;
+        /// <summary>
+        /// 披头编号
+        /// </summary>
+        public string NozzleNumber
+        {
+            get { return __NozzleNumber; }
+            set { SetProperty(ref __NozzleNumber, value); }
+        }
+
+        //当前的操作员名称
+        private string _OperatorName;
+        public string OperatorName
+        {
+            get { return _OperatorName; }
+            set { SetProperty(ref _OperatorName, value); }
+        }
+
+        /// <summary>
+        /// 锁付曲线数据列表
+        /// </summary>
+        public List<WaveData> WaveDatas { get; set; } = new List<WaveData>();
+
+        public LockResult()
+        {
+            // 默认构造函数
+            Timestamp = DateTime.Now;
+        }
+
+        public LockResult(int number, string productNumber, float lockTurns, float lockTorque,bool lockPassed)
+        {
+            Number = number;
+            ProductNumber = productNumber;
+            Timestamp = DateTime.Now;
+            LockTurns = lockTurns;
+            LockTorque = lockTorque;
+            LockPassed = lockPassed;
+        }
+
+        public LockResult Clone()
+        {
+            return new LockResult
+            {
+                Number = this.Number,
+                ProductNumber = this.ProductNumber,
+                Timestamp = this.Timestamp,
+                LockTurns = this.LockTurns,
+                LockTorque = this.LockTorque,
+                LockDuration = this.LockDuration,
+                LockPassed = this.LockPassed,
+                ScrewdriverProgramNumber = this.ScrewdriverProgramNumber,
+                Pressure = this.Pressure,
+                TargetTorque = this.TargetTorque,
+                TargetTurnsUpperLimit = this.TargetTurnsUpperLimit,
+                TargetTurnsLowerLimit = this.TargetTurnsLowerLimit,
+                TargetLockSpeed = this.TargetLockSpeed,
+                StartPositionX = this.StartPositionX,
+                StartPositionY = this.StartPositionY,
+                StartPositionZ = this.StartPositionZ,
+                EndPositionZ = this.EndPositionZ,
+                LockDescentSpeed = this.LockDescentSpeed,
+                FeederNumber = this.FeederNumber,
+                NozzleNumber= this.NozzleNumber,
+                WaveDatas = new List<WaveData>(this.WaveDatas)
+            };
+        }
+
+    }
+}

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

@@ -597,6 +597,7 @@
     <Compile Include="Enums\FocusMethod.cs" />
     <Compile Include="Enums\OutputPointMode.cs" />
     <Compile Include="Enums\RoiOperationMode.cs" />
+    <Compile Include="Events\LockFinishNotification.cs" />
     <Compile Include="Interfaces\ICalibrationService.cs" />
     <Compile Include="Interfaces\ICameraService.cs" />
     <Compile Include="Interfaces\IConfigService.cs" />
@@ -615,6 +616,7 @@
     <Compile Include="Models\DataPoint.cs" />
     <Compile Include="Models\Lights\ChannelConfig.cs" />
     <Compile Include="Models\Lights\LightControllerConfig.cs" />
+    <Compile Include="Models\LockResult.cs" />
     <Compile Include="Models\PLC\PlcAddressConfig.cs" />
     <Compile Include="Models\PLC\PlcAddress.cs" />
     <Compile Include="Models\PLC\PlcPoint.cs" />

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

@@ -134,6 +134,17 @@ namespace TeamAAS_VP.ViewModels
             set { SetProperty(ref _LockCurvePlotModel, value); }
         }
 
+        private ObservableCollection<LockResult> _LockResults = new ObservableCollection<LockResult>();
+
+        /// <summary>
+        /// 锁付结果列表
+        /// </summary>
+        public ObservableCollection<LockResult> LockResults
+        {
+            get { return _LockResults; }
+            set { SetProperty(ref _LockResults, value); }
+        }
+
         #endregion
 
         #region 命令
@@ -176,6 +187,7 @@ namespace TeamAAS_VP.ViewModels
             _remoteCommandService = remoteCommandService;
             _remoteCommandService.CycleTimingTicked += _remoteCommandService_CycleTimingTicked;
             _systemDatabaseService = systemDatabaseService;
+            _eventAggregator.GetEvent<LockFinishNotification>().Subscribe(OnLockFinish);
         }
 
         private void _remoteCommandService_CycleTimingTicked(object sender, TimeSpan e)
@@ -398,6 +410,32 @@ namespace TeamAAS_VP.ViewModels
             LockCurvePlotModel = model;
         }
 
+        /// <summary>
+        /// 螺丝锁付完成时调用
+        /// </summary>
+        /// <param name="result"></param>
+        /// <exception cref="NotImplementedException"></exception>
+        private void OnLockFinish(LockResult result)
+        {
+            //如果当前螺丝编号为1,则清除之前的结果
+            if (result.Number == 1)
+            {
+                LockResults.Clear();
+            }
+            LockResults.Add(result);
+
+            //更新曲线图
+            App.Current.Dispatcher.BeginInvoke(new Action(() => {
+                var series = LockCurvePlotModel.Series[0] as LineSeries;
+                series.Points.Clear();
+                foreach (var waveData in result.WaveDatas)
+                {
+                    series.Points.Add(new OxyPlot.DataPoint(waveData.LockAngle, waveData.Torque));
+                }
+                LockCurvePlotModel.InvalidatePlot(true);
+            }));
+
+        }
         #endregion
 
         #region 继承

+ 18 - 7
TeamAAS-VM/Views/HomeView.xaml

@@ -64,7 +64,7 @@
                                      UniformCornerRadius="10"
                                      BorderBrush="LightGray"
                                      BorderThickness="1"
-                                     Margin="4">
+                                     Margin="0,4">
                     <DockPanel LastChildFill="True"
                                Margin="8">
                         <TextBlock DockPanel.Dock="Top"
@@ -81,25 +81,36 @@
                                   GridLinesVisibility="None"
                                   RowHeaderWidth="0"
                                   MinHeight="120"
-                                  MaxHeight="260"
                                   VerticalAlignment="Stretch"
                                   HorizontalAlignment="Stretch"
                                   Margin="0,8,0,0">
                             <DataGrid.Columns>
                                 <DataGridTextColumn Header="#"
-                                                    Binding="{Binding Index}"
+                                                    Binding="{Binding Number}"
+                                                    Width="auto"
+                                                    IsReadOnly="True" />
+                                <DataGridTextColumn Header="产品编号"
+                                                    Binding="{Binding ProductNumber}"
                                                     Width="auto"
                                                     IsReadOnly="True" />
                                 <DataGridTextColumn Header="时间"
                                                     Binding="{Binding Timestamp, StringFormat={}{0:G}}"
                                                     Width="auto"
                                                     IsReadOnly="True" />
-                                <DataGridTextColumn Header="结果"
-                                                    Binding="{Binding Result}"
+                                <DataGridTextColumn Header="程序号"
+                                                    Binding="{Binding ScrewdriverProgramNumber}"
+                                                    Width="auto"
+                                                    IsReadOnly="True" />
+                                <DataGridTextColumn Header="锁付圈数"
+                                                    Binding="{Binding LockTurns}"
+                                                    Width="auto"
+                                                    IsReadOnly="True" />
+                                <DataGridTextColumn Header="锁付扭矩"
+                                                    Binding="{Binding LockTorque}"
                                                     Width="auto"
                                                     IsReadOnly="True" />
-                                <DataGridTextColumn Header="操作员"
-                                                    Binding="{Binding Operator}"
+                                <DataGridTextColumn Header="锁付结果"
+                                                    Binding="{Binding LockPassed}"
                                                     Width="auto"
                                                     IsReadOnly="True" />
                                 <DataGridTextColumn Header="详情"