Logo Studenta
¡Estudia con miles de materiales!

Vista previa del material en texto

Universidad de Sevilla 
Escuela Politécnica Superior de Sevilla 
 
 
 
 
 
PROGRAMACIÓN E IMPLEMENTACIÓN DE UN BRAZO 
ROBÓTICO HACIENDO USO DE LAS COMUNICACIONES 
INDUSTRIALES PARA SU CONTROL 
 
 
ANEXO IV. CÓDIGO DE LA GUI 
 
 
 
 
 
 
 
Autor: Adrián Díaz Campano 
Tutor: Luis Muñoz Saavedra 
Departamento de Arquitectura y Tecnología de Computadores 
2 
ANEXO IV. CÓDIGO DE LA GUI 
Código más relevante de la GUI 
 
 
Comunicación serie 
 
%****************************************************** 
%* INICIA COMUNICACIONES. PUERTO SERIE * 
%****************************************************** 
delete(instrfind({'Port'},{'COM5'})); % Límpia el puerto. 
global serial_object; 
serial_object = serial('COM5','BaudRate',57600); 
fopen(serial_object); % Abre el puerto 
 
%****************************************************** 
%* ENVÍO DE MENSAJES. PUERTO SERIE * 
%****************************************************** 
q1 = int16(str2double(handles.Texto_q1.String)); % q1 en int16. 
Terminador= 255; % Terminador del mensaje a enviar por el puerto 
serie. 
fwrite(serial_object,'P'); % Envia posición del servo A. 
fwrite(serial_object,'A'); 
fwrite(serial_object,q1,'int16'); 
fwrite(serial_object,Terminador); 
 
 
 
Simulación 
 
%****************************************************** 
%* SIMULACIÓN * 
%****************************************************** 
 
q1 = str2double(handles.Texto_q1.String)*pi/180; 
q2 = str2double(handles.Texto_q2.String)*pi/180; 
q3 = str2double(handles.Texto_q3.String)*pi/180; 
q4 = str2double(handles.Texto_q4.String)*pi/180; 
q5 = str2double(handles.Texto_q5.String)*pi/180; 
 
% Parámetros DH. 
% Theta d a alfa tipo offset 
L(1)= Link ([ 0 L2 L1 pi/2 0 0 ]); 
L(2)= Link ([ 0 0 L3 0 0 pi/2 ]); 
L(3)= Link ([ 0 0 L4 pi/2 0 0 ]); 
L(4)= Link ([ 0 L5 0 pi/2 0 0 ]); 
L(5)= Link ([ 0 0 L6 0 0 pi/2 ]); 
 
Rob = SerialLink(L); 
Rob.name = 'Robot'; 
Rob.plot([q1,q2,q3,q4,q5]); % Gráfica. 
3 
ANEXO IV. CÓDIGO DE LA GUI 
T = Rob.fkine([q1,q2,q3,q4,q5]); % Cálculo de la matriz T. 
 
% Se escribe la posición del punto final de la simulaicón por 
pantalla. 
handles.Texto_Px.String = num2str(T.t(1),'%1.1f'); 
handles.Texto_Py.String = num2str(T.t(2),'%1.1f'); 
handles.Texto_Pz.String = num2str(T.t(3),'%1.1f'); 
 
 
 
Implementación cinemática directa 
 
%****************************************************** 
%* CÁLCULOS CINEMÁTICA DIRECTA * 
%****************************************************** 
q1 = str2double(handles.Texto_q1.String); 
q2 = str2double(handles.Texto_q2.String); 
q3 = str2double(handles.Texto_q3.String); 
q4 = str2double(handles.Texto_q4.String); 
q5 = str2double(handles.Texto_q5.String); 
 
% Ecuación 5.3.10. 
Px = L1*cosd(q1) + L5*(cosd(q1)*cosd(q2)*cosd(q3) - 
cosd(q1)*sind(q2)*sind(q3)) - L3*cosd(q1)*sind(q2) - 
L6*sind(q5)*(sind(q1)*sind(q4) - cosd(q4)*(cosd(q1)*cosd(q2)*sind(q3) 
+ cosd(q1)*cosd(q3)*sind(q2))) + 
L6*cosd(q5)*(cosd(q1)*cosd(q2)*cosd(q3) - cosd(q1)*sind(q2)*sind(q3)) 
- L4*cosd(q1)*cosd(q2)*sind(q3) - L4*cosd(q1)*cosd(q3)*sind(q2); 
 
