MoS2/App/Modules/SicModules/PMs/Routines/PMToProcessIdleRoutine.cs
2026-08-24 14:03:35 +08:00

456 lines
19 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections.Generic;
using System.Diagnostics;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Device.Devices;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using MECF.Framework.Common.Equipment;
using SicModules.PMs.Routines.Base;
namespace SicModules.PMs.Routines
{
public class PMToProcessIdleRoutine : PMBaseRoutine
{
private enum RoutineStep
{
ConfinementServoOn,
RotationServoOn,
RotationEnable,
HeatEnable,
VentPumpClose,
ArSupply,
OpenH2Valve,
SetGroupA,
SetGroupB,
SetGroupC,
SetGroupE,
SetGroupF,
SetGroupH,
SetGroupD,
SetGroupG,
SetGroupK,
SetMFCMode,
SetPCMode,
SetM1to16,
SetM17M18,
SetPC,
SetGroupJ,
SetM18toM40,
SetPC567Close,
SetPC567Default,
SetPC567Mode,
SetGasOut,
SetTv,
SetM291519to38,
SetGasIn1, //V68
OpenFinal1, //V91-96
SetMfcFinal1, //M32-38
SetM18toM26,
SetTVCloseMode,
SetTvPositionToZero,
CheckPM1000,
SetGasIn2,
SetGroupJOpen,
CloseFinal2,
OpenFinal2,
SetMfcFinal2,
WaitPmPressureUp,
WaitPmPressureUp1020,
SetTvOpen,
SetTVEnable,
SetTVPressMode,
SetTV,
SetTvMode,
SetTVto1050,
SetTVto300,
WaitTvTo300,
CheckPmVac,
CheckPmAtm,
CheckV72Open,
SetV72,
SetV25,
SetV76,
SetV75,
SetV31,
SetV32,
SetV35V36,
SetV65,
SetV103,
SetV105,
SetEPV1,
SetEPV2,
SetEPV11,
SetEPV22,
SetTvModeToPress,
SetMfc28to40Special,
SetMfc28to40Default,
SetPressUpOrDown1,
SetPressureDown,
EnableRotation,
EnableHeater,
SetRotation1,
WaitRotation1,
SetTC1Mode,
SetTC1Ratio,
SetTC1RatioTo0,
SetTC1Ref,
SetTC2Mode,
SetTC2Ratio,
SetTC2RatioTo0,
SetTC2Ref,
EnableTC1,
EnableTC2,
CloseTC1,
CloseTC2,
SetFinal1ToDefault,
SetFinal1To0,
SetFinal2ToDefault,
SetFinal2To0,
CheckFinal1Open,
CheckFinal2Open,
CheckTvOpen,
SetRotation2,
SetGroupV25,
SetScrReset,
CheckEpv2Open,
CheckEpv1Open,
SetV92V93V95,
SetV94,
SetV96,
SetV68,
SetM32M35M37,
SetM36,
SetM38,
WaitPmPressureUp1,
DelayV25,
TimeDelay0,
TimeDelay1,
TimeDelay2,
TimeDelay3,
TimeDelay4,
TimeDelay5,
TimeDelay6,
TimeDelay7,
TimeDelay8,
TimeDelay9,
TimeDelay10,
TimeDelay11,
TimeDelay12,
TimeDelay13,
TimeDelay14,
TimeDelay15,
TimeDelay16,
TimeDelay20,
TimeDelay21,
TimeDelay22,
Notify1,
Notify2
}
private IoThrottleValve2 _IoThrottle;
private int _rotationCheckSpeed = 0; //设置旋转速度为0后检查是否转速低于此数值
private int _rotationCloseTimeout; //旋转停止超时
private int _IoValueOpenCloseTimeout = 10; //开关超时时间
private int _heatTimeOut = 5; //Heat关闭等待Di反馈超时时间
private double _pmPressureMaxDiff; //蝶阀与目标压力的差值范围(认为调整到位了)
private int _throttleTimeout; //蝶阀调整到指定压力的超时时间
private double _throttleFinalPressure = 300;//蝶阀最终调整对的压力
private bool _psuHeatEnable = false; //是否启用PSU 加热
private int _psuHeatMode = 0;
//private float _psuPowerRef = 0;
private float _psuL1Ratio = 0;
private float _psuL2Ratio = 0;
private float _psuL3Ratio = 0;
private bool _scrHeatEnable = false; //是否启用SCR 加热
private int _scrHeatMode = 0;
//private float _scrPowerRef = 0;
private float _scrL1Ratio = 0;
private float _scrL2Ratio = 0;
private float _scrL3Ratio = 0;
private int _rotationSpeed = 60;
private int _routineTimeOut;
private Stopwatch _swTimer = new Stopwatch();
private IoInterLock _pmInterLock;
public PMToProcessIdleRoutine(ModuleName module, PMModule pm) : base(module, pm)
{
Module = module.ToString();
Name = "ProcessIdle";
}
public override Result Start(params object[] objs)
{
Reset();
_IoThrottle = DEVICE.GetDevice<IoThrottleValve2>($"{Module}.TV");
_pmInterLock = DEVICE.GetDevice<IoInterLock>($"{Module}.PMInterLock");
//if (!_pmInterLock.SetPMProcessIdleRunning(true, out string reason))
//{
// EV.PostAlarmLog(Module, $"can not run ProcessIdle, {reason}");
// return Result.FAIL;
//}
/*
* 2025-07-16
* 执行ProcessIdle Routine需禁用MFC报警报警只在保持ProcessIdle状态时生效。
* 这个DO原本用来指示正在执行Routine现在改为指示PM维持在ProcessIdle状态。
* 只有维持在ProcessIdle状态时才会启用MFC报警监测。
*
* PM状态机ProcessIdle状态进入和退出时分别设置DOProcessIdleRunning为true和false因此进入当前Routine时
* DOProcessIdleRunning有可能为1需要强制设置为0当前Routine执行完毕后再将这个DO设置为1表示已进入ProcessIdle状态。
*/
if (!_pmInterLock.SetPMProcessIdleRunning(false, out var reason))
{
LOG.Error($"Failed to set DOProcessIdle to false due to {reason}");
}
if (!PmDevice.CheckHeadHeaterEnable(true))
{
EV.PostAlarmLog(Module, $"Should set HeatEnable on first!");
return Result.FAIL;
}
//检查隔热罩状态
if (PmDevice.ConfinementRing.RingServoError || PmDevice.ConfinementRing.RingIsBusy ||
!PmDevice.ConfinementRing.RingServoOn)
{
EV.PostAlarmLog(Module, $"ConfinementRing State abnormal,please check");
return Result.FAIL;
}
////检查磁流体状态
//if(!PmDevice._sicServo.ServoReady)
//{
// EV.PostAlarmLog(Module, $"NAIS Servo State abnormal,please check");
// return Result.FAIL;
//}
_v72IsOpen = false;
_checkPMPressureOver1000 = false;
_rotationCloseTimeout = SC.GetValue<int>($"PM.{Module}.RotationCloseTimeout");
_pmPressureMaxDiff = SC.GetValue<double>($"PM.{Module}.ThrottlePressureMaxDiff");
_throttleTimeout = SC.GetValue<int>($"PM.{Module}.ThrottlePressureTimeout");
_rotationSpeed = SC.GetValue<int>($"PM.{Module}.ProcessIdle.RotationSpeed");
_throttleFinalPressure = SC.GetValue<double>($"PM.{Module}.ProcessIdle.FinalPressure");
_psuHeatEnable = SC.GetValue<bool>($"PM.{Module}.ProcessIdle.PSUHeaterEnable");
_psuHeatMode = SC.GetValue<int>($"PM.{Module}.ProcessIdle.PSUHeaterMode");
_psuL1Ratio = (float)SC.GetValue<double>($"PM.{Module}.ProcessIdle.PSUInnerRatio");
_psuL2Ratio = (float)SC.GetValue<double>($"PM.{Module}.ProcessIdle.PSUMiddleRatio");
_psuL3Ratio = (float)SC.GetValue<double>($"PM.{Module}.ProcessIdle.PSUOuterRatio");
_scrHeatEnable = SC.GetValue<bool>($"PM.{Module}.ProcessIdle.SCRHeaterEnable");
_scrHeatMode = SC.GetValue<int>($"PM.{Module}.ProcessIdle.SCRHeaterMode");
_scrL1Ratio = (float)SC.GetValue<double>($"PM.{Module}.ProcessIdle.SCRUpperRatio");
_scrL2Ratio = (float)SC.GetValue<double>($"PM.{Module}.ProcessIdle.SCRMiddleRatio");
_scrL3Ratio = (float)SC.GetValue<double>($"PM.{Module}.ProcessIdle.SCRLowerRatio");
_routineTimeOut = SC.GetValue<int>($"PM.{Module}.ProcessIdle.RoutineTimeOut");
_finalOpen = false;
_isTvOpen = false;
currentPressureUpOrDown = PressureUpOrDown.None;
_swTimer.Restart();
Notify("Start");
return Result.RUN;
}
public override Result Monitor()
{
try
{
CheckRoutineTimeOut();
//关闭V76,打开V75
SetIoValueByGroup((int)RoutineStep.SetV76, IoGroupName.V76, false, _IoValueOpenCloseTimeout);
SetIoValueByGroup((int)RoutineStep.SetV75, IoGroupName.V75, true, _IoValueOpenCloseTimeout);
//2、 旋转停止,加热停止(根据配置,配置加热就不需要停止加热,没有配置加热时停止加热) 。
//SetHeatEnable((int)RoutineStep.HeatEnable, false, _heatTimeOut);
SetRotationValve((int)RoutineStep.RotationEnable, _rotationCheckSpeed, false, _rotationCloseTimeout);
//3、 打开 V31H2.Supply、 V32(Ar.Supply
SetIoValueByGroup((int)RoutineStep.SetV31, IoGroupName.V31, true, _IoValueOpenCloseTimeout);
SetIoValueByGroup((int)RoutineStep.SetV32, IoGroupName.V32, true, _IoValueOpenCloseTimeout);
//4、 打开 V35(H2N2.Line1)、 V36(H2N2.Line2),关闭 B/C/E/F/H/KValves,打开 D/G Valves。
SetIoValueByGroup((int)RoutineStep.SetV35V36, IoGroupName.V35V36, true, _IoValueOpenCloseTimeout);
SetIoValueByGroup((int)RoutineStep.SetGroupB, IoGroupName.B, false, _IoValueOpenCloseTimeout);
SetIoValueByGroup((int)RoutineStep.SetGroupC, IoGroupName.C, false, _IoValueOpenCloseTimeout);
SetIoValueByGroup((int)RoutineStep.SetGroupE, IoGroupName.E, false, _IoValueOpenCloseTimeout);
SetIoValueByGroup((int)RoutineStep.SetGroupF, IoGroupName.F, false, _IoValueOpenCloseTimeout);
SetIoValueByGroup((int)RoutineStep.SetGroupH, IoGroupName.H, false, _IoValueOpenCloseTimeout);
SetIoValueByGroup((int)RoutineStep.SetGroupK, IoGroupName.K, false, _IoValueOpenCloseTimeout);
SetIoValueByGroup((int)RoutineStep.SetGroupA, IoGroupName.A, true, _IoValueOpenCloseTimeout);
SetIoValueByGroup((int)RoutineStep.SetGroupD, IoGroupName.D, true, _IoValueOpenCloseTimeout);
SetIoValueByGroup((int)RoutineStep.SetGroupG, IoGroupName.G, true, _IoValueOpenCloseTimeout);
//5、 M1-M17 设定为 default 值,所有 PC 设定为 default 值(PC1-PC9)。
SetMfcModeToNormalByGroup((int)RoutineStep.SetMFCMode, MfcGroupName.All);
SetPcToDefault((int)RoutineStep.SetPC, _lstPcList);
//M1-M16设定为default值(M2、M9、M15除外)
SetMfcToDefaultByGroup((int)RoutineStep.SetM1to16, MfcGroupName.M1to16, 0);
SetMfcToDefaultByGroup((int)RoutineStep.SetM17M18, MfcGroupName.M17M18, 0);
//6、 M18-M40除 M30\M34\M39 MFC 5s ramp 到 0。
SetMfcByGroup((int)RoutineStep.SetM18toM40, MfcGroupName.M18toM40No303439, 0, 5);
//7、 打开 EPV2。
SetIoValueByGroup((int)RoutineStep.SetEPV2, IoGroupName.EPV2, true, _IoValueOpenCloseTimeout);
TimeDelay((int)RoutineStep.TimeDelay1, 3);
//8 、打 开 V87 SHPurge.Final )、 V88 OuterGas.Final、 V89 InnerGas.Final )、 V90MiddleGas.Final、 V91OpticPurge.Final、 V97CarryGas.Final
SetIoValueByGroup((int)RoutineStep.OpenFinal2, IoGroupName.Final2, true, _IoValueOpenCloseTimeout);
//9、 M27、 M28、 M29、 M31、 M33、 M40 依次设定 3S ramp 到 default 值
SetMfcToDefaultByGroup((int)RoutineStep.SetMfcFinal2, MfcGroupName.Final2, 3);
//10、打开 V92GasRingPurge.Final、 V93ChamberPurge.Final、 V95ConfinementRing.Final等待 3S
SetIoValueByGroup((int)RoutineStep.SetV92V93V95, IoGroupName.V92V93V95, true, _IoValueOpenCloseTimeout);
TimeDelay((int)RoutineStep.TimeDelay2, 3);
//11、 M32、 M35、 M37 依次设定 3S ramp 到 default 值 等待 3S打开 V68ChamBody.N2.Purge
SetMfcToDefaultByGroup((int)RoutineStep.SetM32M35M37, MfcGroupName.M32M35M37, 3);
SetIoValueByGroup((int)RoutineStep.SetV68, IoGroupName.GasIn1, true, _IoValueOpenCloseTimeout);
//12、打开 V94RotationUpPurge.Final、 M36 设定 5S ramp 到 default 值;等待 3S打开V96HeaterWF.Final M38 依次设定 5S ramp 到 default 值
SetIoValueByGroup((int)RoutineStep.SetV94, IoGroupName.V94, true, _IoValueOpenCloseTimeout);
SetMfcToDefaultByGroup((int)RoutineStep.SetM36, MfcGroupName.M36, 5);
TimeDelay((int)RoutineStep.TimeDelay3, 3);
SetIoValueByGroup((int)RoutineStep.SetV96, IoGroupName.V96, true, _IoValueOpenCloseTimeout);
SetMfcToDefaultByGroup((int)RoutineStep.SetM38, MfcGroupName.M38, 5);
TimeDelay((int)RoutineStep.TimeDelay4, 3);
//13、打开 J Valves 设置 M18-M26 3s ramp 到 default 值。
SetIoValueByGroup((int)RoutineStep.SetGroupJOpen, IoGroupName.J, true, _IoValueOpenCloseTimeout);
SetMfcToDefaultByGroup((int)RoutineStep.SetM18toM26, MfcGroupName.M18toM26, 3);
//14、 打开 TV enable, 压力模式,伺服压力默认设定为 1050mbar
SetThrottleEnableAndWait((int)RoutineStep.SetTVEnable, _IoThrottle, 5);
SetThrottleToPressModeAndWait((int)RoutineStep.SetTVPressMode, _IoThrottle, 5);
SetThrottleToTargetAndNoWait((int)RoutineStep.SetTV, _IoThrottle, 1050);
//15、打开 V72(GasBox.Vent.Pump 关闭 V25(GasBox.Vent.Bypass) 反应腔压力伺服到300mbar可配置
SetIoValueByGroup((int)RoutineStep.SetV72, IoGroupName.VentPump, true, _IoValueOpenCloseTimeout);
TimeDelay((int)RoutineStep.TimeDelay5, 1);
SetIoValueByGroup((int)RoutineStep.SetV25, IoGroupName.V25, false, _IoValueOpenCloseTimeout);
SetThrottleToTargetAndNoWait((int)RoutineStep.SetPressureDown, _IoThrottle, _throttleFinalPressure);
WaitThrottleToPressureAndSetMfcSpecial((int)RoutineStep.SetTVto300, _IoThrottle, _throttleFinalPressure, _pmPressureMaxDiff, _throttleTimeout);
//16、设定转速可配置
EnableRotation((int)RoutineStep.EnableRotation, 5);
SetRotationValveAndNoWait((int)RoutineStep.SetRotation1, _rotationSpeed);
//17、加热使能PSU 和 SCR可配置
if (_psuHeatEnable)
{
//打开PSU加热
SetPSUEnable((int)RoutineStep.EnableTC1, true, 5);
SetPSUHeatMode((int)RoutineStep.SetTC1Mode, _psuHeatMode);
TimeDelay((int)RoutineStep.TimeDelay6, 1);
SetPSUHeatRatio((int)RoutineStep.SetTC1Ratio, _psuL1Ratio, _psuL2Ratio, _psuL3Ratio);
}
else
{
//关闭PSU加热
SetPSUHeatRatio((int)RoutineStep.SetTC1RatioTo0, 0, 0, 0);
SetPSUEnable((int)RoutineStep.CloseTC1, false, 5);
}
if (_scrHeatEnable)
{
//打开SCR加热
SetSCRReset((int)RoutineStep.SetScrReset);
TimeDelay((int)RoutineStep.TimeDelay7, 1);
SetSCREnable((int)RoutineStep.EnableTC2, true, 5);
SetSCRHeatMode((int)RoutineStep.SetTC2Mode, _scrHeatMode);
TimeDelay((int)RoutineStep.TimeDelay8, 1);
SetSCRHeatRatio((int)RoutineStep.SetTC2Ratio, _scrL1Ratio, _scrL2Ratio, _scrL3Ratio);
}
else
{
//关闭SCR加热
SetSCRHeatRatio((int)RoutineStep.SetTC2RatioTo0, 0, 0, 0);
SetSCREnable((int)RoutineStep.CloseTC2, false, 5);
}
WaitRotationValve((int)RoutineStep.WaitRotation1, _rotationSpeed, true, _rotationSpeed / 2);
}
catch (RoutineBreakException)
{
return Result.RUN;
}
catch (RoutineFaildException)
{
return Result.FAIL;
}
// _pmInterLock.SetPMProcessIdleRunning(false, out string reason);
if (!_pmInterLock.SetPMProcessIdleRunning(true, out string reason))
{
LOG.Error($"Failed to set DOProcessIdle to true due to {reason}");
}
Notify($"Finished ! Elapsed time: {(int)(_swTimer.ElapsedMilliseconds / 1000)} s");
_swTimer.Stop();
return Result.DONE;
}
private void CheckRoutineTimeOut()
{
if (_routineTimeOut > 10)
{
if ((int)(_swTimer.ElapsedMilliseconds / 1000) > _routineTimeOut)
{
Notify($"Routine TimeOut! over {_routineTimeOut} s");
throw (new RoutineFaildException());
}
}
}
public override void Abort()
{
_pmInterLock.SetPMProcessIdleRunning(false, out string reason);
PmDevice._ioThrottleValve.StopRamp();
PmDevice.SetMfcStopRamp(PmDevice.GetMfcListByGroupName(MfcGroupName.All));
PmDevice.SetHeaterStopRamp();
PmDevice.SetRotationStopRamp();
PmDevice.SetRotationServo(0, 0);
base.Abort();
}
}
}