You are on page 1of 17

INSTITUTO POLITECNICO NACIONAL Unidad Profesional Interdisciplinaria En Ingeniera Y Tecnologas Avanzadas

SIMULACION DE MOVIMIENTO DE UN ROBOT CARTESIANO DE DOS EJES EN C, CON AMBIENTE GRAFICO

Grupo: 2MM3 Carrera Alva E. Jesus Osmar De la Torre Castro Mario Alejandro

INDICE

Introduccin Objetivos Desarrollo del sistema Resultados Conclusiones

Introduccin: Debido a nuestro personal por iniciar a aprender acerca de la programacin aplicada en la cinemtica de robots se eligi este proyecto que convierte una coordenada cartesiana en dos dimensiones a una coordenada polar igualmente en dos dimensiones. Que de forma grfica y/o aplicada podemos ver a un brazo el cual alcanza el punto deseado, en nuestra carrera aplicado a la mecatrnica podemos ver que Para comenzar a hablar del programa iniciamos a hablar sobre estos dos tipos de coordenadas Coordenadas cartesianas de 2 dimensiones: Este tipo de coordenadas son representadas por dos ejes que son perpendiculares entres ellos, en el punto donde se intersectan se le define como el origen o la coordenada (0,0) y generalmente se caracterizan por el eje Y el cual en el sentido convencional es positivo hacia arriba del origen y se va incrementando conforme se incrementa la distancia hacia arriba del origen, de manera inversa este valor de Y se vuelve negativo por debajo del origen e igualmente se va incrementando negativamente conforme se aleja del origen. Existe tambin el eje X el cual en sentido convencional se incrementa hacia la derecha, y se decrementa hacia la izquierda. Coordenadas polares: Este tipo de coordenadas posen como sus dos ejes una distancia absoluta con respecto al origen a la denominamos radio y un Angulo al que denominaremos (Theta) que convencionalmente mide la rotacin con respecto de lo que en coordenadas cartesianas es el eje +X al que denominaremos eje polar, cuando se mueve en sentido anti horario se incrementa positivamente hasta 3600 o lo que es lo mismo medido en radianes 2 de igual manera se podra decir que moviendo en sentido retro giro llega hasta y movindose en el sentido horario hasta  .

Conversin de coordenadas: Para pasar de una coordenada cartesiana a una polar lo primero que debemos hacer es obtener la distancia del punto con respecto al origen, la cual podemos obtener a base de la ecuacin de Pitgoras: H= (a2+b2)1/2 O lo que es lo mismo la distancia al origen o radio ser igual a la raz de la suma de los cuadrados de las coordenadas X,Y quedando de la siguiente manera: Radio= (X2+Y2)1/2 Ahora para calcular el ngulo tenemos que: Tangente ( )= Cateto Opuesto (C.O.)/ Cateto adyacente (C.A.); Pero si sacamos la funcin inversa y sustituimos al C.O. con Y y al C.A. con x Tenemos que =Arc tan (Y/X);

