using Aitex.Common.Util;
using Aitex.Core.RT.Log;
using Aitex.Core.Util;
using MECF.Framework.Common.Beckhoff.AxisProvider;
using MECF.Framework.Common.Device.Galil;
using MECF.Framework.Common.Net;
using MECF.Framework.Common.Simulator;
using MECF.Framework.Simulator.Core.Driver;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace CyberX8_Simulator.Devices
{
    public class GalilSocketSimulator : SocketDeviceSimulator
    {
        #region 常量
        //最大运动轴数量(abcdefg)
        private const int MAX_AXIS_NUM = 8;
        //GalilControllerData最大数据长度
        private const int MAX_CONTROL_DATA_LENGTH_21 = 264;
        private const int MAX_CONTROL_DATA_LENGTH_40 = 366;
        //GalilAxisData最大数据长度
        private const int MAX_AXIS_DATA_LENGTH_21 = 28;
        private const int MAX_AXIS_DATA_LENGTH_40 = 36;
        //GalilType
        private const string GALIL_21 = "Galil21";
        private const string GALIL_40 = "Galil40";
        private const string TARGET_VELOCITY = "TargetVelocity";
        private const string TARGET_ACCEL = "TargetAcceleration";
        private const string TARGET_DECEL = "TargetDeceleration";
        private const string TARGET_POSITION = "TargetPosition";
        private const string SWITCH_SIGNAL = "SwitchSignal";
        private const string ACTUAL_POSITION = "ActualPosition";
        private const string AUXILIARY_POSITION = "AuxiliaryPosition";
        private const string HOMING_SIGNAL = "HomingSignal";
        private const string FI_HOMING_SIGNAL = "FIHomingSignal";
        private const string MOTION_SIGNAL = "MotionSignal";
        private const string STOP_SIGNAL = "StopSignal";      
       
        #endregion
        #region 内部变量
        private IByteTransform byteTransform = new BigEndianByteTransformBase();
        /// 
        /// Galil数据
        /// 
        private GalilControllerData _galilControlData = new GalilControllerData();
        /// 
        /// Axis名称字典(key:axisName, value:index)
        /// 
        private Dictionary _axisNameIndexDic = new Dictionary();
        /// 
        /// Axis名称列表(index - axisName)
        /// 
        private string[] _nameAxisList = new string[MAX_AXIS_NUM];
        /// 
        /// ModuleName
        /// 
        /// 
        private string _moduleName;
        /// 
        /// Galil Type
        /// 
        private string _galilType;
        /// 
        /// GalilControllerData数据长度
        /// 
        private int _controlDataLength;
        /// 
        /// GalilAxisDatas数据长度
        /// 
        private int _axisDataLength;
        /// 
        /// MotorPosition比例系数字典(index - motorPositionRate)
        /// 
        private Dictionary _motorPositionRateDic = new Dictionary();
        /// 
        /// Velocity比例系数字典(index - motorPositionRate)
        /// 
        private Dictionary _velocityRateDic = new Dictionary();
        /// 
        /// Key:dataName - Value:GalilDI
        /// 
        public Dictionary InputDataNameDIDic = new Dictionary();
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public GalilSocketSimulator(int port) :base(port)
        {
            InitData(port);
        }
        /// 
        /// 解析信息
        /// 
        /// 
        protected override void ProcessUnsplitMessage(byte[] data)
        {
            string cmdStr = ASCIIEncoding.ASCII.GetString(data);
            if (CheckCmdValid(cmdStr))
            {
                var cmdOperation = AnalyseCommand(cmdStr);
                byte[] response;
                if(cmdOperation.Item1 == "QR")
                {
                    //Read
                    response = CreateReadResponse(_galilControlData);
                }
                else
                {
                    //Write
                    SetOperation(cmdOperation.Item1, cmdOperation.Item2, cmdOperation.Item3);
                    response = CreateWriteResponse();
                }
                OnWriteMessage(response);
            }
            else
            {
                OnWriteMessage(CreateError());
            }                   
        }
        /// 
        /// 读回复
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        private byte[] CreateReadResponse(GalilControllerData data)
        {
            //数据头(4 bytes)
            int headLength = 4;
            byte[] result = new byte[headLength + _controlDataLength];
            result[0] = 0x00;
            result[1] = 0x00;
            short dataLength = (short)(headLength + _controlDataLength);
            Array.Copy(byteTransform.GetBytes(dataLength), 0, result, 2, 2);
            //数据体(MAX_CONTROL_DATA_LENGTH bytes)
            switch (_galilType)
            {
                case GALIL_21:
                    Array.Copy(CodeControlData21(data), 0, result, 4, MAX_CONTROL_DATA_LENGTH_21);
                    break;
                case GALIL_40:
                    Array.Copy(CodeControlData40(data), 0, result, 4, MAX_CONTROL_DATA_LENGTH_40);
                    break;
                default:
                    break;
            }           
            return result;
        }
        /// 
        /// 写回复
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        private byte[] CreateWriteResponse()
        {
            //数据头(1 bytes)
            int headLength = 1;
            byte[] result = new byte[headLength];
            result[0] = 0x3A;
            return result;
        }
        /// 
        /// 错误回复
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        private byte[] CreateError()
        {
            int headLength = 1;
            byte[] result = new byte[headLength];
            //Command not valid in program
            result[0] = 0x03;
            return result;
        }
        /// 
        /// 初始化
        /// 
        private void InitData(int port)
        {
            //初始化AxisData(最大MAX_AXIS_NUM个axis)
            _galilControlData.GalilAxisDatas = new List();
            for (int i = 0; i < MAX_AXIS_NUM; i++)
            {
                _galilControlData.GalilAxisDatas.Add(new GalilAxisData());
                _galilControlData.GalilAxisDatas[i].Status = 0x00;
            }
            _galilControlData.Inputs  = new byte[10];
            _galilControlData.Outputs = new byte[10];
            //电机数据更新事件
            MotorSimulator.Instance.OnUpdateMotionDatasChanged += UpdateRealTimeMotionData;
            MotorSimulator.Instance.OnUpdateInputDatasChanged += UpdateInputData;
            //加载GalilControllerCfg-Simulator.xml
            try
            {
                string oldXmlPath = PathManager.GetCfgDir();
                string newXmlPath = oldXmlPath.Replace("CyberX8_Simulator", "CyberX8_RT") + "Devices\\GalilControllerCfg-Simulator.xml";
                GalilControllerCfg cfg = CustomXmlSerializer.Deserialize(new FileInfo(newXmlPath));
                if(cfg != null)
                {
                    foreach (GalilDeviceConfig config in cfg.GalilDeviceConfigs)
                    {
                        if (port == config.Port)
                        {
                            _moduleName = config.Module;
                            _galilType = config.GalilType;
                            foreach (GalilAxisConfig item in config.GalilAxises)
                            {
                                _axisNameIndexDic[item.Name] = item.Index;
                                _nameAxisList[item.Index] = item.Name;
                            }
                            if (config.GalilDigIn != null && config.GalilDigIn.DIs.Count != 0)
                            {
                                foreach (var items in config.GalilDigIn.DIs)
                                {
                                    InputDataNameDIDic[items.Name] = items;
                                }
                            }
                            
                        }
                    }
                }               
            }
            catch
            {
                LOG.WriteLog(eEvent.ERR_GALIL, "Galil", "Load galil GalilControllerCfg-Simulator.xml failed");
            }
            //加载AxisProviderCfg.xml
            try
            {
                string oldXmlPath = PathManager.GetCfgDir();
                string newXmlPath = oldXmlPath.Replace("CyberX8_Simulator", "CyberX8_RT") + "Devices\\AxisProviderCfg.xml";
                BeckhoffAxisProviderCfg axisProviderCfg = CustomXmlSerializer.Deserialize(new FileInfo(newXmlPath));
                if (axisProviderCfg != null)
                {
                    foreach (BeckhoffProviderAxis item in axisProviderCfg.Axes)
                    {
                        for (int i = 0; i < MAX_AXIS_NUM; i++)
                        {
                            if (_nameAxisList[i] == item.Name)
                            {
                                _motorPositionRateDic[item.Name] = item.MotorPositionRate;
                                _velocityRateDic[item.Name] = item.VelocityRate;
                            }
                        }
                    }
                }
            }
            catch
            {
                LOG.WriteLog(eEvent.ERR_AXIS, "axisProvider", "Load AxisProviderCfg.xml failed");
            }
            //初始化对应Galiltype数据       
            if (_galilType == GALIL_40)
            {
                _controlDataLength = MAX_CONTROL_DATA_LENGTH_40;
                _axisDataLength = MAX_AXIS_DATA_LENGTH_40;
                _galilControlData.SBlocks = new byte[10];
                _galilControlData.TBlocks = new byte[10];
            }
            else
            {
                _controlDataLength = MAX_CONTROL_DATA_LENGTH_21;
                _axisDataLength = MAX_AXIS_DATA_LENGTH_21;
                _galilControlData.SBlocks = new byte[8];
                _galilControlData.TBlocks = new byte[8];
            }
            
        }
        #region Galil编码
        /// 
        /// GalilControllerData编码(Galil21)
        /// 
        /// 
        private byte[] CodeControlData21(GalilControllerData ctrlData)
        {
            byte[] result = new byte[MAX_CONTROL_DATA_LENGTH_21];
            int index = 0;
            //Sample(2 bytes)
            Array.Copy(BitConverter.GetBytes(ctrlData.Sample), 0, result, index, 2);
            index += 2;
            //Inputs(1*10 bytes)
            Array.Copy(ctrlData.Inputs, 0, result, index, 10);
            index += 10;
            //Outputs(1*10 bytes)
            Array.Copy(ctrlData.Outputs, 0, result, index, 10);
            index += 10;
            //Error Code(1 bytes)         
            result[13] = ctrlData.ErrorCode;
            index++;
            //General Status(1 bytes)
            result[14] = ctrlData.Status;
            index++;
            //S Block(2+2+4=8 bytes)
            Array.Copy(ctrlData.SBlocks, 0, result, 15, 8);
            index += 8;
            //T Block(2+2+4=8 bytes)
            Array.Copy(ctrlData.TBlocks, 0, result, 23, 8);
            index += 8;
            //Axis Datas(28 * 8 bytes)
            for (int i = 0; i < MAX_AXIS_NUM; i++)
            {
                Array.Copy(CodeAxisData21(ctrlData.GalilAxisDatas[i]), 0, result, index, MAX_AXIS_DATA_LENGTH_21);
                index += MAX_AXIS_DATA_LENGTH_21;
            }
            return result;
        }
        /// 
        /// GalilAxisData编码(Galil21)
        /// 
        /// 
        /// 
        private byte[] CodeAxisData21(GalilAxisData axisData)
        {
            byte[] result = new byte[MAX_AXIS_DATA_LENGTH_21];
            int index = 0;
            //Status(2 bytes)
            Array.Copy(byteTransform.GetBytes(axisData.Status), 0, result, index, 2);
            index += 2;
            //Switches(1 bytes)
            result[index] = axisData.Switches;
            index++;
            //Stop Code(1 bytes)
            result[index] = axisData.StopCode;
            index++;
            //Reference Position(4 bytes)
            Array.Copy(BitConverter.GetBytes(axisData.ReferencePosition), 0, result, index, 4);
            index += 4;
            //Motor Position(4 bytes)
            Array.Copy(BitConverter.GetBytes(axisData.MotorPosition), 0, result, index, 4);
            index += 4;
            //Position Error
            Array.Copy(BitConverter.GetBytes(axisData.PositionError), 0, result, index, 4);
            index += 4;
            //Auxiliary Position
            Array.Copy(BitConverter.GetBytes(axisData.AuxiliaryPosition), 0, result, index, 4);
            index += 4;
            //Velocity
            Array.Copy(BitConverter.GetBytes(axisData.Velocity), 0, result, index, 4);
            index += 4;
            //Torque
            Array.Copy(BitConverter.GetBytes(axisData.Torque), 0, result, index, 2);
            index += 2;
            //Analog
            Array.Copy(BitConverter.GetBytes(axisData.Res), 0, result, index, 2);
            return result;
        }
        /// 
        /// GalilControllerData编码(Galil40)
        /// 
        /// 
        private byte[] CodeControlData40(GalilControllerData ctrlData)
        {
            byte[] result = new byte[MAX_CONTROL_DATA_LENGTH_40];
            int index = 0;
            //Sample(2 bytes)
            Array.Copy(BitConverter.GetBytes(ctrlData.Sample), 0, result, index, 2);
            index += 2;
            //Inputs(1*10 bytes)
            Array.Copy(ctrlData.Inputs, 0, result, index, 10);
            index += 10;
            //Outputs(1*10 bytes)
            Array.Copy(ctrlData.Outputs, 0, result, index, 10);
            index += 10;
            //reservers
            byte[] reservers = new byte[16];
            Array.Copy(reservers, 0, result, index, 16);
            index += 16;
            //ethernet
            byte[] ethernet = new byte[8];
            Array.Copy(ethernet, 0, result, index, 8);
            index += 8;
            //ethernet
            //Error Code(1 bytes)         
            result[13] = ctrlData.ErrorCode;
            index++;
            //General Status(1 bytes)
            result[14] = ctrlData.Status;
            index++;
            //ampliferStatus
            byte[] ampliferStatus = new byte[4];
            Array.Copy(ampliferStatus, 0, result, index, 4);
            index += 4;
            //counterModel
            byte[] counterModel = new byte[6];
            Array.Copy(counterModel, 0, result, index, 6);
            index += 6;
            //S Block(10 bytes)
            Array.Copy(ctrlData.SBlocks, 0, result, index, 10);
            index += 10;
            //T Block(10 bytes)
            Array.Copy(ctrlData.TBlocks, 0, result, index, 10);
            index += 10;
            //Axis Datas(36 * 8 bytes)
            for (int i = 0; i < MAX_AXIS_NUM; i++)
            {
                Array.Copy(CodeAxisData40(ctrlData.GalilAxisDatas[i]), 0, result, index, MAX_AXIS_DATA_LENGTH_40);
                index += MAX_AXIS_DATA_LENGTH_40;
            }
            return result;
        }
        /// 
        /// GalilAxisData编码(Galil40)
        /// 
        /// 
        /// 
        private byte[] CodeAxisData40(GalilAxisData axisData)
        {
            byte[] result = new byte[MAX_AXIS_DATA_LENGTH_40];
            int index = 0;
            //Status(2 bytes)
            Array.Copy(byteTransform.GetBytes(axisData.Status), 0, result, index, 2);
            index += 2;
            //Switches(1 bytes)
            result[index] = axisData.Switches;
            index++;
            //Stop Code(1 bytes)
            result[index] = axisData.StopCode;
            index++;
            //Reference Position(4 bytes)
            Array.Copy(BitConverter.GetBytes(axisData.ReferencePosition), 0, result, index, 4);
            index += 4;
            //Motor Position(4 bytes)
            Array.Copy(BitConverter.GetBytes(axisData.MotorPosition), 0, result, index, 4);
            index += 4;
            //Position Error
            Array.Copy(BitConverter.GetBytes(axisData.PositionError), 0, result, index, 4);
            index += 4;
            //Auxiliary Position
            Array.Copy(BitConverter.GetBytes(axisData.AuxiliaryPosition), 0, result, index, 4);
            index += 4;
            //Velocity
            Array.Copy(BitConverter.GetBytes(axisData.Velocity), 0, result, index, 4);
            index += 4;
            //Torque
            Array.Copy(BitConverter.GetBytes(axisData.Torque), 0, result, index, 4);
            index += 4;
            //Analog
            Array.Copy(BitConverter.GetBytes(axisData.Res), 0, result, index, 2);
            index += 2;
            byte hallInput = 0x00;
            result[index] = hallInput;
            index ++;
            byte reserved = 0x00;
            result[index] = reserved;
            index ++;
            byte[] userVariables = new byte[4];
            Array.Copy(userVariables, 0, result, index, 4);
            return result;
        }
        #endregion
        /// 
        /// 解析指令(操作符, 运动轴, 操作数)
        /// 
        /// 
        /// 
        private (string, char, int) AnalyseCommand(string cmdStr)
        {
            var result = ("", ' ', -1);
            //操作符
            result.Item1 = cmdStr.Substring(0, 2);
            //运动轴
            if (cmdStr.Length >= 4) 
            {
                result.Item2 = Convert.ToChar(cmdStr.Substring(2, 1));
            }
            //操作数
            if (cmdStr.Length >= 5 && int.TryParse(cmdStr.Substring(4, cmdStr.Length - 5), out int tmp))
            {
               result.Item3 = tmp;      
            }
            return result;
        }
        /// 
        /// CMD校验
        /// 
        /// 
        private bool CheckCmdValid(string cmdStr)
        {
            //长度
            if(cmdStr.Length < 3) return false;
            //;结尾
            if (!cmdStr.EndsWith(";")) return false;
            //第1位为A~Z
            if (cmdStr[0] < 'A' || cmdStr[0] > 'Z') return false;
            //第2位为A~Z
            if (cmdStr[1] < 'A' || cmdStr[1] > 'Z') return false;
            if(cmdStr[0] == 'C'&& cmdStr[1] == 'N')
            {
                return true;
            }
            if (cmdStr.Length >= 4)
            {
                //axis名称为A~H
                if (cmdStr[2] < 'A' || cmdStr[2] > 'H') return false;
                //=
                if(cmdStr.Length > 4 && !cmdStr.Contains("="))  return false;
            }
            
            return true;
        }
        /// 
        /// 设置操作
        /// 
        /// 
        /// 
        /// 
        /// 
        private bool SetOperation(string cmd, char axis, int value)
        {
            switch (cmd)
            {
                case "SH"://上电
                    SwitchMotor(axis, true);
                    break;
                case "MO"://下电
                    SwitchMotor(axis, false);
                    break;
                case "PR"://相对位置
                    SetTargetRelativePosition(axis, value);
                    break;
                case "PA"://绝对位置
                    SetTargetAbsolutePosition(axis, value);
                    break;
                case "SP"://速度
                    SetSpeed(axis, value);
                    break;
                case "AC"://加速度
                    SetAcceleration(axis, value);
                    break;
                case "DC"://减速度
                    SetDeceleration(axis, value);
                    break;
                case "ST"://停止
                    ControlMotion(axis, false);
                    break;
                case "BG"://启动
                    ControlMotion(axis, true);
                    break;
                case "HM"://回零
                    Home(axis);
                    break;
                case "FI"://SRDRotation回零
                    Home(axis);
                    break;
                case "DP"://设定motor position
                    SetMotorPosition(axis, value);
                    break;
                case "DE"://设定auxiliary position
                    SetAuxiliaryPosition(axis, value);
                    break;
                case "CN":
                    break;
                default:
                    break;
            }
            return true;
        }
        /// 
        /// 实时更新电机数据
        /// 
        /// 
        private void UpdateRealTimeMotionData(KeyValuePair dataPair)
        {
            if (_axisNameIndexDic.ContainsKey(dataPair.Key))
            {
                UpdateAxisData(_axisNameIndexDic[dataPair.Key], dataPair.Value);
            }
           
        }
        /// 
        /// 更新Galil Input datas
        /// 
        private void UpdateInputData(string module, string VariableName, bool value) 
        {
            if(_moduleName == module && InputDataNameDIDic.ContainsKey(VariableName))
            {
                int tmp = InputDataNameDIDic[VariableName].Invert ? (!value ? 1 : 0) : (value ? 1 : 0);
                _galilControlData.Inputs[InputDataNameDIDic[VariableName].Address] = (byte)(tmp << InputDataNameDIDic[VariableName].Bit);
            }
        }
        /// 
        /// 更新对应Axis数据
        /// 
        /// 
        private void UpdateAxisData(int index, SimulatorMotionData data)
        {
            _galilControlData.GalilAxisDatas[index].Velocity = (int)(data.TargetVelocity * _velocityRateDic[_nameAxisList[index]]);
            _galilControlData.GalilAxisDatas[index].MotorPosition = (int)(data.ActualPosition / _motorPositionRateDic[_nameAxisList[index]]);
            _galilControlData.GalilAxisDatas[index].ReferencePosition = data.TargetPosition;
            _galilControlData.GalilAxisDatas[index].Torque = data.ActualTorque;
            _galilControlData.GalilAxisDatas[index].StopCode = data.StopCode;
            _galilControlData.GalilAxisDatas[index].Switches = (byte)(_galilControlData.GalilAxisDatas[index].Switches & 0xF9
                | ((data.ForwardLimit ? 1 : 0) << 3) | ((data.ReverseLimit ? 1 : 0) << 2));
        }
        /// 
        /// 模拟器UI更新inputs数据
        /// 
        /// 
        /// 
        public void UpdateInputByte(string name, int value)
        {
            if (InputDataNameDIDic.ContainsKey(name))
            {
                GalilDI galilDI = InputDataNameDIDic[name];
                short byteValue = (short)(_galilControlData.Inputs[galilDI.Address] & ~(1 << galilDI.Bit));
                short tmp = (short)(value << galilDI.Bit);
                _galilControlData.Inputs[galilDI.Address] = (byte)(byteValue | tmp);
            }
        }
        /// 
        /// 模拟器获取inputs数据
        /// 
        /// 
        public int GetInputData(string name)
        {
            int result = 0;
            if (!InputDataNameDIDic.ContainsKey(name)) return 0;
            GalilDI galilDI = InputDataNameDIDic[name];
            int tmp = _galilControlData.Inputs[galilDI.Address] & (1 << galilDI.Bit);
            result = (tmp == (1 << galilDI.Bit)) ? 1 : 0;
            return result;
        }
        #region AxisOperation
        /// 
        /// 开/关电机
        /// 
        /// 
        /// 
        private void SwitchMotor(char axis, bool flag)
        {
            byte[] data = byteTransform.GetBytes(_galilControlData.GalilAxisDatas[axis - 'A'].Status);
            data[0] &= 0xFE;
            data[0] |= (byte)(flag ? 0x00 : 0x01);
            _galilControlData.GalilAxisDatas[axis - 'A'].Status = byteTransform.TransUInt16(data, 0);
            MotorSimulator.Instance.SetMotionData(_nameAxisList[axis - 'A'], SWITCH_SIGNAL, flag);
        }
        /// 
        /// 设置速度
        /// 
        private void SetSpeed(char axis, int value)
        {
            MotorSimulator.Instance.SetMotionData(_nameAxisList[axis - 'A'], TARGET_VELOCITY, value);
        }
        /// 
        /// 设置加速度
        /// 
        private void SetAcceleration(char axis, int value)
        {
            MotorSimulator.Instance.SetMotionData(_nameAxisList[axis - 'A'], TARGET_ACCEL, value);
        }
        /// 
        /// 设置减速度
        /// 
        private void SetDeceleration(char axis, int value)
        {
            MotorSimulator.Instance.SetMotionData(_nameAxisList[axis - 'A'], TARGET_DECEL, value);
        }
        /// 
        /// 设置目标绝对位置(设定位置)
        /// 
        private void SetTargetAbsolutePosition(char axis, int value)
        {
            _galilControlData.GalilAxisDatas[axis - 'A'].ReferencePosition = value;
            MotorSimulator.Instance.SetMotionData(_nameAxisList[axis - 'A'], TARGET_POSITION, value);
        }
        /// 
        /// 设置目标相对位置(设定位置)
        /// 
        private void SetTargetRelativePosition(char axis, int value)
        {
            _galilControlData.GalilAxisDatas[axis - 'A'].ReferencePosition = _galilControlData.GalilAxisDatas[axis - 'A'].MotorPosition + value;
            MotorSimulator.Instance.SetMotionData(_nameAxisList[axis - 'A'], TARGET_POSITION, _galilControlData.GalilAxisDatas[axis - 'A'].ReferencePosition);
        }
        /// 
        /// 设置 Motor Position(实际位置)
        /// 
        /// 
        /// 
        private void SetMotorPosition(char axis, int value)
        {
            MotorSimulator.Instance.SetMotionData(_nameAxisList[axis - 'A'], ACTUAL_POSITION, value);
        }
        /// 
        /// 设置 Auxiliary Position
        /// 
        /// 
        /// 
        private void SetAuxiliaryPosition(char axis, int value)
        {
            MotorSimulator.Instance.SetMotionData(_nameAxisList[axis - 'A'], AUXILIARY_POSITION, value);
        }
        /// 
        /// 控制运动
        /// 
        private void ControlMotion(char axis, bool value)
        {
            MotorSimulator.Instance.SetMotionData(_nameAxisList[axis - 'A'], value ? MOTION_SIGNAL : STOP_SIGNAL, value);
        }
        /// 
        /// 电机回零
        /// 
        /// 
        private void Home(char axis)
        {
            MotorSimulator.Instance.SetMotionData(_nameAxisList[axis - 'A'], HOMING_SIGNAL, true);
        }
        /// 
        /// 电机FI回零
        /// 
        /// 
        private void FI(char axis)
        {
            MotorSimulator.Instance.SetMotionData(_nameAxisList[axis - 'A'], FI_HOMING_SIGNAL, true);
        }
        public void SetForwardLimit()
        {
        }
        #endregion
    }
}