using System; using System.Collections.Generic; using System.Linq; using System.Text; using Misc; using FlyADBase; using FLY.Thick.Base.Common; using System.Diagnostics; namespace FLY.Thick.Base.Server { public delegate void EndEventHandler(object obj, MiniGridEventArgs e); /// <summary> /// 只是来回走的逻辑,不包含数据处理 /// </summary> public abstract class GM_ScanMotion : GM_Base { #region 成员变量 protected GSample gsample; /// <summary> /// 归0开始时间点,用于计算什么时候需要归0 /// </summary> private TimeSpan orgStartTime; /// <summary> /// 使用timer.Elapsed 代替 DateTime.Now 使用 /// </summary> private Stopwatch timer = new Stopwatch(); /// <summary> /// 归原点间隔 /// </summary> public int OrgInterval { get; set; } /// <summary> /// 扫描范围 /// </summary> public int ScanStart { get; set; } public int ScanEnd { get; set; } public event EndEventHandler DataPosEvent; public event EndEventHandler EndEvent; public event EventHandler StartEvent; public event EventHandler FinishEvent; enum CTRLST { INIT = 0,//判断进入阶段 #region 归0 及 样品采集阶段 ORIGINWAIT = 2,//正在归0 FORWARD = 3,//前进到样品,或扫描结束位置 FORWAIT_1 = 4,//前进等待 FORWAIT_2 = 5,//前进结束,等待获取grid BACKWARD = 8,//后退到温修,或扫描开始位置 BACKWAIT_1 = 9,//后退等待 BACKWAIT_2 = 10,//后退结束,等待获取grid FORWAIT_SAMPLE = 11,//前进取样中 FORW_SAMPLE = 12,//前进取样 BACKWAIT_SAMPLE = 13,//后退取样中 BACKW_SAMPLE = 14,//后退取样 #endregion #region 正常扫描阶段 SCAN_FORW = 20,//前进扫描 SCAN_FORWAIT = 21,//前进等待 SCAN_BACKW = 22,//后退扫描 SCAN_BACKWAIT = 23,//后退等待 #endregion } CTRLST state; #endregion public UInt32 Velocity { get; set; } public GM_ScanMotion() { GMState = CTRL_STATE.SCAN; ScanStart = -1; ScanEnd = -1; } public virtual void Init(FlyAD7 flyad, GSample gsample) { base.Init(flyad); this.gsample = gsample; flyad.MiniGridEvent += (s, e) => { if ((state == CTRLST.FORWAIT_1) || (state == CTRLST.BACKWAIT_1) || (state == CTRLST.SCAN_FORWAIT) || (state == CTRLST.SCAN_BACKWAIT)) { DataPosEvent?.Invoke(this, e); } }; } protected virtual bool Start2(int start, int end) { ScanStart = start; ScanEnd = end; timer.Restart(); orgStartTime = TimeSpan.FromMinutes(-OrgInterval); state = CTRLST.INIT; if (gsample != null) gsample.Reset(ScanStart, ScanEnd); StartEvent?.Invoke(this, null); return true; } public override void Stop() { timer.Stop(); FinishEvent?.Invoke(this, null); base.Stop(); } bool WaitFinish(ref CTRLST src, CTRLST next) { switch (mFlyAD.DriveStatus) { case DRIVE_MAN_STATUS.STOP://完成任务 case DRIVE_MAN_STATUS.LIMIT: { src = next; return true; } break; case DRIVE_MAN_STATUS.STOP_MANUAL://异常 { NotifyError(ERRNO_Running_Manual); Stop(); return false; } break; } return false; } protected override void OnPoll() { switch (state) { case CTRLST.INIT: { if (IsOrging()) { mFlyAD.Origin(); state = CTRLST.ORIGINWAIT; } else { state = CTRLST.SCAN_FORW; } } break; case CTRLST.ORIGINWAIT: { WaitFinish(ref state, CTRLST.FORWARD); } break; case CTRLST.FORWARD: { int to = ScanEnd; int b, e; if (gsample.GetSampleRange(Misc.DIRECTION.FORWARD, out b, out e)) { FlyADBase.MOTORTYPE motorType = mFlyAD.MotorType; if (motorType == FlyADBase.MOTORTYPE.VF0) { //直接去到取样的位置 to = e; } else//要变速,分开两段 { to = b; } } mFlyAD.SetVelocity(Velocity); mFlyAD.Runto(to); state = CTRLST.FORWAIT_1; } break; case CTRLST.FORWAIT_1: { if (WaitFinish(ref state, CTRLST.FORWAIT_2)) FlushAD(DIRECTION.FORWARD); } break; case CTRLST.FORWAIT_2: { state = CTRLST.BACKWARD; int b, e; if (gsample.GetSampleRange(Misc.DIRECTION.FORWARD, out b, out e)) { FlyADBase.MOTORTYPE motorType = mFlyAD.MotorType; if (motorType == FlyADBase.MOTORTYPE.VF0) { //直接去到取样的位置 state = CTRLST.FORW_SAMPLE; } else//要变速,分开两段 { mFlyAD.SetVelocity(gsample.Velocity); mFlyAD.Runto(e); state = CTRLST.FORWAIT_SAMPLE; } } } break; case CTRLST.FORWAIT_SAMPLE: { WaitFinish(ref state, CTRLST.FORW_SAMPLE); } break; case CTRLST.FORW_SAMPLE: { gsample.Do(Misc.DIRECTION.FORWARD); state = CTRLST.BACKWARD; } break; case CTRLST.BACKWARD: { int to = ScanStart; int b, e; if (gsample.GetSampleRange(Misc.DIRECTION.BACKWARD, out b, out e)) { FlyADBase.MOTORTYPE motorType = mFlyAD.MotorType; if (motorType == FlyADBase.MOTORTYPE.VF0) { //直接去到取样的位置 to = b; } else//要变速,分开两段 { to = e; } } mFlyAD.SetVelocity(Velocity); mFlyAD.Runto(to); state = CTRLST.BACKWAIT_1; } break; case CTRLST.BACKWAIT_1: { if (WaitFinish(ref state, CTRLST.BACKWAIT_2)) FlushAD(DIRECTION.BACKWARD); } break; case CTRLST.BACKWAIT_2: { int b, e; if (gsample.GetSampleRange(Misc.DIRECTION.BACKWARD, out b, out e)) { FlyADBase.MOTORTYPE motorType = mFlyAD.MotorType; if (motorType == FlyADBase.MOTORTYPE.VF0) { //直接去到取样的位置 state = CTRLST.BACKW_SAMPLE; } else//要变速,分开两段 { mFlyAD.SetVelocity(gsample.Velocity); mFlyAD.Runto(b); state = CTRLST.BACKWAIT_SAMPLE; } } else { //完成一次周期 if (!gsample.IsFailure()) orgStartTime = timer.Elapsed; state = CTRLST.INIT; } } break; case CTRLST.BACKWAIT_SAMPLE: { WaitFinish(ref state, CTRLST.BACKW_SAMPLE); } break; case CTRLST.BACKW_SAMPLE: { gsample.Do(Misc.DIRECTION.BACKWARD); //完成一次周期 if (!gsample.IsFailure()) orgStartTime = timer.Elapsed; state = CTRLST.INIT; } break; case CTRLST.SCAN_FORW: { int to = ScanEnd; mFlyAD.SetVelocity(Velocity); mFlyAD.Runto(to); state = CTRLST.SCAN_FORWAIT; } break; case CTRLST.SCAN_FORWAIT: { if (WaitFinish(ref state, CTRLST.SCAN_BACKW)) FlushAD(DIRECTION.FORWARD); } break; case CTRLST.SCAN_BACKW: { int to = ScanStart; mFlyAD.SetVelocity(Velocity); mFlyAD.Runto(to); state = CTRLST.SCAN_BACKWAIT; } break; case CTRLST.SCAN_BACKWAIT: { if (WaitFinish(ref state, CTRLST.INIT)) FlushAD(DIRECTION.BACKWARD); } break; } } private bool IsOrging() { if (OrgInterval > 0) { if (timer.Elapsed >= (orgStartTime + TimeSpan.FromMinutes(OrgInterval))) return true; } return false; } private bool IsOrgEnable() { if (OrgInterval > 0) return true; else return false; } private void FlushAD(Misc.DIRECTION direction) { int pos1, pos2; pos1 = ScanStart; pos2 = ScanEnd; int start_grid = pos1 / mFlyAD.PosOfGrid; int end_grid = pos2 / mFlyAD.PosOfGrid; if (start_grid < 0) start_grid = 0; int len = end_grid - start_grid + 1; int[] dat; mFlyAD.GetGrid(direction, start_grid, len, out dat); if (EndEvent != null) { EndEvent(this, new MiniGridEventArgs() { grid_start = start_grid, direction = direction, posOfGrid = mFlyAD.PosOfGrid, buf = dat }); } } } /// <summary> /// 只是来回走的逻辑,不包含数据处理 /// 0~posLen /// </summary> public abstract class GM_ScanMotion2 : GM_Base { #region 成员变量 int scanCnt;//扫描次数, 当为-1时,无限次扫描,>0时,有限次扫描 protected int ScanCnt { get { return scanCnt; } set { if (scanCnt != value) { scanCnt = value; NotifyPropertyChanged("ScanCnt"); } } } public event EndEventHandler DataPosEvent; public event EndEventHandler EndEvent; public event EventHandler StartEvent; public event EventHandler FinishEvent; enum CTRLST { /// <summary> /// 准备动作:归0 /// </summary> READY_ORIGIN = 1, /// <summary> /// 准备动作:正在归0 /// </summary> READY_ORIGINWAIT = 2, /// <summary> /// 准备动作:后退到 0 脉冲 /// </summary> READY_BACKW = 3, /// <summary> /// 准备动作:正在后退 /// </summary> READY_BACKWAIT = 4, /// <summary> /// 前进到 机架总长 /// </summary> SFORWARD = 5, /// <summary> /// 前进等待 /// </summary> SFORWAIT_1 = 6, /// <summary> /// 前进结束,等待获取grid /// </summary> SFORWAIT_2 = 7, /// <summary> /// 后退到 0 脉冲 /// </summary> SBACKWARD = 8, /// <summary> /// 后退等待 /// </summary> SBACKWAIT_1 = 9, /// <summary> /// 后退结束,等待获取grid /// </summary> SBACKWAIT_2 = 10, } CTRLST state; #endregion public UInt32 Velocity { get; set; } public GM_ScanMotion2() { GMState = CTRL_STATE.SCAN; ScanCnt = -1;//无限扫描 state = CTRLST.READY_ORIGIN; } public override void Init(FlyAD7 flyad) { base.Init(flyad); flyad.MiniGridEvent += (s, e) => { if ((state == CTRLST.SFORWAIT_1) || (state == CTRLST.SBACKWAIT_1)) { if (DataPosEvent != null) DataPosEvent(this, e); } }; } protected virtual void Start2() { state = CTRLST.READY_ORIGIN; if (StartEvent != null) StartEvent(this, null); } public override void Stop() { if (FinishEvent != null) FinishEvent(this, null); base.Stop(); } bool WaitFinish(ref CTRLST src, CTRLST next) { switch (mFlyAD.DriveStatus) { case DRIVE_MAN_STATUS.STOP://完成任务 case DRIVE_MAN_STATUS.LIMIT: { src = next; return true; } break; case DRIVE_MAN_STATUS.STOP_MANUAL://异常 { NotifyError(ERRNO_Running_Manual); Stop(); return false; } break; } return false; } protected override void OnPoll() { switch (state) { case CTRLST.READY_ORIGIN: { mFlyAD.Origin(); state = CTRLST.READY_ORIGINWAIT; } break; case CTRLST.READY_ORIGINWAIT: { WaitFinish(ref state, CTRLST.READY_BACKW); }break; case CTRLST.READY_BACKW: { mFlyAD.SetVelocity(Velocity); mFlyAD.RuntoMin(); state = CTRLST.READY_BACKWAIT; } break; case CTRLST.READY_BACKWAIT: { WaitFinish(ref state, CTRLST.SFORWARD); } break; case CTRLST.SFORWARD: { mFlyAD.SetVelocity(Velocity); mFlyAD.RuntoMax(); state = CTRLST.SFORWAIT_1; } break; case CTRLST.SFORWAIT_1: { if (WaitFinish(ref state, CTRLST.SFORWAIT_2)) FlushAD(DIRECTION.FORWARD); } break; case CTRLST.SFORWAIT_2: { state = CTRLST.SBACKWARD; } break; case CTRLST.SBACKWARD: { mFlyAD.SetVelocity(Velocity); mFlyAD.RuntoMin(); state = CTRLST.SBACKWAIT_1; } break; case CTRLST.SBACKWAIT_1: { if (WaitFinish(ref state, CTRLST.SBACKWAIT_2)) FlushAD(DIRECTION.BACKWARD); } break; case CTRLST.SBACKWAIT_2: { state = CTRLST.SFORWARD; //扫描次数 if (ScanCnt > 0) ScanCnt--; if (ScanCnt == 0) { //扫描完成 Stop(); return; } } break; } } private void FlushAD(Misc.DIRECTION direction) { int start_grid = 0; int end_grid = mFlyAD.PosLen / mFlyAD.PosOfGrid; int len = end_grid - start_grid + 1; int[] dat; mFlyAD.GetGrid(direction, start_grid, len, out dat); if (EndEvent != null) { EndEvent(this, new MiniGridEventArgs() { grid_start = start_grid, direction = direction, posOfGrid = mFlyAD.PosOfGrid, buf = dat }); } } } }