using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using nRTMC;

namespace 回原点运动
{
    public partial class Form1 : Form
    {
        private ushort cardConnectNo = 0; //卡的连接号
        private UInt32 functionReturn = 0; //用于接收函数返回值

        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 窗体加载事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            #region 开卡
            ushort pciNum = 0; //用于接收开卡成功的卡数
            ushort[] pcieIndex = new ushort[12];
            functionReturn = RTMC.MC_Open(0, nRTMC.class_Controller_Connect_Type.CONNECTION_PCI, "", ref pciNum, pcieIndex);
            if (functionReturn == 0)//函数成功执行
            {
                if (pciNum > 0)//至少一张卡被成功开卡
                {
                    cardConnectNo = pcieIndex[0]; //如果有多卡的情况下这里也只用卡1演示

                    #region 获取卡信息
                    //--------------------------获取卡信息------------------------------------------------------------------------
                    ushort totalAxisNum = 0; //用于获取卡的轴数
                    ushort linerNum = 0;//用于获取卡的插补系个数
                    ushort totalInNum = 0;//用于获取卡的输入口数量
                    ushort totalOutNum = 0;//用于获取卡的输出口数量
                    ushort totalPWMNum = 0;//用于获取卡的PWM通道数量
                    functionReturn = RTMC.MC_GetTotalAxesAndIONum(cardConnectNo, ref totalAxisNum, ref linerNum, ref totalInNum, ref totalOutNum, ref totalPWMNum);
                    numericUpDown1.Minimum = 0;
                    numericUpDown1.Maximum = totalAxisNum - 1; //设置界面最大能选择的轴号，轴号参数从0开始。

                    //------------------------------------------------------------------------------------------------------------
                    #endregion

                    //------------------使用轴专用信号前需要使能并且设置有效电平—————————————————————————
                    for(ushort _useAxis = 0;_useAxis<totalAxisNum;_useAxis++) //设置所有轴
                    {
                        //默认设置，低电平有效，减速停止
                        RTMC.MC_SetAxisInIoPrm(cardConnectNo, _useAxis, 0, 1, 0, 0);//负限位
                        RTMC.MC_SetAxisInIoPrm(cardConnectNo, _useAxis, 1, 1, 0, 0);//正限位
                        RTMC.MC_SetAxisInIoPrm(cardConnectNo, _useAxis, 2, 1, 0, 0);//原点
                        RTMC.MC_SetAxisInIoPrm(cardConnectNo, _useAxis, 3, 1, 0, 0);//伺服到位
                        RTMC.MC_SetAxisInIoPrm(cardConnectNo, _useAxis, 5, 1, 0, 0);//伺服报警
                        RTMC.MC_SetAxisInIoPrm(cardConnectNo, _useAxis, 6, 1, 0, 0);//伺服准备

                    }

                    timer1.Start(); //启动界面监控定时器
                }
                else
                {
                    MessageBox.Show("未找到卡!");
                    return;
                }
            }
            else
            {
                MessageBox.Show("开卡失败!");
                return;
            }
            #endregion
        }

