using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using FObjBase; using System.IO; using System.ComponentModel; using System.Xml.Serialization; using FlyADBase; namespace FLY.Simulation.Flyad7 { public class FLYAD7 : IFlyAD, INotifyPropertyChanged, Misc.ISaveToXml { private IPEndPoint localep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 20008); public IPEndPoint LocalEP { get { return localep; } set { if (!IPEndPoint.Equals(localep, value)) { localep.Address = value.Address; localep.Port = value.Port; NotifyPropertyChanged("LocalEP"); } } } private int adforshow; public int ADForShow { get { return adforshow; } set { if (adforshow != value) { adforshow = value; NotifyPropertyChanged("ADForShow"); } } } private int posforshow; public int PosForShow { get { return posforshow; } set { if (posforshow != value) { posforshow = value; NotifyPropertyChanged("PosForShow"); } } } private int pos2forshow; public int Pos2ForShow { get { return pos2forshow; } set { if (pos2forshow != value) { pos2forshow = value; NotifyPropertyChanged("Pos2ForShow"); } } } private int ADSum; private int ADCnt; public List<int> TimeGrid = new List<int>(); private double timespan1ms; public double TimeSpan1ms { get { return timespan1ms; } set { if (timespan1ms != value) { timespan1ms = value; NotifyPropertyChanged("TimeSpan1ms"); } } } /// <summary> /// 原始脉冲值 /// </summary> public int PositionOrg=0; #region 模拟部分 SimDrive mSimDrive = new SimDrive(); public OrderMan mOrderMan = new OrderMan(); public enum SIM_MODE { /// <summary> /// 吹膜 /// </summary> Blowing, /// <summary> /// 涂布 /// </summary> Coating, /// <summary> /// 头尾部检测 /// </summary> HeaderAndTailer, /// <summary> /// 流延 /// </summary> Casting } private SIM_MODE simmode = SIM_MODE.Coating; /// <summary> /// 系统重启时,mSimModeCurr = SimMode ,之后怎么变化都不会影响 mSimModeCurr /// </summary> public SIM_MODE SimMode { get { return simmode; } set { if (simmode != value) { simmode = value; NotifyPropertyChanged("SimMode"); } } } /// <summary> /// 当前模拟类型 /// </summary> SIM_MODE mSimMode = SIM_MODE.Blowing; public FLY.Simulation.ISimulationGageAD mSimGageAD; //public SimDrive_VF0 mSimDriveVF0 = new SimDrive_VF0(); //public SimDrive_Servo mSimDriveServo = new SimDrive_Servo(); #endregion private string param_path; public FLYAD7():this("simulation_flyad7.xml") { } public FLYAD7(string param_path) { this.param_path = param_path; PosOfGrid = 10; Load(); mSimMode = SimMode; switch (mSimMode) { case SIM_MODE.Blowing: mSimGageAD = new FLY.Simulation.Blowing.GageAD(); break; case SIM_MODE.HeaderAndTailer: mSimGageAD = new FLY.Simulation.HeaderAndTailer.GageAD(); break; case SIM_MODE.Casting: mSimGageAD = new FLY.Simulation.Casting.GageAD(); break; case SIM_MODE.Coating: mSimGageAD = new FLY.Simulation.Coating.GageAD(); break; default: throw new Exception("不支持 SIM_MODE" + mSimGageAD.ToString()); } PollModule.Current.Poll_Config( PollModule.POLL_CONFIG.ADD, new PollModule.PollHandler(OnPoll), new TimeSpan((long)(TimeSpan.TicksPerMillisecond * 1.28))); //一定只能用TimeSpan.FromTicks(12800) //TimeSpan.FromMilliseconds(1.28) 会被取整,最后是 1ms this.PropertyChanged += new PropertyChangedEventHandler(FLYAD7_PropertyChanged); mOrderMan.Init(this, mSimDrive); mSimGageAD.Mmpp = mSimDrive.Mmpp; HVelocity1 = (UInt32)((5 * 1000) / mSimDrive.Mmpp / 60); HVelocity2 = (UInt32)((1 * 1000) / mSimDrive.Mmpp / 60); Velocity = (UInt32)((12 * 1000) / mSimDrive.Mmpp / 60); SVelocity = (UInt32)((0 * 1000) / mSimDrive.Mmpp / 60); JogVelocity = (UInt32)((8 * 1000) / mSimDrive.Mmpp / 60); ATime = 500; DTime = 500; mOrderMan.order_org.Velocity1 = (int)HVelocity1; mOrderMan.order_org.Velocity2 = (int)HVelocity2; mOrderMan.order_runto.Velocity = (int)Velocity; mOrderMan.order_forw.Velocity = (int)JogVelocity; mOrderMan.order_backw.Velocity = (int)JogVelocity; mSimDrive.AccTime = ATime; mSimDrive.DecTime = DTime; mOrderMan.order_sync.mSyncOrderList = mSyncOrderList; mOrderMan.FinishEvent += new OrderMan.FinishEventHandler(mSimDriveMan_FinishEvent); } void mSimDriveMan_FinishEvent(bool isNormalStop) { if (isNormalStop) DriveStatus = DRIVE_MAN_STATUS.STOP; else DriveStatus = DRIVE_MAN_STATUS.LIMIT; DriveOrder = DRIVE_MAN_ORDER.IDLE; } void FLYAD7_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == "DriveOrder") { switch (DriveOrder) { case DRIVE_MAN_ORDER.FORWORD: DriveStatus = DRIVE_MAN_STATUS.RUNNING; mOrderMan.Forw(); break; case DRIVE_MAN_ORDER.BACKWORD: DriveStatus = DRIVE_MAN_STATUS.RUNNING; mOrderMan.Backw(); break; case DRIVE_MAN_ORDER.ORIGIN: DriveStatus = DRIVE_MAN_STATUS.RUNNING; mOrderMan.Org(); break; case DRIVE_MAN_ORDER.RUNTO: DriveStatus = DRIVE_MAN_STATUS.RUNNING; mOrderMan.Runto(DriveRuntoTarget); break; case DRIVE_MAN_ORDER.SYNC: DriveStatus = DRIVE_MAN_STATUS.RUNNING; mOrderMan.Sync(); break; case DRIVE_MAN_ORDER.STOP: DriveStatus = DRIVE_MAN_STATUS.RUNNING; mOrderMan.Stop(); break; case DRIVE_MAN_ORDER.IDLE: DriveStatus = DRIVE_MAN_STATUS.STOP; break; } } } class SimulationDataCell { public UInt16 istatus; public UInt32 ad; public override string ToString() { return "ad=" + ad.ToString() + " istatus=" + istatus.ToString("X3"); } } public void Save() { Misc.SaveToXmlHepler.Save(param_path, this); } public void Load() { Misc.SaveToXmlHepler.Load(param_path, this); } double systick; public Int32 GetSysTick() { //以读到的 mSimulationDatas_idx 作为时间, 一个为1.28ms return (Int32)systick; } public Int32 GetSysTick(DateTime dt) { return (Int32)(systick + (dt - Now).TotalMilliseconds); } //1.28ms 触发一次 void OnPoll() { if (Now == DateTime.MinValue) { Now = DateTime.Now; systick = 0; } else { Now += TimeSpan.FromTicks((int)(TimeSpan.TicksPerMillisecond * 1.28)); systick += 1.28; } UpdateAD(); UpdatePos(); UpdateIO(); UpdateDrive(); } DateTime dt = DateTime.MinValue; void UpdateTimeSpan1ms() { DateTime d = DateTime.Now; if (dt == DateTime.MinValue) dt = d; else { TimeSpan1ms = (d-dt).TotalMilliseconds; dt = d; } } void UpdateAD() { mSimGageAD.OnPoll(Now); int ad = mSimGageAD.GetAD(Position); ADSum += ad; ADCnt++; AD = ad; TimeGrid.Add(ad); if (TimeGrid.Count >= 1000) { ADForShow = ADSum / ADCnt; ADSum = 0; ADCnt = 0; UpdateTimeSpan1ms(); if (TimeGridEvent != null) { TimeGridEvent.Invoke(this, new TimeGridEventArgs( Now, TimeSpan.FromMilliseconds(1.28), TimeGrid.ToArray())); } TimeGrid.Clear(); } } public class PosGrid { public int[] Datas = new int[1000]; List<int> gridsum = new List<int>(); int grid_index_last = -1;//上一个grid_index bool isEnable; int grid_start = 0; public void Start() { isEnable = true; grid_start = grid_index_last; } public void End() { if (isEnable) { if (gridsum.Count > 0) { Datas[grid_index_last] = (int)(gridsum.Average()); gridsum.Clear(); } int grid_end = grid_index_last; Misc.DIRECTION dir = Misc.DIRECTION.FORWARD; if (grid_end < grid_start) { int t = grid_start; grid_start = grid_end; grid_end = t; dir = Misc.DIRECTION.BACKWARD; } int len = grid_end - grid_start + 1; int[] data = Datas.Skip(grid_start).Take(len).ToArray(); if (PushEvent != null) PushEvent(false, dir, grid_start, data); } isEnable = false; } public delegate void PushEventHandler(bool isMini, Misc.DIRECTION dir, int grid_start, int[] data); public event PushEventHandler PushEvent; public void UpdateGrid(int grid_index, int ad) { if (grid_index >= 0 && grid_index < Datas.Count()) { if (grid_index_last == grid_index) { gridsum.Add(ad); } else { Misc.DIRECTION dir = Misc.DIRECTION.FORWARD; if (grid_index < grid_index_last) dir = Misc.DIRECTION.BACKWARD; if (gridsum.Count > 0) { Datas[grid_index_last] = (int)(gridsum.Average()); gridsum.Clear(); //TODO 推送MINIGRID if (isEnable) { int[] data = new int[1]; data[0] = Datas[grid_index_last]; if (PushEvent != null) PushEvent(true, dir, grid_index_last, data); } } grid_index_last = grid_index; } } } } public PosGrid mPosGrid = new PosGrid(); void UpdatePos() { Position = mSimDrive.Pos; //Speed = mSimDrive.Speed; mPosGrid.UpdateGrid(Position / PosOfGrid, AD); Position2Org = mSimGageAD.GetPosition2(); int pos2; if(mSyncPos2List.Position2Changed(Position2, out pos2)) { Position2 = pos2; } Speed2 = mSimGageAD.GetSpeed2(); } void UpdateIO() { UInt16 istatus = mSimGageAD.GetInput(); if (mSimDrive.IsMaxLimit) Misc.MyBase.SIGNBIT(ref istatus, IODefinition.IN_MAXLIMIT - 1); else Misc.MyBase.CLEARBIT(ref istatus, IODefinition.IN_MAXLIMIT - 1); if (mSimDrive.IsMinLimit) Misc.MyBase.SIGNBIT(ref istatus, IODefinition.IN_MINLIMIT - 1); else Misc.MyBase.CLEARBIT(ref istatus, IODefinition.IN_MINLIMIT - 1); if (mSimDrive.IsOrg) Misc.MyBase.CLEARBIT(ref istatus, IODefinition.IN_ORG - 1); else Misc.MyBase.SIGNBIT(ref istatus, IODefinition.IN_ORG - 1); UInt16 inchange = (UInt16)(istatus ^ IStatus); if (Misc.MyBase.CHECKBIT(inchange, IODefinition.IN_VSENSOR - 1)) { //处理position2 int pos2; if(mSyncPos2List.VSensorChanged(Misc.MyBase.CHECKBIT(istatus, IODefinition.IN_VSENSOR - 1), Position2, out pos2)) { Position2 = pos2; } } IStatus = istatus; } class SyncPos2Collection { List<SyncPos2Item> list = new List<SyncPos2Item>(); int curr_offset = int.MaxValue; public void Add(SyncPos2Item item) { list.Add(item); } public void Clear() { list.Clear(); } /// <summary> /// 信号改变时调用 /// </summary> /// <param name="vsensor"></param> /// <param name="position2"></param> public bool VSensorChanged(bool vsensor, int position2, out int correct_pos2) { correct_pos2 = position2; if (list.Count() == 0) return false;//列表是空的,什么都不干 SyncPos2Item spitem = list.First();//当前在处理的项 if (vsensor == spitem.At01) { int offset = position2 - spitem.pos2; if (Math.Abs(curr_offset) > Math.Abs(offset)) { curr_offset = offset; return false; } else { //已经找到最近的一个 correct_pos2 = spitem.pos2 + curr_offset; curr_offset = int.MaxValue; list.RemoveAt(0); if (list.Count() > 0) { spitem = list.First();//当前在处理的项 if (vsensor == spitem.At01) curr_offset = position2 - spitem.pos2; } return true; } } return false; } /// <summary> /// 脉冲改变时调用 /// </summary> /// <param name="position2"></param> /// <param name="correct_pos2"></param> /// <returns></returns> public bool Position2Changed(int position2, out int correct_pos2) { correct_pos2 = position2; if (list.Count() == 0) return false;//列表是空的,什么都不干 SyncPos2Item spitem = list.First();//当前在处理的项 if(curr_offset!=int.MaxValue)//之前有一个信号 { int offset = position2 - spitem.pos2; if (Math.Abs(curr_offset) > Math.Abs(offset)) { return false; } else { //已经找到最近的一个 correct_pos2 = spitem.pos2 + curr_offset; curr_offset = int.MaxValue; list.RemoveAt(0); return true; } } return false; } } void UpdateDrive() { mSimDrive.OnPoll(Now); mOrderMan.OnPoll(); } #region INotifyPropertyChanged 成员 protected void NotifyPropertyChanged(string propertyName) { if (this.PropertyChanged != null) this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public event PropertyChangedEventHandler PropertyChanged; #endregion #region IFlyAD接口 DateTime now = DateTime.MinValue; /// <summary> /// systick 转换的时间 /// </summary> public DateTime Now { get { return now; } set { if (now != value) { now = value; NotifyPropertyChanged("Now"); } } } private int position; public int Position { get { return position; } set { if (position != value) { position = value; NotifyPropertyChanged("Position"); } } } private int speed; public int Speed { get { return speed; } set { if (speed != value) { speed = value; NotifyPropertyChanged("Speed"); } } } private int ad; public int AD { get { return ad; } set { if (ad != value) { ad = value; NotifyPropertyChanged("AD"); } } } public int ADMax { get { return 0xffff; } } private UInt16 istatus; public UInt16 IStatus { get { return istatus; } set { if (istatus != value) { istatus = value; NotifyPropertyChanged("IStatus"); } } } private UInt16 ostatus = 0xf; public UInt16 OStatus { get { return ostatus; } set { if (ostatus != value) { ostatus = value; NotifyPropertyChanged("OStatus"); } } } public void SetOutput(ushort mask, ushort enable) { UInt16 ostatus = OStatus; for (int i = 0; i < 16; i++) { if (Misc.MyBase.CHECKBIT(mask, i)) { if (Misc.MyBase.CHECKBIT(enable, i)) Misc.MyBase.SIGNBIT(ref ostatus, i); else Misc.MyBase.CLEARBIT(ref ostatus, i); } } OStatus = ostatus; } public void UpdateParam() { //throw new NotImplementedException(); } #region 配置参数 public void SetSysParam(ushort posOfGrid, FlyADBase.MOTORTYPE motortype, ushort ratio01, ushort ratio02) { MotorType = motortype; } private MOTORTYPE motorType = MOTORTYPE.VF0; public MOTORTYPE MotorType { get { return motorType; } set { if (motorType != value) { motorType = value; //TODO mSimDrive.MotorType = value; NotifyPropertyChanged("MotorType"); } } } UInt16 posOfGrid;//1个Grid=?脉冲数(2B) public UInt16 PosOfGrid { get { return posOfGrid; } set { if (posOfGrid != value) { posOfGrid = value; NotifyPropertyChanged("PosOfGrid"); } } } UInt16 ratio01=1; /// <summary> /// //电机比例(2B) /// </summary> public UInt16 Ratio01 { get { return ratio01; } set { if (ratio01 != value) { ratio01 = value; NotifyPropertyChanged("Ratio01"); } } } UInt16 ratio02=1;//脉冲比例(2B) public UInt16 Ratio02 { get { return ratio02; } set { if (ratio02 != value) { ratio02 = value; NotifyPropertyChanged("Ratio02"); } } } #endregion Int16 posOffset; public Int16 PosOffset { get { return posOffset; } set { if (posOffset != value) { posOffset = value; NotifyPropertyChanged("PosOffset"); } } } UInt32 jogVelocity=500; public UInt32 JogVelocity { get { return jogVelocity; } set { if (jogVelocity != value) { jogVelocity = value; NotifyPropertyChanged("JogVelocity"); mOrderMan.order_forw.Velocity = (int)JogVelocity; mOrderMan.order_backw.Velocity = (int)JogVelocity; } } } #region 速度 UInt32 velocity; public UInt32 Velocity { get { return velocity; } set { if (velocity != value) { velocity = value; NotifyPropertyChanged("Velocity"); mOrderMan.order_runto.Velocity = (int)Velocity; } } } UInt32 svelocity; public uint SVelocity { get { return svelocity; } set { if (svelocity != value) { svelocity = value; NotifyPropertyChanged("SVelocity"); } } } UInt32 atime; public UInt32 ATime { get { return atime; } set { if (atime != value) { atime = value; NotifyPropertyChanged("ATime"); mSimDrive.AccTime = atime; } } } UInt32 dtime; public UInt32 DTime { get { return dtime; } set { if (dtime != value) { dtime = value; NotifyPropertyChanged("DTime"); mSimDrive.DecTime = dtime; } } } UInt32 hvelocity1; public UInt32 HVelocity1 { get { return hvelocity1; } set { if (hvelocity1 != value) { hvelocity1 = value; NotifyPropertyChanged("HVelocity1"); mOrderMan.order_org.Velocity1 = (int)HVelocity1; } } } UInt32 hvelocity2; public UInt32 HVelocity2 { get { return hvelocity2; } set { if (hvelocity2 != value) { hvelocity2 = value; NotifyPropertyChanged("HVelocity2"); mOrderMan.order_org.Velocity2 = (int)HVelocity2;; } } } public void SetPosParam(uint velocity, uint sv, uint atime, uint dtime, uint hspeed1, uint hspeed2) { throw new NotImplementedException(); } #endregion #region 密码 AREA_STATUS areaStatus; public AREA_STATUS AreaStatus { get { return areaStatus; } set { if (areaStatus != value) { areaStatus = value; NotifyPropertyChanged("AreaStatus"); } } } AREA_ERR areaRet; public AREA_ERR AreaRet { get { return areaRet; } set { if (areaRet != value) { areaRet = value; NotifyPropertyChanged("AreaRet"); } } } byte[] code = new byte[7] { 0x74, 0xB7, 0x07, 0x4E, 0x52, 0x3D, 0x06 }; int surplus = 8000; byte[] access = new byte[8] { 0x19, 0x4A, 0xA5, 0x21, 0x7B, 0x74, 0x1A, 0x00 }; public byte[] Code { get { return code; } } public int Surplus { get { return surplus; } set { if (surplus != value) { surplus = value; NotifyPropertyChanged("Surplus"); } } } public byte[] Access { get { return access; } } public void SetAccess(byte[] access) { if (access.Length != 8) return; Array.Copy(access, Access, 8); AreaStatus = AREA_STATUS.VALID; AreaRet = AREA_ERR.NO_ERR; Surplus = 8000; } public void InitArea() { throw new NotImplementedException(); } #endregion public void GetGrid(Misc.DIRECTION direction, int grid_start, int grid_len, out int[] dat) { dat = null; } public void GetGrid(Misc.DIRECTION direction, out int[] dat) { GetGrid(direction, 0, 1000,out dat); } public event TimeGridEventHandler TimeGridEvent; public event MiniGridEventHandler MiniGridEvent; public event MiniGridEventHandler GridEvent; public event IStatusChangedEventHandler IStatusChangedEvent; public void Runto(int to) { Drive(DRIVE_MAN_ORDER.RUNTO, to); } public void Origin() { Drive(DRIVE_MAN_ORDER.ORIGIN); } public void Stop() { Drive(DRIVE_MAN_ORDER.STOP); } public void Backward() { Drive(DRIVE_MAN_ORDER.BACKWORD); } public void Forward() { Drive(DRIVE_MAN_ORDER.FORWORD); } DRIVE_MAN_ORDER driveorder; public DRIVE_MAN_ORDER DriveOrder { get { return driveorder; } set { if (driveorder != value) { driveorder = value; NotifyPropertyChanged("DriveOrder"); } } } DRIVE_MAN_STATUS drivestatus; public DRIVE_MAN_STATUS DriveStatus { get { return drivestatus; } set { if (drivestatus != value) { drivestatus = value; NotifyPropertyChanged("DriveStatus"); } } } int DriveRuntoTarget; void Drive(DRIVE_MAN_ORDER order, object param) { if (order == DRIVE_MAN_ORDER.RUNTO) { DriveRuntoTarget = (int)param; } DriveOrder = order; } void Drive(DRIVE_MAN_ORDER order) { Drive(order, null); } #endregion #region 同步 Int32 marker; /// <summary> /// 同步用标示 /// </summary> public Int32 Marker { get { return marker; } set { if (marker != value) { marker = value; NotifyPropertyChanged("Marker"); } } } #region 横向脉冲 int pos1lcshift; /// <summary> /// 逻辑横向脉冲偏移 Pos1 + Pos1LCShift = Pos1LC /// </summary> public int Pos1LCShift { get { return pos1lcshift; } set { if (pos1lcshift != value) { pos1lcshift = value; NotifyPropertyChanged("Pos1LCShift"); } } } public void SetPos1LCShift(int value) { Pos1LCShift = value; } #endregion #region 主轴脉冲 private int position2_org; int Position2Org { get { return position2_org; } set { if (position2_org != value) { position2_org = value; NotifyPropertyChanged("Position2Org"); cal_position2(); } } } private int position2; /// <summary> /// 纵向脉冲,也叫主轴脉冲 /// </summary> public int Position2 { get { return position2; } set { if (position2 != value) { position2 = value; NotifyPropertyChanged("Position2"); Pos2Shift = position2 - (int)(Position2Org * Pos2Comp); } } } void cal_position2() { position2 = (int)(Position2Org * Pos2Comp + Pos2Shift); } private int speed2; public int Speed2 { get { return speed2; } set { if (speed2 != value) { speed2 = value; NotifyPropertyChanged("Speed2"); } } } int pos2shift=0; /// <summary> /// 纵向偏移 /// </summary> int Pos2Shift { get { return pos2shift; } set { if (pos2shift != value) { pos2shift = value; NotifyPropertyChanged("Pos2Shift"); cal_position2(); } } } public void SetPos2Offset(int offest) { Pos2Shift += offest; } private float pos2comp=1; /// <summary> /// 纵向值补偿系数,补偿时,先乘除后加减 /// </summary> public float Pos2Comp { get { return pos2comp; } set { if (pos2comp != value) { pos2comp = value; NotifyPropertyChanged("Pos2Comp"); cal_position2(); } } } struct SyncPos2Item { public bool At01;//? or At10 public int pos2; public bool immediately; } SyncPos2Collection mSyncPos2List = new SyncPos2Collection(); /// <summary> /// 纵向同步事件,0-1事件 /// </summary> /// <param name="pos2"></param> public void SetPos2At01(int pos2,bool immediately) { mSyncPos2List.Add(new SyncPos2Item() { At01 = true, pos2 = pos2, immediately = immediately }); } #endregion #region 同步控制 同步状态转换规则 /// <summary> /// 进入同步状态 /// </summary> /// <param name="pos2"></param> public void SyncBegin(int pos2) { Position2 = pos2; SyncBegin(); } /// <summary> /// 进入同步状态 /// </summary> public void SyncBegin() { Drive(DRIVE_MAN_ORDER.SYNC); } /// <summary> /// 退出同步状态 /// </summary> public void SyncEnd() { Drive(DRIVE_MAN_ORDER.STOP); } /// <summary> /// 清空同步指令 /// </summary> public void SyncClear() { mSyncOrderList.Clear(); } /// <summary> /// 清空POS2同步列表 /// </summary> public void SyncPos2Clear() { mSyncPos2List.Clear(); } #endregion #region 同步扫描 脚本指令 List<ASyncOrder> mSyncOrderList = new List<ASyncOrder>(); //同步扫描至 //D+0xE0+开始主轴位置+结束主轴位置+结束横向脉冲位置(逻辑位置)+脉冲开关(1B)+命令识标号(4B) public void SyncRunAtLC(int pos2_begin, int pos2_end, int pos1lc, bool hasDataGrid, Int32 marker) { mSyncOrderList.Add( new SyncOrder_RunAtLC() { pos2_begin = pos2_begin, pos2_end = pos2_end, pos1lc_end = pos1lc, hasDataGrid = hasDataGrid, marker = marker }); } //7.2 位于队列头时运行,归零 //D+0xE1+命令识标号(4B) public void SyncOrigin(Int32 marker) { mSyncOrderList.Add( new SyncOrder_Origin() { marker = marker }); } //7.3 位于队列头时运行,以速度运行至物理位置 //D+0xE2+横向脉冲位置(4B:int32,物理位置)+速度(4B:int32)+脉冲开关(1B)+命令识标号(4B) public void SyncRunTo(int pos1, UInt32 velocity, bool hasDataGrid, Int32 marker) { mSyncOrderList.Add( new SyncOrder_RunTo() { pos1 = pos1, velocity = velocity, hasDataGrid = hasDataGrid, marker = marker }); } //7.3 位于队列头时运行,以速度运行至逻辑位置 //D+0xE3+横向脉冲位置(4B:int32,逻辑位置)+速度(4B:int32)+脉冲开关(1B)+命令识标号(4B) public void SyncRunToLC(int pos1lc, UInt32 velocity, bool hasDataGrid, Int32 marker) { mSyncOrderList.Add( new SyncOrder_RunToLC() { pos1lc = pos1lc, velocity = velocity, hasDataGrid = hasDataGrid, marker = marker }); } //7.4 等待,ms //D+0xE4+毫秒数(4B:int32)+命令识标号(4B) public void SyncWait(int ms, Int32 marker) { mSyncOrderList.Add( new SyncOrder_Wait() { ms = ms, marker = marker }); } #endregion #endregion public string[] GetSavePropertyNames() { return new string[] { "LocalEP", "SimMode", "MotorType" }; } } public static class FLYAD7_IODefinition { public const int IN_ORG = 2; public const int IN_MINLIMIT = 3; public const int IN_MAXLIMIT = 4; public const int IN_FORW = 7; public const int IN_BACKW = 8; public const int IN_VSENSOR = 12; } }