pathplanning 0.1.0__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 (86) hide show
  1. CurvesGenerator/__init__.py +1 -0
  2. CurvesGenerator/bezier_path.py +145 -0
  3. CurvesGenerator/bspline_curve.py +80 -0
  4. CurvesGenerator/cubic_spline.py +262 -0
  5. CurvesGenerator/draw.py +66 -0
  6. CurvesGenerator/dubins_path.py +351 -0
  7. CurvesGenerator/quartic_polynomial.py +43 -0
  8. CurvesGenerator/quintic_polynomial.py +143 -0
  9. CurvesGenerator/reeds_shepp.py +720 -0
  10. Sampling_based_Planning/__init__.py +1 -0
  11. Sampling_based_Planning/rrt_2D/__init__.py +1 -0
  12. Sampling_based_Planning/rrt_2D/adaptively_informed_trees.py +0 -0
  13. Sampling_based_Planning/rrt_2D/advanced_batch_informed_trees.py +0 -0
  14. Sampling_based_Planning/rrt_2D/batch_informed_trees.py +402 -0
  15. Sampling_based_Planning/rrt_2D/dubins_rrt_star.py +321 -0
  16. Sampling_based_Planning/rrt_2D/dynamic_rrt.py +342 -0
  17. Sampling_based_Planning/rrt_2D/env.py +45 -0
  18. Sampling_based_Planning/rrt_2D/extended_rrt.py +251 -0
  19. Sampling_based_Planning/rrt_2D/fast_marching_trees.py +220 -0
  20. Sampling_based_Planning/rrt_2D/informed_rrt_star.py +305 -0
  21. Sampling_based_Planning/rrt_2D/plotting.py +115 -0
  22. Sampling_based_Planning/rrt_2D/queue.py +62 -0
  23. Sampling_based_Planning/rrt_2D/rrt.py +114 -0
  24. Sampling_based_Planning/rrt_2D/rrt_connect.py +156 -0
  25. Sampling_based_Planning/rrt_2D/rrt_sharp.py +0 -0
  26. Sampling_based_Planning/rrt_2D/rrt_star.py +184 -0
  27. Sampling_based_Planning/rrt_2D/rrt_star_smart.py +311 -0
  28. Sampling_based_Planning/rrt_2D/utils.py +138 -0
  29. Sampling_based_Planning/rrt_3D/ABIT_star3D.py +148 -0
  30. Sampling_based_Planning/rrt_3D/BIT_star3D.py +353 -0
  31. Sampling_based_Planning/rrt_3D/FMT_star3D.py +192 -0
  32. Sampling_based_Planning/rrt_3D/__init__.py +1 -0
  33. Sampling_based_Planning/rrt_3D/dynamic_rrt3D.py +239 -0
  34. Sampling_based_Planning/rrt_3D/env3D.py +148 -0
  35. Sampling_based_Planning/rrt_3D/extend_rrt3D.py +102 -0
  36. Sampling_based_Planning/rrt_3D/informed_rrt_star3D.py +234 -0
  37. Sampling_based_Planning/rrt_3D/plot_util3D.py +167 -0
  38. Sampling_based_Planning/rrt_3D/queue.py +86 -0
  39. Sampling_based_Planning/rrt_3D/rrt3D.py +72 -0
  40. Sampling_based_Planning/rrt_3D/rrt_connect3D.py +187 -0
  41. Sampling_based_Planning/rrt_3D/rrt_star3D.py +107 -0
  42. Sampling_based_Planning/rrt_3D/rrt_star_smart3D.py +0 -0
  43. Sampling_based_Planning/rrt_3D/utils3D.py +416 -0
  44. Search_based_Planning/Search_3D/Anytime_Dstar3D.py +245 -0
  45. Search_based_Planning/Search_3D/Astar3D.py +119 -0
  46. Search_based_Planning/Search_3D/Dstar3D.py +192 -0
  47. Search_based_Planning/Search_3D/DstarLite3D.py +219 -0
  48. Search_based_Planning/Search_3D/LP_Astar3D.py +194 -0
  49. Search_based_Planning/Search_3D/LRT_Astar3D.py +87 -0
  50. Search_based_Planning/Search_3D/RTA_Astar3D.py +78 -0
  51. Search_based_Planning/Search_3D/__init__.py +1 -0
  52. Search_based_Planning/Search_3D/bidirectional_Astar3D.py +115 -0
  53. Search_based_Planning/Search_3D/env3D.py +147 -0
  54. Search_based_Planning/Search_3D/plot_util3D.py +155 -0
  55. Search_based_Planning/Search_3D/queue.py +154 -0
  56. Search_based_Planning/Search_3D/utils3D.py +359 -0
  57. Search_based_Planning/__init__.py +1 -0
  58. Search_based_Planning/plan2d/__init__.py +17 -0
  59. Search_based_Planning/plan2d/anytime_dstar.py +314 -0
  60. Search_based_Planning/plan2d/anytime_repairing_astar.py +220 -0
  61. Search_based_Planning/plan2d/astar.py +225 -0
  62. Search_based_Planning/plan2d/best_first_search.py +67 -0
  63. Search_based_Planning/plan2d/bidirectional_astar.py +229 -0
  64. Search_based_Planning/plan2d/breadth_first_search.py +69 -0
  65. Search_based_Planning/plan2d/depth_first_search.py +69 -0
  66. Search_based_Planning/plan2d/dijkstra.py +68 -0
  67. Search_based_Planning/plan2d/dstar.py +304 -0
  68. Search_based_Planning/plan2d/dstar_lite.py +239 -0
  69. Search_based_Planning/plan2d/learning_realtime_astar.py +230 -0
  70. Search_based_Planning/plan2d/lifelong_planning_astar.py +254 -0
  71. Search_based_Planning/plan2d/plan2d_facade.py +494 -0
  72. Search_based_Planning/plan2d/realtime_adaptive_astar.py +234 -0
  73. Search_based_Planning/plan2d/run.py +55 -0
  74. Search_based_Planning/plan2d/utils/__init__.py +1 -0
  75. Search_based_Planning/plan2d/utils/env.py +48 -0
  76. Search_based_Planning/plan2d/utils/plotting.py +258 -0
  77. Search_based_Planning/plan2d/utils/queue.py +62 -0
  78. pathplanning-0.1.0.dist-info/LICENSE +21 -0
  79. pathplanning-0.1.0.dist-info/METADATA +354 -0
  80. pathplanning-0.1.0.dist-info/RECORD +86 -0
  81. pathplanning-0.1.0.dist-info/WHEEL +5 -0
  82. pathplanning-0.1.0.dist-info/top_level.txt +4 -0
  83. pathplanningv2/__init__.py +29 -0
  84. pathplanningv2/api.py +18 -0
  85. pathplanningv2/registry.py +107 -0
  86. pathplanningv2/search2d.py +15 -0
