Ver código fonte

增加压力数据最大值显示

zly 5 meses atrás
pai
commit
17d2188f11

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

@@ -1,4 +1,6 @@
 using Cognex.VisionPro.ToolBlock;
+using NPOI.OpenXmlFormats.Vml;
+using Org.BouncyCastle.Crypto;
 using Prism.Events;
 using Prism.Ioc;
 using Prism.Mvvm;
@@ -25,6 +27,7 @@ using TeamAAS_VP.Models;
 using TeamAAS_VP.Models.PLC;
 using TeamAAS_VP.Models.Torque;
 using TeamAAS_VP.Resources.Languages;
+using TeamAAS_VP.Views.Product;
 using TouchSocket.Core;
 using TouchSocket.SerialPorts;
 using TouchSocket.Sockets;
@@ -57,15 +60,15 @@ namespace TeamAAS_VP.Core
         /// <summary>
         /// 压力采集信号控制CTS
         /// </summary>
-        private CancellationTokenSource _pressureCts;
+        private CancellationTokenSource[] _pressureCts = new CancellationTokenSource[100];
         /// <summary>
         /// 压力采集超时CTS
         /// </summary>
-        private CancellationTokenSource _pressureTimeoutCts;
+        private CancellationTokenSource[] _pressureTimeoutCts = new CancellationTokenSource[100];
         /// <summary>
         /// 压力采集CTS
         /// </summary>
-        private CancellationTokenSource _pressureLinkedCts;
+        private CancellationTokenSource[] _pressureLinkedCts = new CancellationTokenSource[100];
         /// <summary>
         /// 压力数据集合
         /// </summary>
@@ -78,6 +81,7 @@ namespace TeamAAS_VP.Core
         /// 超时自动停止秒数
         /// </summary>
         private int _pressureMaxDurationSeconds = 30; //超时自动停止秒数
+        DateTime[] StartCtqTime = new DateTime[3];//开始采集Ctq数据的时间
         List<LockResult> lockResultsAll = new List<LockResult>();//一个产品的总结果
         string productSn = "";//产品sn
         DateTime StartScrewTime = DateTime.Now;//开始锁附的时间
