Skip to content

Commit

Permalink
Merge pull request #24 from mlsdpk/incremental-planning
Browse files Browse the repository at this point in the history
Integrate Incremental planners
  • Loading branch information
mlsdpk authored Dec 2, 2021
2 parents c4926d9 + 2f589f1 commit 39fcf9c
Show file tree
Hide file tree
Showing 28 changed files with 1,081 additions and 753 deletions.
8 changes: 1 addition & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,10 @@

A tool for visualizing numerous pathfinding algorithms in two dimensions.

This project involves minimal implementations of the popular planning algorithms, including both graph-based and sampling-based planners. We provide an easy-to-use GUI to control the animation process and explore different planner configurations. This is an ongoing work and current implementation of the project only involves four search-based planning algorithms: BFS, DFS, DIJKSTRA and A-Star and two sampling-based planners: RRT and RRT*. The project extensively uses SFML, ImGui and Modern C++ features such as smart pointers, lamda expressions along with multi-threading concepts.
This project involves minimal implementations of the popular planning algorithms, including both graph-based and sampling-based planners. We provide an easy-to-use GUI to control the animation process and explore different planner configurations. Current implementation of the project involves four search-based planning algorithms: BFS, DFS, DIJKSTRA and A-Star and two sampling-based planners: RRT and RRT*. The project extensively uses SFML, ImGui and Modern C++ features such as smart pointers, lamda expressions along with multi-threading concepts.

![](figures/img0.png)

## How to use

- to place/remove obstacle cells (`left-CLICKED`)
- to change starting cell (`left-SHIFT + left-CLICKED`)
- to change end cell (`left-CTRL + left-CLICKED`)

## Dependencies

* cmake >= 3.14
Expand Down
3 changes: 2 additions & 1 deletion dependencies/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ add_subdirectory(sfml)
FetchContent_Declare(
imgui
GIT_REPOSITORY https://github.com/ocornut/imgui
GIT_TAG 55d35d8387c15bf0cfd71861df67af8cfbda7456
# GIT_TAG 55d35d8387c15bf0cfd71861df67af8cfbda7456
GIT_TAG 719d9313041b85227a3e6deb289a313819aaeab3 # latest commit of docking-branch
)

