Quickstart¶
This guide will walk you through creating your first Lynx control system diagram: a simple feedback control loop with a proportional controller and first-order plant.
Installation¶
The recommended way to install Lynx is via pip:
pip install lynx-nb
Interactive Editor¶
Launch a Jupyter notebook:
import lynx
import control
import numpy as np
The easiest way to build a diagram is with the inline editor:
diagram = lynx.Diagram() # Empty diagram
lynx.edit(diagram) # Launch the Jupyter widget
This opens an interactive view where you can:
Pan and zoom
Add blocks and make connections
Edit parameters via the properties panel
Drag blocks to reposition
When you’re done you can save the diagram to a JSON:
# Serialize the diagram, including positions, connections, and parameters
diagram.save("demo.json")
# Load the diagram
diagram = lynx.Diagram.load("demo.json")
Note
The editor has access to the full notebook environment, so any variables or valid Python expressions you type can be evaluated to a block parameter.
Programmatic Construction¶
Alternatively, diagrams can be constructed programmatically. For example, the following code defines a simple feedback control loop:
diagram = lynx.Diagram() # Empty diagram
# Add input/output markers
diagram.add_block('io_marker', 'r', marker_type='input', label='r',
position={'x': 0, 'y': 0}) # Reference
diagram.add_block('io_marker', 'y', marker_type='output', label='y',
position={'x': 500, 'y': 0}) # Output
# Add controller
diagram.add_block('gain', 'controller', K=5.0,
position={'x': 150, 'y': 0})
# Add plant: 2/(s+3)
diagram.add_block('transfer_function', 'plant',
num=[2.0],
den=[1.0, 3.0],
position={'x': 300, 'y': 0})
# Add summing junction for error calculation
diagram.add_block('sum', 'error_sum',
signs=['+', '-', '|'], # Top: +, Left: -, Bottom: disabled
position={'x': 75, 'y': 0})
# Forward path
diagram.add_connection('c1', 'r', 'out', 'error_sum', 'in1')
diagram.add_connection('c2', 'error_sum', 'out', 'controller', 'in', label='e')
diagram.add_connection('c3', 'controller', 'out', 'plant', 'in', label='u')
diagram.add_connection('c4', 'plant', 'out', 'y', 'in')
# Feedback path
diagram.add_connection('c5', 'plant', 'out', 'error_sum', 'in2')
The diagram can be handled in exactly the same way:
# Save to JSON file
diagram.save('demo.json')
Export and Analyze¶
You can also extract python-control transfer function or state-space representations between any two labeled signals or I/O markers:
G = diagram.get_ss('u', 'y') # Plant as state-space model
S = diagram.get_tf('r', 'e') # Sensitivity transfer function
This is the core of the ecosystem interoperability, making it seamless to inject parameters from code and extract subsystems back into the workflow.
# Extract closed-loop transfer function from r to y
sys = diagram.get_tf('r', 'y')
# Analyze step response
t = np.linspace(0, 5, 500)
t_out, y_out = control.step_response(sys, t)
# Print DC gain and settling time
print(f"DC Gain: {y_out[-1]:.3f}")
print(f"Final value: {y_out[-1]}")
Next Steps¶
Cruise Control Example: Complete example of a control system workflow
API Reference: Explore all available blocks and methods