Explorar o código

Merge branch 'master' of http://git.jetplasma-oa.com/JetPlasma/CyberX8

chenkui hai 2 meses
pai
achega
94edd6b585

+ 13 - 12
CyberX8_RT/Config/Devices/WagoControllerCfg-Simulator.xml

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <WagoControllerConfig>
-	<WagoDeviceConfig Module="Wago0" IpAddress="10.0.0.12" Port="502" SendTimeout="2000" RecvTimeout="2000" Channel="1">
+	<WagoDeviceConfig Module="Wago0" IpAddress="127.0.0.1" Port="501" SendTimeout="2000" RecvTimeout="2000" Channel="1">
 		<Dig_In>
 			<DIGroup Name="N5">
 				<DI Name="r_Cassette_1_150" Address="0" Invert="false"/>
@@ -76,20 +76,21 @@
 				<AI Name="AI1"  Address="0" Scaling="0=3276.7,-757=16383.5" DataType="short"/>
 				<AI Name="AI2"  Address="1" DataType="short"/>
 				<AI Name="AI3"  Address="2" DataType="short"/>
-				<AI Name="r_LoaderA_LS_Vacuum_anlg"  Address="4" Scaling="1=0,5=-757.5" DataType="short"/>
-				<AI Name="r_LoaderB_LS_Vacuum_anlg"  Address="5" Scaling="1=0,5=-757.5" DataType="short"/>
-				<AI Name="AI6"  Address="5" DataType="short"/>
-				<AI Name="r_LOADER_GasFlowSensor_FLOW"  Address="7" Scaling="1=0,5=500" DataType="short"/>
+				<AI Name="AI4"  Address="3" DataType="short"/>
+				<AI Name="r_LoaderA_LS_Vacuum_anlg"  Address="4" Scaling="0=3276.7,-757=16383.5" DataType="short"/>
+				<AI Name="r_LoaderB_LS_Vacuum_anlg"  Address="5" Scaling="0=3276.7,-757=16383.5" DataType="short"/>
+				<AI Name="AI6"  Address="6" DataType="short"/>
+				<AI Name="r_LOADER_GasFlowSensor_FLOW"  Address="7" Scaling="0=3370, 500=17000" DataType="short"/>
 			</AIGroup>
 			<AIGroup Name="N2">
-				<AI Name="r_LOADERA_BERNOULLI_PRESSURE"  Address="8" Scaling="1=0,5=145.0" DataType="short"/>
-				<AI Name="r_LOADERB_BERNOULLI_PRESSURE"  Address="9" Scaling="1=0,5=145.0" DataType="short"/>
-				<AI Name="r_LOADERA_CHUCK_BLADDER"  Address="10" Scaling="1=0,5=145.0" DataType="short"/>
-				<AI Name="r_LOADERB_CHUCK_BLADDER"  Address="11" Scaling="1=0,5=145.0" DataType="short"/>
-				<AI Name="r_LOADERA_WS_BLADDER_PRESSURE"  Address="12" Scaling="1=0,5=145.0" DataType="short"/>
-				<AI Name="r_LOADERB_WS_BLADDER_PRESSURE"  Address="13" Scaling="1=0,5=145.0" DataType="short"/>
+				<AI Name="r_LOADERA_BERNOULLI_PRESSURE"  Address="8" Scaling="0=3276.7, 145=16383.5" DataType="short"/>
+				<AI Name="r_LOADERB_BERNOULLI_PRESSURE"  Address="9" Scaling="0=3276.7, 145=16383.5" DataType="short"/>
+				<AI Name="r_LOADERA_CHUCK_BLADDER"  Address="10" Scaling="0=3276.7, 145=16383.5" DataType="short"/>
+				<AI Name="r_LOADERB_CHUCK_BLADDER"  Address="11" Scaling="0=3276.7, 145=16383.5" DataType="short"/>
+				<AI Name="r_LOADERA_WS_BLADDER_PRESSURE"  Address="12" Scaling="0=3276.7, 145=16383.5" DataType="short"/>
+				<AI Name="r_LOADERB_WS_BLADDER_PRESSURE"  Address="13" Scaling="0=3276.7, 145=16383.5" DataType="short"/>
 				<AI Name="r_SPUF_VAC"  Address="14" Scaling="1=0,5=-757.5" DataType="short"/>
-				<AI Name="r_LOADER_GasFlowSensor_VACUUM"  Address="15" Scaling="1=0,5=-101" DataType="short"/>
+				<AI Name="r_LOADER_GasFlowSensor_VACUUM"  Address="15" Scaling="0=3276.7,-757=16383.5" DataType="short"/>
 			</AIGroup>
 		</Ano_In>
 		<Ano_Out>

+ 10 - 0
CyberX8_RT/Devices/Loader/LoaderCRSAxisInterLock.cs

@@ -40,11 +40,21 @@ namespace CyberX8_RT.Devices.Loader
         /// <returns></returns>
         public bool CheckGotoPosition(string station)
         {
+            if (!_axis.IsSwitchOn)
+            {
+                LOG.WriteLog(eEvent.ERR_LOADER, Module, $"{Name} is switch off, Cannot execute GotoSavedPosition");
+                return false;
+            }
             if (!_axis.IsHomed)
             {
                 LOG.WriteLog(eEvent.ERR_LOADER, Module, $"{Name} is not home, Cannot execute GotoSavedPosition");
                 return false;
             }
+            if (_axis.IsRun)
+            {
+                LOG.WriteLog(eEvent.ERR_LOADER, Module, $"{Name} is running, Cannot execute GotoSavedPosition");
+                return false;
+            }
             return true;
         }
     }

