Índice del artículo

Código de MatLab empleado:

% PROYECTO - CORTADOR DE PIEZAS AUTOMATIZADO
% Autores: Javier Galnares Arias y David Mejías Rivas.
% Lab. de Automatización y Robótica: Curso 2010 / 2011
% 5º Ingeniería de Telecomunicaciones (98)
% Escuela Superior de Ingeniería de Sevilla

%%% Limpieza de figuras y shell

close all;
clear all;
clc;

msk = [1 1 1; 1 0 1; 1 1 1];

%%% ADQUISICIÓN DE IMÁGENES E INICIALIZACIÓN

% Se capta una imagen en formato BMP y se somete a un preprocesamiento

fprintf('Introduzca el nombre de la imagen con su extensión: ');
nombre_imagen = input('\n', 's');

[imagen, map] = imread (nombre_imagen); % en color RGB
imagen = double(imagen)/255;

[nf, nc, z] = size(imagen); % Tamaño de la imagen

if ( z == 3 )
imagen = rgb2gray(imagen);
end

% Parámetros para cuadrar los planos Scorbot-Imagen
x0 = 0;
y0 = 0;
x1 = 500;
y1 = 2700;

% Número de pasos de corte del Scorbot
disp('Introduzca el número de puntos de corte a interpolar según el');
puntos_max = input('plano imagen (valor típico: 100)\n');
% Tiempo estimado de movimiento entre pasos
t_mov = 3;

%%% Esquinas y fronteras

[puntos, bordes] = corner2(imagen);

%%% Ordena puntos de paso

x = puntos(1, 1);
y = puntos(1, 2);

encuentra = 0;
terminar = 0;
i=1;

camino = [];

bordes_aux = bordes;

while( sum(sum(bordes_aux)) > 0 && terminar == 0)
direccion = msk.*bordes_aux(((x-1):(x+1)), ((y-1):(y+1)));
if sum(sum(direccion)) == 0
disp('Error: Imagen no conexa');
terminar = 1;
end

for m=1:3
for n=1:3
if (direccion (m, n) == 1) && (encuentra == 0)
camino(i, 1) = x;
camino(i, 2) = y;
x = x + m - 2;
y = y + n - 2;
encuentra = 1;
end
end
end

if ((x == puntos(1, 2)) && (y == puntos(1, 1)))
terminar = 1;
end

bordes_aux(x, y) = 0;
encuentra = 0;
i = i + 1;
end

camino(i, 1) = x;
camino(i, 2) = y;

n_puntos = length(camino(:,1));

%%% Correspondencia plano Scorbot - plano imagen

% Calculamos el ángulo de rotación entre los planos imagen y Scorbot
a = atan2((y1 - y0), (x1 - x0)) - pi/2;
% Calculamos el factor de escala a aplicar
escalado = sqrt((x1 - x0)^2 + (y1 - y0)^2)/nc;

if n_puntos > puntos_max
paso = round(n_puntos / puntos_max);
else
paso = 1;
disp(' ');
disp('¡Atención!');
disp('Precisión insuficiente en la imagen para el exigido en el robot');
disp(' ');
end
camino_scorbot = [];
camino_scorbot(1, :) = camino(1, :);
i = 1;

while(n_puntos > paso)
camino_scorbot((i+1), :) = camino((i*paso), :);
n_puntos = n_puntos - paso;
i = i + 1;
end

camino_scorbot((i+1), 1) = camino(1, 1);
camino_scorbot((i+1), 2) = camino(1, 2);
n_movimientos = length(camino_scorbot(:, 1));

M = [cos(a) -sin(a); sin(a) cos(a)];
vec_imagen = zeros(2, 1);
vec_scorbot = zeros(2, 1);

for i=1:length(camino(:, 1))
vec_imagen(1, 1) = camino(i, 1);
vec_imagen(2, 1) = camino(i, 2);
plano_imagen(i, :) = vec_imagen';
end

for i=1:length(camino_scorbot(:, 1))
vec_imagen(1, 1) = camino_scorbot(i, 1);
vec_imagen(2, 1) = camino_scorbot(i, 2);
vec_scorbot = M*vec_imagen;
plano_scorbot(i, :) = vec_scorbot';
end

plano_imagen = escalado*plano_imagen;
plano_scorbot = escalado*plano_scorbot;

%%% Figuras e imágenes

m_corte = floor(t_mov*n_movimientos/60);
s_corte = mod(t_mov*n_movimientos, 60);
fprintf('\t Tiempo estimado del corte: \t\t %i min. %i s.\n', m_corte, s_corte);

figure(1)
subplot(2, 2, 1)
imshow(imagen),
title('Plano CAD de la pieza');

