Supporting classes

Planner superclass

class PlannerBase(occgrid=None, inflate=0, ndims=None, start=None, goal=None, verbose=False, msgcolor='yellow', progress=True, marker=None, seed=None, animate=False, movie=None, **unused)[source]

Bases: object

Mobile robot motion planner (superclass)

Parameters:
Raises:

ValueError – ndims is not given, occgrid is not a BinaryOccupancyGrid or a 2D array, or start or goal is not of length ndims or lies inside an obstacle

Superclass for all mobile robot motion planners. Key functionality includes:

  • encapsulates an occupancy grid and optionally inflates it

  • validates start and goal if given, see validate_start_goal()

  • encapsulates a private random number generator with specifiable seed

  • encapsulates state such as start, goal, and the plan

  • provides a message channel for diagnostic output

Positions, returned paths and plot axes use world coordinates. Grid-based planners convert positions to the nearest cell centre internally, using the occupancy grid’s origin and cell size. A raw array has unit cells and origin (0, 0). Angles are in radians.

The start and goal can be specified in various ways:

  • at constructor time by the arguments start or goal

  • by assigning the attributes start or goal

  • at planning time by specifying goal to the planner’s plan method

  • at query time by specifying start to the planner’s query method

The planners do not share one call signature, since the algorithms need different things at different times. The verbs a planner has are the ones that make sense for it, and they fall into four families:

Family

Planners

Verbs

plan for a goal, then query many starts

DistanceTransformPlanner, DstarPlanner, RRTPlanner

plan(goal), query(start)

build a map of the space, then query both ends

PRMPlanner, LatticePlanner

plan(npoints) or plan(iterations), query(start, goal)

nothing to plan

DubinsPlanner, ReedsSheppPlanner, QuinticPolyPlanner, CurvaturePolyPlanner

query(start, goal)

reactive

Bug2

run(start, goal)

A planner raises ValueError for invalid arguments and NoPathError when a valid problem has no solution.

__str__()[source]

Compact representation of the planner

Returns:

pretty printed representation

Return type:

str

__repr__()[source]

Compact representation of the planner, same as __str__()

Return type:

str

property start: ndarray[Tuple[Literal[2]], dtype[floating]] | ndarray[Tuple[Literal[3]], dtype[floating]] | None

Set/get start point or configuration (superclass)

Getter:

Return start point or configuration, None if not set

Setter:

Set start point or configuration, None is ignored

Raises:

ValueError – (setter) not of length ndims, or inside an obstacle

The start is either a point \((x, y)\) or a configuration \((x, y, \theta)\).

See also

goal()

Setter accepts:

Union[List[float], Tuple[float, float], ndarray[Tuple[Literal[2]], dtype[floating]], Tuple[float, float, float], ndarray[Tuple[Literal[3]], dtype[floating]], None]

property goal: ndarray[Tuple[Literal[2]], dtype[floating]] | ndarray[Tuple[Literal[3]], dtype[floating]] | None

Set/get goal point or configuration (superclass)

Getter:

Return goal point or configuration, None if not set

Setter:

Set goal point or configuration, None is ignored

Raises:

ValueError – (setter) not of length ndims, or inside an obstacle

The goal is either a point \((x, y)\) or a configuration \((x, y, \theta)\).

See also

start()

Setter accepts:

Union[List[float], Tuple[float, float], ndarray[Tuple[Literal[2]], dtype[floating]], Tuple[float, float, float], ndarray[Tuple[Literal[3]], dtype[floating]], None]

property verbose: bool

Get verbosity

Returns:

verbosity

If verbosity print more diagnostic messages to the planner’s message channel.

property animate: bool

Get or set animation of the planner’s operation

Getter:

True if planners that can animate will do so

Setter:

Set the default for methods that take an animate argument

A movie file given to the constructor also implies animation.

property movie: str | tuple[str, float] | None

Get or set the movie file for the animation

Getter:

filename, or tuple (filename, frame interval), None for no movie