x=xi+380; y=-yi+341; for(d1;d1<d2;d1=d1+4){ x=(cos(ang1)*d1)+380; y=(-sin(ang1)*d1)+341;

OBJETIVOS Uno de los objetivos principales del programa es simular un brazo el cual alcanza un punto, el cual previamente introdujimos valores de posicin. Adems de aplicar la mayora de los conocimientos obtenidos a travs del curso de programacin avanzada, y tomando en cuenta nuestros conocimientos previos en el curso de mecnica del cuerpo rgido y as poder realizar el ingreso de las frmulas de clculo para el programa aqu mencionado.

ELABORACION DEL PROGRAMA: El primer problema para la elaboracin del programa fue el cmo poder calcular los ngulos, inicialmente de acuerdo a si la coordenada inicial de Y era positiva o negativa nos mandaba a otra secuencia de if, en la cual dependiendo de si x era positiva o negativa sumaba o restaba ngulos de los ejes. En otras palabras calculaba la tangente y posteriormente de acuerdo al cuadrante sumaba o restaba el Angulo de uno de los ejes para tener el Angulo exacto. Sin embargo al investigar cmo utilizar la funcin arco tangente en el programa descubrimos que existen dos arcos tangentes una que da el valor exacto dependiendo del cuadrante y otra que lo da nicamente como Angulo. Sin embargo la funcin que ya da el Angulo de acuerdo al cuadrante lo da de cero a + , y de cero a  , por lo cual ms tarde tendremos que convertir esto a un valor exacto de 0 a 2 . Ahora ya teniendo resuelto el problema de los ngulos nos dedicamos a investigar como graficar para lo cual encontramos que en dev existe una librera para descargarse conocida como winbgim. #include <windows.h> #include <winbgim.h> Tambin calculamos los radios Ahora que ya calculamos los ngulos tanto de las coordenadas iniciales como las de las coordenadas a moverse iniciamos los grficos y graficamos un margen que sea del radio mximo que deseamos pueda alcanzar el brazo. Para poder seleccionar un punto inicial debemos tomar en cuenta que la ubicacin de las coordenadas de los pixeles no es igual que el sentido convencional, el punto inicial de los grficos comienzan en la esquina superior derecha mirando de frente el monitor, x aumenta hacia la derecha, y aumente hacia abajo en vez de disminuir, por lo cual ahora hacemos un traslado del punto de origen, esto lo logramos sumando las coordenadas del punto de origen a todos las operaciones que hagamos en la computador, tambin debemos de poner las coordenadas de y en sentidos contrarios para todos los clculos. Teniendo esta informacin en cuenta y habiendo graficado crculos centrados en el nuevo origen y de un radio definido hasta que cubran toda la pantalla logramos crear un margen. Despus lanzamos una lnea del punto de origen a la coordenada inicial y debido a que es muy pequea la lnea y aparentemente en la librera no hay comandos para cambiar el grosor de lnea lo que hacemos en graficar lneas que se muevan desde los pixeles que se en

encuentran al lado del origen hasta los pixeles que se encuentran al lado de la primer coordenada, Para que se denote mas donde est la coordenada inicial graficamos crculos alrededor de dicha coordenada. Ahora empezaremos a calcular lo que son los movimientos, habiendo calculado previamente los dos ngulos y los radios existen dos opciones que el radio de la coordenada inicial sea ms o menos grande que el radio de la segunda coordenada: Si es ms grande tendremos que borrar el crculos que pusimos anteriormente e ir dibujando pixeles que se incrementen lentamente para dar el efecto de que la lnea se incrementa, e ir poniendo crculos en las nuevas coordenadas, detenerlos y borrarlos, de esta manera parece que la lnea se extiende al tiempo que los crculos parpadean. En caso de ser ms chico se iran borrando los crculos y se iran colocando otros hasta llegar al radio deseado. Ambas secuencias las logramos con un for, poniendo la longitud del segundo arco como final de las repeticiones y el incremento o decremento del radio 1 hasta que se convierta en el mismo largo que el radio 2. Despus de cualquier secuencia debe de terminar un punto del origen al radio 2, pero con el Angulo de la primer coordenada. Para la siguiente secuencia grafica de movimientos, haremos algo similar, ir incrementando o decrementando el Angulo inicial hasta que se convierta en el ngulo de la segunda coordenada Para lo cual ahora convertimos los radios de 0 a 2 con un simple if, si los angulos son negativos el angulo es igual a y le adicionamos dicho Angulo negativo. Ahora hacemos de nuevo una sentencia for mientras un ngulo sea diferente del otro se deber ir incrementando o decrementando, para lo cual de nuevo usamos una sentencia para decidir en qu direccin es el giro ms corto: Restamos el ngulo 1 del ngulo 2 si el ngulo resultante es positivo quiere decir que dicho ngulo es lo que debe de sumarse al ngulo 1, pero si dicho ngulo es mayor a es decir es mayor a la mitad del circulo conviene ms rotar en sentido contrario. Pero si el ngulo que resulto de la resta es negativo quiere decir que debe ir retrocediendo el ngulo hasta llegar al otro ngulo, e igualmente si lo que tiene que girar es mayor a es mejor que gire en el otro sentido.

Como los ngulos llevan varias diezmilsimas de entero sera demasiado tardado para la computadora que la pongamos a girar de diezmilsima en diezmilsima por lo cual haremos que los ngulos cambien solo de centsima en centsima, por lo cual en el for de giro pondremos como aumentos o decrementos en valores de centsimas, pero hay otro problema al hacer esto puede que el valor gire eternamente y nunca coincida, por lo cual haremos una sentencia dentro del for si el ngulo entre los dos ngulos es = o menor al de un centsima el ngulo se convertir en el ngulo 2 restando esa centsima de esta manera al terminar esta iteracin del ciclo for se convertir en el ngulo exacto y saldr de la secuencia. Bien ahora que ya definimos el cmo realizar el giro colocaremos dentro del dos secuencias una para dibujar la lnea y el circulo, la pausamos y despus la borramos, sin embargo al probar si la lnea se dibujaba bien y se borraba bien quedaron residuos de pixeles dibujados en las partes ms lejanas y esto es porque cerca del centro los radios son pequeos y alejado son grandes por lo cual en las esquinas no alcazaba a borrar todos los pixeles que haba trazado de trayectorias anteriores, por lo cual o el cambio en el movimiento de los ngulos se haca ms pequeos atrasando la memoria de la computadora o se trazaban mas lneas negras paralelas a la que borran las lneas, optando por esta segunda opcin, Y ahora que las funciones por separadas se encontraban sueltas es momento de integrarlas en una sola utilizando la misma clase y la herencia de variables entre las funciones, para terminar y seguir optimizando el cdigo al principio del programa se piden la coordenada X,Y, si el radio es mayor al mximo alcance, los pide de nuevo, en los crculos alrededor del centro al momento de borrarse si son del radio mximo permitido irn borrando parte del margen por lo cual al trazar los cambios de ngulos si son de un intervalo del radio mximo ira redibujando el margen eliminado al tiempo que continua rotando. Ahora para que el sistema pueda encender y apagar la funcin grafica se crea una bandera si el programa corre por primera vez los lanza, al terminar cambia la bandera y pregunta si desea trazar otra coordenada de ser as regresa la funcin y la bandera impide que se habr otra funcin de grficos, haciendo que el nuevo movimiento se realice sobre la misma ventana.

RESULTADOS

CONCLUSIONES Nuestra conclusin tras la realizacin del programa fue que el realizar un programa en este lenguaje bajo de programacin resulta ser ms largo de lo que podra ser el realizarlo en otro programa especializado. Adems nos result muy til y de mucha practica el elaborar este programa, porque adems de que pusimos a prueba nuestros conocimiento aprendidos en el curso, pudimos aplicar de manera prctica la programacin en C++ directamente a nuestra rea de ingeniera.

#include <winbgim.h> #include<iostream.h> #include<stdio.h> #include<conio.h> #include<string.h> #include<stdlib.h> #include<math.h> #include <windows.h> #include <winbgim.h> class robot{ int xi; int yi; int xf; int yf; int mar; float ang1; float ang2; float var; float d; float d1; float d2; public: robot(); void getratio(); void cangle(); void margen(); void moveline(); void mgrade(); void ig(); }; //________________________________________________________________________ ______ robot::robot(){ xi=0; yi=0; xf=0; yf=0; }

//________________________________________________________________________ ______ void robot::getratio(){ do{ cout<<"Proporciona el nuevo valor de X: "; cin>>xf; cout<<"Proporciona el nuevo valor de Y: "; cin>>yf; var=((xf*xf)+(yf*yf)); d2=pow(var,0.5); if(d2>339){cout<<"El punto se encuentra fuera del rango de movimiento.\nPor favor ingreselos nuevamente"; system("pause"); system("cls");} }while(d2>339); var=((xi*xi)+(yi*yi)); d1=pow(var,0.5); } //________________________________________________________________________ ______ void robot::cangle(){ int a; int b; a=xf; b=yf; cout<<"\nX es: "<<a<<"\nY es: "<<b<<"\n"; ang1=atan2(yi,xi); ang2=atan2(b,a); } //************************************************************************ **** void robot::margen(){ cout<<"\ndiametros: "<<d1<<" "<<d2; system ("pause"); moveto(381,341); for(float k=0;k<=10;k++){

setcolor(k); for(float i=340;i<=560;i=i+1){ circle(380,341,i); } sleep(50); } setcolor(14); lineto(xi+380,-yi+341); moveto(379,341); lineto(xi+379,-yi+341); moveto(381,341); lineto(xi+381,-yi+341); moveto(380,340); lineto(xi+379,-yi+340); moveto(381,342); lineto(xi+381,-yi+342); for(float k=0;k<=14;k++){ setcolor(k); for(float j=0;j<=3;j++){circle(xi+380,-yi+341,j);sleep(2);} } } //________________________________________________________________________ ______ void robot::moveline(){ int x; int y; if (d1<d2){ x=xi+380; y=-yi+341; for(d1;d1<d2;d1=d1+4){ x=(cos(ang1)*d1)+380; y=(-sin(ang1)*d1)+341; setcolor(14); moveto(381,341); lineto(x+1,y);moveto(380,341); lineto(x,y);moveto(379,341); lineto(x-1,y);moveto(380,342); lineto(x,y+1);moveto(380,340); lineto(x,y-1);moveto(380,341); for(float j=0;j<=3;j++){circle(x,y,j);} setcolor(BLACK);for(float j=0;j<=3;j++){circle(x,y,j);}