        /// <summary>
        /// 窗体关闭事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            timer1.Stop();
            RTMC.MC_Close(cardConnectNo); //关卡释放资源
        }


        /// <summary>
        /// 执行运动按钮点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            ushort axisNo = (ushort)numericUpDown1.Value; //需要运动的轴号

            double startVel = 0; //启动速度
            double stopVel = 0; //停止速度
            double maxVel = 0; //运行速度
            double Acc = 0; //加速时间
            double Dec = 0; //减速时间
            double sRatio = 0;//S段比例，为0时为T型加减速
            double maxAcc = 0; //最大加速度限制，当Acc>maxAcc时加速度为maxAcc


            ushort posObject = 0; //锁存回零的锁存位置模式
            ushort home_mode = 0; //回零模式
            int home_dir = 1; //回零方向
            ushort home_logic = 0;//原点信号有效电平
            ushort ezCount = 1;//ez回零计EZ信号的个数
            ushort offset_mode = 0;//回零结束模式
            double offset = 0;//回零结束偏移

            try
            {
                startVel = Convert.ToDouble(textBox1.Text);
                stopVel = Convert.ToDouble(textBox2.Text);
                maxVel = Convert.ToDouble(textBox3.Text);
                Acc = Convert.ToDouble(textBox4.Text);
                Dec = Convert.ToDouble(textBox5.Text);
                sRatio = Convert.ToDouble(textBox6.Text);
                maxAcc = Convert.ToDouble(textBox7.Text);

                posObject = ((ushort)comboBox1.SelectedIndex);
                string[] homeModeStrArr = comboBox_homeMode.Text.Split('-');
                home_mode = Convert.ToUInt16(homeModeStrArr[0]);
                if (comboBox_homeDir.SelectedIndex == 1) home_dir = -1;
                offset_mode = (ushort)comboBox_home_endMode.SelectedIndex;
                offset = Convert.ToDouble(textBox_homeOffset.Text);
                ezCount = Convert.ToUInt16(textBox_ezCount.Text);
                if (comboBox2.SelectedIndex == 1) home_logic = 1;


            }
            catch (Exception)
            {
                MessageBox.Show("界面上的数值转换异常，请检查输入的参数！");
            }

            RTMC.MC_Power(cardConnectNo, axisNo, 1); //轴使能，轴使能之后才能够通过指令启动运动发出脉冲

            //先设置轴的运动参数
            RTMC.MC_SetAxisMotionPrm(cardConnectNo, axisNo, startVel, maxVel, stopVel, Acc, Dec, sRatio, maxAcc);

            //启动运动
            //参数三，pos_mode = 0时为相对运动模式， = 1时为绝对运动模式
            RTMC.MC_Home(cardConnectNo, axisNo, posObject,
                    home_mode,
                    home_dir,
                    home_logic,
                    ezCount,
                    offset_mode,
                    offset);

        }

        /// <summary>
        /// 停止运动按钮点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            ushort axisNo = ((ushort)numericUpDown1.Value);//轴号

            //参数三，stop_mode = 0时停止模式为减速停止，=1时为立即停止
            //参数四，stop_time为减速停止时的减速时间
            RTMC.MC_StopAxis(cardConnectNo, axisNo, 0, 0.1);
        }

        /// <summary>
        /// 紧急停止按钮点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            RTMC.MC_StopEmgImd(cardConnectNo); //急停函数，所有轴立即停止
        }

        /// <summary>
        /// 位置清除按钮点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button4_Click(object sender, EventArgs e)
        {
            ushort axisNo = ((ushort)numericUpDown1.Value);
            RTMC.MC_SetAxisCmdPos(cardConnectNo, axisNo, 0);//指令位置清零
        }

        /// <summary>
        /// 用于更新界面信息的定时器
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer1_Tick(object sender, EventArgs e)
        {
            ushort axisNo = ((ushort)numericUpDown1.Value);//轴号
            double cmdPos = 0;
            RTMC.MC_GetAxisCmdPos(cardConnectNo, axisNo, ref cmdPos);//获取当前指令位置
            textBox10.Text = cmdPos.ToString();

            double cmdSpeed = 0;
            RTMC.MC_GetAxisCmdSpeed(cardConnectNo, axisNo, ref cmdSpeed); //获取当前指令速度
            textBox9.Text = cmdSpeed.ToString();

            ushort checkDone = 1;
            RTMC.MC_GetAxisCheckDone(cardConnectNo, axisNo, ref checkDone);//获取轴运动状态
            switch (checkDone)
            {
                case 0:
                    textBox11.Text = "运动中";
                    break;
                case 1:
                    textBox11.Text = "空闲";
                    break;
                default:
                    textBox11.Text = checkDone.ToString();
                    break;
            }

            ushort homeResult = 0;
            RTMC.MC_GetHomeResult(cardConnectNo,axisNo,ref homeResult); //获取回零结果
            switch (homeResult)
            {
                case 0:
                    textBox8.Text = "回零未完成";
                    break;
                case 1:
                    textBox8.Text = "回零完成";
                    break;
                case 2:
                    textBox8.Text = "回零出错，没有原点信号";
                    break;
                case 3:
                    textBox8.Text = "回零中发现两个原点信号";
                    break;
                case 4:
                    textBox8.Text = "回零中没有发现EZ信号";
                    break;
                case 5:
                    textBox8.Text = "回零配置的方向错误";
                    break;
                case 6:
                    textBox8.Text = "回零过程限位停止";
                    break;
                case 7:
                    textBox8.Text = "回零外部停止";
                    break;
                default:
                    textBox8.Text = homeResult.ToString();
                    break;
            }

            uint inioState = 0;
            RTMC.MC_GetAxisInIoState(cardConnectNo, axisNo, ref inioState);//获取轴专用IO状态
            //负限位
            bool state = false;
            state = (inioState & (uint)0x1) > 0 ? true : false;
            if (state) pictureBox_eln.Image = Properties.Resources.red;
            else pictureBox_eln.Image = Properties.Resources.green;

            //正限位
            state = ((inioState >> 1) & (uint)0x1) > 0 ? true : false;
            if (state) pictureBox_elp.Image = Properties.Resources.red;
            else pictureBox_elp.Image = Properties.Resources.green;

            //原点
            state = ((inioState >> 2) & (uint)0x1) > 0 ? true : false;
            if (state) pictureBox_org.Image = Properties.Resources.red;
            else pictureBox_org.Image = Properties.Resources.green;
        }
    }
}
