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

Block 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:
  • subsystem (bool, optional) – importing a subsystems, defaults to False

  • doimport (bool, optional) – import subsystems, defaults to True

Raises:

RuntimeError – various block diagram errors

Returns:

Compile status

Return type:

bool

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:
  • start (Block | Plug) – The output port that the wire starts from.

  • ends (Block | Plug) – The input port(s) that the wire ends at. Can be one or more.

  • name (_type_, optional) – The name of the wire, defaults to None

Return type:

None

Connect blocks together. The start block can be connected to one or more end blocks.

Blocks are added to the block diagram’s blocklist if 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. The wirelist is a list of things that will be connected later.

dotfile(filename, shapes=None)[source]

Write a GraphViz dot file representing the network.

Parameters:
  • file (str, file handle) – Name of file to write to, or file handle

  • shapes (dict) – block shapes

Return type:

None

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

  • SUM and PROD blocks have the sign or operation of their input wires labeled.

The file can be processed using dot:

% dot -Tpng -o out.png dotfile.dot
Block diagram represented as a mathematical graph

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 shapes that maps block class (sink, source, graphics, function, transfer) to the names of GraphViz shapes.

Seealso:

showgraph()

report_lists(**kwargs)[source]

Print a tabular report about the block diagram.

Parameters:

kwargs (dict) – options passed to ansitable.table.ANSIMatrix.print()

Return type:

None

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:

None

Print a table with 4 columns:

  1. Block name, sorted in alphabetical order

  2. The input port (if not a source block)

  3. The block driving this port (if not a source block)

  4. The type of value driving this port (if not a source block)

If the block is an event source, add a @ suffix.

showgraph()[source]

Display diagram as a graph in browser tab

Seealso:

dotfile()

Return type:

None

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:

BDSim

If sysargs is True, process command line arguments and passed options. Command line arguments have precedence.

Note

animation and graphics options are coupled. If graphics=False, all graphics is suppressed. If graphics=True then graphics are shown and the behaviour depends on animation. animation=False shows graphs at the end of the simulation, while animation=True will animate the graphs during simulation.

Seealso:

set_globals()

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 a BlockDiagram.

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:

BlockDiagram

This object describes the connectivity of a set of blocks and wires.

It is an instantiation of the BlockDiagram class 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 .GAIN invokes the constructor for the Gain class.

Seealso:

BlockDiagram()

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:

None

done(bd, block=False)[source]

Enter the matplotlib event loop and clean up after simulation.

Called after run() to allow interactive use of displayed SCOPE figures. If the hold option 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; if False, flush events and return immediately. Overridden by sim.options.hold.

Return type:

None

Note

This method can be called after run() has returned (i.e. outside the simulation context) — for example when the script calls sim.run(..., block=False) and then does post-processing before handing control back to the user. In that case the hold option is read from sim.options directly.

report(bd, type='summary', **kwargs)[source]

Print block diagram report

Parameters:
  • bd (BlockDiagram) – the block diagram to be reported

  • type (str, optional) – report type, one of: “summary” (default), “lists”, “schedule”

  • style (str) – table style, one of: ansi (default), markdown, latex

Return type:

None

Single method wrapper for various block diagram reports. Obeys the -q option 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_eval grid for solve_ivp so results are recorded at uniform steps

  • max_step (float, optional) – maximum integration step passed to solve_ivp

  • solver (str, optional) – solve_ivp method name, defaults to RK45

  • solver_args (dict) – extra keyword arguments for scipy.integrate.solve_ivp

  • debug (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:

BDStruct

The system is simulated from time 0 to T.

The integration backend is always scipy.integrate.solve_ivp. The solver argument selects the method (e.g. RK45, DOP853, Radau, BDF, LSODA). Finer control — tolerances, first step, etc. — can be passed via solver_args.

The output dt controls the time resolution of logged output. When given, solve_ivp is called with a matching t_eval grid so that out.t contains uniformly-spaced points. If omitted, solve_ivp chooses its own internal steps and all accepted points are recorded.

Results are returned in a BDStruct with attributes:

  • t — time vector: ndarray, shape=(M,)

  • x — continuous state matrix: ndarray, shape=(M,N)

  • xnames — list of state names corresponding to columns of x, e.g. "plant.x0" (set via the block’s snames argument)

  • clockNBDStruct for each clock (clock0, clock1, …) with sub-attributes t and x holding the discrete time history; a legacy alias using the clock’s name is also added when possible

  • yN — logged signal for the N-th entry in watch

  • ynames — list of names of the watched ports, same order as watch

  • .statsBDStruct with integration statistics: integration_time_points, run_interval_calls, ydot_calls, integrator_wall_time, events_detected_total, events_detected_by_source

The watch argument is a list of one or more signals whose value during simulation will be recorded. Each element can be:

  • a Block reference, interpreted as output port 0

  • a Plug reference (block with port index)

  • a string of the form "blockname[i]" — port i of the named block

The debug string 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: UserDict

A 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)
__init__(name='BDStruct2', **kwargs)[source]
__str__()[source]