sleep (20);} x=(cos(ang1)*d2)+380; y=(-sin(ang1)*d2)+341; setcolor(14); for(float j=0;j<=3;j++){circle(x,y,j);} } // Ahora va para un diametro menor que el final else{ for(d1;d1>=d2;d1--){ x=(cos(ang1)*d1)+380; y=(-sin(ang1)*d1)+341; setcolor(BLACK); setcolor(14); for(float j=0;j<=3;j++){circle(x,y,j);} sleep (10); setcolor(BLACK); for(float j=0;j<=5;j++){circle(x,y,j);} } x=(cos(ang1)*d1)+380; y=(-sin(ang1)*d1)+341; setcolor(14); for(float j=0;j<=3;j++){circle(x,y,j);} } } //________________________________________________________________________ _____ void robot::mgrade(){ int x; int y; int dir1; float a; if(ang1<0){ang1=6.28318+ang1;} if(ang2<0){ang2=6.28318+ang2;} if(ang1>=6.28318){ang1=ang1-6.28318;} if(ang2>=6.28318){ang2=ang1-6.28318;}

cout<<"\nEl antiguo angulo en radianes es: "<<ang1<<"\nEl angulo nuevo en radianes es: "<<ang2; dir1=ang2-ang1; if(ang2>=ang1){if((fabs(dir1))<=3.14159){ a=0.01;}else{a=-0.01;}} else{ if((fabs(dir1))<=3.14159){ a=-0.01;} else{ a=0.01; } } cout<<"\nDireccion"<<a; for(ang1;ang1!=ang2;ang1=ang1+a){ if(ang1<0){ang1=6.28318+ang1;} if(ang2<0){ang2=6.28318+ang1;} if(ang1>=6.28318){ang1=ang1-6.28318;} if(ang2>=6.28318){ang2=ang1-6.28318;} if((fabs(ang2-ang1))<=0.01){ang1=ang2-a;} x=(cos(ang1)*d2)+380; y=(-sin(ang1)*d2)+340;

setcolor(14); moveto(380,341); lineto(x,y); moveto(381,341); lineto(x+1,y); moveto(379,341); lineto(x-1,y); moveto(380,340); lineto(x,y-1); moveto(380,342); lineto(x,y+1); for(float j=0;j<=4;j++) { circle(x,y,j); sleep(5);

} setcolor(BLACK); for(int i=1;i<=5;i++) { moveto(380,341); lineto(x,y); moveto(380+i,341); lineto(x+i,y); moveto(380-i,341); lineto(x-i,y); moveto(380,341-i); lineto(x,y-i); moveto(380,341+1); lineto(x,y+i); } for(float j=0;j<=7;j++){circle(x,y,j);} setcolor(10); if(d2>=330){ for(float i=340;i<=350;i=i+1){ circle(380,341,i); } }

} x=(cos(ang2)*d2)+380;//se definen de nuevo las coordenadas para k el calculo sea mas exacto; y=(-sin(ang2)*d2)+340; setcolor(14); moveto(380,341); lineto(x,y); moveto(381,341); lineto(x+1,y); moveto(379,341); lineto(x-1,y); moveto(380,340); lineto(x,y-1); moveto(380,342);

lineto(x,y+1); for(float j=0;j<=3;j++){circle(x,y,j);} xi=xf; yi=yf; } //================================================================ ============= void robot::ig(){ initwindow(750,700); //open graphics window } //************************************************************************ ****** //************************************************************************ ****** //**************************************d********************************* ******* int main(){ int f; char q1[67]; strcpy(q1,"Desea realizar otro recorrido? Pulse 0 para volver a realizarlo: "); f=1; robot cnmtks; do { cnmtks.getratio(); cnmtks.cangle(); if(f!=0){ cnmtks.ig();} cnmtks.margen(); cnmtks.moveline(); cnmtks.mgrade(); cout<<"Desea realizar otro recorrido?\nPulse 0 para volver a realizarlo: "; cin>>f; } while(f==0); closegraph(); return(0); }

You might also like