src/Bro.Common.Device/DeviceBase/MotionCardBase.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/Bro.Common.Model/Helper/StaticHelper.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/Bro.Common.Model/Model/MotionCardRelated.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/Bro.Device.GTSCard/GTSCardDriver.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/Bro.Common.Device/DeviceBase/MotionCardBase.cs
@@ -147,6 +147,7 @@ } } [Device("MotionOperationSet", "运动操作配置基类", EnumHelper.DeviceAttributeType.OperationConfig)] public class MotionCardOperationSet : IComplexDisplay { [Category("IO操作配置")] @@ -177,16 +178,19 @@ [DisplayName("IO确认超时")] public int IOConfirmTimeout { get; set; } = 0; //[Category("板卡运动配置")] //[DisplayName("运动配置集合")] //[Description("MovingOps:运动配置集合")] //[TypeConverter(typeof(CollectionCountConvert))] //[Editor(typeof(ComplexCollectionEditor<MovingOption>), typeof(UITypeEditor))] //public List<MovingOption> MovingOps { get; set; } = new List<MovingOption>(); [Category("板卡运动配置")] [DisplayName("运动配置集合")] [Description("MovingOps:运动配置集合")] [TypeConverter(typeof(CollectionCountConvert))] [Editor(typeof(ComplexCollectionEditor<MovingOption>), typeof(UITypeEditor))] public List<MovingOption> MovingOps { get; set; } = new List<MovingOption>(); [Category("板卡运动配置")] [Description("超时设置,单位:ms")] [DisplayName("运动超时")] public int MovingTimeout { get; set; } = 0; [TypeConverter(typeof(ComplexObjectConvert))] [Editor(typeof(PropertyObjectEditor),typeof(UITypeEditor))] public MotionOperationCollection MotionOperationCollection { get; set; } = new MotionOperationCollection(); public string GetDisplayText() { @@ -220,19 +224,34 @@ } string moving = ""; MovingOps.ForEach(i => { moving += i.GetDisplayText() + " "; }); if (moving != "") { moving = " 运动:" + 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 //{ src/Bro.Common.Model/Helper/StaticHelper.cs
@@ -250,5 +250,23 @@ collection.Move(collection.IndexOf(sortedList[i]), i); } } // 布尔类型转换为整型 public static int ToInt(this object obj) { if (Convert.ToBoolean(obj) == true) return 1; else return 0; } // 整型转换为布尔类型 public static bool ToBool(this object obj) { if (Convert.ToInt32(obj) == 1) return true; else return false; } } } src/Bro.Common.Model/Model/MotionCardRelated.cs
@@ -35,66 +35,66 @@ [Category("换算配置")] [DisplayName("脉冲数换算比例")] [Description("脉冲数和其他计量单位的换算比例,例如设置为1000,表示1000个脉冲等于1uint")] public int PulseRatio { get; set; } = 1; 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("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("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("IsHomePositive:回原点方向。 true:正方向开始 false:负方向开始")] //public bool IsHomePositive { get; set; } = true; [Category("回原点设置")] [DisplayName("是否自动回原点")] [Description("IsAutoGoHome:是否自动回原点。 true:是 false:否")] public bool IsAutoGoHome { get; set; } = false; //[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("TimeOutHome:回原点超时,单位毫秒")] //public int TimeOutHome { get; set; } = 30000; [Category("超时设置")] [DisplayName("运动超时")] [Description("TimeOutMove:运动超时,单位毫秒")] public int TimeOutMove { get; set; } = 10000; //[Category("超时设置")] //[DisplayName("运动超时")] //[Description("TimeOutMove:运动超时,单位毫秒")] //public int TimeOutMove { get; set; } = 10000; [Category("开闭环设置")] [DisplayName("是否使用Cmmd回馈")] [Description("IsUseCmmdPosition:是否使用Cmmd回馈")] public bool IsUseCmmdPosition { get; set; } = false; //[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("IsUseMDNStopSignal:是否使用板卡反馈停止信号")] //public bool IsUseMDNStopSignal { get; set; } = false; [Category("开闭环设置")] [DisplayName("是否启用报警")] [Description("IsUseWarning:是否启用报警")] public bool IsUseWarning { 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("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>(); //[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() { @@ -305,6 +305,11 @@ } } [Category("板卡运动配置")] [Description("超时设置,单位:ms")] [DisplayName("运动超时")] public int MovingTimeout { get; set; } = 0; internal List<AxisSetting> _axisSettingList = new List<AxisSetting>(); public void SetAxisSetting(List<AxisSetting> settings) { src/Bro.Device.GTSCard/GTSCardDriver.cs
@@ -75,10 +75,111 @@ AllAxisOff(); } /// <summary> /// 设备 运行(执行 板卡系列的操作的 集合) /// </summary> /// <param name="config"></param> /// <returns></returns> public override ResponseMessage Run(IOperationConfig config) { ResponseMessage responseMessage = new ResponseMessage(); var motionCardOperationConfig = config as MotionCardOperationConfigBase; foreach (var operationSet in motionCardOperationConfig.OperationCollection) { responseMessage = RunOperationSet(operationSet); if (!responseMessage.Result) { return responseMessage; } } return responseMessage; } /// <summary> /// 执行 一个系列的操作 /// </summary> private ResponseMessage RunOperationSet(MotionCardOperationSet operationSet) { ResponseMessage responseMessage = new ResponseMessage(); // 1.预检查 if (CurrentState == DeviceState.DSOpen) { foreach (var preCheck in operationSet.PreCheckIOCollection) { int timeout = operationSet.PreCheckIOTimeout; IOValue? ioData = null; while (CurrentState == DeviceState.DSOpen) { Thread.Sleep(10); ioData = MonitorValues.FirstOrDefault(u => u.IONum == preCheck.IOItem.IONum && u.IOType == preCheck.IOItem.IOType)?.Value;//IO 是开、关 从MonitorValues 获取 timeout -= 10; if (preCheck.CheckValue == ioData || (operationSet.PreCheckIOTimeout > 0 && timeout < 0)) { break; } } if (preCheck.CheckValue != ioData) { responseMessage.Result = false; responseMessage.Message = $"预检查不通过,配置:{preCheck.GetDisplayText()},当前值:{ioData}"; return responseMessage; } } } // 2.板卡运动 if (CurrentState == DeviceState.DSOpen) { responseMessage = MoveToPoint(operationSet.MotionOperationCollection); if (!responseMessage.Result) { return responseMessage; } } // 3.IO输出 不需要超时 if (CurrentState == DeviceState.DSOpen) { foreach (var ioOutput in operationSet.IOOutputCollection) { var ioData = MonitorValues.FirstOrDefault(u => u.IONum == ioOutput.IOItem.IONum && u.IOType == ioOutput.IOItem.IOType)?.Value;//IO 是开、关 从MonitorValues 获取 if (ioOutput.CheckValue != ioData) { responseMessage.Result = false; responseMessage.Message = $"IO输出不通过,配置:{ioOutput.GetDisplayText()},当前值:{ioData}"; return responseMessage; } } } // 4.IO确认 if (CurrentState == DeviceState.DSOpen) { foreach (var ioConfirm in operationSet.IOConfirmCollection) { int timeout = operationSet.IOConfirmTimeout; IOValue? ioData = null; while (CurrentState == DeviceState.DSOpen) { Thread.Sleep(10); ioData = MonitorValues.FirstOrDefault(u => u.IONum == ioConfirm.IOItem.IONum && u.IOType == ioConfirm.IOItem.IOType)?.Value;//IO 是开、关 从MonitorValues 获取 timeout -= 10; if (ioConfirm.CheckValue == ioData || (operationSet.IOConfirmTimeout > 0 && timeout < 0)) { break; } } if (ioConfirm.CheckValue != ioData) { responseMessage.Result = false; responseMessage.Message = $"IO确认不通过,配置:{ioConfirm.GetDisplayText()},当前值:{ioData}"; return responseMessage; } } } return responseMessage; } @@ -164,25 +265,22 @@ /// <returns>运动控制+停止判断</returns> public override ResponseMessage MoveToPoint(IOperationConfig opConfig) { //bool resultOK = false; //var gtsOperationConfig = opConfig as GTSCardOperationConfig; //List<Task<bool>> taskList = new List<Task<bool>>(); ////TaskFactory factory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.None); //// 如果是多个轴的运动 等每个轴运动结束 //foreach (var movingOp in gtsOperationConfig.MovingOps) //{ // //var task = factory.StartNew<bool>((op) => // //{ // // return SingleAxisMoving(op as MovingOption); // //}, movingOp); // var task = SingleAxisMoving(movingOp); // taskList.Add(task); //} //Task.WaitAll(taskList.ToArray()); //resultOK = taskList.All(u => u.GetAwaiter().GetResult()); ResponseMessage responseMessage = new ResponseMessage(); var gtsOperationCollection = opConfig as MotionOperationCollection; List<Task<bool>> taskList = new List<Task<bool>>(); foreach (var movingOp in gtsOperationCollection.MovingOps) { var task = SingleAxisMoving(movingOp); taskList.Add(task); } //return resultOK; throw new NotImplementedException(); Task.WaitAll(taskList.ToArray()); responseMessage.Result = taskList.All(u => u.GetAwaiter().GetResult()); if (!responseMessage.Result) { responseMessage.Message = $"点位运动异常"; } return responseMessage; } /// <summary> @@ -220,12 +318,14 @@ return await Task.Run(() => { bool isSuccessAndStop = false; try { if (IConfig.AxisSettings.FirstOrDefault(a => a.AxisIndex == optionPara.AxisIndex)?.IsAxisEnabled ?? false) { string _position = ""; string motionType = optionPara.MoveMode == EnumHelper.MotorMoveMode.Normal ? (optionPara.IsAbsolute ? "Abs" : "Rel") : optionPara.MoveMode.ToString(); _position = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")},{optionPara.AxisIndex},{motionType},{GetPosition(optionPara.AxisIndex).ToString()},{GetPrfPosition(optionPara.AxisIndex).ToString()},{optionPara.Destination},"; _position = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff},{optionPara.AxisIndex},{motionType},{GetPosition(optionPara.AxisIndex)},{GetPrfPosition(optionPara.AxisIndex)},{optionPara.Destination},"; switch (optionPara.MoveMode) { @@ -262,6 +362,12 @@ _position += $"{GetPosition(optionPara.AxisIndex)},"; _position += $"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}"; LogAsync(DateTime.Now, "", _position); } } catch (Exception ex) { isSuccessAndStop = false; LogAsync(DateTime.Now, $"轴{optionPara.AxisIndex}运动异常", ex.GetExceptionMessage()); } return isSuccessAndStop; }); @@ -332,7 +438,7 @@ if (ret != (short)GTSRetCode.GRCRunOK) { LogAsync(DateTime.Now, "轴" + optionPara.AxisIndex + "APS_absolute_move异常", "错误码:" + ret + ";" + "重试次数:" + repeatTime); Thread.Sleep(50); Thread.Sleep(10); } repeatTime--; } while (ret != (short)GTSRetCode.GRCRunOK && repeatTime > 0); @@ -406,11 +512,11 @@ LogAsync(DateTime.Now, "轴" + optionPara.AxisIndex + "开始运动", "目标坐标:" + optionPara.Destination); short ret = 0; repeatTime = 100; bool isSuccessSetAxisParam = false; int currentPosition = (int)GetPosition(optionPara.AxisIndex); int dPosition = optionPara.Destination + currentPosition; do int timeout = optionPara.MovingTimeout; while (CurrentState == DeviceState.DSOpen) { //设置 运动参数 isSuccessSetAxisParam = SetAxisParam(optionPara); @@ -422,8 +528,12 @@ LogAsync(DateTime.Now, "轴" + optionPara.AxisIndex + "APS_absolute_move异常", "错误码:" + ret + ";" + "重试次数:" + repeatTime); Thread.Sleep(50); } repeatTime--; } while (ret != (short)GTSRetCode.GRCRunOK && !isSuccessSetAxisParam && repeatTime > 0); timeout -= 50; if ((ret == (short)GTSRetCode.GRCRunOK && isSuccessSetAxisParam) || (optionPara.MovingTimeout > 0 && timeout < 0)) { break; } } //运动开始后 检查运动是否停止 bool isStop = false; @@ -477,9 +587,9 @@ } LogAsync(DateTime.Now, "轴" + optionPara.AxisIndex + "开始运动", "目标坐标:" + optionPara.Destination); short ret = 0; repeatTime = 100; bool isSuccessSetAxisParam = false; do int timeout = optionPara.MovingTimeout; while (CurrentState == DeviceState.DSOpen) { //设置 运动参数 isSuccessSetAxisParam = SetAxisParam(optionPara); @@ -491,8 +601,12 @@ LogAsync(DateTime.Now, "轴" + optionPara.AxisIndex + "APS_absolute_move异常", "错误码:" + ret + ";" + "重试次数:" + repeatTime); Thread.Sleep(50); } repeatTime--; } while (ret != (short)GTSRetCode.GRCRunOK && !isSuccessSetAxisParam && repeatTime > 0); timeout -= 50; if ((ret == (short)GTSRetCode.GRCRunOK && isSuccessSetAxisParam) || (optionPara.MovingTimeout > 0 && timeout < 0)) { break; } } bool isStop = false; repeatTime = 1000; @@ -637,14 +751,13 @@ /// <summary> /// 读取IO输出 /// </summary> /// <param name="cardNum"></param> /// <param name="index"></param> /// <param name="index">io索引</param> /// <returns></returns> public bool GetDoSts(short cardNum, short index) public bool GetDoSts(short index) { int outSts; short outNum = (short)(index % 100); GTSCardAPI.GT_GetDo(cardNum, GTSCardAPI.MC_GPO, out outSts); GTSCardAPI.GT_GetDo((short)IConfig.CardNum, GTSCardAPI.MC_GPO, out outSts); if ((outSts & (1 << outNum)) == 0) return true; else return false; } @@ -652,7 +765,6 @@ /// <summary> /// 按位设置数字 IO 输出状态 /// </summary> /// <param name="cardNum">卡号</param> /// <param name="index">输出口,返回1-16</param> /// <param name="value">false表示输出,true表示关闭</param> public override void WriteOutput(short cardNum, short index, IOValue value)