using Aitex.Core.RT.Device; using Aitex.Core.RT.Log; using Aitex.Core.RT.Routine; using Aitex.Core.Util; using MECF.Framework.Common.Beckhoff.Station; using MECF.Framework.Common.CommonData.PowerSupplier; using MECF.Framework.Common.RecipeCenter; using MECF.Framework.Common.Routine; using MECF.Framework.Common.Utilities; using PunkHPX8_Core; using PunkHPX8_RT.Devices.AXIS; using PunkHPX8_RT.Devices.PlatingCell; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace PunkHPX8_RT.Modules.PlatingCell { public class PlatingCellEntryRoutine : RoutineBase, IRoutine { private enum RunRecipeStep { RotationStartEntry, RotationChangeToEntrySpeed, AngleTilt, VerticalGotoPlate, WaitEntryCurrentProtectedFromRinse, WaitEntryCurrentProtectedFromHome, RunPowerStepWithEntryProtect, CheckVerticalGotoPlate, AngleVertical, WaitPlatingDelay, End } #region 常量 /// /// ROTATION电机转速比例 /// private const int SPEED_RATIO = 1; #endregion /// /// recipe /// private DepRecipe _recipe; /// /// Rotation axis /// private JetAxisBase _rotationAxis; /// /// Vertical axis /// private JetAxisBase _verticalAxis; /// /// Platingcell device /// private PlatingCellDevice _device; /// /// rotation运动的目的地 /// private int _rotationgTargetPosition; /// /// vertical axis entity /// private PlatingCellVerticalEntity _verticalEntity; /// /// Power step集合 /// List _powerSupplierStepPeriodDatas = new List(); /// /// Plating启动时间 /// private DateTime _platingStartTime; /// /// 构造函数 /// /// public PlatingCellEntryRoutine(string module) : base(module) { } /// /// 中止 /// public void Abort() { Runner.Stop("Manual Abort"); } /// /// 监控 /// /// public RState Monitor() { //启动Rotation/Rotation 设置为entry 转速 (没有intercal rinse 在entry开始的时候启动rotation) Runner.RunIf(RunRecipeStep.RotationStartEntry, !_recipe.RinseBeforeEntryEnable, RotationStartEntry, _delay_1ms) //有intercal rinse 直接变速 (rotation在interval rinse的时候已经启动了) .RunIf(RunRecipeStep.RotationChangeToEntrySpeed, _recipe.RinseBeforeEntryEnable, () => { return ChangeSpeed(_recipe.EntrySpinSpeed); }, _delay_1ms) //Angle tilt 操作 .Run(RunRecipeStep.AngleTilt, _device.HeadtTiltAction, () => { return _device.PlatingCellDeviceData.IsHeadTilt; }, _delay_1s) //vertical goto plate .Run(RunRecipeStep.VerticalGotoPlate, () => { return StartVertical("Plate", _recipe.DepSteps[0].PlatingZoffset); }, _delay_1ms) //vertical 到达entry位置前110ms (多10ms) .Delay(RunRecipeStep.WaitEntryCurrentProtectedFromRinse, CalculatePowerDelayTime()) //有上电保护,此刻给电 .RunIf(RunRecipeStep.RunPowerStepWithEntryProtect, !_recipe.IsEntryTypeCold, StartPowerStep, _delay_1ms) //检查vertical到达plate位置 .WaitWithStopCondition(RunRecipeStep.CheckVerticalGotoPlate, CheckVerticalEnd, CheckVerticalError) //Angle vertical操作 .Run(RunRecipeStep.AngleVertical, _device.HeadtVerticalAction, () => { return _device.PlatingCellDeviceData.IsHeadVertical; }, _delay_1s) //如果不需要上电保护,执行plating delay .DelayIf(RunRecipeStep.WaitPlatingDelay, _recipe.IsEntryTypeCold, _recipe.PlatingDelay * 1000) .End(RunRecipeStep.End, NullFun); return Runner.Status; } /// /// 计算出上电前需要delay的时间 /// /// 返回值单位ms private int CalculatePowerDelayTime() { int delayTime = 0; if (_recipe.RinseBeforeEntryEnable) { delayTime = _verticalAxis.CalculateVerticaMoveTime($"{_verticalAxis.Module}.Vertical", "Rinse", "Entry", 0 ,_recipe.EntryZoffset) - 110; } else { delayTime = _verticalAxis.CalculateVerticaMoveTime($"{_verticalAxis.Module}.Vertical", "Load", "Entry", 0, _recipe.EntryZoffset) - 110; } return delayTime; } /// /// 启动PowerSupplier /// /// private bool StartPowerStep() { bool result = _device.PowerSupplier.StartSetStepPeriodNoWaitEnd(_powerSupplierStepPeriodDatas); if (!result) { _device.PowerSupplier.DisableOperation("", null); return false; } _platingStartTime = DateTime.Now; return true; } /// /// rotation 从entry步骤开始旋转 /// /// private bool RotationStartEntry() { bool result = _rotationAxis.ProfilePosition(_rotationgTargetPosition, _recipe.EntrySpinSpeed * SPEED_RATIO, 0, 0); if (!result) { NotifyError(eEvent.ERR_PLATINGCELL, "Start Rotation is failed", 0); return false; } return true; } /// /// change speed /// /// private bool ChangeSpeed(int speed) //参数speed单位是rmp { double realSpeed = BeckhoffVelocityUtil.ConvertVelocityToDegPerSecondByRPM(speed); bool result = _rotationAxis.ChangeSpeed((int)realSpeed); if (!result) { NotifyError(eEvent.ERR_PLATINGCELL, "Change Speed failed", 0); return false; } return true; } /// /// vertical 运行 /// /// 目标位置名称 /// 偏移量 /// private bool StartVertical(string positionName, double offset) { return _verticalEntity.CheckToPostMessage(Aitex.Core.RT.Log.eEvent.INFO_PLATINGCELL, Module, (int)PlatingCellVerticalEntity.VerticalMsg.Position, positionName, offset); } /// /// 检验垂直电机是否运动完成 /// /// private bool CheckVerticalEnd() { return _verticalEntity.IsIdle; } /// /// 检验垂直是否出现错误 /// /// private bool CheckVerticalError() { return _verticalEntity.IsError; } /// /// 启动 /// /// /// public RState Start(params object[] objs) { _recipe = (DepRecipe)objs[0]; _rotationgTargetPosition = (int)objs[1]; _powerSupplierStepPeriodDatas = (List)objs[2]; _platingStartTime = (DateTime)objs[3]; _rotationAxis = DEVICE.GetDevice($"{Module}.Rotation"); _device = DEVICE.GetDevice(Module); //获取vertical entity string vertical = ModuleMatcherManager.Instance.GetPlatingVerticalByCell(Module); _verticalEntity = Singleton.Instance.GetModule(vertical); _verticalAxis = DEVICE.GetDevice($"{vertical}.Vertical");//不能用来移动,移动用vertical entity来操作 return Runner.Start(Module, "start Entry routine"); } } }