using nRTMC;
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;

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.Maximum = linerNum; //设置插补系号可选最大值
                    //------------------------------------------------------------------------------------------------------------
                    #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();
            timer1.Dispose();
            RTMC.MC_Close(cardConnectNo); //关卡释放资源
        }

        /// <summary>
        /// 直线插补运动启动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            ushort CrdNo = Convert.ToUInt16(numericUpDown1.Value);
            ushort crdMode = 0; //相对运动
            if (radioButton2.Checked) crdMode = 1; //绝对运动

            SetMotionPrm(CrdNo);

            ushort[] axisList = new ushort[3] { Convert.ToUInt16(numericUpDown2.Value),
            Convert.ToUInt16(numericUpDown3.Value),
            Convert.ToUInt16(numericUpDown4.Value)};

            double[] distList = new double[3] { Convert.ToDouble(textBox10.Text),
            Convert.ToDouble(textBox11.Text),
            Convert.ToDouble(textBox12.Text)};

            RTMC.MC_MoveLinear(cardConnectNo, CrdNo, 3, axisList, distList, crdMode);

        }

        /// <summary>
        /// 终点圆心的圆弧插补启动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            ushort CrdNo = Convert.ToUInt16(numericUpDown1.Value);
            ushort crdMode = 0; //相对运动
            if (radioButton2.Checked) crdMode = 1; //绝对运动

            ushort arcDir = 0; //圆弧插补方向，顺时针
            if(radioButton_anticlockwise.Checked) arcDir = 1;

            uint cirCle = Convert.ToUInt32(numericUpDown_circle.Value);
            SetMotionPrm(CrdNo); //设置运动参数

            ushort[] axisList = new ushort[3] { Convert.ToUInt16(numericUpDown2.Value),
            Convert.ToUInt16(numericUpDown3.Value),
            Convert.ToUInt16(numericUpDown4.Value)};

            double[] distList = new double[3] { Convert.ToDouble(textBox10.Text),
            Convert.ToDouble(textBox11.Text),
            Convert.ToDouble(textBox12.Text)};

            double[] cenList = new double[3] { Convert.ToDouble(textBox15.Text),
            Convert.ToDouble(textBox14.Text),
            Convert.ToDouble(textBox13.Text)};

            //启动运动
            RTMC.MC_MovePlaneArcC(cardConnectNo, CrdNo, 3, axisList, distList, cenList, arcDir, cirCle, crdMode);
        }

        /// <summary>
        /// 终点半径的圆弧插补
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            ushort CrdNo = Convert.ToUInt16(numericUpDown1.Value);
            ushort crdMode = 0; //相对运动
            if (radioButton2.Checked) crdMode = 1; //绝对运动

            ushort arcDir = 0; //圆弧，0 = 劣弧
            if (radioButton3.Checked) arcDir = 1; //优弧

            double arcRadius = Convert.ToDouble(numericUpDown5.Value);

            uint cirCle = Convert.ToUInt32(numericUpDown6.Value);
            SetMotionPrm(CrdNo); //设置运动参数

            ushort[] axisList = new ushort[3] { Convert.ToUInt16(numericUpDown2.Value),
            Convert.ToUInt16(numericUpDown3.Value),
            Convert.ToUInt16(numericUpDown4.Value)};

            double[] distList = new double[3] { Convert.ToDouble(textBox10.Text),
            Convert.ToDouble(textBox11.Text),
            Convert.ToDouble(textBox12.Text)};

            RTMC.MC_MovePlaneArcR(cardConnectNo, CrdNo, 3, axisList, distList, arcRadius, arcDir, cirCle, crdMode);
        }

        /// <summary>
        /// 三点圆弧插补
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button4_Click(object sender, EventArgs e)
        {
            ushort CrdNo = Convert.ToUInt16(numericUpDown1.Value);
            ushort crdMode = 0; //相对运动
            if (radioButton2.Checked) crdMode = 1; //绝对运动

            uint cirCle = Convert.ToUInt32(numericUpDown7.Value); //插补圈速
            SetMotionPrm(CrdNo); //设置运动参数

            ushort[] axisList = new ushort[3] { Convert.ToUInt16(numericUpDown2.Value),
            Convert.ToUInt16(numericUpDown3.Value),
            Convert.ToUInt16(numericUpDown4.Value)};

            double[] distList = new double[3] { Convert.ToDouble(textBox10.Text),
            Convert.ToDouble(textBox11.Text),
            Convert.ToDouble(textBox12.Text)};

            double[] midPos = new double[3] {Convert.ToDouble(textBox18.Text),
            Convert.ToDouble(textBox17.Text),
            Convert.ToDouble(textBox16.Text) };

            //三点圆弧插补
            RTMC.MC_MovePlaneArc3P(cardConnectNo, CrdNo, 3, axisList, distList, midPos, cirCle, crdMode);

        }

        /// <summary>
        /// 终点圆心的空间圆弧插补
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button5_Click(object sender, EventArgs e)
        {
            ushort CrdNo = Convert.ToUInt16(numericUpDown1.Value);
            SetMotionPrm(CrdNo); //设置运动参数

            ushort crdMode = 0; //相对运动
            if (radioButton2.Checked) crdMode = 1; //绝对运动

            uint cirCle = Convert.ToUInt32(numericUpDown8.Value); //插补圈数

            ushort arcDir = 0; //默认方向为顺时针
            if (radioButton5.Checked) arcDir = 1;

            ushort[] axisList = new ushort[3] { Convert.ToUInt16(numericUpDown2.Value),
            Convert.ToUInt16(numericUpDown3.Value),
            Convert.ToUInt16(numericUpDown4.Value)};

            double[] distList = new double[3] { Convert.ToDouble(textBox10.Text),
            Convert.ToDouble(textBox11.Text),
            Convert.ToDouble(textBox12.Text)};

            double[] cenList = new double[3] { Convert.ToDouble(textBox15.Text),
            Convert.ToDouble(textBox14.Text),
            Convert.ToDouble(textBox13.Text)};

            RTMC.MC_MoveSpaceArcC(cardConnectNo, CrdNo, 3, axisList, distList, cenList, arcDir, cirCle, crdMode);
        }

        /// <summary>
        /// 三点圆弧空间插补函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button6_Click(object sender, EventArgs e)
        {
            ushort CrdNo = Convert.ToUInt16(numericUpDown1.Value);
            SetMotionPrm(CrdNo); //设置运动参数

            ushort crdMode = 0; //相对运动
            if (radioButton2.Checked) crdMode = 1; //绝对运动

            uint cirCle = Convert.ToUInt32(numericUpDown9.Value); //插补圈数

            ushort[] axisList = new ushort[3] { Convert.ToUInt16(numericUpDown2.Value),
            Convert.ToUInt16(numericUpDown3.Value),
            Convert.ToUInt16(numericUpDown4.Value)};

            double[] distList = new double[3] { Convert.ToDouble(textBox10.Text),
            Convert.ToDouble(textBox11.Text),
            Convert.ToDouble(textBox12.Text)};

            double[] midposList = new double[3] {Convert.ToDouble(textBox21.Text),
            Convert.ToDouble(textBox20.Text),
            Convert.ToDouble(textBox19.Text)};

            RTMC.MC_MoveSpaceArc3P(cardConnectNo, CrdNo, 3, axisList, distList,midposList, cirCle, crdMode);
        }

        /// <summary>
        /// 椭圆插补
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button7_Click(object sender, EventArgs e)
        {
            ushort CrdNo = Convert.ToUInt16(numericUpDown1.Value);
            SetMotionPrm(CrdNo); //设置运动参数

            ushort crdMode = 0; //相对运动
            if (radioButton2.Checked) crdMode = 1; //绝对运动

            uint cirCle = Convert.ToUInt32(numericUpDown10.Value); //插补圈数

            ushort arcDir = 0; //插补方向默认为顺时针
            if (radioButton7.Checked) arcDir = 1;

            ushort[] axisList = new ushort[3] { Convert.ToUInt16(numericUpDown2.Value),
            Convert.ToUInt16(numericUpDown3.Value),
            Convert.ToUInt16(numericUpDown4.Value)}; //轴号数组

            double[] distList = new double[3] { Convert.ToDouble(textBox10.Text),
            Convert.ToDouble(textBox11.Text),
            Convert.ToDouble(textBox12.Text)}; //目标位置数组

            double[] cenList = new double[3] { Convert.ToDouble(textBox15.Text),
            Convert.ToDouble(textBox14.Text),
            Convert.ToDouble(textBox13.Text)}; //椭圆圆心位置数组

            double longLength = Convert.ToDouble(textBox22.Text); //椭圆长轴
            double shortLength = Convert.ToDouble(textBox23.Text); //椭圆短轴

            RTMC.MC_MovePlaneEllipse(cardConnectNo, CrdNo, 3, axisList, distList, cenList, shortLength, longLength, arcDir, cirCle, crdMode);

        }

        /// <summary>
        /// 根据界面参数设置坐标系运动参数
        /// </summary>
        private void SetMotionPrm(ushort _crdNo)
        {
            //运动轴运动前要使能
            ushort axis0 = Convert.ToUInt16(numericUpDown2.Value);
            ushort axis1 = Convert.ToUInt16(numericUpDown3.Value);
            ushort axis2 = Convert.ToUInt16(numericUpDown4.Value);

            RTMC.MC_Power(cardConnectNo, axis0, 1);
            RTMC.MC_Power(cardConnectNo, axis1, 1);
            RTMC.MC_Power(cardConnectNo, axis2, 1);


            try
            {
                double startVel = Convert.ToDouble(textBox_startVel.Text);
                double maxVel = Convert.ToDouble(textBox_maxVel.Text);
                double stopVel = Convert.ToDouble(textBox_stopVel.Text);
                double tAcc = Convert.ToDouble(textBox_accTime.Text);
                double tDec = Convert.ToDouble(textBox_decTime.Text);
                double s_ratio = Convert.ToDouble(textBox_sTime.Text);
                RTMC.MC_SetCrdMotionPrm(cardConnectNo,
                    _crdNo,
                    startVel,
                    maxVel,
                    stopVel,
                    tAcc,
                    tDec,
                    s_ratio,
                    10000000);

            }
            catch (Exception)
            {
                MessageBox.Show("数据输入错误,请检查！", "错误");
            }
        }

        /// <summary>
        /// 停止插补系运动按钮点击
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button9_Click(object sender, EventArgs e)
        {
            ushort CrdNo = Convert.ToUInt16(numericUpDown1.Value);


            //减速停
            RTMC.MC_StopCrd(cardConnectNo,
                        CrdNo,
                        0,
                        Convert.ToDouble(textBox_decTime.Text));
        }

        /// <summary>
        /// 急停插补系运动按钮点击
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button10_Click(object sender, EventArgs e)
        {
            //所有轴急停
            RTMC.MC_StopEmgImd(cardConnectNo);

        }


        /// <summary>
        /// 位置清除，清除状态监控中的轴指令位置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button8_Click(object sender, EventArgs e)
        {
            ushort axis0 = Convert.ToUInt16(numericUpDown2.Value);
            ushort axis1 = Convert.ToUInt16(numericUpDown3.Value);
            ushort axis2 = Convert.ToUInt16(numericUpDown4.Value);

            //指令位置清零
            RTMC.MC_SetAxisCmdPos(cardConnectNo, axis0, 0);
            RTMC.MC_SetAxisCmdPos(cardConnectNo, axis1, 0);
            RTMC.MC_SetAxisCmdPos(cardConnectNo, axis2, 0);

        }

        /// <summary>
        /// 轴号值改变时事件
        /// 更改状态监控中的轴号显示
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void numericUpDown2_ValueChanged(object sender, EventArgs e)
        {
            NumericUpDown useControl = (sender as NumericUpDown);
            string numericUpDownName = useControl.Name;
            switch (numericUpDownName)
            {
                case "numericUpDown2":
                    groupBox4.Text = "轴" + useControl.Value;
                    break;
                case "numericUpDown3":
                    groupBox3.Text = "轴" + useControl.Value;
                    break;
                case "numericUpDown4":
                    groupBox5.Text = "轴" + useControl.Value;
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 定时器，用于更新界面的状态监控信息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer1_Tick(object sender, EventArgs e)
        {
            ushort axis0 = Convert.ToUInt16(numericUpDown2.Value);
            ushort axis1 = Convert.ToUInt16(numericUpDown3.Value);
            ushort axis2 = Convert.ToUInt16(numericUpDown4.Value);

            double cmdPos = 0;
            double cmdSpeed = 0;
            ushort checkDone = 1;
            //轴x
            RTMC.MC_GetAxisCmdSpeed(cardConnectNo, axis0, ref cmdSpeed); //获取当前指令速度
            textBox1.Text = cmdSpeed.ToString();

            RTMC.MC_GetAxisCmdPos(cardConnectNo, axis0, ref cmdPos);//获取当前指令位置
            textBox2.Text = cmdPos.ToString();

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

            //轴y
            RTMC.MC_GetAxisCmdSpeed(cardConnectNo, axis1, ref cmdSpeed); //获取当前指令速度
            textBox6.Text = cmdSpeed.ToString();

            RTMC.MC_GetAxisCmdPos(cardConnectNo, axis1, ref cmdPos);//获取当前指令位置
            textBox4.Text = cmdPos.ToString();

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

            //轴z
            RTMC.MC_GetAxisCmdSpeed(cardConnectNo, axis1, ref cmdSpeed); //获取当前指令速度
            textBox9.Text = cmdSpeed.ToString();

            RTMC.MC_GetAxisCmdPos(cardConnectNo, axis1, ref cmdPos);//获取当前指令位置
            textBox7.Text = cmdPos.ToString();

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