Browse Source

Modify GALIL simulator;

niuyx 4 months ago
parent
commit
c54b4ddd75

+ 2 - 2
CyberX8_RT/Config/Devices/FestoControllerCfg-Simulator.xml

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <FestoControllerConfig>
 	<FestoDeviceConfig Name="Festo3" IpAddress="127.0.0.1" Port="502" SendTimeout="2000" RecvTimeout="2000" DIStartAddress="45395" Channel="1">
-		<DO Name="c_Transporter_Clamp"  Address="40003" Invert="false" Bit="0"/>
+		<DO Name="c_TRANSPORT1_DROP_BLOCK_LOCK"  Address="40003" Invert="false" Bit="0"/>
 		<DO Name="Festo.DO1" Address="40003" Invert="false" Bit="1"/>
-		<DO Name="c_Transporter2_Clamp"  Address="40003" Invert="false" Bit="2"/>
+		<DO Name="c_TRANSPORT2_DROP_BLOCK_LOCK"  Address="40003" Invert="false" Bit="2"/>
 		<DO Name="Festo.DO3" Address="40003" Invert="false" Bit="3"/>
 		<DO Name="c_Cathode_Clamp" Address="40003" Invert="false" Bit="4"/>
 		<DO Name="Festo.DO5" Address="40003" Invert="false" Bit="5"/>

+ 4 - 4
CyberX8_RT/Config/Devices/WagoControllerCfg-Simulator.xml

@@ -24,8 +24,8 @@
 				<DI Name="r_LoaderA_Wafer_Present"  Address="16" Invert="false"/>
 				<DI Name="r_LoaderB_Wafer_Present"  Address="17" Invert="false"/>
 				<DI Name="r_Cathode_Present"  Address="18" Invert="false"/>
-				<DI Name="r_TRANSPORT1_WS_HOLD_PRESENT"  Address="19" Invert="false"/>
-				<DI Name="r_TRANSPORT2_WS_HOLD_PRESENT"  Address="20" Invert="false"/>
+				<DI Name="DI19"  Address="19" Invert="false"/>
+				<DI Name="DI20"  Address="20" Invert="false"/>
 				<DI Name="DI21"  Address="21" Invert="false"/>
 				<DI Name="DI22"  Address="22" Invert="false"/>
 				<DI Name="DI23"  Address="23" Invert="false"/>
@@ -48,8 +48,8 @@
 				<DO Name="c_Pole_Blue"  Address="516" Invert="false"/>
 				<DO Name="c_System_Alarm2"  Address="517" Invert="false"/>
 				<DO Name="c_VACUUM_TEST"  Address="518" Invert="false"/>
-				<DO Name="c_TRANSPORT1_DROP_BLOCK_LOCK"  Address="519" Invert="false"/>
-				<DO Name="c_TRANSPORT2_DROP_BLOCK_LOCK"  Address="520" Invert="false"/>
+				<DO Name="DO7"  Address="519" Invert="false"/>
+				<DO Name="DO8"  Address="520" Invert="false"/>
 				<DO Name="DO9"  Address="521" Invert="false"/>
 				<DO Name="DO10"  Address="522" Invert="false"/>
 				<DO Name="DO11"  Address="523" Invert="false"/>

+ 9 - 8
CyberX8_RT/Modules/Transporter/TransporterPickDownToRoutine.cs

@@ -62,7 +62,6 @@ namespace CyberX8_RT.Modules.Transporter
         private JetAxisBase _gantryAxis;
         private JetAxisBase _elevatorAxis;
         private JetAxisBase _otherElevatorAxis;
-        private LoaderEntity _loaderEntity;
         private JetAxisBase _loaderRotationAxis;
         private SystemFacilities _facilities;
         private TransporterCommon _transporterCommon;