@@ -1800,6 +1804,7 @@ namespace TeamAAS_VP.Core
                 // 开始锁付
                 else if (addressConfig.In_WorkStart.Address.Contains(tuple.nodeId))
                 {
+
                     if (tuple.value is Int16 state)
                     {
                         if (_LastWorkStart != state)
@@ -1810,6 +1815,7 @@ namespace TeamAAS_VP.Core
                         {
                             return;
                         }
+                        var code = plc.ReadNode<string>(string.Format(addressConfig.In_Code.Address, 0));
                         if (state == 1)
                         {
                             SendTaskMessage(Lang.收到开始锁付信号, MessageLevel.Debug);
@@ -1818,7 +1824,7 @@ namespace TeamAAS_VP.Core
                             Int16 positionIndex = plc.ReadNode<Int16>(addressConfig.In_ProductNum.Address);
                             SendTaskMessage(string.Format(Lang.编号0, positionIndex), MessageLevel.Info);
                             // 开始采集压力值
-                            StartPressureCollection(currentProduct.Name, _productService.CurrentProductCode, positionIndex);
+                            StartPressureCollection(currentProduct.Name, _productService.CurrentProductCode, 0);
                         }
                         else
                         {
@@ -1857,7 +1863,7 @@ namespace TeamAAS_VP.Core
                             var robot = _robotService.GetAllRobots().FirstOrDefault();
                             var currentPosition = robot.GetRobotPos();
                             //读取压力值
-                            float pressure = plc.ReadNode<float>(addressConfig.In_PressureValue.Address);
+                            float pressure = _maxPressure;
                             //当前用户名
                             string currentUserName = _systemDatabaseService.GetCurrentUser().UserName;
 
@@ -1901,6 +1907,8 @@ namespace TeamAAS_VP.Core
                             lockResult.OperatorName = currentUserName;
                             lockResult.ProductImagePath = "";
                             lockResult.WaveDatas = ScrewDriver.WaveDatas;
+
+                            //pressure = 0;
                             //获取系统参数
                             var systemConfig = _configService.GetSystemConfiguration();
                             //判断是否保存锁付曲线
@@ -1957,7 +1965,7 @@ namespace TeamAAS_VP.Core
                                 resultToMes.Add($"Screw{lockResult.Number}_Fail");
                             }
                             SendTaskMessage($"螺丝序号:{lockResult.Number},扭力:{lockResult.LockTorque},压力:{lockResult.Pressure},圈数:{lockResult.LockTurns}", MessageLevel.Info);
-
+                            _maxPressure = 0;
                             lockResultsAll.Add(lockResult);
                             App.Current.Dispatcher.Invoke(() =>
                             {
@@ -1974,6 +1982,7 @@ namespace TeamAAS_VP.Core
                             await plc.WriteNodeAsync(addressConfig.In_WorkDone.Address, (Int16)0);
                             // 停止采集压力并保存
                             await StopAndSavePressureCollectionAsync(currentProduct.Name, _productService.CurrentProductCode, positionIndex);
+                            pressure = 0;
                         }
                         else
                         {
@@ -2807,7 +2816,7 @@ namespace TeamAAS_VP.Core
                 _eventAggregator.GetEvent<TaskMessageNotification>().Publish(new Models.MessageStruct() { Message = msg, level = level });
             });
         }
-
+        private float _maxPressure = float.MinValue;
         #region Pressure collection helpers
         /// <summary>
         /// 开始采集压力值
@@ -2817,29 +2826,36 @@ namespace TeamAAS_VP.Core
         /// <param name="positionIndex">锁付点编号</param>
         private void StartPressureCollection(string productName, string productCode, int positionIndex)
         {
+            
             try
             {
                 // cancel existing if any
-                _pressureCts?.Cancel();
-                _pressureTimeoutCts?.Cancel();
-                _pressureLinkedCts?.Dispose();
+                //_pressureCts?.Cancel();
+                //_pressureTimeoutCts?.Cancel();
+                //_pressureLinkedCts?.Dispose();
+                //_pressureSamples?.Clear();
+                //_pressureTimeoutCts[positionIndex]?.Cancel();
                 _pressureSamples?.Clear();
 
-                _pressureCts = new CancellationTokenSource();
-                _pressureTimeoutCts = new CancellationTokenSource();
+                _pressureCts[positionIndex] = new CancellationTokenSource();
+                _pressureTimeoutCts[positionIndex] = new CancellationTokenSource();
+
+                //_pressureCts = new CancellationTokenSource();
+                //_pressureTimeoutCts = new CancellationTokenSource();
 
                 // timeout after configured seconds
-                _pressureTimeoutCts.CancelAfter(TimeSpan.FromSeconds(_pressureMaxDurationSeconds));
+                _pressureTimeoutCts[positionIndex].CancelAfter(TimeSpan.FromSeconds(_pressureMaxDurationSeconds));
 
                 // link tokens so either stop or timeout cancels
-                _pressureLinkedCts = CancellationTokenSource.CreateLinkedTokenSource(_pressureCts.Token, _pressureTimeoutCts.Token);
+                _pressureLinkedCts[positionIndex] = CancellationTokenSource.CreateLinkedTokenSource(_pressureCts[positionIndex].Token, _pressureTimeoutCts[positionIndex].Token);
 
-                var token = _pressureLinkedCts.Token;
+                var token = _pressureLinkedCts[positionIndex].Token;
                 var addressConfig = _configService.GetPlcAddresses();
                 var plc = _plcService.GetPlcByNumber(addressConfig.PlcNo) as OpcUaClientPLC;
                 if (plc == null || !plc.IsConnected) return;
                 Task.Run(async () =>
                 {
+                    
                     SendTaskMessage($"Pressure collection started for position {positionIndex}", MessageLevel.Debug);
                     while (!token.IsCancellationRequested)
                     {
@@ -2848,7 +2864,13 @@ namespace TeamAAS_VP.Core
                             float pressure = plc.ReadNode<float>(addressConfig.In_PressureValue.Address);
                             lock (_pressureSamples)
                             {
+                                //SendTaskMessage($"压力采集时出错:{pressure}", MessageLevel.Info);
                                 _pressureSamples.Add((DateTime.Now, pressure));
+                                if (pressure > _maxPressure)
+                                {
+                                    _maxPressure = pressure;
+                                }
+
                             }
                         }
                         catch (Exception ex)
@@ -2857,8 +2879,9 @@ namespace TeamAAS_VP.Core
                         }
                         await Task.Delay(_pressureSampleIntervalMs);
                     }
+                    SendTaskMessage($"Pressure {_pressureSamples}", MessageLevel.Debug);
                     // if cancelled due to timeout
-                    if (_pressureTimeoutCts.IsCancellationRequested && !_pressureCts.IsCancellationRequested)
+                    if (_pressureTimeoutCts[positionIndex].IsCancellationRequested && !_pressureCts[positionIndex].IsCancellationRequested)
                     {
                         SendTaskMessage("Pressure collection timed out, saving collected data.", MessageLevel.Alarm);
                         await StopAndSavePressureCollectionAsync(productName, productCode, positionIndex);
@@ -2868,6 +2891,7 @@ namespace TeamAAS_VP.Core
             catch (Exception ex)
             {
                 LogHelper.WriteLogError("StartPressureCollection error", ex);
+                SendTaskMessage($"压力采集时出错:{ex.Message}", MessageLevel.Error);
             }
         }
 
@@ -2882,8 +2906,15 @@ namespace TeamAAS_VP.Core
         {
             try
             {
+                // 获取当前产品
+                var currentProduct = _productService.GetCurrentProduct();
+                if (currentProduct == null)
+                {
+                    return;
+                }
+
                 // cancel sampling
-                _pressureCts?.Cancel();
+                //_pressureCts?.Cancel();
                 // allow worker to observe cancel
                 await Task.Delay(50);
 
@@ -2898,31 +2929,59 @@ namespace TeamAAS_VP.Core
                     SendTaskMessage("No pressure samples collected.", MessageLevel.Info);
                     return;
                 }
-
+                
                 // save to file under configured path
                 try
                 {
                     //获取系统参数
                     var systemConfig = _configService.GetSystemConfiguration();
+
+                    string datePath = DateTime.Now.ToString("yyyy-MM") + "\\" + DateTime.Now.ToString("yyyy-MM-dd") + "\\";
+                    string dirPath = System.IO.Path.Combine(systemConfig.ScrewCurvePath, datePath, currentProduct.Name, positionIndex.ToString());
+                    if (!Directory.Exists(dirPath))
+                    {
+                        Directory.CreateDirectory(dirPath);
+                    }
+                    string fileName = $"pressure-{productCode}-{positionIndex}-{DateTime.Now.ToString("HHmmss")}.csv";
+                    string fullPath = Path.Combine(dirPath, fileName);
+                    string pngfileName = $"pressure-{productCode}-{positionIndex}-{DateTime.Now.ToString("HHmmss")}.png";
+                    string pngPath = Path.Combine(dirPath, pngfileName);
+                    if (!systemConfig.IsSaveScrewCurve)
+                    {
+                        fullPath = string.Empty;
+                        pngPath = string.Empty;
+                    }
+                    App.Current.Dispatcher.Invoke(() =>
+                    {
+                        _eventAggregator.GetEvent<PressureFinishNotification>().Publish((true, snapshot.ToArray(), pngPath));
+                    });
+                    
                     //判断是否保存锁付曲线
                     if (systemConfig.IsSaveScrewCurve)
                     {
-                        string basePath = systemConfig?.ScrewCurvePath ?? Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
-                        string datePath = DateTime.Now.ToString("yyyy-MM") + "\\" + DateTime.Now.ToString("yyyy-MM-dd") + "\\";
-                        string dirPath = Path.Combine(basePath, datePath, productName ?? "UnknownProduct", productCode ?? DateTime.Now.ToString("yyyyMMddHHmmssfff"));
-                        if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath);
-                        string fileName = $"pressure-{productCode}-{positionIndex}-{DateTime.Now.ToString("HHmmss")}.csv";
-                        string fullPath = Path.Combine(dirPath, fileName);
-                        var sb = new StringBuilder();
-                        sb.AppendLine("Timestamp,Value");
-                        foreach (var s in snapshot)
+                        if (!string.IsNullOrEmpty(fullPath))
                         {
-                            sb.AppendLine($"{s.Timestamp:O},{s.Value}");
-                        }
+                            var sb = new StringBuilder();
+                            sb.AppendLine("Timestamp,Value");
+                            foreach (var s in snapshot)
+                            {
+                                sb.AppendLine($"{s.Timestamp:O},{s.Value}");                                
+                            }
 
-                        File.WriteAllText(fullPath, sb.ToString());
-                        SendTaskMessage($"Pressure samples saved to {fullPath}", MessageLevel.Debug);
+                            File.WriteAllText(fullPath, sb.ToString());
+                            SendTaskMessage($"Pressure samples saved to {fullPath}", MessageLevel.Debug);
+                        }
                     }
+
+                    //var sb = new StringBuilder();
+                    //sb.AppendLine("Timestamp,Value");
+                    //foreach (var s in snapshot)
+                    //{
+                    //    sb.AppendLine($"{s.Timestamp:O},{s.Value}");
+                    //}
+
+                    //File.WriteAllText(fullPath, sb.ToString());
+                    // SendTaskMessage($"Pressure samples saved to {fullPath}", MessageLevel.Debug);
                 }
                 catch (Exception ex)
                 {
@@ -2938,11 +2997,12 @@ namespace TeamAAS_VP.Core
             {
                 try
                 {
-                    _pressureLinkedCts?.Cancel();
-                    _pressureLinkedCts?.Dispose();
-                    _pressureTimeoutCts?.Dispose();
-                    _pressureCts?.Dispose();
+                    _pressureLinkedCts[positionIndex]?.Cancel();
+                    _pressureLinkedCts[positionIndex]?.Dispose();
+                    _pressureTimeoutCts[positionIndex]?.Dispose();
+                    _pressureCts[positionIndex]?.Dispose();
                     _pressureSamples?.Clear();
+                    //_maxPressure = 0;
                 }
                 catch { }
             }

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

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

+ 122 - 16
TeamAAS-VM/ViewModels/HomeViewModel.cs

@@ -47,8 +47,17 @@ namespace TeamAAS_VP.ViewModels
         IDialogService _dialogService;
 
         #region 属性
+        private PlotModel _PressurePlotModel = new PlotModel();
+        /// <summary>
+        /// 每个元素是一个 PlotModel,对应一个压力传感器
+        /// </summary>
+        public PlotModel PressurePlotModel
+        {
+            get { return _PressurePlotModel; }
+            set { SetProperty(ref _PressurePlotModel, value); }
+        }
 
-        private ObservableCollection<TaskMessage> messageQueue=new ObservableCollection<TaskMessage>();
+        private ObservableCollection<TaskMessage> messageQueue = new ObservableCollection<TaskMessage>();
 
         /// <summary>
         /// 运行信息队列
@@ -56,7 +65,7 @@ namespace TeamAAS_VP.ViewModels
         public ObservableCollection<TaskMessage> MessageQueue
         {
             get { return messageQueue; }
-            set { SetProperty(ref messageQueue,value); }
+            set { SetProperty(ref messageQueue, value); }
         }
 
         private ObservableCollection<ProductModel> _ProductList;
@@ -87,14 +96,14 @@ namespace TeamAAS_VP.ViewModels
         public ProductModel SelectProduct
         {
             get { return _SelectProduct; }
-            set { SetProperty(ref _SelectProduct,value); }
+            set { SetProperty(ref _SelectProduct, value); }
         }
 
         private bool CanLoad
         {
             get
             {
-                if (SelectProduct!=null && IsLoadProduct)
+                if (SelectProduct != null && IsLoadProduct)
                 {
                     return true;
                 }
@@ -156,17 +165,20 @@ namespace TeamAAS_VP.ViewModels
             get { return _IsAllowEdit; }
             set { SetProperty(ref _IsAllowEdit, value); }
         }
+
+        // 可选:记录传感器 Id -> 索引 的映射,便于外部(如 Management)按 Id 更新
+        private readonly Dictionary<string, int> _sensorIdToIndex = new Dictionary<string, int>();
         #endregion
 
         #region 命令
         public DelegateCommand LoadedCommand { get; set; }
         private DelegateCommand<ProductModel> _LoadProductCommand;
         public DelegateCommand<ProductModel> LoadProductCommand =>
-            _LoadProductCommand ?? (_LoadProductCommand = new DelegateCommand<ProductModel>(ExecuteLoadProductCommand).ObservesCanExecute(()=> CanLoad).ObservesProperty(()=> SelectProduct).ObservesProperty(()=> IsLoadProduct));
+            _LoadProductCommand ?? (_LoadProductCommand = new DelegateCommand<ProductModel>(ExecuteLoadProductCommand).ObservesCanExecute(() => CanLoad).ObservesProperty(() => SelectProduct).ObservesProperty(() => IsLoadProduct));
 
         private DelegateCommand _ResetCounterCommand;
         public DelegateCommand ResetCounterCommand =>
-            _ResetCounterCommand ?? (_ResetCounterCommand = new DelegateCommand(ExecuteResetCounterCommand).ObservesCanExecute(() => DoCondition).ObservesProperty(()=>isCanExecute));
+            _ResetCounterCommand ?? (_ResetCounterCommand = new DelegateCommand(ExecuteResetCounterCommand).ObservesCanExecute(() => DoCondition).ObservesProperty(() => isCanExecute));
 
         private bool DoCondition
         {
@@ -196,7 +208,7 @@ namespace TeamAAS_VP.ViewModels
         public DelegateCommand AddScrewCommand =>
             _AddScrewCommand ?? (_AddScrewCommand = new DelegateCommand(ExecuteAddScrewCommand));
 
-        
+
         private DelegateCommand _SetAlarmValueCommand;
         public DelegateCommand SetAlarmValueCommand =>
             _SetAlarmValueCommand ?? (_SetAlarmValueCommand = new DelegateCommand(ExecuteSetAlarmValueCommand));
@@ -208,7 +220,7 @@ namespace TeamAAS_VP.ViewModels
         #endregion
 
         public HomeViewModel(IEventAggregator ea, IContainerProvider container, IProductService productService, IConfigService configService, IRemoteCommandService remoteCommandService
-            , ISystemDatabaseService systemDatabaseService,IDialogService dialogService)
+            , ISystemDatabaseService systemDatabaseService, IDialogService dialogService)
         {
             _eventAggregator = ea;
             _container = container;
@@ -225,13 +237,16 @@ namespace TeamAAS_VP.ViewModels
             _remoteCommandService.CycleTimingTicked += _remoteCommandService_CycleTimingTicked;
             _systemDatabaseService = systemDatabaseService;
             _eventAggregator.GetEvent<LockFinishNotification>().Subscribe(OnLockFinish);
+            _eventAggregator.GetEvent<PressureFinishNotification>().Subscribe(OnPressureFinish);
+
+            InitPressurePlots();
         }
 
         private void _remoteCommandService_CycleTimingTicked(object sender, TimeSpan e)
         {
             try
             {
-                if (App.Current!=null)
+                if (App.Current != null)
                 {
                     App.Current.Invoke(() =>
                     {
@@ -246,7 +261,7 @@ namespace TeamAAS_VP.ViewModels
         }
 
         #region 方法
-        bool isFirst=true;
+        bool isFirst = true;
         private void OnLoad()
         {
             if (!isFirst)
@@ -306,7 +321,8 @@ namespace TeamAAS_VP.ViewModels
         /// <param name="color"></param>
         public void AddMessage(string msg, Color color)
         {
-            App.Current.Dispatcher.BeginInvoke(new Action(() => {
+            App.Current.Dispatcher.BeginInvoke(new Action(() =>
+            {
                 try
                 {
                     MessageQueue.Add(new TaskMessage()
@@ -332,7 +348,8 @@ namespace TeamAAS_VP.ViewModels
         public void AddMessage(string msg, MessageLevel level)
         {
             MessageStruct messageStruct = new MessageStruct() { Message = msg, level = level };
-            App.Current.Dispatcher.BeginInvoke(new Action(() => {
+            App.Current.Dispatcher.BeginInvoke(new Action(() =>
+            {
                 AddMessage(messageStruct);
             }));
         }
@@ -381,7 +398,8 @@ namespace TeamAAS_VP.ViewModels
 
         public void AddMessageInvoke(MessageStruct messageStruct)
         {
-            App.Current.Dispatcher.BeginInvoke(new Action(() => {
+            App.Current.Dispatcher.BeginInvoke(new Action(() =>
+            {
                 AddMessage(messageStruct);
             }));
         }
@@ -403,7 +421,7 @@ namespace TeamAAS_VP.ViewModels
         /// </summary>
         async void ExecuteResetCounterCommand()
         {
-            var currentProduct =_productService.GetCurrentProduct();
+            var currentProduct = _productService.GetCurrentProduct();
             if (currentProduct == null) return;
             var view = new ShowMessage(Lang.计数清零, Lang.是否重置当前产品的计数);
             //show the dialog
@@ -510,7 +528,6 @@ namespace TeamAAS_VP.ViewModels
             {
                 LockResults.Clear();
             }
-
             LockResults.Add(result);
 
             App.Current.Dispatcher.BeginInvoke(new Action(() =>
@@ -640,6 +657,94 @@ namespace TeamAAS_VP.ViewModels
             });
         }
 
+        /// <summary>
+        /// 保压完成时调用
+        /// </summary>
+        /// <param name="tuple"></param>
+        private void OnPressureFinish((bool IsSuccess, (DateTime Timestamp, float Value)[] values, string SavePath) tuple)
+        {
+            //更新对应传感器的曲线图
+
+            App.Current.Dispatcher.BeginInvoke(new Action(() =>
+            {
+                var model = PressurePlotModel;
+                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()
+        {
+            var model = CreatePlotModelForSensor();
+            PressurePlotModel = model;
+        }
+
+        private PlotModel CreatePlotModelForSensor()
+        {
+            var model = new PlotModel { Title = $"压力曲线", 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 = "Pressure",
+                MajorGridlineStyle = LineStyle.Solid,
+                MinorGridlineStyle = LineStyle.Dot
+            };
+            model.Axes.Add(yAxis);
+            // 添加示例数据系列
+            var series = new LineSeries
+            {
+                Title = $"Sensor 1",
+                StrokeThickness = 2,
+                MarkerSize = 3,
+                MarkerType = MarkerType.Circle,
+                CanTrackerInterpolatePoints = false,
+            };
+            model.Series.Add(series);
+            return model;
+        }
         #endregion
 
         #region 继承
@@ -693,7 +798,8 @@ namespace TeamAAS_VP.ViewModels
 
         private void _productService_OnProductChanged(ProductModel obj)
         {
-            App.Current.Dispatcher.BeginInvoke(new Action(() => {
+            App.Current.Dispatcher.BeginInvoke(new Action(() =>
+            {
                 CurrentProduct = obj;
             }));
         }

+ 20 - 6
TeamAAS-VM/Views/HomeView.xaml

@@ -40,12 +40,26 @@
             <!--图像-->
             <local:ShowVisionRender Grid.Row="0"
                                     Grid.Column="0" />
-            <!--曲线图-->
-            <oxy:PlotView Grid.Row="1"
-                          Grid.Column="0"
-                          Model="{Binding LockCurvePlotModel}"
-                          Background="Transparent"
-                          Margin="10" />
+            <Grid Grid.Row="1">
+                <Grid.ColumnDefinitions>
+                    <ColumnDefinition Width="*" />
+                   
+                </Grid.ColumnDefinitions>
+                <!--曲线图-->
+                <oxy:PlotView Grid.Row="0"
+                      Grid.Column="0"
+                      Model="{Binding LockCurvePlotModel}"
+                      Background="Transparent"
+                      Margin="10,10,0,10" Grid.ColumnSpan="2" />
+                <!-- 动态压力曲线集合 -->
+                <oxy:PlotView Grid.Row="0"
+                      Grid.Column="1"
+                      Model="{Binding PressurePlotModel}"
+                      Background="Transparent"
+                              Visibility="Hidden"
+                      Margin="0" />
+            </Grid>
+
         </Grid>
         <Grid Grid.Row="1"
               Grid.Column="1">