+ 21 - 39
CyberX8_RT/Devices/Loader/LoaderTiltAxisInterLock.cs

@@ -47,14 +47,14 @@ namespace CyberX8_RT.Devices.Loader
         /// <exception cref="NotImplementedException"></exception>
         public bool CheckGotoPosition(string station)
         {
-            if (!_axis.IsHomed)
+            if (!_axis.IsSwitchOn)
             {
-                LOG.WriteLog(eEvent.ERR_LOADER, Module, $"{Name} is not home, Cannot execute GotoSavedPosition");
+                LOG.WriteLog(eEvent.ERR_LOADER, Module, $"{Name} is switch off, Cannot execute GotoSavedPosition");
                 return false;
             }
-            if (!_axis.IsSwitchOn)
+            if (!_axis.IsHomed)
             {
-                LOG.WriteLog(eEvent.ERR_LOADER, Module, $"{Name} is switch off, Cannot execute GotoSavedPosition");
+                LOG.WriteLog(eEvent.ERR_LOADER, Module, $"{Name} is not home, Cannot execute GotoSavedPosition");
                 return false;
             }
             if (_axis.IsRun)
@@ -96,54 +96,36 @@ namespace CyberX8_RT.Devices.Loader
             //判断shuttle是否在out位上
             JetAxisBase shuttleAxis = null;
             double shuttleAxisPosition = 0;
+            int wafersize = 0;
             if (Name == "TiltA")
             {
                 shuttleAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.ShuttleA");
-                if (shuttleAxis != null) 
-                {
-                    if (shuttleAxis.IsRun) //shuttle正在运动返回false
-                    {
-                        LOG.WriteLog(eEvent.ERR_LOADER, Module, $"{Module}.ShuttleA is running,  Cannot execute GotoSavedPosition");
-                        return false;
-                    }
-                    shuttleAxisPosition = shuttleAxis.MotionData.MotorPosition;
-                    if (!shuttleAxis.CheckPositionIsInStation(shuttleAxisPosition, $"OUT{SC.GetValue<int>("Loader1.SideAWaferSize")}"))
-                    {
-                        LOG.WriteLog(eEvent.ERR_LOADER, Module, $"{Module}.ShuttleA is not in out station,  Cannot execute GotoSavedPosition");
-                        return false;
-                    }
-                }
-                else //shuttle为空返回false
-                {
-                    LOG.WriteLog(eEvent.ERR_LOADER, Module, $"{Module}.ShuttleA is null,  Cannot execute GotoSavedPosition");
-                    return false;
-                }
-                
+                wafersize = SC.GetValue<int>("Loader1.SideAWaferSize");
             }
             else
             {
                 shuttleAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.ShuttleB");
-                shuttleAxis.WaferSize = SC.GetValue<int>("Loader1.SideBWaferSize");
-                if (shuttleAxis != null)
+                wafersize = SC.GetValue<int>("Loader1.SideBWaferSize");
+            }
+            if (shuttleAxis != null)
+            {
+                if (shuttleAxis.IsRun) //shuttle正在运动返回false
                 {
-                    if (shuttleAxis.IsRun) //shuttle正在运动返回false
-                    {
-                        LOG.WriteLog(eEvent.ERR_LOADER, Module, $"{Module}.ShuttleB is running,  Cannot execute GotoSavedPosition");
-                        return false;
-                    }
-                    shuttleAxisPosition = shuttleAxis.MotionData.MotorPosition;
-                    if (!shuttleAxis.CheckPositionIsInStation(shuttleAxisPosition, $"OUT{SC.GetValue<int>("Loader1.SideBWaferSize")}"))
-                    {
-                        LOG.WriteLog(eEvent.ERR_LOADER, Module, $"{Module}.ShuttleB is not in out station,  Cannot execute GotoSavedPosition");
-                        return false;
-                    }
+                    LOG.WriteLog(eEvent.ERR_LOADER, Module, $"{Module}.{shuttleAxis.Name} is running,  Cannot execute GotoSavedPosition");
+                    return false;
                 }
-                else  //shuttle为空返回false
+                shuttleAxisPosition = shuttleAxis.MotionData.MotorPosition;
+                if (!shuttleAxis.CheckPositionIsInStation(shuttleAxisPosition, $"OUT{wafersize}"))
                 {
-                    LOG.WriteLog(eEvent.ERR_LOADER, Module, $"{Module}.ShuttleB is null,  Cannot execute GotoSavedPosition");
+                    LOG.WriteLog(eEvent.ERR_LOADER, Module, $"{Module}.{shuttleAxis.Name} is not in out station,  Cannot execute GotoSavedPosition");
                     return false;
                 }
             }
+            else //shuttle为空返回false
+            {
+                LOG.WriteLog(eEvent.ERR_LOADER, Module, $"{Module}.{shuttleAxis.Name} is null,  Cannot execute GotoSavedPosition");
+                return false;
+            }
             return true;
         }
        

+ 8 - 14
CyberX8_RT/Modules/Loader/LoaderSwitchAllOffRoutine.cs

@@ -2,12 +2,6 @@
 using Aitex.Core.RT.Routine;
 using CyberX8_Core;
 using CyberX8_RT.Devices.AXIS;
-using CyberX8_RT.Devices.PUF;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace CyberX8_RT.Modules.Loader
 {
@@ -19,8 +13,8 @@ namespace CyberX8_RT.Modules.Loader
             ShuttleBSwitchOff,
             TiltASwitchOff,
             TiltBSwitchOff,
-            CRSASwitchOff,
-            CRSBSwitchOff,
+            LSASwitchOff,
+            LSBSwitchOff,
             RotationSwitchOff,
             End
         }