@@ -537,8 +536,7 @@ namespace CyberX8_RT.Modules.Transporter
         private void InitializeParameters()
         {
             _elevatorAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Elevator");
-            _gantryAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Gantry");
-            _loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(ModuleName.Loader1.ToString());
+            _gantryAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Gantry");            
             _loaderRotationAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Rotation");
             _facilities = DEVICE.GetDevice<SystemFacilities>("System.Facilities");
             _conflictRoutine = new TransporterConflictRoutine(Module);
@@ -559,13 +557,16 @@ namespace CyberX8_RT.Modules.Transporter
             {
                 return false;
             }
-                     
             //Loader is Home
-            if (!_loaderEntity.IsHomed)
+            if(ModuleHelper.IsInstalled(ModuleName.Loader1))
             {
-                NotifyError(eEvent.ERR_TRANSPORTER, $"{ModuleName.Loader1} is not homed", -1);
-                return false;
-            }
+                LoaderEntity loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(ModuleName.Loader1.ToString());
+                if (loaderEntity != null && !loaderEntity.IsHomed)
+                {
+                    NotifyError(eEvent.ERR_TRANSPORTER, $"{ModuleName.Loader1} is not homed", -1);
+                    return false;
+                }
+            }           
             //若目标Cell为Loader, 则Loader需在TRNA或TRANB位置且WaferShuttlePresent信号on
             if (_cellName == "Loader")
             {

+ 10 - 7
CyberX8_RT/Modules/Transporter/TransporterPickUpFromRoutine.cs

@@ -58,7 +58,6 @@ namespace CyberX8_RT.Modules.Transporter
         private string _cellName;
         private JetAxisBase _gantryAxis;
         private JetAxisBase _elevatorAxis;
-        private LoaderEntity _loaderEntity;
         private JetAxisBase _loaderRotationAxis;
         private SystemFacilities _facilities;
         private TransporterConflictRoutine _conflictRoutine;
@@ -468,8 +467,7 @@ namespace CyberX8_RT.Modules.Transporter
         {
             _cellName = objs[0].ToString();
             _elevatorAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Elevator");;
-            _gantryAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Gantry");
-            _loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(ModuleName.Loader1.ToString());
+            _gantryAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Gantry");            
             _loaderRotationAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Rotation");
             _conflictRoutine = new TransporterConflictRoutine(Module);
             _transporterCommon = DEVICE.GetDevice<TransporterCommon>($"{Module}.Common");
@@ -509,11 +507,16 @@ namespace CyberX8_RT.Modules.Transporter
                 return false;
             }
             //Loader is Home
-            if (_loaderEntity!=null&&!_loaderEntity.IsHomed)
+            if (ModuleHelper.IsInstalled(ModuleName.Loader1))
             {
-                NotifyError(eEvent.ERR_TRANSPORTER, $"{ModuleName.Loader1} is not homed", -1);
-                return false;
-            }
+                //Loader is Home
+                LoaderEntity loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(ModuleName.Loader1.ToString());
+                if (loaderEntity != null && !loaderEntity.IsHomed)
+                {
+                    NotifyError(eEvent.ERR_TRANSPORTER, $"{ModuleName.Loader1} is not homed", -1);
+                    return false;
+                }
+            }              
             //若目标Cell为Loader, 则Loader需在TRNA或TRANB位置且WaferShuttlePresent信号on
             if (_cellName == "Loader")
             {

+ 2 - 0
CyberX8_Simulator/Config/SimulatorIOMapCfg.xml

@@ -10,4 +10,6 @@
 	<SimulatorIOMapItem SourceIOName="c_LOADERB_BERNOULLI_N2" TargetIONameA="r_LOADERB_BERNOULLI_PRESSURE"/>
 	<SimulatorIOMapItem SourceIOName="c_DPUF_A_CHUCK_A_RELEASE" TargetIONameA="r_DPUF_A_CHUCK_A_VAC"/>
 	<SimulatorIOMapItem SourceIOName="c_DPUF_A_CHUCK_B_RELEASE" TargetIONameA="r_DPUF_A_CHUCK_B_VAC"/>
+	<SimulatorIOMapItem SourceIOName="c_TRANSPORT1_DROP_BLOCK_LOCK" TargetIONameA="ProcessTransporterLock"/>			
+	<SimulatorIOMapItem SourceIOName="c_TRANSPORT2_DROP_BLOCK_LOCK" TargetIONameA="LoaderTransporterLock"/>			
 </SimulatorIOMapConfig>

+ 24 - 3
CyberX8_Simulator/Devices/GalilSocketSimulator.cs

@@ -1,5 +1,6 @@
 using Aitex.Common.Util;
 using Aitex.Core.RT.Log;
+using Aitex.Core.UI.Converters;
 using Aitex.Core.Util;
 using MECF.Framework.Common.Beckhoff.AxisProvider;
 using MECF.Framework.Common.Device.Galil;
@@ -77,6 +78,10 @@ namespace CyberX8_Simulator.Devices
         /// MotorPosition比例系数字典(index - motorPositionRate)
         /// </summary>
         private Dictionary<string, double> _motorPositionRateDic = new Dictionary<string, double>();
+        /// <summary>
+        /// Key:dataName - Value:GalilDI
+        /// </summary>
+        private Dictionary<string, GalilDI> _inputDataNameDIDic = new Dictionary<string, GalilDI>();
         #endregion
         /// <summary>
         /// 构造函数
@@ -196,8 +201,8 @@ namespace CyberX8_Simulator.Devices
             _galilControlData.Outputs = new byte[10];             
             
             //电机数据更新事件
-            MotorSimulator.Instance.OnUpdateVariableValueChanged += UpdataRealTimeMotionData;
-
+            MotorSimulator.Instance.OnUpdateMotionDatasChanged += UpdateRealTimeMotionData;
+            MotorSimulator.Instance.OnUpdateInputDatasChanged += UpdateInputData;
             //加载GalilControllerCfg-Simulator.xml
             try
             {
@@ -212,11 +217,16 @@ namespace CyberX8_Simulator.Devices
                         {
                             _moduleName = config.Module;
                             _galilType = config.GalilType;
+
                             foreach (GalilAxisConfig item in config.GalilAxises)
                             {
                                 _axisNameIndexDic[$"{config.Module}.{item.Name}"] = item.Index;
                                 _nameAxisList[item.Index] = $"{config.Module}.{item.Name}";
                             }
+                            foreach(var items in config.GalilDigIn.DIs)
+                            {
+                                _inputDataNameDIDic[items.Name] = items;
+                            }
                         }
                     }
                 }               
