using Bro.Common.Helper; using Newtonsoft.Json; using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Drawing.Design; using System.Globalization; 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("回原点参数")] [TypeConverter(typeof(ComplexObjectConvert))] [Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))] public GoHomePara GoHomePara { get; set; } = new GoHomePara(); [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; } = 0; [Category("速度配置")] [DisplayName("减速度")] [Description("减速度,为0时表示不修改当前设置")] public double Dec { get; set; } = 0; } /// /// 回原点参数对象 /// 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("edge:边缘")] //public short Edge { get; set; } = 0; //[Category("回原点速度")] //[DisplayName("回原点最低速度")] //[Description("LowVelocity:速度,为0时表示不修改当前设置")] //public double LowVelocity { get; set; } = 50; [Category("回原点速度")] [DisplayName("回原点速度")] [Description("HomeVelocity:速度,为0时表示不修改当前设置")] public double HomeVelocity { 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; [Category("回原点方向")] [DisplayName("起始运动方向")] [Description("回原点时,轴的初始运动方向:true 正向,false 负向")] public bool IsHomeDirPositive { get; set; } = true; [Category("回原点方向")] [DisplayName("原点捕捉方向")] [Description("捕捉原点时,轴的运动方向:true 正向,false 负向")] public bool IsCaptureDirPositive { get; set; } = true; [Category("回原点超时")] [DisplayName("回原点超时")] [Description("回原点超时,单位秒")] public int GoHomeTimeOut { get; set; } = 60; [Category("原点捕获模式")] [Description("原点捕获模式,true:使用捕获模式,false:使用原点输入信号")] [DisplayName("原点捕获模式")] public bool IsCaptureMode { get; set; } = true; } /// /// 板卡运动状态对象 /// public class AxisMovingStatus : IComplexDisplay { /// /// 轴索引 /// public int AxisIndex { get; set; } /// /// 轴名称 /// public string AxisName { get; set; } /// /// 当前位置 /// public int CurPosition { get; set; } /// /// 目的地 /// public int Destination { get; set; } /// /// 当前速度参数 /// public double CurVelocity { get; set; } /// /// 规划速度参数 /// public double PrfVelocity { get; set; } /// /// 轴状态 /// public int AxisStatus { get; set; } public string GetDisplayText() { return $"轴{AxisIndex}:{AxisName}-当前状态:{AxisStatus}-当前位置:{CurPosition}-规划位置:{Destination}"; } } /// /// 运动对象 /// public class MovingOption : IComplexDisplay { [Category("运动配置")] [DisplayName("运动轴索引")] [Description("AxisIndex:运动轴索引")] [TypeConverter(typeof(AxisIndexConvert))] public string AxisIndexStr { get; set; } = "1"; [Browsable(false)] [JsonIgnore] public int AxisIndex { get => int.Parse(AxisIndexStr); set => AxisIndexStr = value.ToString(); } //private int axisIndex = 0; //[Category("运动配置")] //[DisplayName("运动轴索引")] //[Description("AxisIndex:运动轴索引")] //[TypeConverter(typeof(AxisIndexConvert))] //public int AxisIndex { get; set; } //{ // 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; set; } = MotionMode.Normal; //{ // 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; set; } = true; //{ // 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; set; } //{ // 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; set; } = new 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; set; } = new 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 = AxisIndexStr; 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 : ComboBoxItemTypeConvert { public override Hashtable GetConvertHash(ITypeDescriptorContext context) { Hashtable table = new Hashtable(); if (context.Instance is MovingOption op) { op._axisSettingList.ForEach(a => { table[a.AxisIndex.ToString()] = a.AxisName; }); } return table; } //public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) //{ // bool flag = base.CanConvertFrom(context, sourceType); // return flag; //} //public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) //{ // return base.CanConvertTo(context, destinationType); //} //public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object v) //{ // //if (string.IsNullOrWhiteSpace(v.ToString())) // //{ // // return 0; // //} // return base.ConvertFrom(context, culture, Convert.ToInt32(v)); //} //public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object v, Type destinationType) //{ // return base.ConvertTo(context, culture, v, destinationType); //} } //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); } }