Display struct as a string

Returns:

struct in indented string format

Return type:

str

The struct is rendered with one line per element, and substructures are indented. Keys whose names start with ‘.’ are hidden (internal metadata fields).

add(name, value)[source]
Return type:

None

dump(outfile)[source]

Pickle the struct to a file.

Parameters:

outfile (str) – path to the output file

Return type:

None

dump_json(outfile)[source]

Serialise the struct to a JSON file.

NumPy arrays are converted to nested lists and NumPy scalars are unwrapped to their Python equivalents. Nested BDStruct instances are recursively converted to plain dicts.

Parameters:

outfile (str) – path to the output file

Return type:

None

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

DEBUG(debug, fmt, *args)[source]
Return type:

None

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

BDSim

If sysargs is True, process command line arguments and passed options. Command line arguments have precedence.

Note

animation and graphics options are coupled. If graphics=False, all graphics is suppressed. If graphics=True then graphics are shown and the behaviour depends on animation. animation=False shows graphs at the end of the simulation, while animation=True will animate the graphs during simulation.

Seealso:

set_globals()

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 a BlockDiagram.

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:

BlockDiagram

This object describes the connectivity of a set of blocks and wires.

It is an instantiation of the BlockDiagram class 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 .GAIN invokes the constructor for the Gain class.

Seealso:

BlockDiagram()

blockinfo(block=None)[source]

Return info about all blocks. :rtype: Any

Deprecated since version Use: block_library instead. sim.blockinfo() is equivalent to sim.block_library; sim.blockinfo(name) is equivalent to sim.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:

None

closefigs()[source]
Return type:

None

done(bd, block=False)[source]

Enter the matplotlib event loop and clean up after simulation.

Called after run() to allow interactive use of displayed SCOPE figures. If the hold option 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; if False, flush events and return immediately. Overridden by sim.options.hold.

Return type:

None

Note

This method can be called after run() has returned (i.e. outside the simulation context) — for example when the script calls sim.run(..., block=False) and then does post-processing before handing control back to the user. In that case the hold option is read from sim.options directly.

fatal(message, retval=1)[source]

Fatal simulation error

Parameters:
  • message (str) – Error message

  • retval (int, optional) – system return value (*nix only) defaults to 1

Return type:

NoReturn

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:

dict of dict

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: - path to the folder holding the Python file defining the block - classname - blockname, upper case version of classname - url of online documentation for the block - package containing 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 reported

  • type (str, optional) – report type, one of: “summary” (default), “lists”, “schedule”

  • style (str) – table style, one of: ansi (default), markdown, latex

Return type:

None

