Browse Source

add Plating cell vertical Module

chenkui 1 day ago
parent
commit
b11c469645

+ 24 - 1
Framework/Common/Device/ModuleName.cs

@@ -141,6 +141,28 @@ namespace MECF.Framework.Common.Equipment
         PlatingCell3,
         [EnumMember]
         PlatingCell4,
+        [EnumMember]
+        PlatingCell5,
+        [EnumMember]
+        PlatingCell6,
+        [EnumMember]
+        PlatingCell7,
+        [EnumMember]
+        PlatingCell8,
+        [EnumMember]
+        PlatingCell9,
+        [EnumMember]
+        PlatingCell10,
+        [EnumMember]
+        PlatingCell1_2,
+        [EnumMember]
+        PlatingCell3_4,
+        [EnumMember]
+        PlatingCell5_6,
+        [EnumMember]
+        PlatingCell7_8,
+        [EnumMember]
+        PlatingCell9_10
     }
 
     /// <summary>
@@ -165,7 +187,8 @@ namespace MECF.Framework.Common.Equipment
         Reservoir,
         VpwMain,
         VPW,
-        PlatingCell
+        PlatingCell,
+        PlatingCellVertical
     }
     public static class ModuleHelper
     {

+ 4 - 0
Framework/Common/ToolLayout/PlatingCellItem.cs

@@ -27,5 +27,9 @@ namespace MECF.Framework.Common.ToolLayout
         /// 是否有独立的泵
         /// </summary>
         public bool DepPump { get; set; }
+        /// <summary>
+        /// 垂直电机ID
+        /// </summary>
+        public string VerticalID { get; set; }
     }
 }

+ 1 - 1
Framework/Common/ToolLayout/PlatingCellItemManager.cs

@@ -46,6 +46,7 @@ namespace MECF.Framework.Common.ToolLayout
             platingCellItem.PlatingCellID = int.Parse(platingCellItemElement.SelectSingleNode("PlatingCellID").InnerText);
             platingCellItem.PermittedWaferSizeInMM = platingCellItemElement.SelectSingleNode("PermittedWaferSizeInMM").InnerText;
             platingCellItem.PlatingPowerSupplyID = platingCellItemElement.SelectSingleNode("PlatingPowerSupplyID").InnerText;
+            platingCellItem.VerticalID = platingCellItemElement.SelectSingleNode("VerticalID").InnerText;
             string key = $"{PREFIX}{platingCellItem.PlatingCellID}";
             platingCellItem.ModuleName = key;
             platingCellItem.ModuleType = ModuleType.PlatingCell.ToString();
@@ -55,7 +56,6 @@ namespace MECF.Framework.Common.ToolLayout
                 InstalledModules.Add(key);
             }
 
-
             PowerSupplierDevice powerSupplierDevice = PowerSupplierDeviceConfigManager.Instance.GetPowerSupplierDeviceByName(platingCellItem.PlatingPowerSupplyID);
             if (powerSupplierDevice != null)
             {

+ 10 - 0
PunkHPX8_Core/RtState.cs

@@ -171,4 +171,14 @@ namespace PunkHPX8_Core
         CCRing,
         RunReciping
     }
+    public enum PlatingCellVerticalState
+    {
+        Unknown,
+        Disable,
+        Error,
+        Init,
+        Initializing,
+        Initialized,
+        Idle
+    }
 }

+ 4 - 0
PunkHPX8_RT/Config/Layout/ToolLayoutConfiguration.xml

@@ -182,6 +182,7 @@
 					<PlatingCellID>1</PlatingCellID>
 					<PlatingPowerSupplyID>Power1-1</PlatingPowerSupplyID>
 					<SubType>DegasMembrance</SubType>
+					<VerticalID>PlatingCell1_2</VerticalID>
 				</Item>
 			</PlatingCells>
 			<CellPosition>13</CellPosition>
@@ -217,6 +218,7 @@
 					<PlatingCellID>2</PlatingCellID>
 				    <PlatingPowerSupplyID>Power2-1</PlatingPowerSupplyID>
 					<SubType>DegasMembrance</SubType>
+					<VerticalID>PlatingCell1_2</VerticalID>
 				</Item>
 			</PlatingCells>
 			<CellPosition>14</CellPosition>