@@ -30,8 +24,8 @@ namespace CyberX8_RT.Modules.Loader
         private JetAxisBase _tiltAAxis;
         private JetAxisBase _tiltBAxis;
         private JetAxisBase _rotationAxis;
-        private JetAxisBase _crsAAxis;
-        private JetAxisBase _crsBAxis;
+        private JetAxisBase _lsAAxis;
+        private JetAxisBase _lsBAxis;
         private int _timeOut = 6000;
         #endregion
         public LoaderSwitchAllOffRoutine(string module) : base(module)
@@ -42,8 +36,8 @@ namespace CyberX8_RT.Modules.Loader
             _tiltAAxis = DEVICE.GetDevice<JetAxisBase>($"{module}.TiltA");
             _tiltBAxis = DEVICE.GetDevice<JetAxisBase>($"{module}.TiltB");
 
-            _crsAAxis = DEVICE.GetDevice<JetAxisBase>($"{module}.LSA");
-            _crsBAxis = DEVICE.GetDevice<JetAxisBase>($"{module}.LSB");
+            _lsAAxis = DEVICE.GetDevice<JetAxisBase>($"{module}.LSA");
+            _lsBAxis = DEVICE.GetDevice<JetAxisBase>($"{module}.LSB");
 
             _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{module}.Rotation");
         }
@@ -59,8 +53,8 @@ namespace CyberX8_RT.Modules.Loader
                 .Run(SwitchOffAllStep.ShuttleBSwitchOff, () => { _shuttleBAxis.SwitchOff(); return true; }, () => { return !_shuttleBAxis.IsSwitchOn; }, _timeOut)
                 .Run(SwitchOffAllStep.TiltASwitchOff, () => { _tiltAAxis.SwitchOff();return true; }, () => { return !_tiltAAxis.IsSwitchOn; }, _timeOut)
                 .Run(SwitchOffAllStep.TiltBSwitchOff, () => { _tiltBAxis.SwitchOff(); return true; }, () => { return !_tiltBAxis.IsSwitchOn; }, _timeOut)
-                .Run(SwitchOffAllStep.CRSASwitchOff, () => { _crsAAxis.SwitchOff(); return true; }, () => { return !_crsAAxis.IsSwitchOn; }, _timeOut)
-                .Run(SwitchOffAllStep.CRSBSwitchOff, () => { _crsBAxis.SwitchOff(); return true; }, () => { return !_crsBAxis.IsSwitchOn; }, _timeOut)
+                .Run(SwitchOffAllStep.LSASwitchOff, () => { _lsAAxis.SwitchOff(); return true; }, () => { return !_lsAAxis.IsSwitchOn; }, _timeOut)
+                .Run(SwitchOffAllStep.LSBSwitchOff, () => { _lsBAxis.SwitchOff(); return true; }, () => { return !_lsBAxis.IsSwitchOn; }, _timeOut)
                 .Run(SwitchOffAllStep.RotationSwitchOff, () => { _rotationAxis.SwitchOff(); return true; }, () => { return !_rotationAxis.IsSwitchOn; }, _timeOut)
                 .End(SwitchOffAllStep.End,NullFun);
 

+ 3 - 3
CyberX8_Simulator/CyberX8_Simulator.csproj

@@ -91,7 +91,7 @@
     <Compile Include="Devices\TMSimulatorServer.cs" />
     <Compile Include="Devices\VceSimulator.cs" />
     <Compile Include="Devices\VPASimulator.cs" />
-	<Compile Include="Devices\WagoSocketSimulator.cs" />
+    <Compile Include="Devices\WagoSocketSimulator.cs" />
     <Compile Include="Instances\SystemConfig.cs" />
     <Compile Include="JetChamber.cs" />
     <Compile Include="JetsiuTM.cs" />
@@ -149,7 +149,7 @@
     <Compile Include="Views\Simu_TMView.xaml.cs">
       <DependentUpon>Simu_TMView.xaml</DependentUpon>
     </Compile>
-	  <Compile Include="Views\WagoView.xaml.cs">
+    <Compile Include="Views\WagoView.xaml.cs">
       <DependentUpon>WagoView.xaml</DependentUpon>
     </Compile>
   </ItemGroup>
@@ -275,7 +275,7 @@
       <Generator>MSBuild:Compile</Generator>
       <SubType>Designer</SubType>
     </Page>
-	   <Page Include="Views\WagoView.xaml">
+    <Page Include="Views\WagoView.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </Page>

+ 63 - 7
CyberX8_Simulator/Devices/FestoSocketSimulator.cs