FetchContent_Declare(
Expand Down
Binary file modified figures/img0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 15 additions & 2 deletions include/Game.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ enum SAMPLING_BASED_PLANNERS_IDS { RRT, RRT_STAR };
class Game {
public:
// Constructors
Game(sf::RenderWindow* window);
Game(sf::RenderWindow* window, sf::RenderTexture* render_texture);

// Destructors
virtual ~Game();
Expand All @@ -36,17 +36,30 @@ class Game {
void update();
void render();
void initGuiTheme();
void renderGui();
void renderNewPlannerMenu();
void renderRunMenu(ImGuiIO& io);
void setGraphBasedPlanner(const int id);
void setSamplingBasedPlanner(const int id);
void showHowToUseWindow();
void showAboutWindow();

private:
sf::RenderWindow* window_;
sf::RenderTexture* render_texture_;
sf::Vector2f view_move_xy_;
ImVec2 mouse_pos_in_canvas_;
sf::Event ev_;
sf::Clock dtClock_;
float dt_;
std::stack<std::unique_ptr<State>> states_;
std::string curr_planner_;
std::shared_ptr<gui::LoggerPanel> logger_panel_;
bool disable_run_;
bool show_how_to_use_window_{true};
bool show_about_window_{true};
bool show_control_panel_{true};
bool show_console_{true};
bool show_stats_panel_{true};
};

} // namespace path_finding_visualizer
134 changes: 134 additions & 0 deletions include/Gui.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#pragma once

#include <imgui-SFML.h>
#include <imgui.h>

namespace path_finding_visualizer {
namespace gui {

class LoggerPanel {
public:
LoggerPanel() {
AutoScroll = true;
clear();
}

void clear() {
Buf.clear();
LineOffsets.clear();
LineOffsets.push_back(0);
}

void render(const char* title) {
if (!ImGui::Begin(title)) {
ImGui::End();
return;
}

ImGui::BeginChild("scrolling", ImVec2(0, 0), false,
ImGuiWindowFlags_HorizontalScrollbar);

ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
const char* buf = Buf.begin();
const char* buf_end = Buf.end();
{
ImGuiListClipper clipper;
clipper.Begin(LineOffsets.Size);
while (clipper.Step()) {
for (int line_no = clipper.DisplayStart; line_no < clipper.DisplayEnd;
line_no++) {
const char* line_start = buf + LineOffsets[line_no];
const char* line_end = (line_no + 1 < LineOffsets.Size)
? (buf + LineOffsets[line_no + 1] - 1)
: buf_end;
ImGui::TextUnformatted(line_start, line_end);
}
}
clipper.End();
}
ImGui::PopStyleVar();

if (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())
ImGui::SetScrollHereY(1.0f);

ImGui::EndChild();
ImGui::End();
}

void info(const std::string& msg) { AddLog("[INFO] %s\n", msg.c_str()); }

private:
ImGuiTextBuffer Buf;
ImVector<int> LineOffsets; // Index to lines offset. We maintain this with
// AddLog() calls.
bool AutoScroll; // Keep scrolling if already at the bottom.

void AddLog(const char* fmt, ...) IM_FMTARGS(2) {
int old_size = Buf.size();
va_list args;
va_start(args, fmt);
Buf.appendfv(fmt, args);
va_end(args);
for (int new_size = Buf.size(); old_size < new_size; old_size++)
if (Buf[old_size] == '\n') LineOffsets.push_back(old_size + 1);
}
};

// Helper to display a little (?) mark which shows a tooltip when hovered.
// In your own code you may want to display an actual icon if you are using a
// merged icon fonts (see docs/FONTS.md)
inline void HelpMarker(const char* desc) {
ImGui::TextDisabled("(?)");
if (ImGui::IsItemHovered()) {
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
ImGui::TextUnformatted(desc);
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
}
}

inline bool inputInt(const std::string& label, int* val, const int& min_val,
const int& max_val, const int& step = 1,
const int& step_fast = 100,
const std::string& help_marker = "",
ImGuiInputTextFlags flags = 0) {
flags |= ImGuiInputTextFlags_EnterReturnsTrue;
bool is_active = ImGui::InputInt(label.c_str(), val, step, step_fast, flags);
if (!help_marker.empty()) {
ImGui::SameLine();
HelpMarker(help_marker.c_str());
}
if (is_active) {
if (*val < min_val)
*val = min_val;
else if (*val > max_val)
*val = max_val;
}
return is_active;
}

inline bool inputDouble(const std::string& label, double* val,
const double& min_val, const double& max_val,
const double& step = 0.0, const double& step_fast = 0.0,
const std::string& help_marker = "",
const char* format = "%.6f",
ImGuiInputTextFlags flags = 0) {
flags |= ImGuiInputTextFlags_EnterReturnsTrue;
bool is_active =
ImGui::InputDouble(label.c_str(), val, step, step_fast, format, flags);
if (!help_marker.empty()) {
ImGui::SameLine();
HelpMarker(help_marker.c_str());
}
if (is_active) {
if (*val < min_val)
*val = min_val;
else if (*val > max_val)
*val = max_val;
}
return is_active;
}

} // namespace gui
} // namespace path_finding_visualizer
27 changes: 14 additions & 13 deletions include/State.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
#include <fstream>
#include <iostream>
#include <map>
#include <memory>
#include <stack>
#include <string>
#include <vector>

#include "Gui.h"

/*
State Base Class
*/
Expand All @@ -19,31 +22,29 @@ namespace path_finding_visualizer {
class State {
private:
protected:
std::stack<std::unique_ptr<State>> &states_;

sf::RenderWindow *window_;
sf::Vector2i mousePositionWindow_;
bool quit_;
std::shared_ptr<gui::LoggerPanel> logger_panel_;
sf::Vector2f mousePositionWindow_;
bool is_reset_;
bool is_running_;

public:
// Constructor
State(sf::RenderWindow *window, std::stack<std::unique_ptr<State>> &states);
State(std::shared_ptr<gui::LoggerPanel> logger_panel);

// Destructor
virtual ~State();

// Accessors
const bool getQuit() const;
void setReset(bool is_reset) { is_reset_ = is_reset; }
void setRunning(bool is_running) { is_running_ = is_running; }

// Functions
virtual void checkForQuit();
virtual void updateMousePosition();
void updateMousePosition(const ImVec2 &mousePos);

// virtual functions
virtual void endState() = 0;
virtual void updateKeybinds() = 0;
virtual void update(const float &dt) = 0;
virtual void render() = 0;
virtual void update(const float &dt, const ImVec2 &mousePos) = 0;
virtual void renderConfig() = 0;
virtual void renderScene(sf::RenderTexture &render_texture) = 0;
};

} // namespace path_finding_visualizer
9 changes: 5 additions & 4 deletions include/States/Algorithms/GraphBased/ASTAR/ASTAR.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,17 @@ struct MinimumDistanceASTAR {
class ASTAR : public BFS {
public:
// Constructor
ASTAR(sf::RenderWindow *window, std::stack<std::unique_ptr<State>> &states);
ASTAR(std::shared_ptr<gui::LoggerPanel> logger_panel);

// Destructor
virtual ~ASTAR();

// Overriden functions
virtual void initAlgorithm() override;
virtual void solveConcurrently(
std::shared_ptr<Node> nodeStart, std::shared_ptr<Node> nodeEnd,
std::shared_ptr<MessageQueue<bool>> message_queue) override;

// override main update function
virtual void updatePlanner(bool &solved, Node &start_node,
Node &end_node) override;

protected:
// ASTAR related
Expand Down
11 changes: 5 additions & 6 deletions include/States/Algorithms/GraphBased/BFS/BFS.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace graph_based {
class BFS : public GraphBased {
public:
// Constructor
BFS(sf::RenderWindow *window, std::stack<std::unique_ptr<State>> &states);
BFS(std::shared_ptr<gui::LoggerPanel> logger_panel);

// Destructor
virtual ~BFS();
Expand All @@ -23,13 +23,12 @@ class BFS : public GraphBased {
virtual void updateNodes() override;

// override render functions
virtual void renderNodes() override;
virtual void renderNodes(sf::RenderTexture &render_texture) override;
virtual void renderParametersGui() override;

// BFS algorithm function
virtual void solveConcurrently(
std::shared_ptr<Node> nodeStart, std::shared_ptr<Node> nodeEnd,
std::shared_ptr<MessageQueue<bool>> message_queue) override;
// override main update function
virtual void updatePlanner(bool &solved, Node &start_node,
Node &end_node) override;

private:
// BFS related
Expand Down
9 changes: 4 additions & 5 deletions include/States/Algorithms/GraphBased/DFS/DFS.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,17 @@ namespace graph_based {
class DFS : public BFS {
public:
// Constructor
DFS(sf::RenderWindow *window, std::stack<std::unique_ptr<State>> &states);
DFS(std::shared_ptr<gui::LoggerPanel> logger_panel);

// Destructor
virtual ~DFS();

// override initialization Functions
void initAlgorithm() override;

// DFS algorithm function
void solveConcurrently(
std::shared_ptr<Node> nodeStart, std::shared_ptr<Node> nodeEnd,
std::shared_ptr<MessageQueue<bool>> message_queue) override;
// override main update function
virtual void updatePlanner(bool &solved, Node &start_node,
Node &end_node) override;

private:
// DFS related
Expand Down
10 changes: 5 additions & 5 deletions include/States/Algorithms/GraphBased/DIJKSTRA/DIJKSTRA.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,17 @@ struct MinimumDistanceDIJKSTRA {
class DIJKSTRA : public BFS {
public:
// Constructor
DIJKSTRA(sf::RenderWindow *window,
std::stack<std::unique_ptr<State>> &states);
DIJKSTRA(std::shared_ptr<gui::LoggerPanel> logger_panel);

// Destructor
virtual ~DIJKSTRA();

// Overriden functions
virtual void initAlgorithm() override;
void solveConcurrently(
std::shared_ptr<Node> nodeStart, std::shared_ptr<Node> nodeEnd,
std::shared_ptr<MessageQueue<bool>> message_queue) override;

// override main update function
virtual void updatePlanner(bool &solved, Node &start_node,
Node &end_node) override;

protected:
// DIJKSTRA related
Expand Down
Loading

0 comments on commit 39fcf9c

Please sign in to comment.