-
-
Notifications
You must be signed in to change notification settings - Fork 104
/
Copy pathpure_pursuit_controller.py
145 lines (110 loc) · 4.52 KB
/
pure_pursuit_controller.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
"""
pure_pursuit_controller.py
Author: Shisato Yano
"""
from math import sin, tan, atan2
class PurePursuitController:
"""
Controller class by Pure Pursuit algorithm
"""
def __init__(self, spec, course=None, color='g'):
"""
Constructor
spec: Vehicle specification object
course: Course data and logic object
color: Color of drawing target point
"""
self.MIN_LOOK_AHEAD_DISTANCE_M = 2.0
self.LOOK_FORWARD_GAIN = 0.3
self.SPEED_PROPORTIONAL_GAIN = 1.0
self.WHEEL_BASE_M = spec.wheel_base_m
self.DRAW_COLOR = color
self.course = course
self.look_ahead_distance_m = self.MIN_LOOK_AHEAD_DISTANCE_M
self.target_course_index = 0
self.target_accel_mps2 = 0.0
self.target_speed_mps = 0.0
self.target_steer_rad = 0.0
self.target_yaw_rate_rps = 0.0
def _calculate_look_ahead_distance(self, state):
"""
Private function to calculate look ahead distance to target point
state: Vehicle's state object
"""
self.look_ahead_distance_m = self.LOOK_FORWARD_GAIN * state.get_speed_mps() + self.MIN_LOOK_AHEAD_DISTANCE_M
def _calculate_target_course_index(self, state):
"""
Private function to calculate target point's index on course
state: Vehicle's state object
"""
nearest_index = self.course.search_nearest_point_index(state)
while self.look_ahead_distance_m > self.course.calculate_distance_from_point(state, nearest_index):
if nearest_index + 1 >= self.course.length(): break
nearest_index += 1
self.target_course_index = nearest_index
def _decide_target_speed_mps(self):
"""
Private function to decide target speed[m/s]
"""
self.target_speed_mps = self.course.point_speed_mps(self.target_course_index)
def _calculate_target_acceleration_mps2(self, state):
"""
Private function to calculate acceleration input
state: Vehicle's state object
"""
diff_speed_mps = self.target_speed_mps - state.get_speed_mps()
self.target_accel_mps2 = self.SPEED_PROPORTIONAL_GAIN * diff_speed_mps
def _calculate_target_steer_angle_rad(self, state):
"""
Private function to calculate steering angle input
state: Vehicle's state object
"""
diff_angle_rad = self.course.calculate_angle_difference_rad(state, self.target_course_index)
self.target_steer_rad = atan2((2 * self.WHEEL_BASE_M * sin(diff_angle_rad)), self.look_ahead_distance_m)
def _calculate_target_yaw_rate_rps(self, state):
"""
Private function to calculate yaw rate input
state: Vehicle's state object
"""
self.target_yaw_rate_rps = state.get_speed_mps() * tan(self.target_steer_rad) / self.WHEEL_BASE_M
def update(self, state, time_s):
"""
Function to update data for path tracking
state: Vehicle's state object
time_s: Simulation interval time[sec]
"""
if not self.course: return
self._calculate_look_ahead_distance(state)
self._calculate_target_course_index(state)
self._decide_target_speed_mps()
self._calculate_target_acceleration_mps2(state)
self._calculate_target_steer_angle_rad(state)
self._calculate_target_yaw_rate_rps(state)
def get_target_accel_mps2(self):
"""
Function to get acceleration input[m/s2]
"""
return self.target_accel_mps2
def get_target_steer_rad(self):
"""
Function to get steering angle input[rad]
"""
return self.target_steer_rad
def get_target_yaw_rate_rps(self):
"""
Function to get yaw rate input[rad/s]
"""
return self.target_yaw_rate_rps
def draw(self, axes, elems):
"""
Function to draw target point on course
axes: Axes object of figure
elems: plot object's list
"""
target_point_plot, = axes.plot(self.course.point_x_m(self.target_course_index),
self.course.point_y_m(self.target_course_index),
marker='o',
color=self.DRAW_COLOR,
linewidth=0,
label="Target Point")
elems.append(target_point_plot)