using Autofac;
|
using Bro.Common.Helper;
|
using Bro.Common.Interface;
|
using Bro.Common.Model;
|
using Newtonsoft.Json;
|
using System;
|
using System.Collections.Generic;
|
using System.ComponentModel;
|
using System.ComponentModel.Design;
|
using System.Drawing.Design;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
using System.Windows.Forms;
|
using static Bro.Common.Helper.EnumHelper;
|
|
namespace Bro.Common.Base
|
{
|
public abstract class MotionCardBase : DeviceBase, IMonitor, IMotionCard
|
{
|
public event Action<DateTime, string, IDevice, IMonitorSet> OnMonitorInvoke;
|
public event Action<DateTime, IDevice, IWarningSet> OnMonitorAlarm;
|
public event Action<int, string> OnAxisAlarmRaised;
|
public event Action<int, int, int> OnAxisStatusChanged;
|
public event Action<int, int> OnAxisPositionChanged;
|
|
public void AxisAlarmRaised(int axisIndex, string msg)
|
{
|
OnAxisAlarmRaised?.Invoke(axisIndex, msg);
|
}
|
|
public void AxisStatusChanged(int axisIndex, int preStatus, int curStatus)
|
{
|
OnAxisStatusChanged?.Invoke(axisIndex, preStatus, curStatus);
|
}
|
|
public void AxisPositionChanged(int axisIndex, int currentPosition)
|
{
|
OnAxisPositionChanged?.Invoke(axisIndex, currentPosition);
|
}
|
|
protected override void Start()
|
{
|
AxisStatusList = IConfig.AxisSettings.Where(a => a.IsAxisEnabled).ToList().ConvertAll(a =>
|
{
|
AxisMovingStatus axisSts = new AxisMovingStatus();
|
axisSts.AxisIndex = a.AxisIndex;
|
axisSts.AxisName = a.AxisName;
|
|
return axisSts;
|
});
|
|
Task.Run(() =>
|
{
|
Monitor();
|
});
|
}
|
public abstract List<AxisInfo> GetCurrentAxisInfo(params string[] axisName);
|
public abstract void Monitor();
|
public abstract ResponseMessage MoveToPoint(IOperationConfig opConfig);
|
public abstract void ResetAlarm();
|
public abstract ResponseMessage Run(IOperationConfig config);
|
/// <summary>
|
/// 清除状态
|
/// </summary>
|
/// <param name="startAxisIndex">起始轴号</param>
|
/// <param name="count">数量</param>
|
/// <returns></returns>
|
public abstract bool ClearStatus(int startAxisIndex, int count);
|
|
/// <summary>
|
/// 读取轴状态
|
/// </summary>
|
/// <param name="axisNum">轴号</param>
|
/// <returns></returns>
|
public abstract int GetAxisStatus(int axisNum);
|
|
/// <summary>
|
/// 位置清零
|
/// </summary>
|
/// <param name="startAxisIndex">起始轴号</param>
|
/// <param name="count">数量</param>
|
/// <returns></returns>
|
public abstract bool PositionReset(int startAxisIndex, int count);
|
|
public abstract bool AllAxisOn();
|
|
public abstract bool AllAxisOff();
|
|
public abstract Task<bool> AxisOnAsync(int axisNum);
|
|
public abstract Task<bool> AxisOffAsync(int axisNum);
|
|
/// <summary>
|
/// 单个轴 运动(点到点 jog 回零...)
|
/// </summary>
|
/// <param name="optionPara">运动参数对象</param>
|
public abstract Task<bool> SingleAxisMoving(MovingOption optionPara);
|
|
/// <summary>
|
/// 某个轴运动停止
|
/// </summary>
|
/// <param name="axisNum">轴号</param>
|
/// <param name="option">0表示平滑停止,1表示紧急停止</param>
|
/// <returns></returns>
|
public abstract Task<bool> MoveStop(int axisNum, int option);
|
|
public virtual void ExcuteMonitorInvoke(DateTime dateTime, string invokeDevice, IDevice device, IMonitorSet monitorSet)
|
{
|
OnMonitorInvoke?.BeginInvoke(dateTime, invokeDevice, device, monitorSet, OnMethodInvoked, null);
|
}
|
|
public abstract void OnMethodInvoked(IAsyncResult ar);
|
|
public virtual void ExcuteMonitorAlarm(DateTime dateTime, IDevice device, IWarningSet warningSet)
|
{
|
OnMonitorAlarm?.BeginInvoke(dateTime, device, warningSet, null, null);
|
}
|
|
public virtual MotionCardInitialConfigBase IConfig
|
{
|
get
|
{
|
return InitialConfig as MotionCardInitialConfigBase;
|
}
|
}
|
|
/// <summary>
|
/// IO的监听值
|
/// </summary>
|
public List<IOItem> MonitorValues { get; set; } = new List<IOItem>();
|
|
/// <summary>
|
/// 轴的运动状态值
|
/// </summary>
|
public List<AxisMovingStatus> AxisStatusList { get; set; } = new List<AxisMovingStatus>();
|
|
public abstract void WriteOutput(short index, IOValue value);
|
|
#region ImmediatePause
|
/// <summary>
|
/// 启动立即暂停
|
/// </summary>
|
public abstract void SetImmediatePause();
|
|
/// <summary>
|
/// 恢复立即暂停
|
/// </summary>
|
public abstract void ResetImmediatePause(bool isResumeMoving);
|
#endregion
|
}
|
|
public class MotionCardInitialConfigBase : InitialConfigBase, IMonitorConfig
|
{
|
[Category("板卡配置")]
|
[DisplayName("卡号")]
|
[Description("CardNum:卡号")]
|
public int CardNum { get; set; } = 1;
|
|
[Category("板卡配置")]
|
[DisplayName("初始配置文件路径")]
|
[Description("InitialConfigFilePath:初始配置文件路径")]
|
[Editor(typeof(FileDialogEditor), typeof(UITypeEditor))]
|
public string InitialConfigFilePath { get; set; }
|
|
[Category("轴配置")]
|
[DisplayName("轴数量")]
|
[Description("AxisNum:轴数量")]
|
public int AxisNum { get; set; } = 4;
|
|
[Category("轴配置")]
|
[DisplayName("轴配置信息集合")]
|
[Description("AxisSettings:轴配置信息集合")]
|
[TypeConverter(typeof(CollectionCountConvert))]
|
[Editor(typeof(ComplexCollectionEditor<AxisSetting>), typeof(UITypeEditor))]
|
public List<AxisSetting> AxisSettings { get; set; } = new List<AxisSetting>();
|
|
[Category("轴配置")]
|
[DisplayName("轴速度比率")]
|
[Description("AxisVelocityRatio:轴速度比率")]
|
public double AxisVelocityRatio { get; set; } = 1;
|
|
//[Category("延时配置")]
|
//[DisplayName("动作完成后延迟")]
|
//[Description("ActionAfterDelay:动作完成后延迟")]
|
//public int ActionAfterDelay { get; set; } = 100;
|
|
[Category("警报配置")]
|
[Description("WarningSetCollection:警报配置列表")]
|
[DisplayName("警报配置")]
|
[TypeConverter(typeof(CollectionCountConvert))]
|
[Editor(typeof(WarningSetsEditor), typeof(UITypeEditor))]
|
public List<IWarningSet> WarningSetCollection { get; set; } = new List<IWarningSet>();
|
|
[Category("IO配置")]
|
[Description("IO定义集合")]
|
[TypeConverter(typeof(CollectionCountConvert))]
|
[Editor(typeof(ComplexCollectionEditor<IODefinition>), typeof(UITypeEditor))]
|
public List<IODefinition> IODefinitionCollection { get; set; } = new List<IODefinition>();
|
|
[Category("IO配置")]
|
[Description("true:输出取反 false:输出不取反")]
|
public bool IsOutputReversed { get; set; } = true;
|
|
#region IMonitorConfig
|
[Category("监听设置")]
|
[Description("MonitorSetCollection:监听操作配置集合")]
|
[DisplayName("监听配置")]
|
[TypeConverter(typeof(CollectionCountConvert))]
|
[Editor(typeof(ComplexCollectionEditor<MotionCardMonitorSet>), typeof(UITypeEditor))]
|
public List<IMonitorSet> MonitorSetCollection { get; set; } = new List<IMonitorSet>();
|
|
[Category("监听设置")]
|
[Description("true:启动监听 false:关闭监听")]
|
[DisplayName("监听启用")]
|
public bool IsEnableMonitor { get; set; } = true;
|
|
[Category("监听设置")]
|
[Description("扫描间隔时间,单位:ms")]
|
[DisplayName("扫描间隔")]
|
public int MonitorInterval { get; set; } = 10;
|
|
[Category("监听设置")]
|
[Description("超时设置,单位:ms")]
|
[DisplayName("监听超时")]
|
public int MonitorTimeout { get; set; } = 500;
|
|
public List<IMonitorSet> GetAllMonitorSet()
|
{
|
WarningSetCollection.ForEach(m => m.Source = this.Name);
|
MonitorSetCollection.ForEach(m => m.SourceDevice = this.Id);
|
return MonitorSetCollection;
|
}
|
#endregion
|
}
|
|
[Device("MotionCardBase", "板卡操作配置基类", EnumHelper.DeviceAttributeType.OperationConfig)]
|
public class MotionCardOperationConfigBase : OperationConfigBase, IComplexDisplay
|
{
|
[Category("板卡操作")]
|
[Description("板卡操作配置基类集合,依次执行")]
|
[TypeConverter(typeof(CollectionCountConvert))]
|
[Editor(typeof(MotionCardOperationSetEditor), typeof(UITypeEditor))]
|
public List<MotionCardOperationSet> OperationCollection { get; set; } = new List<MotionCardOperationSet>();
|
|
public string GetDisplayText()
|
{
|
//OperationCollection.ForEach(o =>
|
//{
|
// o.MotionCardId = DeviceId;
|
//});
|
|
return string.Join(" ", OperationCollection.Select(u => u.GetDisplayText()));
|
}
|
}
|
|
public class MotionCardOperationSetEditor : ComplexCollectionEditor<MotionCardOperationSet>
|
{
|
public MotionCardOperationSetEditor(Type type) : base(type) { }
|
|
IOperationConfig opConfig = null;
|
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
|
{
|
if (context.Instance is IOperationConfig config && value is List<MotionCardOperationSet> setList)
|
{
|
opConfig = config;
|
setList.ForEach(set => set.MotionCardId = opConfig.DeviceId);
|
}
|
|
return base.EditValue(context, provider, value);
|
}
|
|
protected override object CreateInstance(Type itemType)
|
{
|
object obj = base.CreateInstance(itemType);
|
|
if (obj is MotionCardOperationSet set)
|
{
|
set.MotionCardId = opConfig?.DeviceId;
|
}
|
|
return obj;
|
}
|
|
}
|
|
[Device("MotionOperationSet", "运动操作配置基类", EnumHelper.DeviceAttributeType.OperationConfig)]
|
public class MotionCardOperationSet : IComplexDisplay
|
{
|
[Category("1.IO操作配置")]
|
[DisplayName("1.IO预检查")]
|
[Description("IO预检查定义集合")]
|
[TypeConverter(typeof(CollectionCountConvert))]
|
[Editor(typeof(IORefrenceItemCollectionEditor), typeof(UITypeEditor))]
|
public List<IORefrenceItem> PreCheckIOCollection { get; set; } = new List<IORefrenceItem>();
|
|
[Category("1.IO操作配置")]
|
[Description("超时设置,单位:ms")]
|
[DisplayName("2.IO预检查超时")]
|
public int PreCheckIOTimeout { get; set; } = 0;
|
|
[Category("1.IO操作配置")]
|
[DisplayName("3.IO输出")]
|
[Description("IO输出定义集合")]
|
[TypeConverter(typeof(CollectionCountConvert))]
|
[Editor(typeof(IORefrenceItemCollectionEditor), typeof(UITypeEditor))]
|
public List<IORefrenceItem> IOOutputCollection { get; set; } = new List<IORefrenceItem>();
|
|
[Category("1.IO操作配置")]
|
[DisplayName("4.IO输出确认")]
|
[Description("IO确认定义集合")]
|
[TypeConverter(typeof(CollectionCountConvert))]
|
[Editor(typeof(IORefrenceItemCollectionEditor), typeof(UITypeEditor))]
|
public List<IORefrenceItem> IOConfirmCollection { get; set; } = new List<IORefrenceItem>();
|
|
[Category("1.IO操作配置")]
|
[Description("超时设置,单位:ms")]
|
[DisplayName("5.IO输出确认超时")]
|
public int IOConfirmTimeout { get; set; } = 0;
|
|
[Category("2.板卡运动配置")]
|
[DisplayName("运动配置集合")]
|
[Description("MovingOps:运动配置集合")]
|
[TypeConverter(typeof(CollectionCountConvert))]
|
[Editor(typeof(MovingOpsCollectionEditor), typeof(UITypeEditor))]
|
public List<MovingOption> MovingOps { get; set; } = new List<MovingOption>();
|
|
[Category("3.运动延时")]
|
[Description("操作前延时,单位ms")]
|
public int DelayBefore { get; set; } = 0;
|
|
[Category("3.运动延时")]
|
[Description("操作后延时,单位ms")]
|
public int DelayAfter { get; set; } = 0;
|
|
public string MotionCardId = "";
|
|
//[Category("板卡运动配置")]
|
//[DisplayName("运动配置集合")]
|
//[Description("MovingOps:运动配置集合")]
|
//[TypeConverter(typeof(ComplexObjectConvert))]
|
//[Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
|
//public MotionOperationCollection MotionOperationCollection { get; set; } = new MotionOperationCollection();
|
|
|
public string GetDisplayText()
|
{
|
string preCheck = "";
|
PreCheckIOCollection.ForEach(i =>
|
{
|
preCheck += i.GetDisplayText() + " ";
|
});
|
if (preCheck != "")
|
{
|
preCheck = " 预检:" + preCheck;
|
}
|
|
string output = "";
|
IOOutputCollection.ForEach(i =>
|
{
|
output += i.GetDisplayText() + " ";
|
});
|
if (output != "")
|
{
|
output = " 输出:" + output;
|
}
|
string confirm = "";
|
IOConfirmCollection.ForEach(i =>
|
{
|
confirm += i.GetDisplayText() + " ";
|
});
|
if (confirm != "")
|
{
|
confirm = " 确认:" + confirm;
|
}
|
|
string moving = "";
|
MovingOps.ForEach(i =>
|
{
|
moving += i.GetDisplayText() + " ";
|
});
|
|
if (moving != "")
|
{
|
moving = " 运动:" + moving;
|
}
|
|
return (preCheck + output + confirm + moving).Trim();
|
}
|
}
|
|
public class MotionOperationCollection : OperationConfigBase, IComplexDisplay
|
{
|
[Category("运动配置")]
|
[DisplayName("运动配置集合")]
|
[Description("MovingOps:运动配置集合")]
|
[TypeConverter(typeof(CollectionCountConvert))]
|
[Editor(typeof(ComplexCollectionEditor<MovingOption>), typeof(UITypeEditor))]
|
public List<MovingOption> MovingOps { get; set; } = new List<MovingOption>();
|
|
public string GetDisplayText()
|
{
|
return $"{string.Join(" ", MovingOps.Select(u => u.GetDisplayText()))}";
|
}
|
}
|
|
//[Device("MotionCardOperationConfigCollection", "板卡操作配置基类集合", EnumHelper.DeviceAttributeType.OperationConfig)]
|
//public class MotionCardOperationConfigCollection : OperationConfigBase
|
//{
|
// [Category("复位操作")]
|
// [Description("板卡操作配置基类集合,依次执行")]
|
// [TypeConverter(typeof(CollectionCountConvert))]
|
// [Editor(typeof(ComplexCollectionEditor<MotionCardOperationConfigBase>), typeof(UITypeEditor))]
|
// public List<MotionCardOperationConfigBase> MotionCardOpsCollection { get; set; } = new List<MotionCardOperationConfigBase>();
|
//}
|
|
public class IORefrenceItemCollectionEditor : CollectionEditor
|
{
|
protected override CollectionForm CreateCollectionForm()
|
{
|
var form = base.CreateCollectionForm();
|
|
var prop = form.GetType().GetField("propertyBrowser", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
|
if (prop != null)
|
{
|
if (prop.GetValue(form) is PropertyGrid grid)
|
{
|
grid.HelpVisible = true;
|
grid.ToolbarVisible = false;
|
}
|
}
|
|
return form;
|
}
|
|
protected override object CreateInstance(Type itemType)
|
{
|
if (itemType == typeof(IORefrenceItem))
|
{
|
IORefrenceItem item = new IORefrenceItem();
|
if (this.Context.Instance is MotionCardOperationSet set)
|
{
|
using (var scope = GlobalVar.Container.BeginLifetimeScope())
|
{
|
List<IDevice> deviceList = scope.Resolve<List<IDevice>>();
|
|
var device = deviceList.FirstOrDefault(u => u.Id == set.MotionCardId);
|
|
if (device != null && (device is MotionCardBase motionCard))
|
{
|
item.IOItemSource = (motionCard.InitialConfig as MotionCardInitialConfigBase).IODefinitionCollection;
|
}
|
}
|
}
|
|
return item;
|
}
|
|
return base.CreateInstance(itemType);
|
}
|
|
//protected override object[] GetItems(object editValue)
|
//{
|
// return base.GetItems(editValue);
|
//}
|
|
//protected override object SetItems(object editValue, object[] value)
|
//{
|
// return base.SetItems(editValue, value);
|
//}
|
|
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
|
{
|
if (context.Instance is MotionCardOperationSet set)
|
{
|
if (string.IsNullOrWhiteSpace(set.MotionCardId))
|
{
|
return base.EditValue(context, provider, value);
|
}
|
|
using (var scope = GlobalVar.Container.BeginLifetimeScope())
|
{
|
List<IDevice> deviceList = scope.Resolve<List<IDevice>>();
|
|
var device = deviceList.FirstOrDefault(u => u.Id == set.MotionCardId);
|
|
if (device == null)
|
{
|
return base.EditValue(context, provider, value);
|
}
|
|
if (device is MotionCardBase motionCard)
|
{
|
if (value is List<IORefrenceItem> items)
|
{
|
items.ForEach(item =>
|
{
|
item.IOItemSource = (motionCard.InitialConfig as MotionCardInitialConfigBase).IODefinitionCollection;
|
});
|
}
|
}
|
}
|
}
|
|
return base.EditValue(context, provider, value);
|
}
|
|
public IORefrenceItemCollectionEditor(Type type) : base(type)
|
{
|
}
|
|
/// <summary>
|
/// 限制一次选一个实例
|
/// </summary>
|
/// <returns></returns>
|
protected override bool CanSelectMultipleInstances()
|
{
|
return false;
|
}
|
|
/// <summary>
|
/// 指定创建的对象类型
|
/// </summary>
|
/// <returns></returns>
|
protected override Type CreateCollectionItemType()
|
{
|
return typeof(IORefrenceItem);
|
}
|
|
protected override string GetDisplayText(object value)
|
{
|
if (value is IComplexDisplay)
|
{
|
return (value as IComplexDisplay).GetDisplayText();
|
}
|
|
return base.GetDisplayText(value);
|
}
|
|
//protected override void DestroyInstance(object instance)
|
//{
|
// base.DestroyInstance(instance);//重要!自动删除组件的设计时代码!
|
//}
|
}
|
|
public class MovingOpsCollectionEditor : ComplexCollectionEditor<MovingOption>
|
{
|
public MovingOpsCollectionEditor(Type type) : base(type)
|
{
|
}
|
|
MotionCardBase motionCard = null;
|
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
|
{
|
if (context.Instance is MotionCardOperationSet set)
|
{
|
if (!string.IsNullOrWhiteSpace(set.MotionCardId))
|
{
|
using (var scope = GlobalVar.Container.BeginLifetimeScope())
|
{
|
var deviceList = scope.Resolve<List<IDevice>>();
|
if (deviceList != null)
|
{
|
motionCard = deviceList.FirstOrDefault(u => u.Id == set.MotionCardId) as MotionCardBase;
|
}
|
}
|
}
|
|
if (motionCard != null && value is List<MovingOption> ops)
|
{
|
ops.ForEach(o => o.SetAxisSetting(motionCard.IConfig.AxisSettings));
|
}
|
}
|
|
return base.EditValue(context, provider, value);
|
}
|
|
protected override object SetItems(object editValue, object[] value)
|
{
|
Array.ForEach(value, v =>
|
{
|
if (v is MovingOption op && motionCard != null)
|
{
|
op.SetAxisSetting(motionCard.IConfig.AxisSettings);
|
}
|
});
|
|
return base.SetItems(editValue, value);
|
}
|
///// <summary>
|
///// 限制一次选一个实例
|
///// </summary>
|
///// <returns></returns>
|
//protected override bool CanSelectMultipleInstances()
|
//{
|
// return false;
|
//}
|
///// <summary>
|
///// 指定创建的对象类型
|
///// </summary>
|
///// <returns></returns>
|
//protected override Type CreateCollectionItemType()
|
//{
|
// return typeof(MovingOption);
|
//}
|
}
|
|
}
|