临时保存

添加仿真内容
修改旧的仿真调用
This commit is contained in:
hanqiangqiang 2026-07-07 14:58:23 +08:00
parent d930588fc2
commit 9ccbb49746
10 changed files with 952 additions and 25 deletions

View File

@ -1,13 +1,17 @@
using System; using Aitex.Common.Util;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.IOCore; using Aitex.Core.RT.IOCore;
using Aitex.Core.RT.Log; using Aitex.Core.RT.Log;
using Aitex.Core.Util; using Aitex.Core.Util;
using Aitex.Core.WCF; using Aitex.Core.WCF;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.PLC; using MECF.Framework.Common.PLC;
using MECF.Framework.Simulator.Core;
using SicSimulator.Views; using SicSimulator.Views;
using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using System.Threading.Tasks;
namespace SicSimulator.Instances namespace SicSimulator.Instances
{ {
@ -32,6 +36,10 @@ namespace SicSimulator.Instances
WcfServiceManager.Instance.Initialize(new Type[] { typeof(SimulatorAdsPlcService) }); WcfServiceManager.Instance.Initialize(new Type[] { typeof(SimulatorAdsPlcService) });
//Singleton<SimulatorDeviceManager>.Instance.Initialize(PathManager.GetCfgDir() + "DevicePM.xml", "GaN", ModuleName.PM1, "PM1");
//Singleton<SimulatorDeviceManager>.Instance.Initialize(PathManager.GetCfgDir() + "DevicePM.xml", "GaN", ModuleName.PM2, "PM2");
//Singleton<SimulatorDeviceManager>.Instance.Initialize(PathManager.GetCfgDir() + "DeviceTM.xml", "GaN", ModuleName.TM, "TM");
_thread = new PeriodicJob(200, OnMonitor, nameof(SimulatorSystem), true); _thread = new PeriodicJob(200, OnMonitor, nameof(SimulatorSystem), true);
} }
@ -350,34 +358,34 @@ namespace SicSimulator.Instances
try try
{ {
MonitorPressureTM(); MonitorPressureTM();
MonitorPressureLoad(); //MonitorPressureLoad();
MonitorPressureUnLoad(); //MonitorPressureUnLoad();
MonitorSlitValveFlow(); //MonitorSlitValveFlow();
MonitorTMValve(); //MonitorTMValve();
MonitorPm("PM1"); MonitorPm("PM1");
MonitorPm("PM2"); MonitorPm("PM2");
MonitorValve("PM1"); MonitorValve("PM1");
MonitorValve("PM2"); MonitorValve("PM2");
MonitorFlowRamp("PM1"); //MonitorFlowRamp("PM1");
//MonitorFlowRamp("PM2"); //MonitorFlowRamp("PM2");
MonitorGasConnector("PM1"); //MonitorGasConnector("PM1");
MonitorLid("PM1"); //MonitorLid("PM1");
MonitorLidSwing("PM1"); //MonitorLidSwing("PM1");
MonitorConfinementRing("PM1"); //MonitorConfinementRing("PM1");
MonitorGasConnector("PM2"); //MonitorGasConnector("PM2");
MonitorLid("PM2"); //MonitorLid("PM2");
MonitorLidSwing("PM2"); //MonitorLidSwing("PM2");
MonitorConfinementRing("PM2"); //MonitorConfinementRing("PM2");
MonitorChamberMoveBody("PM1"); //MonitorChamberMoveBody("PM1");
MonitorChamberMoveBodyUp("PM1"); //MonitorChamberMoveBodyUp("PM1");
MonitorHeater("PM1"); //MonitorHeater("PM1");
MonitorRotation("PM1"); //MonitorRotation("PM1");
MonitorChamberMoveBody("PM2"); //MonitorChamberMoveBody("PM2");
MonitorChamberMoveBodyUp("PM2"); //MonitorChamberMoveBodyUp("PM2");
MonitorHeater("PM2"); //MonitorHeater("PM2");
MonitorRotation("PM2"); //MonitorRotation("PM2");
} }
catch (Exception e) catch (Exception e)
{ {
@ -915,6 +923,266 @@ namespace SicSimulator.Instances
} }
private void PmMotion(string pm)
{
IO.DI[$"{pm}.DI_PMSlitValveCloseCompleted"].Value = IO.DI[$"TM.DI_PM{(pm == "PM1" ? "A" : "B")}SlitValveClose"].Value;
IO.DI[$"{pm}.DI_LockingCylinderLock"].Value = !IO.DO[$"{pm}.DO_LockingCylinderLockUnlock"].Value;
if (IO.DO[$"{pm}.DO_ChamLidMotorAUp"].Value)
{
IO.DI[$"{pm}.DI_PMChamberLidDownpositioning"].Value = true;
Task.Delay(2000).ContinueWith(x =>
{
IO.DI[$"{pm}.DI_PMChamberLidUppositioning"].Value = false;
});
}
if (IO.DO[$"{pm}.DO_ChamLidMotorADown"].Value)
{
IO.DI[$"{pm}.DI_PMChamberLidUppositioning"].Value = true;
Task.Delay(2000).ContinueWith(x =>
{
IO.DI[$"{pm}.DI_PMChamberLidDownpositioning"].Value = false;
});
}
DelaySetDoToDi(pm, "DI_PMChamberLidTighten", "DO_ChamLidTighten");
DelaySetDoToDi(pm, "DI_PMChamberLidLoosen", "DO_ChamLidLoosen");
DelaySetDoToDi(pm, "DI_PMChamberLidSwingLock", "DO_ChamLidSwingLock");
DelaySetDoToDi(pm, "DI_PMChamberLidSwingUnLock", "DO_ChamLidSwingUnLock");
DelaySetDoToDi(pm, "DI_PMChamberLidLock", "DO_ChamLidLockPL");
DelaySetDoToDi(pm, "DI_PMChamberLidUnLock", "DO_ChamLidUnLockPL");
//磁流体仿真
int temp = pm == "PM1" ? 0 : 1;
if (!_pre_DO_SpindleHome[temp] && IO.DO[$"{pm}.DO_SpindleHome"].Value)
{
IO.DI[$"{pm}.DI_SpindleHomeFinish"].Value = false;
Task.Delay(1000).ContinueWith(x =>
{
IO.AI[$"{pm}.AI_SpindleCurrentPosition"].Value = 0;
IO.DI[$"{pm}.DI_SpindleHomeFinish"].Value = true;
});
}
_pre_DO_SpindleHome[temp] = IO.DO[$"{pm}.DO_SpindleHome"].Value;
if (!_pre_DO_SpindleLoadAngleRun[temp] && IO.DO[$"{pm}.DO_SpindleLoadAngleRun"].Value)
{
IO.DI[$"{pm}.DI_SpindlePositionComplete"].Value = false;
Task.Delay(2000).ContinueWith(x =>
{
IO.AI[$"{pm}.AI_SpindleCurrentPosition"].Value += IO.AO[$"{pm}.AO_SpindleLoadAngle"].Value;
if (IO.AI[$"{pm}.AI_SpindleCurrentPosition"].Value >= 360)
{
IO.AI[$"{pm}.AI_SpindleCurrentPosition"].Value -= 360;
}
IO.DI[$"{pm}.DI_SpindlePositionComplete"].Value = true;
});
}
_pre_DO_SpindleLoadAngleRun[temp] = IO.DO[$"{pm}.DO_SpindleLoadAngleRun"].Value;
if (!_pre_DO_SpindleMoveSlot[temp] && IO.DO[$"{pm}.DO_SpindleMoveSlot"].Value)
{
IO.AI[$"{pm}.AI_SpindleActualSlot"].Value = 0;
Task.Delay(2000).ContinueWith(x =>
{
var s = (int)IO.AO[$"{pm}.AO_SpindleSlot"].Value;
if (s > 0 && s < 9)
{
IO.AI[$"{pm}.AI_SpindleCurrentPosition"].Value = IO.AO[$"{pm}.AO_SpindlePosition{s}"].Value;
IO.AI[$"{pm}.AI_SpindleActualSlot"].Value = s;
}
});
}
_pre_DO_SpindleMoveSlot[temp] = IO.DO[$"{pm}.DO_SpindleMoveSlot"].Value;
//shutter仿真
if (IO.DO[$"{pm}.DO_ShutterUp"].Value)
{
Task.Delay(2000).ContinueWith(x =>
{
IO.DI[$"{pm}.DI_ShutterUp"].Value = true;
IO.DI[$"{pm}.DI_ShutterDown"].Value = false;
});
}
if (IO.DO[$"{pm}.DO_ShutterDown"].Value)
{
Task.Delay(2000).ContinueWith(x =>
{
IO.DI[$"{pm}.DI_ShutterUp"].Value = false;
IO.DI[$"{pm}.DI_ShutterDown"].Value = true;
});
}
if (IO.DO[$"{pm}.DO_ShutterForward"].Value)
{
Task.Delay(2000).ContinueWith(x =>
{
IO.DI[$"{pm}.DI_ShutterForward"].Value = true;
IO.DI[$"{pm}.DI_ShutterBackward"].Value = false;
});
}
if (IO.DO[$"{pm}.DO_ShutterBackward"].Value)
{
Task.Delay(2000).ContinueWith(x =>
{
IO.DI[$"{pm}.DI_ShutterForward"].Value = false;
IO.DI[$"{pm}.DI_ShutterBackward"].Value = true;
});
}
////V99仿真
//if (IO.DO[$"{pm}.DO_PMPressureRelief"].Value && !IO.DO[$"{pm}.DO_PMPressureReliefClose"].Value)
//{
// IO.DI[$"{pm}.DI_PMPressureReliefOpenFB"].Value = true;
// IO.DI[$"{pm}.DI_PMPressureReliefCloseFB"].Value = false;
//}
//if (IO.DO[$"{pm}.DO_PMPressureReliefClose"].Value && !IO.DO[$"{pm}.DO_PMPressureRelief"].Value)
//{
// IO.DI[$"{pm}.DI_PMPressureReliefOpenFB"].Value = false;
// IO.DI[$"{pm}.DI_PMPressureReliefCloseFB"].Value = true;
//}
}
private void DelaySetDoToDi(string pm, string diName, string doName)
{
if (!IO.DO[$"{pm}.{doName}"].Value)
{
IO.DI[$"{pm}.{diName}"].Value = false;
return;
}
if (IO.DI[$"{pm}.{diName}"].Value != IO.DO[$"{pm}.{doName}"].Value)
{
Task.Delay(2000).ContinueWith(x =>
{
IO.DI[$"{pm}.{diName}"].Value = IO.DO[$"{pm}.{doName}"].Value;
});
}
}
private void MonitorTVPm(string pm)
{
IO.AI[$"{pm}.AI_ButterflyValveActualMode"].Value = IO.AO[$"{pm}.AO_ButterflyValveSetMode"].Value;
//IO.AI[$"{pm}.AI_HeartBeat"].Value = IO.AO[$"{pm}.AO_HeartBeat"].Value;
IO.AI[$"{pm}.AI_ButterflyValveActualPosition"].Value = IO.AO[$"{pm}.AO_ButterflyValveSetPosition"].Value;
var mode = IO.AO[$"{pm}.AO_ButterflyValveSetMode"].Value;
//蝶阀开启,跟着蝶阀的设置值走
if (IO.DO[$"{pm}.DO_ButterflyEnable"].Value)
{
if (mode == 5)
{
if (IO.AI[$"{pm}.AI_ButterflyValveActualPressure"].Value > IO.AO[$"{pm}.AO_ButterflyValveSetPressure"].Value)
{
if (IO.AI[$"{pm}.AI_ButterflyValveActualPressure"].Value - 30 > IO.AO[$"{pm}.AO_ButterflyValveSetPressure"].Value)
{
IO.AI[$"{pm}.AI_ButterflyValveActualPressure"].Value -= 30;
}
else
{
IO.AI[$"{pm}.AI_ButterflyValveActualPressure"].Value = IO.AO[$"{pm}.AO_ButterflyValveSetPressure"].Value;
}
}
else if (IO.AI[$"{pm}.AI_ButterflyValveActualPressure"].Value < IO.AO[$"{pm}.AO_ButterflyValveSetPressure"].Value)
{
if (IO.AI[$"{pm}.AI_ButterflyValveActualPressure"].Value + 10 < IO.AO[$"{pm}.AO_ButterflyValveSetPressure"].Value)
{
IO.AI[$"{pm}.AI_ButterflyValveActualPressure"].Value += 10;
}
else
{
IO.AI[$"{pm}.AI_ButterflyValveActualPressure"].Value = IO.AO[$"{pm}.AO_ButterflyValveSetPressure"].Value;
}
}
IO.AI[$"{pm}.AI_PMChamberPressure"].Value = IO.AI[$"{pm}.AI_ButterflyValveActualPressure"].Value;
}
if (mode == 2)
{
if (IO.AO[$"{pm}.AO_ButterflyValveSetPosition"].Value > 0)
{
if (IO.AI[$"{pm}.AI_ButterflyValveActualPressure"].Value > 0)
{
IO.AI[$"{pm}.AI_ButterflyValveActualPressure"].Value -= (IO.AO[$"{pm}.AO_ButterflyValveSetPosition"].Value) / 8;
}
else
IO.AI[$"{pm}.AI_ButterflyValveActualPressure"].Value = 0;
}
IO.AI[$"{pm}.AI_PMChamberPressure"].Value = IO.AI[$"{pm}.AI_ButterflyValveActualPressure"].Value;
}
}
else
{
bool fontMfc = false;
for (int i = 70; i <= 89; i++)
{
if (IO.AI[$"{pm}.AI_M{i}"].Value > 100)
{
fontMfc = true;
continue;
}
}
if (fontMfc)
{
if (IO.AI[$"{pm}.AI_ButterflyValveActualPressure"].Value < 1200)
{
IO.AI[$"{pm}.AI_ButterflyValveActualPressure"].Value += 10;
}
IO.AI[$"{pm}.AI_PMChamberPressure"].Value = IO.AI[$"{pm}.AI_ButterflyValveActualPressure"].Value;
}
}
//蝶阀Ramp有Bug,设置AO值可以化解
//if (IO.AI[$"{pm}.AI_ButterflyValveActualPressure"].Value >= 1100)
//{
// IO.AO[$"{pm}.AO_ButterflyValveSetPressure"].Value = IO.AI[$"{pm}.AI_ButterflyValveActualPressure"].Value;
//}
//string s = pm == "PM1" ? "A" : "B";
//if (IO.DI[$"TM.DI_TMPM{s}BanlanceFB"].Value || IO.DI[$"TM.DI_PM{s}GateValveOpen"].Value)
//{
// var v1 = IO.AI[$"{pm}.AI_PMChamberPressure"].Value;
// var v2 = IO.AI[$"TM.AI_TMChamberPressure"].Value;
// if (v1 > v2)
// {
// IO.AI[$"TM.AI_TMChamberPressure"].Value = v1;
// }
// else
// {
// IO.AI[$"{pm}.AI_PMChamberPressure"].Value = v2;
// }
//}
//else
// IO.AI[$"{pm}.AI_PMChamberPressure"].Value = IO.AI[$"{pm}.AI_ButterflyValveActualPressure"].Value;
//V27自动打开
//if (IO.AI[$"{pm}.AI_ChamPress"].Value > 1020 && IO.DO[$"{pm}.DO_PumpBypass(V27)"].Value != true)
//{
// IO.DO[$"{pm}.DO_PumpBypass(V27)"].Value = true;
//}
//if (IO.AI[$"{pm}.AI_ChamPress"].Value < 900 && IO.DO[$"{pm}.DO_PumpBypass(V27)"].Value)
//{
// IO.DO[$"{pm}.DO_PumpBypass(V27)"].Value = false;
//}
if (IO.DO[$"{pm}.DO_SpindleSpeedRun"].Value)
{
IO.AI[$"{pm}.AI_SpindleCurrentSpeed"].Value = IO.AO[$"{pm}.AO_SpindleVelocity"].Value;
}
else
IO.AI[$"{pm}.AI_SpindleCurrentSpeed"].Value = 0;
//设置PT2的压力比PT1的小20
var pt2 = IO.AI[$"{pm}.AI_PMChamberPressure"].Value - 20;
if (pt2 > 0)
{
IO.AI[$"{pm}.AI_ColdtrapExitPressure"].Value = pt2;
}
IO.AI[$"{pm}.AI_ColdtrapExitPressure"].Value = IO.AI[$"{pm}.AI_PMChamberPressure"].Value - 20 > 0 ? IO.AI[$"{pm}.AI_PMChamberPressure"].Value - 20 : 0;
}
private void MonitorValve(string pm) private void MonitorValve(string pm)
{ {

View File

@ -0,0 +1,80 @@
using Aitex.Core.RT.Device;
using Aitex.Core.RT.IOCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace MECF.Framework.Simulator.Core
{
public class SimulatorAI_AORandom : BaseDevice, IDevice
{
protected List<AI_AORandomData> AI_AOList = new List<AI_AORandomData>();
private readonly Random _rnd = new Random();
public SimulatorAI_AORandom(string module, XmlElement node, string ioModule = "") : base(module, node, ioModule)
{
InitializeIValve(node);
}
/// <summary>
/// 根据XML配置创建MFC控制对象
/// </summary>
/// <param name="node"></param>
protected virtual void InitializeIValve(XmlElement node)
{
XmlNodeList valveNodes = node.GetElementsByTagName("Random");
foreach (XmlElement xmlElement in valveNodes)
{
AI_AORandomData randomData = new AI_AORandomData()
{
Type = xmlElement.GetAttribute("type"),
Name = xmlElement.GetAttribute("ioName"),
BaseValue = Convert.ToSingle(xmlElement.GetAttribute("baseValue"))
};
AI_AOList.Add(randomData);
}
}
protected override void HandleMonitor()
{
Random();
}
protected virtual void Random()
{
foreach (var ai_ao in AI_AOList)
{
if (ai_ao.Type == "AI")
IO.AI[$"{Module}.{ai_ao.Name}"].Value = ai_ao.BaseValue + (float)_rnd.NextDouble();
else if (ai_ao.Type == "AO")
IO.AO[$"{Module}.{ai_ao.Name}"].Value = ai_ao.BaseValue + (float)_rnd.NextDouble();
}
}
public bool Initialize()
{
return true;
}
public void Reset()
{
}
public void Terminate()
{
}
}
public class AI_AORandomData
{
public string Type { get; set; }
public string Name { get; set; }
public float BaseValue { get; set; }
}
}

View File

@ -0,0 +1,188 @@
using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using Aitex.Core.Util;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Utilities;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
namespace MECF.Framework.Simulator.Core
{
public class SimulatorDeviceManager
{
private readonly Dictionary<string, IDevice> _nameDevice = new Dictionary<string, IDevice>();
private readonly object _lockerDevice = new object();
private readonly R_TRIG _trigExceed500 = new R_TRIG();
private readonly Dictionary<Type, List<IDevice>> _typeDevice = new Dictionary<Type, List<IDevice>>();
private readonly ConcurrentBag<IDevice> _optionDevice = new ConcurrentBag<IDevice>();
private PeriodicJob _thread;
/// <summary>
/// 设置或返回是否以异步方式初始化当前管理器中的设备。
/// </summary>
public bool DisableAsyncInitialize { get; set; }
/// <summary>
/// 返回当前设备管理器映射的XML配置文件节点。
/// </summary>
protected XmlElement DeviceModelNodes { get; private set; }
/// <summary>
/// 向设备管理器的设备字典中添加一个设备实例。
/// </summary>
/// <param name="device"></param>
protected virtual void QueueDevice(IDevice device)
{
QueueDevice($"{device.Module}.{device.Name}", device);
}
/// <summary>
/// 向设备管理器的设备字典中添加一个设备实例并自定义该设备在字典中的Key。
/// </summary>
/// <param name="key"></param>
/// <param name="device"></param>
protected void QueueDevice(string key, IDevice device)
{
lock (_lockerDevice)
{
Debug.Assert(!_nameDevice.ContainsKey(key), "DeviceModel config file contains duplicated name " + key);
_nameDevice.Add(key, device);
}
}
public void Initialize(string modelFile, string type, ModuleName mod, string ioModule = "")
{
if (!File.Exists(modelFile))
{
throw new ApplicationException($"did not find the device model file {modelFile} ");
}
var xmlDocument = new XmlDocument();
try
{
xmlDocument.Load(modelFile);
if (!(xmlDocument.SelectSingleNode("DeviceModelDefine") is XmlElement xmlElement))
{
throw new ApplicationException($"device mode file {modelFile} is not valid");
}
var attribute = xmlElement.GetAttribute("type");
if (attribute != type)
{
throw new ApplicationException($"the type {attribute} in device mode file {modelFile} is inaccordance with the system type {type}");
}
DeviceModelNodes = xmlElement;
foreach (XmlNode childNode in xmlElement.ChildNodes)
{
if (childNode.NodeType == XmlNodeType.Comment || !(childNode is XmlElement xmlElement2))
{
continue;
}
var text = xmlElement2.GetAttribute("assembly");
if (string.IsNullOrEmpty(text))
{
text = "MECF.Framework.RT.EquipmentLibrary";
}
var text2 = xmlElement2.Name.Substring(0, xmlElement2.Name.Length - 1);
var text3 = xmlElement2.GetAttribute("classType");
if (string.IsNullOrEmpty(text3))
{
text3 = "Aitex.Core.RT.Device.Unit." + text2;
}
var assembly = Assembly.Load(text);
var type2 = assembly.GetType(text3);
if (type2 == null)
{
continue;
}
foreach (var childNode2 in xmlElement2.ChildNodes)
{
if (!(childNode2 is XmlElement xmlElement3))
{
LOG.Write("Device Model File contains non element node, " + (childNode2 as XmlNode).Value);
continue;
}
var device = Activator.CreateInstance(type2, mod.ToString(), xmlElement3, ioModule) as IDevice;
if (xmlElement3.HasAttribute("option") && Convert.ToBoolean(xmlElement3.Attributes["option"].Value))
{
_optionDevice.Add(device);
continue;
}
QueueDevice(device);
DATA.Subscribe(device, $"{device.Module}.{text2}.{device.Name}");
if (!_typeDevice.ContainsKey(type2))
{
_typeDevice[type2] = new List<IDevice>();
}
_typeDevice[type2].Add(device);
if (DisableAsyncInitialize)
{
InitDevice(device);
continue;
}
var task = Task.Run(delegate
{
InitDevice(device);
});
}
}
_thread = new PeriodicJob(200, Monitor, "SimulatorSystem", true);
}
catch (Exception ex)
{
LOG.Write(ex);
}
}
private void InitDevice(IDevice device)
{
try
{
if (!device.Initialize())
{
LOG.Write(device.Name + " initialize failed.");
}
}
catch (Exception ex)
{
LOG.Write(ex);
}
}
/// <summary>
/// 后台扫面线程调用的方法。
/// </summary>
public bool Monitor()
{
lock (_lockerDevice)
{
foreach (var value in _nameDevice.Values)
{
try
{
PerformanceMonitor.MonitorRun(() =>
{
value.Monitor();
return true;
}, 500, _trigExceed500, out _, $"{value.Module}.{value.Name} monitor");
}
catch (Exception ex)
{
LOG.Write(ex, $"{ModuleName.Diagnosis} Monitor {value.Name} Exception");
}
}
}
return true;
}
}
}

View File

@ -0,0 +1,70 @@
using Aitex.Core.RT.Device;
using Aitex.Core.RT.IOCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace MECF.Framework.Simulator.Core
{
public class SimulatorIoAO_AI : BaseDevice, IDevice
{
protected Dictionary<string, string> AO_AI = new Dictionary<string, string>();
public SimulatorIoAO_AI(string module, XmlElement node, string ioModule) : base(module, node, ioModule)
{
InitializeIValve(node);
}
/// <summary>
/// 根据XML配置创建气阀控制对象
/// </summary>
/// <param name="node"></param>
protected virtual void InitializeIValve(XmlElement node)
{
XmlNodeList valveNodes = node.GetElementsByTagName("AO_AI");
foreach (XmlElement xmlElement in valveNodes)
{
string aiName = xmlElement.GetAttribute("ai");
string aoName = xmlElement.GetAttribute("ao");
if (!AO_AI.ContainsKey(aiName) && !AO_AI.ContainsKey(aoName))
AO_AI.Add(aiName, aoName);
var isDefaultOpen = xmlElement.GetAttribute("aoDefault");
if (!String.IsNullOrWhiteSpace(isDefaultOpen))
IO.AO[$"{Module}.{aoName}"].Value = Convert.ToSingle(isDefaultOpen);
}
}
protected override void HandleMonitor()
{
DoValueToDI();
}
protected void DoValueToDI()
{
foreach (var ai_ao in AO_AI)
{
IO.AI[$"{Module}.{ai_ao.Key}"].Value = IO.AO[$"{Module}.{ai_ao.Value}"].Value;
}
}
public bool Initialize()
{
return true;
}
public void Reset()
{
}
public void Terminate()
{
}
}
}

View File

@ -0,0 +1,39 @@
using Aitex.Core.RT.IOCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace MECF.Framework.Simulator.Core
{
public class SimulatorIoDO_DI : SimulatorIoValve
{
public SimulatorIoDO_DI(string module, XmlElement node, string ioModule) : base(module, node, ioModule)
{
}
/// <summary>
/// 根据XML配置创建气阀控制对象
/// </summary>
/// <param name="node"></param>
protected override void InitializeIValve(XmlElement node)
{
XmlNodeList valveNodes = node.GetElementsByTagName("DO_DI");
foreach (XmlElement xmlElement in valveNodes)
{
string diName = xmlElement.GetAttribute("di");
string doName = xmlElement.GetAttribute("do");
if (!DI_DOList.ContainsKey(diName) && !DI_DOList.ContainsKey(doName))
DI_DOList.Add(diName, doName);
var isDefaultOpen = xmlElement.GetAttribute("doDefault");
if (!String.IsNullOrWhiteSpace(isDefaultOpen))
IO.DO[$"{Module}.{doName}"].Value = Convert.ToBoolean(isDefaultOpen);
}
}
}
}

View File

@ -0,0 +1,73 @@
using Aitex.Core.RT.Device;
using Aitex.Core.RT.IOCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
namespace MECF.Framework.Simulator.Core
{
public class SimulatorIoDefault : BaseDevice, IDevice
{
protected Dictionary<string, object> IO_ValueList = new Dictionary<string, object>();
private readonly Random _rnd = new Random();
public SimulatorIoDefault(string module, XmlElement node, string ioModule = "") : base(module, node, ioModule)
{
InitializeIValve(node);
}
/// <summary>
/// 根据XML配置创建IO对象初始默认值
/// </summary>
/// <param name="node"></param>
protected virtual void InitializeIValve(XmlElement node)
{
XmlNodeList valveNodes = node.GetElementsByTagName("IODefault");
foreach (XmlElement xmlElement in valveNodes)
{
string type = xmlElement.GetAttribute("type");
string ioName = xmlElement.GetAttribute("ioName");
string value = xmlElement.GetAttribute("default");
switch (type)
{
case "DI":
IO.DI[$"{Module}.{ioName}"].Value = Convert.ToBoolean(value);
break;
case "DO":
IO.DO[$"{Module}.{ioName}"].Value = Convert.ToBoolean(value);
break;
case "AI":
IO.AI[$"{Module}.{ioName}"].Value = Convert.ToSingle(value);
break;
case "AO":
IO.AO[$"{Module}.{ioName}"].Value = Convert.ToSingle(value);
break;
}
}
}
public bool Initialize()
{
return true;
}
public void Reset()
{
}
public void Terminate()
{
}
}
}

View File

@ -0,0 +1,92 @@
using Aitex.Core.RT.Device;
using Aitex.Core.RT.IOCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace MECF.Framework.Simulator.Core
{
public class SimulatorMFC : BaseDevice, IDevice
{
protected Dictionary<string, string> AI_AOList = new Dictionary<string, string>();
private readonly Random _rnd = new Random();
public SimulatorMFC(string module, XmlElement node, string ioModule = "") : base(module, node, ioModule)
{
InitializeIValve(node);
}
/// <summary>
/// 根据XML配置创建MFC控制对象
/// </summary>
/// <param name="node"></param>
protected virtual void InitializeIValve(XmlElement node)
{
XmlNodeList valveNodes = node.GetElementsByTagName("IoMfc");
foreach (XmlElement xmlElement in valveNodes)
{
string aiFlow = xmlElement.GetAttribute("aiFlow");
string aoFlow = xmlElement.GetAttribute("aoFlow");
if (!AI_AOList.ContainsKey(aiFlow) && !AI_AOList.ContainsKey(aoFlow))
AI_AOList.Add(aiFlow, aoFlow);
}
}
protected override void HandleMonitor()
{
Ramp();
}
protected virtual void Ramp()
{
foreach (var ai_ao in AI_AOList)
{
float setpoint = 0;
float result = 0;
float current = 0;
if (IO.AI[$"{Module}.{ai_ao.Key}"] != null)
{
current = IO.AI[$"{Module}.{ai_ao.Key}"].Value;
setpoint = IO.AO[$"{Module}.{ai_ao.Value}"].Value;
}
if (current >= setpoint)
{
result = current - 50;
if (result < setpoint)
result = setpoint;
}
if (current < setpoint)
{
result = current + 50;
if (result > setpoint)
result = setpoint;
}
result = result + (float)_rnd.NextDouble();
IO.AI[$"{Module}.{ai_ao.Key}"].Value = result;
}
}
public bool Initialize()
{
return true;
}
public void Reset()
{
}
public void Terminate()
{
}
}
}

View File

@ -0,0 +1,40 @@
using Aitex.Core.RT.Device;
using Aitex.Core.RT.IOCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace MECF.Framework.Simulator.Core
{
public class SimulatorPressure : SimulatorMFC
{
public SimulatorPressure(string module, XmlElement node, string ioModule) : base(module, node, ioModule)
{
}
/// <summary>
/// 根据XML配置创建PC控制对象
/// </summary>
/// <param name="node"></param>
protected override void InitializeIValve(XmlElement node)
{
XmlNodeList valveNodes = node.GetElementsByTagName("IoPressureMeter");
foreach (XmlElement xmlElement in valveNodes)
{
string aiValue = xmlElement.GetAttribute("aiValue");
string aoValue = xmlElement.GetAttribute("aoValue");
if (!String.IsNullOrWhiteSpace(aoValue))
if (!AI_AOList.ContainsKey(aiValue) && !AI_AOList.ContainsKey(aoValue))
AI_AOList.Add(aiValue, aoValue);
}
}
}
}

View File

@ -0,0 +1,69 @@
using Aitex.Core.RT.Device;
using Aitex.Core.RT.IOCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace MECF.Framework.Simulator.Core
{
public class SimulatorIoValve : BaseDevice, IDevice
{
protected Dictionary<string, string> DI_DOList = new Dictionary<string, string>();
public SimulatorIoValve(string module, XmlElement node, string ioModule) : base(module, node, ioModule)
{
InitializeIValve(node);
}
/// <summary>
/// 根据XML配置创建气阀控制对象
/// </summary>
/// <param name="node"></param>
protected virtual void InitializeIValve(XmlElement node)
{
XmlNodeList valveNodes = node.GetElementsByTagName("IoValve");
foreach (XmlElement xmlElement in valveNodes)
{
string diName = xmlElement.GetAttribute("diOpen");
string doName = xmlElement.GetAttribute("doOpen");
if (!DI_DOList.ContainsKey(diName) && !DI_DOList.ContainsKey(doName))
DI_DOList.Add(diName, doName);
var isDefaultOpen = xmlElement.GetAttribute("isDefaultOpen");
if (!String.IsNullOrWhiteSpace(isDefaultOpen))
IO.DO[$"{Module}.{doName}"].Value = Convert.ToBoolean(isDefaultOpen);
}
}
protected override void HandleMonitor()
{
DoValueToDI();
}
protected void DoValueToDI()
{
foreach (var di_do in DI_DOList)
{
IO.DI[$"{Module}.{di_do.Key}"].Value = IO.DO[$"{Module}.{di_do.Value}"].Value;
}
}
public bool Initialize()
{
return true;
}
public void Reset()
{
}
public void Terminate()
{
}
}
}

View File

@ -62,6 +62,7 @@
<Reference Include="WindowsBase" /> <Reference Include="WindowsBase" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="AI_AORandom\SimulatorAI_AORandom.cs" />
<Compile Include="Aligners\HPA48\HPA48Simulator.cs" /> <Compile Include="Aligners\HPA48\HPA48Simulator.cs" />
<Compile Include="Aligners\HPA48\HPA48View.xaml.cs"> <Compile Include="Aligners\HPA48\HPA48View.xaml.cs">
<DependentUpon>HPA48View.xaml</DependentUpon> <DependentUpon>HPA48View.xaml</DependentUpon>
@ -75,6 +76,13 @@
<Compile Include="CarrierIDReader\HoneywellHf800\HoneywellBarcodeView.xaml.cs"> <Compile Include="CarrierIDReader\HoneywellHf800\HoneywellBarcodeView.xaml.cs">
<DependentUpon>HoneywellBarcodeView.xaml</DependentUpon> <DependentUpon>HoneywellBarcodeView.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Device\SimulatorDeviceManager.cs" />
<Compile Include="IoAO_AI\SimulatorIoAO_AI.cs" />
<Compile Include="IoDefault\SimulatorIoDefault.cs" />
<Compile Include="IoDO_DI\SimulatorIoDO_DI.cs" />
<Compile Include="IoMFC\SimulatorMFC.cs" />
<Compile Include="IoPressure\SimulatorPressure.cs" />
<Compile Include="IoValves\SimulatorIoValve.cs" />
<Compile Include="LoadPorts\SG\SGLoadPortSimulator.cs" /> <Compile Include="LoadPorts\SG\SGLoadPortSimulator.cs" />
<Compile Include="LoadPorts\SG\SGLoadPortView.xaml.cs"> <Compile Include="LoadPorts\SG\SGLoadPortView.xaml.cs">
<DependentUpon>SGLoadPortView.xaml</DependentUpon> <DependentUpon>SGLoadPortView.xaml</DependentUpon>
@ -575,7 +583,7 @@
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<ProjectExtensions> <ProjectExtensions>
<VisualStudio> <VisualStudio>
<UserProperties robots_4hiratar4_4iosimulatoritems_1json__JsonSchema="https://jenkins-x.io/schemas/jx-schema.json" vce_4brooksvce_4iosimulatoritems_1json__JsonSchema="http://json.schemastore.org/apibuilder.json" /> <UserProperties vce_4brooksvce_4iosimulatoritems_1json__JsonSchema="http://json.schemastore.org/apibuilder.json" robots_4hiratar4_4iosimulatoritems_1json__JsonSchema="https://jenkins-x.io/schemas/jx-schema.json" />
</VisualStudio> </VisualStudio>
</ProjectExtensions> </ProjectExtensions>
</Project> </Project>