Setter:

Set the default movie file, None for no movie

animation_start(animate: bool | None = None, movie: str | tuple[str, float] | None = None, draw: Callable[[], Any] | None = None) → bool[source]

Begin an animation

Parameters:
  • animate (bool | None) – animate this call, defaults to the planner’s animate

  • movie (str | tuple[str, float] | None) – movie file for this call, defaults to the planner’s movie

  • draw (Callable[[], Any] | None) – function that draws the static background of the animation

Return type:

bool

Returns:

True if the caller should animate

The planner decides what is drawn and when, this helper owns the pacing and recording. If animating, draw is called, then the movie file if any is opened on the current figure. The caller then calls animation_frame() after updating its artists, and animation_end() when done.

A movie implies animation.

animation_frame(pause: float = 0.05) → None[source]

Show the current state of the animation

Parameters:

pause (float) – time to pause for the display to update, defaults to 0.05 s

Return type:

None

Updates the display and adds a frame to the movie, if there is one.

animation_end() → None[source]

End an animation, closing the movie file if there is one

Return type:

None

property random: Generator

Get private random number generator

Returns:

NumPy random number generator

Return type:

numpy.random.Generator

Has methods including:

The generator is initialized with the seed provided at constructor time.

random_init(seed: int | None = None) → None[source]

Initialize private random number generator

Parameters:

seed (int | None) – random number seed, defaults to value given to constructor

Return type:

None

The private random number generator is initialized. The seed is seed or the value given to the constructor. If None, the generator will be randomly seeded using a seed from the operating system.

property occgrid: BinaryOccupancyGrid | None

Occupancy grid

Returns:

occupancy grid used for planning, None if there is none

Returns the occupancy grid that was optionally inflated at constructor time.

isoccupied(p: List[float] | Tuple[float, float] | ndarray[Tuple[Literal[2]], dtype[floating]] | Tuple[float, float, float] | ndarray[Tuple[Literal[3]], dtype[floating]]) → bool[source]

Test if point is occupied (superclass)

Parameters:

p (Union[List[float], Tuple[float, float], ndarray[Tuple[Literal[2]], dtype[floating]], Tuple[float, float, float], ndarray[Tuple[Literal[3]], dtype[floating]]]) – world coordinate (x, y), or configuration (x, y, :math:` heta`)

Return type:

bool

Returns:

occupancy status of corresponding grid cell

The world coordinate is transformed and the status of the occupancy grid cell is returned. If the point lies outside the bounds of the occupancy grid return True (obstacle)

If there is no occupancy grid this function always returns False (free).

See also

occgrid() validate_endpoint() isoccupied

validate_endpoint(p: List[float] | Tuple[float, float] | ndarray[Tuple[Literal[2]], dtype[floating]] | Tuple[float, float, float] | ndarray[Tuple[Literal[3]], dtype[floating]] | None, dtype: Any = None) → ndarray[Tuple[Literal[2]], dtype[floating]] | ndarray[Tuple[Literal[3]], dtype[floating]] | None[source]

Validate start or goal point

Parameters:
Raises:

ValueError – point is of the wrong length, or is inside an obstacle

Return type:

ndarray[Tuple[Literal[2]], dtype[floating]] | ndarray[Tuple[Literal[3]], dtype[floating]] | None

Returns:

point as a NumPy array of specified dtype, None if p is None

The coordinate is tested to be a free cell in the occupancy grid.

progress_start(n: int) → None[source]

Initialize a progress bar (superclass)

Parameters:

n (int) – Number of iterations in the operation

Return type:

None

Create a progress bar for an operation that has n steps, for example:

planner.progress_start(100)
for i in range(100):
    # ...
    planner.progress_next()
planner.progress_end()

Warning

Requires that the progress package is installed.

progress_next() → None[source]

Increment a progress bar (superclass)

Advance a progress bar by one step, for example:

planner.progress_start(100)
for i in range(100):
    # ...
    planner.progress_next()
