lynx.Diagram.get_ss¶
- Diagram.get_ss(from_signal: str, to_signal: str) Any[source]¶
Extract state-space model from one signal to another.
Converts a Lynx diagram to a python-control StateSpace object representing the system dynamics from from_signal to to_signal. Automatically handles subsystem extraction, sign negation for sum blocks, and connection routing.
- Signal Reference Patterns (4-tier priority system):
IOMarker labels (highest priority): Use the ‘label’ parameter from InputMarker or OutputMarker blocks (e.g., ‘r’, ‘y’, ‘u’)
Connection labels: Reference labeled connections between blocks (e.g., ‘error’, ‘control’)
Block.port format: Explicit block ID and port using dot notation (e.g., ‘controller.out’, ‘plant.in’)
Block labels (lowest priority, SISO only): For single-input/single-output blocks, reference by block label (e.g., ‘controller’, ‘plant’)
- Parameters:
from_signal – Source signal name using any of the 4 reference patterns
to_signal – Destination signal name using any of the 4 reference patterns
- Returns:
State-space system from from_signal → to_signal
- Return type:
- Raises:
SignalNotFoundError – If either signal doesn’t exist in the diagram
ValidationError – If diagram has missing I/O markers or unconnected ports
DiagramExportError – If python-control conversion fails
Examples
>>> # Complete feedback loop example >>> diagram = Diagram() >>> diagram.add_block('io_marker', 'ref', marker_type='input', label='r') >>> diagram.add_block('sum', 'error_sum', signs=['+', '-', '|']) >>> diagram.add_block('gain', 'controller', K=5.0, label='C') >>> diagram.add_block('transfer_function', 'plant', ... numerator=[2.0], denominator=[1.0, 3.0], label='P') >>> diagram.add_block( ... 'io_marker', 'output', marker_type='output', label='y' ... ) >>> >>> diagram.add_connection('c1', 'ref', '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', 'output', 'in') >>> diagram.add_connection('c5', 'plant', 'out', 'error_sum', 'in2') >>> >>> # Extract closed-loop transfer function (IOMarker labels) >>> sys_ry = diagram.get_ss('r', 'y') >>> print(f"DC gain: {sys_ry.dcgain()}") # Should be ~0.769 >>> >>> # Extract sensitivity function (IOMarker + connection label) >>> sys_re = diagram.get_ss('r', 'e') >>> >>> # Extract controller transfer function (connection labels) >>> sys_eu = diagram.get_ss('e', 'u') >>> >>> # Extract using block.port format (explicit) >>> sys_cp = diagram.get_ss('controller.out', 'plant.out') >>> >>> # Extract using block labels (SISO blocks only) >>> sys_CP = diagram.get_ss('C', 'P') # Same as controller → plant