Skip to content

Commit

Permalink
Merge pull request #5 from doruirimescu/Development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
doruirimescu authored Apr 24, 2020
2 parents 9977823 + d69c274 commit a7da32e
Show file tree
Hide file tree
Showing 22 changed files with 519 additions and 79 deletions.
6 changes: 3 additions & 3 deletions agent.cpp → Agent.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#include "agent.hpp"
#include "Agent.hpp"

void Agent::show() const
{/* Print agent information */
std::cout << label << " at:(" << X << ", " << Y << ")" << " goal: (" << goalX <<
", "<< goalY << ")" << " heuristic: " << getH() << std::endl;
OUTPUT << label << " at:(" << X << ", " << Y << ")" << " goal: (" << goalX <<
", "<< goalY << ")" << " heuristic: " << getH() << endline;
}

bool Agent::operator == (const Agent &a)const
Expand Down
10 changes: 5 additions & 5 deletions agent.hpp → Agent.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once
#include "heuristic.hpp"
#include <string>
#include <iostream>
#include "porting.hpp"
using namespace porting;

class Agent
{
Expand All @@ -12,7 +12,7 @@ class Agent
*/

public:
Agent(int x, int y, int gx, int gy, std::string l): X(x), Y(y),
Agent(int x, int y, int gx, int gy, string l): X(x), Y(y),
goalX(gx), goalY(gy), label(l){};

int getX() const { return X; };
Expand All @@ -21,7 +21,7 @@ class Agent
int getGoalX() const { return goalX; };
int getGoalY() const { return goalY; };

std::string getLabel() const { return label; };
string getLabel() const { return label; };

void setX(int x) { X = x; };
void setY(int y) { Y = y; };
Expand All @@ -36,5 +36,5 @@ class Agent
private:
int X, Y;
int goalX, goalY;
std::string label;
string label;
};
22 changes: 13 additions & 9 deletions astar.cpp → Astar.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
#include "astar.hpp"
std::vector<MAPPGridState> Astar::astar( MAPPGridState &grid )
#include "Astar.hpp"
vector<MAPPGridState> Astar::astar( MAPPGridState &grid )
{
std::vector<MAPPGridState> newStates = grid.successors();
vector<MAPPGridState> newStates = grid.successors();

if( newStates.size() == 0 )
{/* There is no valid successor */
return {grid};
}
/* A* algo */
std::priority_queue<MAPPGridState, std::vector<MAPPGridState>> Q;
priority_queue<MAPPGridState, vector<MAPPGridState>> Q;
Q.push( grid );

MAPPGridState n = grid;
std::unordered_map<MAPPGridState, MAPPGridState> predecessors;
std::unordered_map<MAPPGridState, unsigned int> minCost;
unordered_map<MAPPGridState, MAPPGridState> predecessors;
unordered_map<MAPPGridState, unsigned int> minCost;

minCost.insert({n,0});
bool going = true;
Expand All @@ -35,12 +39,12 @@ std::vector<MAPPGridState> Astar::astar( MAPPGridState &grid )
if( n.getH() == 0 )
{
going = false;
std::cout<<"Found a result"<<std::endl;
OUTPUT<<"Found a result"<<endline;
}
}

/* std::vector that holds state trajectory */
std::vector<MAPPGridState> results;
/* vector that holds state trajectory */
vector<MAPPGridState> results;
results.reserve(10);

results.emplace_back(n);
Expand Down
10 changes: 5 additions & 5 deletions astar.hpp → Astar.hpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#pragma once
#include "MAPPGridState.hpp"
#include <unordered_map>
#include <queue>
#include<algorithm>
#include "porting.hpp"
#include <algorithm>
using namespace porting;

namespace Astar
{
inline unsigned int mapRetrieve(const std::unordered_map<MAPPGridState, unsigned int> &m,
inline unsigned int mapRetrieve(const unordered_map<MAPPGridState, unsigned int> &m,
const MAPPGridState &n)
{
if ( m.find(n) != m.end() )
Expand All @@ -18,6 +18,6 @@ namespace Astar
return 10000;
}
}
std::vector<MAPPGridState> astar( MAPPGridState &grid );
vector<MAPPGridState> astar( MAPPGridState &grid );

};
9 changes: 5 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,18 @@ add_subdirectory(googletest)


set(Headers
wall.hpp
Wall.hpp
heuristic.hpp
MAPPGridState.hpp
astar.hpp
Astar.hpp
porting.hpp
)

set(Sources
heuristic.cpp
agent.cpp
Agent.cpp
MAPPGridState.cpp
astar.cpp
Astar.cpp
)
add_library( ${This} STATIC ${Sources} ${Headers} )

