Browse Source

update async scheduler

chenkui 1 week ago
parent
commit
4e761b030f

+ 1 - 10
CyberX8_RT/Devices/AXIS/JetAxisBase.cs

@@ -98,10 +98,6 @@ namespace CyberX8_RT.Devices.AXIS
         /// </summary>
         private DateTime _runTime = DateTime.Now;
         /// <summary>
-        /// 尺寸
-        /// </summary>
-        private int _waferSize = 0;
-        /// <summary>
         /// inter lock
         /// </summary>
         private IAxisInterLock _interLock;
@@ -324,10 +320,6 @@ namespace CyberX8_RT.Devices.AXIS
         /// 所有io变量是否初始化
         /// </summary>
         public bool IOInitialized { get { return AllIoVariableInitialized(); } }
-        /// <summary>
-        /// WaferSize
-        /// </summary>
-        public int WaferSize { get { return _waferSize; }  set { _waferSize = value; } }
         #endregion
         /// <summary>
         /// 构造函数
@@ -349,8 +341,7 @@ namespace CyberX8_RT.Devices.AXIS
         /// </summary>
         private void LoadStation()
         {
-            _waferSize = SC.GetValue<int>("System.WaferSize");
-            _stationAxis = BeckhoffStationLocationManager.Instance.GetStationAxis(Module, Name, _waferSize);
+            _stationAxis = BeckhoffStationLocationManager.Instance.GetStationAxis(Module, Name);
         }
         /// <summary>
         /// 订阅数据

+ 2 - 2
CyberX8_RT/Devices/TransPorter/LoaderTransPorterGantryAxisInterLock.cs

@@ -133,8 +133,8 @@ namespace CyberX8_RT.Devices.TransPorter
                     int transporterLayoutHorizontalDistance = SC.GetValue<int>("Transporter.TransporterLayoutHorizontalDistance");
                     int loaderPosition = SC.GetValue<int>("Transporter.TransporterLayoutLoaderPosition");
                     int biasDistanceBetweenLoaderAndProcess = SC.GetValue<int>("Transporter.BiasDistanceBetweenLoaderAndProcess");
-                    BeckhoffStationAxis loaderTransporterAxis = BeckhoffStationLocationManager.Instance.GetStationAxis(ModuleName.Transporter2.ToString(), "Gantry", 0);
-                    BeckhoffStationAxis processTransporterAxis = BeckhoffStationLocationManager.Instance.GetStationAxis(ModuleName.Transporter1.ToString(), "Gantry", 0);
+                    BeckhoffStationAxis loaderTransporterAxis = BeckhoffStationLocationManager.Instance.GetStationAxis(ModuleName.Transporter2.ToString(), "Gantry");
+                    BeckhoffStationAxis processTransporterAxis = BeckhoffStationLocationManager.Instance.GetStationAxis(ModuleName.Transporter1.ToString(), "Gantry");
                     var calculateResult = CalculateTransporterHorizontal(loaderTransporterAxis, processTransporterAxis);
                     double distance = calculateResult.max -biasDistanceBetweenLoaderAndProcess - calculateResult.min;
                     double _ratio = distance / transporterLayoutHorizontalDistance;

+ 2 - 2
CyberX8_RT/Devices/TransPorter/ProcessTransporterGantryAxisInterLock.cs

@@ -130,8 +130,8 @@ namespace CyberX8_RT.Devices.TransPorter
                     int transporterLayoutHorizontalDistance = SC.GetValue<int>("Transporter.TransporterLayoutHorizontalDistance");
                     int loaderPosition = SC.GetValue<int>("Transporter.TransporterLayoutLoaderPosition");
                     int biasDistanceBetweenLoaderAndProcess = SC.GetValue<int>("Transporter.BiasDistanceBetweenLoaderAndProcess");
-                    BeckhoffStationAxis loaderTransporterAxis = BeckhoffStationLocationManager.Instance.GetStationAxis(ModuleName.Transporter2.ToString(), "Gantry", 0);
-                    BeckhoffStationAxis processTransporterAxis = BeckhoffStationLocationManager.Instance.GetStationAxis(ModuleName.Transporter1.ToString(), "Gantry", 0);
+                    BeckhoffStationAxis loaderTransporterAxis = BeckhoffStationLocationManager.Instance.GetStationAxis(ModuleName.Transporter2.ToString(), "Gantry");
+                    BeckhoffStationAxis processTransporterAxis = BeckhoffStationLocationManager.Instance.GetStationAxis(ModuleName.Transporter1.ToString(), "Gantry");
                     var calculateResult = CalculateTransporterHorizontal(loaderTransporterAxis, processTransporterAxis);
                     double distance = calculateResult.max - biasDistanceBetweenLoaderAndProcess - calculateResult.min;
                     double _ratio = distance / transporterLayoutHorizontalDistance;

+ 9 - 0
CyberX8_RT/Dispatch/JobDispatcher.cs

@@ -16,6 +16,8 @@ using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using Aitex.Core.RT.Log;
+using MECF.Framework.Common.RecipeCenter;
+using MECF.Framework.Common.WaferHolder;
 
 namespace CyberX8_RT.Dispatch
 {
@@ -469,6 +471,13 @@ namespace CyberX8_RT.Dispatch
                     {
                         continue;
                     }
+                    List<string> chemistries = SchedulerSequenceRecipeManager.Instance.GetSequenceChemistry(job.SequenceRecipe);
+                    WaferSize waferSize = (WaferSize)job.SequenceRecipe.SubstrateSize;
+                    WaferHolderInfo waferHolderInfo = SchedulerManager.Instance.GetAvaibleBufferToLoaderWaferHolder(waferSize, job.SequenceRecipe.CrsType, chemistries);
+                    if (waferHolderInfo == null)
+                    {
+                        continue;
+                    }
                     tmpProcessJobs.Add(job);
                 }
             }