@@ -252,6 +254,7 @@
 					<PlatingCellID>3</PlatingCellID>
 					<PlatingPowerSupplyID>Power3-1</PlatingPowerSupplyID>
 					<SubType>DegasMembrance</SubType>
+					<VerticalID>PlatingCell3_4</VerticalID>
 				</Item>
 			</PlatingCells>
 			<CellPosition>15</CellPosition>
@@ -287,6 +290,7 @@
 					<PlatingCellID>4</PlatingCellID>
 				    <PlatingPowerSupplyID>Power4-1</PlatingPowerSupplyID>
 					<SubType>DegasMembrance</SubType>
+					<VerticalID>PlatingCell3_4</VerticalID>
 				</Item>
 			</PlatingCells>
 			<CellPosition>16</CellPosition>

+ 13 - 18
PunkHPX8_RT/Devices/DeviceManager.cs

@@ -23,6 +23,7 @@ using PunkHPX8_RT.Devices.SRD;
 using PunkHPX8_RT.Devices.Temperature;
 using PunkHPX8_RT.Devices.VpwCell;
 using PunkHPX8_RT.Devices.VpwMain;
+using PunkHPX8_RT.Modules;
 using SecsGem.Core.ItemModel;
 using System;
 using System.Collections.Generic;
@@ -76,8 +77,8 @@ namespace PunkHPX8_RT.Instances
             InitializePowerSuppliers();
             InitializeVpw();
             InitializeReservoir();
-            InitializePlatingVerticals();
             InitializePlatingCells();
+            InitializePlatingVerticals();
 
             TotalReservoirDevice totalReservoirDevice = new TotalReservoirDevice();
             AddCustomDevice(totalReservoirDevice);
@@ -116,7 +117,6 @@ namespace PunkHPX8_RT.Instances
 
             foreach(string item in VpwCellItemManager.Instance.InstalledModules)
             {
-
                 BeckhoffAxis rotationBeckhoffAxis = BeckhoffAxisManager.Instance.GetAxis($"{item}.Rotation");
                 if (rotationBeckhoffAxis != null)
                 {
@@ -127,7 +127,6 @@ namespace PunkHPX8_RT.Instances
                 }
                 VpwCellDevice vpwCellDevice= new VpwCellDevice(item);
                 AddCustomDevice(vpwCellDevice);
-
             }
 
             VpwDeviceTimer vpwDeviceTimer = new VpwDeviceTimer();
@@ -140,6 +139,8 @@ namespace PunkHPX8_RT.Instances
         {
             foreach (string item in PlatingCellItemManager.Instance.InstalledModules)
             {
+                PlatingCellItem platingCellItem = PlatingCellItemManager.Instance.GetPlatingCellItem(item);
+                ModuleMatcherManager.Instance.InitialPlatingCellVerticalID(platingCellItem.ModuleName, platingCellItem.VerticalID);
                 //初始化platingcell rotation轴
                 BeckhoffAxis rotationBeckhoffAxis = BeckhoffAxisManager.Instance.GetAxis($"{item.ToString()}.Rotation");
                 if (rotationBeckhoffAxis != null)
@@ -150,7 +151,6 @@ namespace PunkHPX8_RT.Instances
                 }
                
 
-                PlatingCellItem platingCellItem = PlatingCellItemManager.Instance.GetPlatingCellItem(item);
                 if (platingCellItem.SubType == ReservoirType.DegasMembrance.ToString())
                 {
                     DMPlatingCellDevice platingCellDevice = new DMPlatingCellDevice(item);
@@ -166,8 +166,6 @@ namespace PunkHPX8_RT.Instances
                     DIPlatingCellDevice platingCellDevice = new DIPlatingCellDevice(item);
                     AddCustomDevice(platingCellDevice);
                 }
-
-                
             }
         }
         /// <summary>
