Repository navigation
Errata
This page contains errors and clarifications for the book. To report an erratum please post an Issue on GitHub and use the errata template.
Jump to: Chapter 2 · Chapter 6 · Chapter 7 · Chapter 11 · Chapter 12 · Chapter 13 · Chapter 14 · Chapter 15 · Appendix B · Appendix C
Most entries are errors in the book itself. Entries marked Code change since publication are not mistakes: the book's code was correct when it was written, but the Toolboxes it depends on (or NumPy) have since changed, so the printed code needs a small edit to run today. The code in the notebooks already has these edits. Printed code that still runs, perhaps with a DeprecationWarning, is not listed.
Code change since publication. tripleangledemo is now an installed command rather than a module, so %run -m tripleangledemo as printed gives 'tripleangledemo' is not a valid modulename. Use
>>> !tripleangledemo
in a notebook, or run it directly from the shell
$ tripleangledemo
Notebook fix RVC3-python#45; cause: RTB PR #600.
Code change since publication. Same change for twistdemo: use !twistdemo in a notebook instead of %run -m twistdemo, or run it directly from the shell as $ twistdemo. Notebook fix RVC3-python#45; cause: RTB PR #600.
There is an error in computing the confidence bounds (the pink regions), they are overestimated (more generous) in the figure. This has been fixed in RTB v1.4.5. For 95% confidence interval plot_error mistakenly used the 2-D chi-squared radius, 2.448σ, rather than the correct 1-D 95% bound which is 1.960σ;
page 225, (6.22) Issue #15
This is the insertion Jacobian for the SLAM case, not the landmark-only case as it should be. For the landmark-only case the Jacobian is
For the SLAM case (6.22) applies using the definition of
page 238 Issue #13
Incorrect variable, the line
>>> Q = np.diag([0.1, 0.1, np.deg2rad(1)]) ** 2;
should be
>>> R = np.diag([0.1, 0.1, np.deg2rad(1)]) ** 2;
which is passed to the ParticleFilter class a few lines later.
Code change since publication. models.list() was replaced by models.catalog(), and the type argument became mtype. The printed
>>> models.list(type="ETS")
>>> models.list(type="URDF")
>>> models.list(type="DH")
should be
>>> models.catalog(mtype="ETS")
>>> models.catalog(mtype="URDF")
>>> models.catalog(mtype="DH")
Notebook fix RVC3-python#29; cause: RTB PR #558.
Code change since publication. ERobot.URDF_read() was removed and the xacro files named in the book are no longer bundled. Instead of
>>> urdf, *_ = ERobot.URDF_read("ur_description/urdf/ur5_joint_limited_robot.urdf.xacro")
use the module-level function with a robot name
>>> from roboticstoolbox.models.URDF.URDFRobot import URDF_read
>>> urdf, *_ = URDF_read("ur5")
Notebook fix RVC3-python#35.
page 275, Table 7.2 Issue#24
The entry for
In most textbooks using standard Denavit-Hartenberg notation (eg. Siciliano, other editions of RVC) the joints are numbered 1 to N, and the links from 0 to N – oddly joint
For the Python toolbox the joints are numbered 0 to N-1 (Python indexing) and the description of standard Denavit-Hartenberg notation differs from all other reference sources – joint
Bottom line, avoid Denavit-Hartenberg parameters as much as you can and embrace ETS notation!
Code change since publication. Image.stats() is no longer callable. .stats is now a property returning a dict, and the method that prints the summary is .printstats(), so street.stats() becomes
>>> street.printstats()
Notebook fix RVC3-python#35; cause: MVTB v2.0.0 release.
Code change since publication. The Image.Zeros(), Image.Constant() etc. class methods now take the image size as a keyword-only size= tuple. The printed
>>> canvas = Image.Zeros(1000, 1000, dtype="uint8")
>>> K = Image.Constant(21, 21, value=1/21**2)
should be
>>> canvas = Image.Zeros(size=(1000, 1000), dtype="uint8")
>>> K = Image.Constant(value=1/21**2, size=(21, 21))
Notebook fix RVC3-python#29; cause: MVTB v2.0.0 release.
Code change since publication. With NumPy 2.0 or later np.linalg.eig() always returns complex arrays, even when the eigenvalues are real. For the symmetric matrix J use eigh, which returns real values
>>> lmbda, x = np.linalg.eigh(J)
Notebook fix RVC3-python#35; cause: NumPy 2.0 release notes.
The equation for
to match the x- and y-axis conventions shown in Fig. 13.16. That error has also been fixed in the code (pushed to GH 2025-03-02 MVTB commit 7af0aa4).
The equation for
Unfortunately, the code implementation for CatadioptricCamera.project_point() has a different error. Correcting that code error (pushed to GH 2025-03-02 MVTB commit 7af0aa4) we get an alternative version of Fig 13.20. This version exhibits much more distortion because the cube is quite close to the camera.

The Greek letters in the axis labels need raw strings, otherwise Python 3.12 reports SyntaxWarning: invalid escape sequence '\p'
>>> spherical.disp(axes=(r"$\phi$", r"$\theta$"));
Notebook fix RVC3-python#35.
The focal length is a typo, f=3045 should be f=4.25e-3 metres (it is in the same units as rho=1.4e-6). With the printed value every call to scene.fiducial() silently fails to estimate a pose
>>> camera = CentralCamera(f=4.25e-3, imagesize=scene.shape,
... pp=(2016, 1512), rho=1.4e-6);
Notebook fix RVC3-python#35.
Code change since publication. Image.paste() no longer modifies the image in place, it returns a new image. The printed calls
>>> composite.paste(images[0], (0, 0));
>>> composite.paste(tile, topleft, method="blend");
must assign the result
>>> composite = composite.paste(images[0], (0, 0));
>>> composite = composite.paste(tile, topleft, method="blend");
Notebook fix RVC3-python#35; cause: MVTB commit 9afa287 "Image immutability".
The visual odometry example processes all 251 stereo pairs, which takes several minutes. The notebook runs
>>> %run -m visodom 50
to process only the first 50 frames; omit the argument for the full sequence. Notebook change RVC3-python#45.
Code change since publication. The logged state of a clock is now the attribute .X, not .x, so
>>> plt.plot(out.clock0.t, out.clock0.X)
Notebook fix RVC3-python#45; cause: bdsim commit f7ba8b4, a refactor with no separate PR.
Code change since publication. eigdemo is now an installed command, use !eigdemo 1 2 3 4 in a notebook instead of %run -m eigdemo 1 2 3 4, or run it directly from the shell as $ eigdemo 1 2 3 4. Notebook fix RVC3-python#45; cause: RTB PR #600.
Code change since publication. Same NumPy 2.0 change as for page 498: for the symmetric matrix E use e, v = np.linalg.eigh(E), otherwise the complex result breaks the following plot_arrow() call. Notebook fix RVC3-python#35; cause: NumPy 2.0 release notes.