Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 23 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,35 +42,36 @@ pip install .

The following example models a damped harmonic oscillator:

$$ \ddot{x} +0.5\dot{x} +2 x = 0 $$
$$ \ddot{x} +0.5\dot{x} +2x = 0 $$

The continuous-time equation is implemented using explicit forward Euler discretization through discrete integrator blocks with a fixed time step.
The continuous-time equation is implemented using explicit forward Euler
discretization through discrete integrator blocks with a fixed time step.

The system is assembled explicitly from discrete operators.
The system is assembled explicitly from discrete-time operators.

```python
from pySimBlocks import Model, Simulator, SimulationConfig, PlotConfig
from pySimBlocks.blocks.operators import Gain, Sum, DiscreteIntegrator
from pySimBlocks.project.plot_from_config import plot_from_config

# 1. Create the blocks
I1 = DiscreteIntegrator("x", initial_state=5)
I2 = DiscreteIntegrator("v", initial_state=2.)
A1 = Gain(name="damping", gain=0.5)
A2 = Gain(name="stiffness", gain=2)
S = Sum(name="sum", signs="--")
v = DiscreteIntegrator("v", initial_state=5)
x = DiscreteIntegrator("x", initial_state=2.)
damping = Gain(name="damping", gain=0.5)
stiffness = Gain(name="stiffness", gain=2)
sum = Sum(name="sum", signs="--")

# 2. Build the model
model = Model("Example")
for block in [I1, I2, A1, A2, S]:
for block in [v, x, damping, stiffness, sum]:
model.add_block(block)

model.connect("x", "out", "v", "in")
model.connect("x", "out", "damping", "in")
model.connect("v", "out", "stiffness", "in")
model.connect("v", "out", "x", "in")
model.connect("v", "out", "damping", "in")
model.connect("x", "out", "stiffness", "in")
model.connect("damping", "out", "sum", "in1")
model.connect("stiffness", "out", "sum", "in2")
model.connect("sum", "out", "x", "in")
model.connect("sum", "out", "v", "in")

# 3. Create the simulator
sim_cfg = SimulationConfig(dt=0.05, T=30.)
Expand All @@ -93,13 +94,20 @@ plot_from_config(logs, plot_cfg)

The simulated position and velocity exhibit the expected damped oscillatory behavior.

![Alt Text](./docs/User_Guide/images/quick_example.png)
![Damped oscillator simulation](./docs/User_Guide/images/quick_example.png)

See [examples/quick_start/oscillator.py](./examples/quick_start/oscillator.py)
to run the example yourself.

### Graphical Editor

The same model can be constructed visually using the graphical editor:

![GUI Example](./docs/User_Guide/images/gui_example.png)

To open the graphical editor, run:
```bash
pysimblocks
pysimblocks examples/quick_start/gui
```

### Tutorials
Expand Down
Binary file added docs/User_Guide/images/gui_example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions examples/quick_start/gui/layout.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
version: 1
blocks:
v:
x: -570.0
y: -300.0
orientation: normal
width: 120.0
height: 60.0
x:
x: -370.0
y: -300.0
orientation: normal
width: 120.0
height: 60.0
Sum:
x: -740.0
y: -300.0
orientation: normal
width: 120.0
height: 60.0
damping:
x: -570.0
y: -210.0
orientation: flipped
width: 130.0
height: 65.0
stiffness:
x: -555.0
y: -410.0
orientation: flipped
width: 135.0
height: 65.0
connections:
damping.out -> Sum.in2:
ports: [damping.out, Sum.in2]
route: [[-585.0, -177.5], [-755.0, -177.5], [-755.0, -225.0], [-755.0, -225.0],
[-755.0, -260.0], [-746.0, -260.0]]
stiffness.out -> Sum.in1:
ports: [stiffness.out, Sum.in1]
route: [[-570.0, -377.5], [-755.0, -377.5], [-755.0, -322.5], [-755.0, -322.5],
[-755.0, -280.0], [-746.0, -280.0]]
23 changes: 23 additions & 0 deletions examples/quick_start/gui/model.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
blocks:
- name: v
category: operators
type: discrete_integrator
- name: x
category: operators
type: discrete_integrator
- name: Sum
category: operators
type: sum
- name: damping
category: operators
type: gain
- name: stiffness
category: operators
type: gain
connections:
- [Sum.out, v.in]
- [v.out, x.in]
- [v.out, damping.in]
- [x.out, stiffness.in]
- [damping.out, Sum.in2]
- [stiffness.out, Sum.in1]
27 changes: 27 additions & 0 deletions examples/quick_start/gui/parameters.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
simulation:
dt: 0.05
T: 30.0
solver: fixed
blocks:
v:
initial_state: 5.0
method: euler forward
x:
initial_state: 2.0
method: euler forward
Sum:
signs: --
damping:
gain: 0.5
multiplication: Element wise (K * u)
stiffness:
gain: 2.0
multiplication: Element wise (K * u)
logging:
- v.outputs.out
- x.outputs.out
plots:
- title: Position and Velocity
signals:
- v.outputs.out
- x.outputs.out
23 changes: 23 additions & 0 deletions examples/quick_start/gui/run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from pathlib import Path
from pySimBlocks.core import Model, Simulator
from pySimBlocks.project.load_project_config import load_project_config
from pySimBlocks.project.plot_from_config import plot_from_config

try:
BASE_DIR = Path(__file__).parent.resolve()
except Exception:
BASE_DIR = Path("")

sim_cfg, model_cfg, plot_cfg = load_project_config(BASE_DIR / 'parameters.yaml')

model = Model(
name="model",
model_yaml=BASE_DIR / 'model.yaml',
model_cfg=model_cfg
)

sim = Simulator(model, sim_cfg)

logs = sim.run()
if True:
plot_from_config(logs, plot_cfg)
41 changes: 41 additions & 0 deletions examples/quick_start/oscillator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from pySimBlocks import Model, Simulator, SimulationConfig, PlotConfig
from pySimBlocks.blocks.operators import Gain, Sum, DiscreteIntegrator
from pySimBlocks.project.plot_from_config import plot_from_config

# 1. Create the blocks
v = DiscreteIntegrator("v", initial_state=5)
x = DiscreteIntegrator("x", initial_state=2.)
damping = Gain(name="damping", gain=0.5)
stiffness = Gain(name="stiffness", gain=2)
sum = Sum(name="sum", signs="--")

# 2. Build the model
model = Model("Example")
for block in [v, x, damping, stiffness, sum]:
model.add_block(block)

model.connect("v", "out", "x", "in")
model.connect("v", "out", "damping", "in")
model.connect("x", "out", "stiffness", "in")
model.connect("damping", "out", "sum", "in1")
model.connect("stiffness", "out", "sum", "in2")
model.connect("sum", "out", "v", "in")

# 3. Create the simulator
sim_cfg = SimulationConfig(dt=0.05, T=30.)
sim = Simulator(model, sim_cfg)

# 4. Run the simulation
logs = sim.run(logging=[
"x.outputs.out",
"v.outputs.out",
]
)

# 5. Plot the results
plot_cfg = PlotConfig([
{"title": "Position and Velocity",
"signals": ["x.outputs.out", "v.outputs.out"],},
])
plot_from_config(logs, plot_cfg)

10 changes: 9 additions & 1 deletion pySimBlocks/blocks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,14 @@
DeadZone, Delay, DiscreteDerivator, DiscreteIntegrator,
Gain, Mux, Product, RateLimiter, Saturation, Sum, ZeroOrderHold
)
from pySimBlocks.blocks.sources import Constant, Ramp, Step, Sinusoidal, WhiteNoise
from pySimBlocks.blocks.sources import (
Constant,
FunctionSource,
Ramp,
Sinusoidal,
Step,
WhiteNoise,
)
from pySimBlocks.blocks.systems import LinearStateSpace, PolytopicStateSpace

__all__ = [
Expand All @@ -50,6 +57,7 @@
"ZeroOrderHold",

"Constant",
"FunctionSource",
"Ramp",
"Step",
"Sinusoidal",
Expand Down
2 changes: 2 additions & 0 deletions pySimBlocks/blocks/sources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

from pySimBlocks.blocks.sources.constant import Constant
from pySimBlocks.blocks.sources.file_source import FileSource
from pySimBlocks.blocks.sources.function_source import FunctionSource
from pySimBlocks.blocks.sources.ramp import Ramp
from pySimBlocks.blocks.sources.step import Step
from pySimBlocks.blocks.sources.sinusoidal import Sinusoidal
Expand All @@ -28,6 +29,7 @@
__all__ = [
"Constant",
"FileSource",
"FunctionSource",
"Ramp",
"Step",
"Sinusoidal",
Expand Down
Loading