├── 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 |
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 |
--------------------------------------------------------------------------------