@@ -557,7 +567,7 @@ namespace CyberX8_Simulator.Devices
         /// 实时更新电机数据
         /// </summary>
         /// <param name="datasDic"></param>
-        private void UpdataRealTimeMotionData(Dictionary<string, SimulatorMotionData> datasDic)
+        private void UpdateRealTimeMotionData(Dictionary<string, SimulatorMotionData> datasDic)
         {
             foreach(var dataItem in datasDic)
             {
@@ -568,6 +578,17 @@ namespace CyberX8_Simulator.Devices
             }
         }
         /// <summary>
+        /// 更新Galil Input datas
+        /// </summary>
+        private void UpdateInputData(string module, string VariableName, bool value) 
+        {
+            if(_moduleName == module)
+            {
+                int tmp = _inputDataNameDIDic[VariableName].Invert ? (!value ? 1 : 0) : (value ? 1 : 0);
+                _galilControlData.Inputs[_inputDataNameDIDic[VariableName].Address] = (byte)(tmp << _inputDataNameDIDic[VariableName].Bit);
+            }
+        }
+        /// <summary>
         /// 更新对应Axis数据
         /// </summary>
         /// <param name="index"></param>

+ 125 - 29
Framework/Common/Simulator/MotorSimulator.cs

@@ -1,6 +1,9 @@
 using Aitex.Common.Util;
+using Aitex.Core.RT.Device;
 using Aitex.Core.RT.Log;
+using Aitex.Core.RT.Routine;
 using Aitex.Core.Util;
+using CyberX8_Core;
 using MECF.Framework.Common.Beckhoff.AxisProvider;
 using MECF.Framework.Common.Beckhoff.Station;
 using MECF.Framework.Common.Device.Galil;
@@ -8,6 +11,7 @@ using MECF.Framework.Common.Equipment;
 using System;
 using System.Collections.Generic;
 using System.IO;