planner.progress_end()

Warning

Requires that the progress package is installed.

Return type:

None

progress_end() → None[source]

Finalize a progress bar (superclass)

Remove/cleanup a progress bar, for example:

planner.progress_start(100)
for i in range(100):
    # ...
    planner.progress_next()
planner.progress_end()

Warning

Requires that the progress package is installed.

Return type:

None

validate_start_goal(start: List[float] | Tuple[float, float] | ndarray[Tuple[Literal[2]], dtype[floating]] | Tuple[float, float, float] | ndarray[Tuple[Literal[3]], dtype[floating]] | None = None, goal: List[float] | Tuple[float, float] | ndarray[Tuple[Literal[2]], dtype[floating]] | Tuple[float, float, float] | ndarray[Tuple[Literal[3]], dtype[floating]] | None = None, dtype: Any = None) → None[source]

Validate and store the start and goal

Parameters:
Raises:

ValueError – start or goal is of the wrong length or is inside an obstacle

Return type:

None

Each given value is tested against the planner’s dimensionality and the occupancy grid, and then stored as start or goal. A value of None leaves the existing value unchanged. If either is invalid neither is stored.

plot(path: NDArray | None = None, path_style: dict[str, Any] | Sequence[dict[str, Any]] | None = None, path_reverse_style: dict[str, Any] | Sequence[dict[str, Any]] | None = None, configspace: bool = False, unwrap: bool = True, direction: ArrayLike | None = None, background: bool = True, path_marker: dict[str, Any] | Sequence[dict[str, Any]] | None = None, path_marker_reverse: dict[str, Any] | Sequence[dict[str, Any]] | None = None, start_style: dict[str, Any] | None = None, goal_style: dict[str, Any] | None = None, start_vehicle_style: dict[str, Any] | None = None, goal_vehicle_style: dict[str, Any] | None = None, start: ArrayLike2 | ArrayLike3 | None = None, goal: ArrayLike2 | ArrayLike3 | None = None, ax: Axes | None = None, block: bool | None = None, bgargs: dict[str, Any] | None = None, *, line: dict[str, Any] | Sequence[dict[str, Any]] | None = None, line_r: dict[str, Any] | Sequence[dict[str, Any]] | None = None, start_marker: dict[str, Any] | None = None, goal_marker: dict[str, Any] | None = None, start_vehicle: dict[str, Any] | None = None, goal_vehicle: dict[str, Any] | None = None, labels: bool = False, label_style: dict[str, Any] | None = None, labelvalues: bool = False, inflated: bool | None = None, colorbar: bool | dict[str, Any] | None = None, colorbar_style: dict[str, Any] | None = None, cmap: str | None = None, **unused: Any) → Axes[source]

Plot vehicle path (superclass)

Parameters:
Raises:

ValueError – configspace is True but the path is not in configuration space

Return type:

Axes

Returns:

the axes plotted into

Plots the start and goal location/pose if they are specified by start or goal or were set by the object constructor or plan or query method.

If the start and goal have length 2, planning in \(\mathbb{R}^2\), then markers are drawn using styles specified by start_style and goal_style, which are dicts using Matplotlib keywords, for example:

planner.plot(path, start_style=dict(marker='s', color='b'))

If the start and goal have length 3, planning in \(\SE{2}\), and configspace is False, then the start and goal configuration are displayed as a vehicle, using start_vehicle_style and goal_vehicle_style.

If configspace is True then a 3D plot is created and the start and goal are indicated by Matplotlib markers specified by the dicts start_style and goal_style.

Default values are provided for all styles:

  • the start point is a circle

  • the goal point is a star

  • the start vehicle style is a VehiclePolygon(shape='car') as an unfilled outline

  • the goal vehicle style is a VehiclePolygon(shape='car') as a transparent filled shape

If background is True then the background of the plot is either or both of:

  • the occupancy grid

  • the distance field of the planner