@@ -175,19 +173,16 @@ namespace PunkHPX8_RT.Instances
         /// </summary>
         private void InitializePlatingVerticals()
         {
-            BeckhoffAxis verticalBeckhoffAxis1_2 = BeckhoffAxisManager.Instance.GetAxis("PlatingCell1_2.Vertical");
-            if (verticalBeckhoffAxis1_2 != null)
-            {
-                JetAxisBase verticalAxis = AxisManager.Instance.GetAxisInstance(verticalBeckhoffAxis1_2.MotorType, "PlatingCell1_2", "Vertical");
-                AddCustomModuleDevice(verticalAxis);
-                AxisManager.Instance.AddModuleAxis("PlatingCell1_2", verticalAxis);
-            }
-            BeckhoffAxis verticalBeckhoffAxis3_4 = BeckhoffAxisManager.Instance.GetAxis("PlatingCell3_4.Vertical");
-            if (verticalBeckhoffAxis3_4 != null)
+            List<string> lst = ModuleMatcherManager.Instance.GetAllPlatingCellVertialList();
+            foreach (string str in lst)
             {
-                JetAxisBase verticalAxis3 = AxisManager.Instance.GetAxisInstance(verticalBeckhoffAxis3_4.MotorType, "PlatingCell3_4", "Vertical");
-                AddCustomModuleDevice(verticalAxis3);
-                AxisManager.Instance.AddModuleAxis("PlatingCell3_4", verticalAxis3);
+                BeckhoffAxis verticalBeckhoffAxis1_2 = BeckhoffAxisManager.Instance.GetAxis($"{str}.Vertical");
+                if (verticalBeckhoffAxis1_2 != null)
+                {
+                    JetAxisBase verticalAxis = AxisManager.Instance.GetAxisInstance(verticalBeckhoffAxis1_2.MotorType, str, "Vertical");
+                    AddCustomModuleDevice(verticalAxis);
+                    AxisManager.Instance.AddModuleAxis(str, verticalAxis);
+                }
             }
         }
         /// <summary>

+ 40 - 0
PunkHPX8_RT/Modules/ModuleMatcherManager.cs

@@ -17,9 +17,16 @@ namespace PunkHPX8_RT.Modules
             { ModuleName.PlatingCell2.ToString(),ModuleName.PlatingCell1.ToString()},
             { ModuleName.PlatingCell3.ToString(),ModuleName.PlatingCell4.ToString()},
             { ModuleName.PlatingCell4.ToString(),ModuleName.PlatingCell3.ToString()},
+            { ModuleName.PlatingCell5.ToString(),ModuleName.PlatingCell6.ToString()},
+            { ModuleName.PlatingCell6.ToString(),ModuleName.PlatingCell5.ToString()},
+            { ModuleName.PlatingCell7.ToString(),ModuleName.PlatingCell8.ToString()},
+            { ModuleName.PlatingCell8.ToString(),ModuleName.PlatingCell7.ToString()},
+            { ModuleName.PlatingCell9.ToString(),ModuleName.PlatingCell10.ToString()},
+            { ModuleName.PlatingCell10.ToString(),ModuleName.PlatingCell9.ToString()},
             { ModuleName.VPW1.ToString(),ModuleName.VPW2.ToString()},
             { ModuleName.VPW2.ToString(),ModuleName.VPW1.ToString()},
         };
+        private Dictionary<string, string> _platingCellVerticalMatcher = new Dictionary<string, string>();
         #endregion
         /// <summary>
         /// 获取配对模块
@@ -36,5 +43,38 @@ namespace PunkHPX8_RT.Modules
                 return "";
             }
         }
+        /// <summary>
+        /// 初始化PlatingCell和垂直电机ID
+        /// </summary>
+        /// <param name="platingCellId"></param>
+        /// <param name="verticalId"></param>
+        public void InitialPlatingCellVerticalID(string platingCellId,string verticalId)
+        {
+            _platingCellVerticalMatcher[platingCellId] = verticalId;
+        }
+        /// <summary>
+        /// 获取所有的PlatingCell的垂直电机集合
+        /// </summary>
+        /// <returns></returns>
+        public List<string> GetAllPlatingCellVertialList()
+        {
+            return _platingCellVerticalMatcher.Values.Distinct().ToList();
+        }
+        /// <summary>
+        /// 根据Plating获取Vertical
+        /// </summary>
+        /// <param name="cell"></param>
+        /// <returns></returns>
+        public string GetPlatingVerticalByCell(string cell)
+        {
+            if (_platingCellVerticalMatcher.ContainsKey(cell))
+            {
+                return _platingCellVerticalMatcher[cell];
+            }
+            else
+            {
+                return "";
+            }
+        }
     }
 }

