11#! /usr/bin/python
22"""
33
4- Path tracking simulation with pure pursuit steering control and PID speed control.
4+ Path tracking simulation with rear wheel feedback steering control and PID speed control.
55
66author: Atsushi Sakai
77
88"""
9- # import numpy as np
109import math
1110import matplotlib .pyplot as plt
1211import unicycle_model
1312from pycubicspline import pycubicspline
1413
1514Kp = 1.0 # speed propotional gain
16- Lf = 1.0 # look-ahead distance
17- # animation = True
18- animation = False
15+ animation = True
16+ # animation = False
1917
2018
2119def PIDControl (target , current ):
@@ -24,74 +22,79 @@ def PIDControl(target, current):
2422 return a
2523
2624
27- def pure_pursuit_control (state , cx , cy , pind ):
25+ def pi_2_pi (angle ):
26+ while (angle > math .pi ):
27+ angle = angle - 2.0 * math .pi
2828
29- ind = calc_target_index (state , cx , cy )
29+ while (angle < - math .pi ):
30+ angle = angle + 2.0 * math .pi
3031
31- if pind >= ind :
32- ind = pind
32+ return angle
3333
34- # print(pind, ind)
35- if ind < len (cx ):
36- tx = cx [ind ]
37- ty = cy [ind ]
38- else :
39- tx = cx [- 1 ]
40- ty = cy [- 1 ]
41- ind = len (cx ) - 1
4234
43- alpha = math .atan2 (ty - state .y , tx - state .x ) - state .yaw
35+ def rear_wheel_feedback_control (state , cx , cy , cyaw , ck , preind ):
36+ KTH = 1.0
37+ KE = 0.5
4438
45- if state .v < 0 : # back
46- alpha = math .pi - alpha
47- # if alpha > 0:
48- # alpha = math.pi - alpha
49- # else:
50- # alpha = math.pi + alpha
39+ ind , e = calc_nearest_index (state , cx , cy , cyaw )
5140
52- delta = math .atan2 (2.0 * unicycle_model .L * math .sin (alpha ) / Lf , 1.0 )
41+ k = ck [ind ]
42+ v = state .v
43+ th_e = pi_2_pi (state .yaw - cyaw [ind ])
44+
45+ omega = v * k * math .cos (th_e ) / (1.0 - k * e ) - \
46+ KTH * abs (v ) * th_e - KE * v * math .sin (th_e ) * e / th_e
47+ # pass
48+
49+ if th_e == 0.0 or omega == 0.0 :
50+ return 0.0 , ind
51+
52+ delta = math .atan2 (unicycle_model .L * omega / v , 1.0 )
53+
54+ # print(k, v, e, th_e, omega, delta)
5355
5456 return delta , ind
5557
5658
57- def calc_target_index (state , cx , cy ):
59+ def calc_nearest_index (state , cx , cy , cyaw ):
5860 dx = [state .x - icx for icx in cx ]
5961 dy = [state .y - icy for icy in cy ]
6062
6163 d = [abs (math .sqrt (idx ** 2 + idy ** 2 )) for (idx , idy ) in zip (dx , dy )]
6264
63- ind = d .index (min (d ))
65+ mind = min (d )
66+
67+ ind = d .index (mind )
6468
65- L = 0.0
69+ dxl = cx [ind ] - state .x
70+ dyl = cy [ind ] - state .y
6671
67- while Lf > L and (ind + 1 ) < len (cx ):
68- dx = cx [ind + 1 ] - cx [ind ]
69- dy = cx [ind + 1 ] - cx [ind ]
70- L += math .sqrt (dx ** 2 + dy ** 2 )
71- ind += 1
72+ angle = pi_2_pi (cyaw [ind ] - math .atan2 (dyl , dxl ))
73+ if angle < 0 :
74+ mind *= - 1
7275
73- return ind
76+ return ind , mind
7477
7578
76- def closed_loop_prediction (cx , cy , cyaw , speed_profile , goal ):
79+ def closed_loop_prediction (cx , cy , cyaw , ck , speed_profile , goal ):
7780
7881 T = 500.0 # max simulation time
7982 goal_dis = 0.3
8083 stop_speed = 0.05
8184
8285 state = unicycle_model .State (x = - 0.0 , y = - 0.0 , yaw = 0.0 , v = 0.0 )
8386
84- # lastIndex = len(cx) - 1
8587 time = 0.0
8688 x = [state .x ]
8789 y = [state .y ]
8890 yaw = [state .yaw ]
8991 v = [state .v ]
9092 t = [0.0 ]
91- target_ind = calc_target_index (state , cx , cy )
93+ target_ind = calc_nearest_index (state , cx , cy , cyaw )
9294
9395 while T >= time :
94- di , target_ind = pure_pursuit_control (state , cx , cy , target_ind )
96+ di , target_ind = rear_wheel_feedback_control (
97+ state , cx , cy , cyaw , ck , target_ind )
9598 ai = PIDControl (speed_profile [target_ind ], state .v )
9699 state = unicycle_model .update (state , ai , di )
97100
@@ -113,7 +116,7 @@ def closed_loop_prediction(cx, cy, cyaw, speed_profile, goal):
113116 v .append (state .v )
114117 t .append (time )
115118
116- if target_ind % 20 == 0 and animation :
119+ if target_ind % 1 == 0 and animation :
117120 plt .cla ()
118121 plt .plot (cx , cy , "-r" , label = "course" )
119122 plt .plot (x , y , "ob" , label = "trajectory" )
@@ -153,7 +156,6 @@ def set_stop_point(target_speed, cx, cy, cyaw):
153156 if switch :
154157 speed_profile [i ] = 0.0
155158
156- speed_profile [0 ] = 0.0
157159 speed_profile [- 1 ] = 0.0
158160
159161 d .append (d [- 1 ])
@@ -175,15 +177,15 @@ def calc_speed_profile(cx, cy, cyaw, target_speed):
175177def main ():
176178 print ("rear wheel feedback tracking start!!" )
177179 ax = [0.0 , 6.0 , 12.5 , 5.0 , 7.5 , 3.0 , - 1.0 ]
178- ay = [0.0 , 0.0 , 5.0 , 6.5 , 0 .0 , 5.0 , - 2.0 ]
180+ ay = [0.0 , 0.0 , 5.0 , 6.5 , 3 .0 , 5.0 , - 2.0 ]
179181 goal = [ax [- 1 ], ay [- 1 ]]
180182
181183 cx , cy , cyaw , ck , s = pycubicspline .calc_spline_course (ax , ay , ds = 0.1 )
182184 target_speed = 10.0 / 3.6
183185
184186 sp = calc_speed_profile (cx , cy , cyaw , target_speed )
185187
186- t , x , y , yaw , v = closed_loop_prediction (cx , cy , cyaw , sp , goal )
188+ t , x , y , yaw , v = closed_loop_prediction (cx , cy , cyaw , ck , sp , goal )
187189
188190 flg , _ = plt .subplots (1 )
189191 print (len (ax ), len (ay ))
0 commit comments