Skip to content

Commit 17c9d71

Browse files
committed
Add sphinx doc generation
1 parent d4aaf50 commit 17c9d71

7 files changed

Lines changed: 399 additions & 0 deletions

File tree

docs/Makefile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Minimal makefile for Sphinx documentation
2+
#
3+
4+
# You can set these variables from the command line, and also
5+
# from the environment for the first two.
6+
SPHINXOPTS ?=
7+
SPHINXBUILD ?= sphinx-build
8+
SOURCEDIR = source
9+
BUILDDIR = build
10+
11+
# Put it first so that "make" without argument is like "make help".
12+
help:
13+
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14+
15+
.PHONY: help Makefile
16+
17+
# Catch-all target: route all unknown targets to Sphinx using the new
18+
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19+
%: Makefile
20+
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

docs/source/README.md

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
# Spatial Maths for Python
2+
3+
Spatial maths capability underpins all of robotics and robotic vision. The aim of the `spatialmath` package is to replicate the functionality of the MATLAB® Spatial Math Toolbox while achieving the conflicting high-level design aims of being:
4+
5+
* as similar as possible to the MATLAB function names and semantics
6+
* as Pythonic as possible
7+
8+
More detailed design aims include:
9+
10+
* Python3 support only
11+
* Use Python keyword arguments to replace the RTB string options supported using `tb_optparse`
12+
* Use `numpy` arrays for all rotation and homogeneous transformation matrices, as well as vectors
13+
* Functions that accept a vector can accept a list, tuple, or `np.ndarray`
14+
* By default all `np.ndarray` vectors have the shape `(N,)` but functions also accept row `(1,N)` and column `(N,1)` vectors. This is a gnarly aspect of numpy.
15+
* Unlike RTB these functions do not support sequences, that functionality is supported by the pose classes `SO2`, `SE2`, `SO3`, `SE3`.
16+
17+
Quick example:
18+
19+
```
20+
import spatialmath as sm
21+
22+
R = sm.SO3.Rx(30, 'deg')
23+
print(R)
24+
1 0 0
25+
0 0.866025 -0.5
26+
0 0.5 0.866025
27+
```
28+
which constructs a rotation about the x-axis by 30 degrees.
29+
30+
31+
## Low-level spatial math
32+
33+
First lets import the low-level transform functions
34+
35+
```
36+
>>> from spatialmath.base.transforms import *
37+
```
38+
39+
Let's start with a familiar and tangible example:
40+
41+
```
42+
>>> rotx(0.3)
43+
array([[ 1. , 0. , 0. ],
44+
[ 0. , 0.95533649, -0.29552021],
45+
[ 0. , 0.29552021, 0.95533649]])
46+
47+
>>> rotx(30, unit='deg')
48+
Out[438]:
49+
array([[ 1. , 0. , 0. ],
50+
[ 0. , 0.8660254, -0.5 ],
51+
[ 0. , 0.5 , 0.8660254]])
52+
```
53+
Remember that these are `numpy` arrays so to perform matrix multiplication you need to use the `@` operator, for example
54+
55+
```
56+
rotx(0.3) @ roty(0.2)
57+
```
58+
59+
Note that the `*` operator performs element-wise multiplication, equivalent to the MATLAB `.*` operator.
60+
61+
We also support multiple ways of passing vector information to functions that require it:
62+
63+
* as separate positional arguments
64+
65+
```
66+
transl2(1, 2)
67+
Out[442]:
68+
array([[1., 0., 1.],
69+
[0., 1., 2.],
70+
[0., 0., 1.]])
71+
```
72+
73+
* as a list or a tuple
74+
75+
```
76+
transl2( [1,2] )
77+
Out[443]:
78+
array([[1., 0., 1.],
79+
[0., 1., 2.],
80+
[0., 0., 1.]])
81+
82+
transl2( (1,2) )
83+
Out[444]:
84+
array([[1., 0., 1.],
85+
[0., 1., 2.],
86+
[0., 0., 1.]])
87+
```
88+
89+
* or as a `numpy` array
90+
91+
```
92+
transl2( np.array([1,2]) )
93+
Out[445]:
94+
array([[1., 0., 1.],
95+
[0., 1., 2.],
96+
[0., 0., 1.]])
97+
```
98+
99+
trplot example
100+
packages, animation
101+
102+
There is a single module that deals with quaternions, unit or not, and the representation is a `numpy` array of four elements. As above, functions can accept the `numpy` array, a list, dict or `numpy` row or column vectors.
103+
104+
```
105+
>>> from spatialmath.base.quaternion import *
106+
>>> q = qqmul([1,2,3,4], [5,6,7,8])
107+
>>> q
108+
array([-60, 12, 30, 24])
109+
>>> qprint(q)
110+
-60.000000 < 12.000000, 30.000000, 24.000000 >
111+
>>> qnorm(q)
112+
72.24956747275377
113+
```
114+
115+
116+
## High-level classes
117+
118+
```
119+
>>> from spatialmath import *
120+
>>> SO2(.1)
121+
[[ 0.99500417 -0.09983342]
122+
[ 0.09983342 0.99500417]]
123+
```
124+
125+
These classes abstract the low-level numpy arrays into objects that obey the rules associated with the mathematical groups SO(2), SE(2), SO(3), SE(3) as well as twists and quaternions. pose classes `SO2`, `SE2`, `SO3`, `SE3`.
126+
127+
Using classes ensures type safety, for example it stops us mixing a 2D homogeneous transformation with a 3D rotation matrix -- both are 3x3 matrices.
128+
129+
These classes are all derived from two parent classes:
130+
131+
* `RTBPose` which provides common functionality for all
132+
* `UserList` which provdides the ability to act like a list
133+
134+
The latter is important because frequnetly in robotics we want a sequence, a trajectory, of rotation matrices or poses. However a list of these items has the type `list` and the elements are not enforced to be homogeneous, ie. a list could contain a mixture of classes.
135+
136+
Another option would be to create a `numpy` array of these objects, the upside being it could be a multi-dimensional array. The downside is that again the array is not guaranteed to be homogeneous.
137+
138+
139+
The approach adopted here is to give these classes list superpowers. Using the example of SE(3) but applicable to all
140+
141+
```
142+
T = transl(1,2,3) # create a 4x4 np.array
143+
144+
a = SE3(T)
145+
a.append(a) # append a copy
146+
a.append(a) # append a copy
147+
type(a)
148+
len(a)
149+
a[1] # extract one element of the list
150+
for x in a:
151+
# do a thing
152+
```
153+
154+
## Symbolic support
155+
156+
Some functions have support for symbolic variables, for example
157+
158+
```
159+
import sympy
160+
161+
theta = sym.symbols('theta')
162+
print(rotx(theta))
163+
[[1 0 0]
164+
[0 cos(theta) -sin(theta)]
165+
[0 sin(theta) cos(theta)]]
166+
```
167+
168+
The resulting `numpy` array is an array of symbolic objects not numbers &ndash; the constants are also symbolic objects. You can read the elements of the matrix
169+
170+
```
171+
a = T[0,0]
172+
173+
a
174+
Out[258]: 1
175+
176+
type(a)
177+
Out[259]: int
178+
179+
a = T[1,1]
180+
a
181+
Out[256]:
182+
cos(theta)
183+
type(a)
184+
Out[255]: cos
185+
```
186+
We see that the symbolic constants are converted back to Python numeric types on read.
187+
188+
Similarly when we assign an element or slice of the symbolic matrix to a numeric value, they are converted to symbolic constants on the way in.
189+
190+
191+
192+
```
193+
T[0,3] = 22
194+
print(T)
195+
[[1 0 0 22]
196+
[0 cos(theta) -sin(theta) 0]
197+
[0 sin(theta) cos(theta) 0]
198+
[0 0 0 1]]
199+
```
200+
but you can't write a symbolic value into a floating point matrix
201+
202+
```
203+
T=trotx(0.2)
204+
205+
T[0,3]=theta
206+
Traceback (most recent call last):
207+
208+
File "<ipython-input-248-b6823f58f38d>", line 1, in <module>
209+
T[0,3]=th
210+
211+
File "/opt/anaconda3/lib/python3.7/site-packages/sympy/core/expr.py", line 325, in __float__
212+
raise TypeError("can't convert expression to float")
213+
214+
TypeError: can't convert expression to float
215+
```
216+
217+
| Function | Symbolic support |
218+
|----------|------------------|
219+
| rot2 | yes |
220+
| transl2 | yes |
221+
| rotx | yes |
222+
| roty | yes |
223+
| rotz | yes |
224+
| transl | yes |
225+
| r2t | yes |
226+
| t2r | yes |
227+
| rotx | yes |
228+
| rotx | yes |
229+
230+
231+
232+
233+
234+
235+