Single method wrapper for various block diagram reports. Obeys the -q option 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_eval grid for solve_ivp so results are recorded at uniform steps

  • max_step (float, optional) – maximum integration step passed to solve_ivp

  • solver (str, optional) – solve_ivp method name, defaults to RK45

  • solver_args (dict) – extra keyword arguments for scipy.integrate.solve_ivp

  • debug (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:

BDStruct

The system is simulated from time 0 to T.

The integration backend is always scipy.integrate.solve_ivp. The solver argument selects the method (e.g. RK45, DOP853, Radau, BDF, LSODA). Finer control — tolerances, first step, etc. — can be passed via solver_args.

The output dt controls the time resolution of logged output. When given, solve_ivp is called with a matching t_eval grid so that out.t contains uniformly-spaced points. If omitted, solve_ivp chooses its own internal steps and all accepted points are recorded.

Results are returned in a BDStruct with attributes:

  • t — time vector: ndarray, shape=(M,)

  • x — continuous state matrix: ndarray, shape=(M,N)

  • xnames — list of state names corresponding to columns of x, e.g. "plant.x0" (set via the block’s snames argument)

  • clockNBDStruct for each clock (clock0, clock1, …) with sub-attributes t and x holding the discrete time history; a legacy alias using the clock’s name is also added when possible

  • yN — logged signal for the N-th entry in watch

  • ynames — list of names of the watched ports, same order as watch

  • .statsBDStruct with integration statistics: integration_time_points, run_interval_calls, ydot_calls, integrator_wall_time, events_detected_total, events_detected_by_source

The watch argument is a list of one or more signals whose value during simulation will be recorded. Each element can be:

  • a Block reference, interpreted as output port 0

  • a Plug reference (block with port index)

  • a string of the form "blockname[i]" — port i of the named block

The debug string 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’s savefig method

Return type:

None

savefigs(bd, format='pdf', **kwargs)[source]

Save figures from all graphics blocks in a block diagram.

Iterates over every block in bd and calls savefig on each GraphicsBlock, 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’s savefig method

Return type:

None

set_globals(globs)[source]

Set globals as specified by command line

Parameters:

globs (dict) – global variables

Return type:

None

The command line option --global var=value can be used to request the change of global variables. However, actually changing them requires explicit code support in the user’s program after the BDSim constructor.

Example:

sim.set_globals(globals())

Messages are displayed by defaulting, indicating which variables are changed, and their old and new values.

set_options(**options)[source]
Return type:

None

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 and dot to be on PATH.

Parameters:
Return type:

None

submit(bd, **kwargs)[source]
Return type:

SimulationJob

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

are stored as list items in options.setparam

block can be either:

  • the block’s name as a string, either user assigned or bdsim assigned

  • the block id as displayed by the report method

param is the name of the parameter used in the constructor

value is the new value of the variable

class bdsim.BDStruct(name='BDStruct2', **kwargs)[source]

Bases: UserDict

A 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)
__init__(name='BDStruct2', **kwargs)[source]
add(name, value)[source]
Return type:

None

dump(outfile)[source]

Pickle the struct to a file.

Parameters:

outfile (str) – path to the output file

Return type:

None

dump_json(outfile)[source]

Serialise the struct to a JSON file.

NumPy arrays are converted to nested lists and NumPy scalars are unwrapped to their Python equivalents. Nested BDStruct instances are recursively converted to plain dicts.

Parameters:

outfile (str) – path to the output file

Return type:

None

This class describes a block diagram, a collection of blocks and wires that can be “executed”.

class bdsim.BlockDiagram(name='main', **kwargs)[source]

Bases: BlockDiagramMixin

Block 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:
  • subsystem (bool, optional) – importing a subsystems, defaults to False

  • doimport (bool, optional) – import subsystems, defaults to True

Raises:

RuntimeError – various block diagram errors

Returns:

Compile status

Return type:

bool

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:
  • start (Block | Plug) – The output port that the wire starts from.

  • ends (Block | Plug) – The input port(s) that the wire ends at. Can be one or more.

  • name (_type_, optional) – The name of the wire, defaults to None

Return type:

None

Connect blocks together. The start block can be connected to one or more end blocks.

Blocks are added to the block diagram’s blocklist if 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. The wirelist is a list of things that will be connected later.

dotfile(filename, shapes=None)[source]

Write a GraphViz dot file representing the network.

Parameters:
  • file (str, file handle) – Name of file to write to, or file handle

  • shapes (dict) – block shapes

Return type:

None

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

  • SUM and PROD blocks have the sign or operation of their input wires labeled.

The file can be processed using dot:

% dot -Tpng -o out.png dotfile.dot
Block diagram represented as a mathematical graph

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 shapes that maps block class (sink, source, graphics, function, transfer) to the names of GraphViz shapes.

Seealso:

showgraph()

report_lists(**kwargs)[source]

Print a tabular report about the block diagram.

Parameters:

kwargs (dict) – options passed to ansitable.table.ANSIMatrix.print()

Return type:

None

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:

None

Print a table with 4 columns:

  1. Block name, sorted in alphabetical order

  2. The input port (if not a source block)

  3. The block driving this port (if not a source block)

  4. The type of value driving this port (if not a source block)

If the block is an event source, add a @ suffix.

showgraph()[source]

