88import  matplotlib .pyplot  as  plt 
99import  math 
1010import  numpy  as  np 
11- import  sys 
1211
1312from  scipy  import  interpolate 
1413from  scipy  import  optimize 
2423show_animation  =  True 
2524
2625class  State :
27-     def  __init__ (self , x = 0.0 , y = 0.0 , yaw = 0.0 , v = 0.0 ):
26+     def  __init__ (self , x = 0.0 , y = 0.0 , yaw = 0.0 , v = 0.0 ,  direction = 1 ):
2827        self .x  =  x 
2928        self .y  =  y 
3029        self .yaw  =  yaw 
3130        self .v  =  v 
31+         self .direction  =  direction 
3232
3333    def  update (self , a , delta , dt ):
3434        self .x    =  self .x  +  self .v  *  math .cos (self .yaw ) *  dt 
@@ -52,36 +52,36 @@ def __init__(self, x, y):
5252
5353        self .length  =  s [- 1 ]
5454
55-     def  yaw (self , s ):
55+     def  calc_yaw (self , s ):
5656        dx , dy  =  self .dX (s ), self .dY (s )
5757        return  np .arctan2 (dy , dx )
5858
59-     def  curvature (self , s ):
59+     def  calc_curvature (self , s ):
6060        dx , dy    =  self .dX (s ), self .dY (s )
6161        ddx , ddy    =  self .ddX (s ), self .ddY (s )
6262        return  (ddy  *  dx  -  ddx  *  dy ) /  ((dx  **  2  +  dy  **  2 )** (3  /  2 ))
6363
64-     def  __findClosestPoint (self , s0 , x , y ):
65-         def  f (_s , * args ):
64+     def  __find_nearest_point (self , s0 , x , y ):
65+         def  calc_distance (_s , * args ):
6666            _x , _y =  self .X (_s ), self .Y (_s )
6767            return  (_x  -  args [0 ])** 2  +  (_y  -  args [1 ])** 2 
6868
69-         def  jac (_s , * args ):
69+         def  calc_distance_jacobian (_s , * args ):
7070            _x , _y  =  self .X (_s ), self .Y (_s )
7171            _dx , _dy  =  self .dX (_s ), self .dY (_s )
7272            return  2 * _dx * (_x  -  args [0 ])+ 2 * _dy * (_y - args [1 ])
7373
74-         minimum  =  optimize .fmin_cg (f , s0 , jac , args = (x , y ), full_output = True , disp = False )
74+         minimum  =  optimize .fmin_cg (calc_distance , s0 , calc_distance_jacobian , args = (x , y ), full_output = True , disp = False )
7575        return  minimum 
7676
77-     def  TrackError (self , x , y , s0 ):
78-         ret  =  self .__findClosestPoint (s0 , x , y )
77+     def  calc_track_error (self , x , y , s0 ):
78+         ret  =  self .__find_nearest_point (s0 , x , y )
7979
8080        s  =  ret [0 ][0 ]
8181        e  =  ret [1 ]
8282
83-         k    =  self .curvature (s )
84-         yaw  =  self .yaw (s )
83+         k    =  self .calc_curvature (s )
84+         yaw  =  self .calc_yaw (s )
8585
8686        dxl  =  self .X (s ) -  x 
8787        dyl  =  self .Y (s ) -  y 
@@ -91,7 +91,7 @@ def TrackError(self, x, y, s0):
9191
9292        return  e , k , yaw , s 
9393
94- def  PIDControl (target , current ):
94+ def  pid_control (target , current ):
9595    a  =  Kp  *  (target  -  current )
9696    return  a 
9797
@@ -119,10 +119,9 @@ def rear_wheel_feedback_control(state, e, k, yaw_r):
119119    return  delta 
120120
121121
122- def  closed_loop_prediction (track ,  speed_profile , goal ):
122+ def  simulate (track , goal ):
123123    T  =  500.0   # max simulation time 
124124    goal_dis  =  0.3 
125-     stop_speed  =  0.05 
126125
127126    state  =  State (x = - 0.0 , y = - 0.0 , yaw = 0.0 , v = 0.0 )
128127
@@ -135,13 +134,14 @@ def closed_loop_prediction(track, speed_profile, goal):
135134    goal_flag  =  False 
136135
137136    s  =  np .arange (0 , track .length , 0.1 )
138-     e , k , yaw_r , s0  =  track .TrackError (state .x , state .y , 0.0 )
137+     e , k , yaw_r , s0  =  track .calc_track_error (state .x , state .y , 0.0 )
139138
140139    while  T  >=  time :
141-         e , k , yaw_r , s0  =  track .TrackError (state .x , state .y , s0 )
140+         e , k , yaw_r , s0  =  track .calc_track_error (state .x , state .y , s0 )
142141        di  =  rear_wheel_feedback_control (state , e , k , yaw_r )
143-         #ai = PIDControl(speed_profile[target_ind], state.v) 
144-         ai  =  PIDControl (speed_profile , state .v )
142+ 
143+         speed_r  =  calc_target_speed (state , yaw_r )
144+         ai  =  pid_control (speed_r , state .v )
145145        state .update (ai , di , dt )
146146
147147        time  =  time  +  dt 
@@ -175,29 +175,20 @@ def closed_loop_prediction(track, speed_profile, goal):
175175
176176    return  t , x , y , yaw , v , goal_flag 
177177
178- def  calc_speed_profile (track , target_speed , s ):
179-     speed_profile  =  [target_speed ] *  len (cx )
180-     direction  =  1.0 
181- 
182-     # Set stop point 
183-     for  i  in  range (len (cx ) -  1 ):
184-         dyaw  =  cyaw [i  +  1 ] -  cyaw [i ]
185-         switch  =  math .pi  /  4.0  <=  dyaw  <  math .pi  /  2.0 
186- 
187-         if  switch :
188-             direction  *=  - 1 
189- 
190-         if  direction  !=  1.0 :
191-             speed_profile [i ] =  -  target_speed 
192-         else :
193-             speed_profile [i ] =  target_speed 
194- 
195-         if  switch :
196-             speed_profile [i ] =  0.0 
178+ def  calc_target_speed (state , yaw_r ):
179+     target_speed  =  10.0  /  3.6 
197180
198-     speed_profile [- 1 ] =  0.0 
181+     dyaw  =  yaw_r  -  state .yaw 
182+     switch  =  math .pi  /  4.0  <=  dyaw  <  math .pi  /  2.0 
199183
200-     return  speed_profile 
184+     if  switch :
185+         state .direction  *=  - 1 
186+         return  0.0 
187+     
188+     if  state .direction  !=  1 :
189+         return  - target_speed 
190+     else :
191+         return  target_speed 
201192
202193def  main ():
203194    print ("rear wheel feedback tracking start!!" )
@@ -208,13 +199,7 @@ def main():
208199    track  =  TrackSpline (ax , ay )
209200    s  =  np .arange (0 , track .length , 0.1 )
210201
211-     target_speed  =  10.0  /  3.6 
212- 
213-     # Note: disable backward direction temporary 
214-     #sp = calc_speed_profile(track, target_speed, s) 
215-     sp  =  target_speed  
216- 
217-     t , x , y , yaw , v , goal_flag  =  closed_loop_prediction (track , sp , goal )
202+     t , x , y , yaw , v , goal_flag  =  simulate (track , goal )
218203
219204    # Test 
220205    assert  goal_flag , "Cannot goal" 
@@ -232,14 +217,14 @@ def main():
232217        plt .legend ()
233218
234219        plt .subplots (1 )
235-         plt .plot (s , np .rad2deg (track .yaw (s )), "-r" , label = "yaw" )
220+         plt .plot (s , np .rad2deg (track .calc_yaw (s )), "-r" , label = "yaw" )
236221        plt .grid (True )
237222        plt .legend ()
238223        plt .xlabel ("line length[m]" )
239224        plt .ylabel ("yaw angle[deg]" )
240225
241226        plt .subplots (1 )
242-         plt .plot (s , track .curvature (s ), "-r" , label = "curvature" )
227+         plt .plot (s , track .calc_curvature (s ), "-r" , label = "curvature" )
243228        plt .grid (True )
244229        plt .legend ()
245230        plt .xlabel ("line length[m]" )
0 commit comments