Simulation-user API
This section describes the public API for users of bdsim. This is the API that is
intended to be stable and supported across versions. It includes the classes and methods
that are used to build and simulate block diagrams.
BlockDiagram class
This class describes a block diagram, a collection of blocks and wires that
can be “executed” by BDSim.run().
- class bdsim.BlockDiagram(name='main', **kwargs)[source]
Bases:
BlockDiagramMixinBlock diagram class. This object is the parent of all blocks and wires in the system.
- Variables:
wirelist (list of Wire instances) – all wires in the diagram
blocklist (list of Block subclass instances) – all blocks in the diagram
x (np.ndarray) – state vector
compiled (bool) – diagram has successfully compiled
blockcounter (defaultdict of itertools.count) – unique counter for each block type
blockdict (dict of lists) – index of all blocks by category
name (str) – name of this diagram
This object:
holds all the blocks and wires that comprise the system
manages continuous- and discrete-time state vector for the whole system, splitting it across blocks as required
evaluates the entire diagram as a function to compute
dot{x} = f(x, t)()
- compile(subsystem=False, doimport=True, evaluate=True, report=False, verbose=False)[source]
Compile the block diagram
- Parameters:
- Raises:
RuntimeError – various block diagram errors
- Returns:
Compile status
- Return type:
Performs a number of operations:
Check sanity of block parameters
Recursively clone and import subsystems
Check for loops without dynamics
Check for inputs driven by more than one wire
Check for unconnected inputs and outputs
Link all output ports to outgoing wires
Link all input ports to incoming wires
Evaluate all blocks in the network
- connect(start, *ends, name=None)[source]
Connect blocks
- Parameters:
- Return type:
Connect blocks together. The start block can be connected to one or more end blocks.
Blocks are added to the block diagram’s
blocklistif they are not already part of it.The wires are added to the diagram’s
wirelist, but the connections are not actually made until compile time. Thewirelistis a list of things that will be connected later.
- dotfile(filename, shapes=None)[source]
Write a GraphViz dot file representing the network.
- Parameters:
- Return type:
Create a GraphViz format file for procesing by
dot. The graph is:directed graph, drawn left to right
source blocks are in the first column
sink and graphics blocks are in the last column
SUMandPRODblocks have the sign or operation of their input wires labeled.
The file can be processed using
dot:% dot -Tpng -o out.png dotfile.dot
Note
By default all blocks have the default shape, with source blocks shown as a rectangle (“record”), and sink/graphics blocks as a rounded rectangle (“Mrecord”). This can be overriden by provide a dictionary
shapesthat maps block class (sink, source, graphics, function, transfer) to the names of GraphViz shapes.- Seealso:
- report_lists(**kwargs)[source]
Print a tabular report about the block diagram.
- Parameters:
kwargs (dict) – options passed to
ansitable.table.ANSIMatrix.print()- Return type:
Print the important lists in pretty format.
block list, all blocks
wire list, all wires
clock list, all discrete time clocks
- report_summary(sortby='name', depth=None, **kwargs)[source]
Print a summary of block diagram.
- Parameters:
sortby (str, optional) – sort rows by specified block attribute: “name” [default] or “type”
depth (int, optional) – only show blocks with subsystem depth less than or equal to this value, defaults to None (show all)
kwargs (dict) – options passed to
ansitable.table.ANSIMatrix.print()
- Return type:
Print a table with 4 columns:
Block name, sorted in alphabetical order
The input port (if not a source block)
The block driving this port (if not a source block)
The type of value driving this port (if not a source block)
If the block is an event source, add a
@suffix.
BDSim class
This class describes the run-time environment for executing a block diagram.
- class bdsim.BDSim(banner=True, packages=None, load=True, toolboxes=True, **kwargs)[source]
Bases:
Runner- __init__(banner=True, packages=None, load=True, toolboxes=True, **kwargs)[source]
- Parameters:
banner (bool, optional) – display docstring banner, defaults to True
packages (str) – colon-separated list of folders to search for blocks
load (bool,optional) – dynamically load blocks from libraries, defaults to True
sysargs (bool, optional) – process options from sys.argv, defaults to True
graphics (bool, optional) – enable graphics, defaults to True
animation (bool, optional) – enable animation, defaults to False
progress (bool, optional) – enable progress bar, defaults to True
debug (str, optional) – debug options, defaults to None
backend (str, optional) – matplotlib backend, defaults to ‘Qt5Agg’
tiles (str, optional) – figure tile layout on monitor, defaults to None
- Raises:
ImportError – syntax error in block
- Returns:
parent object for blockdiagram simulation
- Return type:
If
sysargsis True, process command line arguments and passed options. Command line arguments have precedence.Note
animationandgraphicsoptions are coupled. Ifgraphics=False, all graphics is suppressed. Ifgraphics=Truethen graphics are shown and the behaviour depends onanimation.animation=Falseshows graphs at the end of the simulation, whileanimation=Truewill animate the graphs during simulation.- Seealso:
- property block_library: dict[str, dict[str, Any]]
Read-only view of the loaded block registry, excluding deprecated blocks.
Returns a dict keyed by upper-case block name (e.g.
"GAIN"). Each value is a metadata dict with keys:path,classname,url,class,module,package,params,inputs,outputs,nin,nout,blockclass.Deprecated blocks (decorated with
deprecated_block()) are excluded so they don’t appear in editor menus. They remain in the internal registry and are still accessible as factory methods on aBlockDiagram.
- blockdiagram(name='main')[source]
Instantiate a new block diagram object.
- Parameters:
name (str, optional) – diagram name, defaults to ‘main’
- Returns:
parent object for blockdiagram
- Return type:
This object describes the connectivity of a set of blocks and wires.
It is an instantiation of the
BlockDiagramclass with a factory method for every dynamically loaded block which returns an instance of the block. These factory methods have names which are all upper case, for example, the method.GAINinvokes the constructor for theGainclass.- Seealso:
- blocks()[source]
List all loaded blocks.
Example:
73 blocks loaded bdsim.blocks.functions..................: SUM PROD GAIN CLIP FUNCTION INTERPOLATE bdsim.blocks.sources....................: CONSTANT TIME WAVEFORM PIECEWISE STEP RAMP bdsim.blocks.sinks......................: PRINT STOP NULL WATCH bdsim.blocks.continuous.................: INTEGRATOR POSEINTEGRATOR LTI_SS LTI_SISO bdsim.blocks.sampled....................: ZOH INTEGRATOR_S POSEINTEGRATOR_S bdsim.blocks.linalg.....................: INVERSE TRANSPOSE NORM FLATTEN SLICE2 SLICE1 DET COND bdsim.blocks.displays...................: SCOPE SCOPEXY SCOPEXY1 bdsim.blocks.connections................: ITEM DICT MUX DEMUX INDEX SUBSYSTEM INPORT OUTPORT roboticstoolbox.blocks.arm..............: FKine IKine Jacobian Tr2Delta Delta2Tr Point2Tr TR2T FDyn IDyn Gravload ........................................: Inertia Inertia_X FDyn_X ArmPlot Traj JTraj LSPB CTraj CirclePath roboticstoolbox.blocks.mobile...........: Bicycle Unicycle DiffSteer VehiclePlot roboticstoolbox.blocks.uav..............: MultiRotor MultiRotorMixer MultiRotorPlot machinevisiontoolbox.blocks.camera......: Camera Visjac_p EstPose_p ImagePlane
- Return type:
- done(bd, block=False)[source]
Enter the matplotlib event loop and clean up after simulation.
Called after
run()to allow interactive use of displayedSCOPEfigures. If theholdoption is set (the default), this blocks until the user closes all figure windows; otherwise it returns immediately after flushing pending GUI events.- Parameters:
bd (BlockDiagram) – block diagram whose blocks are to be finalised
block (bool, optional) – if
True, block until all figures are closed; ifFalse, flush events and return immediately. Overridden bysim.options.hold.
- Return type:
Note
This method can be called after
run()has returned (i.e. outside the simulation context) — for example when the script callssim.run(..., block=False)and then does post-processing before handing control back to the user. In that case theholdoption is read fromsim.optionsdirectly.
- report(bd, type='summary', **kwargs)[source]
Print block diagram report
- Parameters:
bd (
BlockDiagram) – the block diagram to be reportedtype (str, optional) – report type, one of: “summary” (default), “lists”, “schedule”
style (str) – table style, one of: ansi (default), markdown, latex
- Return type:
Single method wrapper for various block diagram reports. Obeys the
-qoption to suppress all reports at runtime.- Seealso:
BlockDiagram.report_summary()BlockDiagram.report_lists()BlockDiagram.report_schedule()
- run(bd, T=5, dt=None, max_step=None, solver='RK45', solver_args=None, debug='', block=None, checkfinite=True, minstepsize=1e-12, watch=None, threaded=False)[source]
Run a compiled block diagram.
- Parameters:
T (float, optional) – simulation horizon, defaults to 5
dt (float, optional) – output sample interval; used to build a
t_evalgrid forsolve_ivpso results are recorded at uniform stepsmax_step (float, optional) – maximum integration step passed to solve_ivp
solver (str, optional) – solve_ivp method name, defaults to
RK45solver_args (dict) – extra keyword arguments for
scipy.integrate.solve_ivpdebug (str, optional) – debug flags string (see below), defaults to
''block (bool) – matplotlib block-at-end behaviour, default False
checkfinite (bool) – error if inf or nan on any wire, default True
minstepsize (float) – minimum step length guard, default 1e-12
watch (list, optional) – list of signals to log (see below)
threaded (bool, optional) – run in a worker thread (disables graphics), default False
- Returns:
simulation results container
- Return type:
The system is simulated from time 0 to
T.The integration backend is always
scipy.integrate.solve_ivp. Thesolverargument selects the method (e.g.RK45,DOP853,Radau,BDF,LSODA). Finer control — tolerances, first step, etc. — can be passed viasolver_args.The output
dtcontrols the time resolution of logged output. When given,solve_ivpis called with a matchingt_evalgrid so thatout.tcontains uniformly-spaced points. If omitted,solve_ivpchooses its own internal steps and all accepted points are recorded.Results are returned in a
BDStructwith attributes:t— time vector: ndarray, shape=(M,)x— continuous state matrix: ndarray, shape=(M,N)xnames— list of state names corresponding to columns ofx, e.g."plant.x0"(set via the block’ssnamesargument)clockN—BDStructfor each clock (clock0,clock1, …) with sub-attributestandxholding the discrete time history; a legacy alias using the clock’s name is also added when possibleyN— logged signal for the N-th entry inwatchynames— list of names of the watched ports, same order aswatch.stats—BDStructwith integration statistics:integration_time_points,run_interval_calls,ydot_calls,integrator_wall_time,events_detected_total,events_detected_by_source
The
watchargument is a list of one or more signals whose value during simulation will be recorded. Each element can be:a
Blockreference, interpreted as output port 0a
Plugreference (block with port index)a string of the form
"blockname[i]"— port i of the named block
The
debugstring contains single-character flags:'p'— trace network value propagation's'— trace state vector'd'— trace state derivative'i'— interactive step-by-step debugger
Note
Simulation stops if the step size falls below
minstepsize, which typically indicates the solver is struggling with a very stiff or discontinuous system.
BDStruct class
This class is a struct-like container for storing simulation data. It is
returned by BDSim.run() and contains the time vector, state history, and any watched variables.
- class bdsim.BDStruct(name='BDStruct2', **kwargs)[source]
Bases:
UserDictA simple data container object that allows items to be added by attribute or by index.
For example:
>>> d = BDStruct('thing') >>> d.foo = 1 >>> d.foo 1 >>> d["foo"] ] >>> d["bar"] = 2 >>> d.bar >>> d bar = 2 (int) foo = 1 (int)
- __str__()[source]
Display struct as a string
- Returns:
struct in indented string format
- Return type:
The struct is rendered with one line per element, and substructures are indented. Keys whose names start with ‘.’ are hidden (internal metadata fields).
Developer API
This section describes the internal API for developers of bdsim. This includes
classes and methods that are used internally by the library, and may not be stable or
supported across versions. It is intended for developers who want to understand or
modify the internals of bdsim.
This class describes the run-time environment for executing a block diagram.
- class bdsim.BDSim(banner=True, packages=None, load=True, toolboxes=True, **kwargs)[source]
Bases:
Runner- __init__(banner=True, packages=None, load=True, toolboxes=True, **kwargs)[source]
- Parameters:
banner (bool, optional) – display docstring banner, defaults to True
packages (str) – colon-separated list of folders to search for blocks
load (bool,optional) – dynamically load blocks from libraries, defaults to True
sysargs (bool, optional) – process options from sys.argv, defaults to True
graphics (bool, optional) – enable graphics, defaults to True
animation (bool, optional) – enable animation, defaults to False
progress (bool, optional) – enable progress bar, defaults to True
debug (str, optional) – debug options, defaults to None
backend (str, optional) – matplotlib backend, defaults to ‘Qt5Agg’
tiles (str, optional) – figure tile layout on monitor, defaults to None
- Raises:
ImportError – syntax error in block
- Returns:
parent object for blockdiagram simulation
- Return type:
If
sysargsis True, process command line arguments and passed options. Command line arguments have precedence.Note
animationandgraphicsoptions are coupled. Ifgraphics=False, all graphics is suppressed. Ifgraphics=Truethen graphics are shown and the behaviour depends onanimation.animation=Falseshows graphs at the end of the simulation, whileanimation=Truewill animate the graphs during simulation.- Seealso:
- property block_library: dict[str, dict[str, Any]]
Read-only view of the loaded block registry, excluding deprecated blocks.
Returns a dict keyed by upper-case block name (e.g.
"GAIN"). Each value is a metadata dict with keys:path,classname,url,class,module,package,params,inputs,outputs,nin,nout,blockclass.Deprecated blocks (decorated with
deprecated_block()) are excluded so they don’t appear in editor menus. They remain in the internal registry and are still accessible as factory methods on aBlockDiagram.
- blockdiagram(name='main')[source]
Instantiate a new block diagram object.
- Parameters:
name (str, optional) – diagram name, defaults to ‘main’
- Returns:
parent object for blockdiagram
- Return type:
This object describes the connectivity of a set of blocks and wires.
It is an instantiation of the
BlockDiagramclass with a factory method for every dynamically loaded block which returns an instance of the block. These factory methods have names which are all upper case, for example, the method.GAINinvokes the constructor for theGainclass.- Seealso:
- blockinfo(block=None)[source]
Return info about all blocks. :rtype:
AnyDeprecated since version Use:
block_libraryinstead.sim.blockinfo()is equivalent tosim.block_library;sim.blockinfo(name)is equivalent tosim.block_library[name].
- blocks()[source]
List all loaded blocks.
Example:
73 blocks loaded bdsim.blocks.functions..................: SUM PROD GAIN CLIP FUNCTION INTERPOLATE bdsim.blocks.sources....................: CONSTANT TIME WAVEFORM PIECEWISE STEP RAMP bdsim.blocks.sinks......................: PRINT STOP NULL WATCH bdsim.blocks.continuous.................: INTEGRATOR POSEINTEGRATOR LTI_SS LTI_SISO bdsim.blocks.sampled....................: ZOH INTEGRATOR_S POSEINTEGRATOR_S bdsim.blocks.linalg.....................: INVERSE TRANSPOSE NORM FLATTEN SLICE2 SLICE1 DET COND bdsim.blocks.displays...................: SCOPE SCOPEXY SCOPEXY1 bdsim.blocks.connections................: ITEM DICT MUX DEMUX INDEX SUBSYSTEM INPORT OUTPORT roboticstoolbox.blocks.arm..............: FKine IKine Jacobian Tr2Delta Delta2Tr Point2Tr TR2T FDyn IDyn Gravload ........................................: Inertia Inertia_X FDyn_X ArmPlot Traj JTraj LSPB CTraj CirclePath roboticstoolbox.blocks.mobile...........: Bicycle Unicycle DiffSteer VehiclePlot roboticstoolbox.blocks.uav..............: MultiRotor MultiRotorMixer MultiRotorPlot machinevisiontoolbox.blocks.camera......: Camera Visjac_p EstPose_p ImagePlane
- Return type:
- done(bd, block=False)[source]
Enter the matplotlib event loop and clean up after simulation.
Called after
run()to allow interactive use of displayedSCOPEfigures. If theholdoption is set (the default), this blocks until the user closes all figure windows; otherwise it returns immediately after flushing pending GUI events.- Parameters:
bd (BlockDiagram) – block diagram whose blocks are to be finalised
block (bool, optional) – if
True, block until all figures are closed; ifFalse, flush events and return immediately. Overridden bysim.options.hold.
- Return type:
Note
This method can be called after
run()has returned (i.e. outside the simulation context) — for example when the script callssim.run(..., block=False)and then does post-processing before handing control back to the user. In that case theholdoption is read fromsim.optionsdirectly.
- fatal(message, retval=1)[source]
Fatal simulation error
- Parameters:
- Return type:
Display the error message then terminate the process. For operating systems that support it, return an integer code.
- load_blocks(verbose=True, toolboxes=True)[source]
Dynamically load all block definitions.
- Raises:
ImportError – module could not be imported
- Returns:
dictionary of block metadata
- Return type:
Reads blocks from .py files found in bdsim/bdsim/blocks, folders given by colon separated list in envariable BDSIMPATH, and the command line option
packages.The result is a dict indexed by the upper-case block name with elements: -
pathto the folder holding the Python file defining the block -classname-blockname, upper case version ofclassname-urlof online documentation for the block -packagecontaining the block - doc is the docstring from the class constructor
- report(bd, type='summary', **kwargs)[source]
Print block diagram report
- Parameters:
bd (
BlockDiagram) – the block diagram to be reportedtype (str, optional) – report type, one of: “summary” (default), “lists”, “schedule”
style (str) – table style, one of: ansi (default), markdown, latex
- Return type:
Single method wrapper for various block diagram reports. Obeys the
-qoption to suppress all reports at runtime.- Seealso:
BlockDiagram.report_summary()BlockDiagram.report_lists()BlockDiagram.report_schedule()
- run(bd, T=5, dt=None, max_step=None, solver='RK45', solver_args=None, debug='', block=None, checkfinite=True, minstepsize=1e-12, watch=None, threaded=False)[source]
Run a compiled block diagram.
- Parameters:
T (float, optional) – simulation horizon, defaults to 5
dt (float, optional) – output sample interval; used to build a
t_evalgrid forsolve_ivpso results are recorded at uniform stepsmax_step (float, optional) – maximum integration step passed to solve_ivp
solver (str, optional) – solve_ivp method name, defaults to
RK45solver_args (dict) – extra keyword arguments for
scipy.integrate.solve_ivpdebug (str, optional) – debug flags string (see below), defaults to
''block (bool) – matplotlib block-at-end behaviour, default False
checkfinite (bool) – error if inf or nan on any wire, default True
minstepsize (float) – minimum step length guard, default 1e-12
watch (list, optional) – list of signals to log (see below)
threaded (bool, optional) – run in a worker thread (disables graphics), default False
- Returns:
simulation results container
- Return type:
The system is simulated from time 0 to
T.The integration backend is always
scipy.integrate.solve_ivp. Thesolverargument selects the method (e.g.RK45,DOP853,Radau,BDF,LSODA). Finer control — tolerances, first step, etc. — can be passed viasolver_args.The output
dtcontrols the time resolution of logged output. When given,solve_ivpis called with a matchingt_evalgrid so thatout.tcontains uniformly-spaced points. If omitted,solve_ivpchooses its own internal steps and all accepted points are recorded.Results are returned in a
BDStructwith attributes:t— time vector: ndarray, shape=(M,)x— continuous state matrix: ndarray, shape=(M,N)xnames— list of state names corresponding to columns ofx, e.g."plant.x0"(set via the block’ssnamesargument)clockN—BDStructfor each clock (clock0,clock1, …) with sub-attributestandxholding the discrete time history; a legacy alias using the clock’s name is also added when possibleyN— logged signal for the N-th entry inwatchynames— list of names of the watched ports, same order aswatch.stats—BDStructwith integration statistics:integration_time_points,run_interval_calls,ydot_calls,integrator_wall_time,events_detected_total,events_detected_by_source
The
watchargument is a list of one or more signals whose value during simulation will be recorded. Each element can be:a
Blockreference, interpreted as output port 0a
Plugreference (block with port index)a string of the form
"blockname[i]"— port i of the named block
The
debugstring contains single-character flags:'p'— trace network value propagation's'— trace state vector'd'— trace state derivative'i'— interactive step-by-step debugger
Note
Simulation stops if the step size falls below
minstepsize, which typically indicates the solver is struggling with a very stiff or discontinuous system.
- savefig(block, filename=None, format='pdf', **kwargs)[source]
Save the figure from a single graphics block to a file.
- Parameters:
block (GraphicsBlock) – graphics block whose figure is to be saved
filename (str, optional) – output filename without extension; defaults to the block’s name
format (str, optional) – image format passed to
matplotlib.Figure.savefig, defaults to'pdf'kwargs (
Any) – additional keyword arguments forwarded to the block’ssavefigmethod
- Return type:
- savefigs(bd, format='pdf', **kwargs)[source]
Save figures from all graphics blocks in a block diagram.
Iterates over every block in bd and calls
savefigon eachGraphicsBlock, using the block’s name as the filename stem.- Parameters:
bd (BlockDiagram) – compiled block diagram
format (str, optional) – image format passed to
matplotlib.Figure.savefig, defaults to'pdf'kwargs (
Any) – additional keyword arguments forwarded to each block’ssavefigmethod
- Return type:
- set_globals(globs)[source]
Set globals as specified by command line
The command line option
--global var=valuecan be used to request the change of global variables. However, actually changing them requires explicit code support in the user’s program after theBDSimconstructor.Example:
sim.set_globals(globals())
Messages are displayed by defaulting, indicating which variables are changed, and their old and new values.
- showgraph(bd, **kwargs)[source]
Display the block diagram as a graph in the system browser.
Renders the block diagram to a Graphviz DOT file, converts it to PDF using
dot, and opens the result in the default browser. Requires Graphviz to be installed anddotto be onPATH.- Parameters:
bd (BlockDiagram) – compiled block diagram to render
kwargs (
Any) – additional keyword arguments forwarded toBlockDiagram.dotfile()
- Return type:
- update_parameters(bd)[source]
Set value of parameters according to command line arguments
Command line arguments of the form: :rtype:
None-s block:param=value--set block:param=valueare stored as list items in
options.setparamblockcan be either:the block’s name as a string, either user assigned or bdsim assigned
the block
idas displayed by thereportmethod
paramis the name of the parameter used in the constructorvalueis the new value of the variable
- class bdsim.BDStruct(name='BDStruct2', **kwargs)[source]
Bases:
UserDictA simple data container object that allows items to be added by attribute or by index.
For example:
>>> d = BDStruct('thing') >>> d.foo = 1 >>> d.foo 1 >>> d["foo"] ] >>> d["bar"] = 2 >>> d.bar >>> d bar = 2 (int) foo = 1 (int)
This class describes a block diagram, a collection of blocks and wires that can be “executed”.
- class bdsim.BlockDiagram(name='main', **kwargs)[source]
Bases:
BlockDiagramMixinBlock diagram class. This object is the parent of all blocks and wires in the system.
- Variables:
wirelist (list of Wire instances) – all wires in the diagram
blocklist (list of Block subclass instances) – all blocks in the diagram
x (np.ndarray) – state vector
compiled (bool) – diagram has successfully compiled
blockcounter (defaultdict of itertools.count) – unique counter for each block type
blockdict (dict of lists) – index of all blocks by category
name (str) – name of this diagram
This object:
holds all the blocks and wires that comprise the system
manages continuous- and discrete-time state vector for the whole system, splitting it across blocks as required
evaluates the entire diagram as a function to compute
dot{x} = f(x, t)()
- compile(subsystem=False, doimport=True, evaluate=True, report=False, verbose=False)[source]
Compile the block diagram
- Parameters:
- Raises:
RuntimeError – various block diagram errors
- Returns:
Compile status
- Return type:
Performs a number of operations:
Check sanity of block parameters
Recursively clone and import subsystems
Check for loops without dynamics
Check for inputs driven by more than one wire
Check for unconnected inputs and outputs
Link all output ports to outgoing wires
Link all input ports to incoming wires
Evaluate all blocks in the network
- connect(start, *ends, name=None)[source]
Connect blocks
- Parameters:
- Return type:
Connect blocks together. The start block can be connected to one or more end blocks.
Blocks are added to the block diagram’s
blocklistif they are not already part of it.The wires are added to the diagram’s
wirelist, but the connections are not actually made until compile time. Thewirelistis a list of things that will be connected later.
- dotfile(filename, shapes=None)[source]
Write a GraphViz dot file representing the network.
- Parameters:
- Return type:
Create a GraphViz format file for procesing by
dot. The graph is:directed graph, drawn left to right
source blocks are in the first column
sink and graphics blocks are in the last column
SUMandPRODblocks have the sign or operation of their input wires labeled.
The file can be processed using
dot:% dot -Tpng -o out.png dotfile.dot
Note
By default all blocks have the default shape, with source blocks shown as a rectangle (“record”), and sink/graphics blocks as a rounded rectangle (“Mrecord”). This can be overriden by provide a dictionary
shapesthat maps block class (sink, source, graphics, function, transfer) to the names of GraphViz shapes.- Seealso:
- report_lists(**kwargs)[source]
Print a tabular report about the block diagram.
- Parameters:
kwargs (dict) – options passed to
ansitable.table.ANSIMatrix.print()- Return type:
Print the important lists in pretty format.
block list, all blocks
wire list, all wires
clock list, all discrete time clocks
- report_summary(sortby='name', depth=None, **kwargs)[source]
Print a summary of block diagram.
- Parameters:
sortby (str, optional) – sort rows by specified block attribute: “name” [default] or “type”
depth (int, optional) – only show blocks with subsystem depth less than or equal to this value, defaults to None (show all)
kwargs (dict) – options passed to
ansitable.table.ANSIMatrix.print()
- Return type:
Print a table with 4 columns:
Block name, sorted in alphabetical order
The input port (if not a source block)
The block driving this port (if not a source block)
The type of value driving this port (if not a source block)
If the block is an event source, add a
@suffix.
Wire
- class bdsim.Wire(start, end, name=None)[source]
Bases:
objectCreate a wire.
- Parameters:
- Returns:
A wire object
- Return type:
A Wire object connects two block ports. A Wire has a reference to the start and end ports.
A wire records all the connections defined by the user. At compile time wires are used to build inter-block references.
Between two blocks, a wire can connect one or more ports, ie. it can connect a set of output ports on one block to a same sized set of input ports on another block.
- property fullname: str
Display wire connection details.
- Returns:
Wire name
- Return type:
String format:
d2goal[0] --> Kv[0]
Plug
- class bdsim.Plug(block, port=0, type=None)[source]
Bases:
PortCreate a plug.
- Parameters:
- Returns:
Plug object
- Return type:
Plugs are the interface between a wire and block and have information about port number and wire end. Plugs are on the end of each wire, and connect a Wire to a specific port on a Block.
- The
typeargument indicates if thePlugis at: the start of a wire, ie. the port is an output port
the end of a wire, ie. the port is an input port
A plug can specify a set of ports on a block.
- __annotations__ = {}
Blocks
- class bdsim.Block(name=None, nin=None, nout=None, nstates=0, ndstates=0, inputs=None, inames=None, onames=None, snames=None, clock=None, pos=None, bd=None, type=None, blockclass=None, **kwargs)[source]
Bases:
ABC,Port_summary_
- Parameters:
ABC (_type_) – _description_
- Returns:
_description_
- Return type:
_type_
Block is the superclass of all blocks in the simulation environment. It defines the common properties of all blocks:
ninthe number of input portsnoutthe number of output portsnstatesthe number of continuous-time state variablesndstatesthe number of discrete-time state variablesnamethe unique name of the blockblockclassa string indicating the block class, eg. ‘sink’, ‘source’, ‘function’, ‘transfer’, ‘subsystem’, ‘clocked’, etc.typea string indicating the block type, eg. ‘gain’, ‘sum’, ‘integrator’, etc.
The simulation engine uses these methods:
getstate0(): returns the initial state of the block as a NumPy arraysetstate(x): sets the state of the block to the given statexand returns any remaining state for the next block in the clock sequencenext(t, u, x): computes the next state of the block given the current timet, input valuesinputs, and current statexoutput(t, u, x): returns the output value of the block at output portigiven the current state and inputs. The outputs are cached and can be accessed byblock.output_value(i)deriv(t, u, x): returns the derivative of the state variables for continuous-time blocksreset(): resets the block to its initial statedone(): performs any cleanup at end of the simulationinfo(): displays information about the block for debugging purposes
Ports can be accessed by index, eg.
block.input_value(i)orblock.output_value(i), or by name, eg.block.inport("in1")orblock.outport("out1")if the block has named ports.input_value(i): returns the value of the input port at indexioutput_value(i): returns the value of the output port at indexiinport_name(i): returns the name of the input port at indexioutport_name(i): returns the name of the output port at indexi
- __abstractmethods__ = frozenset({})
- __annotations__ = {'_bd': 'BlockDiagram | None', '_blockclass': 'str', '_clock': 'Clock | None', '_clocked': 'bool', '_graphics': 'bool', '_id': 'int | None', '_initd': 'bool', '_inport_names': 'list[str] | None', '_inport_slots': 'list[PortValueSlot | None]', '_input_wires': 'list[Wire | None]', '_name': 'str | None', '_name_tex': 'str | None', '_outport_names': 'list[str] | None', '_outport_slots': 'list[PortValueSlot]', '_output_values': 'list | None', '_output_wires': 'list[list[Wire]]', '_parameters': 'dict[str, Any]', '_parents': 'list[Plug | None]', '_pos': 'tuple[float, float] | None', '_sequence': 'int | None', '_shape': 'str | None', '_state_names': 'list[str] | None', '_type': 'str', '_x_view': 'np.ndarray | None', 'inlabels': 'list[str] | tuple[str, ...] | None', 'nin': 'int', 'nout': 'int', 'outlabels': 'list[str] | tuple[str, ...] | None'}
- __getattr__(name)[source]
Convert a RHS block name reference to a Plug.
- Parameters:
name (
str) – Port name- Returns:
Block or plug for specified block port name
- Return type:
Port
Used to create a wired connection by assignment, for example:
c = bd.CONSTANT(1, onames=['v']) y = c.v ┌───┐ ┌───┐ │ c ├ v ──────────▶ │ y │ └───┘ └───┘Note
this overloaded method handles all instances of
setattrand implements normal functionality as well, only creating a wire ifnameis a known port name.Warning
to avoid infinite recursion, this method must use
super().__getattribute__to access attributes of the block, and only create a Plug if the name is in the list of port names.
- __getitem__(port)[source]
Convert a RHS block slice reference to a Plug.
Invoked whenever a block is referenced as a slice, for example:
c = bd.CONSTANT(1) bd.connect(x, c[0]) bd.connect(c[0], x)
In both cases
c[0]is converted to aPlugby this method.
- __init__(name=None, nin=None, nout=None, nstates=0, ndstates=0, inputs=None, inames=None, onames=None, snames=None, clock=None, pos=None, bd=None, type=None, blockclass=None, **kwargs)[source]
Construct a new block object.
- Parameters:
name (str, optional) – Name of the block, defaults to None
nin (int, optional) – Number of inputs, defaults to None
nout (int, optional) – Number of outputs, defaults to None
inputs (Block, Plug or list of Block or Plug) – Optional incoming connections
inames (list of str, optional) – Names of input ports, defaults to None
onames (list of str, optional) – Names of output ports, defaults to None
snames (list of str, optional) – Names of states, defaults to None
pos (2-element tuple or list, optional) – Position of block on the canvas, defaults to None
bd (BlockDiagram, optional) – Parent block diagram, defaults to None
kwargs (dict) – Unused arguments
- Returns:
A Block superclass
- Return type:
A block object is the superclass of all blocks in the simulation environment.
This is the top-level initializer, and handles most options passed to the superclass initializer for each block in the library.
- classmethod __init_subclass__(**kwargs)[source]
Initialize a subclass of Block.
- Parameters:
cls (class type) – The subclass being initialized
kwargs (dict) – keyword args passed to subclass definition
- Return type:
This method is called when a new subclass of Block is defined, not when it is instantiated. Here we check that the subclass does not define methods that are inconsistent with its block class, and raise an error if it does. This is a sanity check to prevent blocks from being defined with methods that will never be called by the simulation engine, which would indicate a misunderstanding of the block API.
- __setattr__(name, value)[source]
Convert a LHS block name reference to a wire.
Used to create a wired connection by assignment, for example:
c = bd.CONSTANT(1, inames=['u']) c.u = x
Ths method is invoked to create a wire from
xto port ‘u’ of the constant blockc.+—+ +—+ | x | ——–> u- | c | +—+ +—+
Notes:
this overloaded method handles all instances of
setattrand implements normal functionality as well, only creating a wire ifnameis a known port name.
- __setitem__(port, src)[source]
Convert a LHS block slice reference to a wire.
Used to create a wired connection by assignment, for example:
X[0] = Y
where
XandYare blocks. This method is implicitly invoked and creates a wire fromYto input port 0 ofX.Note
The square brackets on the left-hand-side is critical, and
X = Ywill simply overwrite the reference toX.
- property bd: BlockDiagram
- compile()[source]
Compile the block for execution.
This method is called at compile time to initialize the attributes required for compilation.
- Seealso:
- Return type:
- property info: None
Interactive display of block properties.
Displays all attributes of the block for debugging purposes.
- inport_name(i)[source]
Get the name of an input port.
Get the name of an input port by index. By default the name is the port number in square brackets, but if the block has named ports then the name is taken from the list of input port names.
- Seealso:
- inport_names(names)[source]
Set input port names (legacy method for backward compatibility).
- Return type:
- inport_value(i)[source]
Get the value applied to specified input port.
- Parameters:
i (int) – Input port index
- Returns:
Input port value
- Return type:
Any
Get the value of the signal applied to port
i.Note
The value is read from a pre-bound input slot. For compatibility with direct unit tests (without compile), it falls back to predecessor block output lookup.
- Seealso:
- property inport_values: list[Any]
Get inport values as a list
- Returns:
list of input to block
- Return type:
list of length
nin
Returns a list of values corresponding to the input ports of the block. The types of the elements are dictated by the blocks connected to the input ports.
Note
Values are read from pre-bound input slots. For compatibility with direct unit tests (without compile), if an input slot is not bound yet the value is read from the predecessor block.
- Seealso:
- property inports: list[Plug]
List of output plugs feeding into this block.
- Returns:
List of source plugs
- Return type:
list of Plug, of length
nin
Returns the list of plugs that describe the outout ports (block and port) that feed into this block.
This is determined at compile time by the connections in the block diagram. It is used to determine the order of block execution.
- Seealso:
Block.sources()Block.inputs()
- property isclocked: bool
Test if block is clocked
- Returns:
True if block is clocked
- Return type:
True if block is clocked, False if it is continuous time.
- property isgraphics: bool
Test if block does graphics
- Returns:
True if block does graphics
- Return type:
- outport_name(i)[source]
Get the name of an output port.
Get the name of an output port by index. By default the name is the port number in square brackets, but if the block has named ports then the name is taken from the list of output port names.
- Seealso:
- outport_names(names)[source]
Set output port names (legacy method for backward compatibility).
- Return type:
- outport_value(i)[source]
Get the value of an output port.
- Parameters:
i (int) – Output port index
- Returns:
Output port value
- Return type:
Any
Get the value of the signal at output port
i.Note
The value is obtained from the block’s output values which are stored in the attribute
_output_values– a list of lengthnout. These values are set when the block’soutputmethod is evaluated.- Seealso:
- source_name(port)[source]
Get the name of output port driving this input port.
Get the name of the output port that drives the specified input port. By default the name is the port number in square brackets, but if the block has named ports then the name is taken from the list of input port names.
- Seealso:
- property sources: list[Block]
List of source blocks feeding into this block.
- Returns:
List of source blocks
- Return type:
list of Block, of length
nin
Returns the list of source blocks, those that feed input signals into this block.
This is determined at compile time by the connections in the block diagram. It is used to determine the order of block execution.
- Seealso:
Block.inports()Block.inputs()Block.source_name()
- test_deriv(*inputs, t=0.0, x=None)[source]
Evaluate a block for unit testing.
- Parameters:
- Returns:
Block derivative value
- Return type:
ndarray
The derivative of the block is evaluated for a given set of input port values. Input port values are treated as lists.
Mostly used for making concise unit tests.
- test_next(*inputs, t=0.0, x=None)[source]
Evaluate a block for unit testing.
- Parameters:
- Returns:
Block next state value
- Return type:
ndarray
The next value of a discrete time block is evaluated for a given set of input port values. Input port values are treated as lists.
Mostly used for making concise unit tests.
- test_output(*inputs, t=0.0, x=None)[source]
Evaluate a block for unit testing.
- Parameters:
- Returns:
Block output port values
- Return type:
The output ports of the block are evaluated for a given simulation time and set of input port values. Input ports are assigned to consecutive inputs, output port values are a list.
Mostly used for making concise unit tests.
Source block
- class bdsim.SourceBlock(**blockargs)[source]
Bases:
BlockA SourceBlock is a subclass of Block that represents a block that has outputs but no inputs. Its output is a function of parameters and time.
- __abstractmethods__ = frozenset({'output'})
- __annotations__ = {'_bd': 'BlockDiagram | None', '_blockclass': 'str', '_clock': 'Clock | None', '_clocked': 'bool', '_graphics': 'bool', '_id': 'int | None', '_initd': 'bool', '_inport_names': 'list[str] | None', '_inport_slots': 'list[PortValueSlot | None]', '_input_wires': 'list[Wire | None]', '_name': 'str | None', '_name_tex': 'str | None', '_outport_names': 'list[str] | None', '_outport_slots': 'list[PortValueSlot]', '_output_values': 'list | None', '_output_wires': 'list[list[Wire]]', '_parameters': 'dict[str, Any]', '_parents': 'list[Plug | None]', '_pos': 'tuple[float, float] | None', '_sequence': 'int | None', '_shape': 'str | None', '_state_names': 'list[str] | None', '_type': 'str', '_x_view': 'np.ndarray | None', 'inlabels': 'list[str] | tuple[str, ...] | None', 'nin': 'int', 'nout': 'int', 'outlabels': 'list[str] | tuple[str, ...] | None'}
- __init__(**blockargs)[source]
Create a source block.
- Parameters:
blockargs (dict) – common Block options
- Returns:
source block base class
- Return type:
This is the parent class of all source blocks.
- __module__ = 'bdsim.block'
Sink block
- class bdsim.SinkBlock(**blockargs)[source]
Bases:
BlockA SinkBlock is a subclass of Block that represents a block that has inputs but no outputs. Typically used to save data to a variable, file or graphics.
- __abstractmethods__ = frozenset({'step'})
- __annotations__ = {'_bd': 'BlockDiagram | None', '_blockclass': 'str', '_clock': 'Clock | None', '_clocked': 'bool', '_graphics': 'bool', '_id': 'int | None', '_initd': 'bool', '_inport_names': 'list[str] | None', '_inport_slots': 'list[PortValueSlot | None]', '_input_wires': 'list[Wire | None]', '_name': 'str | None', '_name_tex': 'str | None', '_outport_names': 'list[str] | None', '_outport_slots': 'list[PortValueSlot]', '_output_values': 'list | None', '_output_wires': 'list[list[Wire]]', '_parameters': 'dict[str, Any]', '_parents': 'list[Plug | None]', '_pos': 'tuple[float, float] | None', '_sequence': 'int | None', '_shape': 'str | None', '_state_names': 'list[str] | None', '_type': 'str', '_x_view': 'np.ndarray | None', 'inlabels': 'list[str] | tuple[str, ...] | None', 'nin': 'int', 'nout': 'int', 'outlabels': 'list[str] | tuple[str, ...] | None'}
- __init__(**blockargs)[source]
Create a sink block.
- Parameters:
blockargs (dict) – common Block options
- Returns:
sink block base class
- Return type:
This is the parent class of all sink blocks.
- __module__ = 'bdsim.block'
Function block
- class bdsim.FunctionBlock(**blockargs)[source]
Bases:
BlockA FunctionBlock is a subclass of Block that represents a block that has inputs and outputs but no state variables. Typically used to describe operations such as gain, summation or various mappings.
- __abstractmethods__ = frozenset({'output'})
- __annotations__ = {'_bd': 'BlockDiagram | None', '_blockclass': 'str', '_clock': 'Clock | None', '_clocked': 'bool', '_graphics': 'bool', '_id': 'int | None', '_initd': 'bool', '_inport_names': 'list[str] | None', '_inport_slots': 'list[PortValueSlot | None]', '_input_wires': 'list[Wire | None]', '_name': 'str | None', '_name_tex': 'str | None', '_outport_names': 'list[str] | None', '_outport_slots': 'list[PortValueSlot]', '_output_values': 'list | None', '_output_wires': 'list[list[Wire]]', '_parameters': 'dict[str, Any]', '_parents': 'list[Plug | None]', '_pos': 'tuple[float, float] | None', '_sequence': 'int | None', '_shape': 'str | None', '_state_names': 'list[str] | None', '_type': 'str', '_x_view': 'np.ndarray | None', 'inlabels': 'list[str] | tuple[str, ...] | None', 'nin': 'int', 'nout': 'int', 'outlabels': 'list[str] | tuple[str, ...] | None'}
- __init__(**blockargs)[source]
Create a function block.
- Parameters:
blockargs (dict) – common Block options
- Returns:
function block base class
- Return type:
This is the parent class of all function blocks.
- __module__ = 'bdsim.block'
Continuous-time block
- class bdsim.ContinuousBlock(nstates, x0=None, feedthrough=False, **blockargs)[source]
Bases:
BlockA ContinuousBlock is a subclass of Block that represents a block with inputs, outputs and states. Typically used to describe a continuous-time dynamic system, either linear or nonlinear.
- __abstractmethods__ = frozenset({'deriv', 'output'})
- __annotations__ = {'_bd': 'BlockDiagram | None', '_blockclass': 'str', '_clock': 'Clock | None', '_clocked': 'bool', '_graphics': 'bool', '_id': 'int | None', '_initd': 'bool', '_inport_names': 'list[str] | None', '_inport_slots': 'list[PortValueSlot | None]', '_input_wires': 'list[Wire | None]', '_name': 'str | None', '_name_tex': 'str | None', '_outport_names': 'list[str] | None', '_outport_slots': 'list[PortValueSlot]', '_output_values': 'list | None', '_output_wires': 'list[list[Wire]]', '_parameters': 'dict[str, Any]', '_parents': 'list[Plug | None]', '_pos': 'tuple[float, float] | None', '_sequence': 'int | None', '_shape': 'str | None', '_state_names': 'list[str] | None', '_type': 'str', '_x_view': 'np.ndarray | None', 'inlabels': 'list[str] | tuple[str, ...] | None', 'nin': 'int', 'nout': 'int', 'outlabels': 'list[str] | tuple[str, ...] | None'}
- __init__(nstates, x0=None, feedthrough=False, **blockargs)[source]
Create a continuous-time block.
- Parameters:
nstates (int) – number of continuous-time states
x0 (Vector1D, optional) – initial state vector, defaults to None
feedthrough (bool, optional) – whether the block has direct feedthrough from input to output, defaults to False
blockargs (dict) – common Block options
- Returns:
continuous-time block base class
- Return type:
This is the parent class of all continuous-time dynamic blocks.
- __module__ = 'bdsim.block'
Discrete-time block
- class bdsim.SampledBlock(clock, *, ndstates=None, x0=None, feedthrough=False, **blockargs)[source]
Bases:
BlockA SampledBlock is a subclass of Block that represents a block with inputs, outputs and discrete states. Typically used to describe a sampled-time dynamic system, either linear or nonlinear.
- __init__(clock, *, ndstates=None, x0=None, feedthrough=False, **blockargs)[source]
Create a clocked block.
- Parameters:
ndstates (int, optional) – number of discrete-time states
x0 (Vector1D, optional) – initial state vector, defaults to None
feedthrough (bool, optional) – whether the block has direct feedthrough from input to output, defaults to False
blockargs (dict) – common Block options
- Returns:
clocked block base class
- Return type:
This is the parent class of all sampled-time blocks.
- class bdsim.Clock(arg, unit='s', offset=0, name=None)[source]
Bases:
object- next_event(simstate)[source]
Schedule the next event
- Parameters:
simstate (
SimulationState) – _description_- Return type:
The time of the k’th clock tick is
$t_k = k*T + t_o$
where ‘k’, the clock index, is part of the clock state within the Simstate object.
- class bdsim.TimeQ[source]
Bases:
objectTime-ordered queue for events.
The list comprises tuples of (time, seq, block) to reflect an event associated with the specified block at the specified time. seq is a monotonic counter used as a tie-breaker to ensure a deterministic order of events with the same time, and is generated by an internal counter.
Subsystem block
- class bdsim.SubsystemBlock(subsystem, **blockargs)[source]
Bases:
BlockA SubSystem is a subclass of Block that represents a block that has inputs and outputs but no state variables. Typically used to describe operations such as gain, summation or various mappings.
- __abstractmethods__ = frozenset({})
- __annotations__ = {'_bd': 'BlockDiagram | None', '_blockclass': 'str', '_clock': 'Clock | None', '_clocked': 'bool', '_graphics': 'bool', '_id': 'int | None', '_initd': 'bool', '_inport_names': 'list[str] | None', '_inport_slots': 'list[PortValueSlot | None]', '_input_wires': 'list[Wire | None]', '_name': 'str | None', '_name_tex': 'str | None', '_outport_names': 'list[str] | None', '_outport_slots': 'list[PortValueSlot]', '_output_values': 'list | None', '_output_wires': 'list[list[Wire]]', '_parameters': 'dict[str, Any]', '_parents': 'list[Plug | None]', '_pos': 'tuple[float, float] | None', '_sequence': 'int | None', '_shape': 'str | None', '_state_names': 'list[str] | None', '_type': 'str', '_x_view': 'np.ndarray | None', 'inlabels': 'list[str] | tuple[str, ...] | None', 'nin': 'int', 'nout': 'int', 'outlabels': 'list[str] | tuple[str, ...] | None'}
- __init__(subsystem, **blockargs)[source]
Create a subsystem block.
- Parameters:
subsystem (BlockDiagram) – the subsystem to wrap
blockargs (dict) – common Block options
- Returns:
subsystem block base class
- Return type:
This is the parent class of all subsystem blocks.
- __module__ = 'bdsim.block'
Graphics block
- class bdsim.GraphicsBlock(movie=None, **blockargs)[source]
Bases:
SinkBlockA GraphicsBlock is a subclass of SinkBlock that represents a block that has inputs but no outputs and creates/updates a graphical display.
- __abstractmethods__ = frozenset({})
- __annotations__ = {'_bd': 'BlockDiagram | None', '_blockclass': 'str', '_clock': 'Clock | None', '_clocked': 'bool', '_fig': 'matplotlib.figure.Figure | None', '_graphics': 'bool', '_id': 'int | None', '_initd': 'bool', '_inport_names': 'list[str] | None', '_inport_slots': 'list[PortValueSlot | None]', '_input_wires': 'list[Wire | None]', '_name': 'str | None', '_name_tex': 'str | None', '_outport_names': 'list[str] | None', '_outport_slots': 'list[PortValueSlot]', '_output_values': 'list | None', '_output_wires': 'list[list[Wire]]', '_parameters': 'dict[str, Any]', '_parents': 'list[Plug | None]', '_pos': 'tuple[float, float] | None', '_sequence': 'int | None', '_shape': 'str | None', '_state_names': 'list[str] | None', '_type': 'str', '_x_view': 'np.ndarray | None', 'inlabels': 'list[str] | tuple[str, ...] | None', 'nin': 'int', 'nout': 'int', 'outlabels': 'list[str] | tuple[str, ...] | None'}
- __init__(movie=None, **blockargs)[source]
Create a graphical display block.
- Parameters:
movie (str, optional) – Save animation in this file in MP4 format, defaults to None
blockargs (dict) – common Block options
- Returns:
transfer function block base class
- Return type:
This is the parent class of all graphic display blocks.
- __module__ = 'bdsim.block'