44
55author: Atsushi Sakai (@Atsushi_twi)
66
7+ Ref:
8+
9+ - [Local Path Planning And Motion Control For Agv In Positioning](http://ieeexplore.ieee.org/document/637936/)
10+
711"""
812
913import numpy as np
1014import matplotlib .pyplot as plt
1115import math
1216
17+ # parameter
18+ MAX_T = 100.0
19+ MIN_T = 5.0
20+
1321show_animation = True
1422
1523
1624class quinic_polynomial :
1725
1826 def __init__ (self , xs , vxs , axs , xe , vxe , axe , T ):
27+
28+ # calc coefficient of quinic polynomial
1929 self .xs = xs
2030 self .vxs = vxs
2131 self .axs = axs
@@ -30,12 +40,11 @@ def __init__(self, xs, vxs, axs, xe, vxe, axe, T):
3040 A = np .array ([[T ** 3 , T ** 4 , T ** 5 ],
3141 [3 * T ** 2 , 4 * T ** 3 , 5 * T ** 4 ],
3242 [6 * T , 12 * T ** 2 , 20 * T ** 3 ]])
33- # print(A)
3443 b = np .array ([xe - self .a0 - self .a1 * T - self .a2 * T ** 2 ,
3544 vxe - self .a1 - 2 * self .a2 * T ,
3645 axe - 2 * self .a2 ])
3746 x = np .linalg .solve (A , b )
38- # print(x)
47+
3948 self .a3 = x [0 ]
4049 self .a4 = x [1 ]
4150 self .a5 = x [2 ]
@@ -58,7 +67,31 @@ def calc_second_derivative(self, t):
5867 return xt
5968
6069
61- def quinic_polynomials_planner (sx , sy , syaw , sv , sa , gx , gy , gyaw , gv , ga ):
70+ def quinic_polynomials_planner (sx , sy , syaw , sv , sa , gx , gy , gyaw , gv , ga , max_accel , dt ):
71+ """
72+ quinic polynomial planner
73+
74+ input
75+ sx: start x position [m]
76+ sy: start y position [m]
77+ syaw: start yaw angle [rad]
78+ sa: start accel [m/ss]
79+ gx: goal x position [m]
80+ gy: goal y position [m]
81+ gyaw: goal yaw angle [rad]
82+ ga: goal accel [m/ss]
83+ max_accel: maximum accel [m/ss]
84+ dt: time tick [s]
85+
86+ return
87+ time: time result
88+ rx: x position result list
89+ ry: y position result list
90+ ryaw: yaw angle result list
91+ rv: velocity result list
92+ ra: accel result list
93+
94+ """
6295
6396 vxs = sv * math .cos (syaw )
6497 vys = sv * math .sin (syaw )
@@ -70,43 +103,50 @@ def quinic_polynomials_planner(sx, sy, syaw, sv, sa, gx, gy, gyaw, gv, ga):
70103 axg = ga * math .cos (gyaw )
71104 ayg = ga * math .sin (gyaw )
72105
73- T = 10.0
74- dt = 0.1
106+ for T in np .arange (MIN_T , MAX_T , MIN_T ):
107+ xqp = quinic_polynomial (sx , vxs , axs , gx , vxg , axg , T )
108+ yqp = quinic_polynomial (sy , vys , ays , gy , vyg , ayg , T )
75109
76- xqp = quinic_polynomial (sx , vxs , axs , gx , vxg , axg , T )
77- yqp = quinic_polynomial (sy , vys , ays , gy , vyg , ayg , T )
110+ time , rx , ry , ryaw , rv , ra = [], [], [], [], [], []
78111
79- rx , ry , ryaw , rv , ra = [], [], [], [], []
80- for t in np . arange ( 0.0 , T + dt , dt ):
81- rx .append (xqp .calc_point (t ))
82- ry .append (yqp .calc_point (t ))
112+ for t in np . arange ( 0.0 , T + dt , dt ):
113+ time . append ( t )
114+ rx .append (xqp .calc_point (t ))
115+ ry .append (yqp .calc_point (t ))
83116
84- vx = xqp .calc_first_derivative (t )
85- vy = yqp .calc_first_derivative (t )
86- v = np .hypot (vx , vy )
87- yaw = math .atan2 (vy , vx )
88- rv .append (v )
89- ryaw .append (yaw )
117+ vx = xqp .calc_first_derivative (t )
118+ vy = yqp .calc_first_derivative (t )
119+ v = np .hypot (vx , vy )
120+ yaw = math .atan2 (vy , vx )
121+ rv .append (v )
122+ ryaw .append (yaw )
90123
91- ax = xqp .calc_second_derivative (t )
92- ay = yqp .calc_second_derivative (t )
93- a = np .hypot (ax , ay )
94- if len (rv ) >= 2 and rv [- 1 ] - rv [- 2 ] < 0.0 :
95- a *= - 1
96- ra .append (a )
124+ ax = xqp .calc_second_derivative (t )
125+ ay = yqp .calc_second_derivative (t )
126+ a = np .hypot (ax , ay )
127+ if len (rv ) >= 2 and rv [- 1 ] - rv [- 2 ] < 0.0 :
128+ a *= - 1
129+ pass
130+ ra .append (a )
97131
98- if show_animation :
132+ if max ([abs (i ) for i in ra ]) <= max_accel :
133+ print ("find path!!" )
134+ break
135+
136+ if show_animation :
137+ for i in range (len (rx )):
99138 plt .cla ()
100139 plt .grid (True )
101140 plt .axis ("equal" )
102141 plot_arrow (sx , sy , syaw )
103142 plot_arrow (gx , gy , gyaw )
104- plot_arrow (rx [- 1 ], ry [- 1 ], ryaw [- 1 ])
105- plt .title ("v[m/s]:" + str (rv [- 1 ])[0 :4 ] +
106- " a[m/s]:" + str (ra [- 1 ])[0 :4 ])
143+ plot_arrow (rx [i ], ry [i ], ryaw [i ])
144+ plt .title ("Time[s]:" + str (time [i ])[0 :4 ] +
145+ " v[m/s]:" + str (rv [i ])[0 :4 ] +
146+ " a[m/ss]:" + str (ra [i ])[0 :4 ])
107147 plt .pause (0.001 )
108148
109- return rx , ry , ryaw , rv , ra
149+ return time , rx , ry , ryaw , rv , ra
110150
111151
112152def plot_arrow (x , y , yaw , length = 1.0 , width = 0.5 , fc = "r" , ec = "k" ):
@@ -136,21 +176,32 @@ def main():
136176 gyaw = math .radians (20.0 ) # goal yaw angle [rad]
137177 gv = 1.0 # goal speed [m/s]
138178 ga = 0.1 # goal accel [m/ss]
179+ max_accel = 1.0 # max accel [m/ss]
180+ dt = 0.1 # time tick [s]
139181
140- rx , ry , ryaw , rv , ra = quinic_polynomials_planner (
141- sx , sy , syaw , sv , sa , gx , gy , gyaw , gv , ga )
182+ time , x , y , yaw , v , a = quinic_polynomials_planner (
183+ sx , sy , syaw , sv , sa , gx , gy , gyaw , gv , ga , max_accel , dt )
142184
143185 if show_animation :
144- plt .plot (rx , ry , "-r" )
186+ plt .plot (x , y , "-r" )
145187
146188 plt .subplots ()
147- plt .plot (ryaw , "-r" )
189+ plt .plot (time , [math .degrees (i ) for i in yaw ], "-r" )
190+ plt .xlabel ("Time[s]" )
191+ plt .ylabel ("Yaw[deg]" )
192+ plt .grid (True )
148193
149194 plt .subplots ()
150- plt .plot (rv , "-r" )
195+ plt .plot (time , v , "-r" )
196+ plt .xlabel ("Time[s]" )
197+ plt .ylabel ("Speed[m/s]" )
198+ plt .grid (True )
151199
152200 plt .subplots ()
153- plt .plot (ra , "-r" )
201+ plt .plot (time , a , "-r" )
202+ plt .xlabel ("Time[s]" )
203+ plt .ylabel ("accel[m/ss]" )
204+ plt .grid (True )
154205
155206 plt .show ()
156207
0 commit comments