+using System.Runtime.InteropServices.ComTypes;
 
 namespace MECF.Framework.Common.Simulator
 {
@@ -29,6 +33,8 @@ namespace MECF.Framework.Common.Simulator
         private const string HOMING_SIGNAL = "HomingSignal";
         private const string MOTION_SIGNAL = "MotionSignal";
         private const string STOP_SIGNAL = "StopSignal";
+        private const string FESTO_DATABUFFER_TRANSPORT1_LOCK = "ProcessTransporterLock";
+        private const string FESTO_DATABUFFER_TRANSPORT2_LOCK = "LoaderTransporterLock";
         /// <summary>
         /// 定时器间隔(ms)
         /// </summary>
@@ -52,6 +58,22 @@ namespace MECF.Framework.Common.Simulator
         /// Key:moduleName, Value:minStep
         /// </summary>
         private Dictionary<string, int> _motorNameMinStepDic = new Dictionary<string, int>();
+        /// <summary>
+        /// Key:stationName, Value:position
+        /// </summary>
+        private Dictionary<string, double> _stationPositionDic = new Dictionary<string, double>();
+        /// <summary>
+        /// Key:stationName, Value:Tolerance
+        /// </summary>
+        private Dictionary<string, double> _toleranceDic = new Dictionary<string, double>();
+        /// <summary>
+        /// Key:stationName, Value:BeckhoffProviderAxis
+        /// </summary>
+        private Dictionary<string, BeckhoffProviderAxis> _axisDataDic = new Dictionary<string, BeckhoffProviderAxis>();
+        /// <summary>
+        /// 其他模块数据
+        /// </summary>
+        private Dictionary<string, bool> _otherModuleDataDic = new Dictionary<string, bool>();
         #endregion
 
         #region 属性
@@ -60,14 +82,19 @@ namespace MECF.Framework.Common.Simulator
 
         //delegate
         #region Delegate
-        public delegate void UpdateVariableValueChanged(Dictionary<string, SimulatorMotionData> datasDic);
+        public delegate void UpdateVariableValueMotionDatasChanged(Dictionary<string, SimulatorMotionData> datasDic);
+        public delegate void UpdateVariableValueInputDatasChanged(string module, string VariableName, bool value);
         #endregion
 
         #region 事件
         /// <summary>
-        /// 变量变更事件
+        /// MotionDatas变更事件
+        /// </summary>
+        public event UpdateVariableValueMotionDatasChanged OnUpdateMotionDatasChanged;
+        /// <summary>
+        /// InputDatas变更事件
         /// </summary>
-        public event UpdateVariableValueChanged OnUpdateVariableValueChanged;
+        public event UpdateVariableValueInputDatasChanged OnUpdateInputDatasChanged;
         #endregion
         /// <summary>
         /// 初始化
@@ -82,6 +109,8 @@ namespace MECF.Framework.Common.Simulator
         /// </summary>
         private void Init()
         {
+            SimulatorCommManager.Instance.OnUpdateVariableValueChanged += UpdataDataCausedByOtherModule;
+            InitOtherModuleDatas();
             //加载对应配置文件 GalilControllerCfg-Simulator.xml,初始化数据字典
             try
             {
@@ -100,6 +129,7 @@ namespace MECF.Framework.Common.Simulator
                             _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;
                         }
                     }
                 }
@@ -120,6 +150,7 @@ namespace MECF.Framework.Common.Simulator
                     foreach (BeckhoffProviderAxis item in axisProviderCfg.Axes)
                     {
                         double value = item.ScaleFactor / 30;
+                        _axisDataDic[item.Name] = item;
                         _motorNameMinStepDic[item.Name] = (int)((value < 100) ? 100 : value);                        
                     }
                 }
@@ -132,35 +163,39 @@ namespace MECF.Framework.Common.Simulator
             try
             {
                 string oldXmlPath = PathManager.GetCfgDir();
-                string newXmlPath = oldXmlPath.Replace("CyberX8_Simulator", "CyberX8_RT") + "Devices\\StationPositionsCfg_Simulator.xml";
+                string newXmlPath = oldXmlPath.Replace("CyberX8_Simulator", "CyberX8_RT") + "Station\\StationPositionsCfg_Simulator.xml";
                 StationPositionCfg cfg = CustomXmlSerializer.Deserialize<StationPositionCfg>(new FileInfo(newXmlPath));
                 if (cfg != null)
                 {
-                    //foreach (BeckhoffStationModule config in cfg.Module)
-                    //{
-                    //    if (config.Name == ModuleName.Transporter1.ToString())
-                    //    {
-                    //        foreach (BeckhoffStationAxis item in config.Axises)
-                    //        {
-                    //            ;
-                    //        }
-                    //    }
-                    //    else if(config.Name == ModuleName.Transporter2.ToString())
-                    //    {
-                    //        foreach (BeckhoffStationAxis item in config.Axises)
-                    //        {
-                    //            ;
-                    //        }
-                    //    }
-                        
-                    //}
+                    foreach (BeckhoffStationModule config in cfg.Module)
+                    {
+                        if (config.Name.Contains("Transporter"))
+                        {
+                            foreach (BeckhoffStationAxis item in config.Axises)
+                            {
+                                _toleranceDic[item.Name] = item.ToleranceDefault;
+                                if (item.Name.Contains("Elevator"))
+                                {
+                                    foreach(var subItem in item.Stations)
+                                    {
+                                        _stationPositionDic[subItem.Name.ToLower()] = double.Parse(subItem.Position);
+                                    }                                   
+                                }
+                            }
+                        }                        
+                    }
                 }
             }
             catch
             {
-                LOG.WriteLog(eEvent.ERR_GALIL, "Galil", "Load galil GalilControllerCfg-Simulator.xml failed");
+                LOG.WriteLog(eEvent.ERR_GALIL, "StationPosition", "Load StationPositionCfg-Simulator.xml failed");
             }
         }
+        private void InitOtherModuleDatas()
+        {
+            _otherModuleDataDic[FESTO_DATABUFFER_TRANSPORT1_LOCK] = false;
+            _otherModuleDataDic[FESTO_DATABUFFER_TRANSPORT2_LOCK] = false;
+        }
         /// <summary>
         /// 定时器执行
         /// </summary>
