BoxEquip_AutoFindPos.cs 17.3 KB
using CodeLibrary;
using HuichuanLibrary;
using OnlineStore.Common;
using OnlineStore.LoadCSVLibrary;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using static eyemLib_Sharp.EyemLibDemo;

namespace OnlineStore.DeviceLibrary
{
    public partial class BoxEquip
    {
        //public Dictionary<string, List<DrawerInfo>> DrawerNums = new Dictionary<string, List<DrawerInfo>>();
        public AutoFindPos autoFindPos;
        public bool autoFindPosMode = false;
        private void InitDrawInfos()
        {
            autoFindPos = new AutoFindPos(Config);
            //DrawerNums.Add("A", new List<DrawerInfo>());
            //DrawerNums.Add("B", new List<DrawerInfo>());
            //List<DrawerPosition> drawerPositions = CSVPositionReader<DrawerPosition>.getPositionList();

            //foreach (DrawerPosition position in drawerPositions)
            //{
            //    if (position.StoreId.Equals(DeviceID))
            //    {

            //        DrawerNums[PosSide(position.PositionNum)].Add(new DrawerInfo(position.PositionNum,PositionNumList));
            //    }
            //}
        }
        /// <summary>
        /// 获取抽屉/仓位所在面
        /// </summary>
        /// <param name="pos">位置</param>
        /// <returns></returns>
        private string PosSide(string pos)
        {
            if (pos.Substring(2, 2).Equals("AA")) return "A";
            else if (pos.Substring(2, 2).Equals("BB")) return "B";
            return "";
        }
        /// <summary>
        /// 获取轴的负限位
        /// </summary>
        /// <param name="axisNo"></param>
        /// <returns></returns>

        public bool GetAxisNelSts(short axisNo)
        {
            AxisSts sts = HCBoardManager.GetAxisSts(axisNo);
            return sts.NEL == 1;
        }
        /// <summary>
        /// 获取轴的正限位
        /// </summary>
        /// <param name="axisNo"></param>
        /// <returns></returns>

        public bool GetAxisPelSts(short axisNo)
        {
            AxisSts sts = HCBoardManager.GetAxisSts(axisNo);
            return sts.PEL == 1;
        }
        private void ToDrawer_StartPoint()
        {
            MoveAxis.AbsMove(MoveInfo, autoFindPos.CurRow * autoFindPos.Row_Spacing, Config.MoveAxis_P1_Speed);
            UpdownAxis.AbsMove(MoveInfo, autoFindPos.CurColumn * autoFindPos.Column_Spacing, Config.Updown_P1_Speed);
        }


        private bool CheckMarkXPoint(EyemOcsFXYR eyemOcsFXYR)
        {
            if (Math.Abs(Config.Drawer_X - eyemOcsFXYR.fX) < Config.Drawer_X_Error)
                return true;
            LogInfo($"存储机构-视觉对位 {MoveInfo.SLog}:Mark点X轴坐标{eyemOcsFXYR.fX},模板Mark点X轴坐标{Config.Drawer_X},X轴偏差{(Config.Drawer_X - eyemOcsFXYR.fX)}," +
                $"行走机构相对移动{(Config.Drawer_X - eyemOcsFXYR.fX) * autoFindPos.XCoeffOfCoorToPulse}[{MoveInfo.MoveParam.PosInfo.PosSide}面]");
            MoveAxis.AbsMove(MoveInfo, Convert.ToInt32(MoveAxis.GetAclPosition() + (Config.Drawer_X - eyemOcsFXYR.fX) * autoFindPos.XCoeffOfCoorToPulse), Config.MoveAxis_P1_Speed / 2);
            return false;
        }
        private bool CheckMarkYPoint(EyemOcsFXYR eyemOcsFXYR)
        {
            if (Math.Abs(Config.Drawer_Y - eyemOcsFXYR.fY) < Config.Drawer_Y_Error)
                return true;
            UpdownAxis.AbsMove(MoveInfo, Convert.ToInt32(UpdownAxis.GetAclPosition() + (Config.Drawer_Y - eyemOcsFXYR.fY) * autoFindPos.YCoeffOfCoorToPulse), Config.Updown_P1_Speed / 2);
            LogInfo($"存储机构-视觉对位 {MoveInfo.SLog}:Mark点Y轴坐标{eyemOcsFXYR.fY},模板Mark点Y轴坐标{Config.Drawer_Y},Y轴偏差{(Config.Drawer_Y - eyemOcsFXYR.fY)}," +
     $"移栽升降轴相对移动{(Config.Drawer_Y - eyemOcsFXYR.fY) * autoFindPos.YCoeffOfCoorToPulse}[{MoveInfo.MoveParam.PosInfo.PosSide}面]");
            return false;
        }

