├── animation.gif ├── src ├── plangenerator.m ├── distance_to_obstacles.m ├── angle_to_goal.m ├── create_map.m ├── approach_goal.m ├── standard_plans.m └── do_step.m ├── files ├── fuzzy_system_3_rules.fis ├── fuzzy_system_5_rules.fis ├── neurofuzzy_system_5_rules.fis └── neurofuzzy_system_3_rules.fis ├── LICENSE ├── control_vehicle.m └── README.md /animation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nickgkan/neuro-fuzzy-vehicle-controller/HEAD/animation.gif -------------------------------------------------------------------------------- /src/plangenerator.m: -------------------------------------------------------------------------------- 1 | function [ Y ] = plangenerator( siz ) 2 | % Create a random map. 3 | 4 | Y = round(rand(siz)-0.3); 5 | point= randi(siz^2,1,2); 6 | Y(point(1)) = 2; 7 | Y(point(2)) = 3; 8 | end 9 | 10 | -------------------------------------------------------------------------------- /files/fuzzy_system_3_rules.fis: -------------------------------------------------------------------------------- 1 | [System] 2 | Name='my_fuzzy_system' 3 | Type='mamdani' 4 | Version=2.0 5 | NumInputs=2 6 | NumOutputs=1 7 | NumRules=3 8 | AndMethod='min' 9 | OrMethod='max' 10 | ImpMethod='min' 11 | AggMethod='max' 12 | DefuzzMethod='centroid' 13 | 14 | [Input1] 15 | Name='angle' 16 | Range=[0 180] 17 | NumMFs=2 18 | MF1='GoodAngle':'trimf',[-100 0 110] 19 | MF2='BadAngle':'trimf',[80 180 280] 20 | 21 | [Input2] 22 | Name='obstacleDistance' 23 | Range=[0 400] 24 | NumMFs=2 25 | MF1='GoodDistance':'sigmf',[0.3708 20] 26 | MF2='BadDistance':'zmf',[1 64.021164021164] 27 | 28 | [Output1] 29 | Name='speed' 30 | Range=[0 15] 31 | NumMFs=3 32 | MF1='lowSpeed':'trimf',[-6 0 5] 33 | MF2='midSpeed':'trimf',[4.5 7.5 10.5] 34 | MF3='highSpeed':'trimf',[10 15 21] 35 | 36 | [Rules] 37 | 1 1, 3 (1) : 1 38 | 2 0, 1 (1) : 1 39 | 1 2, 2 (1) : 1 40 | -------------------------------------------------------------------------------- /files/fuzzy_system_5_rules.fis: -------------------------------------------------------------------------------- 1 | [System] 2 | Name='new_my_fuzzy_system_test' 3 | Type='mamdani' 4 | Version=2.0 5 | NumInputs=2 6 | NumOutputs=1 7 | NumRules=5 8 | AndMethod='min' 9 | OrMethod='max' 10 | ImpMethod='min' 11 | AggMethod='max' 12 | DefuzzMethod='centroid' 13 | 14 | [Input1] 15 | Name='angle' 16 | Range=[0 180] 17 | NumMFs=3 18 | MF1='GoodAngle':'trimf',[-100.47619047619 -0.476190476190482 109.52380952381] 19 | MF2='BadAngle':'trimf',[80 180 280] 20 | MF3='VerticalAngle':'trimf',[85.95 90.95 95] 21 | 22 | [Input2] 23 | Name='obstacleDistance' 24 | Range=[0 400] 25 | NumMFs=3 26 | MF1='GoodDistance':'trapmf',[10.72 160.1 430 670] 27 | MF2='BadDistance':'zmf',[1 107.407407407407] 28 | MF3='WorstDistance':'zmf',[0 15] 29 | 30 | [Output1] 31 | Name='speed' 32 | Range=[0 15] 33 | NumMFs=3 34 | MF1='lowSpeed':'trimf',[-6 0 5] 35 | MF2='midSpeed':'trimf',[4.5 7.5 10.5] 36 | MF3='highSpeed':'trimf',[10 15 21] 37 | 38 | [Rules] 39 | 1 1, 3 (1) : 1 40 | 2 0, 1 (1) : 1 41 | 1 2, 2 (1) : 1 42 | 3 2, 3 (1) : 1 43 | 0 3, 2 (1) : 1 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 nickgkan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/distance_to_obstacles.m: -------------------------------------------------------------------------------- 1 | function distance = distance_to_obstacles(current_position_x, current_position_y) 2 | 3 | global map; 4 | global map_size; 5 | 6 | distance_east = 0; 7 | if (current_position_x < map_size) 8 | for i = current_position_x + 1:1:map_size 9 | if map(current_position_y, i) == 0 10 | break; 11 | else 12 | distance_east = distance_east + 1; 13 | end 14 | end 15 | end 16 | 17 | distance_west = 0; 18 | if (current_position_x > 1) 19 | for i = current_position_x - 1:-1:1 20 | if map(current_position_y, i) == 0 21 | break; 22 | else 23 | distance_west = distance_west + 1; 24 | end 25 | end 26 | end 27 | 28 | distance_north = 0; 29 | if (current_position_y > 1) 30 | for i = current_position_y - 1:-1:1 31 | if map(i,current_position_x) == 0 32 | break; 33 | else 34 | distance_north = distance_north + 1; 35 | end 36 | end 37 | end 38 | 39 | distance_south = 0; 40 | if (current_position_y < map_size) 41 | for i = current_position_y + 1:1:map_size 42 | if map(i,current_position_x) == 0 43 | break; 44 | else 45 | distance_south = distance_south + 1; 46 | end 47 | end 48 | end 49 | 50 | distance = [distance_east, distance_north, distance_west, distance_south]; 51 | -------------------------------------------------------------------------------- /src/angle_to_goal.m: -------------------------------------------------------------------------------- 1 | function angle = angle_to_goal(current_position_x, current_position_y, goal_position_x, goal_position_y) 2 | 3 | y_d = current_position_y - goal_position_y; 4 | x_d = goal_position_x - current_position_x; 5 | 6 | if (x_d == 0) 7 | if (y_d >= 0) 8 | angle_east = pi/2; 9 | angle_north = 0; 10 | angle_west = -pi/2; 11 | angle_south = pi; 12 | else 13 | angle_east = -pi/2; 14 | angle_north = pi; 15 | angle_west = pi/2; 16 | angle_south = 0; 17 | end 18 | else 19 | 20 | angle = atan(y_d/x_d); 21 | 22 | if (y_d >= 0 && x_d > 0) 23 | angle_east = angle; 24 | angle_north = -(pi/2 - angle); 25 | angle_west = -(pi - angle); 26 | angle_south = pi/2 + angle; 27 | elseif (y_d >= 0 && x_d < 0) 28 | angle_east = pi + angle; 29 | angle_north = pi/2 + angle; 30 | angle_west = angle; 31 | angle_south = -(pi/2 - angle); 32 | elseif (y_d <= 0 && x_d < 0) 33 | angle_east = -(pi - angle); 34 | angle_north = pi/2 + angle; 35 | angle_west = angle; 36 | angle_south = -(pi/2 - angle); 37 | elseif (y_d <= 0 && x_d > 0) 38 | angle_east = angle; 39 | angle_north = -(pi/2 - angle); 40 | angle_west = pi + angle; 41 | angle_south = pi/2 + angle; 42 | end 43 | end 44 | 45 | angle_east = abs(180/pi*angle_east); 46 | angle_north = abs(180/pi*angle_north); 47 | angle_west = abs(180/pi*angle_west); 48 | angle_south = abs(180/pi*angle_south); 49 | 50 | angle = [angle_east, angle_north, angle_west, angle_south]; 51 | -------------------------------------------------------------------------------- /src/create_map.m: -------------------------------------------------------------------------------- 1 | function create_map(plan) 2 | 3 | global map; 4 | global map_size; 5 | 6 | global init_position_x; 7 | global init_position_y; 8 | global goal_position_x; 9 | global goal_position_y; 10 | 11 | y_size = size(plan,1); 12 | x_size = size(plan,2); 13 | 14 | x_step = floor(map_size/x_size); 15 | y_step = floor(map_size/y_size); 16 | 17 | map = ones(map_size,map_size); 18 | 19 | for j = 1:y_size 20 | for i = 1:x_size 21 | if plan(j,i) == 1 22 | map(floor((j-1)*map_size/y_size) + 1:floor(j*map_size/y_size), floor((i-1)*map_size/x_size) + 1:floor(i*map_size/x_size)) = 0; 23 | elseif plan(j,i) == 2 24 | init_position_y = floor((j-0.5)*map_size/y_size); 25 | init_position_x = floor((i-0.5)*map_size/x_size); 26 | 27 | map(init_position_y, init_position_x) = 0.25; 28 | map(init_position_y + 1, init_position_x + 1) = 0.25; 29 | map(init_position_y + 2, init_position_x + 2) = 0.25; 30 | map(init_position_y + 1, init_position_x - 1) = 0.25; 31 | map(init_position_y + 2, init_position_x - 2) = 0.25; 32 | map(init_position_y - 1, init_position_x + 1) = 0.25; 33 | map(init_position_y - 2, init_position_x + 2) = 0.25; 34 | map(init_position_y - 1, init_position_x - 1) = 0.25; 35 | map(init_position_y - 2, init_position_x - 2) = 0.25; 36 | elseif plan(j,i) == 3 37 | goal_position_y = floor(((2*j-1)*map_size/y_size)/2); 38 | goal_position_x = floor(((2*i-1)*map_size/x_size)/2); 39 | 40 | map(goal_position_y, goal_position_x) = 0.25; 41 | map(goal_position_y + 1, goal_position_x + 1) = 0.25; 42 | map(goal_position_y + 1, goal_position_x - 1) = 0.25; 43 | map(goal_position_y - 1, goal_position_x + 1) = 0.25; 44 | map(goal_position_y - 1, goal_position_x - 1) = 0.25; 45 | map(goal_position_y + 2, goal_position_x) = 0.25; 46 | map(goal_position_y - 2, goal_position_x) = 0.25; 47 | map(goal_position_y, goal_position_x + 2) = 0.25; 48 | map(goal_position_y, goal_position_x - 2) = 0.25; 49 | end 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /control_vehicle.m: -------------------------------------------------------------------------------- 1 | clear all 2 | clc 3 | close all 4 | addpath 'files' 5 | addpath 'src' 6 | 7 | %% GLOBAL CONFIGURATION 8 | global map; 9 | global map_size; 10 | 11 | map_size = 400; 12 | 13 | maps = standard_plans(); 14 | 15 | max_iterations = 60; 16 | 17 | %% FUZZY SYSTEMS 18 | 19 | fis_files = {'fuzzy_system_5_rules.fis', 'fuzzy_system_3_rules.fis'}; 20 | 21 | for f = 1:1:2 22 | fis_file = readfis(fis_files{f}); 23 | for map_id = [1 2 3 5 6] 24 | if (map_id == 6) && (f == 2) 25 | break; 26 | end 27 | create_map(maps{map_id}); 28 | figure('name', sprintf('Plan %d of version %d', map_id, f)) 29 | imshow(map); 30 | [~] = approach_goal(fis_file, max_iterations, f == 1); 31 | if f == 1 && map_id == 1 32 | frame = getframe(gcf); 33 | img = frame2im(frame); 34 | [img, cmap] = rgb2ind(img, 256); 35 | if map_id == 1 36 | imwrite(... 37 | img, cmap, 'animation.gif', 'gif',... 38 | 'LoopCount', Inf, 'DelayTime', 0.03... 39 | ); 40 | else 41 | imwrite(... 42 | img, cmap, 'animation.gif', 'gif',... 43 | 'WriteMode', 'append', 'DelayTime', 0.03... 44 | ); 45 | end 46 | end 47 | end 48 | end 49 | 50 | % Random maps 51 | for f = 1:1:2 52 | fis_file = readfis(fis_files{f}); 53 | for map_id=1:1:3 54 | create_map(plangenerator(11)); 55 | figure('name', sprintf('Random plan %d of version %d', map_id, f)) 56 | imshow(map); 57 | [~] = approach_goal(fis_file, max_iterations, false); 58 | end 59 | end 60 | 61 | 62 | %% NEURO-FUZZY SYSTEMS 63 | 64 | fis_files = {'neurofuzzy_system_5_rules.fis', 'neurofuzzy_system_3_rules.fis'}; 65 | N = 10; 66 | 67 | for f=1:1:2 68 | close all 69 | fis_file = readfis(fis_files{f}); 70 | for map_id=1:1:N 71 | if map_id < 8 72 | create_map(maps{map_id}); 73 | else 74 | create_map(plangenerator(11)); 75 | end 76 | figure('name', sprintf('Plan %d of version %d', map_id, f)) 77 | imshow(map); 78 | [~] = approach_goal(fis_file, max_iterations, false); 79 | end 80 | end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fuzzy and Neuro-Fuzzy Vehicle Navigation MATLAB Code 2 | 3 | ## Requirements 4 | * MATLAB (tested with R2012b, R2015a and R2018a) 5 | * Fuzzy Logic Toolbox 6 | 7 | ## The goal 8 | Given a map containing obstacles, guide a vehicle till a given target. The only information available anytime is the distance from nearest obstacles and the angle to goal, while we can only control the velocity of the vehicle in each possible direction. 9 | 10 | ## Fuzzy systems 11 | The problem is solved using [Fuzzy Logic] using rules that apply to common-sense. Two partitions are constructed for both input variables ("good" and "bad" for the angle and the distance), while the output can be either "low", "moderate" or "high" velocity. 12 | 13 | The first fuzzy system (fuzzy_system_3_rules.fis) is modelled upon the following rules: 14 | 1. If angle is "good" and distance is "good" then velocity is "high". 15 | 2. If angle is "bad" then velocity is "low". 16 | 3. If angle is "good" and distance is "bad" then velocity is "moderate". 17 | 18 | For the second fuzzy system (fuzzy_system_5_rules.fis), the angle can also be "vertical" (angle near 90 degrees) and the distance from the nearest obstacles can also be "worst" (really close to an obstacle). This system is modelled upon the aforementioned rules as well as the following: 19 | 1. If angle is "vertical" and distance is "bad" then velocity is "high". 20 | 2. If distance is "worst" then velocity is "moderate". 21 | 22 | The second system performs better for the given maps but does not generalize well to other, unseen maps. 23 | 24 | ## Neuro-fuzzy systems 25 | Using the successful paths for each fuzzy system, we train a neuro-fuzzy system to navigate the vehicle without relying on hand-crafted rules. These models perform worse on seen maps that fuzzy systems overfit, but satisfactorily generalize to unseen maps, while diminishing oscillations near the target. Here, neurofuzzy_system_5_rules.fis outperforms neurofuzzy_system_3_rules.fis, most possibly due to more valid training data. This indicates that such a neuro-fuzzy system can perform poorly in lack of enough training samples. 26 | 27 | ## Results 28 |

