Robot Fuzzy Logic

Roam function

function [vL, vR] = roam(rangeL, rangeR, rangeC, rangeLC, rangeRC, varargin)

vL_target = 5;

vR_target = 5;

range = min([rangeL rangeR rangeC rangeLC rangeRC]);

if(range <= 10)

vL = vL_target;

vR = vR_target-10+range;

else

vL = vL_target;

vR = vR_target+2*(.5-rand);

end

Evalfis function detailed description

Fuzzy Control function

function [vL, vR] = ctr_fuzzy_1(rangeL, rangeR, rangeC, rangeLC, rangeRC, varargin)

if length(varargin) < 1

error('Error, a parameter must be specified together with the fuzzy controller');

end;

fis = varargin{1};

[outs] = evalfis([rangeL, rangeC, rangeR],fis);

vL = outs(1,1);

vR = outs(1,2);

Robot Starting function

function [pos, sensors] = start_robot(imagen_png, funcion_control, dt, t_end)

if nargin < 1

imagen_png = 'salon.png';

end;

posn = [0,0,0]; % ydim, xdim, angle

rad = 4; % Radius of the robot (pixels)

wdia = 7; % Distance between robot's wheels (pixels)

if nargin < 2

funcion_control = 'roam'; % Robot's control function

end;

if nargin < 3

dt = .5; % Simulation time increment

end;

if nargin < 4

t_end = 100; % Simulation final time

end;

scenario = rgb2gray(imread(imagen_png));

imagesc(scenario), axis image off; colormap gray;