        public void StartFindPos(InOutParam param)
        {
            if (isInSuddenDown || isNoAirpressure_Check ||
                (!runStatus.Equals(RunStatus.Runing))
                   || (!MoveInfo.MoveType.Equals(MoveType.None)))
            {
                LogUtil.error(Name + " 启动视觉对位出错,忙碌或报警中 ,storeStatus=" + runStatus + ",MoveType=" + MoveInfo.MoveType + ",isInSuddenDown=" + isInSuddenDown + ",isNoAirpressure_Check=" + isNoAirpressure_Check);
                return;
            }
            LogInfo(" 启动视觉对位【" + param.PosInfo.ToStr() + "】 ");
            MoveInfo.NewMove(MoveType.Working, param);
            SetBoxStatus(DeviceStatus.Debugging, RunStatus.Busy);
            MoveInfo.NextMoveStep(StepEnum.SA_01_Pos_Start_Find_Pos);
        }
        private bool SaveDrawerPosition()
        {
            StringBuilder stringBuilder = new StringBuilder(MoveInfo.MoveParam.PosInfo.PosId);
            stringBuilder.Append(autoFindPos.CurRow.ToString().PadLeft(2, '0'));
            stringBuilder.Append(autoFindPos.CurColumn.ToString().PadLeft(2, '0'));
            List<string> curDrawer = PositionNumList.FindAll(s => s.StartsWith(stringBuilder.ToString()));
            if (curDrawer != null && curDrawer.Count > 0)
            {
                foreach (string item in curDrawer)
                {
                    BoxPosition ktkPosition = CSVPositionReader<BoxPosition>.GetPositon(item);
                    if (ktkPosition != null)
                    {
                        ktkPosition.MoveAxis_P3 = MoveAxis.GetAclPosition();
                        ktkPosition.Updown_P7_P13 = UpdownAxis.GetAclPosition();

                    }
                    //位置配置
                    string appPath = Application.StartupPath;
                    //如果总配置文件存在,保存到总的配置文件
                    string positionConfigFile = appPath + ConfigAppSettings.GetValue(Setting_Init.ConfigPath_BoxPosition);
                    if (!File.Exists(positionConfigFile))
                    {
                        string nameStr = DeviceID.ToString();
                        positionConfigFile = positionConfigFile.Replace(".csv", "_" + nameStr + ".csv");
                    }
                    bool result = CSVPositionReader<BoxPosition>.SavePostion(positionConfigFile, ktkPosition);
                    if (!result)
                    {
                        SetWarnMsg("库位【" + item + "】保存失败!");
                    }
                    else
                    {

                        LogInfo($"存储机构-视觉对位 {MoveInfo.SLog}:库位[{item}]保存成功[{MoveInfo.MoveParam.PosInfo.PosSide}面]");
                    }
                    return result;
                }
            }
            return false;
        }

