Backends
A backend is what draws a robot, and animates it. The Toolbox talks to a backend through a small, standard interface, so the same program can show a robot in a Matplotlib window, in a notebook or in a web browser, and a new backend can be added without changing the Toolbox. A backend could equally be a simulator or a physical robot, since all the Toolbox asks of it is to display the objects it is given, and to do something when time advances.
Name |
Class |
Display |
Needs |
Teach pendant |
|---|---|---|---|---|
|
3D, in a Matplotlib window or a notebook |
nothing extra |
yes |
|
|
2D, for planar robots, in Matplotlib |
nothing extra |
yes |
|
|
|
3D, in a web browser, with meshes |
the |
yes |
“Teach pendant” in this context means a set of joint configuration sliders that allow you to control the configuration of the displayed robot using the robot’s teach() method.
Using a backend
Most of the time you don’t use a backend directly: robot.plot(q) makes one, adds the robot to it and steps it. Name the backend to choose one, or set the default for a robot or for all robots.
robot.plot(q, backend="swift") # use this backend, this time
robot.default_backend = "swift" # the default for this robot
rtb.Robot.set_default_backend("swift") # the default for all robots
With no explicit choice the robot’s own default is used, then the default for all robots. If there is none, the Toolbox picks one: "pyplot" for a DH robot, "pyplot2" for a planar robot, and for any other robot "swift" if it has geometry to show and "pyplot" if not. If Swift is not installed it falls back to "pyplot". Swift cannot yet draw a DH robot.
roboticstoolbox.backends.load_backend makes a backend from its name. To use one directly, which is what robot.plot does for you:
import roboticstoolbox as rtb
from roboticstoolbox.backends import load_backend
robot = rtb.models.DH.Panda()
backend = load_backend("pyplot") # make a backend
backend.launch() # start it with an empty scene
backend.add(robot) # add the robot to the scene
robot.q = robot.qr # set the configuration
backend.step() # update the display
backend.hold() # keep the window open
What a backend does
The backend holds a scene: the robots and other objects that it has been asked to display. It does not own them. The user’s robot object stays the source of truth, and the backend draws it, so that after robot.q = ... and step() the display agrees with the robot.
Starting and stopping.
launchstarts the display with an empty scene, which has to be done before anything is added,closeshuts it down,resetreturns to the state afterlaunch, andrestartcloses and relaunches.The scene.
add(obj)puts an object in the scene and returns an identifier, andremove(id)takes it out. The object must be of a class that the backend knows how to draw, such as a robot, or an ellipsoid if the backend supports them.Time.
step(dt)advances the scene bydtseconds, which makes each robot act according to its control type (position, velocity, acceleration or torque) and updates the display.Waiting.
holdkeeps the backend running after the script has finished, for as long as the window is open.Optional features, which a backend declares with two flags:
supports_teachis true if it can show the interactive teach pendant ofteach(), andsupports_ellipseis true if it can draw the ellipsoids made byplot_ellipse().
The contract
This is written down as the Connector protocol. A backend is any object that has these methods and flags, and does not have to inherit from it: Swift does not, since it does not depend on the Toolbox. The PyPlot backends inherit from it, which supplies the default values of the flags and makes a missing method an error when the backend is made. The arguments differ from one backend to another, so the methods are declared with *args, **kwargs, and the details are in each backend.
Launch the external program with an empty or specific scene |
|
Gracefully close the external program |
|
Reset the external program to the state defined by |
|
Close and relaunch the external program to the state defined by |
|
Add an object to the external environment |
|
Remove an object from the external environment, given its id |
|
Trigger the external program to make a time step |
|
Keep the backend open, that is stop the program from closing once the main script has finished. |
- class Connector(*args, **kwargs)[source]
What RTB needs of a graphical backend
A backend is any object that has these methods and flags: it does not have to inherit from this class. Swift does not, since it does not depend on RTB. The PyPlot backends inherit from it explicitly, which supplies the default values of the flags and of
_add_teach_panel(), and makes a missing method an error at construction.The methods take different arguments in different backends, so they are declared with
*args, **kwargs; see the backend for the details.- abstractmethod launch(*args, **kwargs)[source]
Launch the external program with an empty or specific scene
- Return type:
- abstractmethod step(*args, **kwargs)[source]
Trigger the external program to make a time step
step(dt)goes through each robot in the scene and makes them act based on their control type (position, velocity, acceleration, or torque). Upon acting, the other three of the four control types will be updated in the internal state of the robot object. The control type is defined by the robot object, and not all robot objects support all control types.- Return type:
- abstractmethod reset(*args, **kwargs)[source]
Reset the external program to the state defined by
launch()- Return type:
- abstractmethod restart(*args, **kwargs)[source]
Close and relaunch the external program to the state defined by
launch()- Return type:
- abstractmethod add(*args, **kwargs)[source]
Add an object to the external environment
id = add(object): the object must be of a class the backend knows. It is added to the list of objects which will act uponstep().- Return type:
The backends
PyPlot and PyPlot2
Both use Matplotlib, which is a common and highly portable graphics library for Python but has relatively limited 3D capability. PyPlot draws robots in 3D axes and is the default. PyPlot2 is its two-dimensional counterpart for planar robots. In a notebook they work with the inline and ipympl backends of Matplotlib.
- class PyPlot[source]
Bases:
ConnectorGraphical backend using matplotlib
matplotlib is a common and highly portable graphics library for Python, but has relatively limited 3D capability.
Example:
1import roboticstoolbox as rtb 2 3robot = rtb.models.DH.Panda() # create a robot 4 5pyplot = rtb.backends.PyPlot() # create a PyPlot backend 6pyplot.add(robot) # add the robot to the backend 7robot.q = robot.qz # set the robot configuration 8pyplot.step() # update the backend and graphical view
Note
PyPlot is the default backend, and
robot.plot(q)effectively performs lines 7-8 above.- launch(name: str | None = None, fig: Any = None, ax: Any = None, limits: ndarray | Sequence[float] | None = None, view: str | None = None, **kwargs: Any) None[source]
Launch a graphical interface
`env = launch()`creates a blank 3D matplotlib figure and returns a reference to the backend.- Parameters:
view (
str|None) –"xy","xz"or"yz"to start with a flat, axis-aligned view of that plane, seeplane_view(), or None for the usual three-dimensional view. The view is not locked, the plot can be rotated as usual.- Raises:
ValueError – if
viewis not one of those- Return type:
Optional keyword arguments
- ax
Existing Matplotlib 3D axes to render into.
- render_mode
One of
'window','notebook-widget', or'notebook-inline'. If omitted it is chosen from the environment, see_resolve_render_mode().- animation
True if frames will be stepped through in a single running cell. In a notebook with the
ipymplbackend this selects the inline mode, since anipymplfigure cannot update while the cell is running.- inline_every_n
Push one inline frame every N simulation steps (inline mode only).
- inline_format
Inline frame format:
'svg'(default) or'png'.- inline_dpi
DPI for PNG inline frames only. Ignored for SVG.
- step(dt: float = 0.05) None[source]
Update the graphical scene
- Parameters:
dt (
float) – time step in seconds, defaults to 50 (0.05 s)- Raises:
ValueError – if
dtis not greater than zero in a window, where the plot pauses fordt- Return type:
env.step(args)triggers an update of the 3D scene in the matplotlib window referenced byenv.Note
Each robot in the scene is updated based on their control type (position, velocity, acceleration, or torque).
Upon acting, the other three of the four control types will be updated in the internal state of the robot object.
The control type is defined by the robot object, and not all robot objects support all control types.
In a window the execution is blocked for the specified interval, which must be greater than zero: Matplotlib’s
pause(0)does not return, since a timeout of zero means to wait until the event loop is stopped. In a notebook there is no pause anddtof zero is fine.
Changed in version 1.5.0: In a window,
dtof zero or less raisesValueError, it used to wait for ever.
- reset() None[source]
Reset the graphical scene
env.reset()triggers a reset of the 3D scene in the matplotlib window referenced byenv. It is restored to the original state defined bylaunch().- Return type:
- restart() None[source]
Restart the graphics display
env.restart()triggers a restart of the matplotlib view referenced byenv. It is closed and relaunched to the original state defined bylaunch().- Return type:
- close() None[source]
env.close()gracefully closes the matplotlib window referenced byenv.- Return type:
- add(ob: Any, readonly: bool = False, display: bool = True, jointaxes: bool = True, jointlabels: bool = False, eeframe: bool = True, shadow: bool = True, name: bool = True, options: Any = None, q: ndarray | Sequence[float] | None = None, color: Any = None) Any[source]
Add a robot to the graphical scene
- Parameters:
ob (
Any) – The object to add to the plot (robot or ellipse)readonly (
bool) – Do not update the state of the object (i.e. display not simulate), defaults to Falsedisplay (
bool) – Display the object, defaults to Truejointaxes (
bool) – Show the joint axes of the robot with arrows, defaults to Trueeeframe (
bool) – Show the end-effector frame of the robot, defaults to Trueshadow (
bool) – Display a shadow of the robot on the x-y gound plane, defaults to Truename (
bool) – Display the name of the robot, defaults to Trueoptions (
Any) – colors and line widths, a dict of dicts that is merged over the defaults, for example{"robot": {"color": "r", "linewidth": 3}}q (
ndarray|Sequence[float] |None) – the joint coordinates to draw, by default those of the robotcolor (
Any) – the color of the robot’s line, shorthand foroptions["robot"]["color"]which it overrides
- Return type:
- Returns:
for a robot, its
RobotPlothandle, for anything else an integer id
handle = env.add(robot)adds therobotto the graphicalenvironment.
The handle is the drawing of the robot in this scene, and its
qis the pose that it draws. Ifqis given the drawing is pinned to that pose, and the same robot can be added again in another pose, each drawn where it was put;handle.q = qmoves only that drawing. Ifqis not given the drawing followsrobot.q, as it has always done.Changed in version 1.5.0: Added
qandcolor, and a robot now returns its plot handle, not an integer id, which nothing could use.Note
robotmust be of an appropriate class.Adds the robot object to a list of robots which will be updated when the
step()method is called.
- remove(id: int) None[source]
Remove a robot or shape from the graphical scene
- Parameters:
- Raises:
ValueError – Figure number must be between 0 and total number of canvases
TypeError – Input must be a DHLink or GraphicalRobot
- Return type:
env.remove(robot)removes therobotfrom the graphicalenvironment.
- class PyPlot2[source]
Bases:
Connector- launch(name: Any = None, limits: Any = None, **kwargs: Any) None[source]
env = launch() launches a blank 2D matplotlib figure
Optional keyword arguments
- render_mode
One of
'window','notebook-widget', or'notebook-inline'. If omitted it is chosen from the environment.- animation
True if frames will be stepped through in a single running cell, which selects the inline mode for the
ipymplbackend.- inline_every_n
Push one inline frame every N simulation steps (inline mode only).
- inline_format
Inline frame format:
'svg'(default) or'png'.- inline_dpi
DPI for PNG inline frames only. Ignored for SVG.
- Return type:
- step(dt: float = 0.05) None[source]
state = step(args) triggers the external program to make a time step of defined time updating the state of the environment as defined by the robot’s actions.
The will go through each robot in the list and make them act based on their control type (position, velocity, acceleration, or torque). Upon acting, the other three of the four control types will be updated in the internal state of the robot object. The control type is defined by the robot object, and not all robot objects support all control types.
- Parameters:
dt (
float) – time step in seconds, which must be greater than zero in a window, where the plot pauses fordt; in a notebook there is no pause- Raises:
ValueError – if
dtis not greater than zero in a window: Matplotlib’spause(0)does not return, since a timeout of zero means to wait until the event loop is stopped- Return type:
- reset() None[source]
state = reset() triggers the external program to reset to the original state defined by launch
- Return type:
- restart() None[source]
state = restart() triggers the external program to close and relaunch to thestate defined by launch
- Return type:
- add(ob: Any, readonly: bool = False, display: bool = True, eeframe: bool = True, name: bool = False, q: Any = None, **kwargs: Any) Any[source]
handle = add(robot) adds the robot to the external environment. robot must be of an appropriate class. This adds a robot object to a list of robots which will act upon the step() method being called.
If
qis given the drawing of the robot is pinned to that pose, and the same robot can be added again in another pose; the handle that is returned is the drawing, andhandle.q = qmoves only that drawing. Otherwise it followsrobot.q. An ellipse has no handle.- Return type:
- remove() None[source]
id = remove(robot) removes the robot to the external environment.
- Return type:
Swift
Swift is a separate package which supports the backend contract, and is installed by the swift extra. It shows the robot in a web browser, with its meshes, and the teach pendant as a panel of sliders. It does not draw ellipsoids.
Swift is a web page served by the Python process, and plot() works out how to show it:
In a script it opens a browser window.
browser="chrome","firefox"or"safari"on macOS,"google-chrome"or"chromium"on Linux, or a command line with%sfor any other browser, chooses the browser; the names are those of Python’s webbrowser module, which depend on the operating system, andwebbrowser.get(name)tells you whether one works on your machine. The default is the system’s browser. Seeswift.Swift.Swift.launch().In a notebook it is shown in a frame of the cell, so the same
robot.plot(q)works whichever you use.notebook=Trueasks for this explicitly, andnotebook=Falsefor a window even in a notebook. The browser that shows the notebook must be on the machine running the kernel, since the frame points atlocalhost.browser="notebook", the old way, is deprecated.A trajectory is animated in real time, one step to each
dt. Swift draws at most 60 frames per second and skips a step that comes sooner, sorealtime=Falsewould show only the first frame of a trajectory.
Changed in version 1.5.0: In a notebook Swift is shown in the cell and not in a browser window, and a trajectory is animated. notebook= is new.