Skip to content

fix(mobile): make PurePursuit usable; rst docstrings and shaped types in drivers.py - #772

Merged
petercorke merged 5 commits into
mainfrom
bug/mobile-drivers
Oct 15, 2026
Merged

petercorke merged 5 commits into
mainfrom
bug/mobile-drivers

Conversation

@petercorke

@petercorke petercorke commented Oct 14, 2026 •

Copy link
Copy Markdown
Owner

What

PurePursuit in mobile/drivers.py could not run at all. This PR fixes it, and brings the whole file up to the project's docstring and typing standard.

Bugs fixed (problem-list entries 1-3)

  • PurePursuit.demand() read self._waypoint_marker, which was never assigned: AttributeError on the first call.
  • PurePursuit.init(ax) crashed with the default linemarkerstyle=None.
  • PurePursuit.__str__ crashed when there was no workspace.
  • __str__ of both drivers printed the x range as the y range.

Design

  • The base class owns a single goal marker, created by _init_goal_marker() and moved by driveto() on every cycle, so RandomPath and PurePursuit share code and style. It moves; it does not leave a trail.
  • PurePursuit draws its path as one line, styled by the new path_style argument (default: the look used in the book figures). linemarkerstyle never worked, so nothing can depend on it and it is replaced without an alias. No per-waypoint markers, because a path from a trajectory generator is dense.
  • path is converted to a float 2xN array and validated (ValueError otherwise). A comment notes this belongs in spatialmath's getmatrix(): getmatrix() rejects a list of lists; revisit the base.X matrix/vector converters rai-opensource/spatialmath-python#255.

Naming and deprecation

  • Style dicts are <thing>_style: goal_style (base class) and path_style (PurePursuit). goalmarkerstyle is deprecated: it still works, warns with DeprecationWarning and maps to goal_style.
  • The defaults are module constants GOAL_STYLE and PATH_STYLE; a user dict is merged over them (DEFAULT | user, the user's values win).
  • The same convention for the rest of mobile is a separate change.

Typing and docstrings

  • Arguments and returns use spatialmath's Points2, ArrayLike2 and R2, since the names tell the reader what the shape is.
  • All docstrings are reST; the leftover MATLAB-style docstring and comments are gone; :type: is kept only where shape adds information.

Testing

  • Five new tests in DriversTest (path validation, __str__, a run without animation, the moving goal marker, the RandomPath goal marker). Four of them fail on main and pass here; the RandomPath marker test passes on both and guards the refactor.
  • mypy clean (163 files).

🤖 Generated with Claude Code

petercorke and others added 3 commits October 15, 2026 07:03
… in drivers.py

PurePursuit could not run at all: demand() read self._waypoint_markers that was
never assigned, init() crashed with the default linemarkerstyle=None, and
__str__ crashed with no workspace.  Now:

- waypoint markers are created in init() when an axes is given, one per
  waypoint, with the current goal highlighted in red
- linemarkerstyle defaults to a thin dashed line; new waypointmarkerstyle
- path is converted to a float 2xN array and validated (ValueError otherwise);
  note in the code that this belongs in spatialmath getmatrix(), see
  spatialmath-python#255
- __str__ printed the x range as the y range, for both drivers
- argument/return types use spatialmath's Points2, ArrayLike2 and R2
- every docstring is reST (the MATLAB-style demand() docstring and comments
  are gone), :type: kept only where shape adds information

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…Pursuit

Drawing a marker per waypoint is wrong for a dense path from a trajectory
generator.  Instead the base class owns a single goal marker that driveto()
moves each cycle, so RandomPath and PurePursuit share the same code and style.
PurePursuit draws its path as one line, linemarkerstyle becomes pathstyle
(defaulting to the style used in the book figures).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@codacy-production

codacy-production Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 13 complexity · 0 duplication

Metric Results
Complexity 13
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@codecov

codecov Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 29 lines in your changes missing coverage. Please review.
✅ Project coverage is 0.00%. Comparing base (f28437f) to head (9feaa7e).

Files with missing lines Patch % Lines
src/roboticstoolbox/mobile/drivers.py 0.00% 29 Missing ⚠️
Additional details and impacted files
@@          Coverage Diff          @@
##            main    #772   +/-   ##
=====================================
  Coverage   0.00%   0.00%           
=====================================
  Files        143     143           
  Lines      14667   14667           
=====================================
  Misses     14667   14667           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

…almarkerstyle

Style dict arguments are named <thing>_style.  The defaults are the module
constants GOAL_STYLE and PATH_STYLE and a user dict is merged over them with
the dict union operator, user values winning.  goalmarkerstyle still works,
with a DeprecationWarning, and is mapped to goal_style.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant