Skip to content

Commit cfd8384

Browse files
committed
for good measure
1 parent ae85e66 commit cfd8384

File tree

3 files changed

+119
-10
lines changed

3 files changed

+119
-10
lines changed

PathPlanning/VisibilityGraphPlanner/visibility_graph_planner.py

Lines changed: 117 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,127 @@
66
77
"""
88

9+
import os
10+
import sys
11+
12+
sys.path.append(os.path.dirname(os.path.abspath(__file__)) +
13+
"/../VoronoiRoadMap/")
14+
15+
import math
16+
import numpy as np
917
import matplotlib.pyplot as plt
18+
from dijkstra_search import DijkstraSearch
1019

1120
show_animation = True
1221

22+
1323
class VisibilityGraphPlanner:
1424

1525
def __init__(self, robot_radius):
1626
self.robot_radius = robot_radius
1727

1828
def planning(self, start_x, start_y, goal_x, goal_y, obstacles):
19-
nodes = self.exstract_graph_node(start_x, start_y, goal_x, goal_y,
20-
obstacles)
21-
29+
nodes = self.extract_graph_node(start_x, start_y, goal_x, goal_y,
30+
obstacles)
2231
graph = self.generate_graph(nodes, obstacles)
2332

24-
rx, ry = dijkstra_search(graph)
33+
# rx, ry = DijkstraSearch().search(graph)
34+
35+
rx, ry = [], []
2536

2637
return rx, ry
2738

28-
def exstract_graph_node(self, start_x, start_y, goal_x, goal_x, obstacles):
29-
nodes = []
39+
def extract_graph_node(self, start_x, start_y, goal_x, goal_y, obstacles):
40+
41+
# add start and goal as nodes
42+
nodes = [DijkstraSearch.Node(start_x, start_y),
43+
DijkstraSearch.Node(goal_x, goal_y, 0, None)]
44+
45+
# add vertexes in configuration space as nodes
46+
for obstacle in obstacles:
47+
48+
cvx_list, cvy_list = self.calc_vertexes_in_configuration_space(
49+
obstacle.x_list, obstacle.y_list)
50+
51+
for (vx, vy) in zip(cvx_list, cvy_list):
52+
nodes.append(DijkstraSearch.Node(vx, vy))
53+
54+
for node in nodes:
55+
plt.plot(node.x, node.y, "xr")
3056

3157
return nodes
3258

59+
def calc_vertexes_in_configuration_space(self, x_list, y_list):
60+
x_list=x_list[0:-1]
61+
y_list=y_list[0:-1]
62+
cvx_list, cvy_list = [], []
63+
64+
n_data=len(x_list)
65+
66+
for index in range(n_data):
67+
offset_x, offset_y = self.calc_offset_xy(
68+
x_list[index - 1], y_list[index - 1],
69+
x_list[index], y_list[index],
70+
x_list[(index + 1) % n_data], y_list[(index + 1) % n_data],
71+
)
72+
cvx_list.append(offset_x)
73+
cvy_list.append(offset_y)
74+
75+
return cvx_list, cvy_list
76+
3377
def generate_graph(self, nodes, obstacles):
3478

3579
graph = []
3680

81+
for target_node in nodes:
82+
for node in nodes:
83+
for obstacle in obstacles:
84+
if not self.is_edge_valid(target_node, node, obstacle):
85+
print("bb")
86+
break
87+
print(target_node, node)
88+
print("aa")
89+
plt.plot([target_node.x, node.x],[target_node.y, node.y], "-r")
90+
3791
return graph
3892

93+
def is_edge_valid(self, target_node, node, obstacle):
94+
95+
for i in range(len(obstacle.x_list)-1):
96+
p1 = np.array([target_node.x, target_node.y])
97+
p2 = np.array([node.x, node.y])
98+
p3 = np.array([obstacle.x_list[i], obstacle.y_list[i]])
99+
p4 = np.array([obstacle.y_list[i+1], obstacle.y_list[i+1]])
100+
101+
if is_seg_intersect(p1, p2, p3, p4):
102+
return False
103+
104+
return True
105+
106+
def calc_offset_xy(self, px, py, x, y, nx, ny):
107+
p_vec = math.atan2(y - py, x - px)
108+
n_vec = math.atan2(ny - y, nx - x)
109+
offset_vec = math.atan2(math.sin(p_vec) + math.sin(n_vec),
110+
math.cos(p_vec) + math.cos(
111+
n_vec))+math.pi/2.0
112+
offset_x = x + self.robot_radius * math.cos(offset_vec)
113+
offset_y = y + self.robot_radius * math.sin(offset_vec)
114+
return offset_x, offset_y
115+
116+
117+
def is_seg_intersect(a1, a2, b1, b2):
118+
119+
xdiff = [a1[0] - a2[0], b1[0] - b2[0]]
120+
ydiff = [a1[1] - a2[1], b1[1] - b2[1]]
121+
122+
def det(a, b):
123+
return a[0] * b[1] - a[1] * b[0]
124+
125+
div = det(xdiff, ydiff)
126+
if div == 0:
127+
return False
128+
else:
129+
return True
39130

40131
class ObstaclePolygon:
41132

@@ -44,6 +135,21 @@ def __init__(self, x_list, y_list):
44135
self.y_list = y_list
45136

46137
self.close_polygon()
138+
self.make_clockwise()
139+
140+
def make_clockwise(self):
141+
if not self.is_clockwise():
142+
self.x_list = list(reversed(self.x_list))
143+
self.y_list = list(reversed(self.y_list))
144+
145+
def is_clockwise(self):
146+
n_data = len(self.x_list)
147+
eval_sum = sum([(self.x_list[i + 1] - self.x_list[i]) *
148+
(self.y_list[i + 1] + self.y_list[i])
149+
for i in range(n_data - 1)])
150+
eval_sum += (self.x_list[0] - self.x_list[n_data - 1]) * \
151+
(self.y_list[0] + self.y_list[n_data - 1])
152+
return eval_sum >= 0
47153

48154
def close_polygon(self):
49155
is_x_same = self.x_list[0] == self.x_list[-1]
@@ -74,13 +180,15 @@ def main():
74180
[50.0, 40.0, 20.0, 40.0],
75181
)]
76182

77-
rx, ry = VisibilityGraphPlanner(robot_radius).planning(sx, sy, gx, gy,
78-
obstacles)
79-
assert rx, 'Cannot found path'
80183
if show_animation: # pragma: no cover
81184
plt.plot(sx, sy, "or")
82185
plt.plot(gx, gy, "ob")
83186
[ob.plot() for ob in obstacles]
187+
188+
rx, ry = VisibilityGraphPlanner(robot_radius).planning(sx, sy, gx, gy,
189+
obstacles)
190+
# assert rx, 'Cannot found path'
191+
if show_animation: # pragma: no cover
84192
plt.plot(rx, ry, "-r")
85193
plt.axis("equal")
86194
plt.show()

PathPlanning/VoronoiRoadMap/dijkstra_search.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class Node:
1717
Node class for dijkstra search
1818
"""
1919

20-
def __init__(self, x, y, cost, parent):
20+
def __init__(self, x, y, cost=None, parent=None):
2121
self.x = x
2222
self.y = y
2323
self.cost = cost

tests/test_rrt_star_dubins.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import sys
44
import os
5+
56
sys.path.append(os.path.dirname(os.path.abspath(__file__))
67
+ "/../PathPlanning/RRTStarDubins/")
78

0 commit comments

Comments
 (0)