Skip to content

Coding patterns

Peter Corke edited this page May 25, 2026 · 2 revisions

There are a few different ways that you can write your system using bdsim.

Classical

import bdsim

sim = bdsim.BDSim(animation=True)  # create simulator
bd = sim.blockdiagram()  # create an empty block diagram

# define the blocks
demand = bd.STEP(T=1, name="demand")
sum = bd.SUM("+-")
gain = bd.GAIN(10)
plant = bd.LTI_SISO(0.5, [2, 1], name="plant")
scope = bd.SCOPE(styles=["k", "r--"])

# connect the blocks
bd.connect(demand, sum[0], scope[1])
bd.connect(plant, sum[1])
bd.connect(sum, gain)
bd.connect(gain, plant)
bd.connect(plant, scope[0])

Pythonic

import bdsim

sim = bdsim.BDSim(animation=True)  # create simulator
bd = sim.blockdiagram()  # create an empty block diagram

# define the blocks
demand = bd.STEP(T=1, name="demand")
plant = bd.LTI_SISO(0.5, [2, 1], name="plant")
scope = bd.SCOPE(styles=["k", "r--"])

# connect the blocks using Python syntax
scope[0] = plant
scope[1] = demand
plant[0] = 10 * (demand - plant)

We can also use the >> operator, A >> B is the same as

bd.connect(A, B)

and the result of the expression is B.

Either or both of A or B can have indexes to indicate a port. The result of A >> B[1] is B.

Now we can write the example as

sim = bdsim.BDSim(animation=True)  # create simulator
bd = sim.blockdiagram()  # create an empty block diagram

# define the blocks
demand = bd.STEP(T=1, name="demand")
sum = bd.SUM("+-")
plant = sum >> bd.GAIN(10) >> bd.LTI_SISO(0.5, [2, 1], name="plant")
scope = bd.SCOPE(styles=["k", "r--"])

# connect the blocks
bd.connect(demand, sum[0], scope[1])
bd.connect(plant, sum[1])
bd.connect(plant, scope[0])

Inputs as parameters

sim = bdsim.BDSim(animation=True)  # create simulator
bd = sim.blockdiagram()  # create an empty block diagram

# define the blocks
demand = bd.STEP(T=1, name="demand")
plant = bd.LTI_SISO(0.5, [2, 1], name="plant")
sum = bd.SUM("+-", inputs=[demand, plant])
gain = bd.GAIN(10, inputs=[sum])
scope = bd.SCOPE(styles=["k", "r--"], inputs=[demand, plant])

# connect the blocks using Python syntax
plant[0] = gain # only 1 wire remains to be added

Maximally cryptic

All of these syntactic tricks can be used in your code, mixed as you see fit. You should probably choose the ones that work best with your way of thinking and stick to them. The following example is minimal but rather cryptic.

import bdsim

sim = bdsim.BDSim(animation=True)  # create simulator
bd = sim.blockdiagram()  # create an empty block diagram

# define the blocks
demand = bd.STEP(T=1, name="demand")
plant = (gain := bd.GAIN(10)) >> bd.LTI_SISO(0.5, [2, 1], name="plant")
scope = bd.SCOPE(styles=["k", "r--"], inputs=[demand, plant])
gain[0] = bd.SUM("+-", inputs=[demand, plant])

Non factory

In the patterns above the blocks are created by factory methods of the bd object like STEP or SCOPE. These are dynamically loaded at run time and in fact correspond to the constructors of classes called Step and Scope defined in files in the blocks folder. We can can construct instances of those classes directly, but at the expense of slightly increased verbosity.

import bdsim
from bdsim.blocks import Sum, Gain, Scope, LTI_SISO, Step

sim = bdsim.BDSim(load=False, animation=True)  # create simulator, don't dynamically load blocks

bd = sim.blockdiagram()  # create an empty block diagram

# define the blocks
demand = Step(T=1, name="demand", bd=bd)
sum = Sum("+-", bd=bd)
gain = Gain(10, bd=bd)
plant = LTI_SISO(0.5, [2, 1], name="plant", bd=bd)
scope = Scope(styles=["k", "r--"], loc="lower right", bd=bd)

We need to tell each block which block diagram it belongs to by passing in the bd argument. See examples/eg1b.py for a runnable example of this approach.

Implicit wiring using Python operators can be used with this programming pattern.

This approach might be advantageous when running in an environment that cannot support the dynamic block loading, perhaps an embedded system running Micro/Circuit Python. This would allow enormous simplification of the BDSim class, but this is not part of the current development path.

    ,
    toolboxes: bool = True,

Clone this wiki locally