예제 #1
0
        private void AutoGrab3DOF(object obj)
        {
            if3DOF = true;
            string str = obj as string;

            fileOperations.GetSetoff(str, out double x, out double y, out int flag, out int id);

            InverseKinematics.Transformation(new double[3] {
                x, y, -8.5
            }, 90, 12.4, -9, out double[] newsetoff);
            try
            {
                if (serialPort1.IsOpen)
                {
                    controller.ArriveSetoff3DOF(newsetoff[0], newsetoff[1], 4, 1);//吸住前过中间点
                    bool ifsol = controller.ArriveSetoff3DOF(newsetoff[0], newsetoff[1], newsetoff[2], 1);
                    if (ifsol)
                    {
                        controller.SuckUp();
                        controller.ArriveSetoff3DOF(10, -10, 10, 1); //吸住后过中间点

                        controller.ArriveSetoff3DOF(0, -15, -3, 1);  //吸住后放置到目标点
                        fileOperations.WriteTxt("flag", "1");
                        Thread.Sleep(200);
                        controller.SuckDown();
                    }
                    AutoGrab_tag3 = 1;
                    if3DOF        = false;
                }
            }
            catch (Exception ex)
            {
                serialPort1.Close();
                //捕获到异常,创建一个新的对象,之前的不可以再用
                serialPort1 = new System.IO.Ports.SerialPort();
                //刷新COM口选项
                comboBox1.Items.Clear();
                comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
                //响铃并显示异常给用户
                System.Media.SystemSounds.Beep.Play();
                button_3DOF.Text      = "连接小手";
                button_3DOF.BackColor = Color.ForestGreen;
                MessageBox.Show(ex.Message);
                comboBox1.Enabled = true;
                if3DOF            = false;
            }
        }
예제 #2
0
        public bool ArriveSetoff3DOF(double x, double y, double z, int mod)  //模式0为顺序执行,模式1为一起执行
        {
            bool ifsol = InverseKinematics.IK3DOF(x, y, z, out joint3DOF);

            if (ifsol)
            {
                if (mod == 0)
                {
                    SortOrderRun3DOF(joint3DOF, ref lastJoint3DOF);
                }
                else
                {
                    TogetherRun3DOF(joint3DOF, ref lastJoint3DOF);
                }
            }
            else
            {
                lastJoint3DOF = joint3DOF;
            }
            return(ifsol);
        }
예제 #3
0
        public bool ArriveSetoff4DOF_level(double x, double y, double z, int mod)  //模式0为顺序执行,模式1为一起执行
        {
            bool ifsol = InverseKinematics.IK4DOF_level(x, y, z, out joint4DOF_level);

            if (ifsol)
            {
                if (mod == 0)
                {
                    TogetherRun4DOF(joint4DOF_level, 50, ref lastJoint4DOF);
                }
                else
                {
                    TogetherRun4DOF(joint4DOF_level, 16, ref lastJoint4DOF);
                }
            }
            else
            {
                lastJoint4DOF = joint4DOF_level;
            }
            return(ifsol);
        }
예제 #4
0
        public bool ArriveSetoff4DOF_level_con(double x, double y, double z, int mod)  //模式0为顺序执行,模式1为一起执行
        {
            bool ifsol = InverseKinematics.IK4DOF_level(x, y, z, out joint4DOF_level);

            joint4DOF_level[1] -= 10;
            joint4DOF_level[2] -= 10;
            joint4DOF_level[3] -= 1;
            if (ifsol)
            {
                if (mod == 0)
                {
                    SortOrderRun4DOF(joint4DOF_level, ref lastJoint4DOF);
                }
                else
                {
                    TogetherRun4DOF_con(joint4DOF_level, ref lastJoint4DOF);
                }
            }
            else
            {
                lastJoint4DOF = joint4DOF_level;
            }
            return(ifsol);
        }
