using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.ComponentModel; using FObjBase; using Misc; using System.Collections.ObjectModel; namespace FlyADBase { public interface IFlyAD : INotifyPropertyChanged { IPEndPoint LocalEP { get; set; } /// <summary> /// 从flyad7 获取 的systick 转换的时间 /// </summary> DateTime Now { get; } //POS & AD int Position { get; } int Speed { get; } int AD { get; }/*1000ms从AD卡获取(或推送)1个AD值。此AD值只用于调试,定点*/ int ADMax { get; }//AD值最大值 ,恒定返回65535 //IO UInt16 IStatus { get; }/*input read*/ UInt16 OStatus { get; }/*output read*/ /// <summary> /// Out0 = 0, SetOutput(0x0001,0x0000); /// Out0 = 1, Out1 = 0, SetOutput(0x0003,0x0001); /// </summary> /// <param name="mask"></param> /// <param name="enable"></param> void SetOutput(UInt16 mask, UInt16 enable); /// <summary> /// 读取参数, 全部!!!! /// </summary> void UpdateParam(); #region 配置参数 void SetSysParam(UInt16 posOfGrid, MOTORTYPE motortype, UInt16 ratio01, UInt16 ratio02); MOTORTYPE MotorType { set; get; } UInt16 PosOfGrid { set; get; }// 单位 pulse/grid UInt16 Ratio01 { get; set; } UInt16 Ratio02 { get; set; } #endregion Int16 PosOffset { set; get; }//脉冲平移 UInt32 JogVelocity { set; get; } #region 速度 UInt32 Velocity { set; get; } UInt32 SVelocity { set; get; } UInt32 ATime { set; get; } UInt32 DTime { set; get; } UInt32 HVelocity1 { set; get; } UInt32 HVelocity2 { set; get; } void SetPosParam(UInt32 velocity, UInt32 sv, UInt32 atime, UInt32 dtime, UInt32 hspeed1, UInt32 hspeed2); #endregion #region 密码 AREA_STATUS AreaStatus { get; } AREA_ERR AreaRet { get; } /// <summary> /// 序列码byte[6] /// </summary> byte[] Code { get; } /// <summary> /// 系统剩余时间 /// </summary> int Surplus { get; } /// <summary> /// 系统授权码access[8] /// </summary> byte[] Access { get; } /// <summary> /// 输入系统授权码 /// </summary> /// <param name="access"></param> void SetAccess(byte[] access); /// <summary> /// 初始化系统信息区 /// </summary> void InitArea(); #endregion //grid void GetGrid(DIRECTION direction, int grid_start, int grid_len, out int[] dat); void GetGrid(DIRECTION direction, out int[] dat); event TimeGridEventHandler TimeGridEvent; event MiniGridEventHandler MiniGridEvent; event IStatusChangedEventHandler IStatusChangedEvent; event MiniGridEventHandler GridEvent; #region 运行 void Runto(int to); void Origin(); void Stop(); void Backward(); void Forward(); #endregion DRIVE_MAN_ORDER DriveOrder { get; } DRIVE_MAN_STATUS DriveStatus { get; } #region 同步 /// <summary> /// 同步用标示 /// </summary> Int32 Marker { get; } #region 横向脉冲 /// <summary> /// 逻辑横向脉冲偏移 Pos1 + Pos1LCShift = Pos1LC /// </summary> int Pos1LCShift { get; set; } #endregion #region 主轴脉冲 /// <summary> /// 纵向脉冲,也叫主轴脉冲 /// </summary> int Position2 { get; set; } /// <summary> /// 纵向速度 /// </summary> int Speed2 { get; } /// <summary> /// 纵向偏移,这个是相对量 /// </summary> void SetPos2Offset(int offset); /// <summary> /// 纵向值补偿系数,补偿时,先乘除后加减 /// </summary> float Pos2Comp { get; set; } /// <summary> /// 纵向同步事件,0-1事件 /// </summary> /// <param name="pos2"></param> /// <param name="immediately">只要是 01,就立刻修正</param> void SetPos2At01(int pos2, bool immediately); #endregion #region 同步控制 同步状态转换规则 /// <summary> /// 进入同步状态 /// </summary> /// <param name="pos2"></param> void SyncBegin(int pos2); /// <summary> /// 进入同步状态 /// </summary> void SyncBegin(); /// <summary> /// 退出同步状态 /// </summary> void SyncEnd(); /// <summary> /// 清空同步指令 /// </summary> void SyncClear(); /// <summary> /// 清空POS2同步列表 /// </summary> void SyncPos2Clear(); #endregion #region 同步扫描 脚本指令 //同步扫描至 //D+0xE0+开始主轴位置+结束主轴位置+结束横向脉冲位置(逻辑位置)+脉冲开关(1B)+命令识标号(4B) void SyncRunAtLC(int pos2_begin, int pos2_end, int pos1lc, bool hasDataGrid, Int32 marker); //位于队列头时运行,归零 //D+0xE1+命令识标号(4B) void SyncOrigin(Int32 marker); //位于队列头时运行,以速度运行至物理位置 //D+0xE2+横向脉冲位置(4B:int32,物理位置)+速度(4B:int32)+脉冲开关(1B)+命令识标号(4B) void SyncRunTo(int pos1, UInt32 velocity, bool hasDataGrid, Int32 marker); //位于队列头时运行,以速度运行至逻辑位置 //D+0xE3+横向脉冲位置(4B:int32,逻辑位置)+速度(4B:int32)+脉冲开关(1B)+命令识标号(4B) void SyncRunToLC(int pos1lc, UInt32 velocity, bool hasDataGrid, Int32 marker); //等待,ms //D+0xE4+毫秒数(4B:int32)+命令识标号(4B) void SyncWait(int ms, Int32 marker); #endregion #endregion } public interface IFlyADClient : IFlyAD { bool IsConnected { get; } int ConnectCnt { get; } CorrectADsHandler CorrectADs { get; set; } bool HasCRC { get; set; } /// <summary> /// grid 滤波 /// </summary> int GridSmooth { get; set; } int InBufLen { get; } /// <summary> /// Ratio02 / Ratio01 /// </summary> double Speed1Scale { get; } void Connect(); void Connect(IPEndPoint ep); void ReConnect(); int PosLen { get; set; } void RuntoMin(); void RuntoMax(); int LastPos2At01 { get; } bool IsSync { get; } void SetOutputBit(int index, bool is1); #region 滞后处理 /// <summary> /// ad滞后修正 单位ms /// </summary> int ADLag { get; set; } event GridAdvEventHandler GridAdvEvent; #endregion #region runto 推送 istatus 变化 void GridIStatusEventAdd(int istatus_no, GridIStatusEventHander func); void GridIStatusEventDel(int istatus_no, GridIStatusEventHander func); #endregion #region 同步 /// <summary> /// 同步列表,完成后,会删除 /// </summary> ObservableCollection<SyncOrder> SyncOrders { get; } #endregion } public enum SyncOrderState { Waiting, Doing, Finish } public abstract class SyncOrder : INotifyPropertyChanged { private SyncOrderState state = SyncOrderState.Waiting; public SyncOrderState State { get { return state; } set { if (state != value) { state = value; NotifyPropertyChanged("State"); } } } public Int32 Marker { get; set; } protected void NotifyPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } public event PropertyChangedEventHandler PropertyChanged; } public class SyncOrder_SyncRunAtLC : SyncOrder { public int Pos2Begin { get; set; } public int Pos2End { get; set; } public int Pos1LC { get; set; } public bool HasDataGrid { get; set; } public override string ToString() { string s; if (State == SyncOrderState.Waiting) s = "_ "; else if (State == SyncOrderState.Doing) s = "√ "; else// if (State == SyncOrderState.Finish) s = "x "; return s+"SyncRunAtLC( " + "Pos2Begin=" + Pos2Begin.ToString() + ", " + "Pos2End=" + Pos2End.ToString() + ", " + "Pos1LC=" + Pos1LC.ToString() + ", " + "HasDataGrid=" + HasDataGrid.ToString() + ", " + "Marker=" + Marker.ToString() + ")"; } } public class SyncOrder_SyncOrigin : SyncOrder { public override string ToString() { string s; if (State == SyncOrderState.Waiting) s = "_ "; else if (State == SyncOrderState.Doing) s = "√ "; else// if (State == SyncOrderState.Finish) s = "x "; return s + "SyncOrigin( " + "Marker=" + Marker.ToString() + ")"; } } public class SyncOrder_SyncRunTo : SyncOrder { public int Pos1 { get; set; } public UInt32 Velocity { get; set; } public bool HasDataGrid { get; set; } public override string ToString() { string s; if (State == SyncOrderState.Waiting) s = "_ "; else if (State == SyncOrderState.Doing) s = "√ "; else// if (State == SyncOrderState.Finish) s = "x "; return s + "SyncRunTo( " + "Pos1=" + Pos1.ToString() + ", " + "Velocity=" + Velocity.ToString() + ", " + "HasDataGrid=" + HasDataGrid.ToString() + ", " + "Marker=" + Marker.ToString() + ")"; } } public class SyncOrder_SyncRunToLC : SyncOrder { public int Pos1 { get; set; } public UInt32 Velocity { get; set; } public bool HasDataGrid { get; set; } public override string ToString() { string s; if (State == SyncOrderState.Waiting) s = "_ "; else if (State == SyncOrderState.Doing) s = "√ "; else// if (State == SyncOrderState.Finish) s = "x "; return s + "SyncRunToLC( " + "Pos1=" + Pos1.ToString() + ", " + "Velocity=" + Velocity.ToString() + ", " + "HasDataGrid=" + HasDataGrid.ToString() + ", " + "Marker=" + Marker.ToString() + ")"; } } public class SyncOrder_SyncWait : SyncOrder { public int MS { get; set; } public override string ToString() { string s; if (State == SyncOrderState.Waiting) s = "_ "; else if (State == SyncOrderState.Doing) s = "√ "; else// if (State == SyncOrderState.Finish) s = "x "; return s + "SyncWait( " + "MS=" + MS.ToString() + ", " + "Marker=" + Marker.ToString() + ")"; } } public static class SyncOrderExtention { public static void Add(this SyncOrder order, IFlyAD flyad) { if (order is SyncOrder_SyncRunAtLC) { ((SyncOrder_SyncRunAtLC)order).Add(flyad); } else if (order is SyncOrder_SyncOrigin) { ((SyncOrder_SyncOrigin)order).Add(flyad); } else if (order is SyncOrder_SyncRunTo) { ((SyncOrder_SyncRunTo)order).Add(flyad); } else if (order is SyncOrder_SyncRunToLC) { ((SyncOrder_SyncRunToLC)order).Add(flyad); } else if (order is SyncOrder_SyncWait) { ((SyncOrder_SyncWait)order).Add(flyad); } } public static void Add(this SyncOrder_SyncRunAtLC order, IFlyAD flyad) { flyad.SyncRunAtLC(order.Pos2Begin, order.Pos2End, order.Pos1LC, order.HasDataGrid, order.Marker); } public static void Add(this SyncOrder_SyncOrigin order, IFlyAD flyad) { flyad.SyncOrigin(order.Marker); } public static void Add(this SyncOrder_SyncRunTo order, IFlyAD flyad) { flyad.SyncRunTo( order.Pos1, order.Velocity, order.HasDataGrid, order.Marker); } public static void Add(this SyncOrder_SyncRunToLC order, IFlyAD flyad) { flyad.SyncRunToLC( order.Pos1, order.Velocity, order.HasDataGrid, order.Marker); } public static void Add(this SyncOrder_SyncWait order, IFlyAD flyad) { flyad.SyncWait(order.MS, order.Marker); } } public class IStatusChangedEventArgs : EventArgs { public IStatusChangedEventArgs(DateTime time, UInt16 istatus, UInt16 ichanged, int pos, int pos2) { Time = time; IStatus = istatus; IChanged = ichanged; Position = pos; Position2 = pos2; } /// <summary> /// 开始时间点 /// </summary> public DateTime Time; /// <summary> /// 输入口状态 /// </summary> public UInt16 IStatus; /// <summary> /// 变化量 /// </summary> public UInt16 IChanged; /// <summary> /// 变化时的脉冲1 /// </summary> public int Position; /// <summary> /// 变化时的脉冲2 /// </summary> public int Position2; } public delegate void IStatusChangedEventHandler(object sender, IStatusChangedEventArgs e); public class TimeGridEventArgs : EventArgs { public TimeGridEventArgs() { } public TimeGridEventArgs(DateTime time, TimeSpan tspan, int[] data) { //Ts = new TimeSpan((long)(TimeSpan.TicksPerMillisecond * 1.28)); Time = time; Ts = tspan; Data = data; } /// <summary> /// 数据 /// </summary> public int[] Data { get; set; } /// <summary> /// 单数据时间间隔 /// </summary> public TimeSpan Ts { get; set; } /// <summary> /// 开始时间点 /// </summary> public DateTime Time { get; set; } } public delegate void TimeGridEventHandler(object sender, TimeGridEventArgs e); public class MiniGridEventArgs : EventArgs { public Misc.DIRECTION direction; public int posOfGrid; public int grid_start; public int[] buf; public Int32 marker;//扫描标记 } public delegate void MiniGridEventHandler(object sender, MiniGridEventArgs e); public delegate void CorrectADsHandler(Misc.DIRECTION direction, int start_grid, int[] dat); public enum MOTORTYPE { NULL = 0, VF0 = 1, SERVO = 2 } public enum AREA_STATUS { /// <summary> /// 没有读过密码区 /// </summary> NOTLOAD = 0, /// <summary> /// 读出错 /// </summary> RDERR = 1, /// <summary> /// 非有效密码区 没有0xAA55 或 0x5A5A 标志 /// </summary> NOTVALID = 2, /// <summary> /// 写出错 /// </summary> WRERR = 3, /// <summary> /// 有效密码区 /// </summary> VALID = 4, /// <summary> /// 有效密码区,应回写EEPROM /// </summary> VALID_DIRTY = 5, /// <summary> /// 有效密码区,但回写EEPROM失败 /// </summary> VALID_WRERR = 6 } public enum AREA_ERR { NO_ERR = 0, // 没有错误 DUP_ACCESS = 1,// 重复使用码 ERR_ACCESS = 2//无效使用码 } public enum DRIVE_MAN_STATUS { /// <summary> /// 正常运行结束 /// </summary> STOP = 0, /// <summary> /// 正在运行 /// </summary> RUNNING = 1, /// <summary> /// 指令结束(收到停止指令) /// </summary> STOP_MANUAL = 2, /// <summary> /// 运行结束,限位开关闭合 /// </summary> LIMIT = 3 } public enum DRIVE_MAN_ORDER { IDLE = 'I', /// <summary> /// 运行到 /// </summary> RUNTO = 'R', /// <summary> /// 归原点 /// </summary> ORIGIN = 'O', /// <summary> /// 后退 /// </summary> BACKWORD = 'B', /// <summary> /// 前进 /// </summary> FORWORD = 'F', /// <summary> /// 停止 /// </summary> STOP = 'S', /// <summary> /// 同步 /// </summary> SYNC = 'D', /// <summary> /// 未知状态 /// </summary> SYNC2 = 'P' } /// <summary> /// 同步状态 /// </summary> public enum SYNC_STATUS { SYNCST_NO = 0, SYNCST_PENDING1 = 1, SYNCST_PENDING2 = 2, SYNCST_PENDING3 = 3, SYNCST_TEMP_OUT = 4, SYNCST_WAIT_TO_PENDING = 5, SYNCST_RESUME = 6, SYNCST_YES = 10, } public class GridAdvUnit { public DateTime dt; public int ad; public int pos; public UInt16 istatus; public override string ToString() { return dt.Ticks.ToString() + " |" + ad.ToString() + " |" + pos.ToString() + " |" + istatus.ToString("X2"); } } public class GridAdvEventArgs : EventArgs { public Misc.DIRECTION direction; public int pos_start; public int pos_len; public Int32 marker;//扫描标记 public List<GridAdvUnit> dt_data; } public delegate void GridAdvEventHandler(object sender, GridAdvEventArgs e); public class GridIStatusEventArgs : EventArgs { public Misc.DIRECTION direction; /// <summary> /// 输入口 1~12 /// </summary> public int istatus_no; public Int32 marker;//扫描标记 /// <summary> /// 扫描开始点 /// </summary> public int pos_start; /// <summary> /// 扫长度 /// </summary> public int pos_len; /// <summary> /// 输入口 信号为0, 的范围段 /// </summary> public List<Range> data_0; /// <summary> /// 输入口 信号为1, 的范围段 /// </summary> public List<Range> data_1; } public delegate void GridIStatusEventHander(object sender, GridIStatusEventArgs e); }