title('Click to specify the robot's initial position');

disp('Click in the scenario to specify the robot's initial position ... ');

[posn(1) posn(2)] = ginput(1);

title('Click to specify the robot's initial orientation ...');

disp('Click on the scenario to specify the robot's initial orientation ...' ... ');

[y x] = ginput(1);

y = y - posn(1);

x = x - posn(2);

[posn(3), r] = cart2pol(x,y);

[pos, sensors] = simula_robot(posn, rad, wdia, scenario,funcion_control, dt, t_end);

% Robot's trayectory trace plot

hold on

plot(pos(:,1),pos(:,2),'y-');

% pos

% sensors

clear fis

Main function

if nargin < 5

error('A parameter is missing');

end;

if nargin < 5, dt = 0.1; end;

if nargin < 6, t_end = 1000; end;

simulation_times = 1:dt:t_end;

if nargout >= 1

num_filas = length(simulation_times) + 1;

pos = zeros(num_filas, size(posn,2));

pos(1,:) = posn;

end;

if nargout >= 2

sensores = zeros(num_filas, 5);

end;

fila = 2;

%--------------------------------------------------------------

controller_fis = readfis('controla_robot_1.fis');

for i = tiempos_simulacion

[rangeL, rangeR, rangeC, rangeLC, rangeRC] = medidas_lrf(posn, rad, scenario);

sen = [rangeL, rangeR, rangeC, rangeLC, rangeRC];

if nargout >= 2

if i == 1

sensores(1,:) = [ rangeL, rangeR, rangeC, rangeLC, rangeRC];

end;

sensores(fila,:) = [ rangeL, rangeR, rangeC, rangeLC, rangeRC];

end;

[vL, vR] = feval(control_function, rangeL, rangeR, rangeC, rangeLC, rangeRC, controller_fis);

posnn = drive(posn, wdia, vL, vR, dt);

if nargout >= 1

pos(fila,:) = posn;

end;

fila = fila + 1;

if(detectcollision(posnn,rad,scenario))

disp(['Collision detected in (' num2str(posn(1)) ',' num2str(posn(2)) ') imposible movement.']);

else

posn = posnn;

end

drawbot(posn,rad,scenario, sen);

pause(.01);

end

%measures_lrf.m - Obtains the LRF sensors values.

function [rangeL, rangeR, rangeC, rangeLC, rangeRC] = measures_lrf(posn,rad, scenario)

% Sensor at pi/6 radians of the head

rangeL = rangefinder([posn(1), posn(2), posn(3)+pi/6], rad, scenario); %left

% Sensor at -pi/6 radians of the head

rangeR = rangefinder([posn(1), posn(2), posn(3)-pi/6], rad, scenario); %right

% Sensor in line with the head

rangeC = rangefinder(posn, rad,scenario); %center

% Sensor at pi/12 radians of the head (between rangeL and head)

rangeLC = rangefinder([posn(1), posn(2), posn(3)+pi/12], rad, scenario); %left

% Sensor at -pi/12 radians of the head (between rangeR and head)

rangeRC = rangefinder([posn(1), posn(2), posn(3)-pi/12], rad, scenario); %right

%rangefinder.m - Obtains the distance to the nearest object.

% written by: Shawn Lankton

% for: ECE8843 (sort-of) fun (mostly)

function dist = rangefinder(posn, rad, scenario)

% get size of scenario

[dimx, dimy] = size(scenario);

%for 100 steps.

for i = rad:(100+rad)

%get x&y coords of point to test

y = posn(1)+ i*sin(posn(3));

x = posn(2)+ i*cos(posn(3));

%make sure x & y are inside the scenario

if x < 1, x = 1; end;

%x(x < 1) = 1;

if x > dimx, x = dimx; end;

if y < 1, y = 1; end;

if y > dimy, y = dimy; end;

%see if the scenario at x & y is an obstacle or not

if(scenario(round(x),round(y)) == 0)

%if yes, return the distance to the obstacle

dist = i-rad;

return;

end

end

%if no obstacles found within 100 pixels, return 100

dist = 100;

return;

%drive.m - does the dead rekoning kinematics based on wheel speeds

% written by: Shawn Lankton

% for: ECE8843 (sort-of) fun (mostly)

function [newposn] = drive(posn, wdia, vL, vR, t)

%get speed differences & sums

vdiff = vR-vL;

vsum = vR+vL;

%calculate new angle (pretty simple)

newposn(3) = posn(3) + vdiff*t/wdia;

if(vdiff == 0)

%calculate new [y x] if wheels moving together.

newposn(1) = vL*t*sin(posn(3))+posn(1);

newposn(2) = vR*t*cos(posn(3))+posn(2);

else

%calculate new [y x] if wheels moving at unequal speeds.

newposn(1) = posn(1) - wdia*vsum/(2*vdiff)*(cos(vdiff*t/wdia+posn(3))-cos(posn(3)));

newposn(2) = posn(2) + wdia*vsum/(2*vdiff)*(sin(vdiff*t/wdia+posn(3))-sin(posn(3)));

end

%detectcollisions.m - sees if the robot hit something

% written by: Shawn Lankton

% for: ECE8843 (sort-of) fun (mostly)

%

function bool = detectcollision(posn, rad, scenario)

%get a circle representing the robot's body

angs = 0:pi/10:2*pi;

y = posn(1) + rad*sin(angs);

x = posn(2) + rad*cos(angs);

%for each of these 20 pixels, check if one is on black

for i = 1:length(y)

if(scenario(round(x(i)),round(y(i))) == 0)

%if so, return 1

bool = 1;

return;

end

end

%if not, return 0

bool = 0;

%drawang.m - Draws a straight line using as parameters, the initial position, %an angle (obtained both from posn vector) and a magnitude (mag)

function drawang(posn, mag, tColor)

% do some polar to cartesian math

y = [posn(1), posn(1)+ mag*sin(posn(3))];

x = [posn(2), posn(2)+ mag*cos(posn(3))];

plot(y,x,tColor);

function tColor = color_from_sensor(range)

if range > 70

tColor = 'g--';

elseif range > 50

tColor = 'm--';

elseif range > 30

tColor = 'b--';

elseif range > 15

tColor = 'k-';

else

tColor = 'r-';

end;

%drawbot.m - plots the robot & its wiskers on the scenario

% written by: Shawn Lankton

% for: ECE8843 (sort-of) fun (mostly)

%

function drawbot(posn, rad, scenario,sens)

hold off;

imagesc(scenario), axis image off; colormap gray;

hold on;

%draw a little circle for the robot

angs = 0:pi/10:2*pi;

y = posn(1) + rad*sin(angs);

x = posn(2) + rad*cos(angs);

plot(y,x,'k-','LineWidth',3);

%sens = [rangeL, rangeR, rangeC, rangeLC, rangeRC];

tColor = color_from_sensor(sens(1));

magnitude = rad + min(sens(1),100);

%magnitude = rad + 10;

drawang([posn(1), posn(2), posn(3) + pi/6],magnitude,tColor);

tColor = color_from_sensor(sens(4));

magnitude = rad + min(sens(4),100);

drawang([posn(1), posn(2), posn(3) + pi/12],magnitude,tColor);

tColor = color_from_sensor(sens(2));

magnitude = rad + min(sens(2),100);

drawang([posn(1), posn(2), posn(3) - pi/6],magnitude,tColor);

tColor = color_from_sensor(sens(5));

magnitude = rad + min(sens(5),100);

drawang([posn(1), posn(2), posn(3) - pi/12],magnitude,tColor);

tColor = color_from_sensor(sens(3));

magnitude = rad + min(sens(3),100);

drawang([posn(1), posn(2), posn(3) ],magnitude,tColor);

Read more