예제 #5
0
        private void Circle()//画圈
        {
            con = false;
            InverseKinematics.Transformation(new double[3] {
                12.4, 15, -6
            }, -90, 12.4, 38, out double[] newsetoff);
            controller.ArriveSetoff4DOF_level_con(newsetoff[0], newsetoff[1], newsetoff[2], 1);
            Thread.Sleep(1500);
            InverseKinematics.Transformation(new double[3] {
                12.4, 15, -1.5
            }, 90, 12.4, -9, out newsetoff);
            controller.ArriveSetoff3DOF(newsetoff[0], newsetoff[1], newsetoff[2], 1);


            InverseKinematics.Transformation(new double[3] {
                16.8, 13.7, -6
            }, -90, 12.4, 38, out newsetoff);
            controller.ArriveSetoff4DOF_level_con(newsetoff[0], newsetoff[1], newsetoff[2], 1);
            InverseKinematics.Transformation(new double[3] {
                16.8, 13.7, -1.5
            }, 90, 12.4, -9, out newsetoff);
            controller.ArriveSetoff3DOF(newsetoff[0], newsetoff[1], newsetoff[2], 1);
            //Thread.Sleep(1000);

            InverseKinematics.Transformation(new double[3] {
                18.6, 9.3, -6
            }, -90, 12.4, 38, out newsetoff);
            controller.ArriveSetoff4DOF_level_con(newsetoff[0], newsetoff[1], newsetoff[2], 1);
            InverseKinematics.Transformation(new double[3] {
                18.6, 9.3, -1.5
            }, 90, 12.4, -9, out newsetoff);
            controller.ArriveSetoff3DOF(newsetoff[0], newsetoff[1], newsetoff[2], 1);
            //Thread.Sleep(1000);

            InverseKinematics.Transformation(new double[3] {
                16.8, 4.9, -6
            }, -90, 12.4, 38, out newsetoff);
            controller.ArriveSetoff4DOF_level_con(newsetoff[0], newsetoff[1], newsetoff[2], 1);
            InverseKinematics.Transformation(new double[3] {
                16.8, 4.9, -1.5
            }, 90, 12.4, -9, out newsetoff);
            controller.ArriveSetoff3DOF(newsetoff[0], newsetoff[1], newsetoff[2], 1);
            //Thread.Sleep(1000);

            InverseKinematics.Transformation(new double[3] {
                12.4, 3, -6
            }, -90, 12.4, 38, out newsetoff);
            controller.ArriveSetoff4DOF_level_con(newsetoff[0], newsetoff[1], newsetoff[2], 1);
            InverseKinematics.Transformation(new double[3] {
                12.4, 3, -1.5
            }, 90, 12.4, -9, out newsetoff);
            controller.ArriveSetoff3DOF(newsetoff[0], newsetoff[1], newsetoff[2], 1);
            //Thread.Sleep(1000);

            InverseKinematics.Transformation(new double[3] {
                8, 4.9, -6
            }, -90, 12.4, 38, out newsetoff);
            controller.ArriveSetoff4DOF_level_con(newsetoff[0], newsetoff[1], newsetoff[2], 1);
            InverseKinematics.Transformation(new double[3] {
                8, 4.9, -1.5
            }, 90, 12.4, -9, out newsetoff);
            controller.ArriveSetoff3DOF(newsetoff[0], newsetoff[1], newsetoff[2], 1);
            //Thread.Sleep(1000);

            InverseKinematics.Transformation(new double[3] {
                6.2, 9.3, -6
            }, -90, 12.4, 38, out newsetoff);
            controller.ArriveSetoff4DOF_level_con(newsetoff[0], newsetoff[1], newsetoff[2], 1);
            InverseKinematics.Transformation(new double[3] {
                6.2, 9.3, -1.5
            }, 90, 12.4, -9, out newsetoff);
            controller.ArriveSetoff3DOF(newsetoff[0], newsetoff[1], newsetoff[2], 1);
            //Thread.Sleep(1000);

            InverseKinematics.Transformation(new double[3] {
                8, 13.7, -6
            }, -90, 12.4, 38, out newsetoff);
            controller.ArriveSetoff4DOF_level_con(newsetoff[0], newsetoff[1], newsetoff[2], 1);
            InverseKinematics.Transformation(new double[3] {
                8, 13.7, -1.5
            }, 90, 12.4, -9, out newsetoff);
            controller.ArriveSetoff3DOF(newsetoff[0], newsetoff[1], newsetoff[2], 1);
            //Thread.Sleep(1000);

            InverseKinematics.Transformation(new double[3] {
                12.4, 15, -6
            }, -90, 12.4, 38, out newsetoff);
            controller.ArriveSetoff4DOF_level_con(newsetoff[0], newsetoff[1], newsetoff[2], 1);
            InverseKinematics.Transformation(new double[3] {
                12.4, 15, -1.5
            }, 90, 12.4, -9, out newsetoff);
            controller.ArriveSetoff3DOF(newsetoff[0], newsetoff[1], newsetoff[2], 1);
            //Thread.Sleep(1000);

            con = true;

            controller.ArriveSetoff3DOF(0, -19, 12, 1);//手臂躲到旁边
            controller.ArriveSetoff4DOF_downward(0, 0, 37, 1);
        }
예제 #6
0
        private void PourWater()  //倒水
        {
            double x = 0, y = 0;
            int    mod  = 3;
            int    flag = 0;

            double[] newsetoff1 = new double[3] {
                0, 0, 0
            };
            while (flag == 0)
            {
                string mod_str = fileOperations.ReadTxt("mod");
                fileOperations.GetSetoff(mod_str, out mod);
                if (mod == 0)
                {
                    Application.ExitThread(); break;
                }
                textBox_chess.Text = fileOperations.ReadTxt("setoff");
                fileOperations.GetSetoff(textBox_chess.Text, out x, out y, out flag, out int id);
            }

            if (flag == 1)
            {
                controller.Openhand();
                PourWaterInit();
                fileOperations.WriteTxt("setoff", "0,0,0,0");
                InverseKinematics.Transformation(new double[3] {
                    x, y, 0
                }, -90, 12.4, 38, out double[] newsetoff);
                try
                {
                    bool ifsol = controller.ArriveSetoff4DOF_level(newsetoff[0], newsetoff[1], 0, 1);

                    controller.Closehand();
                    if (ifsol)
                    {
                        PourWaterMid();

                        //controller.ArriveSetoff4DOF_level(26.5, 0, 10.5, 1);
                        fileOperations.WriteTxt("flagg", "1");
                        int    flag1 = 0;
                        double x1    = 0;
                        double y1    = 0;

                        while (flag1 == 0)
                        {
                            textBox_chess.Text = fileOperations.ReadTxt("setoff");
                            fileOperations.GetSetoff(textBox_chess.Text, out x1, out y1, out flag1, out int id);
                            string mod_str = fileOperations.ReadTxt("mod");
                            fileOperations.GetSetoff(mod_str, out mod);
                            if (mod == 0)
                            {
                                Application.ExitThread(); break;
                            }
                        }
                        if (mod != 0)
                        {
                            fileOperations.WriteTxt("setoff", "0,0,0,0");
                            InverseKinematics.Transformation(new double[3] {
                                x1, y1, 0
                            }, -90, 12.4, 38, out newsetoff1);
                            bool ifsol2 = controller.ArriveSetoff4DOF_level(newsetoff1[0] - 2.5, newsetoff1[1] - 14, 9, 1);
                            if (ifsol2)
                            {
                                controller.Sideturn();
                                Thread.Sleep(1000);
                                controller.Levelturn();

                                // controller.ArriveSetoff4DOF_level(23, 0, 0, 1);
                            }
                            controller.ArriveSetoff4DOF_level(newsetoff[0], newsetoff[1], 0, 1);
                        }
                    }
                    if (mod != 0)
                    {
                        controller.Openhand();
                        PourWaterInit();
                        PourWaterEndM();
                        controller.Openhand();
                        bool ifsol2 = controller.ArriveSetoff4DOF_level(newsetoff1[0], newsetoff1[1], 0, 0);
                        controller.Closehand();
                        controller.ArriveSetoff4DOF_level(newsetoff1[0], newsetoff1[1], 3, 0);
                        controller.ArriveSetoff4DOF_level(newsetoff1[0], newsetoff1[1], 6, 0);

                        controller.ArriveSetoff4DOF_level(10, 23, 4, 0);
                        controller.ArriveSetoff4DOF_level(10, 23, 0, 0);
                        controller.Openhand();
                        PourWaterEndend();
                        controller.ArriveSetoff4DOF_downward(0, 0, 37, 1);
                        controller.Closehand();
                    }
                    fileOperations.WriteTxt("ifend", "1");
                }
                catch (Exception ex)
                {
                    serialPort2.Close();
                    //捕获到异常,创建一个新的对象,之前的不可以再用
                    serialPort2 = new System.IO.Ports.SerialPort();
                    //刷新COM口选项
                    comboBox2.Items.Clear();
                    comboBox2.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
                    //响铃并显示异常给用户
                    System.Media.SystemSounds.Beep.Play();
                    button_4DOF.Text      = "连接大手";
                    button_4DOF.BackColor = Color.ForestGreen;
                    MessageBox.Show(ex.Message);
                    comboBox2.Enabled = true;
                }
            }
        }