Display diagram as a graph in browser tab

Seealso:

dotfile()

Return type:

None

Wire

class bdsim.Wire(start, end, name=None)[source]

Bases: object

Create a wire.

Parameters:
  • start (Plug) – Plug at the start of a wire

  • end (Plug) – Plug at the end of a wire

  • name (str, optional) – Name of wire, defaults to None

Returns:

A wire object

Return type:

Wire

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.

bind_slot(slot)[source]
Return type:

None

property fullname: str

Display wire connection details.

Returns:

Wire name

Return type:

str

String format:

d2goal[0] --> Kv[0]
property info: None

Interactive display of wire properties.

Displays all attributes of the wire for debugging purposes.

property value: Any

Plug

class bdsim.Plug(block, port=0, type=None)[source]

Bases: Port

Create a plug.

Parameters:
  • block (Block) – The block being plugged into

  • port (int, optional) – The port on the block, defaults to 0

  • type (str, optional) – ‘start’ or ‘end’, defaults to None

Returns:

Plug object

Return type:

Plug

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 type argument indicates if the Plug is 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.

__add__(**kwargs: Any) Any[source]
Return type:

Any

__annotations__ = {}
__getitem__(i)[source]
Return type:

Self

__init__(block, port=0, type=None)[source]
__mul__(**kwargs: Any) Any[source]
Return type:

Any

__neg__(**kwargs: Any) Any[source]
Return type:

Any

__pow__(**kwargs: Any) Any[source]
Return type:

Any

__radd__(**kwargs: Any) Any[source]
Return type:

Any

__repr__()[source]

Return repr(self).

Return type:

str

__rmul__(**kwargs: Any) Any[source]
Return type:

Any

__rshift__(**kwargs: Any) Any[source]
Return type:

Any

__rsub__(**kwargs: Any) Any[source]
Return type:

Any

__rtruediv__(**kwargs: Any) Any[source]
Return type:

Any

__str__()[source]

Return str(self).

Return type:

str

__sub__(**kwargs: Any) Any[source]
Return type:

Any

__truediv__(**kwargs: Any) Any[source]
Return type:

Any

property isslice: bool
property portlist: list[int] | range
property width: int

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:

  • nin the number of input ports

  • nout the number of output ports

  • nstates the number of continuous-time state variables

  • ndstates the number of discrete-time state variables

  • name the unique name of the block

  • blockclass a string indicating the block class, eg. ‘sink’, ‘source’, ‘function’, ‘transfer’, ‘subsystem’, ‘clocked’, etc.

  • type a 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 array

  • setstate(x): sets the state of the block to the given state x and returns any remaining state for the next block in the clock sequence

  • next(t, u, x): computes the next state of the block given the current time t, input values inputs, and current state x

  • output(t, u, x): returns the output value of the block at output port i given the current state and inputs. The outputs are cached and can be accessed by block.output_value(i)

  • deriv(t, u, x): returns the derivative of the state variables for continuous-time blocks

  • reset(): resets the block to its initial state

  • done(): performs any cleanup at end of the simulation

  • info(): displays information about the block for debugging purposes

Ports can be accessed by index, eg. block.input_value(i) or block.output_value(i), or by name, eg. block.inport("in1") or block.outport("out1") if the block has named ports.

  • input_value(i): returns the value of the input port at index i

  • output_value(i): returns the value of the output port at index i

  • inport_name(i): returns the name of the input port at index i

  • outport_name(i): returns the name of the output port at index i

__abstractmethods__ = frozenset({})
__add__(**kwargs: Any) Any
Return type:

Any

__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 setattr and implements normal functionality as well, only creating a wire if name is 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.

Parameters:

port (int) – Port number

Returns:

A port plug

Return type:

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 a Plug by 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:

Block

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:

None

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.

__mul__(**kwargs: Any) Any
Return type:

Any

__neg__(**kwargs: Any) Any
Return type:

Any

__pow__(**kwargs: Any) Any
Return type:

Any

__radd__(**kwargs: Any) Any
Return type:

Any

__repr__()[source]

Return repr(self).

Return type:

str

__rmul__(**kwargs: Any) Any
Return type:

Any

__rshift__(**kwargs: Any) Any
Return type:

Any

__rsub__(**kwargs: Any) Any
Return type:

Any

__rtruediv__(**kwargs: Any) Any
Return type:

