Skip to content

Commit 1e101d1

Browse files
authored
improve LQT steering and speed control document (#1047)
* improve LQT steering and speed control * improve LQT steering and speed control * improve LQT steering and speed control doc * improve LQT steering and speed control doc * improve LQT steering and speed control doc * improve LQT steering and speed control doc
1 parent 26deca1 commit 1e101d1

File tree

8 files changed

+149
-8
lines changed

8 files changed

+149
-8
lines changed

PathTracking/lqr_speed_steer_control/lqr_speed_steer_control.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ def update(state, a, delta):
5555
def pi_2_pi(angle):
5656
return angle_mod(angle)
5757

58+
5859
def solve_dare(A, B, Q, R):
5960
"""
6061
solve a discrete time_Algebraic Riccati equation (DARE)
@@ -221,8 +222,9 @@ def do_simulation(cx, cy, cyaw, ck, speed_profile, goal):
221222
if target_ind % 1 == 0 and show_animation:
222223
plt.cla()
223224
# for stopping simulation with the esc key.
224-
plt.gcf().canvas.mpl_connect('key_release_event',
225-
lambda event: [exit(0) if event.key == 'escape' else None])
225+
plt.gcf().canvas.mpl_connect(
226+
'key_release_event',
227+
lambda event: [exit(0) if event.key == 'escape' else None])
226228
plt.plot(cx, cy, "-r", label="course")
227229
plt.plot(x, y, "ob", label="trajectory")
228230
plt.plot(cx[target_ind], cy[target_ind], "xg", label="target")
@@ -290,6 +292,13 @@ def main():
290292
plt.xlabel("x[m]")
291293
plt.ylabel("y[m]")
292294
plt.legend()
295+
plt.subplots(1)
296+
297+
plt.plot(t, np.array(v)*3.6, label="speed")
298+
plt.grid(True)
299+
plt.xlabel("Time [sec]")
300+
plt.ylabel("Speed [m/s]")
301+
plt.legend()
293302

294303
plt.subplots(1)
295304
plt.plot(s, [np.rad2deg(iyaw) for iyaw in cyaw], "-r", label="yaw")

docs/modules/path_tracking/lqr_speed_and_steering_control/lqr_speed_and_steering_control_main.rst

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,133 @@ Path tracking simulation with LQR speed and steering control.
77

88
.. image:: https://github.com/AtsushiSakai/PythonRoboticsGifs/raw/master/PathTracking/lqr_speed_steer_control/animation.gif
99

10+
`[Code Link] <https://github.com/AtsushiSakai/PythonRobotics/blob/master/PathTracking/lqr_speed_steer_control/lqr_speed_steer_control.py>`_
11+
12+
Overview
13+
~~~~~~~~
14+
15+
The LQR (Linear Quadratic Regulator) speed and steering control model implemented in `lqr_speed_steer_control.py` provides a simulation
16+
for an autonomous vehicle to track:
17+
18+
1. A desired speed by adjusting acceleration based on feedback from the current state and the desired speed.
19+
20+
2. A desired trajectory by adjusting steering angle based on feedback from the current state and the desired trajectory.
21+
22+
by only using one LQT controller.
23+
24+
Vehicle motion Model
25+
~~~~~~~~~~~~~~~~~~~~~
26+
27+
The below figure shows the geometric model of the vehicle used in this simulation:
28+
29+
.. image:: lqr_steering_control_model.jpg
30+
:width: 600px
31+
32+
The `e`, :math:`{\theta}`, and :math:`\upsilon` represent the lateral error, orientation error, and velocity error, respectively, with respect to the desired trajectory and speed.
33+
And :math:`\dot{e}` and :math:`\dot{\theta}` represent the rates of change of these errors.
34+
35+
The :math:`e_t` and :math:`\theta_t`, and :math:`\upsilon` are the updated values of `e`, :math:`\theta`, :math:`\upsilon` and at time `t`, respectively, and can be calculated using the following kinematic equations:
36+
37+
.. math:: e_t = e_{t-1} + \dot{e}_{t-1} dt
38+
39+
.. math:: \theta_t = \theta_{t-1} + \dot{\theta}_{t-1} dt
40+
41+
.. math:: \upsilon_t = \upsilon_{t-1} + a_{t-1} dt
42+
43+
Where `dt` is the time difference and :math:`a_t` is the acceleration at the time `t`.
44+
45+
The change rate of the `e` can be calculated as:
46+
47+
.. math:: \dot{e}_t = V \sin(\theta_{t-1})
48+
49+
Where `V` is the current vehicle speed.
50+
51+
If the :math:`\theta` is small,
52+
53+
.. math:: \theta \approx 0
54+
55+
the :math:`\sin(\theta)` can be approximated as :math:`\theta`:
56+
57+
.. math:: \sin(\theta) = \theta
58+
59+
So, the change rate of the `e` can be approximated as:
60+
61+
.. math:: \dot{e}_t = V \theta_{t-1}
62+
63+
The change rate of the :math:`\theta` can be calculated as:
64+
65+
.. math:: \dot{\theta}_t = \frac{V}{L} \tan(\delta)
66+
67+
where `L` is the wheelbase of the vehicle and :math:`\delta` is the steering angle.
68+
69+
If the :math:`\delta` is small,
70+
71+
.. math:: \delta \approx 0
72+
73+
the :math:`\tan(\delta)` can be approximated as :math:`\delta`:
74+
75+
.. math:: \tan(\delta) = \delta
76+
77+
So, the change rate of the :math:`\theta` can be approximated as:
78+
79+
.. math:: \dot{\theta}_t = \frac{V}{L} \delta
80+
81+
The above equations can be used to update the state of the vehicle at each time step.
82+
83+
Control Model
84+
~~~~~~~~~~~~~~
85+
86+
To formulate the state-space representation of the vehicle dynamics as a linear model,
87+
the state vector `x` and control input vector `u` are defined as follows:
88+
89+
.. math:: x_t = [e_t, \dot{e}_t, \theta_t, \dot{\theta}_t, \upsilon_t]^T
90+
91+
.. math:: u_t = [\delta_t, a_t]^T
92+
93+
The linear state transition equation can be represented as:
94+
95+
.. math:: x_{t+1} = A x_t + B u_t
96+
97+
where:
98+
99+
:math:`\begin{equation*} A = \begin{bmatrix} 1 & dt & 0 & 0 & 0\\ 0 & 0 & v & 0 & 0\\ 0 & 0 & 1 & dt & 0\\ 0 & 0 & 0 & 0 & 0\\ 0 & 0 & 0 & 0 & 1\\\end{bmatrix} \end{equation*}`
100+
101+
:math:`\begin{equation*} B = \begin{bmatrix} 0 & 0\\ 0 & 0\\ 0 & 0\\ \frac{v}{L} & 0\\ 0 & dt \\ \end{bmatrix} \end{equation*}`
102+
103+
LQR controller
104+
~~~~~~~~~~~~~~~
105+
106+
The Linear Quadratic Regulator (LQR) controller is used to calculate the optimal control input `u` that minimizes the quadratic cost function:
107+
108+
:math:`J = \sum_{t=0}^{N} (x_t^T Q x_t + u_t^T R u_t)`
109+
110+
where `Q` and `R` are the weighting matrices for the state and control input, respectively.
111+
112+
for the linear model:
113+
114+
:math:`x_{t+1} = A x_t + B u_t`
115+
116+
The optimal control input `u` can be calculated as:
117+
118+
:math:`u_t = -K x_t`
119+
120+
where `K` is the feedback gain matrix obtained by solving the Riccati equation.
121+
122+
Simulation results
123+
~~~~~~~~~~~~~~~~~~~
124+
125+
126+
.. image:: x-y.png
127+
:width: 600px
128+
129+
.. image:: yaw.png
130+
:width: 600px
131+
132+
.. image:: speed.png
133+
:width: 600px
134+
135+
136+
10137
References:
11138
~~~~~~~~~~~
12139

11.4 KB
Loading
22 KB
Loading
30.5 KB
Loading
23.4 KB
Loading

docs/modules/path_tracking/lqr_steering_control/lqr_steering_control_main.rst

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ control.
88

99
.. image:: https://github.com/AtsushiSakai/PythonRoboticsGifs/raw/master/PathTracking/lqr_steer_control/animation.gif
1010

11+
`[Code Link] <https://github.com/AtsushiSakai/PythonRobotics/blob/master/PathTracking/lqr_steer_control/lqr_steer_control.py>`_
12+
1113
Overview
1214
~~~~~~~~
1315

@@ -23,10 +25,10 @@ The below figure shows the geometric model of the vehicle used in this simulatio
2325
.. image:: lqr_steering_control_model.jpg
2426
:width: 600px
2527

26-
The `e` and `theta` represent the lateral error and orientation error, respectively, with respect to the desired trajectory.
28+
The `e` and :math:`\theta` represent the lateral error and orientation error, respectively, with respect to the desired trajectory.
2729
And :math:`\dot{e}` and :math:`\dot{\theta}` represent the rates of change of these errors.
2830

29-
The :math:`e_t` and :math:`theta_t` are the updated values of `e` and `theta` at time `t`, respectively, and can be calculated using the following kinematic equations:
31+
The :math:`e_t` and :math:`\theta_t` are the updated values of `e` and :math:`\theta` at time `t`, respectively, and can be calculated using the following kinematic equations:
3032

3133
.. math:: e_t = e_{t-1} + \dot{e}_{t-1} dt
3234

@@ -38,9 +40,9 @@ The change rate of the `e` can be calculated as:
3840

3941
.. math:: \dot{e}_t = V \sin(\theta_{t-1})
4042

41-
Where `V` is the vehicle speed.
43+
Where `V` is the current vehicle speed.
4244

43-
If the :math:`theta` is small,
45+
If the :math:`\theta` is small,
4446

4547
.. math:: \theta \approx 0
4648

@@ -72,14 +74,17 @@ So, the change rate of the :math:`\theta` can be approximated as:
7274

7375
The above equations can be used to update the state of the vehicle at each time step.
7476

77+
Control Model
78+
~~~~~~~~~~~~~~
79+
7580
To formulate the state-space representation of the vehicle dynamics as a linear model,
7681
the state vector `x` and control input vector `u` are defined as follows:
7782

7883
.. math:: x_t = [e_t, \dot{e}_t, \theta_t, \dot{\theta}_t]^T
7984

8085
.. math:: u_t = \delta_t
8186

82-
The state transition equation can be represented as:
87+
The linear state transition equation can be represented as:
8388

8489
.. math:: x_{t+1} = A x_t + B u_t
8590

tests/test_codestyle.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def run_ruff(files, fix):
5454
return 0, ""
5555
args = ['--fix'] if fix else []
5656
res = subprocess.run(
57-
['ruff', f'--config={CONFIG}'] + args + files,
57+
['ruff', 'check', f'--config={CONFIG}'] + args + files,
5858
stdout=subprocess.PIPE,
5959
encoding='utf-8'
6060
)

0 commit comments

Comments
 (0)