예제 #7
0
        private void RemoteControl()  //遥控
        {
            double[] goalsetoff = new double[3] {
                0, 0, 0
            };
            double goalx = 0, goaly = 0;
            int    flag1 = 0;
            int    counter = 0, tag = 0;

            while (flag1 == 0)
            {
                fileOperations.GetSetoff(fileOperations.ReadTxt("mod"), out int mod); if (mod == 0)
                {
                    Application.ExitThread(); break;
                }
                textBox_send.Text = fileOperations.ReadTxt("cupsetoff");
                fileOperations.GetSetoff(textBox_send.Text, out goalx, out goaly, out flag1, out int id);
                Thread.Sleep(100);
            }
            fileOperations.WriteTxt("cupsetoff", "0,0,0,0");
            InverseKinematics.Transformation(new double[3] {
                goalx, goaly, -1
            }, 90, 12.4, -9, out goalsetoff);
            while (serialPort2.IsOpen || serialPort1.IsOpen)
            {
                fileOperations.GetSetoff(fileOperations.ReadTxt("mod"), out int mod); if (mod == 0)
                {
                    Application.ExitThread(); break;
                }
                textBox_send.Text = fileOperations.ReadTxt("setoff");
                fileOperations.GetSetoff(textBox_send.Text, out double x, out double y, out int flag, out int id);
                if (flag == 1)
                {
                    counter = 0;
                    fileOperations.WriteTxt("setoff", "0,0,0,0");
                    InverseKinematics.Transformation(new double[3] {
                        x, y, -7.8
                    }, 90, 12.4, -9, out double[] newsetoff);
                    try
                    {
                        if (serialPort1.IsOpen)
                        {
                            controller.ArriveSetoff3DOF(newsetoff[0], newsetoff[1], -1, 1);//吸前过中间点
                            bool ifsol = controller.ArriveSetoff3DOF(newsetoff[0], newsetoff[1], newsetoff[2], 1);
                            if (ifsol)
                            {
                                controller.SuckUp();
                                controller.ArriveSetoff3DOF(newsetoff[0], newsetoff[1], -1, 1);              //吸前过中间点
                                controller.ArriveSetoff3DOF(goalsetoff[0], goalsetoff[1], goalsetoff[2], 1); //吸住后放置到目标点
                                Thread.Sleep(500);
                                controller.SuckDown();
                                controller.ArriveSetoff3DOF(13, 0, -1, 1);//吸住后过中间点
                            }
                            fileOperations.WriteTxt("flag", "1");
                            tag = 1;
                        }
                    }
                    catch (Exception ex)
                    {
                        serialPort1.Close();
                        //捕获到异常,创建一个新的对象,之前的不可以再用
                        serialPort1 = new System.IO.Ports.SerialPort();
                        //刷新COM口选项
                        comboBox1.Items.Clear();
                        comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
                        //响铃并显示异常给用户
                        System.Media.SystemSounds.Beep.Play();
                        button_3DOF.Text      = "连接小手";
                        button_3DOF.BackColor = Color.ForestGreen;
                        MessageBox.Show(ex.Message);
                        comboBox1.Enabled = true;
                    }
                }
                if (tag == 1)
                {
                    counter++;
                    Thread.Sleep(50);
                }
                if (counter > 30)
                {
                    tag     = 0;
                    counter = 0;
                    fileOperations.WriteTxt("ifend", "1");
                }
            }
        }
