using Bro.Common.Base; using Bro.Common.Helper; using Bro.Common.Model; using Bro.Common.Model.Interface; using System.Collections.Generic; using System.ComponentModel; using System.Drawing.Design; using System.Linq; namespace Bro.Device.AuboRobot { [Device("AuboRobot", "奥博机器人", EnumHelper.DeviceAttributeType.InitialConfig)] public class AuboRobotInitialConfig : InitialMonitorConfigBase { [Category("机器人设置")] [Description("机器人通信IP")] public string RobotIP { get; set; } = "0.0.0.0"; [Category("机器人设置")] [Description("机器人通信端口")] public int RobotPort { get; set; } [Category("通信设置")] [Description("反馈超时设置,单位ms")] public int ReplyTimeout { get; set; } = 1000; [Category("通信设置")] [Description("反馈超时重试次数")] public int TimeoutRetryTimes { get; set; } = 5; [Category("通信设置")] [Description("协议文本结束字符")] public string EndChar { get; set; } = "#"; [Category("通信设置")] [Description("协议内容分隔字符")] public string Seperator { get; set; } = ","; [Category("动作设置")] [Description("动作超时设置,单位min")] public float OperationTimeout { get; set; } = 1; [Category("通信报警配置")] [Description("通信过程中反馈报警代码配置")] [TypeConverter(typeof(CollectionCountConvert))] [Editor(typeof(ComplexCollectionEditor), typeof(UITypeEditor))] public List RobotReplyWarnings { get; set; } = new List(); } public class RobotReplyWarningCode : IComplexDisplay { [Category("反馈报警配置")] [Description("报警代码")] public int WarningCode { get; set; } [Category("反馈报警配置")] [Description("报警代码描述")] public string WarningDescription { get; set; } public string GetDisplayText() { return $"{WarningCode}-{WarningDescription}"; } } [Device("AuboRobot", "奥博机器人", EnumHelper.DeviceAttributeType.OperationConfig)] public class AuboRobotOperationConfig : OperationConfigBase { [Category("动作指令")] [Description("动作指令")] public RobotMsgAction Action { get; set; } = RobotMsgAction.Move; [Category("参数")] [Description("参数1")] public int Para1 { get; set; } = 0; [Category("参数")] [Description("参数2")] public int Para2 { get; set; } = 0; [Category("运动配置")] [Description("机器人运动点位")] [TypeConverter(typeof(ComplexObjectConvert))] [Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))] public RobotPoint Point { get; set; } = new RobotPoint(); [Category("操作配置")] [Description("是否等待完成信号")] public bool IsWaitFinished { get; set; } = true; } public class RobotMsg : IComplexDisplay { public RobotMsgType Type { get; set; } = RobotMsgType.Send; public int ID { get; set; } public RobotMsgAction Action { get; set; } = RobotMsgAction.Move; public int Para1 { get; set; } public int Para2 { get; set; } = 0; public RobotPoint Point { get; set; } = new RobotPoint(); public byte[] GetMsgBytes(string seperator, string endChar, out string msg) { List list = new List() { ((int)Type).ToString("D2"), ID.ToString("D2") }; if (Type == RobotMsgType.Send) { list.Add(((int)Action).ToString("D2")); list.Add(Para1.ToString("D2")); list.Add(Para2.ToString("D2")); list.Add(GetFormatString(Point.X)); list.Add(GetFormatString(Point.Y)); list.Add(GetFormatString(Point.Z)); list.Add(GetFormatString_Angle(Point.A)); list.Add(GetFormatString_Angle(Point.B)); list.Add(GetFormatString_Angle(Point.C)); } msg = string.Join(seperator, list) + seperator + endChar; return System.Text.Encoding.ASCII.GetBytes(msg); } private string GetFormatString(float x) { string s = x.ToString("f10"); s = s.TrimEnd(new char[] { '0' }); bool isNegative = x < 0; while (s.Length < 11) { s = s.Insert(isNegative ? 1 : 0, "0"); } return s; } /// /// 将角度数值转换为11位字符串,输入角度区间0~360,输出角度区间-180~+180 /// /// /// private string GetFormatString_Angle(float x) { if (x > 180) { x = x - 360; } return GetFormatString(x); } public static RobotMsg GetRobotMsg(string data, string seperator) { string[] datas = data.Split(new string[] { seperator }, System.StringSplitOptions.RemoveEmptyEntries); RobotMsg msg = new RobotMsg(); msg.Type = (RobotMsgType)int.Parse(datas[0]); msg.ID = int.Parse(datas[1]); if (msg.Type == RobotMsgType.Send) { msg.Action = (RobotMsgAction)int.Parse(datas[2]); msg.Para1 = int.Parse(datas[3]); msg.Para2 = int.Parse(datas[4]); msg.Point = new RobotPoint() { X = float.Parse(datas[5]), Y = float.Parse(datas[6]), Z = float.Parse(datas[7]), A = float.Parse(datas[8]) < 0 ? float.Parse(datas[8]) + 360 : float.Parse(datas[8]), B = float.Parse(datas[9]) < 0 ? float.Parse(datas[9]) + 360 : float.Parse(datas[9]), C = float.Parse(datas[10]) < 0 ? float.Parse(datas[10]) + 360 : float.Parse(datas[10]), }; } else { msg.Para1 = int.Parse(datas[2]); } return msg; } public string GetDisplayText() { string msg = $"序号:{ID},{Action.ToString()}_{Para1.ToString()}_{Para2.ToString()}_{Point.GetDisplayText()}"; return msg; } } public enum RobotMsgType { Send = 1, Rec = 2, } public enum RobotMsgAction { Move = 1, Unload = 2, Load = 3, GetPosition = 4, /// /// 指定当前点位为基准点 /// BasePoint = 5, IOSet = 6, IOQuery = 7, Calibration = 9, StandardPoint = 10, } public enum MoveType { [Description("绝对运动")] AbsoluteMove = 1, [Description("机器人坐标系相对运动")] RobotRelativeMove = 2, [Description("相对某个基准点位的相对运动")] BasedPointRelativeMove = 3, [Description("回原点")] Origin = 4, [Description("左侧姿势")] LeftPose = 6, [Description("右侧姿势")] RightPose = 5, [Description("前侧姿势")] FrontPose = 7, [Description("相机坐标系相对运动")] CameraRelativeMove = 12, } public enum TrayType { FullTray = 1, EmptyTray = 2, } //public enum RobotMsgAction //{ // Move = 1, // Unload = 2, // Load = 3, // IO = 6, // Calibration = 9, // StandardPoint = 10, //} //public enum RobotMsgParas //{ // None = 0, // Home = 1, // LineSnap = 2, // EmptyTray = 3, // FullTray = 4, // UnloadEmptyTraySnap = 5, // LoadFullTraySnap = 6, // Query = 7, //} }