src/Bro.Device.AuboRobot/AuboRobotConfig.cs
@@ -1,8 +1,10 @@
using Bro.Common.Base;
using Bro.Common.Helper;
using System;
using Bro.Common.Model;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Design;
using System.Linq;
namespace Bro.Device.AuboRobot
{
@@ -22,17 +24,77 @@
        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监听操作配置集合")]
        [TypeConverter(typeof(CollectionCountConvert))]
        [Editor(typeof(ComplexCollectionEditor<MonitorSet>), typeof(UITypeEditor))]
        public List<MonitorSet> MonitorSetCollection { get; set; } = new List<MonitorSet>();
        [Category("IO监听设置")]
        [Description("IO监听间隔,以ms为单位")]
        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
@@ -43,29 +105,65 @@
        public RobotMsgAction Action { get; set; } = RobotMsgAction.Move;
        public RobotMsgParas Para1 { get; set; } = RobotMsgParas.None;
        public int Para1 { get; set; }
        public List<string> Paras { get; set; } = new List<string>();
        public int Para2 { get; set; } = 0;
        public byte[] GetMsgBytes(string seperator, string endChar)
        public RobotPoint Point { get; set; } = new RobotPoint();
        public byte[] GetMsgBytes(string seperator, string endChar, out string msg)
        {
            List<string> list = new List<string>() { Type.ToString(), ID.ToString() };
            List<string> list = new List<string>() { ((int)Type).ToString("D2"), ID.ToString("D2") };
            if (Type == RobotMsgType.Send)
            {
                list.Add(Action.ToString());
                list.Add(((int)Action).ToString("D2"));
                if (Para1 != RobotMsgParas.None)
                {
                    list.Add(Para1.ToString());
                }
                list.Add(Para1.ToString("D2"));
                list.Add(Para2.ToString("D2"));
                list.AddRange(Paras);
                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)
@@ -74,31 +172,29 @@
            RobotMsg msg = new RobotMsg();
            msg.Type = (RobotMsgType)Enum.Parse(typeof(RobotMsgType), datas[0]);
            msg.Type = (RobotMsgType)int.Parse(datas[0]);
            msg.ID = int.Parse(datas[1]);
            if (msg.Type == RobotMsgType.Send)
            {
                msg.Action = (RobotMsgAction)Enum.Parse(typeof(RobotMsgAction), datas[2]);
                msg.Action = (RobotMsgAction)int.Parse(datas[2]);
                if (int.TryParse(datas[3], out int para1))
                msg.Para1 = int.Parse(datas[3]);
                msg.Para2 = int.Parse(datas[4]);
                msg.Point = new RobotPoint()
                {
                    msg.Para1 = RobotMsgParas.None;
                    for (int i = 3; i < datas.Length; i++)
                    {
                        msg.Paras.Add(datas[i]);
                    }
                }
                else
                {
                    msg.Para1 = (RobotMsgParas)Enum.Parse(typeof(RobotMsgParas), datas[3]);
                    for (int i = 4; i < datas.Length; i++)
                    {
                        msg.Paras.Add(datas[i]);
                    }
                }
                    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;
@@ -106,38 +202,78 @@
        public string GetDisplayText()
        {
            string msg = $"序号:{ID},{Action.ToString()}_{Para1.ToString()}{(Paras.Count > 0 ? ("_" + string.Join(",", Paras)) : "")}";
            string msg = $"序号:{ID},{Action.ToString()}_{Para1.ToString()}_{Para2.ToString()}_{Point.GetDisplayText()}";
            return msg;
        }
    }
    public enum RobotMsgType
    {
        Send,
        Rec
        Send = 1,
        Rec = 2,
    }
    public enum RobotMsgAction
    {
        Move,
        State,
        Adjust,
        IO,
        Move = 1,
        Unload = 2,
        Load = 3,
        GetPosition = 4,
        /// <summary>
        /// 指定当前点位为基准点
        /// </summary>
        BasePoint = 5,
        IOSet = 6,
        IOQuery = 7,
        Calibration = 9,
        StandardPoint = 10,
    }
    public enum RobotMsgParas
    public enum MoveType
    {
        None,
        LineSnap,
        Line,
        Robot,
        LoadEmptyTraySnap,
        LoadEmptyTrayDone,
        LoadFullTraySnap,
        LoadFullTrayDone,
        EmptyTrayReady,
        EmptyTrayEmpty,
        FullTrayFull,
        Query,
        [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,
    //}
}