예제 #8
0
        private void AutoGrab4DOF(object obj)
        {
            if4DOF = true;
            double goalx = -12;
            double goaly = 20;
            double goalz = 10;  //目标
            string str   = obj as string;

            fileOperations.GetSetoff(str, out double x, out double y, out int flag, out int id);

            InverseKinematics.Transformation(new double[3] {
                x, y, -4
            }, -90, 12.4, 38, out double[] newsetoff);
            try
            {
                if (serialPort2.IsOpen)
                {
                    if (newsetoff[1] >= 0)
                    {
                        newsetoff[1] = newsetoff[1] + 2;
                    }
                    if (newsetoff[1] < 0)
                    {
                        newsetoff[1] = newsetoff[1] - 1.4;
                    }

                    bool ifsol = controller.ArriveSetoff4DOF_downward(newsetoff[0], newsetoff[1], 0, 1);
                    if (!ifsol)
                    {
                        label6.Text = "无解";
                    }
                    else
                    {
                        label6.Text = "正常运行";
                        DisplayJoint(controller.joint4DOF_downward);
                        controller.Closehand();
                        bool ifsol1 = controller.ArriveSetoff4DOF_downward(newsetoff[0], newsetoff[1], 20, 1);
                        if (!ifsol1)
                        {
                            controller.ArriveSetoff4DOF_downward(0, 0, 37, 1);
                        }
                        controller.ArriveSetoff4DOF_downward(10, 17, 20, 1);
                        fileOperations.WriteTxt("flag", "1");
                        con = false;
                        controller.ArriveSetoff4DOF_downward(goalx, goaly, 20, 1);
                        con = true;
                        controller.ArriveSetoff4DOF_downward(goalx, goaly, goalz, 1);
                        controller.Openhand();
                        controller.ArriveSetoff4DOF_downward(goalx, goaly, 20, 1);
                        controller.ArriveSetoff4DOF_downward(0, 0, 37, 1);
                    }

                    AutoGrab_tag4 = 1;
                    if4DOF        = false;
                }
            }
            catch (Exception ex)
            {
                serialPort2.Close();
                //捕获到异常,创建一个新的对象,之前的不可以再用
                serialPort2 = new System.IO.Ports.SerialPort();
                //刷新COM口选项
                comboBox2.Items.Clear();
                comboBox2.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
                //响铃并显示异常给用户
                System.Media.SystemSounds.Beep.Play();
                button_4DOF.Text      = "连接小手";
                button_4DOF.BackColor = Color.ForestGreen;
                MessageBox.Show(ex.Message);
                comboBox2.Enabled = true;
                if4DOF            = false;
            }
        }