        public void FindPosEnd()
        {
            MoveInfo.EndMove();
            if (MoveInfo.MoveParam != null)
                LogInfo($"存储机构-视觉对位 {MoveInfo.SLog}:对位结束[{MoveInfo.MoveParam.PosInfo.PosSide}面]");
        }
        EyemOcsFXYR ocsFXYR;
        public void AutoFindPosProcess()
        {
            if (MoveInfo.IsInWait)
            {
                CheckWait(MoveInfo);
            }
            if (MoveInfo.IsInWait)
            {
                return;
            }
            if (!autoFindPosMode)
                return;
            switch (MoveInfo.MoveStep)
            {
                case StepEnum.SA_01_Pos_Start_Find_Pos:
                    MoveInfo.NextMoveStep(StepEnum.SA_02_Pos_To_Drawer_StartPoint);
                    LogInfo($"存储机构-视觉对位 {MoveInfo.SLog}:到抽屉起始点," +
                        $"行走机构到抽屉起始点,移栽升降轴到抽屉起始点[{MoveInfo.MoveParam.PosInfo.PosSide}面]");
                    ToDrawer_StartPoint();
                    break;
                case StepEnum.SA_02_Pos_To_Drawer_StartPoint:
                    //取图
                    Bitmap bitmap = null;
                    int res = AutoFindPos.GetMarkInfo(bitmap, out ocsFXYR);
                    if (res == 0)
                    {
                        MoveInfo.NextMoveStep(StepEnum.SA_03_Pos_AcqImg);
                        LogInfo($"存储机构-视觉对位 {MoveInfo.SLog}:取图[{MoveInfo.MoveParam.PosInfo.PosSide}面]");
                    }
                    else if (res == -4)
                    {
                        SetWarnMsg($"存储机构-视觉对位异常[code={res}],未找到Mark点。对位失败的行={autoFindPos.CurRow}[{MoveAxis.GetAclPosition()}],列={autoFindPos.CurColumn}[{UpdownAxis.GetAclPosition()}]");
                        autoFindPos.FailedDrawers.Add($"{autoFindPos.CurRow},{autoFindPos.CurColumn}");
                        MoveInfo.NextMoveStep(StepEnum.SA_05_Pos_NextDrawer);
                    }
                    else
                    {
                        SetWarnMsg($"存储机构-视觉对位异常[code={res}],未找到Mark点。对位失败的行={autoFindPos.CurRow}[{MoveAxis.GetAclPosition()}],列={autoFindPos.CurColumn}[{UpdownAxis.GetAclPosition()}]");
                        autoFindPos.FailedDrawers.Add($"{autoFindPos.CurRow},{autoFindPos.CurColumn}");
                        MoveInfo.NextMoveStep(StepEnum.SA_05_Pos_NextDrawer);
                    }
                    break;
                case StepEnum.SA_03_Pos_AcqImg:
                    if (CheckMarkXPoint(ocsFXYR) && CheckMarkYPoint(ocsFXYR))
                    {
                        //存储抽屉位置信息
                        if (SaveDrawerPosition())
                        {

                        }
                        else
                        {
                            autoFindPos.FailedDrawers.Add($"{autoFindPos.CurRow},{autoFindPos.CurColumn}");
                        }
                        MoveInfo.NextMoveStep(StepEnum.SA_05_Pos_NextDrawer);
                    }
                    else
                    {
                        MoveInfo.NextMoveStep(StepEnum.SA_04_Pos_AdjPos);
                    }
                    break;
                case StepEnum.SA_04_Pos_AdjPos:
                    MoveInfo.NextMoveStep(StepEnum.SA_02_Pos_To_Drawer_StartPoint);
                    break;
                case StepEnum.SA_05_Pos_NextDrawer:
                    if (autoFindPos.CurColumn < autoFindPos.Columns)
                    {
                        MoveInfo.NextMoveStep(StepEnum.SA_01_Pos_Start_Find_Pos);
                        autoFindPos.CurColumn++;
                    }
                    else
                    {
                        if (autoFindPos.CurRow < autoFindPos.Rows)
                        {
                            MoveInfo.NextMoveStep(StepEnum.SA_06_Neg_Start_Find_Pos);
                            autoFindPos.CurRow++;
                        }
                        else//结束
                        {
                            FindPosEnd();
                        }
                    }
                    break;
                case StepEnum.SA_06_Neg_Start_Find_Pos:
                    MoveInfo.NextMoveStep(StepEnum.SA_07_Neg_To_Drawer_StartPoint);
                    LogInfo($"存储机构-视觉对位 {MoveInfo.SLog}:到抽屉起始点," +
                        $"行走机构到抽屉起始点,移栽升降轴到抽屉起始点[{MoveInfo.MoveParam.PosInfo.PosSide}面]");
                    ToDrawer_StartPoint();
                    break;

                case StepEnum.SA_07_Neg_To_Drawer_StartPoint:
                    //取图
                    Bitmap bitmap1 = null;
                    int res1 = AutoFindPos.GetMarkInfo(bitmap1, out ocsFXYR);
                    if (res1 == 0)
                    {
                        MoveInfo.NextMoveStep(StepEnum.SA_08_Neg_AcqImg);
                        LogInfo($"存储机构-视觉对位 {MoveInfo.SLog}:取图[{MoveInfo.MoveParam.PosInfo.PosSide}面]");
                    }
                    else if (res1 == -4)
                    {
                        SetWarnMsg($"存储机构-视觉对位异常[code={res1}],未找到Mark点。对位失败的行={autoFindPos.CurRow}[{MoveAxis.GetAclPosition()}],列={autoFindPos.CurColumn}[{UpdownAxis.GetAclPosition()}]");
                        autoFindPos.FailedDrawers.Add($"{autoFindPos.CurRow},{autoFindPos.CurColumn}");
                        MoveInfo.NextMoveStep(StepEnum.SA_10_Neg_NextDrawer);
                    }
                    else
                    {
                        SetWarnMsg($"存储机构-视觉对位异常[code={res1}],未找到Mark点。对位失败的行={autoFindPos.CurRow}[{MoveAxis.GetAclPosition()}],列={autoFindPos.CurColumn}[{UpdownAxis.GetAclPosition()}]");
                        autoFindPos.FailedDrawers.Add($"{autoFindPos.CurRow},{autoFindPos.CurColumn}");
                        MoveInfo.NextMoveStep(StepEnum.SA_10_Neg_NextDrawer);
                    }
                    break;
                case StepEnum.SA_08_Neg_AcqImg:
                    if (CheckMarkXPoint(ocsFXYR) && CheckMarkYPoint(ocsFXYR))
                    {
                        //存储抽屉位置信息
                        if (SaveDrawerPosition())
                        {

                        }
                        else
                        {
                            autoFindPos.FailedDrawers.Add($"{autoFindPos.CurRow},{autoFindPos.CurColumn}");
                        }
                        MoveInfo.NextMoveStep(StepEnum.SA_10_Neg_NextDrawer);
                    }
                    else
                    {
                        MoveInfo.NextMoveStep(StepEnum.SA_09_Neg_AdjPos);
                    }
                    break;
                case StepEnum.SA_09_Neg_AdjPos:
                    MoveInfo.NextMoveStep(StepEnum.SA_07_Neg_To_Drawer_StartPoint);
                    break;
                case StepEnum.SA_10_Neg_NextDrawer:
                    if (autoFindPos.CurColumn > 1)
                    {
                        MoveInfo.NextMoveStep(StepEnum.SA_06_Neg_Start_Find_Pos);
                        autoFindPos.CurColumn--;
                    }
                    else
                    {
                        if (autoFindPos.CurRow < autoFindPos.Rows)
                        {
                            MoveInfo.NextMoveStep(StepEnum.SA_01_Pos_Start_Find_Pos);
                            autoFindPos.CurRow++;
                        }
                        else//结束
                        {
                            FindPosEnd();
                        }
                    }
                    break;
            }
        }
    }