+ 1 - 1
CyberX8_RT/Dispatch/WaferHolderTaskManager.cs

@@ -85,7 +85,7 @@ namespace CyberX8_RT.Dispatch
                     }
                     if(waferTaskCount == 0)
                     {
-                        return true;
+                        return false;
                     }
                     _waferHolderTaskDic.TryAdd(waferHolderTask.ID, waferHolderTask);
                     lock (_waferHolderTaskObject)

+ 3 - 2
CyberX8_RT/Modules/Transporter/TransporterPickDownToRoutine.cs

@@ -459,8 +459,9 @@ namespace CyberX8_RT.Modules.Transporter
             {
                 return true;
             }  
-            BeckhoffStationAxis stationAxis = BeckhoffStationLocationManager.Instance.GetStationAxis(Module, "Elevator", 0);
-            Station upStation = stationAxis.Stations.Find(O => O.Name.EndsWith("CellTop")); Station cellStation = null;
+            BeckhoffStationAxis stationAxis = BeckhoffStationLocationManager.Instance.GetStationAxis(Module, "Elevator");
+            Station upStation = stationAxis.Stations.Find(O => O.Name.EndsWith("CellTop")); 
+            Station cellStation = null;
             if (_cellName == "Loader")
             {
                 cellStation = stationAxis.Stations.Find(O => O.Name.EndsWith("Loader"));

+ 1 - 1
CyberX8_RT/Modules/Transporter/TransporterPickUpFromRoutine.cs

@@ -424,7 +424,7 @@ namespace CyberX8_RT.Modules.Transporter
             {
                 return true;
             }  
-            BeckhoffStationAxis stationAxis = BeckhoffStationLocationManager.Instance.GetStationAxis(Module, "Elevator", 0);
+            BeckhoffStationAxis stationAxis = BeckhoffStationLocationManager.Instance.GetStationAxis(Module, "Elevator");
             Station upStation = stationAxis.Stations.Find(O => O.Name.EndsWith("UP"));
             Station cellStation = null;
             if (_cellName == "Loader")

+ 2 - 2
CyberX8_Simulator/Devices/GalilSocketSimulator.cs

@@ -219,8 +219,8 @@ namespace CyberX8_Simulator.Devices
 
                             foreach (GalilAxisConfig item in config.GalilAxises)
                             {
-                                _axisNameIndexDic[$"{config.Module}.{item.Name}"] = item.Index;
-                                _nameAxisList[item.Index] = $"{config.Module}.{item.Name}";
+                                _axisNameIndexDic[item.Name] = item.Index;
+                                _nameAxisList[item.Index] = item.Name;
                             }
                             if (config.GalilDigIn != null && config.GalilDigIn.DIs.Count != 0)
                             {

+ 297 - 297
CyberX8_Simulator/Devices/WagoSocketSimulator.cs

@@ -1,23 +1,23 @@
-using Aitex.Common.Util;
-using Aitex.Core.RT.Device;
-using Aitex.Core.RT.Log;
-using Aitex.Core.UI.Control;
-using Aitex.Core.Util;
-using MECF.Framework.Common.Device.Festo;
-using MECF.Framework.Common.Device.Wago;
-using MECF.Framework.Common.Net;
-using MECF.Framework.Common.Simulator;
-using MECF.Framework.Simulator.Core.Driver;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using static MECF.Framework.Common.Simulator.MotorSimulator;
-
-namespace CyberX8_Simulator.Devices
-{
-    public class WagoSocketSimulator : SocketDeviceSimulator
-    {
-        private const short WRITE_DO_STARTADDRESS = 0x0200;
+using Aitex.Common.Util;
+using Aitex.Core.RT.Device;
+using Aitex.Core.RT.Log;
+using Aitex.Core.UI.Control;
+using Aitex.Core.Util;
+using MECF.Framework.Common.Device.Festo;
+using MECF.Framework.Common.Device.Wago;
+using MECF.Framework.Common.Net;
+using MECF.Framework.Common.Simulator;
+using MECF.Framework.Simulator.Core.Driver;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using static MECF.Framework.Common.Simulator.MotorSimulator;
+
+namespace CyberX8_Simulator.Devices
+{
+    public class WagoSocketSimulator : SocketDeviceSimulator
+    {
+        private const short WRITE_DO_STARTADDRESS = 0x0200;
         private const short WRITE_AO_STARTADDRESS = 0x0200;
 
         //键是名字,值是对应数据所在的位置  注意:要和WagoControlCfg里面的地址顺序对上
@@ -27,41 +27,41 @@ namespace CyberX8_Simulator.Devices
         
         public Dictionary<string, int> AINameIndexDic;
         
-        public Dictionary<string, int> AONameIndexDic;
-
-        private IByteTransform byteTransform = new BigEndianByteTransformBase();
-        //存储模拟器数据的数组
-        public byte[] DOBytes = new byte[200];
-
-        public short[] AOShorts = new short[200];
-
-        public byte[] DIBytes = new byte[200];
-
-        public short[] AIShorts = new short[200];
-
-        /// <summary>
-        /// 写DO锁
-        /// </summary>
-        private object _writeDOLocker = new object();
-        /// <summary>
-        /// 写AO锁
-        /// </summary>
-        private object _writeAOLocker = new object();
+        public Dictionary<string, int> AONameIndexDic;
+
+        private IByteTransform byteTransform = new BigEndianByteTransformBase();
+        //存储模拟器数据的数组
+        public byte[] DOBytes = new byte[200];
+
+        public short[] AOShorts = new short[200];
+
+        public byte[] DIBytes = new byte[200];
+
+        public short[] AIShorts = new short[200];
+
+        /// <summary>
+        /// 写DO锁
+        /// </summary>
+        private object _writeDOLocker = new object();
+        /// <summary>
+        /// 写AO锁
+        /// </summary>
+        private object _writeAOLocker = new object();
         /// <summary>
         /// Festo Data Buffer
-        /// </summary>
-        private Dictionary<string, bool> _festoDataBuffer = new Dictionary<string, bool>();
+        /// </summary>
+        private Dictionary<string, bool> _festoDataBuffer = new Dictionary<string, bool>();
         /// <summary>
         /// Name-WagoDO dictionary
-        /// </summary>
-        private Dictionary<string, WagoDO> _doNameWagoDODic = new Dictionary<string, WagoDO>();
+        /// </summary>
+        private Dictionary<string, WagoDO> _doNameWagoDODic = new Dictionary<string, WagoDO>();
         /// <summary>
         /// Name-WagoDI dictionary
-        /// </summary>
-        private Dictionary<string, WagoDI> _diNameWagoDIDic = new Dictionary<string, WagoDI>();
+        /// </summary>
+        private Dictionary<string, WagoDI> _diNameWagoDIDic = new Dictionary<string, WagoDI>();
         /// <summary>
         /// 定时器
-        /// </summary>
+        /// </summary>
         private PeriodicJob _LoaderPeriodicJob;
         private PeriodicJob _Wago2PeriodicJob;
         private PeriodicJob _Wago4PeriodicJob;
@@ -92,14 +92,14 @@ namespace CyberX8_Simulator.Devices
         public event VariableValueChanged OnAIVariableValueChanged;
         public event VariableValueChanged OnDOVariableValueChanged;
         public event VariableValueChanged OnAOVariableValueChanged;
-        #endregion
-
-        public WagoSocketSimulator(int port):base(port) 
-        {
-            SimulatorCommManager.Instance.OnUpdateVariableValueChanged += UpdataDataCausedByOtherModule;
-            MotorSimulator.Instance.OnUpdateWagoDatasChanged += UpdataDataCausedByOtherModule;
+        #endregion
+
+        public WagoSocketSimulator(int port):base(port) 
+        {
+            SimulatorCommManager.Instance.OnUpdateVariableValueChanged += UpdataDataCausedByOtherModule;
+            MotorSimulator.Instance.OnUpdateWagoDatasChanged += UpdataDataCausedByOtherModule;
             InitializeData(port);
-            _port = port;
+            _port = port;
         }  
         private void UpdataDataCausedByOtherModule(string sourceName,string name, bool value, bool invert)
         {
@@ -298,11 +298,11 @@ namespace CyberX8_Simulator.Devices
                 UpdataDIBytes("r_METAL4_PUMP_ON", value ? 1 : 0);
             }
         }
-        /// <summary>
-        /// 初始化字典
-        /// </summary>
-        private void InitializeData(int port)  //端口用于初始化不同Wago设备的字典
-        {
+        /// <summary>
+        /// 初始化字典
+        /// </summary>
+        private void InitializeData(int port)  //端口用于初始化不同Wago设备的字典
+        {
             //加载对应配置文件 WagoControllerCfg-Simulator.xml
             try
             {
@@ -459,7 +459,7 @@ namespace CyberX8_Simulator.Devices
             if (AINameIndexDic.ContainsKey("r_MBS2_FLOW")) AIShorts[AINameIndexDic["r_MBS2_FLOW"]] = 16000;
 
         }
-        #region 公共方法
+        #region 公共方法
         public void UpdataDOBytes(string name,int value)
         {
             if (OnDOVariableValueChanged != null)
@@ -535,237 +535,237 @@ namespace CyberX8_Simulator.Devices
                 }
             }
         }
-        #endregion
+        #endregion
+
+        #region 功能方法
+        /// <summary>
+        /// 将长度为8的二进制byte数组转成对应十六进制byte值(大端模式)
+        /// </summary>
+        /// <param name="byteArray"></param>
+        /// <returns></returns>
+        public byte ConvertByteArrayToHex(byte[] byteArray)
+        {
+            byte result = 0;
+            // 先将 byte 数组转换为二进制数
+            int binaryValue = 0;
+            for (int i = 0; i < 8; i++)
+            {  
+                binaryValue |= (byteArray[i] << (7 - i));
+            }
 
-        #region 功能方法
-        /// <summary>
-        /// 将长度为8的二进制byte数组转成对应十六进制byte值(大端模式)
-        /// </summary>
-        /// <param name="byteArray"></param>
-        /// <returns></returns>
-        public byte ConvertByteArrayToHex(byte[] byteArray)
-        {
-            byte result = 0;
-            // 先将 byte 数组转换为二进制数
-            int binaryValue = 0;
-            for (int i = 0; i < 8; i++)
-            {  
-                binaryValue |= (byteArray[i] << (7 - i));
-            }
-
-            // 逆转二进制数
-            int reversedValue = 0;
-            for (int i = 0; i < 8; i++)
-            {
-                reversedValue |= ((binaryValue >> i) & 1) << (7 - i);
-            }
-            // 转换为十六进制byte
-            if (byte.TryParse(reversedValue.ToString("X2"), System.Globalization.NumberStyles.HexNumber, null, out result))
-            {
-               return result;
-            }
-            return 0;
-        }
-        /// <summary>
-        /// 将short数组转成长度两倍的byte数组
-        /// </summary>
-        /// <param name="shortArray"></param>
-        /// <returns></returns>
-        private byte[] ConvertShortArrayToByteArray(short[] shortArray)
-        {
-            byte[] byteArray = new byte[shortArray.Length * 2];
-            for (int i = 0; i < shortArray.Length; i++)
-            {
-                byte[] tempBytes = BitConverter.GetBytes(shortArray[i]);
-                Array.Reverse(tempBytes);
-                Array.Copy(tempBytes, 0, byteArray, i * 2, 2);
-            }
-            return byteArray;
-        }
-        #endregion
-        
-        protected override void ProcessUnsplitMessage(byte[] data)
-        {
-            byte command = data[7];
-            if (command == 0x01) //读DO
-            {
-                short flag = byteTransform.TransInt16(data, 0);
-                byte channel = data[6];
-                short startAddress = byteTransform.TransInt16(data, 8);
-                short bitCount = byteTransform.TransInt16(data, 10);
-                byte byteCount = (byte)(bitCount / 8 + 1);
-                byte[] bytes = new byte[byteCount];
-                for(int i = 0; i < byteCount;i++)
-                {
-                    byte[] tempbytes = new byte[8];
-                    Array.Copy(DOBytes,8 * i, tempbytes, 0, 8);
-                    bytes[i] = ConvertByteArrayToHex(tempbytes);
-                }
-                OnWriteMessage(CreateReadDigitalResponse(flag, channel, command, byteCount, bytes));
-                return;
-            }
-            else if(command == 0x03)//读AO
-            {
-                short flag = byteTransform.TransInt16(data, 0);
-                byte channel = data[6];
-                short startAddress = byteTransform.TransInt16(data, 8);
-                short registerCount = byteTransform.TransInt16(data, 10);
-                short[] shorts = new short[registerCount];//获取指定寄存器里的内容
-                Array.Copy(AOShorts, 0, shorts, 0, registerCount);
-                byte[] bytes = new byte[registerCount * 2];
-                bytes = ConvertShortArrayToByteArray(shorts); //转入长度为shorts数组长度两倍的bytes数组中
-                OnWriteMessage(CreateReadAnalogyResponse(flag, channel, command, (byte)registerCount, bytes));
-                return;
-            }
-            else if (command == 0x02)//读DI
-            {
-                short flag = byteTransform.TransInt16(data, 0);
-                byte channel = data[6];
-                short startAddress = byteTransform.TransInt16(data, 8);
-                short bitCount = byteTransform.TransInt16(data, 10);
-                byte byteCount = (byte)(bitCount / 8 + 1);
-                byte[] bytes = new byte[byteCount];
-                for (int i = 0; i < byteCount; i++)
-                {
-                    byte[] tempbytes = new byte[8];
-                    Array.Copy(DIBytes, 8 * i, tempbytes, 0, 8);
-                    bytes[i] = ConvertByteArrayToHex(tempbytes);
-                }
-                OnWriteMessage(CreateReadDigitalResponse(flag, channel, command, byteCount, bytes));
-                return;
-            }
-            else if (command == 0x04)//读AI
-            {
-                short flag = byteTransform.TransInt16(data, 0);
-                byte channel = data[6];
-                short startAddress = byteTransform.TransInt16(data, 8);
-                short registerCount = byteTransform.TransInt16(data, 10);
-                short[] shorts = new short[registerCount];//获取指定寄存器里的内容
-                Array.Copy(AIShorts, 0, shorts, 0, registerCount);
-                byte[] bytes = new byte[registerCount * 2];
-                bytes = ConvertShortArrayToByteArray(shorts); //转入长度为shorts数组两倍的bytes数组中
-                OnWriteMessage(CreateReadAnalogyResponse(flag, channel, command, (byte)registerCount, bytes));
-                return;
-            }
-            else if (command == 0x05)//写DO
-            {
-                short startAddress = byteTransform.TransInt16(data, 8);
-                if (startAddress > 0x03FF || startAddress < WRITE_DO_STARTADDRESS)
-                {
-                    short flag = byteTransform.TransInt16(data, 0);
-                    byte channel = data[6];
-                    OnWriteMessage(CreateError(flag, channel, command, 0x02)); //地址错误
-                    return;
-                }
-                int position = startAddress - WRITE_DO_STARTADDRESS;
-                bool status = data[10] == 0xFF ? true : false;
-                lock (_writeDOLocker)
-                {
-                    DOBytes[position] = status ? (byte)1 : (byte)0;
-                }
-                OnWriteMessage(data); //原消息返回
-                //触发Wago对应数据更新
+            // 逆转二进制数
+            int reversedValue = 0;
+            for (int i = 0; i < 8; i++)
+            {
+                reversedValue |= ((binaryValue >> i) & 1) << (7 - i);
+            }
+            // 转换为十六进制byte
+            if (byte.TryParse(reversedValue.ToString("X2"), System.Globalization.NumberStyles.HexNumber, null, out result))
+            {
+               return result;
+            }
+            return 0;
+        }
+        /// <summary>
+        /// 将short数组转成长度两倍的byte数组
+        /// </summary>
+        /// <param name="shortArray"></param>
+        /// <returns></returns>
+        private byte[] ConvertShortArrayToByteArray(short[] shortArray)
+        {
+            byte[] byteArray = new byte[shortArray.Length * 2];
+            for (int i = 0; i < shortArray.Length; i++)
+            {
+                byte[] tempBytes = BitConverter.GetBytes(shortArray[i]);
+                Array.Reverse(tempBytes);
+                Array.Copy(tempBytes, 0, byteArray, i * 2, 2);
+            }
+            return byteArray;
+        }
+        #endregion
+        
+        protected override void ProcessUnsplitMessage(byte[] data)
+        {
+            byte command = data[7];
+            if (command == 0x01) //读DO
+            {
+                short flag = byteTransform.TransInt16(data, 0);
+                byte channel = data[6];
+                short startAddress = byteTransform.TransInt16(data, 8);
+                short bitCount = byteTransform.TransInt16(data, 10);
+                byte byteCount = (byte)(bitCount / 8 + 1);
+                byte[] bytes = new byte[byteCount];
+                for(int i = 0; i < byteCount;i++)
+                {
+                    byte[] tempbytes = new byte[8];
+                    Array.Copy(DOBytes,8 * i, tempbytes, 0, 8);
+                    bytes[i] = ConvertByteArrayToHex(tempbytes);
+                }
+                OnWriteMessage(CreateReadDigitalResponse(flag, channel, command, byteCount, bytes));
+                return;
+            }
+            else if(command == 0x03)//读AO
+            {
+                short flag = byteTransform.TransInt16(data, 0);
+                byte channel = data[6];
+                short startAddress = byteTransform.TransInt16(data, 8);
+                short registerCount = byteTransform.TransInt16(data, 10);
+                short[] shorts = new short[registerCount];//获取指定寄存器里的内容
+                Array.Copy(AOShorts, 0, shorts, 0, registerCount);
+                byte[] bytes = new byte[registerCount * 2];
+                bytes = ConvertShortArrayToByteArray(shorts); //转入长度为shorts数组长度两倍的bytes数组中
+                OnWriteMessage(CreateReadAnalogyResponse(flag, channel, command, (byte)registerCount, bytes));
+                return;
+            }
+            else if (command == 0x02)//读DI
+            {
+                short flag = byteTransform.TransInt16(data, 0);
+                byte channel = data[6];
+                short startAddress = byteTransform.TransInt16(data, 8);
+                short bitCount = byteTransform.TransInt16(data, 10);
+                byte byteCount = (byte)(bitCount / 8 + 1);
+                byte[] bytes = new byte[byteCount];
+                for (int i = 0; i < byteCount; i++)
+                {
+                    byte[] tempbytes = new byte[8];
+                    Array.Copy(DIBytes, 8 * i, tempbytes, 0, 8);
+                    bytes[i] = ConvertByteArrayToHex(tempbytes);
+                }
+                OnWriteMessage(CreateReadDigitalResponse(flag, channel, command, byteCount, bytes));
+                return;
+            }
+            else if (command == 0x04)//读AI
+            {
+                short flag = byteTransform.TransInt16(data, 0);
+                byte channel = data[6];
+                short startAddress = byteTransform.TransInt16(data, 8);
+                short registerCount = byteTransform.TransInt16(data, 10);
+                short[] shorts = new short[registerCount];//获取指定寄存器里的内容
+                Array.Copy(AIShorts, 0, shorts, 0, registerCount);
+                byte[] bytes = new byte[registerCount * 2];
+                bytes = ConvertShortArrayToByteArray(shorts); //转入长度为shorts数组两倍的bytes数组中
+                OnWriteMessage(CreateReadAnalogyResponse(flag, channel, command, (byte)registerCount, bytes));
+                return;
+            }
+            else if (command == 0x05)//写DO
+            {
+                short startAddress = byteTransform.TransInt16(data, 8);
+                if (startAddress > 0x03FF || startAddress < WRITE_DO_STARTADDRESS)
+                {
+                    short flag = byteTransform.TransInt16(data, 0);
+                    byte channel = data[6];
+                    OnWriteMessage(CreateError(flag, channel, command, 0x02)); //地址错误
+                    return;
+                }
+                int position = startAddress - WRITE_DO_STARTADDRESS;
+                bool status = data[10] == 0xFF ? true : false;
+                lock (_writeDOLocker)
+                {
+                    DOBytes[position] = status ? (byte)1 : (byte)0;
+                }
+                OnWriteMessage(data); //原消息返回
+                //触发Wago对应数据更新
                 UpdateDataCausedByWago(position, status);
-                return;
-            }
-            else if (command == 0x06)//写AO
-            {
-                short startAddress = byteTransform.TransInt16(data, 8);
-                if(startAddress > 0x02FF || startAddress < WRITE_AO_STARTADDRESS)
-                {
-                    short flag = byteTransform.TransInt16(data, 0);
-                    byte channel = data[6];
-                    OnWriteMessage(CreateError(flag, channel, command, 0x02)); //地址错误
-                    return;
-                }
-                int position = startAddress - WRITE_AO_STARTADDRESS;
-                short value = byteTransform.TransInt16(data, 10);
-                lock (_writeAOLocker)
-                {
-                    AOShorts[position] = value;
-                }
-                OnWriteMessage(data); //原消息返回
-                return;
-            }
-            else 
-            {
-                short flag = byteTransform.TransInt16(data, 0);
-                byte channel = data[6];
-                OnWriteMessage(CreateError(flag, channel, command, 0x01)); //指令错误
-                return;
-            }
-        }
-        /// <summary>
-        /// 回复读数字量
-        /// </summary>
-        /// <param name="flag"></param>
-        /// <param name="channel"></param>
-        /// <param name="command"></param>
-        /// <param name="byteCount"></param>
-        /// <param name="values"></param>
-        /// <returns></returns>
-        private byte[] CreateReadDigitalResponse(short flag, byte channel, byte command, byte byteCount, byte[] values)
-        {
-            byte[] bytes = new byte[7 + 2 + values.Length]; //回复字节长度,前面7个字节固定长度 + functionCode一个字节 + byteCount一个字节+values.length个字节
-            Array.Copy(byteTransform.GetBytes(flag), 0, bytes, 0, 2);
-            bytes[2] = 0x00;
-            bytes[3] = 0x00;
-            short dataLength = (short)(3 + values.Length);
-            Array.Copy(byteTransform.GetBytes(dataLength), 0, bytes, 4, 2);
-            bytes[6] = channel;
-            bytes[7] = command;
-            bytes[8] = byteCount;
-            Array.Copy(values, 0, bytes, 9, values.Length);
-            return bytes;
-        }
-        /// <summary>
-        /// 回复读模拟量
-        /// </summary>
-        /// <param name="flag"></param>
-        /// <param name="channel"></param>
-        /// <param name="command"></param>
-        /// <param name="registerCount"></param>
-        /// <param name="values"></param>
-        /// <returns></returns>
-        private byte[] CreateReadAnalogyResponse(short flag, byte channel, byte command, byte registerCount, byte[] values)
-        {
-            byte[] bytes = new byte[7 + 2 + 2 * registerCount]; //回复字节长度,前面7个字节固定长度 + functionCode一个字节 + byteCount一个字节+registerCount*2个字节(一个寄存器占两个字节)
-            Array.Copy(byteTransform.GetBytes(flag), 0, bytes, 0, 2);
-            bytes[2] = 0x00;
-            bytes[3] = 0x00;
-            short dataLength = (short)(3 + 2 * registerCount);
-            Array.Copy(byteTransform.GetBytes(dataLength), 0, bytes, 4, 2);
-            bytes[6] = channel;
-            bytes[7] = command;
-            bytes[8] = (byte)(2 * registerCount);
-            Array.Copy(values, 0, bytes, 9, values.Length);
-            return bytes;
-        }
-        /// <summary>
-        /// 错误回复
-        /// </summary>
-        /// <param name="flag"></param>
-        /// <param name="channel"></param>
-        /// <param name="command"></param>
-        /// <param name="error"></param>
-        /// <returns></returns>
-        private byte[] CreateError(short flag, byte channel, byte command, byte error)
-        {
-            byte[] bytes = new byte[9];
-            Array.Copy(byteTransform.GetBytes(flag), 0, bytes, 0, 2);
-            bytes[2] = 0x00;
-            bytes[3] = 0x00;
-            bytes[4] = 0x00;
-            bytes[5] = 0x03;
-            bytes[6] = channel;
-            bytes[7] = (byte)(command | 0x80);
-            bytes[8] = error;
-            return bytes;
-        }
+                return;
+            }
+            else if (command == 0x06)//写AO
+            {
+                short startAddress = byteTransform.TransInt16(data, 8);
+                if(startAddress > 0x02FF || startAddress < WRITE_AO_STARTADDRESS)
+                {
+                    short flag = byteTransform.TransInt16(data, 0);
+                    byte channel = data[6];
+                    OnWriteMessage(CreateError(flag, channel, command, 0x02)); //地址错误
+                    return;
+                }
+                int position = startAddress - WRITE_AO_STARTADDRESS;
+                short value = byteTransform.TransInt16(data, 10);
+                lock (_writeAOLocker)
+                {
+                    AOShorts[position] = value;
+                }
+                OnWriteMessage(data); //原消息返回
+                return;
+            }
+            else 
+            {
+                short flag = byteTransform.TransInt16(data, 0);
+                byte channel = data[6];
+                OnWriteMessage(CreateError(flag, channel, command, 0x01)); //指令错误
+                return;
+            }
+        }
+        /// <summary>
+        /// 回复读数字量
+        /// </summary>
+        /// <param name="flag"></param>
+        /// <param name="channel"></param>
+        /// <param name="command"></param>
+        /// <param name="byteCount"></param>
+        /// <param name="values"></param>
+        /// <returns></returns>
+        private byte[] CreateReadDigitalResponse(short flag, byte channel, byte command, byte byteCount, byte[] values)
+        {
+            byte[] bytes = new byte[7 + 2 + values.Length]; //回复字节长度,前面7个字节固定长度 + functionCode一个字节 + byteCount一个字节+values.length个字节
+            Array.Copy(byteTransform.GetBytes(flag), 0, bytes, 0, 2);
+            bytes[2] = 0x00;
+            bytes[3] = 0x00;
+            short dataLength = (short)(3 + values.Length);
+            Array.Copy(byteTransform.GetBytes(dataLength), 0, bytes, 4, 2);
+            bytes[6] = channel;
+            bytes[7] = command;
+            bytes[8] = byteCount;
+            Array.Copy(values, 0, bytes, 9, values.Length);
+            return bytes;
+        }
+        /// <summary>
+        /// 回复读模拟量
+        /// </summary>
+        /// <param name="flag"></param>
+        /// <param name="channel"></param>
+        /// <param name="command"></param>
+        /// <param name="registerCount"></param>
+        /// <param name="values"></param>
+        /// <returns></returns>
+        private byte[] CreateReadAnalogyResponse(short flag, byte channel, byte command, byte registerCount, byte[] values)
+        {
+            byte[] bytes = new byte[7 + 2 + 2 * registerCount]; //回复字节长度,前面7个字节固定长度 + functionCode一个字节 + byteCount一个字节+registerCount*2个字节(一个寄存器占两个字节)
+            Array.Copy(byteTransform.GetBytes(flag), 0, bytes, 0, 2);
+            bytes[2] = 0x00;
+            bytes[3] = 0x00;
+            short dataLength = (short)(3 + 2 * registerCount);
+            Array.Copy(byteTransform.GetBytes(dataLength), 0, bytes, 4, 2);
+            bytes[6] = channel;
+            bytes[7] = command;
+            bytes[8] = (byte)(2 * registerCount);
+            Array.Copy(values, 0, bytes, 9, values.Length);
+            return bytes;
+        }
+        /// <summary>
+        /// 错误回复
+        /// </summary>
+        /// <param name="flag"></param>
+        /// <param name="channel"></param>
+        /// <param name="command"></param>
+        /// <param name="error"></param>
+        /// <returns></returns>
+        private byte[] CreateError(short flag, byte channel, byte command, byte error)
+        {
+            byte[] bytes = new byte[9];
+            Array.Copy(byteTransform.GetBytes(flag), 0, bytes, 0, 2);
+            bytes[2] = 0x00;
+            bytes[3] = 0x00;
+            bytes[4] = 0x00;
+            bytes[5] = 0x03;
+            bytes[6] = channel;
+            bytes[7] = (byte)(command | 0x80);
+            bytes[8] = error;
+            return bytes;
+        }
         /// <summary>
         /// loader 定时器
         /// </summary>
-        /// <returns></returns>
+        /// <returns></returns>
         private bool OnTimer()
         {
             LeakTestSimulator();
@@ -774,7 +774,7 @@ namespace CyberX8_Simulator.Devices
         /// <summary>
         /// Wago2定时器
         /// </summary>
-        /// <returns></returns>
+        /// <returns></returns>
         private bool OnTimer1()
         {
             RinseWaterLevelSimulator();
@@ -784,16 +784,16 @@ namespace CyberX8_Simulator.Devices
         /// <summary>
         /// Wago4定时器
         /// </summary>
-        /// <returns></returns>
+        /// <returns></returns>
         private bool OnTimer3()
         {
             Pump4FlowSimulator();
             return true;
         }
-        #region 模拟方法
+        #region 模拟方法
         /// <summary>
         /// Loader LeakTest模拟
-        /// </summary>
+        /// </summary>
         private void LeakTestSimulator()
         {
             if (DOBytes[DONameIndexDic["c_VACUUM_TEST"]] == 1 && _festoDataBuffer["FlowTestClamp"] && AIShorts[AINameIndexDic["r_LOADER_GasFlowSensor_FLOW"]] == 0)
@@ -816,7 +816,7 @@ namespace CyberX8_Simulator.Devices
 
         /// <summary>
         /// QDR水位模拟
-        /// </summary>
+        /// </summary>
         private void RinseWaterLevelSimulator()
         {
             //QDR1
@@ -881,7 +881,7 @@ namespace CyberX8_Simulator.Devices
         }
         /// <summary>
         /// metal1/2/3 pump流量模拟
-        /// </summary>
+        /// </summary>
         private void PumpFlowSimulator()
         {
             if (DOBytes[DONameIndexDic["c_METAL3_PUMP_ON"]] == 1)
@@ -913,7 +913,7 @@ namespace CyberX8_Simulator.Devices
         }
         /// <summary>
         /// metal4 pump流量模拟
-        /// </summary>
+        /// </summary>
         private void Pump4FlowSimulator()
         {
             if (DONameIndexDic.ContainsKey("c_METAL4_PUMP_ON") && DOBytes[DONameIndexDic["c_METAL4_PUMP_ON"]] == 1)
@@ -924,7 +924,7 @@ namespace CyberX8_Simulator.Devices
             {
                 SimulatorCommManager.Instance.CheckDataChanged("c_METAL4_PUMP_ON", false, false);
             }
-        }
-        #endregion
-    }
-}
+        }
+        #endregion
+    }
+}

+ 2 - 3
Framework/Common/Beckhoff/Station/BeckhoffStationLocationManager.cs

@@ -70,11 +70,10 @@ namespace MECF.Framework.Common.Beckhoff.Station
         /// <param name="moduleName"></param>
         /// <param name="name"></param>
         /// <returns></returns>
-        public BeckhoffStationAxis GetStationAxis(string moduleName, string name,int waferSize)
+        public BeckhoffStationAxis GetStationAxis(string moduleName, string name)
         {
             string strName = $"{moduleName}.{name}";
-            string str = $"{moduleName}.{name}.{waferSize}";
-            return _stationAxisDic.ContainsKey(str) ? _stationAxisDic[str] : (_stationAxisDic.ContainsKey(strName) ? _stationAxisDic[strName] : null);
+            return _stationAxisDic.ContainsKey(strName) ? _stationAxisDic[strName] : null;
         }
         /// <summary>
         /// 保存

+ 16 - 8
Framework/Common/Device/Galil/GalilControllerCfgManager.cs

@@ -98,7 +98,11 @@ namespace MECF.Framework.Common.Device.Galil
                             galilDevice.ReceiveTimeout = config.RecvTimeout;
                             galilDevice.SendTimeout = config.SendTimeout;
                             galilDevice.Initialize();
-                            _moduleGalilTcpDeviceDictionary[config.Module] = galilDevice;
+                            List<string> lst = _moduleNameLstDictionary[config.Module];
+                            foreach (var item in lst)
+                            {
+                                _moduleGalilTcpDeviceDictionary[item] = galilDevice;
+                            }
                         }
                         else
                         {
@@ -106,7 +110,11 @@ namespace MECF.Framework.Common.Device.Galil
                             galilDevice.ReceiveTimeout = config.RecvTimeout;
                             galilDevice.SendTimeout = config.SendTimeout;
                             galilDevice.Initialize();
-                            _moduleGalilTcpDeviceDictionary[config.Module] = galilDevice;
+                            List<string> lst = _moduleNameLstDictionary[config.Module];
+                            foreach (var item in lst)
+                            {
+                                _moduleGalilTcpDeviceDictionary[item] = galilDevice;
+                            }
                         }
                     }
                 }
@@ -302,12 +310,12 @@ namespace MECF.Framework.Common.Device.Galil
         /// <returns></returns>
         public bool SetSystemCommand(string module, string name, string commad, object value)
         {
-            if (!_moduleGalilTcpDeviceDictionary.ContainsKey(module))
+            string str = $"{module}.{name}";
+            if (!_moduleGalilTcpDeviceDictionary.ContainsKey(str))
             {
                 LOG.WriteLog(eEvent.ERR_GALIL, module, $"{module} does not have tcp device");
                 return false;
             }
-            string str = $"{module}.{name}";
             if (_moduleNameIndexDictionary.ContainsKey(str))
             {
                 int index = _moduleNameIndexDictionary[str];
@@ -325,7 +333,7 @@ namespace MECF.Framework.Common.Device.Galil
                 {
                     strCommand = $"{commad};";
                 }
-                return _moduleGalilTcpDeviceDictionary[module].SetGalilCommand(strCommand);
+                return _moduleGalilTcpDeviceDictionary[str].SetGalilCommand(strCommand);
             }
             else
             {
@@ -343,12 +351,12 @@ namespace MECF.Framework.Common.Device.Galil
         /// <returns></returns>
         public bool SetAxisCommand(string module, string name,string commad, object value) 
         {
-            if (!_moduleGalilTcpDeviceDictionary.ContainsKey(module))
+            string str = $"{module}.{name}";
+            if (!_moduleGalilTcpDeviceDictionary.ContainsKey(str))
             {
                 LOG.WriteLog(eEvent.ERR_GALIL, module, $"{module} does not have tcp device");
                 return false;
             }
-            string str = $"{module}.{name}";
             if(_moduleNameIndexDictionary.ContainsKey(str))
             {
                 int index = _moduleNameIndexDictionary[str];
@@ -367,7 +375,7 @@ namespace MECF.Framework.Common.Device.Galil
                 {
                     strCommand = $"{commad}{axis};";
                 }
-                return _moduleGalilTcpDeviceDictionary[module].SetGalilCommand(strCommand);
+                return _moduleGalilTcpDeviceDictionary[str].SetGalilCommand(strCommand);
             }
             else
             {

+ 7 - 7
Framework/Common/Simulator/MotorSimulator.cs

@@ -129,13 +129,13 @@ namespace MECF.Framework.Common.Simulator
                     {
                         foreach (GalilAxisConfig item in config.GalilAxises)
                         {
-                            _motorNameDataDic[$"{config.Module}.{item.Name}"] = new SimulatorMotionData();
-                            _motorNameDataDic[$"{config.Module}.{item.Name}"].FwdSoftLimit = item.ForwardSoftwareLimit;
-                            _motorNameDataDic[$"{config.Module}.{item.Name}"].RevSoftLimit = item.ReverseSoftwareLimit;
-                            _motorNameDataDic[$"{config.Module}.{item.Name}"].NegativeTorqueLimit = item.NegativeTorqueLimit;
-                            _motorNameDataDic[$"{config.Module}.{item.Name}"].PositiveTorqueLimit = item.PositiveTorqueLimit;
-                            _motorNameDataDic[$"{config.Module}.{item.Name}"].SwitchSignal = true;
-                            _motorNameDataDic[$"{config.Module}.{item.Name}"].ModuleName = config.Module;
+                            _motorNameDataDic[item.Name] = new SimulatorMotionData();
+                            _motorNameDataDic[item.Name].FwdSoftLimit = item.ForwardSoftwareLimit;
+                            _motorNameDataDic[item.Name].RevSoftLimit = item.ReverseSoftwareLimit;
+                            _motorNameDataDic[item.Name].NegativeTorqueLimit = item.NegativeTorqueLimit;
+                            _motorNameDataDic[item.Name].PositiveTorqueLimit = item.PositiveTorqueLimit;
+                            _motorNameDataDic[item.Name].SwitchSignal = true;
+                            _motorNameDataDic[item.Name].ModuleName = config.Module;
                         }
                     }
                 }

+ 2 - 2
Framework/Common/WaferHolder/WaferHolderManager.cs

@@ -87,7 +87,7 @@ namespace MECF.Framework.Common.WaferHolder
                 if (!string.IsNullOrEmpty(item.WaferAId))
                 {
                     WaferInfo waferInfo=WaferManager.Instance.GetWaferByWaferId(item.WaferAId);
-                    if (item.WaferAType == (int)WaferType.Production||waferInfo.WaferType==WaferType.Production)
+                    if (item.WaferAType == (int)WaferType.Production||waferInfo==null||waferInfo.WaferType==WaferType.Production)
                     {
                         WaferManager.Instance.DeleteWaferById(item.WaferAId);
                         item.WaferAId = $"{item.Id}.01";
@@ -115,7 +115,7 @@ namespace MECF.Framework.Common.WaferHolder
                 if (!string.IsNullOrEmpty(item.WaferBId))
                 {
                     WaferInfo waferInfo = WaferManager.Instance.GetWaferByWaferId(item.WaferBId);
-                    if (item.WaferBType == (int)WaferType.Production||waferInfo.WaferType==WaferType.Production)
+                    if (item.WaferBType == (int)WaferType.Production||waferInfo==null||waferInfo.WaferType==WaferType.Production)
                     {
                         WaferManager.Instance.DeleteWaferById(item.WaferBId);
                         item.WaferBId = $"{item.Id}.02";