From 831256336f525028cb71bfa06d71543d631966ce Mon Sep 17 00:00:00 2001 From: akwkevin Date: Mon, 2 Aug 2021 18:08:43 +0800 Subject: [PATCH] =?UTF-8?q?sfc=E9=80=BB=E8=BE=91=E5=9F=BA=E6=9C=AC?= =?UTF-8?q?=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ViewModels/DiagramsViewModel.cs | 4 + .../ViewModels/FlowchartViewModel.cs | 2 +- .../ViewModels/LogicalViewModel.cs | 8 + .../ViewModels/MainWindowViewModel.cs | 5 + .../ViewModels/SFCViewModel.cs | 89 ++++++--- AIStudio.Wpf.ADiagram/Views/MainWindow.xaml | 10 +- AIStudio.Wpf.Flowchart/FlowchartService.cs | 36 ++-- .../ViewModels/LogicalGateItemViewModel.cs | 2 +- AIStudio.Wpf.SFC/SFCService.cs | 171 +++++++++++++++++- AIStudio.Wpf.SFC/ViewModels/SFCNode.cs | 14 ++ AIStudio.Wpf.SFC/ViewModels/SFCNode.xaml | 10 +- .../ViewModels/Simulate_SolenoidViewModel.cs | 19 ++ .../ViewModels/Simulate_TankViewModel.cs | 11 ++ 13 files changed, 328 insertions(+), 53 deletions(-) diff --git a/AIStudio.Wpf.ADiagram/ViewModels/DiagramsViewModel.cs b/AIStudio.Wpf.ADiagram/ViewModels/DiagramsViewModel.cs index bc0aeaf..38bbfd4 100644 --- a/AIStudio.Wpf.ADiagram/ViewModels/DiagramsViewModel.cs +++ b/AIStudio.Wpf.ADiagram/ViewModels/DiagramsViewModel.cs @@ -1067,5 +1067,9 @@ namespace AIStudio.Wpf.ADiagram.ViewModels return new Size(formattedText.Width, formattedText.Height); } + + public virtual void Dispose() + { + } } } diff --git a/AIStudio.Wpf.ADiagram/ViewModels/FlowchartViewModel.cs b/AIStudio.Wpf.ADiagram/ViewModels/FlowchartViewModel.cs index eb31c35..6af81cd 100644 --- a/AIStudio.Wpf.ADiagram/ViewModels/FlowchartViewModel.cs +++ b/AIStudio.Wpf.ADiagram/ViewModels/FlowchartViewModel.cs @@ -98,7 +98,7 @@ namespace AIStudio.Wpf.Flowchart DiagramViewModel.ClearSelectedItems(); - FlowchartService.InitData(DiagramViewModel.Items.OfType().ToList(), DiagramViewModel.Items.OfType().ToList()); + FlowchartService.InitData(DiagramViewModel.Items.OfType().ToList(), DiagramViewModel.Items.OfType().ToList(), DiagramViewModel); } diff --git a/AIStudio.Wpf.ADiagram/ViewModels/LogicalViewModel.cs b/AIStudio.Wpf.ADiagram/ViewModels/LogicalViewModel.cs index 61f1748..260fc8c 100644 --- a/AIStudio.Wpf.ADiagram/ViewModels/LogicalViewModel.cs +++ b/AIStudio.Wpf.ADiagram/ViewModels/LogicalViewModel.cs @@ -133,6 +133,14 @@ namespace AIStudio.Wpf.Logical } } + if (arg is TimerDesignerItemViewModel) + { + if (DiagramViewModel.Items.OfType().Any(p => p.LogicalType == LogicalType.Time)) + { + return false; + } + } + return true; } diff --git a/AIStudio.Wpf.ADiagram/ViewModels/MainWindowViewModel.cs b/AIStudio.Wpf.ADiagram/ViewModels/MainWindowViewModel.cs index 1f28062..b228534 100644 --- a/AIStudio.Wpf.ADiagram/ViewModels/MainWindowViewModel.cs +++ b/AIStudio.Wpf.ADiagram/ViewModels/MainWindowViewModel.cs @@ -661,6 +661,11 @@ namespace AIStudio.Wpf.ADiagram.ViewModels { //here's how you can cancel stuff: //args.Cancel(); + + if (args.DragablzItem.DataContext is DiagramsViewModel viewModel) + { + viewModel.Dispose(); + } } private void MainWindowViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) diff --git a/AIStudio.Wpf.ADiagram/ViewModels/SFCViewModel.cs b/AIStudio.Wpf.ADiagram/ViewModels/SFCViewModel.cs index d61e1fd..07d7e39 100644 --- a/AIStudio.Wpf.ADiagram/ViewModels/SFCViewModel.cs +++ b/AIStudio.Wpf.ADiagram/ViewModels/SFCViewModel.cs @@ -8,6 +8,7 @@ using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Timers; using System.Windows; using System.Windows.Media; using Util.DiagramDesigner; @@ -35,6 +36,7 @@ namespace AIStudio.Wpf.Flowchart DiagramViewModel.CellVerticalAlignment = CellVerticalAlignment.Center; } + private System.Timers.Timer readDataTimer = new System.Timers.Timer(); protected override void Init() { base.Init(); @@ -42,43 +44,46 @@ namespace AIStudio.Wpf.Flowchart SFCStartNode start = new SFCStartNode() { Left = 0, Top = 60, Text = "S0" }; DiagramViewModel.DirectAddItemCommand.Execute(start); - SFCConditionNode condition1 = new SFCConditionNode() { Left = 0, Top = 120, Text = "X0" }; - DiagramViewModel.DirectAddItemCommand.Execute(condition1); + SFCConditionNode condition1_1 = new SFCConditionNode() { Left = 0, Top = 120, Text = "X01", Expression = "p0==1&p1<20", LinkPoint = new ObservableCollection { SFCService.LinkPoint.FirstOrDefault(p => p.Name == "S0"), SFCService.LinkPoint.FirstOrDefault(p => p.Name == "T2") } }; + DiagramViewModel.DirectAddItemCommand.Execute(condition1_1); + + SFCConditionNode condition1_2 = new SFCConditionNode() { Left = 100, Top = 120, Text = "X02", Expression = "p0==1&p1<30", LinkPoint = new ObservableCollection { SFCService.LinkPoint.FirstOrDefault(p => p.Name == "S0"), SFCService.LinkPoint.FirstOrDefault(p => p.Name == "T2") } }; + DiagramViewModel.DirectAddItemCommand.Execute(condition1_2); SFCNodeNode step1 = new SFCNodeNode() { Left = 0, Top = 180, Text = "S1" }; DiagramViewModel.DirectAddItemCommand.Execute(step1); - SFCActionNode action11 = new SFCActionNode() { Left = 100, Top = 180, Text = "SET_V1" }; + SFCActionNode action11 = new SFCActionNode() { Left = 100, Top = 180, Text = "SET_V1", Expression = "1", LinkPoint = SFCService.LinkPoint.FirstOrDefault(p => p.Name == "K1_DI") }; DiagramViewModel.DirectAddItemCommand.Execute(action11); - SFCActionNode action12 = new SFCActionNode() { Left = 200, Top = 180, Text = "SET_V2" }; + SFCActionNode action12 = new SFCActionNode() { Left = 200, Top = 180, Text = "SET_V2", Expression = "1", LinkPoint = SFCService.LinkPoint.FirstOrDefault(p => p.Name == "K2_DI") }; DiagramViewModel.DirectAddItemCommand.Execute(action12); - SFCActionNode action13 = new SFCActionNode() { Left = 300, Top = 180, Text = "SET_V3" }; + SFCActionNode action13 = new SFCActionNode() { Left = 300, Top = 180, Text = "SET_V3", Expression = "1", LinkPoint = SFCService.LinkPoint.FirstOrDefault(p => p.Name == "K3_DI") }; DiagramViewModel.DirectAddItemCommand.Execute(action13); - SFCActionNode action14 = new SFCActionNode() { Left = 400, Top = 180, Text = "RES_V4" }; + SFCActionNode action14 = new SFCActionNode() { Left = 400, Top = 180, Text = "RES_V4", Expression = "0", LinkPoint = SFCService.LinkPoint.FirstOrDefault(p => p.Name == "K4_DI") }; DiagramViewModel.DirectAddItemCommand.Execute(action14); - SFCConditionNode condition2 = new SFCConditionNode() { Left = 0, Top = 240, Text = "X1" }; + SFCConditionNode condition2 = new SFCConditionNode() { Left = 0, Top = 240, Text = "X1", Expression = "p0>50", LinkPoint = new ObservableCollection { SFCService.LinkPoint.FirstOrDefault(p => p.Name == "T2") } }; DiagramViewModel.DirectAddItemCommand.Execute(condition2); SFCNodeNode step2 = new SFCNodeNode() { Left = 0, Top = 300, Text = "S2" }; DiagramViewModel.DirectAddItemCommand.Execute(step2); - SFCActionNode action2 = new SFCActionNode() { Left = 100, Top = 300, Text = "SET_V4" }; + SFCActionNode action2 = new SFCActionNode() { Left = 100, Top = 300, Text = "SET_V4", Expression = "1", LinkPoint = SFCService.LinkPoint.FirstOrDefault(p => p.Name == "K4_DI") }; DiagramViewModel.DirectAddItemCommand.Execute(action2); - SFCConditionNode condition3 = new SFCConditionNode() { Left = 0, Top = 360, Text = "X2" }; + SFCConditionNode condition3 = new SFCConditionNode() { Left = 0, Top = 360, Text = "X2", Expression = "p0>70", LinkPoint = new ObservableCollection { SFCService.LinkPoint.FirstOrDefault(p => p.Name == "T2") } }; DiagramViewModel.DirectAddItemCommand.Execute(condition3); SFCNodeNode step3 = new SFCNodeNode() { Left = 0, Top = 420, Text = "S3" }; DiagramViewModel.DirectAddItemCommand.Execute(step3); - SFCActionNode action3 = new SFCActionNode() { Left = 100, Top = 420, Text = "RES_V1" }; + SFCActionNode action3 = new SFCActionNode() { Left = 100, Top = 420, Text = "RES_V1", Expression = "0", LinkPoint = SFCService.LinkPoint.FirstOrDefault(p => p.Name == "K1_DI") }; DiagramViewModel.DirectAddItemCommand.Execute(action3); - SFCConditionNode condition4 = new SFCConditionNode() { Left = 0, Top = 480, Text = "X4" }; + SFCConditionNode condition4 = new SFCConditionNode() { Left = 0, Top = 480, Text = "X3", Expression = "p0>80", LinkPoint = new ObservableCollection { SFCService.LinkPoint.FirstOrDefault(p => p.Name == "T2") } }; DiagramViewModel.DirectAddItemCommand.Execute(condition4); SFCCOBeginNode cobegin = new SFCCOBeginNode() { Left = 38, Top = 540, Text = "" }; @@ -87,23 +92,35 @@ namespace AIStudio.Wpf.Flowchart SFCNodeNode step4 = new SFCNodeNode() { Left = 0, Top = 600, Text = "S4" }; DiagramViewModel.DirectAddItemCommand.Execute(step4); - SFCActionNode action4 = new SFCActionNode() { Left = 100, Top = 600, Text = "RES_V2" }; + SFCActionNode action4 = new SFCActionNode() { Left = 100, Top = 600, Text = "RES_V2", Expression = "0", LinkPoint = SFCService.LinkPoint.FirstOrDefault(p => p.Name == "K2_DI") }; DiagramViewModel.DirectAddItemCommand.Execute(action4); + SFCConditionNode condition5 = new SFCConditionNode() { Left = 0, Top = 660, Text = "X4", Expression = "p0==0", LinkPoint = new ObservableCollection { SFCService.LinkPoint.FirstOrDefault(p => p.Name == "K2_DO") } }; + DiagramViewModel.DirectAddItemCommand.Execute(condition5); + SFCNodeNode step5 = new SFCNodeNode() { Left = 200, Top = 600, Text = "S5" }; DiagramViewModel.DirectAddItemCommand.Execute(step5); - SFCActionNode action5 = new SFCActionNode() { Left = 300, Top = 600, Text = "RES_V3" }; + SFCActionNode action5 = new SFCActionNode() { Left = 300, Top = 600, Text = "RES_V3", Expression = "0", LinkPoint = SFCService.LinkPoint.FirstOrDefault(p => p.Name == "K3_DI") }; DiagramViewModel.DirectAddItemCommand.Execute(action5); - SFCCOEndNode coend = new SFCCOEndNode() { Left = 38, Top = 660, Text = "" }; + SFCConditionNode condition6 = new SFCConditionNode() { Left = 200, Top = 660, Text = "X5", Expression = "p0==0", LinkPoint = new ObservableCollection { SFCService.LinkPoint.FirstOrDefault(p => p.Name == "K3_DO") } }; + DiagramViewModel.DirectAddItemCommand.Execute(condition6); + + SFCCOEndNode coend = new SFCCOEndNode() { Left = 38, Top = 720, Text = "" }; DiagramViewModel.DirectAddItemCommand.Execute(coend); - ConnectorViewModel connector1 = new ConnectorViewModel(start.Output[0], condition1.Input[0]); - DiagramViewModel.DirectAddItemCommand.Execute(connector1); + ConnectorViewModel connector1_1 = new ConnectorViewModel(start.Output[0], condition1_1.Input[0]); + DiagramViewModel.DirectAddItemCommand.Execute(connector1_1); - ConnectorViewModel connector2 = new ConnectorViewModel(condition1.Output[0], step1.Input[0]); - DiagramViewModel.DirectAddItemCommand.Execute(connector2); + ConnectorViewModel connector2_1 = new ConnectorViewModel(condition1_1.Output[0], step1.Input[0]); + DiagramViewModel.DirectAddItemCommand.Execute(connector2_1); + + ConnectorViewModel connector1_2 = new ConnectorViewModel(start.Output[0], condition1_2.Input[0]); + DiagramViewModel.DirectAddItemCommand.Execute(connector1_2); + + ConnectorViewModel connector2_2 = new ConnectorViewModel(condition1_2.Output[0], step1.Input[0]); + DiagramViewModel.DirectAddItemCommand.Execute(connector2_2); ConnectorViewModel connector31 = new ConnectorViewModel(step1.Action[0], action11.Input[0]); DiagramViewModel.DirectAddItemCommand.Execute(connector31); @@ -147,21 +164,27 @@ namespace AIStudio.Wpf.Flowchart ConnectorViewModel connector13 = new ConnectorViewModel(step4.Action[0], action4.Input[0]); DiagramViewModel.DirectAddItemCommand.Execute(connector13); - ConnectorViewModel connector14 = new ConnectorViewModel(cobegin.Output[1], step5.Input[0]); + ConnectorViewModel connector14 = new ConnectorViewModel(step4.Output[0], condition5.Input[0]); DiagramViewModel.DirectAddItemCommand.Execute(connector14); - ConnectorViewModel connector15 = new ConnectorViewModel(step5.Action[0], action5.Input[0]); + ConnectorViewModel connector15 = new ConnectorViewModel(cobegin.Output[1], step5.Input[0]); DiagramViewModel.DirectAddItemCommand.Execute(connector15); - ConnectorViewModel connector16 = new ConnectorViewModel(step4.Output[0], coend.Input[0]); + ConnectorViewModel connector16 = new ConnectorViewModel(step5.Action[0], action5.Input[0]); DiagramViewModel.DirectAddItemCommand.Execute(connector16); - ConnectorViewModel connector17 = new ConnectorViewModel(step5.Output[0], coend.Input[1]); + ConnectorViewModel connector17 = new ConnectorViewModel(step5.Output[0], condition6.Input[0]); DiagramViewModel.DirectAddItemCommand.Execute(connector17); - ConnectorViewModel connector18 = new ConnectorViewModel(coend.Output[0], start.Input[0]); + ConnectorViewModel connector18 = new ConnectorViewModel(condition5.Output[0], coend.Input[0]); DiagramViewModel.DirectAddItemCommand.Execute(connector18); + ConnectorViewModel connector19 = new ConnectorViewModel(condition6.Output[0], coend.Input[1]); + DiagramViewModel.DirectAddItemCommand.Execute(connector19); + + ConnectorViewModel connector20 = new ConnectorViewModel(coend.Output[0], start.Input[0]); + DiagramViewModel.DirectAddItemCommand.Execute(connector20); + #region 模拟部分 TextDesignerItemViewModel despcription = new TextDesignerItemViewModel() { @@ -239,9 +262,29 @@ namespace AIStudio.Wpf.Flowchart DiagramViewModel.ClearSelectedItems(); + SFCService.InitData(DiagramViewModel.Items.OfType().ToList(), DiagramViewModel.Items.OfType().ToList(), DiagramViewModel); + readDataTimer.Elapsed += timeCycle; + readDataTimer.Interval = 1000; + readDataTimer.AutoReset = false; + readDataTimer.Start(); } + private void timeCycle(object sender, ElapsedEventArgs e) + { + if (DiagramViewModel != null) + { + SFCService.Execute(DiagramViewModel); + } + readDataTimer.Start(); + } + public override void Dispose() + { + base.Dispose(); + + readDataTimer.Stop(); + readDataTimer.Dispose(); + } } } diff --git a/AIStudio.Wpf.ADiagram/Views/MainWindow.xaml b/AIStudio.Wpf.ADiagram/Views/MainWindow.xaml index 6e54a69..3b4b94e 100644 --- a/AIStudio.Wpf.ADiagram/Views/MainWindow.xaml +++ b/AIStudio.Wpf.ADiagram/Views/MainWindow.xaml @@ -71,7 +71,7 @@ - + + @@ -322,7 +322,7 @@ SizeDefinition="Middle,Small" Command="{Binding DiagramsViewModel.DiagramViewModel.RedoCommand}"> - @@ -1620,7 +1620,7 @@ - + @@ -1646,7 +1646,7 @@ - + diff --git a/AIStudio.Wpf.Flowchart/FlowchartService.cs b/AIStudio.Wpf.Flowchart/FlowchartService.cs index de69c75..9b9c6e2 100644 --- a/AIStudio.Wpf.Flowchart/FlowchartService.cs +++ b/AIStudio.Wpf.Flowchart/FlowchartService.cs @@ -51,7 +51,7 @@ namespace AIStudio.Wpf.Flowchart /// /// 流程数据 /// - public static List FlowNodes { get; set; } + public static Dictionary> FlowNodes { get; set; } = new Dictionary>(); /// @@ -60,7 +60,7 @@ namespace AIStudio.Wpf.Flowchart /// /// /// - public static void InitData(List oASteps, List connectors) + public static void InitData(List oASteps, List connectors, IDiagramViewModel viewModel) { foreach (var edge in connectors) { @@ -120,8 +120,10 @@ namespace AIStudio.Wpf.Flowchart } string nextstepid = oAStartStep.NextStepId; - FlowNodes = InitStep(oASteps, nextstepid); - FlowNodes.Insert(0, oAStartStep); + var nodes = InitStep(oASteps, nextstepid); + nodes.Insert(0, oAStartStep); + + FlowNodes.Add(viewModel, nodes); Approve(oAStartStep, 100); } @@ -214,13 +216,13 @@ namespace AIStudio.Wpf.Flowchart SetStatus(flowNode, status, remark); if (!string.IsNullOrEmpty(flowNode.NextStepId)) { - Next(flowNode.NextStepId); + Next(flowNode.NextStepId, flowNode); } else if (flowNode.SelectNextStep != null && flowNode.SelectNextStep.Count > 0) { foreach (var step in flowNode.SelectNextStep) { - Next(step.Key); + Next(step.Key, flowNode); } } break; @@ -236,8 +238,8 @@ namespace AIStudio.Wpf.Flowchart break; case 3: SetStatus(flowNode, status, remark); - FlowNodes.ForEach(p => { if (p.Status == 100) p.Status = 0; }); - Approve(FlowNodes[0], 100); + FlowNodes[flowNode.Parent].ForEach(p => { if (p.Status == 100) p.Status = 0; }); + Approve(FlowNodes[flowNode.Parent][0], 100); MessageBox.Show("流程重新开始"); break; case 4: @@ -251,16 +253,16 @@ namespace AIStudio.Wpf.Flowchart /// 流向下一个节点 /// /// - public static void Next(string stepid) + public static void Next(string stepid, FlowNode flowNode) { - FlowNode nextNode = FlowNodes.FirstOrDefault(p => p.Id.ToString() == stepid); + FlowNode nextNode = FlowNodes[flowNode.Parent].FirstOrDefault(p => p.Id.ToString() == stepid); SetStatus(nextNode, 1); switch (nextNode.Kind) { case NodeKinds.Start: SetStatus(nextNode, 100); - Next(nextNode.NextStepId); + Next(nextNode.NextStepId, nextNode); break; case NodeKinds.End: SetStatus(nextNode, 100); @@ -278,33 +280,33 @@ namespace AIStudio.Wpf.Flowchart if (result == 1) { SetStatus(nextNode, 100); - Next(step.Key); + Next(step.Key, nextNode); return; } } catch { } } //如果表达式错了,就按第一个处理 - Next(nextNode.SelectNextStep.FirstOrDefault().Key); + Next(nextNode.SelectNextStep.FirstOrDefault().Key, nextNode); break; case NodeKinds.COBegin: foreach (var step in nextNode.SelectNextStep)//启动各个分支 { SetStatus(nextNode, 100); - Next(step.Key); + Next(step.Key, nextNode); } break; case NodeKinds.COEnd: foreach (var prestep in nextNode.PreStepId) { - var step = FlowNodes.FirstOrDefault(p => p.Id.ToString() == prestep); + var step = FlowNodes[flowNode.Parent].FirstOrDefault(p => p.Id.ToString() == prestep); if (step.Status != 100)//如果并行分支没有都完成,那么并行结束节点也未完成 { return; } } SetStatus(nextNode, 100); - Next(nextNode.NextStepId); + Next(nextNode.NextStepId, nextNode); break; } } @@ -318,7 +320,7 @@ namespace AIStudio.Wpf.Flowchart { if (flowNode.PreStepId != null && flowNode.PreStepId.Count == 1) { - FlowNode preNode = FlowNodes.FirstOrDefault(p => p.Id.ToString() == flowNode.PreStepId[0]); + FlowNode preNode = FlowNodes[flowNode.Parent].FirstOrDefault(p => p.Id.ToString() == flowNode.PreStepId[0]); if (preNode.Kind == NodeKinds.Middle) { SetStatus(preNode, 1); diff --git a/AIStudio.Wpf.Logical/ViewModels/LogicalGateItemViewModel.cs b/AIStudio.Wpf.Logical/ViewModels/LogicalGateItemViewModel.cs index 3bf7fbf..cf942e6 100644 --- a/AIStudio.Wpf.Logical/ViewModels/LogicalGateItemViewModel.cs +++ b/AIStudio.Wpf.Logical/ViewModels/LogicalGateItemViewModel.cs @@ -734,7 +734,7 @@ namespace AIStudio.Wpf.Logical.ViewModels public override void Dispose() { base.Dispose(); - + readDataTimer.Stop(); readDataTimer.Dispose(); } diff --git a/AIStudio.Wpf.SFC/SFCService.cs b/AIStudio.Wpf.SFC/SFCService.cs index ca16358..647c42a 100644 --- a/AIStudio.Wpf.SFC/SFCService.cs +++ b/AIStudio.Wpf.SFC/SFCService.cs @@ -1,6 +1,9 @@ using AIStudio.Wpf.SFC.ViewModels; +using org.mariuszgromada.math.mxparser; using System; using System.Collections.Generic; +using System.Linq; +using System.Windows.Media; using Util.DiagramDesigner; namespace AIStudio.Wpf.SFC @@ -27,15 +30,179 @@ namespace AIStudio.Wpf.SFC LinkPoint.Add(new LinkPoint { Id = Guid.NewGuid(), Name = "T3", Despcription = "容器3液位", Value = 20 }); } + /// + /// 流程数据 + /// + public static Dictionary> SFCNodes { get; set; } = new Dictionary>(); + /// /// 初始化数据 /// /// /// /// - public static void InitData(List oASteps, List connectors) + public static void InitData(List nodes, List connectors, IDiagramViewModel viewModel) { - + var start = nodes.FirstOrDefault(p => p.Kind == SFCNodeKinds.Start); + if (start == null) + throw new Exception("没有开始节点"); + + foreach (var edge in connectors) + { + var source = nodes.FirstOrDefault(p => p.BottomConnector == edge.SourceConnectorInfo || p.LeftConnector == edge.SourceConnectorInfo || p.RightConnector == edge.SourceConnectorInfo || p.TopConnector == edge.SourceConnectorInfo); + if (source != null) + { + source.NextNode.Add((edge.SinkConnectorInfo as FullyCreatedConnectorInfo).DataItem as SFCNode); + ((edge.SinkConnectorInfo as FullyCreatedConnectorInfo).DataItem as SFCNode).PreNode.Add(source); + } + } + + SFCNodes.Add(viewModel, nodes); + ResetStatus(viewModel); + } + + private static void ResetStatus(IDiagramViewModel viewModel) + { + var nodes = SFCNodes[viewModel]; + var start = nodes.FirstOrDefault(p => p.Kind == SFCNodeKinds.Start); + + SetStatus(start, 1); + nodes.ForEach(p => + { + if (p != start) + { + SetStatus(p, 0); + } + }); + } + + public static void Execute(IDiagramViewModel viewModel) + { + //仅T2进行计算 + var tank = SFCNodes[viewModel].OfType().FirstOrDefault(p => p.Text == "T2"); + tank.Execute(); + + var startbtn = SFCNodes[viewModel].OfType().FirstOrDefault(); + if (startbtn != null && startbtn.LinkPoint.Value == 0)//停止 + { + ResetStatus(viewModel); + + //关闭所有阀门 + foreach (var node in SFCNodes[viewModel].OfType()) + { + if (node.DILinkPoint != null) + { + node.DILinkPoint.Value = 0; + } + } + + //真实情况不会改变容器液位,只是为了模拟重新启动时候为了低液位处理的 + //tank.LinkPoint.Value = 0; + } + else//启动 + { + var currentNodes = SFCNodes[viewModel].Where(p => p.Status == 1); + foreach (var node in currentNodes) + { + if (node.NextNode.OfType().Count() > 1)//选择分支 + { + foreach (var next in node.NextNode) + { + if (next is SFCConditionNode nextconditionNode) + { + List args = new List(); + for (int i = 0; i < nextconditionNode.LinkPoint.Count; i++) + { + Argument x = new Argument($"p{i}", nextconditionNode.LinkPoint[i].Value); + args.Add(x); + } + Expression e = new Expression(nextconditionNode.Expression, args.ToArray()); + var result = e.calculate(); + if (result == 0) + { + continue; + } + + SetStatus(node, 100); + SetStatus(next, 1); + break; + } + } + } + else + { + if (node is SFCConditionNode conditionNode) + { + List args = new List(); + for (int i = 0; i < conditionNode.LinkPoint.Count; i++) + { + Argument x = new Argument($"p{i}", conditionNode.LinkPoint[i].Value); + args.Add(x); + } + Expression e = new Expression(conditionNode.Expression, args.ToArray()); + var result = e.calculate(); + if (result == 0) + { + continue; + } + } + else if (node is SFCActionNode actionNode) + { + if (actionNode.LinkPoint != null) + { + Expression e = new Expression(actionNode.Expression); + actionNode.LinkPoint.Value = e.calculate(); + SetStatus(actionNode, 100); + } + } + else if (node is SFCCOEndNode cOEndNode) + { + //并行结束节点需要前面节点都完成 + if (cOEndNode.PreNode.Any(p => p.Status != 100)) + { + continue; + } + } + + + SetStatus(node, 100); + foreach (var next in node.NextNode) + { + if (next is SFCStartNode startNode) + { + ResetStatus(viewModel); + } + else + { + SetStatus(next, 1); + } + } + } + } + } + } + + /// + /// 设置颜色 + /// + /// + /// + /// + public static void SetStatus(SFCNode node, int status) + { + node.Status = status; + switch (status) + { + case 100: + node.ColorViewModel.FillColor.Color = Colors.Gray; + break; + case 0: + node.ColorViewModel.FillColor.Color = Colors.Blue; + break; + case 1: + node.ColorViewModel.FillColor.Color = Colors.Green; + break; + } } } } diff --git a/AIStudio.Wpf.SFC/ViewModels/SFCNode.cs b/AIStudio.Wpf.SFC/ViewModels/SFCNode.cs index 77ed75a..7e98e40 100644 --- a/AIStudio.Wpf.SFC/ViewModels/SFCNode.cs +++ b/AIStudio.Wpf.SFC/ViewModels/SFCNode.cs @@ -135,5 +135,19 @@ namespace AIStudio.Wpf.SFC.ViewModels SetProperty(ref _value, value); } } + + private int _status; + + public int Status + { + get { return _status; } + set + { + SetProperty(ref _status, value); + } + } + + public List NextNode { get; set; } = new List(); + public List PreNode { get; set; } = new List(); } } diff --git a/AIStudio.Wpf.SFC/ViewModels/SFCNode.xaml b/AIStudio.Wpf.SFC/ViewModels/SFCNode.xaml index a49588f..a7aa60b 100644 --- a/AIStudio.Wpf.SFC/ViewModels/SFCNode.xaml +++ b/AIStudio.Wpf.SFC/ViewModels/SFCNode.xaml @@ -33,9 +33,9 @@ - + - + @@ -75,6 +75,7 @@ + @@ -242,11 +243,12 @@ ItemsSource="{Binding LinkPoint}" AlternationCount="{Binding LinkPoint.Count}" Background="{DynamicResource Fluent.Ribbon.Brushes.AccentBaseColorBrush}"> - + - + + diff --git a/AIStudio.Wpf.SFC/ViewModels/Simulate_SolenoidViewModel.cs b/AIStudio.Wpf.SFC/ViewModels/Simulate_SolenoidViewModel.cs index 0b709fd..dfc4d78 100644 --- a/AIStudio.Wpf.SFC/ViewModels/Simulate_SolenoidViewModel.cs +++ b/AIStudio.Wpf.SFC/ViewModels/Simulate_SolenoidViewModel.cs @@ -46,7 +46,26 @@ namespace AIStudio.Wpf.SFC.ViewModels } set { + if (_dILinkPoint != null) + { + _dILinkPoint.PropertyChanged -= _dILinkPoint_PropertyChanged; + } SetProperty(ref _dILinkPoint, value); + if (_dILinkPoint != null) + { + _dILinkPoint.PropertyChanged += _dILinkPoint_PropertyChanged; + } + } + } + + private void _dILinkPoint_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + if (e.PropertyName == "Value") + { + if (DOLinkPoint != null) + { + DOLinkPoint.Value = DILinkPoint.Value; + } } } diff --git a/AIStudio.Wpf.SFC/ViewModels/Simulate_TankViewModel.cs b/AIStudio.Wpf.SFC/ViewModels/Simulate_TankViewModel.cs index ac4018e..91f97c7 100644 --- a/AIStudio.Wpf.SFC/ViewModels/Simulate_TankViewModel.cs +++ b/AIStudio.Wpf.SFC/ViewModels/Simulate_TankViewModel.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text; using Util.DiagramDesigner; @@ -68,5 +69,15 @@ namespace AIStudio.Wpf.SFC.ViewModels this.LinkPoint = data.LinkPoint; } } + + public void Execute() + { + double input = PreNode.OfType().Sum(p => p.DOLinkPoint?.Value ?? 0); + double output = NextNode.OfType().Sum(p => p.DOLinkPoint?.Value ?? 0); + if (LinkPoint != null) + { + LinkPoint.Value += input - output; + } + } } }