Skip to content

Commit 39fcf9c

Browse files
authored
Merge pull request #24 from mlsdpk/incremental-planning
Integrate Incremental planners
2 parents c4926d9 + 2f589f1 commit 39fcf9c

File tree

28 files changed

+1081
-753
lines changed

28 files changed

+1081
-753
lines changed

README.md

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,10 @@
44

55
A tool for visualizing numerous pathfinding algorithms in two dimensions.
66

7-
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.
7+
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.
88

99
![](figures/img0.png)
1010

11-
## How to use
12-
13-
- to place/remove obstacle cells (`left-CLICKED`)
14-
- to change starting cell (`left-SHIFT + left-CLICKED`)
15-
- to change end cell (`left-CTRL + left-CLICKED`)
16-
1711
## Dependencies
1812

1913
* cmake >= 3.14

dependencies/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ add_subdirectory(sfml)
1111
FetchContent_Declare(
1212
imgui
1313
GIT_REPOSITORY https://github.com/ocornut/imgui
14-
GIT_TAG 55d35d8387c15bf0cfd71861df67af8cfbda7456
14+
# GIT_TAG 55d35d8387c15bf0cfd71861df67af8cfbda7456
15+
GIT_TAG 719d9313041b85227a3e6deb289a313819aaeab3 # latest commit of docking-branch
1516
)
1617