Expand Down
24 changes: 12 additions & 12 deletions MAPPGridState.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "MAPPGridState.hpp"

MAPPGridState::MAPPGridState( std::vector<Agent>&agents, unsigned int xsize, unsigned int ysize, unsigned int cost )
MAPPGridState::MAPPGridState( vector<Agent>&agents, unsigned int xsize, unsigned int ysize, unsigned int cost )
{
this->agents =agents;
this->xsize = xsize;
Expand All @@ -15,10 +15,10 @@ MAPPGridState::MAPPGridState( std::vector<Agent>&agents, unsigned int xsize, uns
}
currentCost = cost;
}
void MAPPGridState::succCoords( std::vector<Agent> &ret, const Agent &a ) const
void MAPPGridState::succCoords( vector<Agent> &ret, const Agent &a ) const
{ /*
* Take an Agent, move it right, left, up, down, and return
* the new std::vector of Agents. But check for border and wall
* the new vector of Agents. But check for border and wall
* collisions.
*/
int x = a.getX();
Expand All @@ -43,7 +43,7 @@ void MAPPGridState::succCoords( std::vector<Agent> &ret, const Agent &a ) const
}
}

bool MAPPGridState::goodSuccessor( const std::vector<Agent> &successor )
bool MAPPGridState::goodSuccessor( const vector<Agent> &successor )
{
/*
* If the new successor is valid (no two agents are at the same coords)
Expand All @@ -67,13 +67,13 @@ bool MAPPGridState::goodSuccessor( const std::vector<Agent> &successor )
return true;
}

std::vector<MAPPGridState> MAPPGridState::successors()
vector<MAPPGridState> MAPPGridState::successors()
{
/*
* Return the std::vector of successor states
* Return the vector of successor states
*/
std::vector<Agent> newCoords[numberAgents];
std::vector<MAPPGridState> newStates;
vector<Agent> newCoords[numberAgents];
vector<MAPPGridState> newStates;

/* There cannot be more than 4 new states (up, down, left, right) */
newStates.reserve(4);
Expand All @@ -98,7 +98,7 @@ std::vector<MAPPGridState> MAPPGridState::successors()
/* Make a copy of the agent whose position will be modified */
Agent tmp = agents.at(i);

/* Now, the agents std::vector holds the successor candidate position */
/* Now, the agents vector holds the successor candidate position */
agents.at(i) = newCoords[ i ][ j ];

if( goodSuccessor(agents) )
Expand Down Expand Up @@ -126,13 +126,13 @@ void MAPPGridState::show()const
/*
* Print state information
*/
std::cout << std::endl << "--------PRINTING STATE--------" << std::endl << std::endl;
OUTPUT << endline << "--------PRINTING STATE--------" << endline << endline;
for( const auto &i : agents )
{
i.show();
}
std::cout << "G " << currentCost <<" H: " << currentHeuristic << " F: " <<
this->getF() << std::endl;
OUTPUT << "G " << currentCost <<" H: " << currentHeuristic << " F: " <<
this->getF() << endline;
}
bool MAPPGridState::operator ==( const MAPPGridState &a)const
{
Expand Down
28 changes: 15 additions & 13 deletions MAPPGridState.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#pragma once
#include "agent.hpp"
#include "wall.hpp"
#include<vector>
#include "Agent.hpp"
#include "Wall.hpp"
#include "porting.hpp"

using namespace porting;
class MAPPGridState
{
/*
Expand All @@ -11,7 +12,7 @@ class MAPPGridState
* y size of the grid.
*/
public:
MAPPGridState( std::vector<Agent>&agents, unsigned int xsize, unsigned int ysize, unsigned int cost );
MAPPGridState( vector<Agent>&agents, unsigned int xsize, unsigned int ysize, unsigned int cost );
inline unsigned int getF() const
{
return currentCost + currentHeuristic;
Expand Down Expand Up @@ -39,7 +40,7 @@ class MAPPGridState
return false;
}

void succCoords( std::vector<Agent> &ret, const Agent &a ) const;
void succCoords( vector<Agent> &ret, const Agent &a ) const;

inline bool sameCoord( const Agent &a, const Agent &b )
{
Expand All @@ -53,20 +54,21 @@ class MAPPGridState
return false;
}

bool goodSuccessor( const std::vector<Agent> &successor );
bool goodSuccessor( const vector<Agent> &successor );

std::vector<MAPPGridState> successors();
vector<MAPPGridState> successors();

void show() const;

bool operator ==( const MAPPGridState &a)const;
static std::vector<Wall>walls;

friend struct std::less<MAPPGridState>;
friend struct std::hash<MAPPGridState>;
static vector<Wall>walls;

friend less<MAPPGridState>;
friend hash<MAPPGridState>;

private:
std::vector<Agent>agents;
unsigned int xsize, ysize, numberAgents, currentCost, currentHeuristic;
vector<Agent>agents;
unsigned int xsize, ysize, numberAgents, currentCost, currentHeuristic;
};


Expand Down
19 changes: 19 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
output: main.o Astar.o MAPPGridState.o Agent.o heuristic.o
g++ main.o Astar.o MAPPGridState.o Agent.o heuristic.o -o output

main.o: main.cpp
g++ -c main.cpp

Astar.o: Astar.cpp Astar.hpp
g++ -c Astar.cpp

MAPPGridState.o: MAPPGridState.cpp MAPPGridState.hpp
g++ -c MAPPGridState.cpp

Agent.o: Agent.cpp Agent.hpp
g++ -c Agent.cpp

heuristic.o: heuristic.cpp heuristic.hpp
g++ -c heuristic.cpp
clean:
rm main.o Astar.o MAPPGridState.o Agent.o heuristic.o
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Description
**Programming language: C++11 and newer**

Multi-agent path planning (MAPP) using the A* algorithm. This implementation is based on the [Aalto CS-E4800 Artificial Intelligence](https://mycourses.aalto.fi/course/view.php?id=24364) course, where I was a teaching assistant.

The problem comprises of a two-dimensional grid, where there are set of agents (each with its own location and goal) and optionally, a set of walls representing locations where no agent can be.

## File descriptions
| Class | Description | Location |
| ---------------- | ------------------------------------------------------------------------------------ |-----------|
| Wall | A grid location where no agent can be located at any time. _Walls should not be added at any agent's goal coordinates._ | Wall.hpp |
| Agent | An intelligent agent, moving in a two-dimensional grid from a starting position towards its goal (final position). In multi-agent problems such as this one, _there can be more than one single agent pursuing its goal at any time in the grid_.| Agent.hpp, Agent.cpp |
| MAPPGridState | The state-space representation of a grid comprises of a vector of MAPPGridStates, each such state representing a collection of agents and their current positions on the grid, together with the total cost which took to reach the state, and the _state heuristic -the estimated cost to reach the goal state-_. The cost of moving from one state to the successor (next) state is always 1, since in this representation only one agent can move per state transition. The state heuristic is computed as the sum of all individual heuristics of the agents. | MAPPGridState.hpp, MAPPGridState.cpp |

| Namespace | Description | Location |
| ---------------- | ------------------------------------------------------------------------------------ |-----------|
| heuristic | Contains a function that computes the heuristic of an agent, ie. the estimate of the distance from the current location to the goal. It is enouraged to add more heuristics -if required by the problem- in this namespace. | heuristic.hpp, heuristic.cpp |
| Astar | Contains the actual A* algorithm, used to search the state-space and retrieve the best state trajectory that solves the problem. | Astar.hpp, Astar.cpp |

| File | Description |
| ---------------- | ------------------------------------------------------------------------------------ |
| porting.hpp | For easily porting the standard library-based implementation to other frameworks (such as QT). |
| main.cpp | For demonstrating the usage of the Astar program in a practical scenario. |
| test/AstarTests.cpp | Unit tests that shall pass after any modification that is made to the program. |

# Compile and run
In order to compile and run the program, run the following commands:

```make```

```./output```

```make clean```

# Google Test
In order to run the unit tests, run the following commands from the Astar folder.

```cmake --build build --config Debug --target all -- -j 6```

```cd build```

```ctest -j6 -C Debug -T test --output-on-failure```

Or, you can open the project with Visual Studio Code and run the tests from the status bar, CMake Tools extension is needed.

For more details on Google Test with VS Code, watch : https://youtu.be/Lp1ifh9TuFI
File renamed without changes.
33 changes: 33 additions & 0 deletions googletest/googletest/generated/GTestConfig.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
####### Any changes to this file will be overwritten by the next CMake run ####
####### The input file was Config.cmake.in ########

get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)

macro(set_and_check _var _file)
set(${_var} "${_file}")
if(NOT EXISTS "${_file}")
message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
endif()
endmacro()

macro(check_required_components _NAME)
foreach(comp ${${_NAME}_FIND_COMPONENTS})
if(NOT ${_NAME}_${comp}_FOUND)
if(${_NAME}_FIND_REQUIRED_${comp})
set(${_NAME}_FOUND FALSE)
endif()
endif()
endforeach()
endmacro()

####################################################################################
include(CMakeFindDependencyMacro)
if (ON)
set(THREADS_PREFER_PTHREAD_FLAG )
find_dependency(Threads)
endif()

include("${CMAKE_CURRENT_LIST_DIR}/GTestTargets.cmake")
check_required_components("")
Loading

0 comments on commit a7da32e

Please sign in to comment.