subplot(2, 2, 2)
imshow(bordes);
hold on
plot(puntos(:,2), puntos(:,1), 'r+'),
title('Detección de puntos singulares y bordes');

subplot(2, 2, 3)
plot(plano_imagen(:, 2), plano_imagen(:, 1), 'b'),
title('Plano imagen escalado (girado 180º)'),
xlabel('Décimas de milímetro'),
ylabel('Décimas de milímetro');

subplot(2, 2, 4)
plot(plano_scorbot(:, 2), plano_scorbot(:, 1), 'b'),
title('Plano Scorbot (girado 180º)'),
xlabel('Décimas de milímetro'),
ylabel('Décimas de milímetro');

%%% Comunicación serie

PS1=serial('COM1');
set(PS1,'Baudrate',9600); % Se configura la velocidad a 9600 Baudios
set(PS1,'StopBits',1); % Se configura bit de parada a uno
set(PS1,'DataBits',8); % Se configura que el dato es de 8 bits
set(PS1,'Parity','none'); % Se configura sin paridad

% Abrimos el puerto COM1 para comunicarnos con el Scorbot
fopen(PS1);

% Mandamos la cadena '|echo .....' como nos señaló la captura con el
% lookRS232.
fwrite(PS1, '|echo.');
fwrite(PS1, ' ');
for i=1:5
pause(2);
fwrite(PS1, '.');
end
% Hacemos un 'HOME' para calibrar el Scorbot
fwrite(PS1, 'HOME.');
disp('Realizando calibrado... Pulse ENTER cuando finalice');
pause;
% Ponemos la velocidad a 20
disp('Calibrado terminado. Velocidad 20. ¡Precaución! Comienza el corte');
fwrite(PS1, 'SPEED 20.');

% Llevamos al Scorbot a la posición (0, 0) del plano Scorbot
% Esto habría que recalibrarlo para cada Scorbot
fwrite(PS1, 'HERE POS_SCORBOT.');
fwrite(PS1, 'SHIFTC POS_SCORBOT BY X 1000.'); % 'X' 10 cms
fwrite(PS1, 'SHIFTC POS_SCORBOT BY Y 1500.'); % 'Y' 15 cms
fwrite(PS1, 'SHIFTC POS_SCORBOT BY Z 2500.'); % 'Z' 25 cms
fwrite(PS1, 'MOVELD POS_SCORBOT.');
% Guardamos la posición del origen de coordenadas en POS_INI
fwrite(PS1, 'HERE POS_INI.');
pause(5);

repetir = 1;
while(repetir == 1)
fwrite(PS1, 'HERE POS_SCORBOT.');
fwrite(PS1, 'SHIFTC POS_SCORBOT BY X ');
fwrite(PS1, int2str(plano_scorbot(1, 1)));
fwrite(PS1, '.');
fwrite(PS1, 'SHIFTC POS_SCORBOT BY Y ');
fwrite(PS1, int2str(plano_scorbot(1, 2)));
fwrite(PS1, '.');
fwrite(PS1, 'MOVELD POS_SCORBOT.');
pause(5);

% Activamos el láser poniendo la salida 5 ON o cerrando la garra,
% según el modelo de láser que estemos usando
fwrite(PS1, 'SET OUT[5] 1.'); % Láser alimentado por el controlador
% fwrite(PS1, 'CLOSE.'); % Láser alimentado a pilas

for i=2:n_puntos
fwrite(PS1, 'HERE POS_SCORBOT.');
auxX = plano_scorbot(i, 1) - plano_scorbot(i-1, 1);
fwrite(PS1, 'SHIFTC POS_SCORBOT BY X ');
fwrite(PS1,int2str(auxX));
fwrite(PS1, '.');
auxY = plano_scorbot(i, 2) - plano_scorbot(i-1, 2);
fwrite(PS1, 'SHIFTC POS_SCORBOT BY Y ');
fwrite(PS1,int2str(auxY));
fwrite(PS1, '.');
fwrite(PS1, 'MOVELD POS_SCORBOT.');
pause(3) % Espera 3 s.
end;

% Desactivamos el láser quitando la salida 5 o abrimos la garra,
% según el modelo de láser que estemos usando
fwrite(PS1, 'SET OUT[5] 0.'); % Láser alimentado por el controlador
% fwrite(PS1, 'OPEN.'); % Láser alimentado a pilas

fwrite(PS1, 'MOVED POS_INI.');
pause(5);

disp('¿Desea cortar otra pieza idéntica a la anterior? [s/n]:');
resp = input('\n', 's');
if (resp == 's' || resp == 'S')
repetir = 1;
else
repetir = 0;
end
end

% Cerramos el puerto, devolviéndole el control al SO
fclose(PS1);
delete(PS1);
clear PS1;