docs/source/conf.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Configuration file for the Sphinx documentation builder.
2+
#
3+
# This file only contains a selection of the most common options. For a full
4+
# list see the documentation:
5+
# https://www.sphinx-doc.org/en/master/usage/configuration.html
6+
7+
# -- Path setup --------------------------------------------------------------
8+
9+
# If extensions (or modules to document with autodoc) are in another directory,
10+
# add these directories to sys.path here. If the directory is relative to the
11+
# documentation root, use os.path.abspath to make it absolute, like shown here.
12+
#
13+
import os
14+
import sys
15+
sys.path.insert(0, os.path.abspath('.'))
16+
sys.path.insert(0, os.path.abspath('../base'))
17+
18+
19+
# -- Project information -----------------------------------------------------
20+
21+
project = 'Spatial Maths package'
22+
copyright = '2020, Peter Corke'
23+
author = 'Peter Corke'
24+
25+
# The full version, including alpha/beta/rc tags
26+
release = '0.9'
27+
28+
29+
# -- General configuration ---------------------------------------------------
30+
31+
# Add any Sphinx extension module names here, as strings. They can be
32+
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
33+
# ones.
34+
extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.viewcode', 'recommonmark', 'sphinx.ext.imgmath'
35+
]
36+
37+
# Add any paths that contain templates here, relative to this directory.
38+
templates_path = ['_templates']
39+
40+
# List of patterns, relative to source directory, that match files and
41+
# directories to ignore when looking for source files.
42+
# This pattern also affects html_static_path and html_extra_path.
43+
exclude_patterns = []
44+
45+
46+
# -- Options for HTML output -------------------------------------------------
47+
48+
# The theme to use for HTML and HTML Help pages. See the documentation for
49+
# a list of builtin themes.
50+
#
51+
html_theme = 'sphinx_rtd_theme'
52+
53+
# Add any paths that contain custom static files (such as style sheets) here,
54+
# relative to this directory. They are copied after the builtin static files,
55+
# so a file named "default.css" will overwrite the builtin "default.css".
56+
html_static_path = ['_static']
57+
58+
autodoc_mock_imports = ["numpy", "scipy"]