+ 179 - 0
PunkHPX8_RT/Modules/PlatingCell/PlatingCellVerticalEntity.cs

@@ -0,0 +1,179 @@
+using Aitex.Core.RT.Fsm;
+using Aitex.Core.RT.Log;
+using Aitex.Core.Util;
+using Aitex.Core.Utilities;
+using MECF.Framework.Common.Equipment;
+using MECF.Framework.Common.Persistent.Reservoirs;
+using MECF.Framework.Common.Persistent.Temperature;
+using MECF.Framework.Common.ToolLayout;
+using PunkHPX8_Core;
+using PunkHPX8_RT.Modules.Reservoir;
+using PunkHPX8_RT.Modules.VpwCell;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using static PunkHPX8_RT.Modules.PlatingCell.PlatingCellEntity;
+
+namespace PunkHPX8_RT.Modules.PlatingCell
+{
+    public class PlatingCellVerticalEntity : Entity, IEntity, IModuleEntity
+    {
+        public enum VerticalMsg
+        {
+            NONE,
+            Error,
+            ResumeError,
+            Initialize,
+            Abort,
+            Init
+        }
+
+        #region 内部变量
+        private PlatingCellVerticalInitializeRoutine _initializeRoutine;
+        #endregion
+
+        #region 属性
+        /// <summary>
+        /// 模块名称
+        /// </summary>
+        public ModuleName Module { get; private set; }
+        /// <summary>
+        /// 是否Init
+        /// </summary>
+        public bool IsInit
+        {
+            get { return fsm.State == (int)PlatingCellVerticalState.Init; }
+        }
+        /// <summary>
+        /// 是否Idle
+        /// </summary>
+        public bool IsIdle
+        {
+            get
+            {
+                return fsm.State == (int)PlatingCellVerticalState.Idle;
+            }
+        }
+        /// <summary>
+        /// 是否错误
+        /// </summary>
+        public bool IsError
+        {
+            get { return fsm.State == (int)PlatingCellVerticalState.Error; }
+        }
+        /// <summary>
+        /// 正在忙碌
+        /// </summary>
+        public bool IsBusy
+        {
+            get { return fsm.State == (int)PlatingCellVerticalState.Initializing; }
+        }
+        /// <summary>
+        /// 状态
+        /// </summary>
+        public int State { get { return fsm.State; } }
+        public bool IsDisable { get { return false; } }
+
+        public bool IsAuto { get { return true; } }
+
+        public bool IsEngineering { get { return false; } }
+
+        public bool IsProduction { get { return true; } }
+        #endregion
+
+        /// <summary>
+        /// 构造函数
+        /// </summary>
+        /// <param name="module"></param>
+        public PlatingCellVerticalEntity(ModuleName module)
+        {
+            Module = module;
+            
+            InitialFsm();
+        }
+        /// <summary>
+        /// 初始化
+        /// </summary>
+        /// <returns></returns>
+        protected override bool Init()
+        {
+            InitializeRoutine();
+            return true;
+        }
+        /// <summary>
+        /// 初始化Routine
+        /// </summary>
+        private void InitializeRoutine()
+        {
+            _initializeRoutine = new PlatingCellVerticalInitializeRoutine(Module.ToString());
+        }
+
+        /// 初始化状态机
+        /// </summary>
+        private void InitialFsm()
+        {
+            fsm = new StateMachine<PlatingCellVerticalEntity>(Module.ToString(), (int)PlatingCellVerticalState.Init, 100);
+            fsm.EnableRepeatedMsg(true);
+
+            AnyStateTransition(VerticalMsg.Initialize, InitializeAll, PlatingCellVerticalState.Initializing);
+            Transition(PlatingCellVerticalState.Initializing, FSM_MSG.TIMER, InitializeAllMonitor, PlatingCellVerticalState.Idle);
+            AnyStateTransition(VerticalMsg.Error, NullFunc, PlatingCellVerticalState.Error);
+            //Enter Init
+            Transition(PlatingCellVerticalState.Idle, VerticalMsg.Init, NullFunc, PlatingCellVerticalState.Init);
+
+            EnumLoop<PlatingCellVerticalState>.ForEach((item) => { fsm.MapState((int)item, item.ToString()); });
+
+            EnumLoop<VerticalMsg>.ForEach((item) => { fsm.MapMessage((int)item, item.ToString()); });
+        }
+
+        #region 初始化
+        /// <summary>
+        /// 初始化
+        /// </summary>
+        /// <returns></returns>
+        private bool InitializeAll(object[] param)
+        {
+            return _initializeRoutine.Start() == RState.Running;
+        }
+        /// <summary>
+        /// Initialize 监控
+        /// </summary>
+        /// <param name="param"></param>
+        /// <returns></returns>
+        private bool InitializeAllMonitor(object[] param)
+        {
+            RState rsstate = _initializeRoutine.Monitor();
+            if (rsstate == RState.End)
+            {
+                return true;
+            }
+            else if (rsstate == RState.Failed || rsstate == RState.Timeout)
+            {
+                PostMsg(VerticalMsg.Error);
+                return false;
+            }
+            return false;
+        }
+
+        #endregion
+
+
+        public bool Check(int msg, out string reason, params object[] args)
+        {
+            reason = "";
+            return true;
+        }
+
+        public bool CheckAcked(int msg)
+        {
+            return true;
+        }
+
+        public int Invoke(string function, params object[] args)
+        {
+            return (int)FSM_MSG.NONE;
+        }
+    }
+}