@@ -0,0 +1,720 @@
1
+ import math
2
+ import numpy as np
3
+ import matplotlib.pyplot as plt
4
+
5
+ import draw
6
+
7
+ # parameters initiation
8
+ STEP_SIZE = 0.2
9
+ MAX_LENGTH = 1000.0
10
+ PI = math.pi
11
+
12
+
13
+ # class for PATH element
14
+ class PATH:
15
+ def __init__(self, lengths, ctypes, L, x, y, yaw, directions):
16
+ self.lengths = lengths # lengths of each part of path (+: forward, -: backward) [float]
17
+ self.ctypes = ctypes # type of each part of the path [string]
18
+ self.L = L # total path length [float]
19
+ self.x = x # final s positions [m]
20
+ self.y = y # final y positions [m]
21
+ self.yaw = yaw # final yaw angles [rad]
22
+ self.directions = directions # forward: 1, backward:-1
23
+
24
+
25
+ def calc_optimal_path(sx, sy, syaw, gx, gy, gyaw, maxc, step_size=STEP_SIZE):
26
+ paths = calc_all_paths(sx, sy, syaw, gx, gy, gyaw, maxc, step_size=step_size)
27
+
28
+ minL = paths[0].L
29
+ mini = 0
30
+
31
+ for i in range(len(paths)):
32
+ if paths[i].L <= minL:
33
+ minL, mini = paths[i].L, i
34
+
35
+ return paths[mini]
36
+
37
+
38
+ def calc_all_paths(sx, sy, syaw, gx, gy, gyaw, maxc, step_size=STEP_SIZE):
39
+ q0 = [sx, sy, syaw]
40
+ q1 = [gx, gy, gyaw]
41
+
42
+ paths = generate_path(q0, q1, maxc)
43
+
44
+ for path in paths:
45
+ x, y, yaw, directions = \
46
+ generate_local_course(path.L, path.lengths,
47
+ path.ctypes, maxc, step_size * maxc)
48
+
49
+ # convert global coordinate
50
+ path.x = [math.cos(-q0[2]) * ix + math.sin(-q0[2]) * iy + q0[0] for (ix, iy) in zip(x, y)]
51
+ path.y = [-math.sin(-q0[2]) * ix + math.cos(-q0[2]) * iy + q0[1] for (ix, iy) in zip(x, y)]
52
+ path.yaw = [pi_2_pi(iyaw + q0[2]) for iyaw in yaw]
53
+ path.directions = directions
54
+ path.lengths = [l / maxc for l in path.lengths]
55
+ path.L = path.L / maxc
56
+
57
+ return paths
58
+
59
+
60
+ def set_path(paths, lengths, ctypes):
61
+ path = PATH([], [], 0.0, [], [], [], [])
62
+ path.ctypes = ctypes
63
+ path.lengths = lengths
64
+
65
+ # check same path exist
66
+ for path_e in paths:
67
+ if path_e.ctypes == path.ctypes:
68
+ if sum([x - y for x, y in zip(path_e.lengths, path.lengths)]) <= 0.01:
69
+ return paths # not insert path
70
+
71
+ path.L = sum([abs(i) for i in lengths])
72
+
73
+ if path.L >= MAX_LENGTH:
74
+ return paths
75
+
76
+ assert path.L >= 0.01
77
+ paths.append(path)
78
+
79
+ return paths
80
+
81
+
82
+ def LSL(x, y, phi):
83
+ u, t = R(x - math.sin(phi), y - 1.0 + math.cos(phi))
84
+
85
+ if t >= 0.0:
86
+ v = M(phi - t)
87
+ if v >= 0.0:
88
+ return True, t, u, v
89
+
90
+ return False, 0.0, 0.0, 0.0
91
+
92
+
93
+ def LSR(x, y, phi):
94
+ u1, t1 = R(x + math.sin(phi), y - 1.0 - math.cos(phi))
95
+ u1 = u1 ** 2
96
+
97
+ if u1 >= 4.0:
98
+ u = math.sqrt(u1 - 4.0)
99
+ theta = math.atan2(2.0, u)
100
+ t = M(t1 + theta)
101
+ v = M(t - phi)
102
+
103
+ if t >= 0.0 and v >= 0.0:
104
+ return True, t, u, v
105
+
106
+ return False, 0.0, 0.0, 0.0
107
+
108
+
109
+ def LRL(x, y, phi):
110
+ u1, t1 = R(x - math.sin(phi), y - 1.0 + math.cos(phi))
111
+
112
+ if u1 <= 4.0:
113
+ u = -2.0 * math.asin(0.25 * u1)
114
+ t = M(t1 + 0.5 * u + PI)
115
+ v = M(phi - t + u)
116
+
117
+ if t >= 0.0 and u <= 0.0:
118
+ return True, t, u, v
119
+
120
+ return False, 0.0, 0.0, 0.0
121
+
122
+
123
+ def SCS(x, y, phi, paths):
124
+ flag, t, u, v = SLS(x, y, phi)
125
+
126
+ if flag:
127
+ paths = set_path(paths, [t, u, v], ["S", "L", "S"])
128
+
129
+ flag, t, u, v = SLS(x, -y, -phi)
130
+ if flag:
131
+ paths = set_path(paths, [t, u, v], ["S", "R", "S"])
132
+
133
+ return paths
134
+
135
+
136
+ def SLS(x, y, phi):
137
+ phi = M(phi)
138
+
139
+ if y > 0.0 and 0.0 < phi < PI * 0.99:
140
+ xd = -y / math.tan(phi) + x
141
+ t = xd - math.tan(phi / 2.0)
142
+ u = phi
143
+ v = math.sqrt((x - xd) ** 2 + y ** 2) - math.tan(phi / 2.0)
144
+ return True, t, u, v
145
+ elif y < 0.0 and 0.0 < phi < PI * 0.99:
146
+ xd = -y / math.tan(phi) + x
147
+ t = xd - math.tan(phi / 2.0)
148
+ u = phi
149
+ v = -math.sqrt((x - xd) ** 2 + y ** 2) - math.tan(phi / 2.0)
150
+ return True, t, u, v
151
+
152
+ return False, 0.0, 0.0, 0.0
153
+
154
+
155
+ def CSC(x, y, phi, paths):
156
+ flag, t, u, v = LSL(x, y, phi)
157
+ if flag:
158
+ paths = set_path(paths, [t, u, v], ["L", "S", "L"])
159
+
160
+ flag, t, u, v = LSL(-x, y, -phi)
161
+ if flag:
162
+ paths = set_path(paths, [-t, -u, -v], ["L", "S", "L"])
163
+
164
+ flag, t, u, v = LSL(x, -y, -phi)
165
+ if flag:
166
+ paths = set_path(paths, [t, u, v], ["R", "S", "R"])
167
+
168
+ flag, t, u, v = LSL(-x, -y, phi)
169
+ if flag:
170
+ paths = set_path(paths, [-t, -u, -v], ["R", "S", "R"])
171
+
172
+ flag, t, u, v = LSR(x, y, phi)
173
+ if flag:
174
+ paths = set_path(paths, [t, u, v], ["L", "S", "R"])
175
+
176
+ flag, t, u, v = LSR(-x, y, -phi)
177
+ if flag:
178
+ paths = set_path(paths, [-t, -u, -v], ["L", "S", "R"])
179
+
180
+ flag, t, u, v = LSR(x, -y, -phi)
181
+ if flag:
182
+ paths = set_path(paths, [t, u, v], ["R", "S", "L"])
183
+
184
+ flag, t, u, v = LSR(-x, -y, phi)
185
+ if flag:
186
+ paths = set_path(paths, [-t, -u, -v], ["R", "S", "L"])
187
+
188
+ return paths
189
+
190
+
191
+ def CCC(x, y, phi, paths):
192
+ flag, t, u, v = LRL(x, y, phi)
193
+ if flag:
194
+ paths = set_path(paths, [t, u, v], ["L", "R", "L"])
195
+
196
+ flag, t, u, v = LRL(-x, y, -phi)
197
+ if flag:
198
+ paths = set_path(paths, [-t, -u, -v], ["L", "R", "L"])
199
+
200
+ flag, t, u, v = LRL(x, -y, -phi)
201
+ if flag:
202
+ paths = set_path(paths, [t, u, v], ["R", "L", "R"])
203
+
204
+ flag, t, u, v = LRL(-x, -y, phi)
205
+ if flag:
206
+ paths = set_path(paths, [-t, -u, -v], ["R", "L", "R"])
207
+
208
+ # backwards
209
+ xb = x * math.cos(phi) + y * math.sin(phi)
210
+ yb = x * math.sin(phi) - y * math.cos(phi)
211
+
212
+ flag, t, u, v = LRL(xb, yb, phi)
213
+ if flag:
214
+ paths = set_path(paths, [v, u, t], ["L", "R", "L"])
215
+
216
+ flag, t, u, v = LRL(-xb, yb, -phi)
217
+ if flag:
218
+ paths = set_path(paths, [-v, -u, -t], ["L", "R", "L"])
219
+
220
+ flag, t, u, v = LRL(xb, -yb, -phi)
221
+ if flag:
222
+ paths = set_path(paths, [v, u, t], ["R", "L", "R"])
223
+
224
+ flag, t, u, v = LRL(-xb, -yb, phi)
225
+ if flag:
226
+ paths = set_path(paths, [-v, -u, -t], ["R", "L", "R"])
227
+
228
+ return paths
229
+
230
+
231
+ def calc_tauOmega(u, v, xi, eta, phi):
232
+ delta = M(u - v)
233
+ A = math.sin(u) - math.sin(delta)
234
+ B = math.cos(u) - math.cos(delta) - 1.0
235
+
236
+ t1 = math.atan2(eta * A - xi * B, xi * A + eta * B)
237
+ t2 = 2.0 * (math.cos(delta) - math.cos(v) - math.cos(u)) + 3.0
238
+
239
+ if t2 < 0:
240
+ tau = M(t1 + PI)
241
+ else:
242
+ tau = M(t1)
243
+
244
+ omega = M(tau - u + v - phi)
245
+
246
+ return tau, omega
247
+
248
+
249
+ def LRLRn(x, y, phi):
250
+ xi = x + math.sin(phi)
251
+ eta = y - 1.0 - math.cos(phi)
252
+ rho = 0.25 * (2.0 + math.sqrt(xi * xi + eta * eta))
253
+
254
+ if rho <= 1.0:
255
+ u = math.acos(rho)
256
+ t, v = calc_tauOmega(u, -u, xi, eta, phi)
257
+ if t >= 0.0 and v <= 0.0:
258
+ return True, t, u, v
259
+
260
+ return False, 0.0, 0.0, 0.0
261
+
262
+
263
+ def LRLRp(x, y, phi):
264
+ xi = x + math.sin(phi)
265
+ eta = y - 1.0 - math.cos(phi)
266
+ rho = (20.0 - xi * xi - eta * eta) / 16.0
267
+
268
+ if 0.0 <= rho <= 1.0:
269
+ u = -math.acos(rho)
270
+ if u >= -0.5 * PI:
271
+ t, v = calc_tauOmega(u, u, xi, eta, phi)
272
+ if t >= 0.0 and v >= 0.0:
273
+ return True, t, u, v
274
+
275
+ return False, 0.0, 0.0, 0.0
276
+
277
+
278
+ def CCCC(x, y, phi, paths):
279
+ flag, t, u, v = LRLRn(x, y, phi)
280
+ if flag:
281
+ paths = set_path(paths, [t, u, -u, v], ["L", "R", "L", "R"])
282
+
283
+ flag, t, u, v = LRLRn(-x, y, -phi)
284
+ if flag:
285
+ paths = set_path(paths, [-t, -u, u, -v], ["L", "R", "L", "R"])
286
+
287
+ flag, t, u, v = LRLRn(x, -y, -phi)
288
+ if flag:
289
+ paths = set_path(paths, [t, u, -u, v], ["R", "L", "R", "L"])
290
+
291
+ flag, t, u, v = LRLRn(-x, -y, phi)
292
+ if flag:
293
+ paths = set_path(paths, [-t, -u, u, -v], ["R", "L", "R", "L"])
294
+
295
+ flag, t, u, v = LRLRp(x, y, phi)
296
+ if flag:
297
+ paths = set_path(paths, [t, u, u, v], ["L", "R", "L", "R"])
298
+
299
+ flag, t, u, v = LRLRp(-x, y, -phi)
300
+ if flag:
301
+ paths = set_path(paths, [-t, -u, -u, -v], ["L", "R", "L", "R"])
302
+
303
+ flag, t, u, v = LRLRp(x, -y, -phi)
304
+ if flag:
305
+ paths = set_path(paths, [t, u, u, v], ["R", "L", "R", "L"])
306
+
307
+ flag, t, u, v = LRLRp(-x, -y, phi)
308
+ if flag:
309
+ paths = set_path(paths, [-t, -u, -u, -v], ["R", "L", "R", "L"])
310
+
311
+ return paths
312
+
313
+
314
+ def LRSR(x, y, phi):
315
+ xi = x + math.sin(phi)
316
+ eta = y - 1.0 - math.cos(phi)
317
+ rho, theta = R(-eta, xi)
318
+
319
+ if rho >= 2.0:
320
+ t = theta
321
+ u = 2.0 - rho
322
+ v = M(t + 0.5 * PI - phi)
323
+ if t >= 0.0 and u <= 0.0 and v <= 0.0:
324
+ return True, t, u, v
325
+
326
+ return False, 0.0, 0.0, 0.0
327
+
328
+
329
+ def LRSL(x, y, phi):
330
+ xi = x - math.sin(phi)
331
+ eta = y - 1.0 + math.cos(phi)
332
+ rho, theta = R(xi, eta)
333
+
334
+ if rho >= 2.0:
335
+ r = math.sqrt(rho * rho - 4.0)
336
+ u = 2.0 - r
337
+ t = M(theta + math.atan2(r, -2.0))
338
+ v = M(phi - 0.5 * PI - t)
339
+ if t >= 0.0 and u <= 0.0 and v <= 0.0:
340
+ return True, t, u, v
341
+
342
+ return False, 0.0, 0.0, 0.0
343
+
344
+
345
+ def CCSC(x, y, phi, paths):
346
+ flag, t, u, v = LRSL(x, y, phi)
347
+ if flag:
348
+ paths = set_path(paths, [t, -0.5 * PI, u, v], ["L", "R", "S", "L"])
349
+
350
+ flag, t, u, v = LRSL(-x, y, -phi)
351
+ if flag:
352
+ paths = set_path(paths, [-t, 0.5 * PI, -u, -v], ["L", "R", "S", "L"])
353
+
354
+ flag, t, u, v = LRSL(x, -y, -phi)
355
+ if flag:
356
+ paths = set_path(paths, [t, -0.5 * PI, u, v], ["R", "L", "S", "R"])
357
+
358
+ flag, t, u, v = LRSL(-x, -y, phi)
359
+ if flag:
360
+ paths = set_path(paths, [-t, 0.5 * PI, -u, -v], ["R", "L", "S", "R"])
361
+
362
+ flag, t, u, v = LRSR(x, y, phi)
363
+ if flag:
364
+ paths = set_path(paths, [t, -0.5 * PI, u, v], ["L", "R", "S", "R"])
365
+
366
+ flag, t, u, v = LRSR(-x, y, -phi)
367
+ if flag:
368
+ paths = set_path(paths, [-t, 0.5 * PI, -u, -v], ["L", "R", "S", "R"])
369
+
370
+ flag, t, u, v = LRSR(x, -y, -phi)
371
+ if flag:
372
+ paths = set_path(paths, [t, -0.5 * PI, u, v], ["R", "L", "S", "L"])
373
+
374
+ flag, t, u, v = LRSR(-x, -y, phi)
375
+ if flag:
376
+ paths = set_path(paths, [-t, 0.5 * PI, -u, -v], ["R", "L", "S", "L"])
377
+
378
+ # backwards
379
+ xb = x * math.cos(phi) + y * math.sin(phi)
380
+ yb = x * math.sin(phi) - y * math.cos(phi)
381
+
382
+ flag, t, u, v = LRSL(xb, yb, phi)
383
+ if flag:
384
+ paths = set_path(paths, [v, u, -0.5 * PI, t], ["L", "S", "R", "L"])
385
+
386
+ flag, t, u, v = LRSL(-xb, yb, -phi)
387
+ if flag:
388
+ paths = set_path(paths, [-v, -u, 0.5 * PI, -t], ["L", "S", "R", "L"])
389
+
390
+ flag, t, u, v = LRSL(xb, -yb, -phi)
391
+ if flag:
392
+ paths = set_path(paths, [v, u, -0.5 * PI, t], ["R", "S", "L", "R"])
393
+
394
+ flag, t, u, v = LRSL(-xb, -yb, phi)
395
+ if flag:
396
+ paths = set_path(paths, [-v, -u, 0.5 * PI, -t], ["R", "S", "L", "R"])
397
+
398
+ flag, t, u, v = LRSR(xb, yb, phi)
399
+ if flag:
400
+ paths = set_path(paths, [v, u, -0.5 * PI, t], ["R", "S", "R", "L"])
401
+
402
+ flag, t, u, v = LRSR(-xb, yb, -phi)
403
+ if flag:
404
+ paths = set_path(paths, [-v, -u, 0.5 * PI, -t], ["R", "S", "R", "L"])
405
+
406
+ flag, t, u, v = LRSR(xb, -yb, -phi)
407
+ if flag:
408
+ paths = set_path(paths, [v, u, -0.5 * PI, t], ["L", "S", "L", "R"])
409
+
410
+ flag, t, u, v = LRSR(-xb, -yb, phi)
411
+ if flag:
412
+ paths = set_path(paths, [-v, -u, 0.5 * PI, -t], ["L", "S", "L", "R"])
413
+
414
+ return paths
415
+
416
+
417
+ def LRSLR(x, y, phi):
418
+ # formula 8.11 *** TYPO IN PAPER ***
419
+ xi = x + math.sin(phi)
420
+ eta = y - 1.0 - math.cos(phi)
421
+ rho, theta = R(xi, eta)
422
+
423
+ if rho >= 2.0:
424
+ u = 4.0 - math.sqrt(rho * rho - 4.0)
425
+ if u <= 0.0:
426
+ t = M(math.atan2((4.0 - u) * xi - 2.0 * eta, -2.0 * xi + (u - 4.0) * eta))
427
+ v = M(t - phi)
428
+
429
+ if t >= 0.0 and v >= 0.0:
430
+ return True, t, u, v
431
+
432
+ return False, 0.0, 0.0, 0.0
433
+
434
+
435
+ def CCSCC(x, y, phi, paths):
436
+ flag, t, u, v = LRSLR(x, y, phi)
437
+ if flag:
438
+ paths = set_path(paths, [t, -0.5 * PI, u, -0.5 * PI, v], ["L", "R", "S", "L", "R"])
439
+
440
+ flag, t, u, v = LRSLR(-x, y, -phi)
441
+ if flag:
442
+ paths = set_path(paths, [-t, 0.5 * PI, -u, 0.5 * PI, -v], ["L", "R", "S", "L", "R"])
443
+
444
+ flag, t, u, v = LRSLR(x, -y, -phi)
445
+ if flag:
446
+ paths = set_path(paths, [t, -0.5 * PI, u, -0.5 * PI, v], ["R", "L", "S", "R", "L"])
447
+
448
+ flag, t, u, v = LRSLR(-x, -y, phi)
449
+ if flag:
450
+ paths = set_path(paths, [-t, 0.5 * PI, -u, 0.5 * PI, -v], ["R", "L", "S", "R", "L"])
451
+
452
+ return paths
453
+
454
+
455
+ def generate_local_course(L, lengths, mode, maxc, step_size):
456
+ point_num = int(L / step_size) + len(lengths) + 3
457
+
458
+ px = [0.0 for _ in range(point_num)]
459
+ py = [0.0 for _ in range(point_num)]
460
+ pyaw = [0.0 for _ in range(point_num)]
461
+ directions = [0 for _ in range(point_num)]
462
+ ind = 1
463
+
464
+ if lengths[0] > 0.0:
465
+ directions[0] = 1
466
+ else:
467
+ directions[0] = -1
468
+
469
+ if lengths[0] > 0.0:
470
+ d = step_size
471
+ else:
472
+ d = -step_size
473
+
474
+ pd = d
475
+ ll = 0.0
476
+
477
+ for m, l, i in zip(mode, lengths, range(len(mode))):
478
+ if l > 0.0:
479
+ d = step_size
480
+ else:
481
+ d = -step_size
482
+
483
+ ox, oy, oyaw = px[ind], py[ind], pyaw[ind]
484
+
485
+ ind -= 1
486
+ if i >= 1 and (lengths[i - 1] * lengths[i]) > 0:
487
+ pd = -d - ll
488
+ else:
489
+ pd = d - ll
490
+
491
+ while abs(pd) <= abs(l):
492
+ ind += 1
493
+ px, py, pyaw, directions = \
494
+ interpolate(ind, pd, m, maxc, ox, oy, oyaw, px, py, pyaw, directions)
495
+ pd += d
496
+
497
+ ll = l - pd - d # calc remain length
498
+
499
+ ind += 1
500
+ px, py, pyaw, directions = \
501
+ interpolate(ind, l, m, maxc, ox, oy, oyaw, px, py, pyaw, directions)
502
+
503
+ # remove unused data
504
+ while px[-1] == 0.0:
505
+ px.pop()
506
+ py.pop()
507
+ pyaw.pop()
508
+ directions.pop()
509
+
510
+ return px, py, pyaw, directions
511
+
512
+
513
+ def interpolate(ind, l, m, maxc, ox, oy, oyaw, px, py, pyaw, directions):
514
+ if m == "S":
515
+ px[ind] = ox + l / maxc * math.cos(oyaw)
516
+ py[ind] = oy + l / maxc * math.sin(oyaw)
517
+ pyaw[ind] = oyaw
518
+ else:
519
+ ldx = math.sin(l) / maxc
520
+ if m == "L":
521
+ ldy = (1.0 - math.cos(l)) / maxc
522
+ elif m == "R":
523
+ ldy = (1.0 - math.cos(l)) / (-maxc)
524
+
525
+ gdx = math.cos(-oyaw) * ldx + math.sin(-oyaw) * ldy
526
+ gdy = -math.sin(-oyaw) * ldx + math.cos(-oyaw) * ldy
527
+ px[ind] = ox + gdx
528
+ py[ind] = oy + gdy
529
+
530
+ if m == "L":
531
+ pyaw[ind] = oyaw + l
532
+ elif m == "R":
533
+ pyaw[ind] = oyaw - l
534
+
535
+ if l > 0.0:
536
+ directions[ind] = 1
537
+ else:
538
+ directions[ind] = -1
539
+
540
+ return px, py, pyaw, directions
541
+
542
+
543
+ def generate_path(q0, q1, maxc):
544
+ dx = q1[0] - q0[0]
545
+ dy = q1[1] - q0[1]
546
+ dth = q1[2] - q0[2]
547
+ c = math.cos(q0[2])
548
+ s = math.sin(q0[2])
549
+ x = (c * dx + s * dy) * maxc
550
+ y = (-s * dx + c * dy) * maxc
551
+
552
+ paths = []
553
+ paths = SCS(x, y, dth, paths)
554
+ paths = CSC(x, y, dth, paths)
555
+ paths = CCC(x, y, dth, paths)
556
+ paths = CCCC(x, y, dth, paths)
557
+ paths = CCSC(x, y, dth, paths)
558
+ paths = CCSCC(x, y, dth, paths)
559
+
560
+ return paths
561
+
562
+
563
+ # utils
564
+ def pi_2_pi(theta):
565
+ while theta > PI:
566
+ theta -= 2.0 * PI
567
+
568
+ while theta < -PI:
569
+ theta += 2.0 * PI
570
+
571
+ return theta
572
+
573
+
574
+ def R(x, y):
575
+ """
576
+ Return the polar coordinates (r, theta) of the point (s, y)
577
+ """
578
+ r = math.hypot(x, y)
579
+ theta = math.atan2(y, x)
580
+
581
+ return r, theta
582
+
583
+
584
+ def M(theta):
585
+ """
586
+ Regulate theta to -pi <= theta < pi
587
+ """
588
+ phi = theta % (2.0 * PI)
589
+
590
+ if phi < -PI:
591
+ phi += 2.0 * PI
592
+ if phi > PI:
593
+ phi -= 2.0 * PI
594
+
595
+ return phi
596
+
597
+
598
+ def get_label(path):
599
+ label = ""
600
+
601
+ for m, l in zip(path.ctypes, path.lengths):
602
+ label = label + m
603
+ if l > 0.0:
604
+ label = label + "+"
605
+ else:
606
+ label = label + "-"
607
+
608
+ return label
609
+
610
+
611
+ def calc_curvature(x, y, yaw, directions):
612
+ c, ds = [], []
613
+
614
+ for i in range(1, len(x) - 1):
615
+ dxn = x[i] - x[i - 1]
616
+ dxp = x[i + 1] - x[i]
617
+ dyn = y[i] - y[i - 1]
618
+ dyp = y[i + 1] - y[i]
619
+ dn = math.hypot(dxn, dyn)
620
+ dp = math.hypot(dxp, dyp)
621
+ dx = 1.0 / (dn + dp) * (dp / dn * dxn + dn / dp * dxp)
622
+ ddx = 2.0 / (dn + dp) * (dxp / dp - dxn / dn)
623
+ dy = 1.0 / (dn + dp) * (dp / dn * dyn + dn / dp * dyp)
624
+ ddy = 2.0 / (dn + dp) * (dyp / dp - dyn / dn)
625
+ curvature = (ddy * dx - ddx * dy) / (dx ** 2 + dy ** 2)
626
+ d = (dn + dp) / 2.0
627
+
628
+ if np.isnan(curvature):
629
+ curvature = 0.0
630
+
631
+ if directions[i] <= 0.0:
632
+ curvature = -curvature
633
+
634
+ if len(c) == 0:
635
+ ds.append(d)
636
+ c.append(curvature)
637
+
638
+ ds.append(d)
639
+ c.append(curvature)
640
+
641
+ ds.append(ds[-1])
642
+ c.append(c[-1])
643
+
644
+ return c, ds
645
+
646
+
647
+ def check_path(sx, sy, syaw, gx, gy, gyaw, maxc):
648
+ paths = calc_all_paths(sx, sy, syaw, gx, gy, gyaw, maxc)
649
+
650
+ assert len(paths) >= 1
651
+
652
+ for path in paths:
653
+ assert abs(path.x[0] - sx) <= 0.01
654
+ assert abs(path.y[0] - sy) <= 0.01
655
+ assert abs(path.yaw[0] - syaw) <= 0.01
656
+ assert abs(path.x[-1] - gx) <= 0.01
657
+ assert abs(path.y[-1] - gy) <= 0.01
658
+ assert abs(path.yaw[-1] - gyaw) <= 0.01
659
+
660
+ # course distance check
661
+ d = [math.hypot(dx, dy)
662
+ for dx, dy in zip(np.diff(path.x[0:len(path.x) - 1]),
663
+ np.diff(path.y[0:len(path.y) - 1]))]
664
+
665
+ for i in range(len(d)):
666
+ assert abs(d[i] - STEP_SIZE) <= 0.001
667
+
668
+
669
+ def main():
670
+ # choose states pairs: (s, y, yaw)
671
+ # simulation-1
672
+ # states = [(0, 0, 0), (10, 10, -90), (20, 5, 60), (30, 10, 120),
673
+ # (35, -5, 30), (25, -10, -120), (15, -15, 100), (0, -10, -90)]
674
+
675
+ # simulation-2
676
+ states = [(-3, 3, 120), (10, -7, 30), (10, 13, 30), (20, 5, -25),
677
+ (35, 10, 180), (32, -10, 180), (5, -12, 90)]
678
+
679
+ max_c = 0.1 # max curvature
680
+ path_x, path_y, yaw = [], [], []
681
+
682
+ for i in range(len(states) - 1):
683
+ s_x = states[i][0]
684
+ s_y = states[i][1]
685
+ s_yaw = np.deg2rad(states[i][2])
686
+ g_x = states[i + 1][0]
687
+ g_y = states[i + 1][1]
688
+ g_yaw = np.deg2rad(states[i + 1][2])
689
+
690
+ path_i = calc_optimal_path(s_x, s_y, s_yaw,
691
+ g_x, g_y, g_yaw, max_c)
692
+
693
+ path_x += path_i.x
694
+ path_y += path_i.y
695
+ yaw += path_i.yaw
696
+
697
+ # animation
698
+ plt.ion()
699
+ plt.figure(1)
700
+
701
+ for i in range(len(path_x)):
702
+ plt.clf()
703
+ plt.plot(path_x, path_y, linewidth=1, color='gray')
704
+
705
+ for x, y, theta in states:
706
+ draw.Arrow(x, y, np.deg2rad(theta), 2, 'blueviolet')
707
+
708
+ draw.Car(path_x[i], path_y[i], yaw[i], 1.5, 3)
709
+
710
+ plt.axis("equal")
711
+ plt.title("Simulation of Reeds-Shepp Curves")
712
+ plt.axis([-10, 42, -20, 20])
713
+ plt.draw()
714
+ plt.pause(0.001)
715
+
716
+ plt.pause(1)
717
+
718
+
719
+ if __name__ == '__main__':
720
+ main()
@@ -0,0 +1 @@
1
+ """Sampling-based planning algorithms package."""
@@ -0,0 +1 @@
1
+ """2D sampling-based planners."""