src/Bro.Device.AuboRobot/AuboRobotConfig.cs
@@ -1,7 +1,6 @@
using Bro.Common.Base;
using Bro.Common.Helper;
using Bro.Common.Model;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Design;
@@ -25,12 +24,20 @@
        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("IO监听设置")]
        [Description("IO监听操作配置集合")]
@@ -40,12 +47,54 @@
        [Category("IO监听设置")]
        [Description("IO监听间隔,以ms为单位")]
        public int ScanInterval { get; set; } = 100;
        public int ScanInterval { get; set; } = 9999;
        [Category("IO监听设置")]
        [Description("是否启用IO监听,true:监听 false:不监听")]
        public bool IsEnableMonitor { get; set; } = false;
        [Category("报警配置")]
        [Description("报警代码配置")]
        [TypeConverter(typeof(CollectionCountConvert))]
        [Editor(typeof(ComplexCollectionEditor<RobotWarningCode>), typeof(UITypeEditor))]
        public List<RobotWarningCode> RobotWarnings { get; set; } = new List<RobotWarningCode>();
    }
    public class RobotWarningCode
    {
        [Category("报警配置")]
        [Description("报警代码")]
        public int WarningCode { get; set; }
        [Category("报警配置")]
        [Description("报警代码描述")]
        public string WarningDescription { get; set; }
    }
    [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
@@ -56,16 +105,13 @@
        public RobotMsgAction Action { get; set; } = RobotMsgAction.Move;
        public RobotMsgParas Para1 { get; set; } = RobotMsgParas.None;
        public int Para1 { get; set; }
        public int Para2 { get; set; } = 0;
        /// <summary>
        /// Paras不包含Para1,Para2内容
        /// </summary>
        public List<string> Datas { get; set; } = new List<string>();
        public RobotPoint Point { get; set; } = new RobotPoint();
        public byte[] GetMsgBytes(string seperator, string endChar)
        public byte[] GetMsgBytes(string seperator, string endChar, out string msg)
        {
            List<string> list = new List<string>() { ((int)Type).ToString("D2"), ID.ToString("D2") };
@@ -73,34 +119,51 @@
            {
                list.Add(((int)Action).ToString("D2"));
                list.Add(((int)Para1).ToString("D2"));
                list.Add(Para1.ToString("D2"));
                list.Add(Para2.ToString("D2"));
                if (Datas == null)
                {
                    Datas = new List<string>();
                }
                while (Datas.Count < 5)
                {
                    Datas.Add("0");
                }
                list.AddRange(Datas.ConvertAll(s =>
                {
                    string res = float.Parse(s).ToString("F7");
                    while (res.Length < 11)
                    {
                        res = "0" + res;
                    }
                    return res;
                }));
                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));
            }
            string msg = string.Join(seperator, list);
            msg = string.Join(seperator, list) + seperator + endChar;
            return System.Text.Encoding.ASCII.GetBytes(msg + 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;
        }
        /// <summary>
        /// 将角度数值转换为11位字符串,输入角度区间0~360,输出角度区间-180~+180
        /// </summary>
        /// <param name="x"></param>
        /// <returns></returns>
        private string GetFormatString_Angle(float x)
        {
            if (x > 180)
            {
                x = x - 360;
            }
            return GetFormatString(x);
        }
        public static RobotMsg GetRobotMsg(string data, string seperator)
@@ -116,10 +179,22 @@
            {
                msg.Action = (RobotMsgAction)int.Parse(datas[2]);
                msg.Para1 = (RobotMsgParas)int.Parse(datas[3]);
                msg.Para1 = int.Parse(datas[3]);
                msg.Para2 = int.Parse(datas[4]);
                msg.Datas = datas.Skip(5).ToList();
                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;
@@ -127,7 +202,7 @@
        public string GetDisplayText()
        {
            string msg = $"序号:{ID},{Action.ToString()}_{Para1.ToString()}_{Para2.ToString()}_{(Datas.Count > 0 ? ("_" + string.Join(",", Datas)) : "")}";
            string msg = $"序号:{ID},{Action.ToString()}_{Para1.ToString()}_{Para2.ToString()}_{Point.GetDisplayText()}";
            return msg;
        }
    }
@@ -143,20 +218,62 @@
        Move = 1,
        Unload = 2,
        Load = 3,
        IO = 6,
        GetPosition = 4,
        /// <summary>
        /// 指定当前点位为基准点
        /// </summary>
        BasePoint = 5,
        IOSet = 6,
        IOQuery = 7,
        Calibration = 9,
        StandardPoint = 10,
    }
    public enum RobotMsgParas
    public enum MoveType
    {
        None = 0,
        Home = 1,
        LineSnap = 2,
        EmptyTray = 3,
        FullTray = 4,
        UnloadEmptyTraySnap = 5,
        LoadFullTraySnap = 6,
        Query = 7,
        [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,
    //}
}