예제 #9
0
        public static bool IK4DOF_downward(double x, double y, double z, out double[] jointAngle4DOF) //机械臂逆解
        {
            double a, b;                                                                              //中间变量

            jointAngle4DOF = new double[4];
            double L1 = 10.5, L2 = 13.5, L3 = 13, error = 1;
            double m, n, t, q, p;  //中间变量
            double x1, y1, z1, yy; //逆解后正解的值,用以验证
            double ANG2RED = 3.1415926535898 / 180.0;

            double[,] temp = new double[300, 3];
            double maxj3 = 0; //存放最大角度
            int    u = 0;     //i为有无解标志位,u为有无精确解标志位
            int    counter = 0, maxcounter = 0;
            // if (((Math.Pow(x, 2) + Math.Pow(y, 2) + Math.Pow(z, 2)) > Math.Pow(L1 + L2 + L3, 2))) printf("超出范围");
            bool ifsol = false;

            jointAngle4DOF[0] = Math.Atan2(y, x);
            b = InverseKinematics.RAD2ANG(jointAngle4DOF[0]);
            a = x / Math.Cos(jointAngle4DOF[0]);
            if (x == 0)
            {
                a = y;
            }
            b = z;
            for (jointAngle4DOF[1] = -90; jointAngle4DOF[1] < 90; jointAngle4DOF[1]++)
            {
                jointAngle4DOF[1] *= ANG2RED;
                double temp1 = (Math.Pow(a, 2) + Math.Pow(b, 2) + Math.Pow(L1, 2) - Math.Pow(L2, 2) - Math.Pow(L3, 2) - 2 * a * L1 * Math.Sin(jointAngle4DOF[1]) - 2 * b * L1 * Math.Cos(jointAngle4DOF[1])) / (2 * L2 * L3);
                if (Math.Abs(temp1) <= 1)
                {
                    jointAngle4DOF[3] = Math.Acos(temp1);
                    if (RAD2ANG(jointAngle4DOF[3]) >= 95 || RAD2ANG(jointAngle4DOF[3]) <= -135)
                    {
                        jointAngle4DOF[1] = InverseKinematics.RAD2ANG(jointAngle4DOF[1]); continue;
                    }
                    m = L2 * Math.Sin(jointAngle4DOF[1]) + L3 * Math.Sin(jointAngle4DOF[1]) * Math.Cos(jointAngle4DOF[3]) + L3 * Math.Cos(jointAngle4DOF[1]) * Math.Sin(jointAngle4DOF[3]);
                    n = L2 * Math.Cos(jointAngle4DOF[1]) + L3 * Math.Cos(jointAngle4DOF[1]) * Math.Cos(jointAngle4DOF[3]) - L3 * Math.Sin(jointAngle4DOF[1]) * Math.Sin(jointAngle4DOF[3]);
                    t = a - L1 * Math.Sin(jointAngle4DOF[1]);
                    p = Math.Pow(Math.Pow(n, 2) + Math.Pow(m, 2), 0.5);
                    q = Math.Asin(m / p);
                    jointAngle4DOF[2] = -(Math.Asin(t / p) - q);
                    if (Math.Abs(InverseKinematics.RAD2ANG(jointAngle4DOF[2])) >= 135)
                    {
                        jointAngle4DOF[1] = InverseKinematics.RAD2ANG(jointAngle4DOF[1]); continue;
                    }
                    x1 = (L1 * Math.Sin(jointAngle4DOF[1]) + L2 * Math.Sin(jointAngle4DOF[1] + jointAngle4DOF[2]) + L3 * Math.Sin(jointAngle4DOF[1] + jointAngle4DOF[2] + jointAngle4DOF[3])) * Math.Cos(jointAngle4DOF[0]);
                    y1 = (L1 * Math.Sin(jointAngle4DOF[1]) + L2 * Math.Sin(jointAngle4DOF[1] + jointAngle4DOF[2]) + L3 * Math.Sin(jointAngle4DOF[1] + jointAngle4DOF[2] + jointAngle4DOF[3])) * Math.Sin(jointAngle4DOF[0]);
                    z1 = L1 * Math.Cos(jointAngle4DOF[1]) + L2 * Math.Cos(jointAngle4DOF[1] + jointAngle4DOF[2]) + L3 * Math.Cos(jointAngle4DOF[1] + jointAngle4DOF[2] + jointAngle4DOF[3]);

                    jointAngle4DOF[1] = InverseKinematics.RAD2ANG(jointAngle4DOF[1]);
                    jointAngle4DOF[2] = InverseKinematics.RAD2ANG(jointAngle4DOF[2]);
                    jointAngle4DOF[3] = InverseKinematics.RAD2ANG(jointAngle4DOF[3]);
                    if (x1 < (x + 0.5) && x1 > (x - 0.5) && y1 < (y + 0.5) && y1 > (y - 0.5) && z1 < (z + 0.5) && z1 > (z - 0.5))
                    {
                        counter++;
                        ifsol = true;
                        u     = 1;
                        for (int k = 0; k < 3; k++)
                        {
                            temp[counter, k] = jointAngle4DOF[k + 1];
                        }
                        if (temp[counter, 2] > (maxj3))
                        {
                            maxj3      = temp[counter, 2];
                            maxcounter = counter;
                        }
                    }
                }
                else
                {
                    jointAngle4DOF[1] = RAD2ANG(jointAngle4DOF[1]);
                }
            }

            for (jointAngle4DOF[1] = -90; jointAngle4DOF[1] < 90; jointAngle4DOF[1]++)
            {
                jointAngle4DOF[1] *= ANG2RED;
                double temp1 = (Math.Pow(a, 2) + Math.Pow(b, 2) + Math.Pow(L1, 2) - Math.Pow(L2, 2) - Math.Pow(L3, 2) - 2 * a * L1 * Math.Sin(jointAngle4DOF[1]) - 2 * b * L1 * Math.Cos(jointAngle4DOF[1])) / (2 * L2 * L3);
                if (Math.Abs(temp1) <= 1)
                {
                    jointAngle4DOF[3] = Math.Acos(temp1);
                    if (RAD2ANG(jointAngle4DOF[3]) >= 95 || RAD2ANG(jointAngle4DOF[3]) <= -135)
                    {
                        jointAngle4DOF[1] = InverseKinematics.RAD2ANG(jointAngle4DOF[1]); continue;
                    }
                    m = L2 * Math.Sin(jointAngle4DOF[1]) + L3 * Math.Sin(jointAngle4DOF[1]) * Math.Cos(jointAngle4DOF[3]) + L3 * Math.Cos(jointAngle4DOF[1]) * Math.Sin(jointAngle4DOF[3]);
                    n = L2 * Math.Cos(jointAngle4DOF[1]) + L3 * Math.Cos(jointAngle4DOF[1]) * Math.Cos(jointAngle4DOF[3]) - L3 * Math.Sin(jointAngle4DOF[1]) * Math.Sin(jointAngle4DOF[3]);
                    t = a - L1 * Math.Sin(jointAngle4DOF[1]);
                    p = Math.Pow(Math.Pow(n, 2) + Math.Pow(m, 2), 0.5);
                    q = ANG2RAD(180) - Math.Asin(m / p);
                    jointAngle4DOF[2] = -(Math.Asin(t / p) - q);
                    if (Math.Abs(InverseKinematics.RAD2ANG(jointAngle4DOF[2])) >= 135)
                    {
                        jointAngle4DOF[1] = InverseKinematics.RAD2ANG(jointAngle4DOF[1]); continue;
                    }
                    x1 = (L1 * Math.Sin(jointAngle4DOF[1]) + L2 * Math.Sin(jointAngle4DOF[1] + jointAngle4DOF[2]) + L3 * Math.Sin(jointAngle4DOF[1] + jointAngle4DOF[2] + jointAngle4DOF[3])) * Math.Cos(jointAngle4DOF[0]);
                    y1 = (L1 * Math.Sin(jointAngle4DOF[1]) + L2 * Math.Sin(jointAngle4DOF[1] + jointAngle4DOF[2]) + L3 * Math.Sin(jointAngle4DOF[1] + jointAngle4DOF[2] + jointAngle4DOF[3])) * Math.Sin(jointAngle4DOF[0]);
                    z1 = L1 * Math.Cos(jointAngle4DOF[1]) + L2 * Math.Cos(jointAngle4DOF[1] + jointAngle4DOF[2]) + L3 * Math.Cos(jointAngle4DOF[1] + jointAngle4DOF[2] + jointAngle4DOF[3]);

                    jointAngle4DOF[1] = InverseKinematics.RAD2ANG(jointAngle4DOF[1]);
                    jointAngle4DOF[2] = InverseKinematics.RAD2ANG(jointAngle4DOF[2]);
                    jointAngle4DOF[3] = InverseKinematics.RAD2ANG(jointAngle4DOF[3]);
                    if (x1 < (x + 0.5) && x1 > (x - 0.5) && y1 < (y + 0.5) && y1 > (y - 0.5) && z1 < (z + 0.5) && z1 > (z - 0.5))
                    {
                        counter++;
                        ifsol = true;
                        u     = 1;
                        for (int k = 0; k < 3; k++)
                        {
                            temp[counter, k] = jointAngle4DOF[k + 1];
                        }
                        if (temp[counter, 2] > (maxj3))
                        {
                            maxj3      = temp[counter, 2];
                            maxcounter = counter;
                        }
                    }
                }
                else
                {
                    jointAngle4DOF[1] = RAD2ANG(jointAngle4DOF[1]);
                }
            }

            jointAngle4DOF[0] = InverseKinematics.RAD2ANG(jointAngle4DOF[0]);
            if (u == 1) //有解选取j1最小的
            {
                jointAngle4DOF[1] = temp[maxcounter, 0];
                jointAngle4DOF[2] = temp[maxcounter, 1];
                jointAngle4DOF[3] = temp[maxcounter, 2];
            }
            return(ifsol);
        }