@@ -1,7 +1,15 @@
-using MECF.Framework.Common.Net;
+using Aitex.Common.Util;
+using Aitex.Core.RT.Device;
+using Aitex.Core.RT.IOCore;
+using Aitex.Core.Util;
+using MECF.Framework.Common.Device.Festo;
+using MECF.Framework.Common.Net;
 using MECF.Framework.Simulator.Core.Driver;
 using System;
 using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
 
 namespace CyberX8_Simulator.Devices
 {
@@ -23,8 +31,11 @@ namespace CyberX8_Simulator.Devices
         /// <summary>
         /// 数据(DOName - index)
         /// </summary>
-        private Dictionary<string, int> _festoNameIndexDic = new Dictionary<string, int>();
-
+        private Dictionary<string, FestoDO> _festoNameIndexDic = new Dictionary<string, FestoDO>();
+        /// <summary>
+        /// do 索引对象字典(key-地址索引-bit,value--do名称)
+        /// </summary>
+        private Dictionary<string, string> _doNameDictionary = new Dictionary<string, string>();
         /// <summary>
         /// 构造函数
         /// </summary>
@@ -35,7 +46,21 @@ namespace CyberX8_Simulator.Devices
             {
                 _festoOutputDataDic[i] = 0x00;
             }
-
+            string oldXmlPath = PathManager.GetCfgDir();
+            string newXmlPath = oldXmlPath.Replace("CyberX8_Simulator", "CyberX8_RT") + "Devices\\FestoControllerCfg-Simulator.xml";
+            FestoControllerCfg cfg = CustomXmlSerializer.Deserialize<FestoControllerCfg>(new FileInfo(newXmlPath));
+            foreach (FestoDeviceConfig config in cfg.FestoDeviceConfigs)
+            {            
+                if(port == config.Port)
+                {
+                    foreach (FestoDO item in config.FestoDoes)
+                    {
+                        _festoNameIndexDic[item.Name] = item;
+                        string str = $"{item.Address}-{item.Bit}";
+                        _doNameDictionary[str] = item.Name;
+                    }
+                }
+            }
         }
         /// <summary>
         /// 解析信息
@@ -72,9 +97,12 @@ namespace CyberX8_Simulator.Devices
 
                 if(startAddress >= FESTO_DO_START_ADDRESS)
                 {
+                    //通知相关数据变化
+                    var result = DecodeDOData(startAddress, value);
+                    SimulatorCommManager.Instance.CheckDataChanged(result.Item1, result.Item2);
                     //modbus起始地址n为数据,n+1为诊断数据,取地址n下的数据
-                    int index = (startAddress - FESTO_DO_START_ADDRESS) * 2;
-                    _festoOutputDataDic[index] = value;
+                    _festoOutputDataDic[(startAddress - FESTO_DO_START_ADDRESS) * 2] = value;
+                    
                     OnWriteMessage(CreateWriteResponse(flag, channel, command, startAddress, value));
                 }
                 else
@@ -158,6 +186,34 @@ namespace CyberX8_Simulator.Devices
             bytes[8] = error;
             return bytes;
         }
-
+        /// <summary>
+        /// 更新DI数据
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="value"></param>
+        public void UpdataDOBytes(string name, int value)
+        {
+            if (_festoNameIndexDic.ContainsKey(name))
+            {
+                FestoDO festoDO = _festoNameIndexDic[name];
+                short byteValue = (short) (_festoOutputDataDic[(festoDO.Address - FESTO_DO_START_ADDRESS) * 2] & ~(1 << festoDO.Bit));
+                short tmp = (short)(value << festoDO.Bit);
+                _festoOutputDataDic[(festoDO.Address - FESTO_DO_START_ADDRESS) * 2] = (short)(byteValue | tmp);
+            }
+        }
+        /// <summary>
+        /// 解析数据
+        /// </summary>
+        /// <param name="address"></param>
+        /// <param name="value"></param>
+        /// <returns></returns>
+        private (string, bool) DecodeDOData(ushort address, short value)
+        {
+            int index = (address - FESTO_DO_START_ADDRESS) * 2;
+            int bitNum = (int)Math.Log(_festoOutputDataDic[index] ^ value, 2);
+            bool valueBool = (value & (1 << bitNum)) != 0 ? true : false;
+            string str = $"{address}-{bitNum}";
+            return (_doNameDictionary[str], valueBool);
+        }
     }
 }

+ 125 - 18
CyberX8_Simulator/Devices/WagoSocketSimulator.cs

@@ -1,11 +1,14 @@
-using MECF.Framework.Common.Net;
+using Aitex.Core.RT.Device;
+using MECF.Framework.Common.Net;
 using MECF.Framework.Simulator.Core.Driver;
 using System;
 using System.Collections.Generic;
+using System.Diagnostics.Eventing.Reader;
 using System.Linq;
 using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
+using System.Timers;
 
 namespace CyberX8_Simulator.Devices
 {
@@ -15,14 +18,13 @@ namespace CyberX8_Simulator.Devices
         private const short WRITE_AO_STARTADDRESS = 0x0200;
 
         //键是名字,值是对应数据所在的位置  注意:要和WagoControlCfg里面的地址顺序对上
-        private Dictionary<string, int> DONameIndexDic = new Dictionary<string, int>
-        {{"DO0",0 },{"c_LoaderA_LS_Vacuum",1} };
-        private Dictionary<string, int> DINameIndexDic = new Dictionary<string, int>
-        {{"r_DRIP_TRAY_FLUID_DETECTION",19 },{"DI1",1} };
-        private Dictionary<string, int> AINameIndexDic = new Dictionary<string, int>
-        {{"r_LoaderA_LS_Vacuum_anlg",0 },{"AI1",1} };
-        private Dictionary<string, int> AONameIndexDic = new Dictionary<string, int>
-        {{"AO0",0 },{"AO1",1} };
+        private Dictionary<string, int> DONameIndexDic;
+
+        private Dictionary<string, int> DINameIndexDic;
+        
+        private Dictionary<string, int> AINameIndexDic;
+        
+        private Dictionary<string, int> AONameIndexDic;
 
         private IByteTransform byteTransform = new BigEndianByteTransformBase();
 
@@ -34,8 +36,6 @@ namespace CyberX8_Simulator.Devices
 
         private short[] AIShorts = new short[50];
 
-
-
         /// <summary>
         /// 写DO锁
         /// </summary>
@@ -47,16 +47,123 @@ namespace CyberX8_Simulator.Devices
 
         public WagoSocketSimulator(int port):base(port) 
         {
-            InitializeData();
-        }
-        
+            SimulatorCommManager.Instance.OnUpdateVariableValueChanged += UpdataDataCausedByOtherModule;
+            InitializeData(port);    
+        }  
+        
+        private void UpdataDataCausedByOtherModule(string name,bool value)
+        {
+            if (AINameIndexDic.ContainsKey(name))
+            {
+                if (value)
+                {
+                    AIShorts[AINameIndexDic[name]] = 0x2710;
+                }
+                else
+                {
+                    AIShorts[AINameIndexDic[name]] = 0x00;
+                }
+            }
+        }
         /// <summary>
