Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial commit #51

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 0 additions & 46 deletions .github/workflows/manual.yml

This file was deleted.

4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
*.swp
*.osm
!map.osm
*.o
draw.cpp
test.cpp
build/
bin/
lib/
.github/**
lib/
40 changes: 20 additions & 20 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,50 +1,50 @@
cmake_minimum_required(VERSION 3.11.3)

# Set the C++ standard we will use
set(CMAKE_CXX_STANDARD 17)

# Add the path of the cmake files to the CMAKE_MODULE_PATH
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)

project(OSM_A_star_search)

# Set library output path to /lib
set(LIBRARY_OUTPUT_PATH "${CMAKE_SOURCE_DIR}/lib")
# Project Output Paths
set(MAINFOLDER ${PROJECT_SOURCE_DIR})
set(LIBRARY_OUTPUT_PATH "${MAINFOLDER}/lib")

# Locate project prerequisites
# Locate Project Prerequisites
find_package(io2d REQUIRED)
find_package(Cairo)
find_package(GraphicsMagick)

# Set IO2D flags
# Add Build Targets
set(IO2D_WITHOUT_SAMPLES 1)
set(IO2D_WITHOUT_TESTS 1)

# Add the pugixml and GoogleTest library subdirectories
add_subdirectory(thirdparty/pugixml)
add_subdirectory(thirdparty/googletest)

# Find all executables
file(GLOB project_SRCS src/*.cpp src/*.h)

# Add project executable
add_executable(OSM_A_star_search src/main.cpp src/model.cpp src/render.cpp src/route_model.cpp src/route_planner.cpp)
add_executable(OSM_A_star_search ${project_SRCS})

target_link_libraries(OSM_A_star_search
PRIVATE io2d::io2d
PUBLIC pugixml
)

# Add the testing executable
add_executable(test test/utest_rp_a_star_search.cpp src/route_planner.cpp src/model.cpp src/route_model.cpp)

target_link_libraries(test
gtest_main
pugixml
)

# Set options for Linux or Microsoft Visual C++
if( ${CMAKE_SYSTEM_NAME} MATCHES "Linux" )
target_link_libraries(OSM_A_star_search PUBLIC pthread)
endif()

if(MSVC)
target_compile_options(OSM_A_star_search PUBLIC /D_SILENCE_CXX17_ALLOCATOR_VOID_DEPRECATION_WARNING /wd4459)
endif()

# Create a library for unit tests
add_library(route_planner OBJECT src/route_planner.cpp src/model.cpp src/route_model.cpp)
target_include_directories(route_planner PRIVATE thirdparty/pugixml/src)

# Add testing executable
add_executable(test test/utest_rp_a_star_search.cpp)
target_link_libraries(test gtest_main route_planner pugixml)
add_test(NAME test COMMAND test)
unset(TESTING CACHE)
1 change: 0 additions & 1 deletion CODEOWNERS

This file was deleted.

16 changes: 0 additions & 16 deletions LICENSE.md

This file was deleted.

67 changes: 5 additions & 62 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
# Route Planning Project

This repo contains the starter code for the Route Planning project.

<img src="map.png" width="600" height="450" />

# CppND-Route-Planning-Project
This project is part of udacity C++ Nano degree. I implemented a route planner using A* search algorithm to find and visualize the best route between two points in a given map. The user will be asked to enter the (x,y) coordinates of the start and end points then the program will output the route visualized on the given map using the io2d liberary. My contribution to this project is presented in the ```route-planner.cpp```.<img src="Route-Planner.png" width="600" height="450" />
## Cloning
When cloning this project, be sure to use the --recurse-submodules flag. Using HTTPS:

When cloning this project, be sure to use the `--recurse-submodules` flag. Using HTTPS:
```
git clone https://github.com/udacity/CppND-Route-Planning-Project.git --recurse-submodules
git clone https://github.com/AbdelrahmanAbdeldaim/CppND-Route-Planning-Project.git --recurse-submodules
```
or with SSH:
```
git clone git@github.com:udacity/CppND-Route-Planning-Project.git --recurse-submodules
```

```git clone git@github.com:AbdelrahmanAbdeldaim/CppND-Route-Planning-Project.git --recurse-submodules```
## Dependencies for Running Locally
* cmake >= 3.11.3
* All OSes: [click here for installation instructions](https://cmake.org/install/)
Expand Down Expand Up @@ -52,54 +46,3 @@ Or to specify a map file:
```
./OSM_A_star_search -f ../<your_osm_file.osm>
```

## Testing

The testing executable is also placed in the `build` directory. From within `build`, you can run the unit tests as follows:
```
./test
```

## Troubleshooting
* Some students have reported issues in cmake to find io2d packages, make sure you have downloaded [this](https://github.com/cpp-io2d/P0267_RefImpl/blob/master/BUILDING.md#xcode-and-libc).
* For MAC Users cmake issues: Comment these lines from CMakeLists.txt under P0267_RefImpl
```
if( NOT DEFINED IO2D_WITHOUT_SAMPLES )
add_subdirectory(P0267_RefImpl/Samples)
endif()
```
And then run "ALL_Build" and "install" in XCode.

If any packages are missing try to install packages using
```
brew install pkg-config
```
* For Ubuntu Linux IO2D installation errors, follow the given steps:
```
sudo apt update
sudo apt install build-essential
sudo apt install cmake
sudo apt install libcairo2-dev
sudo apt install libgraphicsmagick1-dev
sudo apt install libpng-dev

git clone --recurse-submodules https://github.com/cpp-io2d/P0267_RefImpl
cd P0267_RefImpl
mkdir Debug
cd Debug
cmake --config Debug "-DCMAKE_BUILD_TYPE=Debug" ..
cmake --build .
sudo make install
```

* If you are working on windows and unable to install IO2D:
* Enable WSL (Windows Subsystem for Linux) and use a distribution like [Ubuntu](https://ubuntu.com/wsl).(available from the windows store):
* Install the required dependencies (compiler, cmake etc.) in the WSL(as mentioned above for ubuntu)
* Configure CLion to use the WSL [toolchain](https://www.jetbrains.com/help/clion/how-to-use-wsl-development-environment-in-product.html#wsl-tooclhain)
* Use the WSL toolchain to build the project
* If you are still facing errors, visit this [link](https://github.com/udacity/CppND-Route-Planning-Project/issues/9).


* If you are facing errors with --config try to remove -- from the command.


Binary file added Route-Planner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed map.png
Binary file not shown.
15 changes: 10 additions & 5 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,21 @@ int main(int argc, const char **argv)
else
osm_data = std::move(*data);
}

// TODO 1: Declare floats `start_x`, `start_y`, `end_x`, and `end_y` and get
// user input for these values using std::cin. Pass the user input to the
// RoutePlanner object below in place of 10, 10, 90, 90.

float start_x,start_y,end_x,end_y;
std::cout << "Please enter the x coordiante of the start: ";
std::cin >> start_x;
std::cout << "Please enter the y coordiante of the start: ";
std::cin >> start_y;
std::cout << "Please enter the x coordiante of the end: ";
std::cin >> end_x;
std::cout << "Please enter the y coordiante of the end: ";
std::cin >> end_y;
// Build Model.
RouteModel model{osm_data};

// Create RoutePlanner object and perform A* search.
RoutePlanner route_planner{model, 10, 10, 90, 90};
RoutePlanner route_planner{model, start_x, start_y, end_x, end_y};
route_planner.AStarSearch();

std::cout << "Distance: " << route_planner.GetDistance() << " meters. \n";
Expand Down
91 changes: 43 additions & 48 deletions src/route_planner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,77 +8,72 @@ RoutePlanner::RoutePlanner(RouteModel &model, float start_x, float start_y, floa
end_x *= 0.01;
end_y *= 0.01;

// TODO 2: Use the m_Model.FindClosestNode method to find the closest nodes to the starting and ending coordinates.
// Store the nodes you find in the RoutePlanner's start_node and end_node attributes.

start_node = &(m_Model.FindClosestNode(start_x, start_y));
end_node = &(m_Model.FindClosestNode(end_x, end_y));
}


// TODO 3: Implement the CalculateHValue method.
// Tips:
// - You can use the distance to the end_node for the h value.
// - Node objects have a distance method to determine the distance to another node.

float RoutePlanner::CalculateHValue(RouteModel::Node const *node) {

return node->distance(*end_node);
}


// TODO 4: Complete the AddNeighbors method to expand the current node by adding all unvisited neighbors to the open list.
// Tips:
// - Use the FindNeighbors() method of the current_node to populate current_node.neighbors vector with all the neighbors.
// - For each node in current_node.neighbors, set the parent, the h_value, the g_value.
// - Use CalculateHValue below to implement the h-Value calculation.
// - For each node in current_node.neighbors, add the neighbor to open_list and set the node's visited attribute to true.

void RoutePlanner::AddNeighbors(RouteModel::Node *current_node) {
current_node->FindNeighbors();
auto g = current_node->g_value;
for(auto neighbor : current_node->neighbors)
{
neighbor->parent = current_node;
neighbor->g_value = g+ current_node->distance(*neighbor);
neighbor->h_value = CalculateHValue(neighbor) ;
neighbor->visited = true;
open_list.push_back(neighbor);
}

}


// TODO 5: Complete the NextNode method to sort the open list and return the next node.
// Tips:
// - Sort the open_list according to the sum of the h value and g value.
// - Create a pointer to the node in the list with the lowest sum.
// - Remove that node from the open_list.
// - Return the pointer.

bool Compare(RouteModel::Node const *a, RouteModel::Node const *b) {
return (a->g_value + a->h_value) > (b->g_value + b->h_value);
}
RouteModel::Node *RoutePlanner::NextNode() {

std::sort(open_list.begin(), open_list.end(), Compare);
auto lowest = open_list.back();
open_list.pop_back();
return lowest;
}


// TODO 6: Complete the ConstructFinalPath method to return the final path found from your A* search.
// Tips:
// - This method should take the current (final) node as an argument and iteratively follow the
// chain of parents of nodes until the starting node is found.
// - For each node in the chain, add the distance from the node to its parent to the distance variable.
// - The returned vector should be in the correct order: the start node should be the first element
// of the vector, the end node should be the last element.

std::vector<RouteModel::Node> RoutePlanner::ConstructFinalPath(RouteModel::Node *current_node) {
// Create path_found vector
distance = 0.0f;
std::vector<RouteModel::Node> path_found;

// TODO: Implement your solution here.


while(current_node->parent != nullptr)
{
path_found.insert(path_found.begin(), *current_node);
auto parent_node = current_node->parent;
distance+= current_node->distance(*parent_node);
current_node = parent_node;
}
path_found.insert(path_found.begin(), *start_node);
distance *= m_Model.MetricScale(); // Multiply the distance by the scale of the map to get meters.
return path_found;

}


// TODO 7: Write the A* Search algorithm here.
// Tips:
// - Use the AddNeighbors method to add all of the neighbors of the current node to the open_list.
// - Use the NextNode() method to sort the open_list and return the next node.
// - When the search has reached the end_node, use the ConstructFinalPath method to return the final path that was found.
// - Store the final path in the m_Model.path attribute before the method exits. This path will then be displayed on the map tile.

void RoutePlanner::AStarSearch() {
RouteModel::Node *current_node = nullptr;

// TODO: Implement your solution here.

start_node->visited = true;
open_list.push_back(start_node);
while (open_list.size() > 0)
{
current_node = NextNode();
if(current_node == end_node){
m_Model.path = ConstructFinalPath(current_node);
return;
}
else
{
AddNeighbors(current_node);
}
}
}
3 changes: 0 additions & 3 deletions src/route_planner.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,15 @@
class RoutePlanner {
public:
RoutePlanner(RouteModel &model, float start_x, float start_y, float end_x, float end_y);
// Add public variables or methods declarations here.
float GetDistance() const {return distance;}
void AStarSearch();

// The following methods have been made public so we can test them individually.
void AddNeighbors(RouteModel::Node *current_node);
float CalculateHValue(RouteModel::Node const *node);
std::vector<RouteModel::Node> ConstructFinalPath(RouteModel::Node *);
RouteModel::Node *NextNode();

private:
// Add private variables or methods declarations here.
std::vector<RouteModel::Node*> open_list;
RouteModel::Node *start_node;
RouteModel::Node *end_node;
Expand Down
Loading