Additional arguments bgargs can be passed through to plot_bg()

If path is specified it has one column per point and either 2 or 3 rows:

  • 2 rows describes motion in the \(xy\)-plane and a 2D plot is created

  • 3 rows describes motion in the \(xy\theta\)-configuration space. By default only the \(xy\)-plane is plotted unless configspace is True in which case motion in \(xy\theta\)-configuration space is shown as a 3D plot.

If the planner supports bi-directional motion then the direction option gives the direction for each point on the path.

Forward motion segments are drawn using the layers of path_style while reverse motion segments are drawn using path_reverse_style. These are each one dict, or a sequence of dicts, of Matplotlib plot options which can draw an arbitrary number of lines on top of each other. The default:

path_style = (
        {color:'black', linewidth:4},
        {color:'yellow', linewidth:3, dashes:(5,5)}
    )

will draw a black line of width 4 with a dashed yellow line of width 3 plotted on top, giving a line of alternating black and yellow dashes. A style given by the caller replaces these layers.

Deprecated since version 1.5.0: The arguments line, line_r, path_marker, path_marker_reverse, start_marker, goal_marker, start_vehicle and goal_vehicle are deprecated, use path_style, path_reverse_style, start_style, goal_style, start_vehicle_style and goal_vehicle_style. path_marker and path_marker_reverse were accepted but had no effect.

See also

plot_bg() plot_poly

Note

Unknown keyword arguments are ignored, with a DeprecationWarning, as they were silently by RTB 1.4.4 and earlier.

Deprecated since version 1.5.0: labelvalues is deprecated, use labels. It is the name used in the book, where it had no effect.

Changed in version 1.5.0: block=False shows the figure without waiting, as documented. It used to do nothing, the same as None.

plot_bg(distance: NDArray | None = None, cmap: str = 'gray', ax: Axes | None = None, inflated: bool = True, colorbar: bool | dict[str, Any] = True, block: bool | None = None, colorbar_style: dict[str, Any] | None = None, labels: bool = False, label_style: dict[str, Any] | None = None, labelvalues: bool = False, **unused: Any) → None[source]

Plot background (superclass)

Parameters:
  • distance (ndarray | None) – override distance field, defaults to None. The array is not modified.

  • cmap (str) – Specify a colormap for the distance field, defaults to ‘gray’

  • ax (Axes | None) – axes to plot into, defaults to the current axes

  • inflated (bool) – show the inflated obstacles, defaults to True

  • colorbar (bool | dict[str, Any]) – show a colorbar for the distance field, defaults to True

  • block (bool | None) – None leaves showing the figure to the environment (no plt.show call), False shows it and returns at once, True shows it and waits until it is closed; ignored by notebook backends, defaults to None

  • colorbar_style (dict[str, Any] | None) – options for the colorbar, passed to matplotlib.figure.Figure.colorbar(), defaults to None. The label defaults to “Distance”.

  • labels (bool) – write the value in each cell of the distance field, defaults to False

  • labelvalues (bool) – deprecated, use labels

  • label_style (dict[str, Any] | None) – Matplotlib text options for the values, merged over red, centered fontsize 8 text, as in the book, with a thin white outline (path_effects) so that it is legible on any gray. The axes are set to show every cell whole.

Return type:

None

Deprecated since version 1.5.0: Giving a dict as colorbar is deprecated, use colorbar=True with colorbar_style.

Displays the background which is either the occupancy grid or a distance field. The distance field encodes the distance of a point from the goal, small distance is dark, a large distance is bright.

If the planner has an occupancy grid then that will be displayed with:
  • free cells in white

  • occupied cells in red

  • inflated occupied cells in pink

If distance is provided, or the planner has a distancemap attribute the distance field will be used as the background and obstacle cells (actual or inflated) will be shown in red. A colorbar is added.

Note

Unknown keyword arguments are ignored, with a DeprecationWarning, as they were silently by RTB 1.4.4 and earlier.

