1
1
#! /usr/bin/python
2
2
"""
3
3
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.
5
5
6
6
author: Atsushi Sakai
7
7
8
8
"""
9
- # import numpy as np
10
9
import math
11
10
import matplotlib .pyplot as plt
12
11
import unicycle_model
13
12
from pycubicspline import pycubicspline
14
13
15
14
Kp = 1.0 # speed propotional gain
16
- Lf = 1.0 # look-ahead distance
17
- # animation = True
18
- animation = False
15
+ animation = True
16
+ # animation = False
19
17
20
18
21
19
def PIDControl (target , current ):
@@ -24,74 +22,79 @@ def PIDControl(target, current):
24
22
return a
25
23
26
24
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
28
28
29
- ind = calc_target_index (state , cx , cy )
29
+ while (angle < - math .pi ):
30
+ angle = angle + 2.0 * math .pi
30
31
31
- if pind >= ind :
32
- ind = pind
32
+ return angle
33
33
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
42
34
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
44
38
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 )
51
40
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)
53
55
54
56
return delta , ind
55
57
56
58
57
- def calc_target_index (state , cx , cy ):
59
+ def calc_nearest_index (state , cx , cy , cyaw ):
58
60
dx = [state .x - icx for icx in cx ]
59
61
dy = [state .y - icy for icy in cy ]
60
62
61
63
d = [abs (math .sqrt (idx ** 2 + idy ** 2 )) for (idx , idy ) in zip (dx , dy )]
62
64
63
- ind = d .index (min (d ))
65
+ mind = min (d )
66
+
67
+ ind = d .index (mind )
64
68
65
- L = 0.0
69
+ dxl = cx [ind ] - state .x
70
+ dyl = cy [ind ] - state .y
66
71
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
72
75
73
- return ind
76
+ return ind , mind
74
77
75
78
76
- def closed_loop_prediction (cx , cy , cyaw , speed_profile , goal ):
79
+ def closed_loop_prediction (cx , cy , cyaw , ck , speed_profile , goal ):
77
80
78
81
T = 500.0 # max simulation time
79
82
goal_dis = 0.3
80
83
stop_speed = 0.05
81
84
82
85
state = unicycle_model .State (x = - 0.0 , y = - 0.0 , yaw = 0.0 , v = 0.0 )
83
86
84
- # lastIndex = len(cx) - 1
85
87
time = 0.0
86
88
x = [state .x ]
87
89
y = [state .y ]
88
90
yaw = [state .yaw ]
89
91
v = [state .v ]
90
92
t = [0.0 ]
91
- target_ind = calc_target_index (state , cx , cy )
93
+ target_ind = calc_nearest_index (state , cx , cy , cyaw )
92
94
93
95
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 )
95
98
ai = PIDControl (speed_profile [target_ind ], state .v )
96
99
state = unicycle_model .update (state , ai , di )
97
100
@@ -113,7 +116,7 @@ def closed_loop_prediction(cx, cy, cyaw, speed_profile, goal):
113
116
v .append (state .v )
114
117
t .append (time )
115
118
116
- if target_ind % 20 == 0 and animation :
119
+ if target_ind % 1 == 0 and animation :
117
120
plt .cla ()
118
121
plt .plot (cx , cy , "-r" , label = "course" )
119
122
plt .plot (x , y , "ob" , label = "trajectory" )
@@ -153,7 +156,6 @@ def set_stop_point(target_speed, cx, cy, cyaw):
153
156
if switch :
154
157
speed_profile [i ] = 0.0
155
158
156
- speed_profile [0 ] = 0.0
157
159
speed_profile [- 1 ] = 0.0
158
160
159
161
d .append (d [- 1 ])
@@ -175,15 +177,15 @@ def calc_speed_profile(cx, cy, cyaw, target_speed):
175
177
def main ():
176
178
print ("rear wheel feedback tracking start!!" )
177
179
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 ]
179
181
goal = [ax [- 1 ], ay [- 1 ]]
180
182
181
183
cx , cy , cyaw , ck , s = pycubicspline .calc_spline_course (ax , ay , ds = 0.1 )
182
184
target_speed = 10.0 / 3.6
183
185
184
186
sp = calc_speed_profile (cx , cy , cyaw , target_speed )
185
187
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 )
187
189
188
190
flg , _ = plt .subplots (1 )
189
191
print (len (ax ), len (ay ))
0 commit comments