docs/source/index.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
.. Spatial Maths package documentation master file, created by
2+
sphinx-quickstart on Sun Apr 12 15:50:23 2020.
3+
You can adapt this file completely to your liking, but it should at least
4+
contain the root `toctree` directive.
5+
6+
Welcome to Spatial Maths package's documentation!
7+
=================================================
8+
9+
10+
.. toctree::
11+
:maxdepth: 2
12+
:caption: Contents:
13+
14+
support
15+
README
16+
spatialmath
17+
18+
Indices and tables
19+
==================
20+
21+
* :ref:`genindex`
22+
* :ref:`modindex`
23+
* :ref:`search`

docs/source/modules.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
spatialmath
2+
===========
3+
4+
.. toctree::
5+
:maxdepth: 4
6+
7+
spatialmath

docs/source/spatialmath.rst

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
spatialmath package
2+
===================
3+
4+
Pose classes
5+
------------
6+
7+
8+
9+
spatialmath.pose
10+
^^^^^^^^^^^^^^^^
11+
12+
.. automodule:: spatialmath.pose
13+
:members:
14+
:undoc-members:
15+
:show-inheritance:
16+
17+
18+
spatialmath.quaternion
19+
^^^^^^^^^^^^^^^^^^^^^^
20+
21+
.. automodule:: spatialmath.quaternion
22+
:members:
23+
:undoc-members:
24+
:show-inheritance:
25+
26+
27+
Low-level functions: spatialmath.base
28+
-------------------------------------
29+
30+
spatialmath.base.transforms
31+
^^^^^^^^^^^^^^^^^^^^^^^^^^^
32+
33+
.. automodule:: spatialmath.base.transforms
34+
:members:
35+
:undoc-members:
36+
:show-inheritance:
37+
38+
spatialmath.base.quaternion
39+
^^^^^^^^^^^^^^^^^^^^^^^^^^^
40+
41+
.. automodule:: spatialmath.base.quaternion
42+
:members:
43+
:undoc-members:
44+
:show-inheritance:

0 commit comments

Comments
 (0)