예제 #10
0
        public static bool IK4DOF_level(double x, double y, double z, out double[] jointAngle4DOF) //机械臂逆解
        {
            double a, b;                                                                           //中间变量

            double [] jointAngle4DOFtemp = new double[4];
            jointAngle4DOF = new double[4];
            double L1 = 10.5, L2 = 13.5, L3 = 13, error = 1;
            double m, n, t, q, p; //中间变量
            double x1, y1, z1;    //逆解后正解的值,用以验证
            double ANG2RED = 3.1415926535898 / 180.0;
            int    u       = 0;   //i为有无解标志位,u为有无精确解标志位
            // if (((Math.Pow(x, 2) + Math.Pow(y, 2) + Math.Pow(z, 2)) > Math.Pow(L1 + L2 + L3, 2))) printf("超出范围");
            bool ifsol = false;

            jointAngle4DOFtemp[0] = Math.Atan2(y, x);
            b = InverseKinematics.RAD2ANG(jointAngle4DOFtemp[0]);
            a = x / Math.Cos(jointAngle4DOFtemp[0]);
            if (x == 0)
            {
                a = y;
            }
            b = z;
            for (jointAngle4DOFtemp[1] = -90; jointAngle4DOFtemp[1] < 90; jointAngle4DOFtemp[1]++)
            {
                jointAngle4DOFtemp[1] *= ANG2RED;
                double temp1 = (Math.Pow(a, 2) + Math.Pow(b, 2) + Math.Pow(L1, 2) - Math.Pow(L2, 2) - Math.Pow(L3, 2) - 2 * a * L1 * Math.Sin(jointAngle4DOFtemp[1]) - 2 * b * L1 * Math.Cos(jointAngle4DOFtemp[1])) / (2 * L2 * L3);
                if (Math.Abs(temp1) <= 1)
                {
                    jointAngle4DOFtemp[3] = -Math.Acos(temp1);
                    if (Math.Abs(InverseKinematics.RAD2ANG(jointAngle4DOFtemp[3])) >= 135)
                    {
                        jointAngle4DOFtemp[1] = InverseKinematics.RAD2ANG(jointAngle4DOFtemp[1]); continue;
                    }
                    m = L2 * Math.Sin(jointAngle4DOFtemp[1]) + L3 * Math.Sin(jointAngle4DOFtemp[1]) * Math.Cos(jointAngle4DOFtemp[3]) + L3 * Math.Cos(jointAngle4DOFtemp[1]) * Math.Sin(jointAngle4DOFtemp[3]);
                    n = L2 * Math.Cos(jointAngle4DOFtemp[1]) + L3 * Math.Cos(jointAngle4DOFtemp[1]) * Math.Cos(jointAngle4DOFtemp[3]) - L3 * Math.Sin(jointAngle4DOFtemp[1]) * Math.Sin(jointAngle4DOFtemp[3]);
                    t = a - L1 * Math.Sin(jointAngle4DOFtemp[1]);
                    p = Math.Pow(Math.Pow(n, 2) + Math.Pow(m, 2), 0.5);
                    q = ANG2RAD(180) - Math.Asin(m / p);
                    jointAngle4DOFtemp[2] = -(Math.Asin(t / p) - q);
                    if (Math.Abs(InverseKinematics.RAD2ANG(jointAngle4DOFtemp[2])) >= 135)
                    {
                        jointAngle4DOFtemp[1] = InverseKinematics.RAD2ANG(jointAngle4DOFtemp[1]); continue;
                    }
                    x1 = (L1 * Math.Sin(jointAngle4DOFtemp[1]) + L2 * Math.Sin(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2]) + L3 * Math.Sin(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2] + jointAngle4DOFtemp[3])) * Math.Cos(jointAngle4DOFtemp[0]);
                    y1 = (L1 * Math.Sin(jointAngle4DOFtemp[1]) + L2 * Math.Sin(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2]) + L3 * Math.Sin(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2] + jointAngle4DOFtemp[3])) * Math.Sin(jointAngle4DOFtemp[0]);
                    z1 = L1 * Math.Cos(jointAngle4DOFtemp[1]) + L2 * Math.Cos(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2]) + L3 * Math.Cos(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2] + jointAngle4DOFtemp[3]);

                    jointAngle4DOFtemp[1] = InverseKinematics.RAD2ANG(jointAngle4DOFtemp[1]);
                    jointAngle4DOFtemp[2] = InverseKinematics.RAD2ANG(jointAngle4DOFtemp[2]);
                    jointAngle4DOFtemp[3] = InverseKinematics.RAD2ANG(jointAngle4DOFtemp[3]);
                    if (Math.Abs(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2] + jointAngle4DOFtemp[3] - 90) < 3 && x1 <(x + 0.5) && x1> (x - 0.5) && y1 <(y + 0.5) && y1> (y - 0.5) && z1 <(z + 0.5) && z1> (z - 0.5))
                    {
                        ifsol             = true;
                        jointAngle4DOF[1] = jointAngle4DOFtemp[1];
                        jointAngle4DOF[2] = jointAngle4DOFtemp[2];
                        jointAngle4DOF[3] = jointAngle4DOFtemp[3];
                        break;
                    }

                    if (Math.Abs(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2] + jointAngle4DOFtemp[3] - 90) < 6 && x1 <(x + 0.5) && x1> (x - 0.5) && y1 <(y + 0.5) && y1> (y - 0.5) && z1 <(z + 0.5) && z1> (z - 0.5))
                    {
                        ifsol             = true;
                        jointAngle4DOF[1] = jointAngle4DOFtemp[1];
                        jointAngle4DOF[2] = jointAngle4DOFtemp[2];
                        jointAngle4DOF[3] = jointAngle4DOFtemp[3];
                        break;
                    }

                    if (Math.Abs(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2] + jointAngle4DOFtemp[3] - 90) < 10 && x1 <(x + 0.5) && x1> (x - 0.5) && y1 <(y + 0.5) && y1> (y - 0.5) && z1 <(z + 0.5) && z1> (z - 0.5))
                    {
                        ifsol             = true;
                        jointAngle4DOF[1] = jointAngle4DOFtemp[1];
                        jointAngle4DOF[2] = jointAngle4DOFtemp[2];
                        jointAngle4DOF[3] = jointAngle4DOFtemp[3];
                        break;
                    }
                }
                else
                {
                    jointAngle4DOFtemp[1] = RAD2ANG(jointAngle4DOFtemp[1]);
                }
            }

            /******************************************************/
            if (!ifsol)
            {
                for (jointAngle4DOFtemp[1] = -90; jointAngle4DOFtemp[1] < 90; jointAngle4DOFtemp[1]++)
                {
                    jointAngle4DOFtemp[1] *= ANG2RED;
                    double temp1 = (Math.Pow(a, 2) + Math.Pow(b, 2) + Math.Pow(L1, 2) - Math.Pow(L2, 2) - Math.Pow(L3, 2) - 2 * a * L1 * Math.Sin(jointAngle4DOFtemp[1]) - 2 * b * L1 * Math.Cos(jointAngle4DOFtemp[1])) / (2 * L2 * L3);
                    if (Math.Abs(temp1) <= 1)
                    {
                        jointAngle4DOFtemp[3] = Math.Acos(temp1);
                        if (Math.Abs(InverseKinematics.RAD2ANG(jointAngle4DOFtemp[3])) >= 135)
                        {
                            jointAngle4DOFtemp[1] = InverseKinematics.RAD2ANG(jointAngle4DOFtemp[1]); continue;
                        }
                        m = L2 * Math.Sin(jointAngle4DOFtemp[1]) + L3 * Math.Sin(jointAngle4DOFtemp[1]) * Math.Cos(jointAngle4DOFtemp[3]) + L3 * Math.Cos(jointAngle4DOFtemp[1]) * Math.Sin(jointAngle4DOFtemp[3]);
                        n = L2 * Math.Cos(jointAngle4DOFtemp[1]) + L3 * Math.Cos(jointAngle4DOFtemp[1]) * Math.Cos(jointAngle4DOFtemp[3]) - L3 * Math.Sin(jointAngle4DOFtemp[1]) * Math.Sin(jointAngle4DOFtemp[3]);
                        t = a - L1 * Math.Sin(jointAngle4DOFtemp[1]);
                        p = Math.Pow(Math.Pow(n, 2) + Math.Pow(m, 2), 0.5);
                        q = Math.Asin(m / p);
                        jointAngle4DOFtemp[2] = -(Math.Asin(t / p) - q);
                        if (Math.Abs(InverseKinematics.RAD2ANG(jointAngle4DOFtemp[2])) >= 135)
                        {
                            jointAngle4DOFtemp[1] = InverseKinematics.RAD2ANG(jointAngle4DOFtemp[1]); continue;
                        }
                        x1 = (L1 * Math.Sin(jointAngle4DOFtemp[1]) + L2 * Math.Sin(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2]) + L3 * Math.Sin(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2] + jointAngle4DOFtemp[3])) * Math.Cos(jointAngle4DOFtemp[0]);
                        y1 = (L1 * Math.Sin(jointAngle4DOFtemp[1]) + L2 * Math.Sin(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2]) + L3 * Math.Sin(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2] + jointAngle4DOFtemp[3])) * Math.Sin(jointAngle4DOFtemp[0]);
                        z1 = L1 * Math.Cos(jointAngle4DOFtemp[1]) + L2 * Math.Cos(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2]) + L3 * Math.Cos(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2] + jointAngle4DOFtemp[3]);

                        jointAngle4DOFtemp[1] = InverseKinematics.RAD2ANG(jointAngle4DOFtemp[1]);
                        jointAngle4DOFtemp[2] = InverseKinematics.RAD2ANG(jointAngle4DOFtemp[2]);
                        jointAngle4DOFtemp[3] = InverseKinematics.RAD2ANG(jointAngle4DOFtemp[3]);
                        if (Math.Abs(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2] + jointAngle4DOFtemp[3] - 90) < 3 && x1 <(x + 0.5) && x1> (x - 0.5) && y1 <(y + 0.5) && y1> (y - 0.5) && z1 <(z + 0.5) && z1> (z - 0.5))
                        {
                            ifsol             = true;
                            jointAngle4DOF[1] = jointAngle4DOFtemp[1];
                            jointAngle4DOF[2] = jointAngle4DOFtemp[2];
                            jointAngle4DOF[3] = jointAngle4DOFtemp[3];
                            break;
                        }

                        if (Math.Abs(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2] + jointAngle4DOFtemp[3] - 90) < 6 && x1 <(x + 0.5) && x1> (x - 0.5) && y1 <(y + 0.5) && y1> (y - 0.5) && z1 <(z + 0.5) && z1> (z - 0.5))
                        {
                            ifsol             = true;
                            jointAngle4DOF[1] = jointAngle4DOFtemp[1];
                            jointAngle4DOF[2] = jointAngle4DOFtemp[2];
                            jointAngle4DOF[3] = jointAngle4DOFtemp[3];
                            break;
                        }

                        if (Math.Abs(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2] + jointAngle4DOFtemp[3] - 90) < 10 && x1 <(x + 0.5) && x1> (x - 0.5) && y1 <(y + 0.5) && y1> (y - 0.5) && z1 <(z + 0.5) && z1> (z - 0.5))
                        {
                            ifsol             = true;
                            jointAngle4DOF[1] = jointAngle4DOFtemp[1];
                            jointAngle4DOF[2] = jointAngle4DOFtemp[2];
                            jointAngle4DOF[3] = jointAngle4DOFtemp[3];
                            break;
                        }
                    }
                    else
                    {
                        jointAngle4DOFtemp[1] = RAD2ANG(jointAngle4DOFtemp[1]);
                    }
                }
            }

            /******************************************************/
            if (!ifsol)
            {
                for (jointAngle4DOFtemp[1] = -90; jointAngle4DOFtemp[1] < 90; jointAngle4DOFtemp[1]++)
                {
                    jointAngle4DOFtemp[1] *= ANG2RED;
                    double temp1 = (Math.Pow(a, 2) + Math.Pow(b, 2) + Math.Pow(L1, 2) - Math.Pow(L2, 2) - Math.Pow(L3, 2) - 2 * a * L1 * Math.Sin(jointAngle4DOFtemp[1]) - 2 * b * L1 * Math.Cos(jointAngle4DOFtemp[1])) / (2 * L2 * L3);
                    if (Math.Abs(temp1) <= 1)
                    {
                        jointAngle4DOFtemp[3] = Math.Acos(temp1);
                        if (Math.Abs(InverseKinematics.RAD2ANG(jointAngle4DOFtemp[3])) >= 135)
                        {
                            jointAngle4DOFtemp[1] = InverseKinematics.RAD2ANG(jointAngle4DOFtemp[1]); continue;
                        }
                        m = L2 * Math.Sin(jointAngle4DOFtemp[1]) + L3 * Math.Sin(jointAngle4DOFtemp[1]) * Math.Cos(jointAngle4DOFtemp[3]) + L3 * Math.Cos(jointAngle4DOFtemp[1]) * Math.Sin(jointAngle4DOFtemp[3]);
                        n = L2 * Math.Cos(jointAngle4DOFtemp[1]) + L3 * Math.Cos(jointAngle4DOFtemp[1]) * Math.Cos(jointAngle4DOFtemp[3]) - L3 * Math.Sin(jointAngle4DOFtemp[1]) * Math.Sin(jointAngle4DOFtemp[3]);
                        t = a - L1 * Math.Sin(jointAngle4DOFtemp[1]);
                        p = Math.Pow(Math.Pow(n, 2) + Math.Pow(m, 2), 0.5);
                        q = ANG2RAD(180) - Math.Asin(m / p);
                        jointAngle4DOFtemp[2] = -(Math.Asin(t / p) - q);
                        if (Math.Abs(InverseKinematics.RAD2ANG(jointAngle4DOFtemp[2])) >= 135)
                        {
                            jointAngle4DOFtemp[1] = InverseKinematics.RAD2ANG(jointAngle4DOFtemp[1]); continue;
                        }
                        x1 = (L1 * Math.Sin(jointAngle4DOFtemp[1]) + L2 * Math.Sin(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2]) + L3 * Math.Sin(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2] + jointAngle4DOFtemp[3])) * Math.Cos(jointAngle4DOFtemp[0]);
                        y1 = (L1 * Math.Sin(jointAngle4DOFtemp[1]) + L2 * Math.Sin(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2]) + L3 * Math.Sin(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2] + jointAngle4DOFtemp[3])) * Math.Sin(jointAngle4DOFtemp[0]);
                        z1 = L1 * Math.Cos(jointAngle4DOFtemp[1]) + L2 * Math.Cos(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2]) + L3 * Math.Cos(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2] + jointAngle4DOFtemp[3]);

                        jointAngle4DOFtemp[1] = InverseKinematics.RAD2ANG(jointAngle4DOFtemp[1]);
                        jointAngle4DOFtemp[2] = InverseKinematics.RAD2ANG(jointAngle4DOFtemp[2]);
                        jointAngle4DOFtemp[3] = InverseKinematics.RAD2ANG(jointAngle4DOFtemp[3]);
                        if (Math.Abs(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2] + jointAngle4DOFtemp[3] - 90) < 3 && x1 <(x + 0.5) && x1> (x - 0.5) && y1 <(y + 0.5) && y1> (y - 0.5) && z1 <(z + 0.5) && z1> (z - 0.5))
                        {
                            ifsol             = true;
                            jointAngle4DOF[1] = jointAngle4DOFtemp[1];
                            jointAngle4DOF[2] = jointAngle4DOFtemp[2];
                            jointAngle4DOF[3] = jointAngle4DOFtemp[3];
                            break;
                        }

                        if (Math.Abs(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2] + jointAngle4DOFtemp[3] - 90) < 6 && x1 <(x + 0.5) && x1> (x - 0.5) && y1 <(y + 0.5) && y1> (y - 0.5) && z1 <(z + 0.5) && z1> (z - 0.5))
                        {
                            ifsol             = true;
                            jointAngle4DOF[1] = jointAngle4DOFtemp[1];
                            jointAngle4DOF[2] = jointAngle4DOFtemp[2];
                            jointAngle4DOF[3] = jointAngle4DOFtemp[3];
                            break;
                        }

                        if (Math.Abs(jointAngle4DOFtemp[1] + jointAngle4DOFtemp[2] + jointAngle4DOFtemp[3] - 90) < 10 && x1 <(x + 0.5) && x1> (x - 0.5) && y1 <(y + 0.5) && y1> (y - 0.5) && z1 <(z + 0.5) && z1> (z - 0.5))
                        {
                            ifsol             = true;
                            jointAngle4DOF[1] = jointAngle4DOFtemp[1];
                            jointAngle4DOF[2] = jointAngle4DOFtemp[2];
                            jointAngle4DOF[3] = jointAngle4DOFtemp[3];
                            break;
                        }
                    }
                    else
                    {
                        jointAngle4DOFtemp[1] = RAD2ANG(jointAngle4DOFtemp[1]);
                    }
                }
            }

            jointAngle4DOF[0] = InverseKinematics.RAD2ANG(jointAngle4DOFtemp[0]);
            return(ifsol);
        }