AxisBean.cs 11.3 KB
using DeviceLib;
using OnlineStore.Common;
using OnlineStore.LoadCSVLibrary;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace OnlineStore.DeviceLibrary
{
    public class AxisBean
    {
        public ConfigMoveAxis Config = null;
        public static int TimeoutInterval = 500;
        public int LastPosition = 0;

        public string AxisName;
        public AxisBean(ConfigMoveAxis axisConfig, string deviceName)
        {
            this.Config = axisConfig;
            AxisName = "[" + Config.Explain + "_" + Config.DeviceName + "_" + Config.GetAxisValue() + "]";
        }


        private bool IsIntSlvBlock = false;
        public bool Open(bool isCheck, out string Msg)
        {
            Msg = "";
            string portName = Config.DeviceName;
            int slvAddr = Config.GetAxisValue();
            //打开所有轴 
            int bot = ConfigAppSettings.GetIntValue(Setting_Init.ACBaudRate);
            ACServerManager.OpenPort(Config.DeviceName, bot);
            Thread.Sleep(50);
            //初始化
            if (!IsIntSlvBlock)
            {
                ACServerManager.InitSlvAddr(portName, slvAddr, Config.TargetSpeed, Config.AddSpeed, Config.DelSpeed);
                Thread.Sleep(100);
            }
            ACServerManager.AlarmClear(portName, slvAddr);
            Thread.Sleep(100);
            ACServerManager.ServoOn(portName, slvAddr);

            //打开所有轴
            if (isCheck)
            {
                Thread.Sleep(1000);
                if (!AxisIsOpen(out Msg))
                {
                    return false;
                }
            }
            IsIntSlvBlock = true;
            return true;
        }

        public bool AxisIsOpen(out string msg)
        {
            msg = "";
            //判断轴是否正常
            string portName = Config.DeviceName;
            int slvAddr = Config.GetAxisValue();
            if (ACServerManager.ServerOnStatus(portName, slvAddr))
            {
                LogUtil.info(AxisName + "成功打开");
            }
            else
            {
                //清理报警,再重新打开一次
                LogUtil.info(AxisName + "打开失败,清理报警,重新打开");
                ACServerManager.AlarmClear(portName, slvAddr);
                System.Threading.Thread.Sleep(1200);
                ACServerManager.ServoOn(portName, slvAddr);
                System.Threading.Thread.Sleep(300);
                if (ACServerManager.ServerOnStatus(portName, slvAddr))
                {
                    LogUtil.info(AxisName + "重新打开成功");
                }
                else
                {
                    ACServerManager.ServoOff(portName, slvAddr);
                    msg = AxisName+ "打开失败 ";
                    LogUtil.info(AxisName + msg);
                    return false;
                }
            }

            return true;
        }
        public void ServoOff()
        {
            LogUtil.info("ServoOff【" + AxisName + "】");
            ACServerManager.ServoOff(Config.DeviceName, Config.GetAxisValue());
        }
        public void HomeMove(RobotMoveInfo MoveInfo)
        {
            Config.TargetPosition = 0;
            LogUtil.info(AxisName + "speed[" + Config.TargetSpeed + "]开始原点返回");
            MoveInfo.WaitList.Add(WaitResultInfo.WaitAxis(Config, true));
            ACServerManager.HomeMove(Config.DeviceName, Config.GetAxisValue(), Config.HomeHighSpeed);
        }

        public void AbsMove(RobotMoveInfo MoveInfo, int targetPosition, int targetSpeed)
        {
            if (MoveInfo == null)
            {
                AbsMove(targetPosition, targetSpeed);
            }
            else
            {
                MoveInfo.WaitList.Add(WaitResultInfo.WaitAxis(Config, targetPosition, targetSpeed));
                Config.TargetPosition = targetPosition;
                ACServerManager.AbsMove(Config.DeviceName, Config.GetAxisValue(), targetPosition, targetSpeed);
            }
        }

        public static bool ACAxisMoveIsEnd(RobotMoveInfo MoveInfo, ConfigMoveAxis axis, int targetPosition, int targetSpeed, out string msg)
        {
            msg = "";
            string deviceName = axis.DeviceName;
            short axisNo = axis.GetAxisValue();

            bool isOk = ACServerManager.GetBusyStatus(deviceName, axisNo).Equals(0);
            int outCount = ACServerManager.GetActualtPosition(deviceName, axisNo);
            int errorCount = Math.Abs(outCount - targetPosition);
            if (isOk)
            {
                if (errorCount <= axis.CanErrorCountMax)
                {
                    return true;
                }
                //判断是否需要重新运动
                if (MoveInfo.CanWhileCount > 0)
                {
                    LogUtil.error(MoveInfo.Name + axis.DisplayStr + "目标位置[" + targetPosition + "]当前位置[" + outCount +
                     "],误差过大,重新开始运动,剩余[" + MoveInfo.CanWhileCount + "]次");
                    ACServerManager.SuddenStop(axis.DeviceName, axis.GetAxisValue());
                    ACServerManager.AbsMove(axis.DeviceName, axis.GetAxisValue(), targetPosition, targetSpeed);
                    MoveInfo.CanWhileCount--;
                }
                else if (MoveInfo.CanWhileCount == -1) {
                    msg = " " + MoveInfo.MoveStep + MoveInfo.Name + axis.DisplayStr + ",目标位置[" + targetPosition + "]当前位置[" + outCount
                        + "],误差过大,配置为忽略";
                    LogUtil.error(msg, MoveInfo.ErrorLogType);
                    return true;
                }
                else
                {
                    msg = " " + MoveInfo.MoveStep + MoveInfo.Name + axis.DisplayStr + ",目标位置[" + targetPosition + "]当前位置[" + outCount
                        + "],误差过大,需要报警";
                    LogUtil.error(msg, MoveInfo.ErrorLogType);
                }
            }
            return false;
        }
        public static bool HomeMoveIsEnd(RobotMoveInfo MoveInfo, ConfigMoveAxis axis, out string msg)
        {
            msg = "";
            if (ACServerManager.IsHomeMoveEnd(axis.DeviceName, axis.GetAxisValue()))
            {
                //原点完成并且位置=0
                int outCount = ACServerManager.GetActualtPosition(axis.DeviceName, axis.GetAxisValue());
                int errorCount = Math.Abs(outCount);
                if (errorCount <= axis.CanErrorCountMax)
                {
                    return true;
                }
                //判断是否需要重新运动
                if (MoveInfo.CanWhileCount > 0)
                {
                    LogUtil.error(MoveInfo.Name + axis.DisplayStr + "收到原点完成信号,当前位置[" + outCount + "],重新回原点,剩余[" + MoveInfo.CanWhileCount + "]次");
                    //LogUtil.error( StoreName +  moveAxis.DisplayStr +  "重新回原点"); 
                    ACServerManager.HomeMove(axis.DeviceName, axis.GetAxisValue(), axis.HomeHighSpeed, true);
                    MoveInfo.CanWhileCount--;
                }
                else
                {
                    msg = MoveInfo.Name + " " + MoveInfo.MoveStep + axis.DisplayStr + ",收到原点完成信号,当前位置[" + outCount + "],误差过大,需要报警";
                    LogUtil.error(msg);
                }
            }
            return false;
        }

        public int GetAclPosition()
        {
            int p = ACServerManager.GetActualtPosition(Config.DeviceName, Config.GetAxisValue());
            return p;
        }
        public bool IsInPosition(int targetP)
        {
            int currp = GetAclPosition();

            int chaz = targetP - currp;
            if (Math.Abs(chaz) < Config.CanErrorCountMax)
            {
                return true;
            }
            return false;
        }
        private void AbsMove(int targetPos, double targetSpeed)
        {
            if (targetPos.Equals(-1))
            {
                return;
            }
            LastPosition = -1;
            if (targetSpeed > Config.TargetSpeed || targetSpeed <= 0)
            {
                targetSpeed = Config.TargetSpeed;
            }
            //小于1,表示是目标速度的百分比
            else if (targetSpeed <= 1)
            {
                targetSpeed = Config.TargetSpeed * targetSpeed;
            }
            ACServerManager.AbsMove(Config.DeviceName, Config.GetAxisValue(), targetPos, (int)targetSpeed);

        }
        public void SuddenStop(bool needCheck = false)
        {
            if (needCheck)
            {
                if (ACServerManager.GetBusyStatus(Config.DeviceName, Config.GetAxisValue()).Equals(0))
                {
                    return;
                }
            }
            ACServerManager.SuddenStop(Config.DeviceName, Config.GetAxisValue());
            if (ACServerManager.GetBusyStatus(Config.DeviceName, Config.GetAxisValue()).Equals(1))
            {
                LogUtil.info(Config.DisplayStr + " 停止失败");
            }
        }



        #region  匀速上升处理 
        private System.Timers.Timer axisCheckTimer = null;
        internal string TargetIoType = "";
        internal IO_VALUE TargetIoValue = IO_VALUE.HIGH;
        public bool BatchAxisStartCheck(string targetIo , IO_VALUE value = IO_VALUE.HIGH)
        {
            if (String.IsNullOrEmpty(targetIo))
            {
                targetIo = "";
            }
            if (axisCheckTimer == null)
            {
                axisCheckTimer = new System.Timers.Timer();
                axisCheckTimer.AutoReset = true;
                axisCheckTimer.Interval += 30;
                axisCheckTimer.Elapsed += CheckTimer_Elapsed;
                axisCheckTimer.Enabled = false;
            }
            TargetIoValue = value;
            TargetIoType = targetIo;
            IsInProcess = false;
            axisCheckTimer.Start();
            return true;
        }

        public bool AxisStopCheckMove()
        {
            if (!(axisCheckTimer == null))
            {
                axisCheckTimer.Stop();
            }
            return true;
        }
        private bool IsInProcess = false;
        private DateTime lastOkTime = DateTime.Now;
        private void CheckTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            TimeSpan pan = DateTime.Now - lastOkTime;
            if (IsInProcess && pan.TotalMilliseconds < 100) { return; }
            try
            {

                IsInProcess = true;
                lastOkTime = DateTime.Now;
                if (IOManager.IOValue(TargetIoType, 0).Equals(TargetIoValue))
                {
                    AxisStopCheckMove();
                    LogUtil.info(AxisName + "上料轴,检测到 " + TargetIoType + "=" + TargetIoValue + ",停止运动,AclPosition=" + GetAclPosition().ToString());
                    SuddenStop(); 
                }
            }
            catch (Exception ex)
            {
                LogUtil.error("CheckTimer_Elapsed出错:", ex);
            }
            finally
            {
                IsInProcess = false;
            }
        }


        #endregion

    }
}