using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using AR; namespace Project.Commands { public class CommandBuffer { public int Idx { get; set; } private int REGISTER_VALUE = 0; private Boolean REGISTER_TRUE = false; private Boolean REGISTER_FALSE = false; private Boolean REGISTER_EQUAL = false; private Boolean REGISTER_ABOVE = false; private Boolean REGISTER_BELOW = false; /// /// 순차실행명령 /// public List Commands; /// /// 상시실행명령 /// public List SPS; public CommandBuffer() { Commands = new List(); SPS = new List(); } public void AddSeq(Command cmd) { cmd.Idx = this.Commands.Count; this.Commands.Add(cmd); } public void AddSPS(Command cmd) { cmd.Idx = this.SPS.Count; this.SPS.Add(cmd); } public void Clear() { Commands.Clear(); SPS.Clear(); Idx = 0; } public StepResult Run() { //sps는 모두 실행한다 StepResult rlt; foreach (var sps in this.SPS) { rlt = RunCode(sps); if (rlt == StepResult.Wait) return StepResult.Wait; //SPS에서 대기 코드가 있다 else if (rlt == StepResult.Error) return StepResult.Error; } //sequece 는 현재 것만 실행한다. if (Idx < 0) Idx = 0; var cmd = this.Commands[Idx]; rlt = RunCode(cmd); if (rlt == StepResult.Complete) //이 명령이 완료되면 다음으로 진행한다 { Idx += 1; if (Idx >= this.Commands.Count) return StepResult.Complete; else return StepResult.Wait; } return rlt; } private StepResult RunCode(Command cmd) { switch (cmd.type) { case CType.NOP: return StepResult.Complete; case CType.Wait: var data0 = cmd.Data as CDWait; if (data0.Trigger == false) { //아직 시작을 안했으니 시작시키고 대기한다 data0.SetTrigger(true); return StepResult.Wait; } else { //아직 시간을 다 쓰지 않았다면 넘어간다 if (data0.TimeOver == false) return StepResult.Wait; } break; case CType.Output: var data1 = cmd.Data as CDOutput; if (data1.PinIndex < 0) return StepResult.Error; if (DIO.SetOutput((eDOName)data1.Pin, data1.Value) == false) return StepResult.Error; break; case CType.Move: var data2 = cmd.Data as CDMove; MOT.Move((eAxis)data2.Axis, data2.Position, data2.Speed, data2.Acc, data2.Relative); break; case CType.MoveForece: var data3 = cmd.Data as CDMove; MOT.Move((eAxis)data3.Axis, data3.Position, data3.Speed, data3.Acc, data3.Relative, false, false); break; case CType.MoveWait: var data4 = cmd.Data as CDMove; var axis = (eAxis)data4.Axis; var mrlt = MOT.CheckMotionPos(axis, new TimeSpan(1), data4.Position, data4.Speed, data4.Acc, data4.Dcc, cmd.description); if (mrlt == false) return StepResult.Wait; break; case CType.GetFlag: var data5 = cmd.Data as CDFlag; data5.Value = PUB.flag.get(data5.Flag); REGISTER_FALSE = data5.Value == false; REGISTER_TRUE = data5.Value == true; break; case CType.SetFlag: var data6 = cmd.Data as CDFlag; PUB.flag.set(data6.Flag, data6.Value, cmd.description); break; case CType.True: var data7 = cmd.Data as CDCommand; if (REGISTER_TRUE) return RunCode(data7.Command); break; case CType.False: var data8 = cmd.Data as CDCommand; if (REGISTER_FALSE) return RunCode(data8.Command); break; case CType.GetVar: //공용변수의값 var data10 = cmd.Data as CDGetVar; if (data10.Key == "STEPTIME") { data10.Confirm = true; data10.Value = (int)PUB.sm.StepRunTime.TotalMilliseconds; } break; case CType.GetSetVar: //공용변수(설정)의 값 var data11 = cmd.Data as CDGetVar; if (data11.Key == "TIMEOUT_HOMEFULL") { data11.Confirm = true; data11.Value = 60;// (int)Pub.sm.StepRunTime.TotalMilliseconds; } break; case CType.Compare: var data9 = cmd.Data as CDCompare; if (data9 != null) { RunCode(data9.Source); //비교값(좌) RunCode(data9.Target); //비교값(우) var valS = data9.Source.Data as ICommandValue; var valT = data9.Target.Data as ICommandValue; int ValueS = (int)valS.Value; int ValueT = (int)valT.Value; REGISTER_ABOVE = ValueS > ValueT; REGISTER_BELOW = ValueS < ValueT; REGISTER_EQUAL = ValueS == ValueT; REGISTER_TRUE = ValueS == ValueT; REGISTER_FALSE = ValueS != ValueT; REGISTER_VALUE = ValueS - ValueT; } else return StepResult.Error; break; case CType.SetError: var data12 = cmd.Data as CDError; PUB.Result.SetResultMessage(data12.ResultCode, data12.ErrorCode, data12.NextStep); break; } return StepResult.Complete; } } public enum CType { NOP = 0, /// /// motion move /// Move, MoveForece, /// /// move and wait /// MoveWait, /// /// set digital output /// Output, Log, StepChange, /// /// check digital input /// InputCheck, /// /// check digital output /// OutputCheck, GetFlag, SetFlag, Equal, NotEqual, True, False, Zero, NonZero, SetError, Compare, SetVar, GetVar, GetSetVar, Above, Below, Wait, Run, } public class Command { public CType type { get; set; } = CType.NOP; public int Idx { get; set; } public string description { get; set; } public ICommandData Data { get; set; } public Command(CType type, string desc = "") { this.type = type; this.description = desc; } } public interface ICommandData { // string Description { get; set; } } public interface ICommandValue { object Value { get; set; } } public class CDGetVar : ICommandData, ICommandValue { public string Key { get; set; } public object Value { get; set; } public Boolean Confirm { get; set; } public CDGetVar(string key) { this.Key = key; } } public class CDGetSetVar : ICommandData, ICommandValue { public string Key { get; set; } public object Value { get; set; } public Boolean Confirm { get; set; } public CDGetSetVar(string key) { this.Key = key; } } public class CDSetVar : ICommandData { public string Key { get; set; } public int Value { get; set; } public CDSetVar(string key, int value) { this.Key = key; this.Value = Value; } } public class CDFlag : ICommandData { public eVarBool Flag { get; set; } public Boolean Value { get; set; } public CDFlag(eVarBool flag) { this.Flag = flag; Value = false; } } public class CDSetValI : ICommandData { public int Value { get; set; } public CDSetValI(int idx, int value) { this.Value = value; } } public class CDSetValB : ICommandData { public bool Value { get; set; } public CDSetValB(int idx, bool value) { this.Value = value; } } public class CDCommand : ICommandData { public Command Command { get; set; } public CDCommand(Command command) { this.Command = command; } } public class CDError : ICommandData { public eResult ResultCode { get; set; } public eECode ErrorCode { get; set; } public eNextStep NextStep { get; set; } public CDError(eResult resultCode, eECode errorCode, eNextStep nextStep) { ResultCode = resultCode; ErrorCode = errorCode; NextStep = nextStep; } } //public class CDCompare : ICommandData //{ // public T Value { get; set; } // public CDCompare(T value) // { // Value = value; // } // public CDCompare(Command source, Command target) // { // Value = value; // } //} public class CDCompare : ICommandData { public Command Source { get; set; } public Command Target { get; set; } public CDCompare(Command source, Command target) { Source = source; Target = target; } } public class CDWait : ICommandData { public int WaitMS { get; set; } public DateTime StartTime { get; set; } public Boolean Trigger { get; set; } private TimeSpan GetTime { get { return DateTime.Now - StartTime; } } public Boolean TimeOver { get { return GetTime.TotalMilliseconds > WaitMS; } } public void SetTrigger(Boolean value) { Trigger = value; StartTime = DateTime.Now; } public CDWait() : this(100) { } public CDWait(int ms) { this.WaitMS = ms; } } public class CDMove : ICommandData { public int Axis { get; set; } public double Position { get; set; } public double Speed { get; set; } public double Acc { get; set; } public double Dcc { get; set; } public Boolean Relative { get; set; } // public string Description { get; set; } public CDMove(eAxis axis, double pos, double speed) : this((int)axis, pos, speed, 0) { } public CDMove(int axis, double pos, double speed, double acc, double dcc = 0, Boolean relatvie = false) { Axis = axis; Position = pos; Speed = speed; Acc = acc; Dcc = dcc == 0 ? acc : dcc; Relative = relatvie; } } public class CDOutput : ICommandData { public eDOName Pin { get; set; } public int PinIndex { get; set; } public Boolean Value { get; set; } // public string Description { get; set; } //public CDOutput(eDOName pin) : this(pin, false) { } public CDOutput(eDOName pin, Boolean value) { Pin = pin; PinIndex = (int)pin; Value = value; } public CDOutput(int point, Boolean value) { Pin = (eDOName)point; PinIndex = point; Value = value; } } public class CDRun : ICommandData { public Action Target { get; set; } public CDRun(Action target) { Target = target; } } public class CDRunRet : ICommandData { public Func Target { get; set; } public CDRunRet(Func target) { Target = target; } } public class CDLog : ICommandData { public string Message { get; set; } public Boolean IsError { get; set; } public CDLog(string message, Boolean err = false) { Message = message; IsError = err; } } public class CDStep : ICommandData { public eSMStep Step { get; set; } public Boolean Force { get; set; } public CDStep(eSMStep step, Boolean force = false) { Step = step; Force = force; } } }