-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrrt.cpp
184 lines (160 loc) · 4.38 KB
/
rrt.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#include <iostream>
#include <vector>
#include <cmath>
#include <random>
struct Node
{
double x;
double y;
Node *parent;
Node(double x_val, double y_val, Node *parent_node)
{
x = x_val;
y = y_val;
parent = parent_node;
}
};
// Euclidean distance
double distance(Node *node1, Node *node2)
{
double dx = node1->x - node2->x;
double dy = node1->y - node2->y;
return std::sqrt(dx * dx + dy * dy);
}
Node *generateRandomNode(double max_x, double max_y)
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<double> dist_x(0.0, max_x);
std::uniform_real_distribution<double> dist_y(0.0, max_y);
double x = dist_x(gen);
double y = dist_y(gen);
return new Node(x, y, nullptr);
}
Node *findNearestNode(const std::vector<Node *> &tree, Node *random_node)
{
Node *nearest_node = nullptr;
double min_distance = std::numeric_limits<double>::max();
for (Node *node : tree)
{
double dist = distance(node, random_node);
if (dist < min_distance)
{
min_distance = dist;
nearest_node = node;
}
}
return nearest_node;
}
Node *steer(
Node *nearest_node,
Node *random_node, double max_step)
{
double dist = distance(nearest_node, random_node);
if (dist <= max_step)
{
return random_node;
}
else
{
double theta = std::atan2(
random_node->y - nearest_node->y,
random_node->x - nearest_node->x);
double new_x = nearest_node->x + max_step * std::cos(theta);
double new_y = nearest_node->y + max_step * std::sin(theta);
return new Node(new_x, new_y, nearest_node);
}
}
bool isCollisionFree(
Node *node, double obs_x,
double obs_y,
double obs_width,
double obs_height)
{
// Check collision with obstacles or environment constraints
// Assuming a rectangular obstacle defined by (obs_x, obs_y) and (obs_x + obs_width, obs_y + obs_height)
// Check if the node is inside the rectangular obstacle
if (node->x >= obs_x && node->x <= obs_x + obs_width &&
node->y >= obs_y && node->y <= obs_y + obs_height)
{
return false; // Node is in collision
}
return true; // Node is collision-free
}
std::vector<Node *> buildRRT(
double start_x,
double start_y,
double goal_x,
double goal_y,
double max_x,
double max_y,
int max_iterations,
double max_step)
{
std::vector<Node *> tree;
Node *start_node = new Node(start_x, start_y, nullptr);
tree.push_back(start_node);
// Assuming rectangular obstacle defined in the environment
double obs_x = 2.0;
double obs_y = 2.0;
double obs_width = 1.0;
double obs_height = 1.0;
for (int i = 0; i < max_iterations; i++)
{
Node *random_node = generateRandomNode(max_x, max_y);
Node *nearest_node = findNearestNode(tree, random_node);
Node *new_node = steer(nearest_node, random_node, max_step);
if (isCollisionFree(new_node, obs_x, obs_y, obs_width, obs_height))
{
tree.push_back(new_node);
// Check if the goal is reached
if (distance(new_node, new Node(goal_x, goal_y, nullptr)) <= max_step)
{
Node *goal_node = new Node(goal_x, goal_y, new_node);
tree.push_back(goal_node);
return tree; // Path found
}
}
}
return tree; // Path not found
}
int main()
{
double start_x = 0.0;
double start_y = 0.0;
double goal_x = 5.0;
double goal_y = 5.0;
double max_x = 10.0;
double max_y = 10.0;
int max_iterations = 1000;
double max_step = 0.5;
std::vector<Node *> rrt_tree = buildRRT(
start_x,
start_y,
goal_x,
goal_y,
max_x,
max_y,
max_iterations,
max_step);
// Print the path if it exists
if (rrt_tree.size() > 0)
{
Node *current_node = rrt_tree.back();
while (current_node != nullptr)
{
std::cout << "(" << current_node->x << ", " << current_node->y << ")" << std::endl;
current_node = current_node->parent;
}
}
else
{
std::cout << "Path not found!" << std::endl;
}
// Memory Cleanup: Delete allocated nodes
for (Node *node : rrt_tree)
{
delete node;
}
return 0;
}