Skip to content

Commit 8a3e5a0

Browse files
committed
first release rear wheel feedback
1 parent 74b3470 commit 8a3e5a0

File tree

1 file changed

+44
-42
lines changed

1 file changed

+44
-42
lines changed

PathTracking/rear_wheel_feedback/rear_wheel_feedback.py

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
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
66
author: Atsushi Sakai
77
88
"""
9-
# import numpy as np
109
import math
1110
import matplotlib.pyplot as plt
1211
import unicycle_model
1312
from pycubicspline import pycubicspline
1413

1514
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
1917

2018

2119
def 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):
175177
def 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

Comments
 (0)