% Ecuación 5.3.11. 
Py = L1*sind(q1) - L5*(sind(q1)*sind(q2)*sind(q3) - 
cosd(q2)*cosd(q3)*sind(q1)) - L3*sind(q1)*sind(q2) + 
L6*sind(q5)*(cosd(q1)*sind(q4) + cosd(q4)*(cosd(q2)*sind(q1)*sind(q3) 
+ cosd(q3)*sind(q1)*sind(q2))) - 
L6*cosd(q5)*(sind(q1)*sind(q2)*sind(q3) - cosd(q2)*cosd(q3)*sind(q1)) 
- L4*cosd(q2)*sind(q1)*sind(q3) - L4*cosd(q3)*sind(q1)*sind(q2); 
 
% Ecuación 5.3.12. 
Pz = L2 + L5*(cosd(q2)*sind(q3) + cosd(q3)*sind(q2)) + L3*cosd(q2) + 
L6*cosd(q5)*(cosd(q2)*sind(q3) + cosd(q3)*sind(q2)) + 
L4*cosd(q2)*cosd(q3) - L4*sind(q2)*sind(q3) - 
L6*cosd(q4)*sind(q5)*(cosd(q2)*cosd(q3) - sind(q2)*sind(q3)); 
 
 
% Se escribe la posición del punto final por pantalla. 
handles.Texto_PxC.String = num2str(Px,'%1.1f'); 
handles.Texto_PyC.String = num2str(Py,'%1.1f'); 
handles.Texto_PzC.String = num2str(Pz,'%1.1f'); 
 
% Ecuación 5.3.1. 
nx = cosd(q5)*(cosd(q1)*cosd(q2)*cosd(q3) - 
cosd(q1)*sind(q2)*sind(q3)) - sind(q5)*(sind(q1)*sind(q4) - 
cosd(q4)*(cosd(q1)*cosd(q2)*sind(q3) + cosd(q1)*cosd(q3)*sind(q2))); 
 
% Ecuación 5.3.2. 
4 
ANEXO IV. CÓDIGO DE LA GUI 
ny = sind(q5)*(cosd(q1)*sind(q4) + 
cosd(q4)*(cosd(q2)*sind(q1)*sind(q3) + cosd(q3)*sind(q1)*sind(q2))) - 
cosd(q5)*(sind(q1)*sind(q2)*sind(q3) - cosd(q2)*cosd(q3)*sind(q1)); 
 
 
% Ecuación 5.3.3. 
nz = cosd(q5)*(cosd(q2)*sind(q3) + cosd(q3)*sind(q2)) - 
cosd(q4)*sind(q5)*(cosd(q2)*cosd(q3) - sind(q2)*sind(q3)); 
 
% Ecuación 5.3.4. 
%ox = -cosd(q5)*(sind(q1)*sind(q4) - 
cosd(q4)*(cosd(q1)*cosd(q2)*sind(q3) + cosd(q1)*cosd(q3)*sind(q2))) - 
sind(q5)*(cosd(q1)*cosd(q2)*cosd(q3) - cosd(q1)*sind(q2)*sind(q3)); 
 
% Ecuación 5.3.5. 
%oy = cosd(q5)*(cosd(q1)*sind(q4) + 
cosd(q4)*(cosd(q2)*sind(q1)*sind(q3) + cosd(q3)*sind(q1)*sind(q2))) + 
sind(q5)*(sind(q1)*sind(q2)*sind(q3) - cosd(q2)*cosd(q3)*sind(q1)); 
 
% Ecuación 5.3.6. 
oz = - sind(q5)*(cosd(q2)*sind(q3) + cosd(q3)*sind(q2)) - 
cosd(q4)*cosd(q5)*(cosd(q2)*cosd(q3) - sind(q2)*sind(q3)); 
 