+ 145 - 0
PunkHPX8_RT/Modules/PlatingCell/PlatingCellVerticalInitializeRoutine.cs

@@ -0,0 +1,145 @@
+using Aitex.Core.RT.Device;
+using Aitex.Core.RT.Log;
+using Aitex.Core.RT.Routine;
+using Aitex.Core.RT.SCCore;
+using MECF.Framework.Common.Persistent.Reservoirs;
+using MECF.Framework.Common.RecipeCenter;
+using MECF.Framework.Common.Routine;
+using MECF.Framework.Common.ToolLayout;
+using PunkHPX8_Core;
+using PunkHPX8_RT.Devices.AXIS;
+using PunkHPX8_RT.Devices.PlatingCell;
+using PunkHPX8_RT.Devices.Reservoir;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.Eventing.Reader;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media.Imaging;
+
+namespace PunkHPX8_RT.Modules.PlatingCell
+{
+    public class PlatingCellVerticalInitializeRoutine : RoutineBase, IRoutine
+    {
+        private enum InitializeStep
+        {
+            VerticalHome,
+            VerticalHomeCheck,
+            GoToLoad,
+            GoToLoadCheck,
+            End
+        }
+
+        #region 内部变量
+        /// <summary>
+        /// vertical axis
+        /// </summary>
+        private JetAxisBase _verticalAxis; 
+        #endregion
+
+        /// <summary>
+        /// 构造函数
+        /// </summary>
+        /// <param name="module"></param>
+        public PlatingCellVerticalInitializeRoutine(string module) : base(module)
+        {
+        }
+
+        /// <summary>
+        /// 中止
+        /// </summary>
+        public void Abort()
+        {
+            Runner.Stop("Manual Abort");
+        }
+        /// <summary>
+        /// 监控
+        /// </summary>
+        /// <returns></returns>
+        public RState Monitor()
+        {
+            Runner.Run(InitializeStep.VerticalHome, Home, NullFun, 100)
+                .WaitWithStopCondition(InitializeStep.VerticalHomeCheck, CheckVerticalPositionStatus, CheckVerticalPositionRunStop)
+                .Run(InitializeStep.GoToLoad, VerticalGotoLoad, 100)
+                .WaitWithStopCondition(InitializeStep.GoToLoadCheck, CheckVerticalPositionStatus, CheckVerticalPositionRunStop)
+                .End(InitializeStep.End, NullFun, _delay_1ms);
+            return Runner.Status;
+        }
+        /// <summary>
+        /// vertical 运动到Load位置
+        /// </summary>
+        /// <returns></returns>
+        private bool VerticalGotoLoad()
+        {
+            if(_verticalAxis != null )
+            {
+                if (!_verticalAxis.IsSwitchOn)
+                {
+                    LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Vertical is not Power On");
+                    return false;
+                }
+                else if (!_verticalAxis.IsHomed)
+                {
+                    LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Vertical is not Home,Home vertical first");
+                    return false;
+                }
+                return _verticalAxis.PositionStation("Load", true);
+
+            }
+            else
+            {
+                LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "vertical axis is null");
+                return false;
+            }   
+        }
+        /// <summary>
+        /// Home
+        /// </summary>
+        /// <returns></returns>
+        private bool Home()
+        {
+            if (_verticalAxis != null)
+            {
+                if (!_verticalAxis.IsSwitchOn)
+                {
+                    LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Vertical is not Power On");
+                    return false;
+                }
+                return _verticalAxis.Home();
+
+            }
+            else
+            {
+                LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Verticel axis is null");
+                return false;
+            }
+        }
+        /// <summary>
+        /// 检验Vertical移动状态
+        /// </summary>
+        /// <returns></returns>
+        private bool CheckVerticalPositionStatus()
+        {
+            return _verticalAxis.Status == RState.End;
+        }
+        /// <summary>
+        /// 检验Vertical是否还在运动
+        /// </summary>
+        /// <returns></returns>
+        private bool CheckVerticalPositionRunStop()
+        {
+            return _verticalAxis.Status == RState.Failed;
+        }
+        /// <summary>
+        /// 启动
+        /// </summary>
+        /// <param name="objs"></param>
+        /// <returns></returns>
+        public RState Start(params object[] objs)
+        {
+            _verticalAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Vertical");
+            return Runner.Start(Module, "Start PlatingCell Vertical Initialize");
+        }
+    }
+}

