领胜LDS 键盘AOI检测项目
wells.liu
2020-06-29 0d97500a3aac13b642fc93fae2e5dd01e1086b21
src/Bro.Device.GTSCard/GTSCardConfig.cs
@@ -1,247 +1,675 @@
using Bro.Common.Base;
using Bro.Common.Helper;
using Bro.Common.Interface;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Configuration;
using System.Drawing.Design;
using System.Linq;
using System.Threading;
using static Bro.Common.Helper.EnumHelper;
namespace Bro.Device.GTSCard
{
    public abstract class GTSCardOperationConfigBase : OperationConfigBase
    [Device("GTSCard", "固高板卡", EnumHelper.DeviceAttributeType.OperationConfig)]
    public class GTSCardOperationConfig : OperationConfigBase, IComplexDisplay
    {
        ///// <summary>
        ///// 需要操作的PLC项
        ///// </summary>
        //public List<PLCItem> Items { get; set; } = new List<PLCItem>();
        [Category("板卡运动配置")]
        [DisplayName("运动配置集合")]
        [Description("MovingOps:运动配置集合")]
        [TypeConverter(typeof(CollectionCountConvert))]
        [Editor(typeof(ComplexCollectionEditor<MovingOption>), typeof(UITypeEditor))]
        public ObservableCollection<MovingOption> MovingOps { get; set; } = new ObservableCollection<MovingOption>();
        public string GetDisplayText()
        {
            return MovingOps.Count() == 0 ? "--" : string.Join(";", MovingOps.Select(m => m.GetDisplayText()));
        }
    }
    //public class GTSCardInitialConfigBase : InitialConfigBase, IMonitorConfig
    //{
    //    [Category("驱动类型")]
    //    [Description("驱动类型")]
    //    [DisplayName("驱动类型")]
    //    [TypeConverter(typeof(PLCTypeConverter))]
    //    public override string DriverType { get; set; }
    [Device("GTSCard", "固高板卡", EnumHelper.DeviceAttributeType.OperationConfig)]
    public class GTSCardInitialConfig : InitialConfigBase, IMonitorConfig
    {
        [Category("板卡配置")]
        [DisplayName("卡号")]
        [Description("CardNum:卡号")]
        public int CardNum { get; set; }
    //    [Category("警报配置")]
    //    [Description("警报配置列表")]
    //    [DisplayName("警报配置")]
    //    [TypeConverter(typeof(CollectionCountConvert))]
    //    [Editor(typeof(WarningSetsEditor), typeof(UITypeEditor))]
    //    public List<WarningSet> WarningSetCollection { get; set; } = new List<WarningSet>();
        //[Category("板卡配置")]
        //[Description("IO卡号")]
        //public int IOCardNum { get; set; }
    //    #region IMonitorConfig
    //    [Category("监听设置")]
    //    [Description("监听操作配置集合")]
    //    [DisplayName("监听配置")]
    //    [TypeConverter(typeof(CollectionCountConvert))]
    //    [Editor(typeof(ComplexCollectionEditor<MonitorSet>), typeof(UITypeEditor))]
    //    public List<IMonitorSet> MonitorSetCollection { get; set; } = new List<IMonitorSet>();
        [Category("板卡配置")]
        [DisplayName("初始配置文件路径")]
        [Description("InitialConfigFilePath:初始配置文件路径")]
        [Editor(typeof(FileDialogEditor), typeof(UITypeEditor))]
        public string InitialConfigFilePath { get; set; }
    //    [Category("监听设置")]
    //    [Description("true:启动监听 false:关闭监听")]
    //    [DisplayName("监听启用")]
    //    public bool IsEnableMonitor { get; set; } = true;
        [Category("IO扫描配置")]
        [DisplayName("扫描间隔")]
        [Description("ScanInterval:扫描间隔,以毫秒为单位")]
        public int ScanInterval { get; set; } = 100;
    //    [Category("监听设置")]
    //    [Description("扫描间隔时间,单位:ms")]
    //    [DisplayName("扫描间隔")]
    //    public int MonitorInterval { get; set; } = 100;
        [Category("轴配置")]
        [DisplayName("轴数量")]
        [Description("AxisNum:轴数量")]
        public int AxisNum { get; set; } = 2;
    //    [Category("监听设置")]
    //    [Description("超时设置,单位:ms")]
    //    [DisplayName("监听超时")]
    //    public int MonitorTimeout { get; set; } = 500;
        [Category("轴配置")]
        [DisplayName("轴配置信息集合")]
        [Description("AxisSettings:轴配置信息集合")]
        [TypeConverter(typeof(CollectionCountConvert))]
        [Editor(typeof(ComplexCollectionEditor<AxisSetting>), typeof(UITypeEditor))]
        public List<AxisSetting> AxisSettings { get; set; } = new List<AxisSetting>();
    //    [Category("事件地址设置")]
    //    [Description("事件开始地址,PLC的实际寄存器地址。十进制,不包含功能码。")]
    //    [DisplayName("监听开始地址")]
    //    public int EventStartAddress { get; set; } = 8000;
        [Category("轴配置")]
        [DisplayName("轴速度比率")]
        [Description("AxisVelocityRatio:轴速度比率")]
        public double AxisVelocityRatio { get; set; } = 1;
    //    [Category("事件地址设置")]
    //    [Description("事件地址长度,最大长度128")]
    //    [DisplayName("监听长度")]
    //    public int EventLength { get; set; } = 120;
        [Category("延时配置")]
        [DisplayName("动作完成后延迟")]
        [Description("ActionAfterDelay:动作完成后延迟")]
        public int ActionAfterDelay { get; set; } = 100;
    //    public List<IMonitorSet> GetAllMonitorSet()
    //    {
    //        WarningSetCollection.ForEach(m => m.Source = this.Name);
        public bool IsEnableMonitor { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
        public int MonitorInterval { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
        public int MonitorTimeout { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
        public List<IMonitorSet> MonitorSetCollection { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
    //        MonitorSetCollection.ForEach(m => m.SourceDevice = this.Id);
    //        return MonitorSetCollection;
    //    }
    //    #endregion
    //    #region IMotion Related
    //    [Category("运动配置")]
    //    [Description("运动轴状态集合")]
    //    [DisplayName("运动轴状态集合")]
    //    [TypeConverter(typeof(CollectionCountConvert))]
    //    [Editor(typeof(ComplexCollectionEditor<PLCMotionDefinition_State>), typeof(UITypeEditor))]
    //    public List<PLCMotionDefinition_State> MotionStateCollection { get; set; } = new List<PLCMotionDefinition_State>();
    //    #endregion
    //}
        public List<IMonitorSet> GetAllMonitorSet()
        {
            throw new NotImplementedException();
        }
    }
    /// <summary>
    /// 点位类型
    /// 轴配置
    /// </summary>
    public enum PosType
    public class AxisSetting : IComplexDisplay
    {
        /// <summary>
        /// 直线插补
        /// </summary>
        Line = 1,
        /// <summary>
        /// 圆弧插补(半径)
        /// </summary>
        CircleRadius,
        /// <summary>
        /// 圆弧插补(圆心)
        /// </summary>
        CircleCenter
        [Category("轴配置")]
        [DisplayName("轴号索引")]
        [Description("AxisIndex:轴号索引")]
        public int AxisIndex { get; set; }
        [Category("轴配置")]
        [DisplayName("轴名称")]
        [Description("AxisName:轴名称")]
        public string AxisName { get; set; }
        [Category("轴配置")]
        [DisplayName("轴是否启用")]
        [Description("IsAxisEnabled:轴是否启用")]
        public bool IsAxisEnabled { get; set; } = false;
        [Category("换算配置")]
        [DisplayName("脉冲数换算比例")]
        [Description("脉冲数和其他计量单位的换算比例,例如设置为1000,表示1000个脉冲等于1uint")]
        public int PulseRatio { get; set; } = 1;
        [Category("速度配置")]
        [DisplayName("默认速度参数")]
        [Description("VelocityPara:默认速度参数")]
        [TypeConverter(typeof(ComplexObjectConvert))]
        [Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
        public VelocityPara VelocityPara { get; set; } = new VelocityPara();
        [Category("回原点设置")]
        [DisplayName("回原点模式")]
        [Description("HomeMode:回原点模式。0:一般模式 1:极限限位模式 2:外部触发模式")]
        public int HomeMode { get; set; } = 0;
        [Category("回原点设置")]
        [DisplayName("回原点方向")]
        [Description("IsHomePositive:回原点方向。 true:正方向开始  false:负方向开始")]
        public bool IsHomePositive { get; set; } = true;
        [Category("回原点设置")]
        [DisplayName("是否自动回原点")]
        [Description("IsAutoGoHome:是否自动回原点。 true:是  false:否")]
        public bool IsAutoGoHome { get; set; } = false;
        [Category("超时设置")]
        [DisplayName("回原点超时")]
        [Description("TimeOutHome:回原点超时,单位毫秒")]
        public int TimeOutHome { get; set; } = 30000;
        [Category("超时设置")]
        [DisplayName("运动超时")]
        [Description("TimeOutMove:运动超时,单位毫秒")]
        public int TimeOutMove { get; set; } = 10000;
        [Category("开闭环设置")]
        [DisplayName("是否使用Cmmd回馈")]
        [Description("IsUseCmmdPosition:是否使用Cmmd回馈")]
        public bool IsUseCmmdPosition { get; set; } = false;
        [Category("开闭环设置")]
        [DisplayName("是否使用板卡反馈停止信号")]
        [Description("IsUseMDNStopSignal:是否使用板卡反馈停止信号")]
        public bool IsUseMDNStopSignal { get; set; } = false;
        [Category("开闭环设置")]
        [DisplayName("是否启用报警")]
        [Description("IsUseWarning:是否启用报警")]
        public bool IsUseWarning { get; set; } = false;
        [Category("暂停配置")]
        [DisplayName("是否启用立即暂停")]
        [Description("IsImmediatePause:是否启用立即暂停")]
        public bool IsImmediatePause { get; set; } = false;
        [Category("暂停配置")]
        [DisplayName("轴位置处于区间内时适用的暂停操作")]
        [Description("ImmediatePauseSections:当轴位置处于区间内时适用的暂停操作")]
        [TypeConverter(typeof(CollectionCountConvert))]
        [Editor(typeof(ComplexCollectionEditor<Section>), typeof(UITypeEditor))]
        public List<Section> ImmediatePauseSections { get; set; } = new List<Section>();
        public string GetDisplayText()
        {
            return AxisIndex + "-" + AxisName + "-" + (IsAxisEnabled ? "启用" : "禁用");
        }
    }
    public static class GTSCardParameter
    /// <summary>
    /// 位置对象
    /// </summary>
    public class Section : IComplexDisplay
    {
        #region 运动参数
        public static int Dangliang = 1;
        public static int AxisCount = 2;//运动轴数量
        public static short CardNum = Convert.ToInt16(ConfigurationManager.AppSettings["cardNum"]);
        public static short fifo = Convert.ToInt16(ConfigurationManager.AppSettings["fifo"]);
        public static int FlySpeed = Convert.ToInt32(ConfigurationManager.AppSettings["flySpeed"]);
        public static double FlyAcc = Convert.ToDouble(ConfigurationManager.AppSettings["flyAcc"]);
        public static int P2PSpeed = Convert.ToInt32(ConfigurationManager.AppSettings["p2pSpeed"]);
        public static double P2PAcc = Convert.ToDouble(ConfigurationManager.AppSettings["p2pAcc"]);
        public static double P2PDec = Convert.ToDouble(ConfigurationManager.AppSettings["p2pDec"]);
        public static int FreeSpeed = Convert.ToInt32(ConfigurationManager.AppSettings["freeSpeed"]);
        public static int VelEnd = Convert.ToInt32(ConfigurationManager.AppSettings["velEnd"]);//飞拍结束速度
        public static int HomeSpeed = Convert.ToInt32(ConfigurationManager.AppSettings["homeSpeed"]);
        public static int Loading = Convert.ToInt32(ConfigurationManager.AppSettings["loading"]);
        //public const short cardn = 0;//运动控制器卡号 默认为:0
        //public const short crdn = 1;//坐标系号 取值范围:[1, 2]
        //public const short fifo = 0;//插补缓存区号 取值范围:[0, 1],默认值为:0
        //public const int flySpeed = 250;//飞拍速度
        //public const double flyAcc = 0.5;//飞拍加速度
        //public const int gocatorSpeed = 150;//3D检测轴运动速度
        //public const int p2pSpeed = 250;//P2P速度
        //public const double p2pAcc = 1;//P2P加速度
        //public const double p2pDec = 1;//P2P减速度
        //public const int calibrationSpeed = 10;//标定速度
        //public const int calibrationZ = 19336;//标定Z轴高度
        //public const int barcodeSpeed = 250;//条码检测轴运动速度
        //public const int freeSpeed = 250;//非检测时轴运动速度
        //public const int velEnd = 0;//飞拍结束速度
        //public const int homeSpeed = 50;//回零速度
        //public const int loading = 80000;//上料位置
        #endregion
        [Category("暂停区间")]
        [DisplayName("起始位置")]
        [Description("StartPosition:起始位置")]
        public int StartPosition { get; set; }
        #region IO
        /// <summary>
        /// 输入IO默认值
        /// </summary>
        public const int InDefaultValue = 0xFFDA;
        /// <summary>
        /// 夹紧气缸
        /// </summary>
        public const short EXO_1 = 100;//夹紧气缸
        /// <summary>
        /// 日光灯
        /// </summary>
        public const short EXO_2 = 101;//日光灯
        /// <summary>
        /// 光源切换
        /// </summary>
        public const short EXO_3 = 102;//光源切换
        /// <summary>
        /// 红灯
        /// </summary>
        public const short EXO_4 = 103;//红灯
        /// <summary>
        /// 黄灯
        /// </summary>
        public const short EXO_5 = 104;//黄灯
        /// <summary>
        /// 绿灯
        /// </summary>
        public const short EXO_6 = 105;//绿灯
        /// <summary>
        /// 蜂鸣器
        /// </summary>
        public const short EXO_7 = 106;//蜂鸣器
        /// <summary>
        /// Gocator X
        /// </summary>
        public const short EXO_8 = 107;//Gocator X
        [Category("暂停区间")]
        [DisplayName("结束位置")]
        [Description("EndPosition:结束位置")]
        public int EndPosition { get; set; }
        /// <summary>
        /// 正面光(左)
        /// </summary>
        public const short EXO_9 = 108;//正面光(左)
        /// <summary>
        /// 正面光(后)
        /// </summary>
        public const short EXO_10 = 109;//正面光(后)
        /// <summary>
        /// 正面光(右)
        /// </summary>
        public const short EXO_11 = 110;//正面光(右)
        /// <summary>
        /// 正面光(前)
        /// </summary>
        public const short EXO_12 = 111;//正面光(前)
        /// <summary>
        /// Gocator Y
        /// </summary>
        public const short EXO_16 = 115;//Gocator Y
        /// <summary>
        /// 输出IO默认值
        /// </summary>
        public const int OutDefaultValue = 0xFFF;
        /// <summary>
        /// 左启动
        /// </summary>
        public const short EXI0 = 0;//左起动
        /// <summary>
        /// 右启动
        /// </summary>
        public const short EXI1 = 1;//右起动
        /// <summary>
        /// 停止
        /// </summary>
        public const short EXI2 = 2;//停止
        /// <summary>
        /// 复位
        /// </summary>
        public const short EXI3 = 3;//复位
        /// <summary>
        /// 急停
        /// </summary>
        public const short EXI4 = 4;//急停
        /// <summary>
        /// 门开关
        /// </summary>
        public const short EXI5 = 5;//门开关
        /// <summary>
        /// 安全光幕
        /// </summary>
        public const short EXI6 = 6;//安全光幕
        public const short EXI7 = 7;//
        /// <summary>
        /// 夹紧气缸原位
        /// </summary>
        public const short EXI8 = 8;//夹紧气缸原位
        /// <summary>
        /// 夹紧气缸到位
        /// </summary>
        public const short EXI9 = 9;//夹紧气缸到位
        #endregion
        public string GetDisplayText()
        {
            return $"{StartPosition}--{EndPosition}";
        }
    }
    /// <summary>
    /// 速度参数对象
    /// </summary>
    public class VelocityPara
    {
        [Category("速度配置")]
        [DisplayName("速度")]
        [Description("Velocity:速度,为0时表示不修改当前设置")]
        public double Velocity { get; set; } = 0;
        [Category("速度配置")]
        [DisplayName("加速度")]
        [Description("Acc:加速度,为0时表示不修改当前设置")]
        public double Acc { get; set; } = 0;
        [Category("速度配置")]
        [DisplayName("减速度")]
        [Description("减速度,为0时表示不修改当前设置。回原点模式时设置为曲线参数")]
        public double Dec { get; set; } = 0;
    }
    /// <summary>
    /// 运动对象
    /// </summary>
    public class MovingOption : INotifyPropertyChanged, IComplexDisplay
    {
        private int axisIndex = 0;
        [Category("运动配置")]
        [DisplayName("运动轴索引")]
        [Description("AxisIndex:运动轴索引")]
        [TypeConverter(typeof(AxisIndexConvert))]
        public int AxisIndex
        {
            get => axisIndex;
            set
            {
                if (axisIndex != value)
                {
                    axisIndex = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("AxisIndex"));
                }
                axisIndex = value;
            }
        }
        private MotorMoveMode moveMode = MotorMoveMode.Normal;
        [Category("运动配置")]
        [DisplayName("运动模式")]
        [Description("MoveMode:运动模式")]
        public MotorMoveMode MoveMode
        {
            get => moveMode;
            set
            {
                if (moveMode != value)
                {
                    moveMode = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("MoveMode"));
                }
                moveMode = value;
            }
        }
        private bool isAbsolute = true;
        [Category("运动配置")]
        [DisplayName("是否绝对运动")]
        [Description("IsAbsolute:是否绝对运动")]
        public bool IsAbsolute
        {
            get => isAbsolute;
            set
            {
                if (isAbsolute != value)
                {
                    isAbsolute = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsAbsolute"));
                }
                isAbsolute = value;
            }
        }
        private int destination = 0;
        [Category("运动配置")]
        [DisplayName("目的地")]
        [Description("Destination:目的地")]
        public int Destination
        {
            get => destination;
            set
            {
                if (destination != value)
                {
                    destination = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Destination"));
                }
                destination = value;
            }
        }
        private VelocityPara velocityPara = new VelocityPara();
        [Category("运动配置")]
        [DisplayName("速度参数")]
        [Description("VelocityPara:速度参数")]
        [TypeConverter(typeof(ComplexObjectConvert))]
        [Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
        public VelocityPara VelocityPara
        {
            get => velocityPara;
            set
            {
                velocityPara = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("VelocityPara"));
            }
        }
        internal List<AxisSetting> _axisSettingList = new List<AxisSetting>();
        public void SetAxisSetting(List<AxisSetting> settings)
        {
            if (settings != null)
                _axisSettingList = settings;
        }
        public string GetDisplayText()
        {
            string axisName = AxisIndex.ToString();
            var axisSet = _axisSettingList.FirstOrDefault(a => a.AxisIndex == AxisIndex);
            if (axisSet != null)
            {
                axisName += ("-" + axisSet.AxisName);
            }
            return axisName + "," + MoveMode.ToString() + "," + (IsAbsolute ? "Abs" : "Rel") + "," + Destination;
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
    public class AxisIndexConvert : TypeConverter
    {
        Dictionary<int, string> _indexNameDict = new Dictionary<int, string>();
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {
            return true;
        }
        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            MovingOption mo = context.Instance as MovingOption;
            _indexNameDict = mo._axisSettingList.ToDictionary(a => a.AxisIndex, a => a.AxisIndex + "-" + a.AxisName);
            return new StandardValuesCollection(_indexNameDict.Keys);
        }
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(string))
            {
                return true;
            }
            return base.CanConvertFrom(context, sourceType);
        }
        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object v)
        {
            if (v is string)
            {
                foreach (var indexName in _indexNameDict)
                {
                    if (indexName.Value == v.ToString())
                    {
                        return indexName.Key;
                    }
                }
                return Convert.ToInt32(v);
            }
            return base.ConvertFrom(context, culture, v);
        }
        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object v, Type destinationType)
        {
            if (destinationType == typeof(string))
            {
                if (_indexNameDict.ContainsKey(Convert.ToInt32(v)))
                {
                    return _indexNameDict[Convert.ToInt32(v)];
                }
            }
            return base.ConvertTo(context, culture, v, destinationType);
        }
        public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
        {
            return false;
        }
    }
    public class AxisConflictSet : IComplexDisplay
    {
        [Category("1.轴冲突条件")]
        [Description("轴冲突条件,满足全部条件时轴运动需要检查冲突")]
        [TypeConverter(typeof(CollectionCountConvert))]
        [Editor(typeof(ComplexCollectionEditor<AxisLimit>), typeof(UITypeEditor))]
        public List<AxisLimit> AxisOptions { get; set; } = new List<AxisLimit>();
        [Category("1.轴冲突条件")]
        [Description("IO冲突条件,满足全部条件时轴运动需要检查冲突")]
        [TypeConverter(typeof(CollectionCountConvert))]
        [Editor(typeof(ComplexCollectionEditor<IOLimit>), typeof(UITypeEditor))]
        public List<IOLimit> IOOptions { get; set; } = new List<IOLimit>();
        [Category("2.轴冲突限制")]
        [Description("轴冲突限制,轴运动允许区间")]
        [TypeConverter(typeof(CollectionCountConvert))]
        [Editor(typeof(ComplexCollectionEditor<AxisLimit>), typeof(UITypeEditor))]
        public List<AxisLimit> AxisLimits { get; set; } = new List<AxisLimit>();
        [Category("2.轴冲突限制")]
        [Description("IO允许条件,允许输出的IO")]
        [TypeConverter(typeof(CollectionCountConvert))]
        [Editor(typeof(ComplexCollectionEditor<IOLimit>), typeof(UITypeEditor))]
        public List<IOLimit> IOOutputs { get; set; } = new List<IOLimit>();
        [Category("3.轴冲突启用")]
        [Description("true:启用轴冲突限制 false:不启用轴冲突限制")]
        public bool IsEnabled { get; set; } = true;
        public string GetDisplayText()
        {
            string optionStr = "Options:" + String.Join(";", AxisOptions.Select(a => a.GetDisplayText()));
            string limitStr = "Limits:" + String.Join(";", AxisLimits.Select(a => a.GetDisplayText()));
            return optionStr + "|" + limitStr;
        }
    }
    public class AxisLimit : IComplexDisplay
    {
        [Category("1.轴号")]
        [Description("1.轴号")]
        public int AxisIndex { get; set; }
        [Category("2.轴最小限制")]
        [Description("2.轴最小限制")]
        public int LimitMin { get; set; }
        [Category("3.轴最大限制")]
        [Description("3.轴最大限制")]
        public int LimitMax { get; set; }
        private int currentPosition = 0;
        [Browsable(false)]
        [JsonIgnore]
        public int CurrentPosition
        {
            get => currentPosition;
            set
            {
                if (currentPosition != value)
                {
                    if (value >= LimitMin && value <= LimitMax)
                    {
                        IsInLimit = true;
                    }
                    else
                    {
                        IsInLimit = false;
                    }
                }
                currentPosition = value;
            }
        }
        [Browsable(false)]
        [JsonIgnore]
        public bool IsInLimit { get; set; }
        public string GetDisplayText()
        {
            return String.Format("Index:{0},{1}->{2}", AxisIndex, LimitMin, LimitMax);
        }
    }
    public class IOLimit : IComplexDisplay
    {
        [Category("1.IO限制")]
        [Description("IO索引")]
        public int IOIndex { get; set; }
        [Category("1.IO限制")]
        [Description("IO限制值。输入判断时该值作为启用判断值,输出判断时该值作为允许输出值")]
        public bool IOSignal { get; set; }
        public string GetDisplayText()
        {
            return IOIndex + "--" + IOSignal.ToString();
        }
    }
    public class AxisMovingStay
    {
        public int Position { get; set; }
        public int Velocity { get; set; }
        public AutoResetEvent MoveHandle { get; set; } = new AutoResetEvent(false);
        public AutoResetEvent MoveSendHandle { get; set; } = new AutoResetEvent(false);
    }
    ///// <summary>
    ///// 点位类型
    ///// </summary>
    //public enum PosType
    //{
    //    /// <summary>
    //    /// 直线插补
    //    /// </summary>
    //    Line = 1,
    //    /// <summary>
    //    /// 圆弧插补(半径)
    //    /// </summary>
    //    CircleRadius,
    //    /// <summary>
    //    /// 圆弧插补(圆心)
    //    /// </summary>
    //    CircleCenter
    //}
    //public static class GTSCardParameter
    //{
    //    #region 运动参数
    //    public static int Dangliang = 1;
    //    public static int AxisCount = 2;//运动轴数量
    //    public static short CardNum = Convert.ToInt16(ConfigurationManager.AppSettings["cardNum"]);
    //    public static short fifo = Convert.ToInt16(ConfigurationManager.AppSettings["fifo"]);
    //    public static int FlySpeed = Convert.ToInt32(ConfigurationManager.AppSettings["flySpeed"]);
    //    public static double FlyAcc = Convert.ToDouble(ConfigurationManager.AppSettings["flyAcc"]);
    //    public static int P2PSpeed = Convert.ToInt32(ConfigurationManager.AppSettings["p2pSpeed"]);
    //    public static double P2PAcc = Convert.ToDouble(ConfigurationManager.AppSettings["p2pAcc"]);
    //    public static double P2PDec = Convert.ToDouble(ConfigurationManager.AppSettings["p2pDec"]);
    //    public static int FreeSpeed = Convert.ToInt32(ConfigurationManager.AppSettings["freeSpeed"]);
    //    public static int VelEnd = Convert.ToInt32(ConfigurationManager.AppSettings["velEnd"]);//飞拍结束速度
    //    public static int HomeSpeed = Convert.ToInt32(ConfigurationManager.AppSettings["homeSpeed"]);
    //    public static int Loading = Convert.ToInt32(ConfigurationManager.AppSettings["loading"]);
    //    //public const short cardn = 0;//运动控制器卡号 默认为:0
    //    //public const short crdn = 1;//坐标系号 取值范围:[1, 2]
    //    //public const short fifo = 0;//插补缓存区号 取值范围:[0, 1],默认值为:0
    //    //public const int flySpeed = 250;//飞拍速度
    //    //public const double flyAcc = 0.5;//飞拍加速度
    //    //public const int gocatorSpeed = 150;//3D检测轴运动速度
    //    //public const int p2pSpeed = 250;//P2P速度
    //    //public const double p2pAcc = 1;//P2P加速度
    //    //public const double p2pDec = 1;//P2P减速度
    //    //public const int calibrationSpeed = 10;//标定速度
    //    //public const int calibrationZ = 19336;//标定Z轴高度
    //    //public const int barcodeSpeed = 250;//条码检测轴运动速度
    //    //public const int freeSpeed = 250;//非检测时轴运动速度
    //    //public const int velEnd = 0;//飞拍结束速度
    //    //public const int homeSpeed = 50;//回零速度
    //    //public const int loading = 80000;//上料位置
    //    #endregion
    //    #region IO
    //    /// <summary>
    //    /// 输入IO默认值
    //    /// </summary>
    //    public const int InDefaultValue = 0xFFDA;
    //    /// <summary>
    //    /// 夹紧气缸
    //    /// </summary>
    //    public const short EXO_1 = 100;//夹紧气缸
    //    /// <summary>
    //    /// 日光灯
    //    /// </summary>
    //    public const short EXO_2 = 101;//日光灯
    //    /// <summary>
    //    /// 光源切换
    //    /// </summary>
    //    public const short EXO_3 = 102;//光源切换
    //    /// <summary>
    //    /// 红灯
    //    /// </summary>
    //    public const short EXO_4 = 103;//红灯
    //    /// <summary>
    //    /// 黄灯
    //    /// </summary>
    //    public const short EXO_5 = 104;//黄灯
    //    /// <summary>
    //    /// 绿灯
    //    /// </summary>
    //    public const short EXO_6 = 105;//绿灯
    //    /// <summary>
    //    /// 蜂鸣器
    //    /// </summary>
    //    public const short EXO_7 = 106;//蜂鸣器
    //    /// <summary>
    //    /// Gocator X
    //    /// </summary>
    //    public const short EXO_8 = 107;//Gocator X
    //    /// <summary>
    //    /// 正面光(左)
    //    /// </summary>
    //    public const short EXO_9 = 108;//正面光(左)
    //    /// <summary>
    //    /// 正面光(后)
    //    /// </summary>
    //    public const short EXO_10 = 109;//正面光(后)
    //    /// <summary>
    //    /// 正面光(右)
    //    /// </summary>
    //    public const short EXO_11 = 110;//正面光(右)
    //    /// <summary>
    //    /// 正面光(前)
    //    /// </summary>
    //    public const short EXO_12 = 111;//正面光(前)
    //    /// <summary>
    //    /// Gocator Y
    //    /// </summary>
    //    public const short EXO_16 = 115;//Gocator Y
    //    /// <summary>
    //    /// 输出IO默认值
    //    /// </summary>
    //    public const int OutDefaultValue = 0xFFF;
    //    /// <summary>
    //    /// 左启动
    //    /// </summary>
    //    public const short EXI0 = 0;//左起动
    //    /// <summary>
    //    /// 右启动
    //    /// </summary>
    //    public const short EXI1 = 1;//右起动
    //    /// <summary>
    //    /// 停止
    //    /// </summary>
    //    public const short EXI2 = 2;//停止
    //    /// <summary>
    //    /// 复位
    //    /// </summary>
    //    public const short EXI3 = 3;//复位
    //    /// <summary>
    //    /// 急停
    //    /// </summary>
    //    public const short EXI4 = 4;//急停
    //    /// <summary>
    //    /// 门开关
    //    /// </summary>
    //    public const short EXI5 = 5;//门开关
    //    /// <summary>
    //    /// 安全光幕
    //    /// </summary>
    //    public const short EXI6 = 6;//安全光幕
    //    public const short EXI7 = 7;//
    //    /// <summary>
    //    /// 夹紧气缸原位
    //    /// </summary>
    //    public const short EXI8 = 8;//夹紧气缸原位
    //    /// <summary>
    //    /// 夹紧气缸到位
    //    /// </summary>
    //    public const short EXI9 = 9;//夹紧气缸到位
    //    #endregion
    //}
}