% Ecuación 5.3.7. 
%ax = - cosd(q4)*sind(q1) - sind(q4)*(cosd(q1)*cosd(q2)*sind(q3) + 
cosd(q1)*cosd(q3)*sind(q2)); 
 
% Ecuación 5.3.8. 
%ay = cosd(q1)*cosd(q4) - sind(q4)*(cosd(q2)*sind(q1)*sind(q3) + 
cosd(q3)*sind(q1)*sind(q2)); 
 
% Ecuación 5.3.9. 
az = sind(q4)*(cosd(q2)*cosd(q3) - sind(q2)*sind(q3)); 
 
% Ecuación 5.10. 
beta = atand(-nz/(sqrt(1-(-nz)^2))); 
 
if az < 0 
 alpha = atand(oz/az) - 180; % Debido a que atand solo da valores 
entre [90,-90] hay que tener en cuenta los demás casos restando 180 
grados. Ecuación 5.6. 
else 
 alpha = atand(oz/az); % Ecuación 5.6. 
end 
 
if nx < 0 
 gamma = atand(ny/nx) - 180; % Debido a aque atand solo da valores 
entre [90,-90] hay que tener en cuenta los demás casos restando 180 
grados. Ecuación 5.7. 
else 
 gamma = atand(ny/nx); % Ecuación 5.7. 
end 
 
% Se escribe la orientación del punto final por pantalla. 
handles.Texto_alphaC.String = num2str(alpha,'%1.1f'); 
handles.Texto_betaC.String = num2str(beta,'%1.1f'); 
handles.Texto_gammaC.String = num2str(gamma,'%1.1f'); 
 
 
5 
ANEXO IV. CÓDIGO DE LA GUI 
 
 
Implementación cinemática inversa 
%****************************************************** 
%* CÁLCULOS CINEMÁTICA INVERSA * 
%****************************************************** 
L1 = 11; L2 = 96.3; L3 = 120; L4 = -6; L5 = 120.5; L6 = 123; % Medidas 
del brazo. 
 
Px = str2double(handles.Texto_PxC.String); 
Py = str2double(handles.Texto_PyC.String); 
Pz = str2double(handles.Texto_PzC.String); 
alpha = str2double(handles.Texto_alphaC.String); 
beta = str2double(handles.Texto_betaC.String); 
gamma = str2double(handles.Texto_gammaC.String); 
 
% Transformación de los ángulos alpha, beta y gamma a matriz de 
rotación 
% (Ecuación 5.12) 
nx = cosd(gamma)*cosd(beta); 
ny = sind(gamma)*cosd(beta); 
nz = -sind(beta); 
ox = -sind(gamma)*cosd(alpha) + cosd(gamma)*sind(beta)*sind(alpha); 
oy = cosd(gamma)*cosd(alpha) + sind(gamma)*sind(beta)*sind(alpha); 
oz = cosd(beta)*sind(alpha); 
ax = sind(gamma)*sind(alpha) + cosd(gamma)*sind(beta)*cosd(alpha); 
ay = -cosd(gamma)*sind(alpha) + sind(gamma)*sind(beta)*cosd(alpha); 
az = cosd(beta)*cosd(alpha); 
 
% Es necesario redondear para que MATLAB no ponga ceros negativos. 
nx = round(nx,5); 
ny = round(ny,5); 
nz = round(nz,5); 
ox = round(ox,5); 
oy = round(oy,5); 
oz = round(oz,5); 
ax = round(ax,5); 
ay = round(ay,5); 
az = round(az,5); 
 
Pf = [Px Py Pz]; % Posición del extremo del robot. Ecuación 4.30. 
Pm = Pf - L6*[nx ny nz]; % Posición de la muñeca del robot. Ecuación 
5.29. 
 
% Medidas del robot 
L =sqrt(L4^2 + L5^2); % Ecuación 5.13. 
h = Pm(3) - L2; % Ecuación 5.14. 
psi = atand(L5/-L4); % Ecuación5.15. 
 
 
% Primera articulación. 
q1= atand(abs(Pm(2)/Pm(1))); % Ecuación 5.16. Sólo se moverá entre los 
[0,90]. 
 
q1= round(q1); % Se redondea el ángulo, ya que no se van a usar más 
decimales. Así se evitan mayores errores en el cálculo. 
 