-        /// 初始化数组数据
+        /// 初始化字典
         /// </summary>
-        private void InitializeData()
+        private void InitializeData(int port)
         {
-            AIShorts[0] = 0x1388;
-        }
+            DONameIndexDic = new Dictionary<string, int>
+            {{"c_System_Alarm",0 },
+             {"c_Pole_Red",1},
+             {"c_Pole_Amber",2},
+             {"c_Pole_Green",3},
+             {"c_Pole_Blue",4},
+             {"c_System_Alarm2",5},
+             {"c_BACKSIDE_PRESSURE_TEST",6},
+             {"c_VACUUM_TEST",7},
+             {"DO8",8},
+             {"DO9",9},
+             {"DO10",10},
+             {"DO11",11},
+             {"DO12",12},
+             {"DO13",13},
+             {"DO14",14},
+             {"DO15",15},
+             {"DO16",16},
+             {"DO17",17},
+             {"DO18",18},
+             {"DO19",19},
+             {"DO20",20},
+             {"DO21",21}};
+
+            DINameIndexDic = new Dictionary<string, int>
+            {{"r_Cassette_1_150",0 },
+             {"r_Cassette_1_100",1},
+             {"r_Cassette_1_200",2},
+             {"r_Cassette_2_150",3},
+             {"r_Cassette_2_100",4},
+             {"r_Cassette_2_200",5},
+             {"r_Cassette_3_150",6},
+             {"r_Cassette_3_100",7},
+             {"r_Cassette_3_200",8 },
+             {"r_Dummy_1_150",9},
+             {"r_Dummy_1_100",10},
+             {"r_Dummy_1_200",11},
+             {"r_Dummy_2_150",12},
+             {"r_Dummy_2_100",13},
+             {"r_Dummy_2_200",14},
+             {"DI15",15},
+             {"r_LoaderA_Wafer_Present",16},
+             {"r_LoaderB_Wafer_Present",17},
+             {"r_Cathode_Present",18},
+             {"DI19",19},
+             {"DI20",20},
+             {"DI21",21},
+             {"DI22",22},
+             {"DI23",23},
+             {"DI24",24},
+             {"DI25",25},
+             {"r_LOADERA_CRS_CURTAIN_1",26},
+             {"r_LOADERA_CRS_CURTAIN_2",27},
+             {"r_LOADERA_CRS_CURTAIN_3",28},
+             {"r_LOADERA_CRS_CURTAIN_4",29},
+             {"r_LOADERA_CRS_CURTAIN_5",30},
+             {"r_LOADERA_CRS_CURTAIN_6",31}};
+
+            AINameIndexDic = new Dictionary<string, int>
+            {{"AI1",0 },
+             {"AI2",1},
+             {"AI3",2},
+             {"AI4",3},
+             {"r_LoaderA_LS_Vacuum_anlg",4},
+             {"r_LoaderB_LS_Vacuum_anlg",5},
+             {"AI6",6},
+             {"r_LOADER_GasFlowSensor_FLOW",7},
+             {"r_LOADERA_BERNOULLI_PRESSURE",8},
+             {"r_LOADERB_BERNOULLI_PRESSURE",9},
+             {"r_LOADERA_CHUCK_BLADDER",10},
+             {"r_LOADERB_CHUCK_BLADDER",11},
+             {"r_LOADERA_WS_BLADDER_PRESSURE",12},
+             {"r_LOADERB_WS_BLADDER_PRESSURE",13},
+             {"r_SPUF_VAC",14},
+             {"r_LOADER_GasFlowSensor_VACUUM",15},};
+
+            AONameIndexDic = new Dictionary<string, int>
+            {{"AO1",0},
+             {"AO2",1},
+             {"AO3",2},
+             {"AO4",3},
+             {"AO5",4},
+             {"AO6",5},
+             {"AO7",6},
+             {"AO8",7},
+             {"AO9",8},
+             {"AO10",9},
+             {"AO11",10},
+             {"AO12",11},
+             {"AO13",12},
+             {"AO14",13},
+             {"AO15",14},
+             {"AO16",15}};
+            }
 
         #region 公共方法
         public void UpdataDOBytes(string name,int value)

+ 6 - 0
CyberX8_Simulator/Views/FestoView.xaml

@@ -20,6 +20,12 @@
         <Grid  Grid.Row="1">
             <StackPanel Orientation="Horizontal" Width="1200">
                 <Button Content="Clear Log" Width="100" Height="35"   Command="{Binding ClearLogCommand}"></Button>
