pathplanning 0.1.0__tar.gz

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 (95) hide show
  1. pathplanning-0.1.0/CurvesGenerator/__init__.py +1 -0
  2. pathplanning-0.1.0/CurvesGenerator/bezier_path.py +145 -0
  3. pathplanning-0.1.0/CurvesGenerator/bspline_curve.py +80 -0
  4. pathplanning-0.1.0/CurvesGenerator/cubic_spline.py +262 -0
  5. pathplanning-0.1.0/CurvesGenerator/draw.py +66 -0
  6. pathplanning-0.1.0/CurvesGenerator/dubins_path.py +351 -0
  7. pathplanning-0.1.0/CurvesGenerator/quartic_polynomial.py +43 -0
  8. pathplanning-0.1.0/CurvesGenerator/quintic_polynomial.py +143 -0
  9. pathplanning-0.1.0/CurvesGenerator/reeds_shepp.py +720 -0
  10. pathplanning-0.1.0/LICENSE +21 -0
  11. pathplanning-0.1.0/PKG-INFO +354 -0
  12. pathplanning-0.1.0/README.md +298 -0
  13. pathplanning-0.1.0/Sampling_based_Planning/__init__.py +1 -0
  14. pathplanning-0.1.0/Sampling_based_Planning/rrt_2D/__init__.py +1 -0
  15. pathplanning-0.1.0/Sampling_based_Planning/rrt_2D/adaptively_informed_trees.py +0 -0
  16. pathplanning-0.1.0/Sampling_based_Planning/rrt_2D/advanced_batch_informed_trees.py +0 -0
  17. pathplanning-0.1.0/Sampling_based_Planning/rrt_2D/batch_informed_trees.py +402 -0
  18. pathplanning-0.1.0/Sampling_based_Planning/rrt_2D/dubins_rrt_star.py +321 -0
  19. pathplanning-0.1.0/Sampling_based_Planning/rrt_2D/dynamic_rrt.py +342 -0
  20. pathplanning-0.1.0/Sampling_based_Planning/rrt_2D/env.py +45 -0
  21. pathplanning-0.1.0/Sampling_based_Planning/rrt_2D/extended_rrt.py +251 -0
  22. pathplanning-0.1.0/Sampling_based_Planning/rrt_2D/fast_marching_trees.py +220 -0
  23. pathplanning-0.1.0/Sampling_based_Planning/rrt_2D/informed_rrt_star.py +305 -0
  24. pathplanning-0.1.0/Sampling_based_Planning/rrt_2D/plotting.py +115 -0
  25. pathplanning-0.1.0/Sampling_based_Planning/rrt_2D/queue.py +62 -0
  26. pathplanning-0.1.0/Sampling_based_Planning/rrt_2D/rrt.py +114 -0
  27. pathplanning-0.1.0/Sampling_based_Planning/rrt_2D/rrt_connect.py +156 -0
  28. pathplanning-0.1.0/Sampling_based_Planning/rrt_2D/rrt_sharp.py +0 -0
  29. pathplanning-0.1.0/Sampling_based_Planning/rrt_2D/rrt_star.py +184 -0
  30. pathplanning-0.1.0/Sampling_based_Planning/rrt_2D/rrt_star_smart.py +311 -0
  31. pathplanning-0.1.0/Sampling_based_Planning/rrt_2D/utils.py +138 -0
  32. pathplanning-0.1.0/Sampling_based_Planning/rrt_3D/ABIT_star3D.py +148 -0
  33. pathplanning-0.1.0/Sampling_based_Planning/rrt_3D/BIT_star3D.py +353 -0
  34. pathplanning-0.1.0/Sampling_based_Planning/rrt_3D/FMT_star3D.py +192 -0
  35. pathplanning-0.1.0/Sampling_based_Planning/rrt_3D/__init__.py +1 -0
  36. pathplanning-0.1.0/Sampling_based_Planning/rrt_3D/dynamic_rrt3D.py +239 -0
  37. pathplanning-0.1.0/Sampling_based_Planning/rrt_3D/env3D.py +148 -0
  38. pathplanning-0.1.0/Sampling_based_Planning/rrt_3D/extend_rrt3D.py +102 -0
  39. pathplanning-0.1.0/Sampling_based_Planning/rrt_3D/informed_rrt_star3D.py +234 -0
  40. pathplanning-0.1.0/Sampling_based_Planning/rrt_3D/plot_util3D.py +167 -0
  41. pathplanning-0.1.0/Sampling_based_Planning/rrt_3D/queue.py +86 -0
  42. pathplanning-0.1.0/Sampling_based_Planning/rrt_3D/rrt3D.py +72 -0
  43. pathplanning-0.1.0/Sampling_based_Planning/rrt_3D/rrt_connect3D.py +187 -0
  44. pathplanning-0.1.0/Sampling_based_Planning/rrt_3D/rrt_star3D.py +107 -0
  45. pathplanning-0.1.0/Sampling_based_Planning/rrt_3D/rrt_star_smart3D.py +0 -0
  46. pathplanning-0.1.0/Sampling_based_Planning/rrt_3D/utils3D.py +416 -0
  47. pathplanning-0.1.0/Search_based_Planning/Search_3D/Anytime_Dstar3D.py +245 -0
  48. pathplanning-0.1.0/Search_based_Planning/Search_3D/Astar3D.py +119 -0
  49. pathplanning-0.1.0/Search_based_Planning/Search_3D/Dstar3D.py +192 -0
  50. pathplanning-0.1.0/Search_based_Planning/Search_3D/DstarLite3D.py +219 -0
  51. pathplanning-0.1.0/Search_based_Planning/Search_3D/LP_Astar3D.py +194 -0
  52. pathplanning-0.1.0/Search_based_Planning/Search_3D/LRT_Astar3D.py +87 -0
  53. pathplanning-0.1.0/Search_based_Planning/Search_3D/RTA_Astar3D.py +78 -0
  54. pathplanning-0.1.0/Search_based_Planning/Search_3D/__init__.py +1 -0
  55. pathplanning-0.1.0/Search_based_Planning/Search_3D/bidirectional_Astar3D.py +115 -0
  56. pathplanning-0.1.0/Search_based_Planning/Search_3D/env3D.py +147 -0
  57. pathplanning-0.1.0/Search_based_Planning/Search_3D/plot_util3D.py +155 -0
  58. pathplanning-0.1.0/Search_based_Planning/Search_3D/queue.py +154 -0
  59. pathplanning-0.1.0/Search_based_Planning/Search_3D/utils3D.py +359 -0
  60. pathplanning-0.1.0/Search_based_Planning/__init__.py +1 -0
  61. pathplanning-0.1.0/Search_based_Planning/plan2d/__init__.py +17 -0
  62. pathplanning-0.1.0/Search_based_Planning/plan2d/anytime_dstar.py +314 -0
  63. pathplanning-0.1.0/Search_based_Planning/plan2d/anytime_repairing_astar.py +220 -0
  64. pathplanning-0.1.0/Search_based_Planning/plan2d/astar.py +225 -0
  65. pathplanning-0.1.0/Search_based_Planning/plan2d/best_first_search.py +67 -0
  66. pathplanning-0.1.0/Search_based_Planning/plan2d/bidirectional_astar.py +229 -0
  67. pathplanning-0.1.0/Search_based_Planning/plan2d/breadth_first_search.py +69 -0
  68. pathplanning-0.1.0/Search_based_Planning/plan2d/depth_first_search.py +69 -0
  69. pathplanning-0.1.0/Search_based_Planning/plan2d/dijkstra.py +68 -0
  70. pathplanning-0.1.0/Search_based_Planning/plan2d/dstar.py +304 -0
  71. pathplanning-0.1.0/Search_based_Planning/plan2d/dstar_lite.py +239 -0
  72. pathplanning-0.1.0/Search_based_Planning/plan2d/learning_realtime_astar.py +230 -0
  73. pathplanning-0.1.0/Search_based_Planning/plan2d/lifelong_planning_astar.py +254 -0
  74. pathplanning-0.1.0/Search_based_Planning/plan2d/plan2d_facade.py +494 -0
  75. pathplanning-0.1.0/Search_based_Planning/plan2d/realtime_adaptive_astar.py +234 -0
  76. pathplanning-0.1.0/Search_based_Planning/plan2d/run.py +55 -0
  77. pathplanning-0.1.0/Search_based_Planning/plan2d/utils/__init__.py +1 -0
  78. pathplanning-0.1.0/Search_based_Planning/plan2d/utils/env.py +48 -0
  79. pathplanning-0.1.0/Search_based_Planning/plan2d/utils/plotting.py +258 -0
  80. pathplanning-0.1.0/Search_based_Planning/plan2d/utils/queue.py +62 -0
  81. pathplanning-0.1.0/pathplanning.egg-info/PKG-INFO +354 -0
  82. pathplanning-0.1.0/pathplanning.egg-info/SOURCES.txt +93 -0
  83. pathplanning-0.1.0/pathplanning.egg-info/dependency_links.txt +1 -0
  84. pathplanning-0.1.0/pathplanning.egg-info/requires.txt +11 -0
  85. pathplanning-0.1.0/pathplanning.egg-info/top_level.txt +4 -0
  86. pathplanning-0.1.0/pathplanningv2/__init__.py +29 -0
  87. pathplanning-0.1.0/pathplanningv2/api.py +18 -0
  88. pathplanning-0.1.0/pathplanningv2/registry.py +107 -0
  89. pathplanning-0.1.0/pathplanningv2/search2d.py +15 -0
  90. pathplanning-0.1.0/pyproject.toml +77 -0
  91. pathplanning-0.1.0/setup.cfg +4 -0
  92. pathplanning-0.1.0/tests/test_package_api.py +22 -0
  93. pathplanning-0.1.0/tests/test_runtime_representative_smoke.py +22 -0
  94. pathplanning-0.1.0/tests/test_search2d_smoke.py +32 -0
  95. pathplanning-0.1.0/tests/test_supported_modules_import.py +13 -0