+ 9 - 1
PunkHPX8_RT/Modules/RouteManager.cs

@@ -194,7 +194,7 @@ namespace PunkHPX8_RT.Modules
             InitialModuleList(SrdItemManager.Instance.InstalledModules, typeof(SRDEntity), ModuleType.SRD);
             InitialModuleList(ReservoirItemManager.Instance.InstalledModules, typeof(ReservoirEntity), ModuleType.Reservoir);
             InitialModuleList(PlatingCellItemManager.Instance.InstalledModules, typeof(PlatingCellEntity), ModuleType.PlatingCell);
-
+            InitialPlatingCellVerticalModuleList();
             fsm = new StateMachine<RouteManager>(Name, (int)RtState.Init, 200);
 
             SubscribeOperation();
@@ -213,6 +213,14 @@ namespace PunkHPX8_RT.Modules
             }
         }
         /// <summary>
+        /// 初始化PlatingCellVertical
+        /// </summary>
+        private void InitialPlatingCellVerticalModuleList()
+        {
+            List<string> lst = ModuleMatcherManager.Instance.GetAllPlatingCellVertialList();
+            InitialModuleList(lst,typeof(PlatingCellVerticalEntity),ModuleType.PlatingCellVertical);
+        }
+        /// <summary>
         /// 初始化模块对象
         /// </summary>
         /// <param name="item"></param>

+ 2 - 0
PunkHPX8_RT/PunkHPX8_RT.csproj

@@ -299,8 +299,10 @@
     <Compile Include="Modules\ModuleMatcherManager.cs" />
     <Compile Include="Modules\PlatingCell\PlatingCellCCRRoutine.cs" />
     <Compile Include="Modules\PlatingCell\PlatingCellEntity.cs" />
+    <Compile Include="Modules\PlatingCell\PlatingCellVerticalInitializeRoutine.cs" />
     <Compile Include="Modules\PlatingCell\PlatingCellInitializeRoutine.cs" />
     <Compile Include="Modules\PlatingCell\PlatingCellRunRecipeRoutine.cs" />
+    <Compile Include="Modules\PlatingCell\PlatingCellVerticalEntity.cs" />
     <Compile Include="Modules\ReservoirCellHomeRoutine.cs" />
     <Compile Include="Modules\Reservoir\DIReservoirInitializeRoutine.cs" />
     <Compile Include="Modules\Reservoir\DMInitializeRoutine.cs" />