+                <StackPanel Orientation="Horizontal" Width="500" Height="50" Margin="100,0,0,0">
+                    <Label Content="DO:" VerticalAlignment="Center"></Label>
+                    <ComboBox  Width="250" Height="30" VerticalContentAlignment="Center" ItemsSource="{Binding DONameItems}" SelectedItem="{Binding DOSelectedItem}" />
+                    <ComboBox  Width="60" Height="30" Margin="5,0,0,0" VerticalContentAlignment="Center" ItemsSource="{Binding DigitalOutputSelected}" SelectedItem="{Binding DOInputValue}" HorizontalContentAlignment="Center"></ComboBox>
+                    <Button Content="DOInput" Height="30" Width="100" Margin="5,10,0,0" Command="{Binding SetDOCommand}"/>
+                </StackPanel>
             </StackPanel>
         </Grid>
 

+ 60 - 3
CyberX8_Simulator/Views/FestoView.xaml.cs

@@ -1,6 +1,12 @@
-using Aitex.Core.UI.MVVM;
+using Aitex.Common.Util;
+using Aitex.Core.UI.MVVM;
+using Aitex.Core.Util;
+using Aitex.Core.Utilities;
 using CyberX8_Simulator.Devices;
+using MECF.Framework.Common.Device.Festo;
 using MECF.Framework.Simulator.Core.Commons;
+using System.Collections.ObjectModel;
+using System.IO;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Input;
@@ -24,11 +30,42 @@ namespace CyberX8_Simulator.Views
     }
     class FestoViewModel : SocketDeviceViewModel
     {
+        #region 属性
         public string Title
         {
             get { return "Festo Simulator"; }
         }
 
+        private string _DOSelectedItem;
+        [IgnorePropertyChange]
+        public string DOSelectedItem
+        {
+            get
+            {
+                return _DOSelectedItem;
+            }
+            set
+            {
+                _DOSelectedItem = value;
+            }
+        }
+        private int _DOInputValue;
+        [IgnorePropertyChange]
+        public int DOInputValue
+        {
+            get
+            {
+                return _DOInputValue;
+            }
+            set
+            {
+                _DOInputValue = value;
+            }
+        }
+        public ObservableCollection<string> DONameItems { get; set; }
+        public ObservableCollection<int> DigitalOutputSelected { get; set; }
+        #endregion
+
         public ICommand SetDOCommand { get; set; }
         private FestoSocketSimulator _sim;
         public FestoViewModel(string str) : base("FestoViewModel")
@@ -36,12 +73,32 @@ namespace CyberX8_Simulator.Views
             int.TryParse(str, out int port);
             _sim = new FestoSocketSimulator(port);
             Init(_sim);
+            InitData(port);
             SetDOCommand = new DelegateCommand<object>(SetDOAction);
         }
-
+        private void InitData(int port)
+        {
+            DigitalOutputSelected = new ObservableCollection<int> { 0, 1 };
+            string oldXmlPath = PathManager.GetCfgDir();
+            string newXmlPath = oldXmlPath.Replace("CyberX8_Simulator", "CyberX8_RT") + "Devices\\FestoControllerCfg-Simulator.xml";
+            FestoControllerCfg cfg = CustomXmlSerializer.Deserialize<FestoControllerCfg>(new FileInfo(newXmlPath));
+            DONameItems = new ObservableCollection<string>();
+            foreach (FestoDeviceConfig config in cfg.FestoDeviceConfigs)
+            {
+                if (port == config.Port)
+                {
+                    foreach (FestoDO item in config.FestoDoes)
+                    {
+                        DONameItems.Add(item.Name);
+                    }
+                }
+            }
+            
+       
+        }
         private void SetDOAction(object obj)
         {
-            //_sim.UpdataDOBytes(DOSelectedItem, DOInputValue);
+            _sim.UpdataDOBytes(DOSelectedItem, DOInputValue);
         }
     }
 }

+ 5 - 5
CyberX8_Simulator/Views/WagoView.xaml

@@ -23,23 +23,23 @@
             <StackPanel Orientation="Horizontal" Width="500" Height="50" Canvas.Left="120">
                 <Label Content="DO:" VerticalAlignment="Center"></Label>
                 <ComboBox  Width="250" Height="30" VerticalContentAlignment="Center" ItemsSource="{Binding DONameItems}" SelectedItem="{Binding DOSelectedItem}" />
-                <ComboBox  Width="60" Height="30" Margin="5,0,0,0" VerticalContentAlignment="Center" ItemsSource="{Binding DigitalInputSelected}" SelectedItem="{Binding DOInputValue}" HorizontalContentAlignment="Center"></ComboBox>
+                <ComboBox  Width="100" Height="30" Margin="5,0,0,0" VerticalContentAlignment="Center" ItemsSource="{Binding DigitalInputSelected}" SelectedItem="{Binding DOInputValue}" HorizontalContentAlignment="Center"></ComboBox>
                 <Button Content="DOInput" Height="30" Width="100" Margin="5,10,0,0" Command="{Binding SetDOCommand}"/>
             </StackPanel>
             
-            <StackPanel Orientation="Horizontal" Width="500" Height="50" Canvas.Left="620">
+            <StackPanel Orientation="Horizontal" Width="500" Height="50" Canvas.Left="640">
                 <Label Content="DI:" VerticalAlignment="Center"></Label>
                 <ComboBox  Width="250" Height="30" VerticalContentAlignment="Center" ItemsSource="{Binding DINameItems}" SelectedItem="{Binding DISelectedItem}" />
