Skip to content

Commit 31178c8

Browse files
authored
Enhance dubins path docs (AtsushiSakai#679)
* Enhance dubins path docs * Enhance dubins path docs * Enhance dubins path docs * Enhance dubins path docs * Enhance dubins path docs * Enhance dubins path docs * Enhance dubins path docs * Enhance dubins path docs * Enhance dubins path docs * Enhance dubins path docs * Enhance dubins path docs * Enhance dubins path docs * Enhance dubins path docs * Enhance dubins path docs * Enhance dubins path docs * Enhance dubins path docs * Enhance dubins path docs
1 parent 2c44c73 commit 31178c8

File tree

8 files changed

+275
-234
lines changed

8 files changed

+275
-234
lines changed

PathPlanning/DubinsPath/dubins_path_planner.py

Lines changed: 153 additions & 221 deletions
Large diffs are not rendered by default.

docs/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
4040
# ones.
4141
extensions = [
42+
'matplotlib.sphinxext.plot_directive',
4243
'sphinx.ext.autodoc',
4344
'sphinx.ext.mathjax',
4445
'sphinx.ext.viewcode',
Loading

docs/modules/path_planning/dubins_path/dubins_path_main.rst

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,40 +9,68 @@ Dubins path
99
~~~~~~~~~~~~
1010
Dubins path is a analytical path planning algorithm for a simple car model.
1111

12-
It can generates a shortest path between 2D poses (x, y, yaw) with maximum curvture comstraint and tangent(yaw angle) constraint.
12+
It can generates a shortest path between two 2D poses (x, y, yaw) with maximum curvature constraint and tangent(yaw angle) constraint.
1313

14-
The path consist of 3 segments of maximum curvature curves or a straight line segment.
14+
Generated paths consist of 3 segments of maximum curvature curves or a straight line segment.
1515

1616
Each segment type can is categorized by 3 type: 'Right turn (R)' , 'Left turn (L)', and 'Straight (S).'
1717

18-
Possible path will be at least one of these six types: RSR, RSL, LSR, LSL, RLR, LRL.
18+
Possible path will be at least one of these six types: RSR, RSL, LSR, LSL, RLR, LRL.
1919

20-
For example, one of RSR Dubins paths is:
20+
Dubins path planner can output each segment type and distance of each course segment.
21+
22+
For example, a RSR Dubins path is:
2123

2224
.. image:: RSR.jpg
2325
:width: 400px
2426

25-
one of RLR Dubins paths is:
27+
Each segment distance can be calculated by:
28+
29+
:math:`\alpha = mod(-\theta)`
30+
31+
:math:`\beta = mod(x_{e, yaw} - \theta)`
32+
33+
:math:`p^2 = 2 + d ^ 2 - 2\cos(\alpha-\beta) + 2d(\sin\alpha - \sin\beta)`
34+
35+
:math:`t = atan2(\cos\beta - \cos\alpha, d + \sin\alpha - \sin\beta)`
36+
37+
:math:`d_1 = mod(-\alpha + t)`
38+
39+
:math:`d_2 = p`
40+
41+
:math:`d_3 = mod(\beta - t)`
42+
43+
where :math:`\theta` is tangent and d is distance from :math:`x_s` to :math:`x_e`
44+
45+
A RLR Dubins path is:
2646

2747
.. image:: RLR.jpg
2848
:width: 200px
2949

30-
Dubins path planner can output three types and distances of each course segment.
50+
Each segment distance can be calculated by:
51+
52+
:math:`t = (6.0 - d^2 + 2\cos(\alpha-\beta) + 2d(\sin\alpha - \sin\beta)) / 8.0`
53+
54+
:math:`d_2 = mod(2\pi - acos(t))`
55+
56+
:math:`d_1 = mod(\alpha - atan2(\cos\beta - \cos\alpha, d + \sin\alpha - \sin\beta) + d_2 / 2.0)`
57+
58+
:math:`d_3 = mod(\alpha - \beta - d_1 + d_2)`
3159

3260
You can generate a path from these information and the maximum curvature information.
3361

34-
In the example code, a path which is minimum course length one among 6 course type is selected and then a path is constructed.
62+
A path type which has minimum course length among 6 types is selected,
63+
and then a path is constructed based on the selected type and its distances.
3564

36-
Code
65+
API
3766
~~~~~~~~~~~~~~~~~~~~
3867

39-
.. automodule:: PathPlanning.DubinsPath.dubins_path_planner
40-
:members:
68+
.. autofunction:: PathPlanning.DubinsPath.dubins_path_planner.plan_dubins_path
4169

4270

4371
Reference
4472
~~~~~~~~~~~~~~~~~~~~
45-
73+
- `On Curves of Minimal Length with a Constraint on Average Curvature, and with Prescribed Initial and Terminal Positions and Tangents <https://www.jstor.org/stable/2372560?origin=crossref>`__
4674
- `Dubins path - Wikipedia <https://en.wikipedia.org/wiki/Dubins_path>`__
4775
- `15.3.1 Dubins Curves <http://planning.cs.uiuc.edu/node821.html>`__
4876
- `A Comprehensive, Step-by-Step Tutorial to Computing Dubin’s Paths <https://gieseanw.wordpress.com/2012/10/21/a-comprehensive-step-by-step-tutorial-to-computing-dubins-paths/>`__

tests/test_dubins_path_planning.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,24 @@ def test_3():
6969
check_path_length(px, py, lengths)
7070

7171

72+
def test_path_plannings_types():
73+
dubins_path_planner.show_animation = False
74+
start_x = 1.0 # [m]
75+
start_y = 1.0 # [m]
76+
start_yaw = np.deg2rad(45.0) # [rad]
77+
78+
end_x = -3.0 # [m]
79+
end_y = -3.0 # [m]
80+
end_yaw = np.deg2rad(-45.0) # [rad]
81+
82+
curvature = 1.0
83+
84+
_, _, _, mode, _ = dubins_path_planner.plan_dubins_path(
85+
start_x, start_y, start_yaw, end_x, end_y, end_yaw, curvature,
86+
selected_types=["RSL"])
87+
88+
assert mode == ["R", "S", "L"]
89+
90+
7291
if __name__ == '__main__':
7392
conftest.run_this_test(__file__)

tests/test_utils.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
import numpy as np
55

66

7+
def test_rot_mat_2d():
8+
assert_allclose(angle.rot_mat_2d(0.0),
9+
np.array([[1., 0.],
10+
[0., 1.]]))
11+
12+
713
def test_angle_mod():
814
assert_allclose(angle.angle_mod(-4.0), 2.28318531)
915
assert(isinstance(angle.angle_mod(-4.0), float))

utils/angle.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,22 @@
22
from scipy.spatial.transform import Rotation as Rot
33

44

5-
def create_2d_rotation_matrix(angle):
5+
def rot_mat_2d(angle):
66
"""
7-
Create 2D totation matrix from an angle
7+
Create 2D rotation matrix from an angle
88
99
Parameters
1010
----------
1111
angle :
1212
1313
Returns
1414
-------
15+
A 2D rotation matrix
16+
17+
Examples
18+
--------
19+
>>> angle_mod(-4.0)
20+
1521
1622
"""
1723
return Rot.from_euler('z', angle).as_matrix()[0:2, 0:2]

utils/plot.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
"""
2+
Matplotlib based plotting utilities
3+
"""
4+
import math
5+
import matplotlib.pyplot as plt
6+
7+
8+
def plot_arrow(x, y, yaw, arrow_length=1.0,
9+
origin_point_plot_style="xr",
10+
head_width=0.1, fc="r", ec="k", **kwargs):
11+
"""
12+
Plot an arrow or arrows based on 2D state (x, y, yaw)
13+
14+
All optional settings of matplotlib.pyplot.arrow can be used.
15+
- matplotlib.pyplot.arrow:
16+
https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.arrow.html
17+
18+
Parameters
19+
----------
20+
x : a float or array_like
21+
a value or a list of arrow origin x position.
22+
y : a float or array_like
23+
a value or a list of arrow origin y position.
24+
yaw : a float or array_like
25+
a value or a list of arrow yaw angle (orientation).
26+
arrow_length : a float (optional)
27+
arrow length. default is 1.0
28+
origin_point_plot_style : str (optional)
29+
origin point plot style. If None, not plotting.
30+
head_width : a float (optional)
31+
arrow head width. default is 0.1
32+
fc : string (optional)
33+
face color
34+
ec : string (optional)
35+
edge color
36+
"""
37+
if not isinstance(x, float):
38+
for (i_x, i_y, i_yaw) in zip(x, y, yaw):
39+
plot_arrow(i_x, i_y, i_yaw, head_width=head_width,
40+
fc=fc, ec=ec, **kwargs)
41+
else:
42+
plt.arrow(x, y,
43+
arrow_length * math.cos(yaw),
44+
arrow_length * math.sin(yaw),
45+
head_width=head_width,
46+
fc=fc, ec=ec,
47+
**kwargs)
48+
if origin_point_plot_style is not None:
49+
plt.plot(x, y, origin_point_plot_style)

0 commit comments

Comments
 (0)