-
-
Notifications
You must be signed in to change notification settings - Fork 39
Coding patterns
There are a few different ways that you can write your system using bdsim.
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])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])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 addedAll 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])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,
Copyright (c) Peter Corke 2020-
- Home
- Control Systems Magazine article
- FAQ
- Changes
- Adding blocks
- Block path
- Connecting blocks
- Subsystems
- Compiling
- Running
- Runtime options
- Discrete-time blocks
- Figures
- Notebook animation
- PID control
- Coding patterns
- Block methods and attributes
- Event handling
- Discrete-time dynamics
- Blocks, wires and plug
- Discrete-time blocks
- Evaluation
- Runtimes and simulator state
- Creating a new block
- Future & related work
Under development on feat/realtime branch