Any

__setattr__(name, value)[source]

Convert a LHS block name reference to a wire.

Parameters:
  • name (str) – Port name

  • value (Port) – the RHS

Return type:

None

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 x to port ‘u’ of the constant block c.

+—+ +—+ | x | ——–> u- | c | +—+ +—+

Notes:

  • this overloaded method handles all instances of setattr and implements normal functionality as well, only creating a wire if name is a known port name.

__setitem__(port, src)[source]

Convert a LHS block slice reference to a wire.

Parameters:
  • port (int) – Port number

  • src (Block or Plug) – the RHS

Return type:

None

Used to create a wired connection by assignment, for example:

X[0] = Y

where X and Y are blocks. This method is implicitly invoked and creates a wire from Y to input port 0 of X.

Note

The square brackets on the left-hand-side is critical, and X = Y will simply overwrite the reference to X.

__sub__(**kwargs: Any) Any
Return type:

Any

__truediv__(**kwargs: Any) Any
Return type:

Any

add_input_wire(w)[source]
Return type:

None

add_output_wire(w)[source]
Return type:

None

add_param(param, handler=None)[source]
Return type:

None

property bd: BlockDiagram
bind_input_slot(i, slot)[source]
Return type:

None

property blockclass: str
check()[source]
Return type:

None

check_safe()[source]
Return type:

None

compile()[source]

Compile the block for execution.

This method is called at compile time to initialize the attributes required for compilation.

Seealso:

BlockDiagram.compile()

Return type:

None

deriv_safe(t, u, x)[source]
Return type:

Any

done(**kwargs)[source]
Return type:

None

done_safe(**kwargs)[source]
Return type:

None

property fullname: str
getstate0_safe()[source]
Return type:

Any

property hasstate: bool

True if the block owns continuous or discrete state.

property id: int | None
property info: None

Interactive display of block properties.

Displays all attributes of the block for debugging purposes.

property initd: bool
inlabels: list[str] | tuple[str, ...] | None = None
inport_name(i)[source]

Get the name of an input port.

Parameters:

i (int) – Input port index

Return type:

str

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:

outport_name() source_name()

inport_names(names)[source]

Set input port names (legacy method for backward compatibility).

Return type:

None

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:

inport_values()

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:

inport_value()

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:

bool

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:

bool

property name: str | None
property name_tex: str | None
property ndstates: int
next_safe(t, u, x)[source]
Return type:

Any

nin: int = 0
nout: int = 0
property nstates: int
outlabels: list[str] | tuple[str, ...] | None = None
outport_name(i)[source]

Get the name of an output port.

Parameters:

i (int) – Output port index

Return type:

str

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:

inport_name() source_name()

outport_names(names)[source]

Set output port names (legacy method for backward compatibility).

Return type:

None

outport_slot(i)[source]
Return type:

PortValueSlot

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 length nout. These values are set when the block’s output method is evaluated.

Seealso:

inport_value()

output_safe(t, u, x)[source]
Return type:

Any

property pos: tuple[float, float] | None
reset()[source]
Return type:

None

reset_safe()[source]
Return type:

None

savefig(*pos, **kwargs)[source]
Return type:

None

set_param(name, newvalue)[source]
Return type:

None

property shape: str | None
source_name(port)[source]

Get the name of output port driving this input port.

Parameters:

port (int) – Input port

Returns:

Port name

Return type:

str

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:

outport_name() inport_name()

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

start(simstate)[source]
Return type:

None

start_safe(simstate)[source]
Return type:

None

state_names(names)[source]
Return type:

None

step_safe(t, u)[source]
Return type:

None

test_deriv(*inputs, t=0.0, x=None)[source]

Evaluate a block for unit testing.

Parameters:
  • inputs (list) – input port values

  • t (float, optional) – Simulation time, defaults to 0.0

  • x (ndarray) – state vector

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:
  • inputs (list) – input port values

  • t (float, optional) – Simulation time, defaults to 0.0

  • x (ndarray) – state vector

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:
  • inputs (Any) – Input port values

  • t (float, optional) – Simulation time, defaults to 0.0

  • x (ndarray) – state vector

Returns:

Block output port values

Return type:

list

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.

test_start(simstate=None)[source]
Return type:

SimulationState

test_step(*inputs, t=0.0)[source]

Step a block for unit testing.

