├── README.md ├── RRT-2-Agents ├── RRT - 2 Agents │ ├── .DS_Store │ ├── AIprojectMain.m │ ├── Agent.m │ ├── Map0.bmp │ ├── Map1.bmp │ ├── README.txt │ └── RRT.m └── __MACOSX │ ├── ._RRT - 2 Agents │ └── RRT - 2 Agents │ ├── ._.DS_Store │ ├── ._AIprojectMain.m │ ├── ._Agent.m │ ├── ._Map0.bmp │ ├── ._Map1.bmp │ ├── ._README.txt │ └── ._RRT.m ├── RRT-3-Agents ├── RRT - 3 Agents │ ├── .DS_Store │ ├── AIprojectMain.m │ ├── Agent.m │ ├── Map0.bmp │ ├── Map1.bmp │ ├── README.txt │ └── RRT.m └── __MACOSX │ ├── ._ RRT - 3 Agents │ └── RRT - 3 Agents │ ├── ._.DS_Store │ ├── ._AIprojectMain.m │ ├── ._Agent.m │ ├── ._Map0.bmp │ ├── ._Map1.bmp │ ├── ._README.txt │ └── ._RRT.m └── Thumbs.db /README.md: -------------------------------------------------------------------------------- 1 | # MultiAgentRRT 2 | Multi Agent Task sharing implementation using RRT algorithm. Implementation in MatLab 3 | 4 | # Report 5 | hteeteeps://drive.google.com/open?id=0B8WGYNv1KrmrcEtQQXh6X2xoY3M 6 | # Presentation 7 | 8 | hteeteeps://drive.google.com/open?id=0B8WGYNv1KrmrRzdOTi1jZjg1TDA 9 | 10 | # Revert the changes in the protocol to get access to the link. 11 | -------------------------------------------------------------------------------- /RRT-2-Agents/RRT - 2 Agents/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RohinMohanadas/MultiAgentRRT/d3f305746adf955290006548de58aec164e7bcdd/RRT-2-Agents/RRT - 2 Agents/.DS_Store -------------------------------------------------------------------------------- /RRT-2-Agents/RRT - 2 Agents/AIprojectMain.m: -------------------------------------------------------------------------------- 1 | %*****************************************************************************************************% 2 | %* *% 3 | %* NAME: AIprojectMain *% 4 | %* DESCRIPTION: Multi-Agent tile painting using RRT *% 5 | %* AUTHOR: Team 19 *% 6 | %* DATE CREATION:08/10/2016 *% 7 | %* LAST MODIFIED:14/10/2016 *% 8 | %* *% 9 | %*****************************************************************************************************% 10 | 11 | % This main class deals with the followin functions 12 | % 1. Read an 8 bit image and load it into a matrix. 13 | % 2. Modify the image matrix to the form that is suited to RRT processing. 14 | % 3. Initialize the agents. 15 | % 4. Assign Random Starting points to the two agents conforming with the boundaries. 16 | % 5. Decide which agent is going to start the proceedings and call the agent's RRT function with the matrix passed by value 17 | 18 | % Define numer of agents 19 | AGENT_COUNT = 2; 20 | 21 | % Load Map 22 | MainImage = importdata('Map0.bmp'); 23 | GlobalCopy = MainImage(1).cdata; 24 | [Xmax,Ymax] = size(GlobalCopy); 25 | GlobalCopy(GlobalCopy==79) = 5; % 79 -> 5 (Red to obstacles) 26 | GlobalCopy(GlobalCopy==0) = 2; % 0 -> 2 (Black cell to picture to be painted) 27 | GlobalCopy(GlobalCopy==255) = 0; % 255 -> 0 (White to Empty Cell) 28 | 29 | valid = false; 30 | 31 | for i=1:AGENT_COUNT 32 | while(valid == false) 33 | Xinit(i) = ceil((Xmax-1)*rand); 34 | Yinit(i) = ceil((Ymax-1)*rand); 35 | Position = [Xinit(i),Yinit(i)]; 36 | if(GlobalCopy(Xinit,Yinit) ~= 5) 37 | A(i) = Agent(Position,GlobalCopy); 38 | valid = true; 39 | end; 40 | end; 41 | valid = false; 42 | end; 43 | 44 | 45 | %AgentMap = zeros(Xmax,Ymax); %Map that holds agent's workspace 46 | %To identify the processs start 47 | Counter = 0; 48 | 49 | if(isempty(A(1).path)) 50 | A(1) = calculatePath(A(1),[]); %its initial, opPosition's path will be empty 51 | A(1) = assignpath(A(1)); 52 | A(1) = updateMap(A(1),A(1).goal,3); 53 | A(2) = updateMap(A(2),A(1).goal,3); 54 | end; 55 | if(isempty(A(2).path)) 56 | A(2) = calculatePath(A(2),A(1).path); %its initial, 57 | A(2) = assignpath(A(2)); 58 | A(1) = updateMap(A(1),A(2).goal,3); 59 | A(2) = updateMap(A(2),A(2).goal,3); 60 | end; 61 | 62 | obstacledMap = GlobalCopy; 63 | obstacledMap(obstacledMap==2) = 5; 64 | 65 | while(~isequal(A(1).Map,obstacledMap) || ~isequal(A(2).Map,obstacledMap)) %While (the map is not the goal map) iterate 66 | 67 | fprintf('timestep:%d , A(1) in position [%d %d] and A(2) in position [%d %d]\n',Counter,A(1).Position(1),A(1).Position(2),A(2).Position(1),A(2).Position(2)); 68 | fprintf('timestep:%d , A(1) wants to paint [%d %d] and A(2) wants to paint [%d %d]\n',Counter,A(1).goal(1),A(1).goal(2),A(2).goal(1),A(2).goal(2)); 69 | 70 | Counter = Counter + 1; % increase counter 71 | 72 | % Call the move function on both the agents and handle the results 73 | % below. The only place in the while loop where move will be called 74 | 75 | 76 | if(mod(Counter,1)==0) %update the plan of the agent that offers the best bid 77 | 78 | % Calculate potential path for all agents. avoid targeting the same goals 79 | 80 | if A(2).Map(A(2).goal(1),A(2).goal(2)) == 3 && A(1).Map(A(2).goal(1),A(2).goal(2)) == 3 81 | A(1) = updateMap(A(1),A(2).goal,2); 82 | A(2) = updateMap(A(2),A(2).goal,2); 83 | end 84 | if A(1).Map(A(1).goal(1),A(1).goal(2)) == 3 && A(2).Map(A(1).goal(1),A(1).goal(2)) == 3 85 | A(1) = updateMap(A(1),A(1).goal,2); 86 | A(2) = updateMap(A(2),A(1).goal,2); 87 | end 88 | 89 | % Both agents calculate a posible new path 90 | 91 | A(1) = calculatePath(A(1),A(2).path); 92 | 93 | if ~isequal(A(1).Position,A(1).posiblegoal) 94 | A(2) = updateMap(A(2),A(1).posiblegoal,3); %prevent the 2 agents to go to the same goal 95 | A(2) = calculatePath(A(2),A(1).path); 96 | A(2) = updateMap(A(2),A(1).posiblegoal,2); %change the map back 97 | end 98 | 99 | 100 | % The bids are compared and, if there is an averall improvement of 101 | % the task, one of the agent updated his path 102 | if(A(1).Bid > 0 || A(2).Bid > 0) || A(2).Bid < 100 || A(1).Bid < 100 103 | if(A(2).Bid > A(1).Bid) && ~isequal(A(2).Position,A(2).posiblegoal) && ~isequal(A(1).goal,A(2).posiblegoal) 104 | fprintf('\nA(2) replans\n\n') 105 | A(2) = assignpath(A(2)); 106 | A(1) = updateMap(A(1),A(2).goal,3); 107 | A(2) = updateMap(A(2),A(2).goal,3); 108 | 109 | if ~isequal(A(1).Position,A(1).goal) 110 | A(1) = updateMap(A(1),A(1).goal,3); 111 | A(2) = updateMap(A(2),A(1).goal,3); 112 | end 113 | 114 | elseif ~isequal(A(1).Position,A(1).posiblegoal) && ~isequal(A(2).goal,A(1).posiblegoal) 115 | fprintf('\nA(1) replans\n\n') 116 | A(1) = assignpath(A(1)); 117 | A(1) = updateMap(A(1),A(1).goal,3); 118 | A(2) = updateMap(A(2),A(1).goal,3); 119 | 120 | if ~isequal(A(2).Position,A(2).goal) 121 | A(1) = updateMap(A(1),A(2).goal,3); 122 | A(2) = updateMap(A(2),A(2).goal,3); 123 | end 124 | end 125 | end 126 | end 127 | 128 | %Agents move forward 129 | 130 | A(1) = move(A(1)); 131 | A(2) = move(A(2)); 132 | 133 | %Verify that any agent hit an obstacle and that they are not in the same position 134 | 135 | if A(1).Map(A(1).Position(1),A(1).Position(2)) == 5 && A(1).lastMove == 1 136 | fprintf('\nHit an obstacle!: %d %d by A(1)\n\n',A(1).Position(1),A(1).Position(2)); 137 | end 138 | if A(2).Map(A(2).Position(1),A(2).Position(2)) == 5 && A(2).lastMove == 1 139 | fprintf('\nHit an obstacle!: %d %d by A(2)\n\n',A(2).Position(1),A(2).Position(2)); 140 | end 141 | if isequal(A(2).Position,A(1).Position) && A(1).lastMove == 1 && A(2).lastMove == 1 142 | fprintf('\nAgents crashed!!\n\n') 143 | end 144 | 145 | if (isequal(A(2).goal,A(2).Position)) && (A(2).Map(A(2).Position(1),A(2).Position(2))~=5) && (A(1).Map(A(2).Position(1),A(2).Position(2))~=5) && A(2).lastMove == 1 % one agent is still on the move. 146 | 147 | A(1) = updateMap(A(1),A(2).goal,5); 148 | A(2) = updateMap(A(2),A(2).goal,5); 149 | 150 | fprintf('A(2) painted a tile : %d,%d\n',A(2).goal(1),A(2).goal(2)); 151 | 152 | end 153 | 154 | if (isequal(A(1).goal,A(1).Position)) && (A(1).Map(A(1).Position(1),A(1).Position(2))~=5) && (A(2).Map(A(1).Position(1),A(1).Position(2))~=5) && A(1).lastMove == 1 % one agent is still on the move. 155 | 156 | A(1) = updateMap(A(1),A(1).goal,5); 157 | A(2) = updateMap(A(2),A(1).goal,5); 158 | 159 | fprintf('A(1) painted a tile : %d,%d\n',A(1).goal(1),A(1).goal(2)); 160 | 161 | end 162 | end 163 | 164 | fprintf('Time take for the Multi Agent planning :%d\n',Counter); -------------------------------------------------------------------------------- /RRT-2-Agents/RRT - 2 Agents/Agent.m: -------------------------------------------------------------------------------- 1 | classdef Agent 2 | 3 | %*****************************************************************************************************% 4 | %* *% 5 | %* NAME: Agent *% 6 | %* DESCRIPTION: Class used to model the behavior of the agent performing the task *% 7 | %* AUTHOR: Team 19 *% 8 | %* DATE CREATION:08/10/2016 *% 9 | %* LAST MODIFIED:14/10/2016 *% 10 | %* *% 11 | %*****************************************************************************************************% 12 | 13 | properties 14 | Position %Current position of the agent (timestep k) 15 | Bid %Current Bid 16 | Map %Map used by the agent to campute RRT 17 | path %Current path 18 | timeSinceStart %Number of steps from the beginning of the path 19 | timeToGoal %Number of timesteps from the beginning of the path until the goal 20 | lastMove %Value of the last move (1 or 0) 21 | goal %Position of the current goal 22 | posiblepath %Potential new path 23 | posiblegoal %Potential new path 24 | lastPosition %Position in the previous timestep 25 | end 26 | 27 | methods 28 | 29 | %%Class Constructor 30 | function agent = Agent(position,currentMap) 31 | if nargin == 2 32 | agent.Position = position; 33 | agent.Map = currentMap; 34 | agent.timeSinceStart = 1; 35 | else 36 | error('Incorrect Number of Inputs for class Agent') 37 | end 38 | end 39 | 40 | %% Update the and the goal with posiblepath and posible goal 41 | function Agent = assignpath(Agent) %Value should be 1 or 0 42 | Agent.path = Agent.posiblepath; 43 | Agent.goal = Agent.posiblegoal; 44 | c = size(Agent.path); Agent.timeToGoal = c(1); 45 | Agent.timeSinceStart = 1; 46 | Agent.lastMove = 0; 47 | end 48 | 49 | %%Update the Agent Map with the desired value 50 | function Agent = updateMap(Agent,tile,value) %Updates the map of the agent with iformation from another agent 51 | Agent.Map(tile(1),tile(2)) = value; 52 | end 53 | 54 | %%Find the closest tile to paint, calculate a path to reach it and 55 | %%compute the bid 56 | function Agent = calculatePath(Agent,otherPath) %Calculates the path using RRT 57 | Agent = findClosestTile(Agent); 58 | r = RRT(Agent.Map , Agent.Position , Agent.posiblegoal); 59 | r = runRRT(r); 60 | Agent.posiblepath = r.path; 61 | size1 = size(Agent.posiblepath); 62 | size2 = size(otherPath); 63 | time = min(size1(1),size2(1)); 64 | for i = 2:time 65 | if Agent.posiblepath(i,1) == otherPath(i,1) && Agent.posiblepath(i,2) == otherPath(i,2) 66 | Agent.posiblepath = [Agent.posiblepath(1:i-1,:); Agent.posiblepath(i-1,:); Agent.posiblepath(i:end,:)];%stops twice in a tile if required 67 | end 68 | end 69 | oldcost = length(Agent.path); 70 | if (isequal(Agent.goal,Agent.Position)) && (Agent.lastMove == 1) 71 | Agent.Bid = - 100*length(Agent.posiblepath); 72 | elseif (isequal(Agent.goal,Agent.Position)) && (Agent.lastMove == 0) 73 | Agent.Bid = length(Agent.posiblepath); 74 | else 75 | Agent.Bid = oldcost - length(Agent.posiblepath); 76 | end 77 | Agent.lastPosition = Agent.Position; 78 | end 79 | 80 | %% Agent finds the closest tiles that needs to be painted 81 | function Agent = findClosestTile(Agent) %Returns position [row,column] of closest tile. [-1,-1] if there are no more tiles to paint 82 | [rows,columns] = find(Agent.Map); 83 | closestDistance = Inf; 84 | for i=1:length(rows) 85 | if Agent.Map(rows(i),columns(i)) == 2 86 | distance = abs(Agent.Position(1)-rows(i)) + abs(Agent.Position(2)-columns(i)); 87 | if distance < closestDistance 88 | closestDistance = distance; 89 | Agent.posiblegoal = [rows(i) columns(i)]; 90 | end 91 | end 92 | end 93 | end 94 | 95 | %% Agent moves one step forward according to the current plan 96 | function Agent = move(Agent) %returns 1 if the agent moved towards the goal, 0 if he already reached the goal 97 | Agent.lastMove = 0; 98 | Agent.lastPosition = Agent.Position; 99 | 100 | if Agent.timeSinceStart == Agent.timeToGoal && ~isequal(Agent.lastPosition,Agent.Position) 101 | Agent.lastMove = 1; 102 | end 103 | 104 | if Agent.timeSinceStart < Agent.timeToGoal 105 | Agent.Position = Agent.path(2,:); 106 | Agent.path = Agent.path(2:end,:); 107 | Agent.lastMove = 1; 108 | Agent.timeSinceStart = Agent.timeSinceStart + 1; 109 | end 110 | 111 | if Agent.timeSinceStart == 2 && isequal(Agent.lastPosition,Agent.Position) 112 | Agent.lastMove = 0; 113 | end 114 | end 115 | end 116 | end 117 | 118 | -------------------------------------------------------------------------------- /RRT-2-Agents/RRT - 2 Agents/Map0.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RohinMohanadas/MultiAgentRRT/d3f305746adf955290006548de58aec164e7bcdd/RRT-2-Agents/RRT - 2 Agents/Map0.bmp -------------------------------------------------------------------------------- /RRT-2-Agents/RRT - 2 Agents/Map1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RohinMohanadas/MultiAgentRRT/d3f305746adf955290006548de58aec164e7bcdd/RRT-2-Agents/RRT - 2 Agents/Map1.bmp -------------------------------------------------------------------------------- /RRT-2-Agents/RRT - 2 Agents/README.txt: -------------------------------------------------------------------------------- 1 | # Multi Agent Tile Painting 2 | 3 | #Run the Program in Matlab 4 | run AIprojectMain 5 | 6 | #Several Maps are offered in order to test the program in different environments 7 | in line 22 of AIprojectMain, modify MainImage = importdata('XXXXXXX.bmp') where XXXXXXX is the name of the desired map 8 | 9 | 10 | -------------------------------------------------------------------------------- /RRT-2-Agents/RRT - 2 Agents/RRT.m: -------------------------------------------------------------------------------- 1 | classdef RRT 2 | 3 | %*****************************************************************************************************% 4 | %* *% 5 | %* NAME: RRT *% 6 | %* DESCRIPTION: *% 7 | %* AUTHOR: *% 8 | %* DATE CREATION:09/10/2016 *% 9 | %* LAST MODIFIED:10/12/2016 *% 10 | %* *% 11 | %*****************************************************************************************************% 12 | 13 | properties 14 | initialMap %number of timesteps from the beginning of the path until the goal 15 | initialPosition % value of the last move (1 or 0) 16 | goal %position of the current goal 17 | n %number of rows/columns 18 | N %number of tiles in the map (N=nxn) 19 | path %sequence of positions from initialPosition to goal 20 | path_found %boolean to indicate that a path has been found 21 | finalMap %Map with 1's on the path positions 22 | end 23 | 24 | methods 25 | %%Class Constructor 26 | function rrt = RRT(Map,Position,Goal) 27 | if nargin == 3 28 | rrt.initialMap = Map; 29 | rrt.initialPosition = Position; 30 | rrt.goal = Goal; 31 | s = size(rrt.initialMap); 32 | rrt.N = s(1)*s(2); 33 | rrt.n = s(1); 34 | rrt.path_found = false; 35 | else 36 | error('Incorrect Number of Inputs for class Agent') 37 | end 38 | end 39 | 40 | function rrt = runRRT(rrt) %Value should be 1 or 0 41 | tree = zeros(rrt.N,2); 42 | parent = zeros(rrt.N,1); 43 | node_x = zeros(1,rrt.N); 44 | node_y = zeros(1,rrt.N); 45 | node_x(1) = rrt.initialPosition(1); 46 | node_y(1) = rrt.initialPosition(2); 47 | tree(1,:) = [node_x(1),node_y(1)]; 48 | rrt.initialMap(node_x(1),node_y(1)) = 1; 49 | loop_count = 0; 50 | no_path = false; 51 | 52 | for i = 2:rrt.N 53 | is_valid = false; 54 | while (is_valid == false) 55 | if(nnz(~rrt.initialMap) == 0) %all map elements have been filled 56 | break; 57 | end 58 | %find a sample node 59 | random_node = randomNode(rrt,node_x,node_y); 60 | %Finding the nearest node 61 | nearest_node = nearestNode(rrt,node_x,node_y,random_node); 62 | %get the new node 63 | new_node = newNode(rrt,random_node,nearest_node); 64 | %check if new node is in collision => rerun that loop 65 | is_valid = detectObstacle(rrt,new_node,is_valid); 66 | %update loop count of this while loop 67 | loop_count = loop_count + 1; 68 | if(loop_count > rrt.N^2) 69 | break; 70 | end 71 | end 72 | 73 | if(loop_count > rrt.N^2) 74 | disp('Leaving RRT: No path found'); 75 | break; 76 | end 77 | 78 | %add the new nodes to node history 79 | node_x(i) = new_node(1); 80 | node_y(i) = new_node(2); 81 | %fprintf('new node: (%d,%d)\n', new_node(1),new_node(2)); 82 | 83 | %update tree 84 | tree(i,:) = new_node; 85 | %find the index of the location of the nearest node in tree (find 86 | %parent) 87 | for index = 1:i 88 | if nearest_node == [node_x(index)',node_y(index)'] 89 | parent(i) = index; 90 | end 91 | end 92 | 93 | %show entire map with all trees (not necessary) 94 | rrt.initialMap(new_node(1),new_node(2)) = 1; 95 | %disp(map); 96 | 97 | %check to see if you have reached goal -- get rrt_path 98 | if (rrt.initialMap(rrt.goal(1),rrt.goal(2)) == 1) 99 | %fprintf('Found goal in %d iterations\n', i); 100 | %trace back your path: 101 | rrt.path = getPath(rrt,tree,parent,i); 102 | break; %breaks loop if you have reached the end 103 | end 104 | 105 | %if(loop_count >= N^2) 106 | if(nnz(~rrt.initialMap) == 0) 107 | no_path = true; 108 | disp('Leaving RRT: No path found'); 109 | break; 110 | end 111 | end 112 | 113 | %create an updated rrt map that shows path 114 | if(no_path == false && loop_count < rrt.N^2) 115 | rrt.path_found = true; %indicates path has been found 116 | %create an updated rrt map that shows path 117 | rrt.finalMap = getPathMap(rrt); 118 | end 119 | end 120 | 121 | function random_node = randomNode(rrt,node_x,node_y) 122 | valid = false; 123 | random_node = randi([1,rrt.n],1,2); 124 | k = 1; 125 | while (valid == false) 126 | if ((random_node(1) == node_x(k) && random_node(2) == node_y(k)) || (rrt.initialMap(random_node(1),random_node(2)) == 5)) 127 | random_node = randi([1,rrt.n],1,2); 128 | k = 1; 129 | continue; 130 | end 131 | if (k == size(node_x,2)) 132 | valid = true; 133 | end 134 | k = k+1; 135 | end 136 | %fprintf('random node: (%d,%d)\n', random_node(1),random_node(2)); 137 | end 138 | 139 | function nearest_node = nearestNode(rrt, node_x,node_y,random_node) 140 | if (length(find(node_x)) == 1) %finds the number of non-zero elements 141 | nearest_node = [node_x(1),node_y(1)]; 142 | else 143 | nearest_node = [node_x(1),node_y(1)]; 144 | distance = sqrt((random_node(1)-node_x(1))^2 + (random_node(2)-node_y(1))^2); 145 | for j = 2:length(find(node_x)) 146 | tmp = sqrt((random_node(1)-node_x(j))^2 + (random_node(2)-node_y(j))^2); %Euclidean distance 147 | if (tmp < distance) 148 | nearest_node = [node_x(j),node_y(j)]; %finds the nearest node by searching min 149 | distance = tmp; 150 | end 151 | end 152 | end 153 | %fprintf('nearest node: (%d,%d)\n', nearest_node(1),nearest_node(2)); 154 | end 155 | 156 | function new_node = newNode(rrt,random_node,nearest_node) 157 | %Agent movements 158 | up = [-1,0]; 159 | down = [1,0]; 160 | left = [0,-1]; 161 | right = [0,1]; 162 | 163 | %find the slope from nearest_node to random_node: y_diff/x_diff 164 | y_diff = random_node(1)-nearest_node(1); 165 | x_diff = random_node(2)-nearest_node(2); 166 | if (abs(x_diff) > 0 && (abs(x_diff) < abs(y_diff) || y_diff == 0))%the lesser slope difference is the one that's added 167 | if (x_diff > 0) 168 | new_node = nearest_node+right; 169 | else 170 | new_node = nearest_node+left; 171 | end 172 | elseif (abs(y_diff) > 0) 173 | if (y_diff > 0) 174 | new_node = nearest_node+down; 175 | else 176 | new_node = nearest_node+up; 177 | end 178 | elseif (abs(x_diff) == abs(y_diff)) %if both are equally likely jsut choose randomly 179 | if (nearest_node(1) == rrt.n) %if you're at the row border, increase column 180 | new_node = [nearest_node(1), nearest_node(2)+1]; 181 | elseif (nearest_node(2) == rrt.n) 182 | new_node = [nearest_node(1)+1, nearest_node(2)]; 183 | else 184 | choice = randi(2); %choose between options randomly 185 | if (choice == 1) 186 | if (x_diff > 0) 187 | new_node = nearest_node + right; 188 | else 189 | new_node = nearest_node + left; 190 | end 191 | else 192 | if (y_diff > 0) 193 | new_node = nearest_node + down; 194 | else 195 | new_node = nearest_node + up; 196 | end 197 | end 198 | end 199 | end 200 | end 201 | 202 | function is_valid = detectObstacle(rrt, new_node, is_valid) 203 | if(rrt.initialMap(new_node(1),new_node(2)) ~= 5) 204 | is_valid = true; 205 | end 206 | end 207 | 208 | function rrt_path = getPath(rrt,tree,parent,current_index) 209 | rrt_path = zeros(current_index,2); 210 | for index = 1:current_index 211 | if (index == 1) 212 | rrt_path(index,:) = tree(current_index,:); 213 | ncol = size(rrt_path, 2); %getting rid of the unnecessary zeros 214 | rrt_path(rrt_path == 0) = []; 215 | rrt_path = reshape(rrt_path, [], ncol); 216 | child_of = parent(current_index); 217 | else 218 | if(child_of == 0) 219 | break; 220 | else 221 | rrt_path(index,:) = tree(child_of,:); 222 | child_of = parent(child_of); 223 | end 224 | end 225 | end 226 | rrt_path = flipud(rrt_path); %flipping the matrix 227 | end 228 | 229 | function rrt_map = getPathMap(rrt) 230 | rrt_map = zeros(rrt.n); 231 | for index = 1:size(rrt.path,1) 232 | rrt_map(rrt.path(index,1),rrt.path(index,2)) = 1; 233 | end 234 | end 235 | 236 | end 237 | end -------------------------------------------------------------------------------- /RRT-2-Agents/__MACOSX/._RRT - 2 Agents: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RohinMohanadas/MultiAgentRRT/d3f305746adf955290006548de58aec164e7bcdd/RRT-2-Agents/__MACOSX/._RRT - 2 Agents -------------------------------------------------------------------------------- /RRT-2-Agents/__MACOSX/RRT - 2 Agents/._.DS_Store: -------------------------------------------------------------------------------- 1 | Mac OS X  2Fx ATTRxx -------------------------------------------------------------------------------- /RRT-2-Agents/__MACOSX/RRT - 2 Agents/._AIprojectMain.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RohinMohanadas/MultiAgentRRT/d3f305746adf955290006548de58aec164e7bcdd/RRT-2-Agents/__MACOSX/RRT - 2 Agents/._AIprojectMain.m -------------------------------------------------------------------------------- /RRT-2-Agents/__MACOSX/RRT - 2 Agents/._Agent.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RohinMohanadas/MultiAgentRRT/d3f305746adf955290006548de58aec164e7bcdd/RRT-2-Agents/__MACOSX/RRT - 2 Agents/._Agent.m -------------------------------------------------------------------------------- /RRT-2-Agents/__MACOSX/RRT - 2 Agents/._Map0.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RohinMohanadas/MultiAgentRRT/d3f305746adf955290006548de58aec164e7bcdd/RRT-2-Agents/__MACOSX/RRT - 2 Agents/._Map0.bmp -------------------------------------------------------------------------------- /RRT-2-Agents/__MACOSX/RRT - 2 Agents/._Map1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RohinMohanadas/MultiAgentRRT/d3f305746adf955290006548de58aec164e7bcdd/RRT-2-Agents/__MACOSX/RRT - 2 Agents/._Map1.bmp -------------------------------------------------------------------------------- /RRT-2-Agents/__MACOSX/RRT - 2 Agents/._README.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RohinMohanadas/MultiAgentRRT/d3f305746adf955290006548de58aec164e7bcdd/RRT-2-Agents/__MACOSX/RRT - 2 Agents/._README.txt -------------------------------------------------------------------------------- /RRT-2-Agents/__MACOSX/RRT - 2 Agents/._RRT.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RohinMohanadas/MultiAgentRRT/d3f305746adf955290006548de58aec164e7bcdd/RRT-2-Agents/__MACOSX/RRT - 2 Agents/._RRT.m -------------------------------------------------------------------------------- /RRT-3-Agents/RRT - 3 Agents/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RohinMohanadas/MultiAgentRRT/d3f305746adf955290006548de58aec164e7bcdd/RRT-3-Agents/RRT - 3 Agents/.DS_Store -------------------------------------------------------------------------------- /RRT-3-Agents/RRT - 3 Agents/AIprojectMain.m: -------------------------------------------------------------------------------- 1 | %*****************************************************************************************************% 2 | %* *% 3 | %* NAME: AIprojectMain *% 4 | %* DESCRIPTION: Multi-Agent tile painting using RRT *% 5 | %* AUTHOR: Team 19 *% 6 | %* DATE CREATION:08/10/2016 *% 7 | %* LAST MODIFIED:14/10/2016 *% 8 | %* *% 9 | %*****************************************************************************************************% 10 | 11 | % This main class deals with the followin functions 12 | % 1. Read an 8 bit image and load it into a matrix. 13 | % 2. Modify the image matrix to the form that is suited to RRT processing. 14 | % 3. Initialize the agents. 15 | % 4. Assign Random Starting points to the two agents conforming with the boundaries. 16 | % 5. Decide which agent is going to start the proceedings and call the agent's RRT function with the matrix passed by value 17 | 18 | % Define numer of agents 19 | AGENT_COUNT = 3; 20 | 21 | % Load Map 22 | MainImage = importdata('Map0.bmp'); 23 | GlobalCopy = MainImage(1).cdata; 24 | [Xmax,Ymax] = size(GlobalCopy); 25 | GlobalCopy(GlobalCopy==79) = 5; % 79 -> 5 (Red to obstacles) 26 | GlobalCopy(GlobalCopy==0) = 2; % 0 -> 2 (Black cell to picture to be painted) 27 | GlobalCopy(GlobalCopy==255) = 0; % 255 -> 0 (White to Empty Cell) 28 | 29 | valid = false; 30 | 31 | for i=1:AGENT_COUNT 32 | while(valid == false) 33 | Xinit(i) = ceil((Xmax-1)*rand); 34 | Yinit(i) = ceil((Ymax-1)*rand); 35 | Position = [Xinit(i),Yinit(i)]; 36 | if(GlobalCopy(Xinit,Yinit) ~= 5) 37 | A(i) = Agent(Position,GlobalCopy); 38 | valid = true; 39 | end; 40 | end; 41 | valid = false; 42 | end; 43 | 44 | 45 | %AgentMap = zeros(Xmax,Ymax); %Map that holds agent's workspace 46 | %To identify the processs start 47 | Counter = 0; 48 | for i=1:AGENT_COUNT 49 | if(isempty(A(i).path)) 50 | A(i) = calculatePath(A(i),A(mod(i,3)+1).path,A(mod(i+1,3)+1).path); %its initial, opPosition's path will be empty 51 | A(i) = assignpath(A(i)); 52 | for j=1:AGENT_COUNT 53 | A(j) = updateMap(A(j),A(i).goal,3); 54 | end 55 | end; 56 | end 57 | 58 | obstacledMap = GlobalCopy; 59 | obstacledMap(obstacledMap==2) = 5; 60 | 61 | while(~isequal(A(1).Map,obstacledMap) && ~isequal(A(2).Map,obstacledMap) && ~isequal(A(3).Map,obstacledMap)) %While (the map is not the goal map) iterate 62 | 63 | fprintf('timestep:%d , A(1) in position [%d %d] , A(2) in position [%d %d] and A(3) in position [%d %d]\n',Counter,A(1).Position(1),A(1).Position(2),A(2).Position(1),A(2).Position(2),A(3).Position(1),A(3).Position(2)); 64 | fprintf('timestep:%d , A(1) wants to paint [%d %d] , A(2) wants to paint [%d %d] and A(3) wants to paint [%d %d]\n',Counter,A(1).goal(1),A(1).goal(2),A(2).goal(1),A(2).goal(2),A(3).goal(1),A(3).goal(2)); 65 | 66 | Counter = Counter + 1; % increase counter 67 | 68 | % Call the move function on both the agents and handle the results 69 | % below. The only place in the while loop where move will be called 70 | 71 | 72 | if(mod(Counter,1)==0) %update the plan of the agent that offers the best bid 73 | 74 | % Calculate potential path for all agents. avoid targeting the same goals 75 | 76 | for i=1:AGENT_COUNT 77 | if A(i).Map(A(i).goal(1),A(i).goal(2)) == 3 78 | for j=1:AGENT_COUNT 79 | A(j) = updateMap(A(j),A(i).goal,2); 80 | end 81 | end 82 | end 83 | 84 | %verify there are no more 3's in the map 85 | for i=1:AGENT_COUNT 86 | for j=1:size(A(i).Map,1) 87 | for g=1:size(A(i).Map,2) 88 | if A(i).Map(j,g)==3 89 | A(i).Map(j,g)=2; 90 | end 91 | end 92 | end 93 | end 94 | 95 | % Both agents calculate a posible new path 96 | 97 | A(1) = calculatePath(A(1),A(2).path,A(3).path); 98 | 99 | if ~isequal(A(1).Position,A(1).posiblegoal) 100 | A(2) = updateMap(A(2),A(1).posiblegoal,3); %prevent the 2 agents to go to the same goal 101 | A(2) = calculatePath(A(2),A(1).path,A(3).path); 102 | A(3) = updateMap(A(3),A(1).posiblegoal,3); 103 | if ~isequal(A(2).Position,A(2).posiblegoal) 104 | A(3) = updateMap(A(3),A(2).posiblegoal,3); 105 | A(3) = calculatePath(A(3),A(1).path,A(2).path); 106 | A(3) = updateMap(A(3),A(2).posiblegoal,2); 107 | end 108 | A(3) = updateMap(A(3),A(1).posiblegoal,2); 109 | A(2) = updateMap(A(2),A(1).posiblegoal,2); %change the map back 110 | end 111 | 112 | 113 | % The bids are compared and, if there is an averall improvement of 114 | % the task, one of the agent updated his path 115 | if A(1).Bid > 0 || A(2).Bid > 0 || A(3).Bid > 0 || A(2).Bid < 100 || A(1).Bid < 100 || A(3).Bid < 100 116 | if(A(2).Bid > A(1).Bid && A(2).Bid > A(3).Bid) && ~isequal(A(2).Position,A(2).posiblegoal) && ~isequal(A(1).goal,A(2).posiblegoal) && ~isequal(A(3).goal,A(2).posiblegoal) 117 | fprintf('\nA(2) replans\n\n') 118 | A(2) = assignpath(A(2)); 119 | A(1) = updateMap(A(1),A(2).goal,3); 120 | A(2) = updateMap(A(2),A(2).goal,3); 121 | A(3) = updateMap(A(3),A(2).goal,3); 122 | 123 | if ~isequal(A(1).Position,A(1).goal) 124 | A(1) = updateMap(A(1),A(1).goal,3); 125 | A(2) = updateMap(A(2),A(1).goal,3); 126 | end 127 | 128 | if ~isequal(A(3).Position,A(3).goal) 129 | A(1) = updateMap(A(1),A(3).goal,3); 130 | A(2) = updateMap(A(2),A(3).goal,3); 131 | end 132 | 133 | elseif (A(1).Bid > A(2).Bid && A(1).Bid > A(3).Bid) && ~isequal(A(1).Position,A(1).posiblegoal) && ~isequal(A(2).goal,A(1).posiblegoal) && ~isequal(A(3).goal,A(1).posiblegoal) 134 | fprintf('\nA(1) replans\n\n') 135 | A(1) = assignpath(A(1)); 136 | A(1) = updateMap(A(1),A(1).goal,3); 137 | A(2) = updateMap(A(2),A(1).goal,3); 138 | A(3) = updateMap(A(3),A(1).goal,3); 139 | 140 | if ~isequal(A(2).Position,A(2).goal) 141 | A(1) = updateMap(A(1),A(2).goal,3); 142 | A(2) = updateMap(A(2),A(2).goal,3); 143 | end 144 | 145 | if ~isequal(A(3).Position,A(3).goal) 146 | A(1) = updateMap(A(1),A(3).goal,3); 147 | A(2) = updateMap(A(2),A(3).goal,3); 148 | end 149 | elseif (A(3).Bid > A(1).Bid && A(3).Bid > A(2).Bid) && ~isequal(A(3).Position,A(3).posiblegoal) && ~isequal(A(2).goal,A(3).posiblegoal) && ~isequal(A(1).goal,A(3).posiblegoal) 150 | fprintf('\nA(3) replans\n\n') 151 | A(3) = assignpath(A(3)); 152 | A(1) = updateMap(A(1),A(3).goal,3); 153 | A(2) = updateMap(A(2),A(3).goal,3); 154 | A(3) = updateMap(A(3),A(3).goal,3); 155 | 156 | if ~isequal(A(2).Position,A(2).goal) 157 | A(1) = updateMap(A(1),A(2).goal,3); 158 | A(2) = updateMap(A(2),A(2).goal,3); 159 | end 160 | 161 | if ~isequal(A(1).Position,A(1).goal) 162 | A(1) = updateMap(A(1),A(1).goal,3); 163 | A(2) = updateMap(A(2),A(1).goal,3); 164 | end 165 | end 166 | end 167 | end 168 | 169 | %Agents move forward 170 | 171 | A(1) = move(A(1)); 172 | A(2) = move(A(2)); 173 | A(3) = move(A(3)); 174 | 175 | %Verify that any agent hit an obstacle and that they are not in the same position 176 | 177 | if A(1).Map(A(1).Position(1),A(1).Position(2)) == 5 && A(1).lastMove == 1 178 | fprintf('\nHit an obstacle!: %d %d by A(1)\n\n',A(1).Position(1),A(1).Position(2)); 179 | end 180 | if A(2).Map(A(2).Position(1),A(2).Position(2)) == 5 && A(2).lastMove == 1 181 | fprintf('\nHit an obstacle!: %d %d by A(2)\n\n',A(2).Position(1),A(2).Position(2)); 182 | end 183 | if A(3).Map(A(3).Position(1),A(3).Position(2)) == 5 && A(3).lastMove == 1 184 | fprintf('\nHit an obstacle!: %d %d by A(3)\n\n',A(3).Position(1),A(3).Position(2)); 185 | end 186 | 187 | if isequal(A(2).Position,A(1).Position) && A(1).lastMove == 1 && A(2).lastMove == 1 188 | fprintf('\nAgents 1 and 2 crashed!!\n\n') 189 | end 190 | 191 | if isequal(A(3).Position,A(1).Position) && A(1).lastMove == 1 && A(2).lastMove == 1 192 | fprintf('\nAgents 1 and 3 crashed!!\n\n') 193 | end 194 | 195 | if isequal(A(2).Position,A(3).Position) && A(1).lastMove == 1 && A(2).lastMove == 1 196 | fprintf('\nAgents 2 and 3 crashed!!\n\n') 197 | end 198 | 199 | if (isequal(A(1).goal,A(1).Position)) && (A(1).Map(A(1).Position(1),A(1).Position(2))~=5) && (A(2).Map(A(1).Position(1),A(1).Position(2))~=5) && A(1).lastMove == 1 % one agent is still on the move. 200 | 201 | A(1) = updateMap(A(1),A(1).goal,5); 202 | A(2) = updateMap(A(2),A(1).goal,5); 203 | A(3) = updateMap(A(3),A(1).goal,5); 204 | 205 | fprintf('A(1) painted a tile : %d,%d\n',A(1).goal(1),A(1).goal(2)); 206 | 207 | for i=1:AGENT_COUNT 208 | if(i ~= 1) 209 | contains = 0; 210 | for j=1:size(A(i).path,1) 211 | if isequal(A(i).path(j,:),A(1).goal) 212 | contains = 1; 213 | end 214 | end 215 | if contains ==1 216 | A(i) = calculatePath(A(i),A(mod(i,3)+1).path,A(mod(i+1,3)+1).path); %its initial, opPosition's path will be empty 217 | A(i) = assignpath(A(i)); 218 | fprintf('\nA(%d) replans\n\n',i); 219 | Counter = Counter + 1; 220 | for y=1:AGENT_COUNT 221 | A(y) = updateMap(A(y),A(i).goal,3); 222 | end 223 | end 224 | end 225 | end 226 | 227 | end 228 | 229 | if (isequal(A(2).goal,A(2).Position)) && (A(2).Map(A(2).Position(1),A(2).Position(2))~=5) && (A(1).Map(A(2).Position(1),A(2).Position(2))~=5) && A(2).lastMove == 1 % one agent is still on the move. 230 | 231 | A(1) = updateMap(A(1),A(2).goal,5); 232 | A(2) = updateMap(A(2),A(2).goal,5); 233 | A(3) = updateMap(A(3),A(2).goal,5); 234 | 235 | fprintf('A(2) painted a tile : %d,%d\n',A(2).goal(1),A(2).goal(2)); 236 | 237 | for i=1:AGENT_COUNT 238 | if(i ~= 2) 239 | contains = 0; 240 | for j=1:size(A(i).path,1) 241 | if isequal(A(i).path(j,:),A(2).goal) 242 | contains = 1; 243 | end 244 | end 245 | if contains ==1 246 | A(i) = calculatePath(A(i),A(mod(i,3)+1).path,A(mod(i+1,3)+1).path); %its initial, opPosition's path will be empty 247 | A(i) = assignpath(A(i)); 248 | fprintf('\nA(%d) replans\n\n',i); 249 | Counter = Counter + 1; 250 | for y=1:AGENT_COUNT 251 | A(y) = updateMap(A(y),A(i).goal,3); 252 | end 253 | end 254 | end 255 | end 256 | 257 | end 258 | 259 | if (isequal(A(3).goal,A(3).Position)) && (A(3).Map(A(3).Position(1),A(3).Position(2))~=5) && A(3).lastMove == 1 % one agent is still on the move. 260 | 261 | A(1) = updateMap(A(1),A(3).goal,5); 262 | A(2) = updateMap(A(2),A(3).goal,5); 263 | A(3) = updateMap(A(3),A(3).goal,5); 264 | 265 | fprintf('A(3) painted a tile : %d,%d\n',A(3).goal(1),A(3).goal(2)); 266 | 267 | for i=1:AGENT_COUNT 268 | if(i ~= 3) 269 | contains = 0; 270 | for j=1:size(A(i).path,1) 271 | if isequal(A(i).path(j,:),A(3).goal) 272 | contains = 1; 273 | end 274 | end 275 | if contains ==1 276 | A(i) = calculatePath(A(i),A(mod(i,3)+1).path,A(mod(i+1,3)+1).path); %its initial, opPosition's path will be empty 277 | A(i) = assignpath(A(i)); 278 | fprintf('\nA(%d) replans\n\n',i); 279 | Counter = Counter + 1; 280 | for y=1:AGENT_COUNT 281 | A(y) = updateMap(A(y),A(i).goal,3); 282 | end 283 | end 284 | end 285 | end 286 | end 287 | end 288 | 289 | fprintf('Time take for the Multi Agent planning :%d\n',Counter); -------------------------------------------------------------------------------- /RRT-3-Agents/RRT - 3 Agents/Agent.m: -------------------------------------------------------------------------------- 1 | classdef Agent 2 | 3 | %*****************************************************************************************************% 4 | %* *% 5 | %* NAME: Agent *% 6 | %* DESCRIPTION: Class used to model the behavior of the agent performing the task *% 7 | %* AUTHOR: Team 19 *% 8 | %* DATE CREATION:08/10/2016 *% 9 | %* LAST MODIFIED:14/10/2016 *% 10 | %* *% 11 | %*****************************************************************************************************% 12 | 13 | properties 14 | Position %Current position of the agent (timestep k) 15 | Bid %Current Bid 16 | Map %Map used by the agent to campute RRT 17 | path %Current path 18 | timeSinceStart %Number of steps from the beginning of the path 19 | timeToGoal %Number of timesteps from the beginning of the path until the goal 20 | lastMove %Value of the last move (1 or 0) 21 | goal %Position of the current goal 22 | posiblepath %Potential new path 23 | posiblegoal %Potential new path 24 | lastPosition %Position in the previous timestep 25 | end 26 | 27 | methods 28 | 29 | %%Class Constructor 30 | function agent = Agent(position,currentMap) 31 | if nargin == 2 32 | agent.Position = position; 33 | agent.Map = currentMap; 34 | agent.timeSinceStart = 1; 35 | else 36 | error('Incorrect Number of Inputs for class Agent') 37 | end 38 | end 39 | 40 | %% Update the and the goal with posiblepath and posible goal 41 | function Agent = assignpath(Agent) %Value should be 1 or 0 42 | Agent.path = Agent.posiblepath; 43 | Agent.goal = Agent.posiblegoal; 44 | c = size(Agent.path); Agent.timeToGoal = c(1); 45 | Agent.timeSinceStart = 1; 46 | Agent.lastMove = 0; 47 | end 48 | 49 | %%Update the Agent Map with the desired value 50 | function Agent = updateMap(Agent,tile,value) %Updates the map of the agent with iformation from another agent 51 | Agent.Map(tile(1),tile(2)) = value; 52 | end 53 | 54 | %%Find the closest tile to paint, calculate a path to reach it and 55 | %%compute the bid 56 | function Agent = calculatePath(Agent,otherPath1,otherPath2) %Calculates the path using RRT 57 | Agent = findClosestTile(Agent); 58 | r = RRT(Agent.Map , Agent.Position , Agent.posiblegoal); 59 | r = runRRT(r); 60 | if r.path_found == true 61 | Agent.posiblepath = r.path; 62 | size1 = size(Agent.posiblepath); 63 | size2 = size(otherPath1); 64 | size3 = size(otherPath2); 65 | time = min(size1(1),size2(1)); 66 | for i = 2:time 67 | if Agent.posiblepath(i,1) == otherPath1(i,1) && Agent.posiblepath(i,2) == otherPath1(i,2) 68 | Agent.posiblepath = [Agent.posiblepath(1:i-1,:); Agent.posiblepath(i-1,:); Agent.posiblepath(i:end,:)];%stops twice in a tile if required 69 | end 70 | end 71 | time = min(size1(1),size3(1)); 72 | for i = 2:time 73 | if Agent.posiblepath(i,1) == otherPath2(i,1) && Agent.posiblepath(i,2) == otherPath2(i,2) 74 | Agent.posiblepath = [Agent.posiblepath(1:i-1,:); Agent.posiblepath(i-1,:); Agent.posiblepath(i:end,:)];%stops twice in a tile if required 75 | end 76 | end 77 | oldcost = length(Agent.path); 78 | if (isequal(Agent.goal,Agent.Position)) && (Agent.lastMove == 0) 79 | Agent.Bid = length(Agent.posiblepath); 80 | else 81 | Agent.Bid = oldcost - length(Agent.posiblepath); 82 | if Agent.Bid == 0 83 | Agent.Bid = -20; 84 | end 85 | end 86 | Agent.lastPosition = Agent.Position; 87 | end 88 | end 89 | 90 | %% Agent finds the closest tiles that needs to be painted 91 | function Agent = findClosestTile(Agent) %Returns position [row,column] of closest tile. [-1,-1] if there are no more tiles to paint 92 | [rows,columns] = find(Agent.Map); 93 | closestDistance = Inf; 94 | for i=1:length(rows) 95 | if Agent.Map(rows(i),columns(i)) == 2 96 | distance = abs(Agent.Position(1)-rows(i)) + abs(Agent.Position(2)-columns(i)); 97 | if distance < closestDistance 98 | closestDistance = distance; 99 | Agent.posiblegoal = [rows(i) columns(i)]; 100 | end 101 | end 102 | end 103 | end 104 | 105 | %% Agent moves one step forward according to the current plan 106 | function Agent = move(Agent) %returns 1 if the agent moved towards the goal, 0 if he already reached the goal 107 | Agent.lastMove = 0; 108 | Agent.lastPosition = Agent.Position; 109 | 110 | if Agent.timeSinceStart == Agent.timeToGoal && ~isequal(Agent.lastPosition,Agent.Position) 111 | Agent.lastMove = 1; 112 | end 113 | 114 | if Agent.timeSinceStart < Agent.timeToGoal 115 | Agent.Position = Agent.path(2,:); 116 | Agent.path = Agent.path(2:end,:); 117 | Agent.lastMove = 1; 118 | Agent.timeSinceStart = Agent.timeSinceStart + 1; 119 | end 120 | 121 | if Agent.timeSinceStart == 2 && isequal(Agent.lastPosition,Agent.Position) 122 | Agent.lastMove = 0; 123 | end 124 | end 125 | end 126 | end 127 | 128 | -------------------------------------------------------------------------------- /RRT-3-Agents/RRT - 3 Agents/Map0.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RohinMohanadas/MultiAgentRRT/d3f305746adf955290006548de58aec164e7bcdd/RRT-3-Agents/RRT - 3 Agents/Map0.bmp -------------------------------------------------------------------------------- /RRT-3-Agents/RRT - 3 Agents/Map1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RohinMohanadas/MultiAgentRRT/d3f305746adf955290006548de58aec164e7bcdd/RRT-3-Agents/RRT - 3 Agents/Map1.bmp -------------------------------------------------------------------------------- /RRT-3-Agents/RRT - 3 Agents/README.txt: -------------------------------------------------------------------------------- 1 | # Multi Agent Tile Painting 2 | 3 | #Run the Program in Matlab 4 | run AIprojectMain 5 | 6 | #Several Maps are offered in order to test the program in different environments 7 | in line 22 of AIprojectMain, modify MainImage = importdata('XXXXXXX.bmp') where XXXXXXX is the name of the desired map 8 | 9 | 10 | -------------------------------------------------------------------------------- /RRT-3-Agents/RRT - 3 Agents/RRT.m: -------------------------------------------------------------------------------- 1 | classdef RRT 2 | 3 | %*****************************************************************************************************% 4 | %* *% 5 | %* NAME: RRT *% 6 | %* DESCRIPTION: *% 7 | %* AUTHOR: *% 8 | %* DATE CREATION:09/10/2016 *% 9 | %* LAST MODIFIED:10/12/2016 *% 10 | %* *% 11 | %*****************************************************************************************************% 12 | 13 | properties 14 | initialMap %number of timesteps from the beginning of the path until the goal 15 | initialPosition % value of the last move (1 or 0) 16 | goal %position of the current goal 17 | n %number of rows/columns 18 | N %number of tiles in the map (N=nxn) 19 | path %sequence of positions from initialPosition to goal 20 | path_found %boolean to indicate that a path has been found 21 | finalMap %Map with 1's on the path positions 22 | end 23 | 24 | methods 25 | %%Class Constructor 26 | function rrt = RRT(Map,Position,Goal) 27 | if nargin == 3 28 | rrt.initialMap = Map; 29 | rrt.initialPosition = Position; 30 | rrt.goal = Goal; 31 | s = size(rrt.initialMap); 32 | rrt.N = s(1)*s(2); 33 | rrt.n = s(1); 34 | rrt.path_found = false; 35 | else 36 | error('Incorrect Number of Inputs for class Agent') 37 | end 38 | end 39 | 40 | function rrt = runRRT(rrt) %Value should be 1 or 0 41 | tree = zeros(rrt.N,2); 42 | parent = zeros(rrt.N,1); 43 | node_x = zeros(1,rrt.N); 44 | node_y = zeros(1,rrt.N); 45 | node_x(1) = rrt.initialPosition(1); 46 | node_y(1) = rrt.initialPosition(2); 47 | tree(1,:) = [node_x(1),node_y(1)]; 48 | rrt.initialMap(node_x(1),node_y(1)) = 1; 49 | loop_count = 0; 50 | no_path = false; 51 | 52 | for i = 2:rrt.N 53 | is_valid = false; 54 | while (is_valid == false) 55 | if(nnz(~rrt.initialMap) == 0) %all map elements have been filled 56 | break; 57 | end 58 | %find a sample node 59 | random_node = randomNode(rrt,node_x,node_y); 60 | %Finding the nearest node 61 | nearest_node = nearestNode(rrt,node_x,node_y,random_node); 62 | %get the new node 63 | new_node = newNode(rrt,random_node,nearest_node); 64 | %check if new node is in collision => rerun that loop 65 | is_valid = detectObstacle(rrt,new_node,is_valid); 66 | %update loop count of this while loop 67 | loop_count = loop_count + 1; 68 | if(loop_count > rrt.N^2) 69 | break; 70 | end 71 | end 72 | 73 | if(loop_count > rrt.N^2) 74 | disp('Leaving RRT: No path found'); 75 | break; 76 | end 77 | 78 | %add the new nodes to node history 79 | node_x(i) = new_node(1); 80 | node_y(i) = new_node(2); 81 | %fprintf('new node: (%d,%d)\n', new_node(1),new_node(2)); 82 | 83 | %update tree 84 | tree(i,:) = new_node; 85 | %find the index of the location of the nearest node in tree (find 86 | %parent) 87 | for index = 1:i 88 | if nearest_node == [node_x(index)',node_y(index)'] 89 | parent(i) = index; 90 | end 91 | end 92 | 93 | %show entire map with all trees (not necessary) 94 | rrt.initialMap(new_node(1),new_node(2)) = 1; 95 | %disp(map); 96 | 97 | %check to see if you have reached goal -- get rrt_path 98 | if (rrt.initialMap(rrt.goal(1),rrt.goal(2)) == 1) 99 | %fprintf('Found goal in %d iterations\n', i); 100 | %trace back your path: 101 | rrt.path = getPath(rrt,tree,parent,i); 102 | break; %breaks loop if you have reached the end 103 | end 104 | 105 | %if(loop_count >= N^2) 106 | if(nnz(~rrt.initialMap) == 0) 107 | no_path = true; 108 | disp('Leaving RRT: No path found'); 109 | break; 110 | end 111 | end 112 | 113 | %create an updated rrt map that shows path 114 | if(no_path == false && loop_count < rrt.N^2) 115 | rrt.path_found = true; %indicates path has been found 116 | %create an updated rrt map that shows path 117 | rrt.finalMap = getPathMap(rrt); 118 | end 119 | end 120 | 121 | function random_node = randomNode(rrt,node_x,node_y) 122 | valid = false; 123 | random_node = randi([1,rrt.n],1,2); 124 | k = 1; 125 | while (valid == false) 126 | if ((random_node(1) == node_x(k) && random_node(2) == node_y(k)) || (rrt.initialMap(random_node(1),random_node(2)) == 5)) 127 | random_node = randi([1,rrt.n],1,2); 128 | k = 1; 129 | continue; 130 | end 131 | if (k == size(node_x,2)) 132 | valid = true; 133 | end 134 | k = k+1; 135 | end 136 | %fprintf('random node: (%d,%d)\n', random_node(1),random_node(2)); 137 | end 138 | 139 | function nearest_node = nearestNode(rrt, node_x,node_y,random_node) 140 | if (length(find(node_x)) == 1) %finds the number of non-zero elements 141 | nearest_node = [node_x(1),node_y(1)]; 142 | else 143 | nearest_node = [node_x(1),node_y(1)]; 144 | distance = sqrt((random_node(1)-node_x(1))^2 + (random_node(2)-node_y(1))^2); 145 | for j = 2:length(find(node_x)) 146 | tmp = sqrt((random_node(1)-node_x(j))^2 + (random_node(2)-node_y(j))^2); %Euclidean distance 147 | if (tmp < distance) 148 | nearest_node = [node_x(j),node_y(j)]; %finds the nearest node by searching min 149 | distance = tmp; 150 | end 151 | end 152 | end 153 | %fprintf('nearest node: (%d,%d)\n', nearest_node(1),nearest_node(2)); 154 | end 155 | 156 | function new_node = newNode(rrt,random_node,nearest_node) 157 | %Agent movements 158 | up = [-1,0]; 159 | down = [1,0]; 160 | left = [0,-1]; 161 | right = [0,1]; 162 | 163 | %find the slope from nearest_node to random_node: y_diff/x_diff 164 | y_diff = random_node(1)-nearest_node(1); 165 | x_diff = random_node(2)-nearest_node(2); 166 | if (abs(x_diff) > 0 && (abs(x_diff) < abs(y_diff) || y_diff == 0))%the lesser slope difference is the one that's added 167 | if (x_diff > 0) 168 | new_node = nearest_node+right; 169 | else 170 | new_node = nearest_node+left; 171 | end 172 | elseif (abs(y_diff) > 0) 173 | if (y_diff > 0) 174 | new_node = nearest_node+down; 175 | else 176 | new_node = nearest_node+up; 177 | end 178 | elseif (abs(x_diff) == abs(y_diff)) %if both are equally likely jsut choose randomly 179 | if (nearest_node(1) == rrt.n) %if you're at the row border, increase column 180 | new_node = [nearest_node(1), nearest_node(2)+1]; 181 | elseif (nearest_node(2) == rrt.n) 182 | new_node = [nearest_node(1)+1, nearest_node(2)]; 183 | else 184 | choice = randi(2); %choose between options randomly 185 | if (choice == 1) 186 | if (x_diff > 0) 187 | new_node = nearest_node + right; 188 | else 189 | new_node = nearest_node + left; 190 | end 191 | else 192 | if (y_diff > 0) 193 | new_node = nearest_node + down; 194 | else 195 | new_node = nearest_node + up; 196 | end 197 | end 198 | end 199 | end 200 | end 201 | 202 | function is_valid = detectObstacle(rrt, new_node, is_valid) 203 | if(rrt.initialMap(new_node(1),new_node(2)) ~= 5) 204 | is_valid = true; 205 | end 206 | end 207 | 208 | function rrt_path = getPath(rrt,tree,parent,current_index) 209 | rrt_path = zeros(current_index,2); 210 | for index = 1:current_index 211 | if (index == 1) 212 | rrt_path(index,:) = tree(current_index,:); 213 | ncol = size(rrt_path, 2); %getting rid of the unnecessary zeros 214 | rrt_path(rrt_path == 0) = []; 215 | rrt_path = reshape(rrt_path, [], ncol); 216 | child_of = parent(current_index); 217 | else 218 | if(child_of == 0) 219 | break; 220 | else 221 | rrt_path(index,:) = tree(child_of,:); 222 | child_of = parent(child_of); 223 | end 224 | end 225 | end 226 | rrt_path = flipud(rrt_path); %flipping the matrix 227 | end 228 | 229 | function rrt_map = getPathMap(rrt) 230 | rrt_map = zeros(rrt.n); 231 | for index = 1:size(rrt.path,1) 232 | rrt_map(rrt.path(index,1),rrt.path(index,2)) = 1; 233 | end 234 | end 235 | 236 | end 237 | end -------------------------------------------------------------------------------- /RRT-3-Agents/__MACOSX/._ RRT - 3 Agents: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RohinMohanadas/MultiAgentRRT/d3f305746adf955290006548de58aec164e7bcdd/RRT-3-Agents/__MACOSX/._ RRT - 3 Agents -------------------------------------------------------------------------------- /RRT-3-Agents/__MACOSX/RRT - 3 Agents/._.DS_Store: -------------------------------------------------------------------------------- 1 | Mac OS X  2Fx ATTRxx -------------------------------------------------------------------------------- /RRT-3-Agents/__MACOSX/RRT - 3 Agents/._AIprojectMain.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RohinMohanadas/MultiAgentRRT/d3f305746adf955290006548de58aec164e7bcdd/RRT-3-Agents/__MACOSX/RRT - 3 Agents/._AIprojectMain.m -------------------------------------------------------------------------------- /RRT-3-Agents/__MACOSX/RRT - 3 Agents/._Agent.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RohinMohanadas/MultiAgentRRT/d3f305746adf955290006548de58aec164e7bcdd/RRT-3-Agents/__MACOSX/RRT - 3 Agents/._Agent.m -------------------------------------------------------------------------------- /RRT-3-Agents/__MACOSX/RRT - 3 Agents/._Map0.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RohinMohanadas/MultiAgentRRT/d3f305746adf955290006548de58aec164e7bcdd/RRT-3-Agents/__MACOSX/RRT - 3 Agents/._Map0.bmp -------------------------------------------------------------------------------- /RRT-3-Agents/__MACOSX/RRT - 3 Agents/._Map1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RohinMohanadas/MultiAgentRRT/d3f305746adf955290006548de58aec164e7bcdd/RRT-3-Agents/__MACOSX/RRT - 3 Agents/._Map1.bmp -------------------------------------------------------------------------------- /RRT-3-Agents/__MACOSX/RRT - 3 Agents/._README.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RohinMohanadas/MultiAgentRRT/d3f305746adf955290006548de58aec164e7bcdd/RRT-3-Agents/__MACOSX/RRT - 3 Agents/._README.txt -------------------------------------------------------------------------------- /RRT-3-Agents/__MACOSX/RRT - 3 Agents/._RRT.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RohinMohanadas/MultiAgentRRT/d3f305746adf955290006548de58aec164e7bcdd/RRT-3-Agents/__MACOSX/RRT - 3 Agents/._RRT.m -------------------------------------------------------------------------------- /Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RohinMohanadas/MultiAgentRRT/d3f305746adf955290006548de58aec164e7bcdd/Thumbs.db --------------------------------------------------------------------------------