1718
FetchContent_Declare(

figures/img0.png

168 KB
Loading

include/Game.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ enum SAMPLING_BASED_PLANNERS_IDS { RRT, RRT_STAR };
2222
class Game {
2323
public:
2424
// Constructors
25-
Game(sf::RenderWindow* window);
25+
Game(sf::RenderWindow* window, sf::RenderTexture* render_texture);
2626

2727
// Destructors
2828
virtual ~Game();
@@ -36,17 +36,30 @@ class Game {
3636
void update();
3737
void render();
3838
void initGuiTheme();
39-
void renderGui();
39+
void renderNewPlannerMenu();
40+
void renderRunMenu(ImGuiIO& io);
4041
void setGraphBasedPlanner(const int id);
4142
void setSamplingBasedPlanner(const int id);
43+
void showHowToUseWindow();
44+
void showAboutWindow();
4245

4346
private:
4447
sf::RenderWindow* window_;
48+
sf::RenderTexture* render_texture_;
49+
sf::Vector2f view_move_xy_;
50+
ImVec2 mouse_pos_in_canvas_;
4551
sf::Event ev_;
4652
sf::Clock dtClock_;
4753
float dt_;
4854
std::stack<std::unique_ptr<State>> states_;
4955
std::string curr_planner_;
56+
std::shared_ptr<gui::LoggerPanel> logger_panel_;
57+
bool disable_run_;
58+
bool show_how_to_use_window_{true};
59+
bool show_about_window_{true};
60+
bool show_control_panel_{true};
61+
bool show_console_{true};
62+
bool show_stats_panel_{true};
5063
};
5164

5265
} // namespace path_finding_visualizer

include/Gui.h

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
#pragma once
2+
3+
#include <imgui-SFML.h>
4+
#include <imgui.h>
5+
6+
namespace path_finding_visualizer {
7+
namespace gui {
8+
9+
class LoggerPanel {
10+
public:
11+
LoggerPanel() {
12+
AutoScroll = true;
13+
clear();
14+
}
15+
16+
void clear() {
17+
Buf.clear();
18+
LineOffsets.clear();
19+
LineOffsets.push_back(0);
20+
}
21+
22+
void render(const char* title) {
23+
if (!ImGui::Begin(title)) {
24+
ImGui::End();
25+
return;
26+
}
27+
28+
ImGui::BeginChild("scrolling", ImVec2(0, 0), false,
29+
ImGuiWindowFlags_HorizontalScrollbar);
30+
31+
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
32+
const char* buf = Buf.begin();
33+
const char* buf_end = Buf.end();
34+
{
35+
ImGuiListClipper clipper;
36+
clipper.Begin(LineOffsets.Size);
37+
while (clipper.Step()) {
38+
for (int line_no = clipper.DisplayStart; line_no < clipper.DisplayEnd;
39+
line_no++) {
40+
const char* line_start = buf + LineOffsets[line_no];
41+
const char* line_end = (line_no + 1 < LineOffsets.Size)
42+
? (buf + LineOffsets[line_no + 1] - 1)
43+
: buf_end;
44+
ImGui::TextUnformatted(line_start, line_end);
45+
}
46+
}
47+
clipper.End();
48+
}
49+
ImGui::PopStyleVar();
50+
51+
if (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())
52+
ImGui::SetScrollHereY(1.0f);
53+
54+
ImGui::EndChild();
55+
ImGui::End();
56+
}
57+
58+
void info(const std::string& msg) { AddLog("[INFO] %s\n", msg.c_str()); }
59+
60+
private:
61+
ImGuiTextBuffer Buf;
62+
ImVector<int> LineOffsets; // Index to lines offset. We maintain this with
63+
// AddLog() calls.
64+
bool AutoScroll; // Keep scrolling if already at the bottom.
65+
66+
void AddLog(const char* fmt, ...) IM_FMTARGS(2) {
67+
int old_size = Buf.size();
68+
va_list args;
69+
va_start(args, fmt);
70+
Buf.appendfv(fmt, args);
71+
va_end(args);
72+
for (int new_size = Buf.size(); old_size < new_size; old_size++)
73+
if (Buf[old_size] == '\n') LineOffsets.push_back(old_size + 1);
74+
}
75+
};
76+
77+
// Helper to display a little (?) mark which shows a tooltip when hovered.
78+
// In your own code you may want to display an actual icon if you are using a
79+
// merged icon fonts (see docs/FONTS.md)
80+
inline void HelpMarker(const char* desc) {
81+
ImGui::TextDisabled("(?)");
82+
if (ImGui::IsItemHovered()) {
83+
ImGui::BeginTooltip();
84+
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
85+
ImGui::TextUnformatted(desc);
86+
ImGui::PopTextWrapPos();
87+
ImGui::EndTooltip();
88+
}
89+
}
90+
91+
inline bool inputInt(const std::string& label, int* val, const int& min_val,
92+
const int& max_val, const int& step = 1,
93+
const int& step_fast = 100,
94+
const std::string& help_marker = "",
95+
ImGuiInputTextFlags flags = 0) {
96+
flags |= ImGuiInputTextFlags_EnterReturnsTrue;
97+
bool is_active = ImGui::InputInt(label.c_str(), val, step, step_fast, flags);
98+
if (!help_marker.empty()) {
99+
ImGui::SameLine();
100+
HelpMarker(help_marker.c_str());
101+
}
102+
if (is_active) {
103+
if (*val < min_val)
104+
*val = min_val;
105+
else if (*val > max_val)
106+
*val = max_val;
107+
}
108+
return is_active;
109+
}
110+
111+
inline bool inputDouble(const std::string& label, double* val,
112+
const double& min_val, const double& max_val,
113+
const double& step = 0.0, const double& step_fast = 0.0,
114+
const std::string& help_marker = "",
115+
const char* format = "%.6f",
116+
ImGuiInputTextFlags flags = 0) {
117+
flags |= ImGuiInputTextFlags_EnterReturnsTrue;
118+
bool is_active =
119+
ImGui::InputDouble(label.c_str(), val, step, step_fast, format, flags);
120+
if (!help_marker.empty()) {
121+
ImGui::SameLine();
122+
HelpMarker(help_marker.c_str());
123+
}
124+
if (is_active) {
125+
if (*val < min_val)
126+
*val = min_val;
127+
else if (*val > max_val)
128+
*val = max_val;
129+
}
130+
return is_active;
131+
}
132+
133+
} // namespace gui
134+
} // namespace path_finding_visualizer

include/State.h

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@
66
#include <fstream>
77
#include <iostream>
88
#include <map>
9+
#include <memory>
910
#include <stack>
1011
#include <string>
1112
#include <vector>
1213

14+
#include "Gui.h"
15+
1316
/*
1417
State Base Class
1518
*/
@@ -19,31 +22,29 @@ namespace path_finding_visualizer {
1922
class State {
2023
private:
2124
protected:
22-
std::stack<std::unique_ptr<State>> &states_;
23-
24-
sf::RenderWindow *window_;
25-
sf::Vector2i mousePositionWindow_;
26-
bool quit_;
25+
std::shared_ptr<gui::LoggerPanel> logger_panel_;
26+
sf::Vector2f mousePositionWindow_;
27+
bool is_reset_;
28+
bool is_running_;
2729

2830
public:
2931
// Constructor
30-
State(sf::RenderWindow *window, std::stack<std::unique_ptr<State>> &states);
32+
State(std::shared_ptr<gui::LoggerPanel> logger_panel);
3133

3234
// Destructor
3335
virtual ~State();
3436

35-
// Accessors
36-
const bool getQuit() const;
37+
void setReset(bool is_reset) { is_reset_ = is_reset; }
38+
void setRunning(bool is_running) { is_running_ = is_running; }
3739

3840
// Functions
39-
virtual void checkForQuit();
40-
virtual void updateMousePosition();
41+
void updateMousePosition(const ImVec2 &mousePos);
4142

4243
// virtual functions
4344
virtual void endState() = 0;
44-
virtual void updateKeybinds() = 0;
45-
virtual void update(const float &dt) = 0;
46-
virtual void render() = 0;
45+
virtual void update(const float &dt, const ImVec2 &mousePos) = 0;
46+
virtual void renderConfig() = 0;
47+
virtual void renderScene(sf::RenderTexture &render_texture) = 0;
4748
};
4849

4950
} // namespace path_finding_visualizer

include/States/Algorithms/GraphBased/ASTAR/ASTAR.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,17 @@ struct MinimumDistanceASTAR {
2121
class ASTAR : public BFS {
2222
public:
2323
// Constructor
24-
ASTAR(sf::RenderWindow *window, std::stack<std::unique_ptr<State>> &states);
24+
ASTAR(std::shared_ptr<gui::LoggerPanel> logger_panel);
2525

2626
// Destructor
2727
virtual ~ASTAR();
2828

2929
// Overriden functions
3030
virtual void initAlgorithm() override;
31-
virtual void solveConcurrently(
32-
std::shared_ptr<Node> nodeStart, std::shared_ptr<Node> nodeEnd,
33-
std::shared_ptr<MessageQueue<bool>> message_queue) override;
31+
32+
// override main update function
33+
virtual void updatePlanner(bool &solved, Node &start_node,
34+
Node &end_node) override;
3435

3536
protected:
3637
// ASTAR related

include/States/Algorithms/GraphBased/BFS/BFS.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace graph_based {
1111
class BFS : public GraphBased {
1212
public:
1313
// Constructor
14-
BFS(sf::RenderWindow *window, std::stack<std::unique_ptr<State>> &states);
14+
BFS(std::shared_ptr<gui::LoggerPanel> logger_panel);
1515

1616
// Destructor
1717
virtual ~BFS();
@@ -23,13 +23,12 @@ class BFS : public GraphBased {
2323
virtual void updateNodes() override;
2424

2525
// override render functions
26-
virtual void renderNodes() override;
26+
virtual void renderNodes(sf::RenderTexture &render_texture) override;
2727
virtual void renderParametersGui() override;
2828

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

3433
private:
3534
// BFS related

include/States/Algorithms/GraphBased/DFS/DFS.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,17 @@ namespace graph_based {
1010
class DFS : public BFS {
1111
public:
1212
// Constructor
13-
DFS(sf::RenderWindow *window, std::stack<std::unique_ptr<State>> &states);
13+
DFS(std::shared_ptr<gui::LoggerPanel> logger_panel);
1414

1515
// Destructor
1616
virtual ~DFS();
1717

1818
// override initialization Functions
1919
void initAlgorithm() override;
2020

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

2625
private:
2726
// DFS related

include/States/Algorithms/GraphBased/DIJKSTRA/DIJKSTRA.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,17 @@ struct MinimumDistanceDIJKSTRA {
2121
class DIJKSTRA : public BFS {
2222
public:
2323
// Constructor
24-
DIJKSTRA(sf::RenderWindow *window,
25-
std::stack<std::unique_ptr<State>> &states);
24+
DIJKSTRA(std::shared_ptr<gui::LoggerPanel> logger_panel);
2625

2726
// Destructor
2827
virtual ~DIJKSTRA();
2928

3029
// Overriden functions
3130
virtual void initAlgorithm() override;
32-
void solveConcurrently(
33-
std::shared_ptr<Node> nodeStart, std::shared_ptr<Node> nodeEnd,
34-
std::shared_ptr<MessageQueue<bool>> message_queue) override;
31+
32+
// override main update function
33+
virtual void updatePlanner(bool &solved, Node &start_node,
34+
Node &end_node) override;
3535

3636
protected:
3737
// DIJKSTRA related

0 commit comments

Comments
 (0)