using Bro.Common.Helper; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing.Design; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using static Bro.Common.Helper.EnumHelper; namespace Bro.Common.Model { /// /// 轴配置 /// public class AxisSetting : IComplexDisplay { [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 AxisRatio { 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
), typeof(UITypeEditor))] //public List
ImmediatePauseSections { get; set; } = new List
(); public string GetDisplayText() { return AxisIndex + "-" + AxisName + "-" + (IsAxisEnabled ? "启用" : "禁用"); } } /// /// 位置对象 /// public class Section : IComplexDisplay { [Category("暂停区间")] [DisplayName("起始位置")] [Description("StartPosition:起始位置")] public int StartPosition { get; set; } [Category("暂停区间")] [DisplayName("结束位置")] [Description("EndPosition:结束位置")] public int EndPosition { get; set; } public string GetDisplayText() { return $"{StartPosition}--{EndPosition}"; } } /// /// 速度参数对象 /// public class VelocityPara { [Category("速度配置")] [DisplayName("速度")] [Description("Velocity:速度,为0时表示不修改当前设置")] public double Velocity { get; set; } = 0; [Category("速度配置")] [DisplayName("加速度")] [Description("Acc:加速度,为0时表示不修改当前设置")] public double Acc { get; set; } = 1; [Category("速度配置")] [DisplayName("减速度")] [Description("减速度,为0时表示不修改当前设置")] public double Dec { get; set; } = 1; } /// /// 回原点参数对象 /// public class GoHomePara { [Category("回原点参数")] [DisplayName("回原点方式")] [Description("HomeMode:回原点方式 (HOME_MODE_LIMIT = 10; HOME_MODE_LIMIT_HOME = 11; HOME_MODE_LIMIT_INDEX = 12; HOME_MODE_LIMIT_HOME_INDEX = 13;HOME_MODE_HOME = 20;HOME_MODE_HOME_INDEX = 22;HOME_MODE_INDEX = 30;")] public short HomeMode { get; set; } = 11; [Category("回原点参数")] [DisplayName("回原点方向")] [Description("HomeDir:1 正向,-1 负向")] public short HomeDir { get; set; } = 1; [Category("回原点参数")] [DisplayName("回原点方向")] [Description("HomeDir:1 正向,-1 负向")] public short Edge { get; set; } = 0; [Category("回原点参数")] [DisplayName("回原点最低速度")] [Description("LowVelocity:速度,为0时表示不修改当前设置")] public double LowVelocity { get; set; } = 50; [Category("回原点参数")] [DisplayName("回原点最高速度")] [Description("HighVelocity:速度,为0时表示不修改当前设置")] public double HighVelocity { get; set; } = 50; [Category("回原点参数")] [DisplayName("搜搜距离")] [Description("SearchHomeDistance:搜搜距离")] public int SearchHomeDistance { get; set; } = 9999999; [Category("回原点参数")] [DisplayName("偏移距离")] [Description("HomeOffset:偏移距离")] public int HomeOffset { get; set; } = 0; [Category("回原点参数")] [DisplayName("跳过步长")] [Description("EscapeStep:跳过步长")] public int EscapeStep { get; set; } = 1000; } /// /// 运动对象 /// 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 MotionMode moveMode = MotionMode.Normal; [Category("运动配置")] [DisplayName("运动模式")] [Description("MoveMode:运动模式")] public MotionMode 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")); } } private GoHomePara goHomePara = new GoHomePara(); [Category("运动配置")] [DisplayName("回原点参数")] [Description("GoHomePara:速度参数")] [TypeConverter(typeof(ComplexObjectConvert))] [Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))] public GoHomePara GoHomePara { get => goHomePara; set { goHomePara = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("GoHomePara")); } } [Category("板卡运动配置")] [Description("超时设置,单位:ms")] [DisplayName("运动超时")] public int MovingTimeout { get; set; } = 0; internal List _axisSettingList = new List(); public void SetAxisSetting(List 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 _indexNameDict = new Dictionary(); 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), typeof(UITypeEditor))] public List AxisOptions { get; set; } = new List(); [Category("1.轴冲突条件")] [Description("IO冲突条件,满足全部条件时轴运动需要检查冲突")] [TypeConverter(typeof(CollectionCountConvert))] [Editor(typeof(ComplexCollectionEditor), typeof(UITypeEditor))] public List IOOptions { get; set; } = new List(); [Category("2.轴冲突限制")] [Description("轴冲突限制,轴运动允许区间")] [TypeConverter(typeof(CollectionCountConvert))] [Editor(typeof(ComplexCollectionEditor), typeof(UITypeEditor))] public List AxisLimits { get; set; } = new List(); [Category("2.轴冲突限制")] [Description("IO允许条件,允许输出的IO")] [TypeConverter(typeof(CollectionCountConvert))] [Editor(typeof(ComplexCollectionEditor), typeof(UITypeEditor))] public List IOOutputs { get; set; } = new List(); [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); } }