88import numpy as np
99import math
1010import matplotlib .pyplot as plt
11- import unicycle_model
12- from pycubicspline import pycubicspline
13- from matplotrecorder import matplotrecorder
1411import scipy .linalg as la
12+ from pycubicspline import pycubicspline
1513
1614Kp = 1.0 # speed proportional gain
1715
1816# LQR parameter
1917Q = np .eye (4 )
2018R = np .eye (1 )
2119
22- matplotrecorder .donothing = True
20+ # parameters
21+ dt = 0.1 # time tick[s]
22+ L = 0.5 # Wheel base of the vehicle [m]
23+ max_steer = math .radians (45.0 ) # maximum steering angle[rad]
24+
25+ show_animation = True
26+ # show_animation = False
27+
28+
29+ class State :
30+
31+ def __init__ (self , x = 0.0 , y = 0.0 , yaw = 0.0 , v = 0.0 ):
32+ self .x = x
33+ self .y = y
34+ self .yaw = yaw
35+ self .v = v
36+
37+
38+ def update (state , a , delta ):
39+
40+ if delta >= max_steer :
41+ delta = max_steer
42+ if delta <= - max_steer :
43+ delta = - max_steer
44+
45+ state .x = state .x + state .v * math .cos (state .yaw ) * dt
46+ state .y = state .y + state .v * math .sin (state .yaw ) * dt
47+ state .yaw = state .yaw + state .v / L * math .tan (delta ) * dt
48+ state .v = state .v + a * dt
49+
50+ return state
2351
2452
2553def PIDControl (target , current ):
@@ -84,25 +112,25 @@ def lqr_steering_control(state, cx, cy, cyaw, ck, pe, pth_e):
84112
85113 A = np .matrix (np .zeros ((4 , 4 )))
86114 A [0 , 0 ] = 1.0
87- A [0 , 1 ] = unicycle_model . dt
115+ A [0 , 1 ] = dt
88116 A [1 , 2 ] = v
89117 A [2 , 2 ] = 1.0
90- A [2 , 3 ] = unicycle_model . dt
118+ A [2 , 3 ] = dt
91119 # print(A)
92120
93121 B = np .matrix (np .zeros ((4 , 1 )))
94- B [3 , 0 ] = v / unicycle_model . L
122+ B [3 , 0 ] = v / L
95123
96124 K , _ , _ = dlqr (A , B , Q , R )
97125
98126 x = np .matrix (np .zeros ((4 , 1 )))
99127
100128 x [0 , 0 ] = e
101- x [1 , 0 ] = (e - pe ) / unicycle_model . dt
129+ x [1 , 0 ] = (e - pe ) / dt
102130 x [2 , 0 ] = th_e
103- x [3 , 0 ] = (th_e - pth_e ) / unicycle_model . dt
131+ x [3 , 0 ] = (th_e - pth_e ) / dt
104132
105- ff = math .atan2 (unicycle_model . L * k , 1 )
133+ ff = math .atan2 (L * k , 1 )
106134 fb = pi_2_pi ((- K * x )[0 , 0 ])
107135
108136 delta = ff + fb
@@ -135,7 +163,7 @@ def closed_loop_prediction(cx, cy, cyaw, ck, speed_profile, goal):
135163 goal_dis = 0.3
136164 stop_speed = 0.05
137165
138- state = unicycle_model . State (x = - 0.0 , y = - 0.0 , yaw = 0.0 , v = 0.0 )
166+ state = State (x = - 0.0 , y = - 0.0 , yaw = 0.0 , v = 0.0 )
139167
140168 time = 0.0
141169 x = [state .x ]
@@ -152,13 +180,12 @@ def closed_loop_prediction(cx, cy, cyaw, ck, speed_profile, goal):
152180 state , cx , cy , cyaw , ck , e , e_th )
153181
154182 ai = PIDControl (speed_profile [target_ind ], state .v )
155- # state = unicycle_model.update(state, ai, di)
156- state = unicycle_model .update (state , ai , dl )
183+ state = update (state , ai , dl )
157184
158185 if abs (state .v ) <= stop_speed :
159186 target_ind += 1
160187
161- time = time + unicycle_model . dt
188+ time = time + dt
162189
163190 # check goal
164191 dx = state .x - goal [0 ]
@@ -173,7 +200,7 @@ def closed_loop_prediction(cx, cy, cyaw, ck, speed_profile, goal):
173200 v .append (state .v )
174201 t .append (time )
175202
176- if target_ind % 1 == 0 :
203+ if target_ind % 1 == 0 and show_animation :
177204 plt .cla ()
178205 plt .plot (cx , cy , "-r" , label = "course" )
179206 plt .plot (x , y , "ob" , label = "trajectory" )
@@ -183,9 +210,7 @@ def closed_loop_prediction(cx, cy, cyaw, ck, speed_profile, goal):
183210 plt .title ("speed[km/h]:" + str (round (state .v * 3.6 , 2 )) +
184211 ",target index:" + str (target_ind ))
185212 plt .pause (0.0001 )
186- matplotrecorder .save_frame () # save each frame
187213
188- plt .close ()
189214 return t , x , y , yaw , v
190215
191216
@@ -232,33 +257,33 @@ def main():
232257
233258 t , x , y , yaw , v = closed_loop_prediction (cx , cy , cyaw , ck , sp , goal )
234259
235- matplotrecorder . save_movie ( "animation.gif" , 0.1 ) # gif is ok.
236-
237- flg , _ = plt .subplots (1 )
238- plt .plot (ax , ay , "xb" , label = "input" )
239- plt .plot (cx , cy , "-r" , label = "spline" )
240- plt .plot (x , y , "-g" , label = "tracking" )
241- plt .grid (True )
242- plt .axis ("equal" )
243- plt .xlabel ("x[m]" )
244- plt .ylabel ("y[m]" )
245- plt .legend ()
246-
247- flg , ax = plt .subplots (1 )
248- plt .plot (s , [math .degrees (iyaw ) for iyaw in cyaw ], "-r" , label = "yaw" )
249- plt .grid (True )
250- plt .legend ()
251- plt .xlabel ("line length[m]" )
252- plt .ylabel ("yaw angle[deg]" )
253-
254- flg , ax = plt .subplots (1 )
255- plt .plot (s , ck , "-r" , label = "curvature" )
256- plt .grid (True )
257- plt .legend ()
258- plt .xlabel ("line length[m]" )
259- plt .ylabel ("curvature [1/m]" )
260-
261- plt .show ()
260+ if show_animation :
261+ plt . close ()
262+ flg , _ = plt .subplots (1 )
263+ plt .plot (ax , ay , "xb" , label = "input" )
264+ plt .plot (cx , cy , "-r" , label = "spline" )
265+ plt .plot (x , y , "-g" , label = "tracking" )
266+ plt .grid (True )
267+ plt .axis ("equal" )
268+ plt .xlabel ("x[m]" )
269+ plt .ylabel ("y[m]" )
270+ plt .legend ()
271+
272+ flg , ax = plt .subplots (1 )
273+ plt .plot (s , [math .degrees (iyaw ) for iyaw in cyaw ], "-r" , label = "yaw" )
274+ plt .grid (True )
275+ plt .legend ()
276+ plt .xlabel ("line length[m]" )
277+ plt .ylabel ("yaw angle[deg]" )
278+
279+ flg , ax = plt .subplots (1 )
280+ plt .plot (s , ck , "-r" , label = "curvature" )
281+ plt .grid (True )
282+ plt .legend ()
283+ plt .xlabel ("line length[m]" )
284+ plt .ylabel ("curvature [1/m]" )
285+
286+ plt .show ()
262287
263288
264289if __name__ == '__main__' :
0 commit comments