6 
ANEXO IV. CÓDIGO DE LA GUI 
 
% Tercera articulación. 
r_p_xy = sqrt((Pm(1)-L1*cosd(q1))^2 +(Pm(2)-L1*sind(q1))^2); % 
Ecuación 5.20. 
cos_theta3 = (-r_p_xy^2 - h^2 + L3^2 + L^2)/(2*L3*L); % Ecuación 5.23. 
 
if cos_theta3 <= 0 % Desde q3 = [0, 90]. 
 q3 = (atand(sqrt(abs(1-cos_theta3^2))/cos_theta3) - psi) +180; % 
Ecuación 5.25. 
 
else % Desde q3 = [-40, 0). 
 q3 = (atand(sqrt(abs(1-cos_theta3^2))/cos_theta3) - psi) ; % 
Ecuación 5.25. 
end 
q3 = round(q3 
 
 
% Segunda articulación. 
if q1 == 0 || q1 == 180 
 if (Pm(1)-L1*cosd(q1))/(abs(Pm(1)-L1*cosd(q1))) == 
L1*cosd(q1)/abs(L1*cosd(q1)) 
 b = atand(h/r_p_xy); % Ecuación 5.27. 
 else 
 b = -atand(h/r_p_xy) + 180; % Ecuación 5.27. 
 end 
elseif q1 == 90 
 if (Pm(2)-L1*sind(q1))/(abs(Pm(2)-L1*sind(q1))) == 
L1*sind(q1)/abs(L1*sind(q1)) 
 b = atand(h/r_p_xy); % Ecuación 5.27. 
 else 
 b = -atand(h/r_p_xy) + 180; % Ecuación 5.27. 
 end 
else 
 if (Pm(1)-L1*cosd(q1))/(abs(Pm(1)-L1*cosd(q1))) == 
L1*cosd(q1)/abs(L1*cosd(q1)) && (Pm(2)-L1*sind(q1))/(abs(Pm(2)-
L1*sind(q1))) == L1*sind(q1)/abs(L1*sind(q1)) 
 b = atand(h/r_p_xy); % Ecuación 5.27. 
 else 
 b = -atand(h/r_p_xy) + 180; % Ecuación 5.27. 
 end 
end 
 
al = abs(atand(L*sind(q3 + psi)/(L3 - L*cosd(q3 + psi))));% Ecuación 
5.28. 
q2 = (b + al) - 90; % Ecuación 5.26. 
q2 = round(q2); 
 
 
% Cuarta articulación. 
 
cos_theta4 = -ax*sind(q1) + ay*cosd(q1); % Ecuación 5.39. 
cos_theta5 = nx*(cosd(q1)*cosd(q2)*cosd(q3) - 
cosd(q1)*sind(q2)*sind(q3)) - ny*(sind(q1)*sind(q2)*sind(q3) - 
cosd(q2)*cosd(q3)*sind(q1)) + nz*(cosd(q2)*sind(q3) + 
cosd(q3)*sind(q2)); % Ecuación 5.40. 
q4 = atand(sqrt(abs(1-cos_theta4^2))/cos_theta4); % Ecuación 5.42. 
if cos_theta4 < 0 
 q4 = q4 + 180; % Debido a que la función atand() da valores 
entre -90º y 90º y q4 tiene un rango comprendido de 0º a 180º hay que 
hacer este ajuste. 
7 
ANEXO IV. CÓDIGO DE LA GUI 
end 
q4 = round(q4); 
 
q5 = atand(sqrt(abs(1-cos_theta5^2))/cos_theta5); % Ecuación 5.44. 
 
if cos_theta5 < 0 
 q5 = q5 +180; % debido a que la función atand() da valores entre 
-90º y 90º y q5 tiene un rango comprendido de 0º a 120º hay que hacer 
este ajuste. 
end 
q5= round(q5); 
 
 
% Se escribe la posición de los motores por pantalla. 
handles.Texto_q1.String = num2str(q1); 
handles.Texto_q2.String = num2str(q2); 
handles.Texto_q3.String = num2str(q3); 
handles.Texto_q4.String = num2str(q4); 
handles.Texto_q5.String = num2str(q5);