-                <ComboBox  Width="60" Height="30" Margin="5,0,0,0" VerticalContentAlignment="Center" ItemsSource="{Binding DigitalInputSelected}" SelectedItem="{Binding DIInputValue}" HorizontalContentAlignment="Center"></ComboBox>
+                <ComboBox  Width="100" Height="30" Margin="5,0,0,0" VerticalContentAlignment="Center" ItemsSource="{Binding DigitalInputSelected}" SelectedItem="{Binding DIInputValue}" HorizontalContentAlignment="Center"></ComboBox>
                 <Button Content="DIInput" Height="30" Width="100" Margin="5,10,0,0" Command="{Binding SetDICommand}"/>
             </StackPanel>
             <StackPanel Orientation="Horizontal" Width="500" Height="50" Canvas.Top="50" Canvas.Left="120">
                 <Label Content="AO:" VerticalAlignment="Center"></Label>
                 <ComboBox  Width="250" Height="30" VerticalContentAlignment="Center" ItemsSource="{Binding AONameItems}" SelectedItem="{Binding AOSelectedItem}" />
                 <TextBox Text="{Binding AOInputValue,Mode=OneWayToSource}" Width="100" Height="30" Margin="5,0,0,0" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"></TextBox>
-                <Button Content="AoInput" Height="30" Width="100" Margin="5,10,0,0" Command="{Binding SetAOCommand}"/>
+                <Button Content="AOInput" Height="30" Width="100" Margin="5,10,0,0" Command="{Binding SetAOCommand}"/>
             </StackPanel>
-            <StackPanel Orientation="Horizontal" Width="500" Height="50" Canvas.Top="50" Canvas.Left="620">
+            <StackPanel Orientation="Horizontal" Width="500" Height="50" Canvas.Top="50" Canvas.Left="640">
                 <Label Content="AI:" VerticalAlignment="Center"></Label>
                 <ComboBox  Width="250" Height="30" VerticalContentAlignment="Center" ItemsSource="{Binding AINameItems}" SelectedItem="{Binding AISelectedItem}" />
                 <TextBox Text="{Binding AIInputValue,Mode=OneWayToSource}" Width="100" Height="30" Margin="5,0,0,0" VerticalContentAlignment="Center" HorizontalContentAlignment="Center"></TextBox>

+ 90 - 8
CyberX8_Simulator/Views/WagoView.xaml.cs

@@ -173,7 +173,7 @@ namespace CyberX8_Simulator.Views
 
         public WagoViewModel(string str) : base("WagoViewModel")
         {
-            InitData();
+            
             
             SetDICommand = new DelegateCommand<object>(SetDIAction);
             SetDOCommand = new DelegateCommand<object>(SetDOAction);
@@ -183,6 +183,7 @@ namespace CyberX8_Simulator.Views
             int.TryParse(str, out int port);
             _sim = new WagoSocketSimulator(port);
             Init(_sim);
+            InitData(port);
         }
 
         private void SetDIAction(object obj)
@@ -202,21 +203,102 @@ namespace CyberX8_Simulator.Views
             _sim.UpdataAOShorts(AOSelectedItem, AOInputValue);
         }
 
-        private void InitData()
+        private void InitData(int port)
         {
             DigitalInputSelected = new ObservableCollection<int> { 0, 1 };
 
             DONameItems = new ObservableCollection<string>
-            { "DO1","DO2","DO3","c_LoaderA_LS_Vacuum","DO4","DO5","DO6","DO7","DO8"
-            ,"DO9","DO10","DO11","DO12","DO12","DO13","DO14","DO15","DO16","DO17","DO18",
-                "c_LOADERA_DOOR_UNLOCK","DO20","DO21"};
+            { "c_System_Alarm",
+              "c_Pole_Red",
+              "c_Pole_Amber",
+              "c_Pole_Green",
+              "c_Pole_Blue",
+              "c_System_Alarm2",
+              "c_BACKSIDE_PRESSURE_TEST",
+              "c_VACUUM_TEST",
+              "DO8",
+              "DO9",
+              "DO10",
+              "DO11",
+              "DO12",
+              "DO13",
+              "DO14",
+              "DO15",
+              "DO16",
+              "DO17",
+              "DO18",
+              "DO19",
+              "DO20",
+              "DO21"};
             
             DINameItems = new ObservableCollection<string>
-            { "r_Cassette_1_150","r_Cassette_1_100","r_DRIP_TRAY_FLUID_DETECTION"};
+            { "r_Cassette_1_150",
+              "r_Cassette_1_100",
+              "r_Cassette_1_200",
+              "r_Cassette_2_150",
+              "r_Cassette_2_100",
+              "r_Cassette_2_200",
+              "r_Cassette_3_150",
+              "r_Cassette_3_100",
+              "r_Cassette_3_200",
+              "r_Dummy_1_150",
+              "r_Dummy_1_100",
+              "r_Dummy_1_200",
+              "r_Dummy_2_150",
+              "r_Dummy_2_100",
+              "r_Dummy_2_100",
+              "D15",
+              "r_LoaderA_Wafer_Present",
+              "r_LoaderB_Wafer_Present",
+              "r_Cathode_Present",
+              "DI19",
+              "DI20",
+              "DI21",
+              "DI22",
+              "DI23",
+              "DI24",
+              "DI25",
+              "r_LOADERA_CRS_CURTAIN_1",
+              "r_LOADERA_CRS_CURTAIN_2",
+              "r_LOADERA_CRS_CURTAIN_3",
+              "r_LOADERA_CRS_CURTAIN_4",
+              "r_LOADERA_CRS_CURTAIN_5",
+              "r_LOADERA_CRS_CURTAIN_6",};
 
-            AONameItems = new ObservableCollection<string> { "AO0", "AO1" };
+            AONameItems = new ObservableCollection<string> 
+            { "AO1", 
+              "AO2",
+              "AO3",
+              "AO4",
+              "AO5",
+              "AO6",
+              "AO7",
+              "AO8",
+              "AO9",
+              "AO10",
+              "AO11",
+              "AO12",
+              "AO13",
+              "AO14",
+              "AO15",
+              "AO16"};
 
-            AINameItems = new ObservableCollection<string> { "r_LoaderA_LS_Vacuum_anlg", "AI1" };
+            AINameItems = new ObservableCollection<string> 
+            { "AI1", 
+              "AI2",
+              "AI3",
+              "r_LoaderA_LS_Vacuum_anlg",
+              "r_LoaderB_LS_Vacuum_anlg",
+              "AI6",
+              "r_LOADER_GasFlowSensor_FLOW",
+              "r_LOADERA_BERNOULLI_PRESSURE",
+              "r_LOADERB_BERNOULLI_PRESSURE",
+              "r_LOADERA_CHUCK_BLADDER",
+              "r_LOADERB_CHUCK_BLADDER",
+              "r_LOADERA_WS_BLADDER_PRESSURE",
+              "r_LOADERB_WS_BLADDER_PRESSURE",
+              "r_SPUF_VAC",
+              "r_LOADER_GasFlowSensor_VACUUM",};
         }
     }
 

