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

                    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
            double pos = 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);
                pos = Convert.ToDouble(textBox8.Text);
            }
            catch (Exception)
            {
                MessageBox.Show("界面上的数值转换异常，请检查输入的参数！");
            }

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

            const ushort MovePosFunction = 0;
            switch (MovePosFunction)//启动一段点位运动有三种写法
            {
                case 0:
                    //先设置轴的运动参数
                    RTMC.MC_SetAxisMotionPrm(cardConnectNo, axisNo, startVel, maxVel, stopVel, Acc, Dec, sRatio, maxAcc);

                    //启动运动
                    //参数三，pos_mode = 0时为相对运动模式， = 1时为绝对运动模式
                    RTMC.MC_MovePos(cardConnectNo, axisNo, 0, pos);
                    break;
                case 1:
                    //启动一段绝对位置运动，只需要一条指令
                    RTMC.MC_MoveAbsolute(cardConnectNo, axisNo, pos, startVel, stopVel, maxVel, Acc, Dec, sRatio, maxAcc);
                    break;
                case 2:
                    //启动一段相对位置运动，只需要一条指令
                    RTMC.MC_MoveRelative(cardConnectNo, axisNo, pos, startVel, stopVel, maxVel, Acc, Dec, sRatio, maxAcc);
                    break;
                default:
                    break;
            }
        }


        /// <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 button5_Click(object sender, EventArgs e)
        {
            ushort axisNo = ((ushort)numericUpDown1.Value);//轴号
            double newVel = 0;
            try
            {
                newVel = Convert.ToDouble(textBox12.Text);
            }
            catch (Exception)
            {
                MessageBox.Show("界面上的数值转换异常，请检查输入的参数！");
            }
            RTMC.MC_MoveUpdateVel(cardConnectNo, axisNo, newVel);
        }

        private void button6_Click(object sender, EventArgs e)
        {
            //在运动过程中想要改变最终停止的位置，只需要再次执行一次点动指令发送新位置就可以了
            ushort axisNo = ((ushort)numericUpDown1.Value);//轴号
            double newPos = 0;
            try
            {
                newPos = Convert.ToDouble(textBox13.Text);
            }
            catch (Exception)
            {
                MessageBox.Show("界面上的数值转换异常，请检查输入的参数！");
            }
            RTMC.MC_MovePos(cardConnectNo, axisNo, 0, newPos);
        }

        /// <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;
            }

        }

        /// <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);//指令位置清零
        }
    }
}