Deprecated since version 1.5.0: labelvalues is deprecated, use labels. It is the name used in the book, where it had no effect.

message(s: str, color: str | None = None) → None[source]

Print message to message channel

Parameters:
  • s (str) – message to print

  • color (str | None) – color to print it, defaults to color specified at constructor time.

Return type:

None

The message is printed only if verbose is True.

exception NoPathError[source]

A valid planning problem has no solution

Raised by a planner when the start, goal and environment are valid but there is no path between them, for example the goal is unreachable or the robot is trapped. Invalid input raises ValueError instead. This is a RuntimeError, so code that catches that continues to work.

Occupancy grid base classes

class BaseMap(workspace=None, name=None)[source]

Bases: ABC

property width: float | None

Width of the workspace in world units

Returns:

x-extent of the workspace, None if there is no workspace

property height: float | None

Height of the workspace in world units

Returns:

y-extent of the workspace, None if there is no workspace

class BaseOccupancyGrid(grid=None, origin=(0, 0), value=0, cellsize=1, workspace=None, name=None)[source]

Bases: BaseMap

copy()[source]

Copy an occupancy grid (superclass)

Return type:

Self

Returns:

copy of the occupancy grid

__repr__()[source]

Compact string description of occupancy grid, same as __str__()

Return type:

str

__str__()[source]

Compact string description of occupancy grid (superclass)

Returns:

summary of occupancy grid characteristics

Return type:

str

property grid: ndarray

Occupancy grid as a NumPy array (superclass)

Returns:

binary occupancy grid

Return type:

ndarray(N,M) of bool

If inflate has been called, this will return the inflated occupancy grid.

property xmin: float

Minimum x-coordinate of this grid (superclass)

Returns:

minimum world x-coordinate

Return type:

float

property xmax: float

Maximum x-coordinate of this grid (superclass)

Returns:

maximum world x-coordinate

Return type:

float

property ymin: float

Minimum y-coordinate of this grid (superclass)

Returns:

minimum world y-coordinate

Return type:

float

property ymax: float

Maximum y-coordinate of this grid (superclass)

Returns:

maximum world y-coordinate

Return type:

float

property shape: tuple[int, ...]

Shape of the occupancy grid array (superclass)

Returns:

shape of the occupancy grid array

Return type:

2-tuple

This is the shape of the NumPy array that holds the occupancy grid.

property maxdim: float

Maximum dimension of grid in world coordinates (superclass)

Returns:

maximum side length of the occupancy grid

Return type:

float

property cellsize: float

Cell size in world units (superclass)

Returns:

side length of a grid cell

property workspace: ndarray[Tuple[Literal[4]], dtype[floating]]

Bounds of the occupancy grid in world coordinates (superclass)

Returns:

workspace bounds [xmin, xmax, ymin, ymax]

Returns the bounds of the occupancy grid in world coordinates.

property name: str | None

Occupancy grid name (superclass)

Returns:

name of the occupancy grid

Return type:

str

set(region, value)[source]

Set region of map (superclass)

Parameters:
Return type:

None

The cells that contain the corners of the region, and all those between them, are set.

grid_to_world(p)[source]

Convert grid coordinate to world coordinate (superclass)

Parameters:

p (Union[List[float], Tuple[float, float], ndarray[Tuple[Literal[2]], dtype[floating]]]) – grid coordinate (column, row)

Return type:

ndarray[Tuple[Literal[2]], dtype[floating]]

Returns:

world coordinate (x, y)

The grid cell size and offset are used to convert occupancy grid coordinate p to a world coordinate.

g2w is a shorthand for this method.

g2w(p)

Convert grid coordinate to world coordinate (superclass)

Parameters:

p (Union[List[float], Tuple[float, float], ndarray[Tuple[Literal[2]], dtype[floating]]]) – grid coordinate (column, row)

Return type:

ndarray[Tuple[Literal[2]], dtype[floating]]

Returns:

world coordinate (x, y)

