Diagram Class¶
The Diagram class is the central object for creating and managing control system diagrams in Lynx.
Overview¶
A diagram contains:
Blocks: Computational units (Gain, TransferFunction, StateSpace, Sum, IOMarker)
Connections: Directed edges between block ports
Metadata: Labels, positions, and parameters
All modifications are performed in-place. Diagrams can be saved to and loaded from JSON files.
Creating Diagrams¶
import lynx
# Create empty diagram
diagram = lynx.Diagram()
# Load existing diagram
diagram = lynx.Diagram.load("diagram.json")
# Create new diagram from template
diagram = lynx.Diagram.from_template("feedforward_tf")
Adding Blocks¶
Use add_block() to add blocks to your diagram:
# Syntax: add_block(block_type, block_id, **parameters)
# Gain block
diagram.add_block('gain', 'controller', K=5.0, position={'x': 100, 'y': 50})
# Transfer function: G(s) = 2/(s+3)
diagram.add_block('transfer_function', 'plant',
num=[2.0],
den=[1.0, 3.0],
position={'x': 200, 'y': 50})
# State-space block with A, B, C, D matrices
import numpy as np
A = np.array([[-1, 0], [0, -2]])
B = np.array([[1], [1]])
C = np.array([[1, 0]])
D = np.array([[0]])
diagram.add_block('state_space', 'ss_system',
A=A, B=B, C=C, D=D,
position={'x': 300, 'y': 50})
# Sum block with configurable signs
diagram.add_block('sum', 'error_sum',
signs=['+', '-', '|'], # top, left, bottom
position={'x': 50, 'y': 50})
# I/O markers for system boundaries
diagram.add_block('io_marker', 'r', marker_type='input', label='r', position={'x': 0, 'y': 50})
diagram.add_block('io_marker', 'y', marker_type='output', label='y', position={'x': 400, 'y': 50})
Adding Connections¶
Use add_connection() to connect block ports:
# Syntax: add_connection(connection_id, source_block, source_port, target_block, target_port)
# Basic connection
diagram.add_connection('c1', 'controller', 'out', 'plant', 'in')
# Connection with label (useful for export)
diagram.add_connection('c2', 'plant', 'out', 'y', 'in', label='output_signal')
# Feedback connection
diagram.add_connection('c3', 'plant', 'out', 'error_sum', 'in2')
Saving and Loading¶
# Save to JSON file
diagram.save('my_control_system.json')
# Load from JSON file
loaded_diagram = lynx.Diagram.load('my_control_system.json')
JSON format is human-readable and version-controlled friendly.
Exporting to Python-Control¶
Extract transfer functions or state-space representations:
import control as ct
# Export closed-loop transfer function
sys_tf = diagram.get_tf('r', 'y') # From input 'r' to output 'y'
# Export state-space representation
sys_ss = diagram.get_ss('r', 'y')
# Analyze with python-control
bode = ct.bode_plot(sys_tf)
nyquist = ct.nyquist_plot(sys_tf)
See Python-Control Export for details on signal reference patterns.
Interactive Widget¶
Launch the interactive Jupyter widget:
# In Jupyter notebook
lynx.edit(diagram)
This opens a visual editor where you can:
Drag blocks to reposition
Edit parameters via properties panel
Add/remove connections
View block labels and LaTeX rendering
Changes in the widget sync back to the Python object.
API Reference¶
Add a block to the diagram. |
|
Add a connection between two block ports with validation. |
|
Remove block from diagram and all connected edges. |
|
Remove connection from diagram. |
|
Update block parameter (with undo support). |
|
Save diagram to JSON file. |
|
Load diagram from JSON file with optional expression re-evaluation. |
|
Extract transfer function from one signal to another. |
|
Extract state-space model from one signal to another. |
|
Launch interactive widget to edit a diagram. |
See Also¶
Block Types - Detailed block type reference
Python-Control Export - Signal references and subsystem extraction
Validation - Pre-export validation