python-motion-planning 0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. python_motion_planning/__init__.py +4 -0
  2. python_motion_planning/curve_generation/__init__.py +9 -0
  3. python_motion_planning/curve_generation/bezier_curve.py +131 -0
  4. python_motion_planning/curve_generation/bspline_curve.py +271 -0
  5. python_motion_planning/curve_generation/cubic_spline.py +128 -0
  6. python_motion_planning/curve_generation/curve.py +64 -0
  7. python_motion_planning/curve_generation/dubins_curve.py +348 -0
  8. python_motion_planning/curve_generation/fem_pos_smooth.py +114 -0
  9. python_motion_planning/curve_generation/polynomial_curve.py +226 -0
  10. python_motion_planning/curve_generation/reeds_shepp.py +736 -0
  11. python_motion_planning/global_planner/__init__.py +3 -0
  12. python_motion_planning/global_planner/evolutionary_search/__init__.py +4 -0
  13. python_motion_planning/global_planner/evolutionary_search/aco.py +186 -0
  14. python_motion_planning/global_planner/evolutionary_search/evolutionary_search.py +87 -0
  15. python_motion_planning/global_planner/evolutionary_search/pso.py +356 -0
  16. python_motion_planning/global_planner/graph_search/__init__.py +28 -0
  17. python_motion_planning/global_planner/graph_search/a_star.py +124 -0
  18. python_motion_planning/global_planner/graph_search/d_star.py +291 -0
  19. python_motion_planning/global_planner/graph_search/d_star_lite.py +188 -0
  20. python_motion_planning/global_planner/graph_search/dijkstra.py +77 -0
  21. python_motion_planning/global_planner/graph_search/gbfs.py +78 -0
  22. python_motion_planning/global_planner/graph_search/graph_search.py +87 -0
  23. python_motion_planning/global_planner/graph_search/jps.py +165 -0
  24. python_motion_planning/global_planner/graph_search/lazy_theta_star.py +114 -0
  25. python_motion_planning/global_planner/graph_search/lpa_star.py +230 -0
  26. python_motion_planning/global_planner/graph_search/s_theta_star.py +133 -0
  27. python_motion_planning/global_planner/graph_search/theta_star.py +171 -0
  28. python_motion_planning/global_planner/graph_search/voronoi.py +200 -0
  29. python_motion_planning/global_planner/sample_search/__init__.py +6 -0
  30. python_motion_planning/global_planner/sample_search/informed_rrt.py +152 -0
  31. python_motion_planning/global_planner/sample_search/rrt.py +151 -0
  32. python_motion_planning/global_planner/sample_search/rrt_connect.py +147 -0
  33. python_motion_planning/global_planner/sample_search/rrt_star.py +77 -0
  34. python_motion_planning/global_planner/sample_search/sample_search.py +135 -0
  35. python_motion_planning/local_planner/__init__.py +19 -0
  36. python_motion_planning/local_planner/apf.py +144 -0
  37. python_motion_planning/local_planner/ddpg.py +630 -0
  38. python_motion_planning/local_planner/dqn.py +687 -0
  39. python_motion_planning/local_planner/dwa.py +212 -0
  40. python_motion_planning/local_planner/local_planner.py +262 -0
  41. python_motion_planning/local_planner/lqr.py +146 -0
  42. python_motion_planning/local_planner/mpc.py +214 -0
  43. python_motion_planning/local_planner/pid.py +158 -0
  44. python_motion_planning/local_planner/rpp.py +147 -0
  45. python_motion_planning/utils/__init__.py +19 -0
  46. python_motion_planning/utils/agent/__init__.py +0 -0
  47. python_motion_planning/utils/agent/agent.py +135 -0
  48. python_motion_planning/utils/environment/__init__.py +0 -0
  49. python_motion_planning/utils/environment/env.py +134 -0
  50. python_motion_planning/utils/environment/node.py +85 -0
  51. python_motion_planning/utils/environment/point2d.py +96 -0
  52. python_motion_planning/utils/environment/pose2d.py +91 -0
  53. python_motion_planning/utils/helper/__init__.py +3 -0
  54. python_motion_planning/utils/helper/math_helper.py +65 -0
  55. python_motion_planning/utils/planner/__init__.py +0 -0
  56. python_motion_planning/utils/planner/control_factory.py +31 -0
  57. python_motion_planning/utils/planner/curve_factory.py +29 -0
  58. python_motion_planning/utils/planner/planner.py +40 -0
  59. python_motion_planning/utils/planner/search_factory.py +51 -0
  60. python_motion_planning/utils/plot/__init__.py +0 -0
  61. python_motion_planning/utils/plot/plot.py +274 -0
  62. python_motion_planning-0.1.dist-info/LICENSE +674 -0
  63. python_motion_planning-0.1.dist-info/METADATA +873 -0
  64. python_motion_planning-0.1.dist-info/RECORD +66 -0
  65. python_motion_planning-0.1.dist-info/WHEEL +5 -0
  66. python_motion_planning-0.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,274 @@