@@ -173,23 +208,38 @@ namespace MECF.Framework.Common.Simulator
                 //对应电机进行模拟
                 MotorMotionSimulator(motorItem);
                 //实时更新电机数据
-                UpdateVariableValue(_motorNameDataDic);
+                UpdateMotionDatas(_motorNameDataDic);
+                //更新InputDatas
+                UpdateInputDatas(motorItem);                              
             }
             
             return true;
         }
         /// <summary>
-        /// 通知Galil模块数据变化
+        /// 通知Galil模块motion数据变化
         /// </summary>
         /// <param name="data"></param>
-        private void UpdateVariableValue(Dictionary<string, SimulatorMotionData> datasDic)
+        private void UpdateMotionDatas(Dictionary<string, SimulatorMotionData> datasDic)
         {
-            if (OnUpdateVariableValueChanged != null)
+            if (OnUpdateMotionDatasChanged != null)
             {
-                OnUpdateVariableValueChanged(datasDic);
+                OnUpdateMotionDatasChanged(datasDic);
             }
         }
         /// <summary>
+        /// 通知Galil模块Input数据变化
+        /// </summary>
+        /// <param name="module"></param>
+        /// <param name="value"></param>
+        private void UpdateInputDatas(KeyValuePair<string, SimulatorMotionData> motorItem)
+        {         
+            if (OnUpdateInputDatasChanged != null && CheckMotionData(motorItem, out string VariableName, out bool value))
+            {
+                OnUpdateInputDatasChanged(motorItem.Value.ModuleName, VariableName, value);
+            }
+        }
+
+        /// <summary>
         /// 设置电机数据
         /// </summary>
         /// <param name="axisName"></param>
@@ -357,6 +407,52 @@ namespace MECF.Framework.Common.Simulator
             }
             return speed;
         }
-
+        /// <summary>
+        /// 检查电机数据
+        /// </summary>
+        /// <returns></returns>
+        private bool CheckMotionData(KeyValuePair<string, SimulatorMotionData> motor, out string name,out bool value)
+        {
+            bool result = false;
+            value = false;
+            name = "";
+            switch (motor.Key) 
+            {
+                case "Transporter1.Elevator":
+                    name = "r_TRANSPORT1_WS_HOLD_PRESENT";
+                    value = _otherModuleDataDic[FESTO_DATABUFFER_TRANSPORT1_LOCK] && CheckAtStation(motor.Key, motor.Value, "up") ? true : false; 
+                    result = true;
+                    break;
+                case "Transporter2.Elevator":
+                    name = "r_TRANSPORT2_WS_HOLD_PRESENT";
+                    value = _otherModuleDataDic[FESTO_DATABUFFER_TRANSPORT2_LOCK] && CheckAtStation(motor.Key, motor.Value, "up") ? true : false;
+                    result = true;
+                    break;
+                default:
+                    break;
+            }  
+            return result;
+        }
+        /// <summary>
+        /// 更新其他模块数据
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="value"></param>
+        private void UpdataDataCausedByOtherModule(string name, bool value)
+        {
+            if (_otherModuleDataDic.ContainsKey(name))
+            {
+                _otherModuleDataDic[name] = value;
+            }
+        }
+        private bool CheckAtStation(string name, SimulatorMotionData data, string stationName)
+        {
+            double diff = Math.Abs(data.ActualPosition - _stationPositionDic[$"{name.ToLower()}.{stationName.ToLower()}"] * _axisDataDic[name].ScaleFactor);
+            if (diff <= _toleranceDic[name] * _axisDataDic[name].ScaleFactor)
+            {
+                return true;
+            }
+            return false;
+        }
     }
 }

+ 8 - 1
Framework/Common/Simulator/SimulatorMotionData.cs

@@ -1,4 +1,5 @@
 using MECF.Framework.Common.CommonData;
+using System.Drawing;
 using System.Runtime.Serialization;
 
 namespace MECF.Framework.Common.Simulator
@@ -173,6 +174,12 @@ namespace MECF.Framework.Common.Simulator
             get { return _stopSignal; }
             set { _stopSignal = value; InvokePropertyChanged(nameof(StopSignal)); }
         }
+        [DataMember]
+        public string ModuleName
+        {
+            get { return _moduleName; }
+            set { _moduleName = value; InvokePropertyChanged(nameof(ModuleName)); }
+        }
         #endregion
 
         #region 内部变量
@@ -217,7 +224,7 @@ namespace MECF.Framework.Common.Simulator
         private int _negativeTorqueLimit;
         private int _positiveTorqueLimit;
 
-        
+        private string _moduleName;
         #endregion
     }
 }