29 | Sublime's custom image 30 |

31 | 32 | ## Next step? 33 | Under these specifications, there many cases the problem can not be solved. An interesting approach would be to combine fuzzy modeling with memory, trial-and-error approaches or decision trees. Another appealing approach would be to learn the fuzzy rules via reinforcement learning. 34 | 35 | [Fuzzy Logic]: 36 | -------------------------------------------------------------------------------- /src/approach_goal.m: -------------------------------------------------------------------------------- 1 | function data = approach_goal(fis, max_iterations, write_to_gif) 2 | 3 | global map; 4 | global map_size; 5 | 6 | global init_position_x; 7 | global init_position_y; 8 | global goal_position_x; 9 | global goal_position_y; 10 | 11 | current_position_x = init_position_x; 12 | current_position_y = init_position_y; 13 | 14 | data = []; 15 | for i = 1:max_iterations 16 | dist = distance_to_obstacles(current_position_x, current_position_y); 17 | angle = angle_to_goal(current_position_x, current_position_y, goal_position_x, goal_position_y); 18 | 19 | input = [angle' dist']; 20 | speed = [evalfis(input(1,:), fis)' evalfis(input(2,:), fis)' evalfis(input(3,:), fis)' evalfis(input(4,:), fis)']; 21 | 22 | data = [data; angle(1,1) dist(1,1) speed(1,1)]; 23 | data = [data; angle(1,2) dist(1,2) speed(1,2)]; 24 | data = [data; angle(1,3) dist(1,3) speed(1,3)]; 25 | data = [data; angle(1,4) dist(1,4) speed(1,4)]; 26 | 27 | direction = find(speed == max(speed)); 28 | speed = ceil(speed); 29 | if (length(direction) > 1) 30 | direction = direction(round((length(direction) - 1)*rand) + 1); 31 | end 32 | 33 | if speed(direction) == 0 34 | break; 35 | end 36 | 37 | if (direction == 1) % move east 38 | [new_current_position_x, new_current_position_y] = do_step(current_position_x,current_position_y, speed(direction),0); 39 | elseif (direction == 2) % move north 40 | [new_current_position_x, new_current_position_y] = do_step(current_position_x,current_position_y,0,-speed(direction)); 41 | elseif (direction == 3) % move west 42 | [new_current_position_x, new_current_position_y] = do_step(current_position_x,current_position_y,-speed(direction),0); 43 | elseif (direction == 4) % move south 44 | [new_current_position_x, new_current_position_y] = do_step(current_position_x,current_position_y,0,speed(direction)); 45 | end 46 | 47 | if (new_current_position_x == goal_position_x && new_current_position_y == goal_position_y) 48 | break; 49 | end 50 | 51 | if (new_current_position_x == current_position_x && new_current_position_y == current_position_y) 52 | break; 53 | end 54 | 55 | current_position_x = new_current_position_x; 56 | current_position_y = new_current_position_y; 57 | 58 | imshow(map); 59 | 60 | if write_to_gif 61 | frame = getframe(gcf); 62 | img = frame2im(frame); 63 | [img, cmap] = rgb2ind(img, 256); 64 | imwrite(img, cmap, 'animation.gif', 'gif', 'WriteMode', 'append', 'DelayTime', 0.03); 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /files/neurofuzzy_system_5_rules.fis: -------------------------------------------------------------------------------- 1 | [System] 2 | Name='immortal_aek1' 3 | Type='sugeno' 4 | Version=2.0 5 | NumInputs=2 6 | NumOutputs=1 7 | NumRules=25 8 | AndMethod='prod' 9 | OrMethod='probor' 10 | ImpMethod='prod' 11 | AggMethod='sum' 12 | DefuzzMethod='wtaver' 13 | 14 | [Input1] 15 | Name='input1' 16 | Range=[0 180] 17 | NumMFs=5 18 | MF1='in1mf1':'gaussmf',[19.1725542832031 0.0289655845399928] 19 | MF2='in1mf2':'gaussmf',[19.918330851332 45.6065039842873] 20 | MF3='in1mf3':'gaussmf',[17.8561384596317 88.8966368060921] 21 | MF4='in1mf4':'gaussmf',[20.7393955660632 133.451314897599] 22 | MF5='in1mf5':'gaussmf',[19.2508051144919 179.934827787931] 23 | 24 | [Input2] 25 | Name='input2' 26 | Range=[0 387] 27 | NumMFs=5 28 | MF1='in2mf1':'gaussmf',[41.151192142947 0.044265741935376] 29 | MF2='in2mf2':'gaussmf',[41.1201285015792 96.7595011891461] 30 | MF3='in2mf3':'gaussmf',[41.1088034261968 193.503291450641] 31 | MF4='in2mf4':'gaussmf',[41.0695867224607 290.274380394273] 32 | MF5='in2mf5':'gaussmf',[41.0749673368203 387.008270764556] 33 | 34 | [Output1] 35 | Name='output' 36 | Range=[1.6173 13.38] 37 | NumMFs=25 38 | MF1='out1mf1':'constant',[6.64375760300522] 39 | MF2='out1mf2':'constant',[12.2420004672653] 40 | MF3='out1mf3':'constant',[13.6716980879481] 41 | MF4='out1mf4':'constant',[12.6612486377696] 42 | MF5='out1mf5':'constant',[12.5830997817901] 43 | MF6='out1mf6':'constant',[7.12216679352668] 44 | MF7='out1mf7':'constant',[12.7664583819314] 45 | MF8='out1mf8':'constant',[14.3307737619534] 46 | MF9='out1mf9':'constant',[13.5308634202609] 47 | MF10='out1mf10':'constant',[14.0929083578285] 48 | MF11='out1mf11':'constant',[7.8050014230812] 49 | MF12='out1mf12':'constant',[9.7758338618063] 50 | MF13='out1mf13':'constant',[9.36369894996224] 51 | MF14='out1mf14':'constant',[7.63036795695339] 52 | MF15='out1mf15':'constant',[9.47368706129376] 53 | MF16='out1mf16':'constant',[2.29780798721785] 54 | MF17='out1mf17':'constant',[0.953665231968855] 55 | MF18='out1mf18':'constant',[0.819689047038176] 56 | MF19='out1mf19':'constant',[1.05923937674022] 57 | MF20='out1mf20':'constant',[1.22275411863244] 58 | MF21='out1mf21':'constant',[1.97538253482103] 59 | MF22='out1mf22':'constant',[2.0338764423938] 60 | MF23='out1mf23':'constant',[1.95061772193759] 61 | MF24='out1mf24':'constant',[1.93113973202651] 62 | MF25='out1mf25':'constant',[1.96510424755866] 63 | 64 | [Rules] 65 | 1 1, 1 (1) : 1 66 | 1 2, 2 (1) : 1 67 | 1 3, 3 (1) : 1 68 | 1 4, 4 (1) : 1 69 | 1 5, 5 (1) : 1 70 | 2 1, 6 (1) : 1 71 | 2 2, 7 (1) : 1 72 | 2 3, 8 (1) : 1 73 | 2 4, 9 (1) : 1 74 | 2 5, 10 (1) : 1 75 | 3 1, 11 (1) : 1 76 | 3 2, 12 (1) : 1 77 | 3 3, 13 (1) : 1 78 | 3 4, 14 (1) : 1 79 | 3 5, 15 (1) : 1 80 | 4 1, 16 (1) : 1 81 | 4 2, 17 (1) : 1 82 | 4 3, 18 (1) : 1 83 | 4 4, 19 (1) : 1 84 | 4 5, 20 (1) : 1 85 | 5 1, 21 (1) : 1 86 | 5 2, 22 (1) : 1 87 | 5 3, 23 (1) : 1 88 | 5 4, 24 (1) : 1 89 | 5 5, 25 (1) : 1 90 | -------------------------------------------------------------------------------- /files/neurofuzzy_system_3_rules.fis: -------------------------------------------------------------------------------- 1 | [System] 2 | Name='immortal_aek2' 3 | Type='sugeno' 4 | Version=2.0 5 | NumInputs=2 6 | NumOutputs=1 7 | NumRules=25 8 | AndMethod='prod' 9 | OrMethod='probor' 10 | ImpMethod='prod' 11 | AggMethod='sum' 12 | DefuzzMethod='wtaver' 13 | 14 | [Input1] 15 | Name='input1' 16 | Range=[0 180] 17 | NumMFs=5 18 | MF1='in1mf1':'gaussmf',[19.2572134542684 0.0690441675641779] 19 | MF2='in1mf2':'gaussmf',[19.7518020242362 45.4869973098739] 20 | MF3='in1mf3':'gaussmf',[17.4645961728319 88.7759418687326] 21 | MF4='in1mf4':'gaussmf',[20.5137120980576 133.59743218911] 22 | MF5='in1mf5':'gaussmf',[19.3353101851126 179.890611909391] 23 | 24 | [Input2] 25 | Name='input2' 26 | Range=[0 384] 27 | NumMFs=5 28 | MF1='in2mf1':'gaussmf',[40.6569101143404 -0.0831525078274382] 29 | MF2='in2mf2':'gaussmf',[40.7962614547148 95.9414584674689] 30 | MF3='in2mf3':'gaussmf',[40.7578269486047 191.968362681859] 31 | MF4='in2mf4':'gaussmf',[40.788428323713 287.950825744478] 32 | MF5='in2mf5':'gaussmf',[40.8046183704765 383.971319363499] 33 | 34 | [Output1] 35 | Name='output' 36 | Range=[1.6173 13.38] 37 | NumMFs=25 38 | MF1='out1mf1':'constant',[5.93999203276595] 39 | MF2='out1mf2':'constant',[13.2745389171899] 40 | MF3='out1mf3':'constant',[13.0773415155507] 41 | MF4='out1mf4':'constant',[13.4750901445826] 42 | MF5='out1mf5':'constant',[-2.65859894343671] 43 | MF6='out1mf6':'constant',[9.14433643087119] 44 | MF7='out1mf7':'constant',[14.2082559615645] 45 | MF8='out1mf8':'constant',[13.6513373218089] 46 | MF9='out1mf9':'constant',[13.3694062236808] 47 | MF10='out1mf10':'constant',[14.5648038584222] 48 | MF11='out1mf11':'constant',[8.07797818906007] 49 | MF12='out1mf12':'constant',[9.79077614041422] 50 | MF13='out1mf13':'constant',[8.326471711406] 51 | MF14='out1mf14':'constant',[12.6082022615384] 52 | MF15='out1mf15':'constant',[6.76183797866624] 53 | MF16='out1mf16':'constant',[0.877189017052452] 54 | MF17='out1mf17':'constant',[1.51857774928753] 55 | MF18='out1mf18':'constant',[0.897131804758584] 56 | MF19='out1mf19':'constant',[0.576704941040862] 57 | MF20='out1mf20':'constant',[0.70457361492718] 58 | MF21='out1mf21':'constant',[2.46036749034313] 59 | MF22='out1mf22':'constant',[1.89485442801724] 60 | MF23='out1mf23':'constant',[1.93843191825479] 61 | MF24='out1mf24':'constant',[1.95860789109482] 62 | MF25='out1mf25':'constant',[2.14879603712628] 63 | 64 | [Rules] 65 | 1 1, 1 (1) : 1 66 | 1 2, 2 (1) : 1 67 | 1 3, 3 (1) : 1 68 | 1 4, 4 (1) : 1 69 | 1 5, 5 (1) : 1 70 | 2 1, 6 (1) : 1 71 | 2 2, 7 (1) : 1 72 | 2 3, 8 (1) : 1 73 | 2 4, 9 (1) : 1 74 | 2 5, 10 (1) : 1 75 | 3 1, 11 (1) : 1 76 | 3 2, 12 (1) : 1 77 | 3 3, 13 (1) : 1 78 | 3 4, 14 (1) : 1 79 | 3 5, 15 (1) : 1 80 | 4 1, 16 (1) : 1 81 | 4 2, 17 (1) : 1 82 | 4 3, 18 (1) : 1 83 | 4 4, 19 (1) : 1 84 | 4 5, 20 (1) : 1 85 | 5 1, 21 (1) : 1 86 | 5 2, 22 (1) : 1 87 | 5 3, 23 (1) : 1 88 | 5 4, 24 (1) : 1 89 | 5 5, 25 (1) : 1 90 | -------------------------------------------------------------------------------- /src/standard_plans.m: -------------------------------------------------------------------------------- 1 | function maps = standard_plans() 2 | % Create the standard plans to test our fuzzy system and train our 3 | % neurofuzzy system. 4 | 5 | maps = cell(7, 1); 6 | maps{1} = [1 1 1 0 1 0 1 0 1; 7 | 0 2 0 0 0 0 0 0 0; 8 | 1 0 0 0 0 1 1 0 1; 9 | 0 0 0 0 0 0 1 0 0; 10 | 1 0 0 0 0 0 0 0 1; 11 | 1 0 1 0 0 0 0 0 1; 12 | 1 0 1 1 0 0 0 0 1; 13 | 0 0 0 0 0 0 0 3 1; 14 | 1 0 1 0 1 0 1 1 1]; 15 | 16 | maps{2} = [2 0 0 0 0 0 0 0 0 0 0; 17 | 0 1 0 1 0 1 0 1 0 1 0; 18 | 0 0 0 0 0 0 0 0 0 0 0; 19 | 0 1 0 1 1 1 0 1 0 1 0; 20 | 0 0 0 1 0 1 0 0 0 0 0; 21 | 0 1 0 1 1 1 0 1 0 1 0; 22 | 0 0 0 0 0 0 0 0 0 0 0; 23 | 0 1 0 1 0 1 0 1 1 1 0; 24 | 0 0 0 0 0 0 0 1 0 1 0; 25 | 0 1 0 1 0 1 0 1 1 1 0; 26 | 0 0 0 0 0 0 0 0 0 0 3]; 27 | 28 | maps{3} = [2 0 0 0 0 0 0 0 0 0 0; 29 | 0 1 0 1 0 1 0 1 0 1 0; 30 | 0 0 0 0 0 0 0 0 0 0 0; 31 | 0 1 0 1 1 1 0 1 0 1 0; 32 | 0 0 0 1 0 1 0 0 0 0 0; 33 | 0 1 0 1 1 1 0 1 0 1 0; 34 | 0 0 0 0 0 0 0 0 0 0 0; 35 | 0 1 0 1 0 1 0 0 1 0 0; 36 | 0 0 0 0 0 0 0 1 1 1 0; 37 | 0 1 0 1 0 1 0 0 1 0 0; 38 | 0 0 0 0 0 0 0 0 0 0 3]; 39 | 40 | maps{4} = [1 0 1 1 0 1 0 1 0 1 1; 41 | 0 0 0 0 0 0 0 0 0 0 1; 42 | 0 0 0 0 0 0 0 0 0 0 1; 43 | 2 0 1 0 1 0 1 0 1 3 1; 44 | 0 0 0 0 0 0 0 0 0 0 1; 45 | 1 0 0 1 1 0 0 0 0 0 1; 46 | 1 0 0 0 0 1 1 0 0 1 0; 47 | 1 0 0 1 0 0 0 0 0 1 0; 48 | 0 0 0 0 0 0 0 0 1 1 0; 49 | 0 0 0 0 0 0 0 0 0 0 0; 50 | 1 0 0 1 0 1 0 1 1 0 1]; 51 | 52 | maps{5} = [1 1 0 1 0 0 0 1 1 0 1 1; 53 | 1 1 0 0 0 1 1 0 0 3 0 1; 54 | 0 0 0 0 0 0 0 0 1 1 0 0; 55 | 1 0 0 1 0 0 0 0 1 0 0 0; 56 | 0 0 0 1 1 1 1 0 0 1 1 0; 57 | 1 0 0 1 0 1 0 0 1 1 1 1; 58 | 1 1 0 0 0 0 0 1 0 1 0 1; 59 | 0 0 0 1 1 0 0 0 0 0 1 0; 60 | 0 0 0 0 0 0 0 0 0 0 0 0; 61 | 2 1 0 1 0 1 0 1 0 1 1 1; 62 | 0 1 1 1 0 1 1 1 0 1 0 1]; 63 | 64 | maps{6} = [1 1 0 1 0 0 0 1 1 0 1 1; 65 | 1 3 0 0 0 1 1 0 0 0 0 1; 66 | 0 0 0 0 0 0 0 0 1 1 0 0; 67 | 1 0 0 0 0 0 0 0 1 0 0 0; 68 | 0 0 0 1 0 1 1 0 0 1 1 0; 69 | 1 0 0 1 0 1 0 0 1 1 1 1; 70 | 1 0 0 0 0 1 0 1 0 1 0 1; 71 | 0 0 0 1 1 0 0 0 0 0 1 0; 72 | 0 1 1 1 0 0 1 0 0 0 0 0; 73 | 0 0 2 0 0 1 0 1 0 1 1 1; 74 | 0 1 1 1 0 1 1 1 0 1 0 1]; 75 | 76 | maps{7} = [1 0 1 0 1 0 1 0 1; 77 | 0 0 0 0 0 0 0 3 0; 78 | 1 0 0 1 1 1 1 0 1; 79 | 0 0 1 1 0 0 1 0 0; 80 | 1 0 0 0 0 0 1 0 1; 81 | 0 0 0 2 0 1 1 0 0; 82 | 1 0 0 0 0 1 0 0 1; 83 | 0 1 0 0 0 0 0 0 0; 84 | 1 0 1 0 1 0 1 0 1]; 85 | -------------------------------------------------------------------------------- /src/do_step.m: -------------------------------------------------------------------------------- 1 | function [x, y] = do_step(current_position_x, current_position_y, step_x, step_y) 2 | 3 | global map; 4 | global map_size; 5 | 6 | global goal_position_x; 7 | global goal_position_y; 8 | 9 | if (step_x > 0) 10 | true_step_x = step_x; 11 | for i = 1:1:step_x 12 | if (current_position_x + i > map_size) 13 | true_step_x = i - 1; 14 | break; 15 | elseif current_position_y == goal_position_y && current_position_x + i == goal_position_x 16 | true_step_x = i; 17 | break; 18 | elseif map(current_position_y,current_position_x + i) == 0 19 | true_step_x = i - 1; 20 | break; 21 | end 22 | end 23 | 24 | x = current_position_x + true_step_x; 25 | y = current_position_y; 26 | 27 | if (true_step_x > 0) 28 | map(current_position_y,current_position_x + 1:current_position_x + true_step_x) = 0.5; 29 | end 30 | elseif (step_x < 0) 31 | true_step_x = step_x; 32 | for i = -1:-1:step_x 33 | if (current_position_x + i <= 0) 34 | true_step_x = i + 1; 35 | break; 36 | elseif current_position_y == goal_position_y && current_position_x + i == goal_position_x 37 | true_step_x = i; 38 | break; 39 | elseif map(current_position_y,current_position_x + i) == 0 40 | true_step_x = i + 1; 41 | break; 42 | end 43 | end 44 | 45 | x = current_position_x + true_step_x; 46 | y = current_position_y; 47 | 48 | if (true_step_x < 0) 49 | map(current_position_y,current_position_x + true_step_x:current_position_x - 1) = 0.5; 50 | end 51 | 52 | elseif (step_y > 0) 53 | true_step_y = step_y; 54 | for i = 1:1:step_y 55 | if (current_position_y + i > map_size) 56 | true_step_y = i - 1; 57 | break; 58 | elseif current_position_x == goal_position_x && current_position_y + i == goal_position_y 59 | true_step_y = i; 60 | break; 61 | elseif map(current_position_y + i,current_position_x) == 0 62 | true_step_y = i - 1; 63 | break; 64 | end 65 | end 66 | 67 | x = current_position_x; 68 | y = current_position_y + true_step_y; 69 | 70 | if (true_step_y > 0) 71 | map(current_position_y + 1:current_position_y + true_step_y,current_position_x) = 0.5; 72 | end 73 | 74 | elseif (step_y < 0) 75 | true_step_y = step_y; 76 | for i = -1:-1:step_y 77 | if (current_position_y + i <= 0) 78 | true_step_y = i + 1; 79 | break; 80 | elseif current_position_x == goal_position_x && current_position_y + i == goal_position_y 81 | true_step_y = i; 82 | break; 83 | elseif map(current_position_y + i,current_position_x) == 0 84 | true_step_y = i + 1; 85 | break; 86 | end 87 | end 88 | 89 | x = current_position_x; 90 | y = current_position_y + true_step_y; 91 | 92 | if (true_step_y < 0) 93 | map(current_position_y + true_step_y:current_position_y - 1,current_position_x) = 0.5; 94 | end 95 | end 96 | --------------------------------------------------------------------------------