@@ -0,0 +1 @@
1
+ """Curve generation utilities."""
@@ -0,0 +1,145 @@
1
+ """
2
+ bezier path
3
+
4
+ author: Atsushi Sakai(@Atsushi_twi)
5
+ modified: damminhtien
6
+ """
7
+
8
+ import numpy as np
9
+ import matplotlib.pyplot as plt
10
+ from scipy.special import comb
11
+ import draw
12
+
13
+
14
+ def calc_4points_bezier_path(sx, sy, syaw, gx, gy, gyaw, offset):
15
+
16
+ dist = np.hypot(sx - gx, sy - gy) / offset
17
+ control_points = np.array(
18
+ [[sx, sy],
19
+ [sx + dist * np.cos(syaw), sy + dist * np.sin(syaw)],
20
+ [gx - dist * np.cos(gyaw), gy - dist * np.sin(gyaw)],
21
+ [gx, gy]])
22
+
23
+ path = calc_bezier_path(control_points, n_points=100)
24
+
25
+ return path, control_points
26
+
27
+
28
+ def calc_bezier_path(control_points, n_points=100):
29
+ traj = []
30
+
31
+ for t in np.linspace(0, 1, n_points):
32
+ traj.append(bezier(t, control_points))
33
+
34
+ return np.array(traj)
35
+
36
+
37
+ def Comb(n, i, t):
38
+ return comb(n, i) * t ** i * (1 - t) ** (n - i)
39
+
40
+
41
+ def bezier(t, control_points):
42
+ n = len(control_points) - 1
43
+ return np.sum([Comb(n, i, t) * control_points[i] for i in range(n + 1)], axis=0)
44
+
45
+
46
+ def bezier_derivatives_control_points(control_points, n_derivatives):
47
+ w = {0: control_points}
48
+
49
+ for i in range(n_derivatives):
50
+ n = len(w[i])
51
+ w[i + 1] = np.array([(n - 1) * (w[i][j + 1] - w[i][j])
52
+ for j in range(n - 1)])
53
+
54
+ return w
55
+
56
+
57
+ def curvature(dx, dy, ddx, ddy):
58
+ return (dx * ddy - dy * ddx) / (dx ** 2 + dy ** 2) ** (3 / 2)
59
+
60
+
61
+ def simulation():
62
+ sx = [-3, 0, 4, 6]
63
+ sy = [2, 0, 1.5, 6]
64
+
65
+ ratio = np.linspace(0, 1, 100)
66
+ pathx, pathy = [], []
67
+
68
+ for t in ratio:
69
+ x, y = [], []
70
+ for i in range(len(sx) - 1):
71
+ x.append(sx[i + 1] * t + sx[i] * (1 - t))
72
+ y.append(sy[i + 1] * t + sy[i] * (1 - t))
73
+
74
+ xx, yy = [], []
75
+ for i in range(len(x) - 1):
76
+ xx.append(x[i + 1] * t + x[i] * (1 - t))
77
+ yy.append(y[i + 1] * t + y[i] * (1 - t))
78
+
79
+ px = xx[1] * t + xx[0] * (1 - t)
80
+ py = yy[1] * t + yy[0] * (1 - t)
81
+ pathx.append(px)
82
+ pathy.append(py)
83
+
84
+ plt.cla()
85
+ plt.plot(sx, sy, linestyle='-', marker='o', color='dimgray', label="Control Points")
86
+ plt.plot(x, y, color='dodgerblue')
87
+ plt.plot(xx, yy, color='cyan')
88
+ plt.plot(pathx, pathy, color='darkorange', linewidth=2, label="Bezier Path")
89
+ plt.plot(px, py, marker='o')
90
+ plt.axis("equal")
91
+ plt.legend()
92
+ plt.title("Cubic Bezier Curve demo")
93
+ plt.grid(True)
94
+ plt.pause(0.001)
95
+
96
+ plt.show()
97
+
98
+
99
+ def main():
100
+ sx, sy, syaw = 10.0, 1.0, np.deg2rad(180.0)
101
+ gx, gy, gyaw = 0.0, -3.0, np.deg2rad(-45.0)
102
+ offset = 3.0
103
+
104
+ path, control_points = calc_4points_bezier_path(sx, sy, syaw, gx, gy, gyaw, offset)
105
+
106
+ t = 0.8 # Number in [0, 1]
107
+ x_target, y_target = bezier(t, control_points)
108
+ derivatives_cp = bezier_derivatives_control_points(control_points, 2)
109
+ point = bezier(t, control_points)
110
+ dt = bezier(t, derivatives_cp[1])
111
+ ddt = bezier(t, derivatives_cp[2])
112
+ # Radius of curv
113
+ radius = 1 / curvature(dt[0], dt[1], ddt[0], ddt[1])
114
+ # Normalize derivative
115
+ dt /= np.linalg.norm(dt, 2)
116
+ tangent = np.array([point, point + dt])
117
+ normal = np.array([point, point + [- dt[1], dt[0]]])
118
+ curvature_center = point + np.array([- dt[1], dt[0]]) * radius
119
+ circle = plt.Circle(tuple(curvature_center), radius,
120
+ color=(0, 0.8, 0.8), fill=False, linewidth=1)
121
+
122
+ assert path.T[0][0] == sx, "path is invalid"
123
+ assert path.T[1][0] == sy, "path is invalid"
124
+ assert path.T[0][-1] == gx, "path is invalid"
125
+ assert path.T[1][-1] == gy, "path is invalid"
126
+
127
+ fig, ax = plt.subplots()
128
+ ax.plot(path.T[0], path.T[1], label="Bezier Path")
129
+ ax.plot(control_points.T[0], control_points.T[1],
130
+ '--o', label="Control Points")
131
+ ax.plot(x_target, y_target)
132
+ ax.plot(tangent[:, 0], tangent[:, 1], label="Tangent")
133
+ ax.plot(normal[:, 0], normal[:, 1], label="Normal")
134
+ ax.add_artist(circle)
135
+ draw.Arrow(sx, sy, syaw, 1, "darkorange")
136
+ draw.Arrow(gx, gy, gyaw, 1, "darkorange")
137
+ plt.grid(True)
138
+ plt.title("Bezier Path: from Atsushi's work")
139
+ ax.axis("equal")
140
+ plt.show()
141
+
142
+
143
+ if __name__ == '__main__':
144
+ main()
145
+ # simulation()
@@ -0,0 +1,80 @@
1
+ """
2
+
3
+ Path Planner with B-Spline
4
+
5
+ author: Atsushi Sakai (@Atsushi_twi)
6
+
7
+ """
8
+
9
+ import numpy as np
10
+ import matplotlib.pyplot as plt
11
+ import scipy.interpolate as scipy_interpolate
12
+ import cubic_spline as cs
13
+
14
+
15
+ def approximate_b_spline_path(x, y, n_path_points, degree=3):
16
+ t = range(len(x))
17
+ x_tup = scipy_interpolate.splrep(t, x, k=degree)
18
+ y_tup = scipy_interpolate.splrep(t, y, k=degree)
19
+
20
+ x_list = list(x_tup)
21
+ x_list[1] = x + [0.0, 0.0, 0.0, 0.0]
22
+
23
+ y_list = list(y_tup)
24
+ y_list[1] = y + [0.0, 0.0, 0.0, 0.0]
25
+
26
+ ipl_t = np.linspace(0.0, len(x) - 1, n_path_points)
27
+ rx = scipy_interpolate.splev(ipl_t, x_list)
28
+ ry = scipy_interpolate.splev(ipl_t, y_list)
29
+
30
+ return rx, ry
31
+
32
+
33
+ def interpolate_b_spline_path(x, y, n_path_points, degree=3):
34
+ ipl_t = np.linspace(0.0, len(x) - 1, len(x))
35
+ spl_i_x = scipy_interpolate.make_interp_spline(ipl_t, x, k=degree)
36
+ spl_i_y = scipy_interpolate.make_interp_spline(ipl_t, y, k=degree)
37
+
38
+ travel = np.linspace(0.0, len(x) - 1, n_path_points)
39
+ return spl_i_x(travel), spl_i_y(travel)
40
+
41
+
42
+ def main():
43
+ print(__file__ + " start!!")
44
+ # way points
45
+ # way_point_x = [-1.0, 3.0, 4.0, 2.0, 1.0]
46
+ # way_point_y = [0.0, -3.0, 1.0, 1.0, 3.0]
47
+ way_point_x = [-2, 2.0, 3.5, 5.5, 6.0, 8.0]
48
+ way_point_y = [0, 2.7, -0.5, 0.5, 3.0, 4.0]
49
+
50
+ sp = cs.Spline2D(way_point_x, way_point_y)
51
+ s = np.arange(0, sp.s[-1], 0.1)
52
+
53
+ rx, ry, ryaw, rk = [], [], [], []
54
+ for i_s in s:
55
+ ix, iy = sp.calc_position(i_s)
56
+ rx.append(ix)
57
+ ry.append(iy)
58
+ ryaw.append(sp.calc_yaw(i_s))
59
+ rk.append(sp.calc_curvature(i_s))
60
+
61
+ n_course_point = 100 # sampling number
62
+ rax, ray = approximate_b_spline_path(way_point_x, way_point_y,
63
+ n_course_point)
64
+ rix, riy = interpolate_b_spline_path(way_point_x, way_point_y,
65
+ n_course_point)
66
+
67
+ # show results
68
+ plt.plot(way_point_x, way_point_y, '-og', label="Control Points")
69
+ plt.plot(rax, ray, '-r', label="Approximated B-Spline path")
70
+ plt.plot(rix, riy, '-b', label="Interpolated B-Spline path")
71
+ plt.plot(rx, ry, color='dimgray', label="Cubic Spline")
72
+ plt.grid(True)
73
+ plt.title("Curves Comparison")
74
+ plt.legend()
75
+ plt.axis("equal")
76
+ plt.show()
77
+
78
+
79
+ if __name__ == '__main__':
80
+ main()
@@ -0,0 +1,262 @@
1
+ #! /usr/bin/python
2
+ # -*- coding: utf-8 -*-
3
+ u"""
4
+ Cubic Spline library on python
5
+
6
+ author Atsushi Sakai
7
+
8
+ usage: see test codes as below
9
+
10
+ license: MIT
11
+ """
12
+ import math
13
+ import numpy as np
14
+ import bisect
15
+
16
+
17
+ class Spline:
18
+ u"""
19
+ Cubic Spline class
20
+ """
21
+
22
+ def __init__(self, x, y):
23
+ self.b, self.c, self.d, self.w = [], [], [], []
24
+
25
+ self.x = x
26
+ self.y = y
27
+
28
+ self.nx = len(x) # dimension of s
29
+ h = np.diff(x)
30
+
31
+ # calc coefficient cBest
32
+ self.a = [iy for iy in y]
33
+
34
+ # calc coefficient cBest
35
+ A = self.__calc_A(h)
36
+ B = self.__calc_B(h)
37
+ self.c = np.linalg.solve(A, B)
38
+ # print(self.c1)
39
+
40
+ # calc spline coefficient b and d
41
+ for i in range(self.nx - 1):
42
+ self.d.append((self.c[i + 1] - self.c[i]) / (3.0 * h[i]))
43
+ tb = (self.a[i + 1] - self.a[i]) / h[i] - h[i] * \
44
+ (self.c[i + 1] + 2.0 * self.c[i]) / 3.0
45
+ self.b.append(tb)
46
+
47
+ def calc(self, t):
48
+ u"""
49
+ Calc position
50
+
51
+ if t is outside of the input s, return None
52
+
53
+ """
54
+
55
+ if t < self.x[0]:
56
+ return None
57
+ elif t > self.x[-1]:
58
+ return None
59
+
60
+ i = self.__search_index(t)
61
+ dx = t - self.x[i]
62
+ result = self.a[i] + self.b[i] * dx + \
63
+ self.c[i] * dx ** 2.0 + self.d[i] * dx ** 3.0
64
+
65
+ return result
66
+
67
+ def calcd(self, t):
68
+ u"""
69
+ Calc first derivative
70
+
71
+ if t is outside of the input s, return None
72
+ """
73
+
74
+ if t < self.x[0]:
75
+ return None
76
+ elif t > self.x[-1]:
77
+ return None
78
+
79
+ i = self.__search_index(t)
80
+ dx = t - self.x[i]
81
+ result = self.b[i] + 2.0 * self.c[i] * dx + 3.0 * self.d[i] * dx ** 2.0
82
+ return result
83
+
84
+ def calcdd(self, t):
85
+ u"""
86
+ Calc second derivative
87
+ """
88
+
89
+ if t < self.x[0]:
90
+ return None
91
+ elif t > self.x[-1]:
92
+ return None
93
+
94
+ i = self.__search_index(t)
95
+ dx = t - self.x[i]
96
+ result = 2.0 * self.c[i] + 6.0 * self.d[i] * dx
97
+ return result
98
+
99
+ def __search_index(self, x):
100
+ u"""
101
+ search data segment index
102
+ """
103
+ return bisect.bisect(self.x, x) - 1
104
+
105
+ def __calc_A(self, h):
106
+ u"""
107
+ calc matrix A for spline coefficient cBest
108
+ """
109
+ A = np.zeros((self.nx, self.nx))
110
+ A[0, 0] = 1.0
111
+ for i in range(self.nx - 1):
112
+ if i != (self.nx - 2):
113
+ A[i + 1, i + 1] = 2.0 * (h[i] + h[i + 1])
114
+ A[i + 1, i] = h[i]
115
+ A[i, i + 1] = h[i]
116
+
117
+ A[0, 1] = 0.0
118
+ A[self.nx - 1, self.nx - 2] = 0.0
119
+ A[self.nx - 1, self.nx - 1] = 1.0
120
+ # print(A)
121
+ return A
122
+
123
+ def __calc_B(self, h):
124
+ u"""
125
+ calc matrix B for spline coefficient cBest
126
+ """
127
+ B = np.zeros(self.nx)
128
+ for i in range(self.nx - 2):
129
+ B[i + 1] = 3.0 * (self.a[i + 2] - self.a[i + 1]) / \
130
+ h[i + 1] - 3.0 * (self.a[i + 1] - self.a[i]) / h[i]
131
+ # print(B)
132
+ return B
133
+
134
+
135
+ class Spline2D:
136
+ u"""
137
+ 2D Cubic Spline class
138
+
139
+ """
140
+
141
+ def __init__(self, x, y):
142
+ self.s = self.__calc_s(x, y)
143
+ self.sx = Spline(self.s, x)
144
+ self.sy = Spline(self.s, y)
145
+
146
+ def __calc_s(self, x, y):
147
+ dx = np.diff(x)
148
+ dy = np.diff(y)
149
+ self.ds = [math.sqrt(idx ** 2 + idy ** 2)
150
+ for (idx, idy) in zip(dx, dy)]
151
+ s = [0]
152
+ s.extend(np.cumsum(self.ds))
153
+ return s
154
+
155
+ def calc_position(self, s):
156
+ u"""
157
+ calc position
158
+ """
159
+ x = self.sx.calc(s)
160
+ y = self.sy.calc(s)
161
+
162
+ return x, y
163
+
164
+ def calc_curvature(self, s):
165
+ u"""
166
+ calc curvature
167
+ """
168
+ dx = self.sx.calcd(s)
169
+ ddx = self.sx.calcdd(s)
170
+ dy = self.sy.calcd(s)
171
+ ddy = self.sy.calcdd(s)
172
+ k = (ddy * dx - ddx * dy) / (dx ** 2 + dy ** 2)
173
+ return k
174
+
175
+ def calc_yaw(self, s):
176
+ u"""
177
+ calc yaw
178
+ """
179
+ dx = self.sx.calcd(s)
180
+ dy = self.sy.calcd(s)
181
+ yaw = math.atan2(dy, dx)
182
+ return yaw
183
+
184
+
185
+ def calc_spline_course(x, y, ds=0.1):
186
+ sp = Spline2D(x, y)
187
+ s = np.arange(0, sp.s[-1], ds)
188
+
189
+ rx, ry, ryaw, rk = [], [], [], []
190
+ for i_s in s:
191
+ ix, iy = sp.calc_position(i_s)
192
+ rx.append(ix)
193
+ ry.append(iy)
194
+ ryaw.append(sp.calc_yaw(i_s))
195
+ rk.append(sp.calc_curvature(i_s))
196
+
197
+ return rx, ry, ryaw, rk, s
198
+
199
+
200
+ def test_spline2d():
201
+ print("Spline 2D test")
202
+ import matplotlib.pyplot as plt
203
+ x = [-2.5, 0.0, 2.5, 5.0, 7.5, 3.0, -1.0]
204
+ y = [0.7, -6, 5, 6.5, 0.0, 5.0, -2.0]
205
+
206
+ sp = Spline2D(x, y)
207
+ s = np.arange(0, sp.s[-1], 0.1)
208
+
209
+ rx, ry, ryaw, rk = [], [], [], []
210
+ for i_s in s:
211
+ ix, iy = sp.calc_position(i_s)
212
+ rx.append(ix)
213
+ ry.append(iy)
214
+ ryaw.append(sp.calc_yaw(i_s))
215
+ rk.append(sp.calc_curvature(i_s))
216
+
217
+ flg, ax = plt.subplots(1)
218
+ plt.plot(x, y, "xb", label="input")
219
+ plt.plot(rx, ry, "-r", label="spline")
220
+ plt.grid(True)
221
+ plt.axis("equal")
222
+ plt.xlabel("s[m]")
223
+ plt.ylabel("y[m]")
224
+ plt.legend()
225
+
226
+ flg, ax = plt.subplots(1)
227
+ plt.plot(s, [math.degrees(iyaw) for iyaw in ryaw], "-r", label="yaw")
228
+ plt.grid(True)
229
+ plt.legend()
230
+ plt.xlabel("line length[m]")
231
+ plt.ylabel("yaw angle[deg]")
232
+
233
+ flg, ax = plt.subplots(1)
234
+ plt.plot(s, rk, "-r", label="curvature")
235
+ plt.grid(True)
236
+ plt.legend()
237
+ plt.xlabel("line length[m]")
238
+ plt.ylabel("curvature [1/m]")
239
+
240
+ plt.show()
241
+
242
+
243
+ def test_spline():
244
+ print("Spline test")
245
+ import matplotlib.pyplot as plt
246
+ x = [-0.5, 0.0, 0.5, 1.0, 1.5]
247
+ y = [3.2, 2.7, 6, 5, 6.5]
248
+
249
+ spline = Spline(x, y)
250
+ rx = np.arange(-2.0, 4, 0.01)
251
+ ry = [spline.calc(i) for i in rx]
252
+
253
+ plt.plot(x, y, "xb")
254
+ plt.plot(rx, ry, "-r")
255
+ plt.grid(True)
256
+ plt.axis("equal")
257
+ plt.show()
258
+
259
+
260
+ if __name__ == '__main__':
261
+ test_spline()
262
+ # test_spline2d()
@@ -0,0 +1,66 @@
1
+ import matplotlib.pyplot as plt
2
+ import numpy as np
3
+ PI = np.pi
4
+
5
+
6
+ class Arrow:
7
+ def __init__(self, x, y, theta, L, c):
8
+ angle = np.deg2rad(30)
9
+ d = 0.5 * L
10
+ w = 2
11
+
12
+ x_start = x
13
+ y_start = y
14
+ x_end = x + L * np.cos(theta)
15
+ y_end = y + L * np.sin(theta)
16
+
17
+ theta_hat_L = theta + PI - angle
18
+ theta_hat_R = theta + PI + angle
19
+
20
+ x_hat_start = x_end
21
+ x_hat_end_L = x_hat_start + d * np.cos(theta_hat_L)
22
+ x_hat_end_R = x_hat_start + d * np.cos(theta_hat_R)
23
+
24
+ y_hat_start = y_end
25
+ y_hat_end_L = y_hat_start + d * np.sin(theta_hat_L)
26
+ y_hat_end_R = y_hat_start + d * np.sin(theta_hat_R)
27
+
28
+ plt.plot([x_start, x_end], [y_start, y_end], color=c, linewidth=w)
29
+ plt.plot([x_hat_start, x_hat_end_L],
30
+ [y_hat_start, y_hat_end_L], color=c, linewidth=w)
31
+ plt.plot([x_hat_start, x_hat_end_R],
32
+ [y_hat_start, y_hat_end_R], color=c, linewidth=w)
33
+
34
+
35
+ class Car:
36
+ def __init__(self, x, y, yaw, w, L):
37
+ theta_B = PI + yaw
38
+
39
+ xB = x + L / 4 * np.cos(theta_B)
40
+ yB = y + L / 4 * np.sin(theta_B)
41
+
42
+ theta_BL = theta_B + PI / 2
43
+ theta_BR = theta_B - PI / 2
44
+
45
+ x_BL = xB + w / 2 * np.cos(theta_BL) # Bottom-Left vertex
46
+ y_BL = yB + w / 2 * np.sin(theta_BL)
47
+ x_BR = xB + w / 2 * np.cos(theta_BR) # Bottom-Right vertex
48
+ y_BR = yB + w / 2 * np.sin(theta_BR)
49
+
50
+ x_FL = x_BL + L * np.cos(yaw) # Front-Left vertex
51
+ y_FL = y_BL + L * np.sin(yaw)
52
+ x_FR = x_BR + L * np.cos(yaw) # Front-Right vertex
53
+ y_FR = y_BR + L * np.sin(yaw)
54
+
55
+ plt.plot([x_BL, x_BR, x_FR, x_FL, x_BL],
56
+ [y_BL, y_BR, y_FR, y_FL, y_BL],
57
+ linewidth=1, color='black')
58
+
59
+ Arrow(x, y, yaw, L / 2, 'black')
60
+ # plt.axis("equal")
61
+ # plt.show()
62
+
63
+
64
+ if __name__ == '__main__':
65
+ # Arrow(-1, 2, 60)
66
+ Car(0, 0, 1, 2, 60)