Reactive navigation

These algorithms work with an occupancy grid representation of the world. Start and goal are specified by 2D \((x, y)\) coordinates in the plane.

class Bug2(**kwargs)[source]

Bases: PlannerBase

Bug2 reactive navigator

Parameters:

kwargs (Any) – common arguments for PlannerBase superclass, in particular occgrid

Returns:

Bug2 reactive navigator

Creates an object which simulates an automaton, capable of omnidirectional motion, finding a path across an occupancy grid using only a bump sensor.

Reference:

“Path-Planning Strategies for a Point Mobile Automaton Moving Amidst Unknown Obstacles of Arbitrary Shape”, Lumelsky and Stepanov, Algorithmica (1987)2, pp.403-430

Note

This class is not a planner, even though it subclasses PlannerBase. It can produce very inefficient paths.

Author:

Kristian Gibson and Peter Corke, based on MATLAB version by Peter Corke

See also

PlannerBase

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

Get m-line

Returns:

m-line in homogeneous form, None if run() has not been called

Return type:

ndarray(3)

This is the m-line computed for the last run().

run(start: List[float] | Tuple[float, float] | ndarray[Tuple[Literal[2]], dtype[floating]] | None = None, goal: List[float] | Tuple[float, float] | ndarray[Tuple[Literal[2]], dtype[floating]] | None = None, animate: bool | None = None, pause: float = 0.001, trail: bool = True, movie: str | tuple[str, float] | None = None, label: str = 'robot path') → ndarray[source]

Find a path using Bug2 reactive navigation algorithm

Parameters:
Raises:
  • ValueError – start and goal are not both given, or lie inside an obstacle

  • NoPathError – the robot is trapped, or the goal is enclosed by an obstacle

Returns:

path from start to goal, one point per row

Return type:

ndarray

Compute the path from start to goal assuming the robot is capable of 8-way motion from its current cell to the next.

Note

start and goal are (x,y) world coordinates, rounded to cell centres using the occupancy grid’s origin and cell size. The returned path and hit points use the same world coordinates.

Changed in version 1.5.0: The robot is considered to have crossed the m-line when it is within \(\sqrt{2}/2\) cells of it, previously half a cell. A line at 45 degrees to the grid passes between two diagonal neighbours at that distance from each, and could be stepped over without being seen, so that the robot was reported as trapped. This shortens the house floorplan example, from the bedroom to the kitchen, by one point.

Changed in version 1.5.0: The robot leaves an obstacle only where the next step along the m-line is free. Previously it could leave, find the obstacle in the way, and hit it again from the same cell, so that cell appeared twice in the path, and a goal enclosed by an obstacle was never given up on. The cell where an obstacle is first hit is also no longer repeated in the path. Together these remove two repeated points at the places the robot left an obstacle blocked, and two at the first hits, so that the house floorplan example from the bedroom to the kitchen has 1302 points rather than the 1307 of earlier versions.

See also

Bug2.plot()

plot_m_line(*args: Any, **kwargs: Any) → None[source]

Plot m-line

Parameters:
  • args (Any) – positional arguments passed to plot(), for example a format string

  • kwargs (Any) – keyword arguments passed to plot()

Raises:

ValueError – there is no m-line, run() has not been called

Return type:

None

Plots the m-line on the current axes. By default it is a black dashed line.

__repr__()

Compact representation of the planner, same as __str__()

Return type:

str

__str__()

Compact representation of the planner

Returns:

pretty printed representation

Return type:

str

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.

animation_end() → None

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

Return type:

None

animation_frame(pause: float = 0.05) → None

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_start(animate: bool | None = None, movie: str | tuple[str, float] | None = None, draw: Callable[[], Any] | None = None) → bool

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.

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 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

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.

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

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.

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]

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

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.

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

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.

property verbose: bool

Get verbosity

Returns:

verbosity

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