Parameters:
  • inputs (list) – input port values

  • t (float, optional) – Simulation time, defaults to 0.0

Return type:

None

Step the block for a given set of input port values. Input port values are treated as lists.

Mostly used for making concise unit tests.

property type: str

Source block

class bdsim.SourceBlock(**blockargs)[source]

Bases: Block

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

SourceBlock

This is the parent class of all source blocks.

__module__ = 'bdsim.block'
abstract output(t, u, x)[source]
Return type:

list[Any]

Sink block

class bdsim.SinkBlock(**blockargs)[source]

Bases: Block

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

SinkBlock

This is the parent class of all sink blocks.

__module__ = 'bdsim.block'
abstract step(t, u)[source]
Return type:

None

Function block

class bdsim.FunctionBlock(**blockargs)[source]

Bases: Block

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

FunctionBlock

This is the parent class of all function blocks.

__module__ = 'bdsim.block'
abstract output(t, u, x)[source]
Return type:

list[Any]

Continuous-time block

class bdsim.ContinuousBlock(nstates, x0=None, feedthrough=False, **blockargs)[source]

Bases: Block

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

ContinuousBlock

This is the parent class of all continuous-time dynamic blocks.

__module__ = 'bdsim.block'
check()[source]
Return type:

None

abstract deriv(t, u, x)[source]
Return type:

ndarray

getstate0()[source]
Return type:

ndarray

abstract output(t, u, x)[source]
Return type:

list[Any]

reset()[source]
Return type:

None

setstate(x)[source]
Return type:

ndarray

Discrete-time block

class bdsim.SampledBlock(clock, *, ndstates=None, x0=None, feedthrough=False, **blockargs)[source]

Bases: Block

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

SampledBlock

This is the parent class of all sampled-time blocks.

check()[source]
Return type:

None

getstate0()[source]
Return type:

ndarray

reset()[source]
Return type:

None

setstate(x)[source]
Return type:

ndarray

class bdsim.Clock(arg, unit='s', offset=0, name=None)[source]

Bases: object

__init__(arg, unit='s', offset=0, name=None)[source]
add_block(block)[source]
Return type:

None

getlog(simstate=None)[source]
Return type:

tuple[list, list]

getstate(t)[source]
Return type:

ndarray[tuple[Any, ...], dtype[Any]]

getstate0()[source]
Return type:

ndarray[tuple[Any, ...], dtype[Any]]

next_event(simstate)[source]

Schedule the next event

Parameters:

simstate (SimulationState) – _description_

Return type:

None

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.

savestate(t, simstate=None, x=None)[source]
Return type:

None

setstate(simstate=None)[source]
Return type:

None

start(simstate)[source]
Return type:

None

tick_realtime(t, simstate)[source]

Handle one realtime clock tick without event-queue rescheduling.

Realtime scheduling is owned by timer backends; unlike __call__ this method does not enqueue the next event in simstate.eventq.

Return type:

None

time(k)[source]
Return type:

float

class bdsim.TimeQ[source]

Bases: object

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

__init__()[source]
pop(dt=0.0)[source]
Return type:

tuple[float | None, list[Any]]

pop_until(t)[source]
Return type:

list[tuple[float, Any]]

push(value)[source]
Return type:

None

Subsystem block

class bdsim.SubsystemBlock(subsystem, **blockargs)[source]

Bases: Block

A 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:
Returns:

subsystem block base class

Return type:

SubsystemBlock

This is the parent class of all subsystem blocks.

__module__ = 'bdsim.block'

Graphics block

class bdsim.GraphicsBlock(movie=None, **blockargs)[source]

Bases: SinkBlock

A 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:
Returns:

transfer function block base class

Return type:

GraphicsBlock

This is the parent class of all graphic display blocks.

__module__ = 'bdsim.block'
create_figure(state)[source]
Return type:

Figure

done(block=False, **kwargs)[source]
Return type:

None

property fig: Figure | None
property movie: str | None
savefig(filename=None, format='pdf', **kwargs)[source]

Save the figure as an image file

Parameters:
  • fname (str) – Name of file to save graphics to

  • **kwargs – Options passed to savefig

Return type:

None

The file format is taken from the file extension and can be jpeg, png or pdf.

start(simstate)[source]
Return type:

None

step(t, inports)[source]
Return type:

None

property writer: Any