    public class AutoFindPos
    {
        /// <summary>
        /// 当前行
        /// </summary>
        public int CurRow { get; set; } = 1;
        /// <summary>
        /// x坐标到脉冲的转换系数
        /// </summary>
        public float XCoeffOfCoorToPulse { get; set; } = 1;
        /// <summary>
        /// 坐标到脉冲的转换系数
        /// </summary>
        public float YCoeffOfCoorToPulse { get; set; } = 1;
        /// <summary>
        /// 当前列
        /// </summary>
        public int CurColumn { get; set; } = 1;
        /// <summary>
        /// 抽屉行数
        /// </summary>
        public int Rows { get; private set; }
        /// <summary>
        /// 抽屉列数
        /// </summary>

        public int Columns { get; private set; }

        /// <summary>
        /// 抽屉间行间距
        /// </summary>
        public int Row_Spacing { get; private set; }
        /// <summary>
        /// 抽屉间列间距
        /// </summary>
        public int Column_Spacing { get; private set; }

        public List<string> FailedDrawers { get; set; }
        BoxEquip_Config boxEquip_Config;
        public AutoFindPos(BoxEquip_Config boxEquip_Config)
        {
            this.boxEquip_Config = boxEquip_Config;
            Row_Spacing = boxEquip_Config.Row_Spacing;
            Column_Spacing = boxEquip_Config.Column_Spacing;
            Rows = boxEquip_Config.Drawer_Rows;
            Columns = boxEquip_Config.Drawer_Columns;
            FailedDrawers = new List<string>();
        }
        public void SetParam(int curRow, int curColumn, float xCooef, float yCooef)
        {
            CurRow = curRow;
            CurColumn = curColumn;
            Row_Spacing = boxEquip_Config.Row_Spacing;
            Column_Spacing = boxEquip_Config.Column_Spacing;
            Rows = boxEquip_Config.Drawer_Rows;
            Columns = boxEquip_Config.Drawer_Columns;
            XCoeffOfCoorToPulse = xCooef;
            YCoeffOfCoorToPulse = yCooef;
        }
        /// <summary>
        /// Mark点坐标信息 
        /// </summary>
        /// <param name="bitmap">输入图片</param>
        /// <param name="markCoor">mark点坐标信息</param>
        /// <returns>0 正常 -4未定位到 </returns>
        public static int GetMarkInfo(Bitmap bitmap, out EyemOcsFXYR markCoor)
        {
            int flag;
            markCoor = new EyemOcsFXYR();
            EyemImage image = eyemCvtToEyemImage(bitmap);
            flag = eyemMarkerTracing(image, 130, ref markCoor);
            Marshal.FreeHGlobal(image.vpImage);
            return flag;
        }
    }
}