+ 1 - 0
Framework/Common/Common.csproj

@@ -229,6 +229,7 @@
     <Compile Include="Device\BarcodeReader\BarcodeReaderConfig.cs" />
     <Compile Include="Device\BarcodeReader\BarcodeReaderDeviceConfig.cs" />
     <Compile Include="Device\BarcodeReader\BarcodeReaderSerialDevice.cs" />
+    <Compile Include="Device\Common\SimulatorCommManager.cs" />
     <Compile Include="Device\Festo\FestoCommand.cs" />
     <Compile Include="Device\Festo\FestoControllerCfg.cs" />
     <Compile Include="Device\Festo\FestoControllerCfgManager.cs" />

+ 76 - 0
Framework/Common/Device/Common/SimulatorCommManager.cs

@@ -0,0 +1,76 @@
+using Aitex.Core.Util;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Aitex.Core.RT.Device
+{
+    public class SimulatorCommManager:Singleton<SimulatorCommManager>
+    {
+
+        #region 内部变量
+        /// <summary>
+        /// 关联变量字典
+        /// </summary>
+        private Dictionary<string, string> _relatedDictionary = new Dictionary<string, string>();
+        #endregion
+
+        //delegate
+        #region Delegate
+        public delegate void UpdateVariableValueChanged(string name,bool value);
+        #endregion
+
+        #region 事件
+        /// <summary>
+        /// 变量变更事件
+        /// </summary>
+        public event UpdateVariableValueChanged OnUpdateVariableValueChanged;
+        #endregion
+
+
+        public void Initialize()
+        {
+            _relatedDictionary.Add("c_LOADERA_WS_BLADDER", "r_LOADERA_WS_BLADDER_PRESSURE");//Wafershuttle bladder
+            _relatedDictionary.Add("c_LOADERB_WS_BLADDER", "r_LOADERB_WS_BLADDER_PRESSURE");
+            
+            _relatedDictionary.Add("c_LOADERA_BERNOULLI_BLADDER", "r_LOADERA_CHUCK_BLADDER");//bernoulli bladder
+            _relatedDictionary.Add("c_LOADERB_BERNOULLI_BLADDER", "r_LOADERB_CHUCK_BLADDER");
+            
+            _relatedDictionary.Add("c_LoaderA_LS_Vacuum", "r_LoaderA_LS_Vacuum_anlg");//Ls vacuum
+            _relatedDictionary.Add("c_LoaderB_LS_Vacuum", "r_LoaderB_LS_Vacuum_anlg");
+            
+            _relatedDictionary.Add("c_LOADERA_BERNOULLI_N2", "r_LOADERA_BERNOULLI_PRESSURE"); //bernoulli N2
+            _relatedDictionary.Add("c_LOADERB_BERNOULLI_N2", "r_LOADERB_BERNOULLI_PRESSURE");
+        }
+
+
+        /// <summary>
+        /// 通知受关联模块变化的变量以及变化的值
+        /// </summary>
+        /// <param name="data"></param>
+        private void UpdateVariableValue(string name, bool value)
+        {
+            if (OnUpdateVariableValueChanged != null)
+            {
+                OnUpdateVariableValueChanged(name, value);
+            }
+        }
+
+        /// <summary>
+        /// 检查变化的值是否影响别的模块
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="value"></param>
+        /// <returns></returns>
+        public void CheckDataChanged(string name, bool value)
+        {
+            if (_relatedDictionary.ContainsKey(name))
+            {
+                UpdateVariableValue(_relatedDictionary[name], value);
+            }
+            
+        }
+    }
+}

+ 2 - 0
Framework/UICore/E95Template/CenterView.xaml.cs

@@ -15,6 +15,7 @@ using System.Reflection;
 using Aitex.Core.RT.Log;
 using MECF.Framework.UI.Core.Applications;
 using Autofac;
+using Aitex.Core.RT.Device;
 
 namespace Aitex.Core.UI.View.Frame
 {
@@ -32,6 +33,7 @@ namespace Aitex.Core.UI.View.Frame
 
         public void CreateView(List<ViewItem> views )
         {
+            SimulatorCommManager.Instance.Initialize();
             foreach (ViewItem item in views)
             {
                 if (item.SubView == null || item.SubView.Count == 0)