Inverz Kinematika

     Jó reggelt mindenkinek. Gyönyörű napra ébredtünk. A nap hétágra süt, a madarak meg torkukszakadtából csiripelnek. Tegnap éjjel befejeztem az inverz kinematika programom első verzióját. Persze dokumentálni még nem igazán volt időm. Viszont van róla videóm. ;)



     A forráskódot még ki kell egy kicsit kommentezzem, hogy ne csak nekem legyen érthető.

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 Inverz_k
{
    public partial class Form1 : Form
    {
        System.Drawing.Pen whitePen; //Pen - ezzel rajzoljuk a vonalakat
        System.Drawing.Pen myPen;    // azert kell ketto belole, hogy le is tudjuk torolni az addigi rajzot.
        System.Drawing.Brush myBrush;
        System.Drawing.Graphics pg,pg2; // ez a ket panel, amire rajzolunk
        int x0, y0, x1, y1, x2, y2; // a robotkarunk harom pontja. 
        int L1, L2;                 // a robotkar karjainak hossza
        int[] a,b,c,d,e,f;          // ezekben tarolom a kirajzolt objektum koordinatait
        double teta1, teta2, teta3; // ezekben taroljuk a szervok elfordulasi szoget radianban
        double teta1szog, teta2szog, teta3szog;  // itt meg a szogeket fokokban
        double valosteta1, valosteta2, valosteta3; // erre azert van szukseg, mert lehet, hogy alapbol eltolas van a szogben
        double alfa; // ez a szog, amit a robotkar vegpontja a kezdopont sikjaval bezar.
        double atfogo; // ez meg a kezdopont-vegpontot osszekoto szakasz hossza
        public Form1()
        {
            InitializeComponent();
            whitePen = new Pen(System.Drawing.Color.White,4); // feher ceruza. Ezzel torlunk
            myPen = new Pen(System.Drawing.Color.Red,4);      // piros ceruza. Ezzel rajzolunk
            myBrush = new SolidBrush(System.Drawing.Color.Black); // ez nemtudom mire van :-S
            a = new int[2]; //
            b = new int[2]; //
            c = new int[2]; //itt megmondjuk, hogy a pontoknak ket komponensuk van. Egy x es egy Y 
            d = new int[2]; // vagy felulnezetbol egy X es egy Z
            e = new int[2]; // vagy valami hasonlo
            f = new int[2]; //
            pg = panel1.CreateGraphics(); //bal oldali panel. erre rajzolunk
            pg2 = panel2.CreateGraphics(); // jobb oldali panel
            L1 = 100; // femur hossza. 
            L2 = 150; // tibia hossza (ask google)
            x0 = 0;   // kezdopont X
            y0 = panel1.Height / 3; // kezdopont Y
            x1 = x0 + L1;
            y1 = y0;
            x2 = x1;
            y2 = y1 + L2;
            a[0] = x0;      //beallitjuk a koordinatatengely x koordinatajat
            a[1] = y0;      //beallitjuk a koordinatatengely y koordinatajat
            b[0] = x1;
            b[1] = y1;
            c[0] = x2;
            c[1] = y2;
            d[0] = 0;
            d[1] = panel2.Height / 2;
            e[0] = b[0];
            e[1] = d[1];
            f[0] = c[0];
            f[1] = e[1];
//            k_transz(x0, y0);
        }
        private void k_transz(int x, int y) // transzformaciora azert van szukseg, mert a kepletem
        {                                   //ugy szol, hogy az alap a 0,0 pontban helyezkedik el
            a[0] -= x;      //beallitjuk a koordinatatengely x koordinatajat
            a[1] -= y;      //beallitjuk a koordinatatengely y koordinatajat
            b[0] -= x;
            b[1] -= y;
            c[0] -= x;
            c[1] -= y;
        }

        private void draw(Pen p)
        {
            try
            {
                k_transz(x0, y0); //transzponalunk
                calculate();      // szamolunk
                k_transz((-x0), (-y0)); // visszatranszponalunk

                //itt jon a sok sok rajzolas. Vonalak, korok, miegymas

                pg.DrawEllipse(p, a[0] - 5, a[1] - 5, 10, 10);
                pg.DrawLine(p, a[0], a[1], b[0], b[1]);
                pg.DrawEllipse(p, b[0] - 5, b[1] - 5, 10, 10);
                pg.DrawLine(p, b[0], b[1], c[0], c[1]);
                pg.DrawEllipse(p, c[0] - 5, c[1] - 5, 10, 10);

                pg2.DrawEllipse(p, d[0] - 5, d[1] - 5, 10, 10);
                pg2.DrawLine(p, d[0], d[1], e[0], e[1]);
                pg2.DrawEllipse(p, e[0] - 5, e[1] - 5, 10, 10);
                pg2.DrawLine(p, e[0], e[1], f[0], f[1]);
                pg2.DrawEllipse(p, f[0] - 5, f[1] - 5, 10, 10);

            }
            catch
            { 
                //hibakezeles. Nincs.
            }
        }

        private void calculate()
        { 
            //itt szamoljuk ki, hogy az egyes reszek milyen szogben kell alljanak.
            //elso ket sor hetedikes matek
            atfogo = Math.Sqrt(c[0]*c[0]+c[1]*c[1]);
            alfa = Math.Atan(c[1]/(double)c[0]);

            //koszinusz tetel, MIT OCV-ben megtalalhato a leirasa.
            teta1 = alfa - Math.Acos((double)(c[0] * c[0] + c[1] * c[1] + L1 * L1 - L2 * L2) / (double)(2 * L1 * Math.Sqrt(c[0]*c[0]+c[1]*c[1])));
            teta2 = (double)Math.PI - Math.Acos((double)(L1 * L1 + L2 * L2 - c[0] * c[0] - c[1] * c[1]) / (double)(2 * L1 * L2));

            //atalakitas radianbol fokba
            teta1szog = teta1 * 180 / (double)Math.PI;
            teta2szog = teta2 * 180 / (double)Math.PI;

            //eltolasok kiszamitasa
            valosteta1 = teta1szog;
            valosteta2 = teta2szog - 90;

            //eredmeny kiiratasa
            tb_teta1.Text = valosteta1.ToString();
            tb_teta2.Text = valosteta2.ToString();

            //pontok poziciojanak kiszamitasa
            b[0] = a[0] + (int)(Math.Cos(teta1) * L1);
            b[1] = a[1] + (int)(Math.Sin(teta1) * L1);

            e[0] = d[0] + (int)(Math.Cos(teta3) * b[0]);
            e[1] = d[1] + (int)(Math.Sin(teta3) * b[0]);

            f[0] = d[0] + (int)(Math.Cos(teta3) * c[0]);
            f[1] = d[1] + (int)(Math.Sin(teta3) * c[0]);

        }

        //itt kovetkezik egy par gomb esemeny. Ha kattintunk a felfele vagy lefele vagy
        //jobbra-balra nyilakra, akkor a megfelelo erteket noveljuk, majd ujrarajzoljuk 
        private void b_fel_Click(object sender, EventArgs e)
        {
            draw(whitePen); //letoroljuk a rajzlapot
            c[1] -= 1;      //frissitjuk az erteket
            draw(myPen);    //ujrarajzoljuk
        }

        private void b_le_Click(object sender, EventArgs e)
        {
            draw(whitePen);
            c[1] += 1;
            draw(myPen);
        }

        private void b_balra_Click(object sender, EventArgs e)
        {
            draw(whitePen);
            c[0] -= 1; 
            draw(myPen);
        }

        private void b_jobbra_Click(object sender, EventArgs e)
        {
            draw(whitePen);
            c[0] += 1;
            draw(myPen);
        }

        //egeresemeny. Ha lenyomott egergombot huzom a panel folott, akkor jon ez. 
        //ez a bal oldali rajzlapon
        private void panel1_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left) //le van-e nyomva az eger?
            {
                draw(whitePen);//torol

                c[0] = e.X;  //frissit
                c[1] = e.Y;

                draw(myPen);   //rajzol
            }
        }

        //egeresemeny jobb oldali rajzlapon
        private void panel2_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                draw(whitePen);

                teta3 = Math.Atan((double)(e.Y-d[1]) / (double)(e.X-d[0])); // szamolunk
                c[0] = (int)Math.Sqrt((e.X)*(e.X)+(e.Y-d[1])*(e.Y-d[1])); //frissitunk
                teta3szog = teta3 * 180 / (double)Math.PI;
                tb_teta3.Text = teta3szog.ToString();
                draw(myPen);//rajzolunk
            }
        }

        //megint egy par gomb, ezek a jobboldaliak. 
        //itt van egy kis kerekitesi hiba, vagyis ha felmegyek es utana le, nem jutok vissza a 
        //kiindulopontba. Ez a tizedesresz elhanyagolasa miatt van. 
        private void b_fel2_Click(object sender, EventArgs e)
        {
            draw(whitePen);
            f[1] -= 10;
            c[0] = (int)Math.Sqrt((f[0]) * (f[0]) + (f[1] - d[1]) * (f[1] - d[1]));//itt a kerekites.
            teta3 = Math.Atan((double)(f[1] - d[1]) / (double)(f[0] - d[0]));
            draw(myPen);
        }

        private void b_le2_Click(object sender, EventArgs e)
        {
            draw(whitePen);
            f[1] += 10;
            c[0] = (int)Math.Sqrt((f[0]) * (f[0]) + (f[1] - d[1]) * (f[1] - d[1]));
            teta3 = Math.Atan((double)(f[1] - d[1]) / (double)(f[0] - d[0]));
            draw(myPen);
        }

        private void b_balra2_Click(object sender, EventArgs e)
        {
            draw(whitePen);
            f[0] -= 10;
            c[0] = (int)Math.Sqrt((f[0]) * (f[0]) + (f[1] - d[1]) * (f[1] - d[1]));
            teta3 = Math.Atan((double)(f[1] - d[1]) / (double)(f[0] - d[0]));
            draw(myPen);
        }

        private void b_jobbra2_Click(object sender, EventArgs e)
        {
            draw(whitePen);
            f[0] += 10;
            c[0] = (int)Math.Sqrt((f[0]) * (f[0]) + (f[1] - d[1]) * (f[1] - d[1]));
            teta3 = Math.Atan((double)(f[1] - d[1]) / (double)(f[0] - d[0]));
            draw(myPen);
        }
    }
}




    Úgy érzem, hogy a program elég jól sikerült ahhoz, hogy érdemes legyen vele még egy kicsit foglalkozni. Arra gondoltam, hogy elkészítem Karé Halvorsen excel táblázatának a megfelelőjét. Persze az nem kis munka, meg nem kis odafigyelés. Az említett excel táblázat nem egy akármilyen táblázat. Tele van macro-val meg minden földi jóval.

     A tábla segitségével előre le tud gyártani bizonyos mozgás-szekvenciákat, amiket majd átküld a szervó vezérlőegységének, ami visszajátssza azt. Rengeteg videója van fent a srácnak youtubeon, azóta készített más robotokat is (leghíresebb az A-Pod, ami olyan, mint egy hangya...) A kedvencemet megosztanám itt is...



Ha nagy leszek, én is ilyet akarok. Csak sokkal szebbet ;)

1 megjegyzés:

Unknown

Hi,
Loved your work on Inverse Kinematics.(Inverz_k.sln). I have tried to add forth joint (for the Gripper). No success. can you help?

Megjegyzés küldése

Return top