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);
///
/// 只是来回走的逻辑,不包含数据处理
///
public abstract class GM_ScanMotion : GM_Base
{
#region 成员变量
protected GSample gsample;
///
/// 归0开始时间点,用于计算什么时候需要归0
///
private TimeSpan orgStartTime;
///
/// 使用timer.Elapsed 代替 DateTime.Now 使用
///
private Stopwatch timer = new Stopwatch();
///
/// 归原点间隔
///
public int OrgInterval { get; set; }
///
/// 扫描范围
///
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(IFlyADClientAdv 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
});
}
}
}
///
/// 只是来回走的逻辑,不包含数据处理
/// 0~posLen
///
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
{
///
/// 准备动作:归0
///
READY_ORIGIN = 1,
///
/// 准备动作:正在归0
///
READY_ORIGINWAIT = 2,
///
/// 准备动作:后退到 0 脉冲
///
READY_BACKW = 3,
///
/// 准备动作:正在后退
///
READY_BACKWAIT = 4,
///
/// 前进到 机架总长
///
SFORWARD = 5,
///
/// 前进等待
///
SFORWAIT_1 = 6,
///
/// 前进结束,等待获取grid
///
SFORWAIT_2 = 7,
///
/// 后退到 0 脉冲
///
SBACKWARD = 8,
///
/// 后退等待
///
SBACKWAIT_1 = 9,
///
/// 后退结束,等待获取grid
///
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(IFlyADClientAdv 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
});
}
}
}
}