1
+ """
2
+ Plot tools 2D
3
+ @author: huiming zhou
4
+ """
5
+ import numpy as np
6
+ import matplotlib
7
+ import matplotlib.pyplot as plt
8
+ import matplotlib.patches as patches
9
+
10
+ from ..environment.env import Env, Grid, Map, Node
11
+
12
+
13
+ class Plot:
14
+ def __init__(self, start, goal, env: Env):
15
+ self.start = Node(start, start, 0, 0)
16
+ self.goal = Node(goal, goal, 0, 0)
17
+ self.env = env
18
+ self.fig = plt.figure("planning")
19
+ self.ax = self.fig.add_subplot()
20
+
21
+ def animation(self, path: list, name: str, cost: float = None, expand: list = None, history_pose: list = None,
22
+ predict_path: list = None, lookahead_pts: list = None, cost_curve: list = None,
23
+ ellipse: np.ndarray = None) -> None:
24
+ name = name + "\ncost: " + str(cost) if cost else name
25
+ self.plotEnv(name)
26
+ if expand is not None:
27
+ self.plotExpand(expand)
28
+ if history_pose is not None:
29
+ self.plotHistoryPose(history_pose, predict_path, lookahead_pts)
30
+ if path is not None:
31
+ self.plotPath(path)
32
+
33
+ if cost_curve:
34
+ plt.figure("cost curve")
35
+ self.plotCostCurve(cost_curve, name)
36
+
37
+ if ellipse is not None:
38
+ self.plotEllipse(ellipse)
39
+
40
+ plt.show()
41
+
42
+ def plotEnv(self, name: str) -> None:
43
+ '''
44
+ Plot environment with static obstacles.
45
+
46
+ Parameters
47
+ ----------
48
+ name: Algorithm name or some other information
49
+ '''
50
+ plt.plot(self.start.x, self.start.y, marker="s", color="#ff0000")
51
+ plt.plot(self.goal.x, self.goal.y, marker="s", color="#1155cc")
52
+
53
+ if isinstance(self.env, Grid):
54
+ obs_x = [x[0] for x in self.env.obstacles]
55
+ obs_y = [x[1] for x in self.env.obstacles]
56
+ plt.plot(obs_x, obs_y, "sk")
57
+
58
+ if isinstance(self.env, Map):
59
+ ax = self.fig.add_subplot()
60
+ # boundary
61
+ for (ox, oy, w, h) in self.env.boundary:
62
+ ax.add_patch(patches.Rectangle(
63
+ (ox, oy), w, h,
64
+ edgecolor='black',
65
+ facecolor='black',
66
+ fill=True
67
+ )
68
+ )
69
+ # rectangle obstacles
70
+ for (ox, oy, w, h) in self.env.obs_rect:
71
+ ax.add_patch(patches.Rectangle(
72
+ (ox, oy), w, h,
73
+ edgecolor='black',
74
+ facecolor='gray',
75
+ fill=True
76
+ )
77
+ )
78
+ # circle obstacles
79
+ for (ox, oy, r) in self.env.obs_circ:
80
+ ax.add_patch(patches.Circle(
81
+ (ox, oy), r,
82
+ edgecolor='black',
83
+ facecolor='gray',
84
+ fill=True
85
+ )
86
+ )
87
+
88
+ plt.title(name)
89
+ plt.axis("equal")
90
+
91
+ def plotExpand(self, expand: list) -> None:
92
+ '''
93
+ Plot expanded grids using in graph searching.
94
+
95
+ Parameters
96
+ ----------
97
+ expand: Expanded grids during searching
98
+ '''
99
+ if self.start in expand:
100
+ expand.remove(self.start)
101
+ if self.goal in expand:
102
+ expand.remove(self.goal)
103
+
104
+ count = 0
105
+ if isinstance(self.env, Grid):
106
+ for x in expand:
107
+ count += 1
108
+ plt.plot(x.x, x.y, color="#dddddd", marker='s')
109
+ plt.gcf().canvas.mpl_connect('key_release_event',
110
+ lambda event: [exit(0) if event.key == 'escape' else None])
111
+ if count < len(expand) / 3: length = 20
112
+ elif count < len(expand) * 2 / 3: length = 30
113
+ else: length = 40
114
+ if count % length == 0: plt.pause(0.001)
115
+
116
+ if isinstance(self.env, Map):
117
+ for x in expand:
118
+ count += 1
119
+ if x.parent:
120
+ plt.plot([x.parent[0], x.x], [x.parent[1], x.y],
121
+ color="#dddddd", linestyle="-")
122
+ plt.gcf().canvas.mpl_connect('key_release_event',
123
+ lambda event:
124
+ [exit(0) if event.key == 'escape' else None])
125
+ if count % 10 == 0:
126
+ plt.pause(0.001)
127
+
128
+ plt.pause(0.01)
129
+
130
+ def plotPath(self, path: list, path_color: str='#13ae00', path_style: str="-") -> None:
131
+ '''
132
+ Plot path in global planning.
133
+
134
+ Parameters
135
+ ----------
136
+ path: Path found in global planning
137
+ '''
138
+ path_x = [path[i][0] for i in range(len(path))]
139
+ path_y = [path[i][1] for i in range(len(path))]
140
+ plt.plot(path_x, path_y, path_style, linewidth='2', color=path_color)
141
+ plt.plot(self.start.x, self.start.y, marker="s", color="#ff0000")
142
+ plt.plot(self.goal.x, self.goal.y, marker="s", color="#1155cc")
143
+
144
+ def plotAgent(self, pose: tuple, radius: float=1) -> None:
145
+ '''
146
+ Plot agent with specifical pose.
147
+
148
+ Parameters
149
+ ----------
150
+ pose: Pose of agent
151
+ radius: Radius of agent
152
+ '''
153
+ x, y, theta = pose
154
+ ref_vec = np.array([[radius / 2], [0]])
155
+ rot_mat = np.array([[np.cos(theta), -np.sin(theta)],
156
+ [np.sin(theta), np.cos(theta)]])
157
+ end_pt = rot_mat @ ref_vec + np.array([[x], [y]])
158
+
159
+ try:
160
+ self.ax.artists.pop()
161
+ for art in self.ax.get_children():
162
+ if isinstance(art, matplotlib.patches.FancyArrow):
163
+ art.remove()
164
+ except:
165
+ pass
166
+
167
+ self.ax.arrow(x, y, float(end_pt[0]) - x, float(end_pt[1]) - y,
168
+ width=0.1, head_width=0.40, color="r")
169
+ circle = plt.Circle((x, y), radius, color="r", fill=False)
170
+ self.ax.add_artist(circle)
171
+
172
+ def plotHistoryPose(self, history_pose, predict_path=None, lookahead_pts=None) -> None:
173
+ lookahead_handler = None
174
+ for i, pose in enumerate(history_pose):
175
+ if i < len(history_pose) - 1:
176
+ plt.plot([history_pose[i][0], history_pose[i + 1][0]],
177
+ [history_pose[i][1], history_pose[i + 1][1]], c="#13ae00")
178
+ if predict_path is not None:
179
+ plt.plot(predict_path[i][:, 0], predict_path[i][:, 1], c="#ddd")
180
+ i += 1
181
+
182
+ # agent
183
+ self.plotAgent(pose)
184
+
185
+ # lookahead
186
+ if lookahead_handler is not None:
187
+ lookahead_handler.remove()
188
+ if lookahead_pts is not None:
189
+ try:
190
+ lookahead_handler = self.ax.scatter(lookahead_pts[i][0], lookahead_pts[i][1], c="b")
191
+ except:
192
+ lookahead_handler = self.ax.scatter(lookahead_pts[-1][0], lookahead_pts[-1][1], c="b")
193
+
194
+ plt.gcf().canvas.mpl_connect('key_release_event',
195
+ lambda event: [exit(0) if event.key == 'escape' else None])
196
+ if i % 5 == 0: plt.pause(0.03)
197
+
198
+ def plotCostCurve(self, cost_list: list, name: str) -> None:
199
+ '''
200
+ Plot cost curve with epochs using in evolutionary searching.
201
+
202
+ Parameters
203
+ ----------
204
+ cost_list: Cost with epochs
205
+ name: Algorithm name or some other information
206
+ '''
207
+ plt.plot(cost_list, color="b")
208
+ plt.xlabel("epochs")
209
+ plt.ylabel("cost value")
210
+ plt.title(name)
211
+ plt.grid()
212
+
213
+ def plotEllipse(self, ellipse: np.ndarray, color: str = 'darkorange', linestyle: str = '--', linewidth: float = 2):
214
+ plt.plot(ellipse[0, :], ellipse[1, :], linestyle=linestyle, color=color, linewidth=linewidth)
215
+
216
+ def connect(self, name: str, func) -> None:
217
+ self.fig.canvas.mpl_connect(name, func)
218
+
219
+ def clean(self):
220
+ plt.cla()
221
+
222
+ def update(self):
223
+ self.fig.canvas.draw_idle()
224
+
225
+ @staticmethod
226
+ def plotArrow(x, y, theta, length, color):
227
+ angle = np.deg2rad(30)
228
+ d = 0.5 * length
229
+ w = 2
230
+
231
+ x_start, y_start = x, y
232
+ x_end = x + length * np.cos(theta)
233
+ y_end = y + length * np.sin(theta)
234
+
235
+ theta_hat_L = theta + np.pi - angle
236
+ theta_hat_R = theta + np.pi + angle
237
+
238
+ x_hat_start = x_end
239
+ x_hat_end_L = x_hat_start + d * np.cos(theta_hat_L)
240
+ x_hat_end_R = x_hat_start + d * np.cos(theta_hat_R)
241
+
242
+ y_hat_start = y_end
243
+ y_hat_end_L = y_hat_start + d * np.sin(theta_hat_L)
244
+ y_hat_end_R = y_hat_start + d * np.sin(theta_hat_R)
245
+
246
+ plt.plot([x_start, x_end], [y_start, y_end], color=color, linewidth=w)
247
+ plt.plot([x_hat_start, x_hat_end_L], [y_hat_start, y_hat_end_L], color=color, linewidth=w)
248
+ plt.plot([x_hat_start, x_hat_end_R], [y_hat_start, y_hat_end_R], color=color, linewidth=w)
249
+
250
+ @staticmethod
251
+ def plotCar(x, y, theta, width, length, color):
252
+ theta_B = np.pi + theta
253
+
254
+ xB = x + length / 4 * np.cos(theta_B)
255
+ yB = y + length / 4 * np.sin(theta_B)
256
+
257
+ theta_BL = theta_B + np.pi / 2
258
+ theta_BR = theta_B - np.pi / 2
259
+
260
+ x_BL = xB + width / 2 * np.cos(theta_BL) # Bottom-Left vertex
261
+ y_BL = yB + width / 2 * np.sin(theta_BL)
262
+ x_BR = xB + width / 2 * np.cos(theta_BR) # Bottom-Right vertex
263
+ y_BR = yB + width / 2 * np.sin(theta_BR)
264
+
265
+ x_FL = x_BL + length * np.cos(theta) # Front-Left vertex
266
+ y_FL = y_BL + length * np.sin(theta)
267
+ x_FR = x_BR + length * np.cos(theta) # Front-Right vertex
268
+ y_FR = y_BR + length * np.sin(theta)
269
+
270
+ plt.plot([x_BL, x_BR, x_FR, x_FL, x_BL],
271
+ [y_BL, y_BR, y_FR, y_FL, y_BL],
272
+ linewidth=1, color=color)
273
+
274
+ Plot.plotArrow(x, y, theta, length / 2, color)