The grid cell size and offset are used to convert occupancy grid coordinate p to a world coordinate.

g2w is a shorthand for this method.

world_to_grid(p)[source]

Convert world coordinate to grid coordinate (superclass)

Parameters:

p (Union[List[float], Tuple[float, float], ndarray[Tuple[Literal[2]], dtype[floating]]]) – world coordinate (x, y)

Return type:

ndarray[Tuple[Literal[2]], dtype[floating]]

Returns:

grid coordinate (column, row)

The grid cell size and offset are used to convert p to an occupancy grid coordinate. The grid coordinate is rounded and cast to integer value. No check is made on the validity of the coordinate.

w2g is a shorthand for this method.

w2g(p)

Convert world coordinate to grid coordinate (superclass)

Parameters:

p (Union[List[float], Tuple[float, float], ndarray[Tuple[Literal[2]], dtype[floating]]]) – world coordinate (x, y)

Return type:

ndarray[Tuple[Literal[2]], dtype[floating]]

Returns:

grid coordinate (column, row)

The grid cell size and offset are used to convert p to an occupancy grid coordinate. The grid coordinate is rounded and cast to integer value. No check is made on the validity of the coordinate.

w2g is a shorthand for this method.

plot(map=None, ax=None, block=None, *, field=None, colorbar=True, colorbar_style=None, labels=False, label_style=None, cmap=None, inflated=None, **kwargs)[source]

Plot the occupancy grid (superclass)

Parameters:
  • map (ndarray | None) – array which is plotted instead of the grid, must be same size as the occupancy grid, defaults to None

  • ax (Axes | None) – Matplotlib axes to plot into, defaults to None (the current axes)

  • block (bool | None) – None leaves showing the figure to the environment (no plt.show call), False shows it and returns at once, True shows it and waits until it is closed; ignored by notebook backends, defaults to None

  • field (ndarray | None) – optional scalar field, with the same shape as the grid; obstacles are drawn over it, defaults to None

  • colorbar (bool | dict[str, Any]) – show a colorbar for the field, defaults to True

  • colorbar_style (dict[str, Any] | None) – colorbar options, with label “Distance” by default

  • labels (bool) – label finite field values at cell centres, defaults to False

  • label_style (dict[str, Any] | None) – Matplotlib text options, merged over red centred text with a white outline

  • cmap (str | Colormap | None) – colormap for the field or replacement map. Fields default to gray; replacement images use Matplotlib’s default colormap

  • inflated (ndarray | None) – inflated obstacle mask, with the same shape as the grid; additional occupied cells are drawn in pink, defaults to None

  • kwargs (Any) – arguments passed to imshow

Raises:

ValueError – an array has the wrong shape, or both map and field are supplied

Return type:

None

The grid is plotted as an image but with axes in world coordinates.

Binary grids show free space in white, obstacles in red and inflated obstacles in pink. A field is drawn beneath the obstacles, with unreachable (infinite) values in blue. General grids and replacement images are drawn using their numeric values. Passing cmap without a field overrides the grid’s colormap.

Cell centres use the grid’s origin and cell size; image edges extend half a cell beyond the outer centres. labels shows the edge cells whole. The field and supplied style dictionaries are not modified.

line_world(p1, p2)[source]

Get index of cells along a line segment (superclass)

Parameters:
Returns:

index into the raveled grid

Return type:

ndarray

Get the indices of cells along a line segment defined by the end points given in world coordinates.

The returned indices can be applied to a raveled view of the grid.

line_w is a shorthand for this method.

line_w(p1, p2)

Get index of cells along a line segment (superclass)

Parameters:
Returns:

index into the raveled grid

Return type:

ndarray

Get the indices of cells along a line segment defined by the end points given in world coordinates.

The returned indices can be applied to a raveled view of the grid.

line_w is a shorthand for this method.

property ravel: ndarray

Ravel the grid (superclass)

Returns:

1D view of the occupancy grid

Return type:

ndarray(N)