Skip to main content

Modern Python control systems framework with distributed multi-agent simulation

Project description

Synapsys logo

Synapsys

Modern Python control systems framework with distributed multi-agent simulation

CI PyPI version Python Docs License: MIT Coverage Code style: ruff pre-commit

Documentation · Quickstart · PyPI · Examples · Changelog


Overview

Synapsys is an open-source Python library for modelling, simulating, and deploying control systems. It provides a MATLAB-compatible API built on SciPy, a modern multi-agent simulation framework, and a pluggable transport layer (shared memory / ZeroMQ) that scales from a single laptop to distributed lab setups.

Any PyTorch, Keras or JAX model plugs directly into a ControllerAgent via a plain np.ndarray -> np.ndarray callback, making it straightforward to combine classical control theory with deep learning or reinforcement learning.

from synapsys.api import tf, ss, feedback, step, c2d

# SISO
G    = tf([1], [1, 2, 1])    # G(s) = 1 / (s^2 + 2s + 1)
T    = feedback(G)            # closed-loop: T = G / (1 + G)
t, y = step(T)                # step response
Gd   = c2d(G, dt=0.02)       # ZOH discretisation at 50 Hz

# MIMO
G_mimo = tf([[[ 1], [0]],
             [[ 0], [1]]],
            [[[1,1],[1]],
             [[1],[1,2]]])
T_mimo = feedback(G_mimo)     # returns StateSpace closed-loop

Demo — Quadcopter MIMO Neural-LQR

12-state linearised quadcopter controlled by a residual Neural-LQR (du = -K*e + MLP(e)). The MLP output layer is zeroed at initialisation, so the controller starts as provably stable LQR and the residual can be trained later via RL or imitation learning without destabilising the loop.

PyVista 3D window — drone tracking a figure-8 trajectory in real time
PyVista 3D window — drone mesh, trajectory trail and live HUD at 50 Hz
matplotlib telemetry — position, Euler angles and control inputs
matplotlib telemetry — x-y position, altitude, Euler angles and control deviations

Full walkthrough: Quadcopter MIMO Neural-LQR example


Features

Feature Description
MATLAB-Compatible API tf(), ss(), c2d(), step(), bode(), feedback(), lsim() — same names, pure Python
LTI Core TransferFunction, StateSpace, and TransferFunctionMatrix with operator overloading, poles, zeros, stability
MIMO Support TransferFunctionMatrix for multi-input multi-output plants, MIMO feedback(), transmission zeros via Rosenbrock pencil
Control Algorithms Discrete PID with anti-windup, LQR via algebraic Riccati equation (Q/R validated)
AI Integration Any PyTorch, Keras or JAX model as a controller — plain callable interface, no wrappers
Multi-Agent Simulation PlantAgent and ControllerAgent with lock-step and wall-clock sync
Distributed Transport Zero-copy shared memory (single-host) and ZeroMQ PUB/SUB and REQ/REP (multi-process / multi-machine)
Hardware Abstraction HardwareInterface contract enables seamless MIL to SIL to HIL transitions
Matrix Builders StateEquations, mat(), col(), row() — define state-space models from named equations

Installation

Requirements: Python >= 3.10, NumPy >= 1.24, SciPy >= 1.10, pyzmq >= 25.0

# pip
pip install synapsys

# uv
uv add synapsys

# Poetry
poetry add synapsys

# conda / mamba  (conda-forge)
conda install -c conda-forge synapsys

For 3D visualisation (quadcopter example):

pip install synapsys[viz] torch matplotlib

For development:

git clone https://github.com/synapsys-lab/synapsys.git
cd synapsys
uv sync --extra dev

Quickstart

1. LTI systems and frequency analysis

from synapsys.api import tf, ss, bode, feedback, c2d

# SISO second-order transfer function
G = tf([1], [1, 2, 1])

# Closed-loop with unity negative feedback
T = feedback(G)

# Frequency response
w, mag, phase = bode(G)

# ZOH discretisation at 50 Hz
Gd = c2d(G, dt=0.02)

# MIMO: 2x2 transfer-function matrix
G_mimo = tf(
    [[[1], [0]], [[0], [1]]],
    [[[1, 1], [1]], [[1], [1, 2]]],
)
T_mimo = feedback(G_mimo)    # returns StateSpace

2. Control algorithms

from synapsys.algorithms import PID, lqr
import numpy as np

# Discrete PID with anti-windup saturation
pid = PID(Kp=3.0, Ki=0.5, Kd=0.1, dt=0.01, u_min=-10.0, u_max=10.0)
u   = pid.compute(setpoint=5.0, measurement=y)

# LQR — solves the algebraic Riccati equation
A = np.array([[0., 1.], [-2., -3.]])
B = np.array([[0.], [1.]])
K, P = lqr(A, B, Q=np.eye(2), R=np.eye(1))
# Control law: u = -K * x

3. State-space from named equations

from synapsys.utils import StateEquations

m, c, k = 1.0, 0.1, 2.0

eqs = (
    StateEquations(states=["x1", "x2", "v1", "v2"], inputs=["F"])
    .eq("x1", v1=1).eq("x2", v2=1)
    .eq("v1", x1=-2*k/m, x2=k/m,  v1=-c/m)
    .eq("v2", x1=k/m,  x2=-2*k/m, v2=-c/m, F=1/m)
)

print(eqs.A)   # 4x4 system matrix
print(eqs.B)   # 4x1 input matrix

4. Multi-agent closed-loop simulation

from synapsys.api import ss, c2d
from synapsys.agents import PlantAgent, ControllerAgent, SyncEngine, SyncMode
from synapsys.algorithms import PID
from synapsys.transport import SharedMemoryTransport
import numpy as np

# Discretise G(s) = 1/(s+1) at 100 Hz
plant_d = c2d(ss([[-1]], [[1]], [[1]], [[0]]), dt=0.01)

with SharedMemoryTransport("demo", {"y": 1, "u": 1}, create=True) as bus:
    bus.write("y", np.zeros(1))
    bus.write("u", np.zeros(1))

    pid  = PID(Kp=4.0, Ki=1.0, dt=0.01)
    def law(y: np.ndarray) -> np.ndarray:
        return np.array([pid.compute(setpoint=3.0, measurement=y[0])])

    sync = SyncEngine(SyncMode.WALL_CLOCK, dt=0.01)

    PlantAgent("plant", plant_d, bus, sync).start(blocking=False)
    ControllerAgent("ctrl",  law,  bus, sync).start(blocking=True)

5. MIL to SIL to HIL — swap transport, keep algorithm

# MIL — shared memory, single host
from synapsys.transport import SharedMemoryTransport
bus = SharedMemoryTransport("demo", {"y": 1, "u": 1}, create=True)

# SIL — ZeroMQ, cross-process or cross-machine
from synapsys.transport import ZMQTransport
bus = ZMQTransport("tcp://localhost:5555", mode="pub")

# HIL — real hardware
from synapsys.agents import HardwareAgent
from synapsys.hw import MockHardwareInterface
hw    = MockHardwareInterface(n_inputs=1, n_outputs=1, plant_fn=my_hw)
agent = HardwareAgent("hw", hw, bus, sync)

# PlantAgent and ControllerAgent stay exactly the same in all three modes

Examples

Example Description
basic/step_response.py Step response of a 2nd-order system
distributed/plant.py + controller.py Two-process PID loop via shared memory
distributed/plant_zmq.py Same loop over ZeroMQ (cross-machine)
advanced/01_custom_signals.py Custom reference signals with lsim()
advanced/02_sil_ai_controller/02b_sil_ai_controller.py SIL + Neural-LQR PyTorch controller on 2-DOF mass-spring-damper
advanced/03_realtime_scope.py Text-mode real-time oscilloscope
advanced/04_realtime_matplotlib.py Live matplotlib oscilloscope
advanced/05_digital_twin/05_digital_twin.py Digital twin with mechanical wear detection
advanced/06_quadcopter_mimo/ 12-state quadcopter MIMO Neural-LQR with PyVista 3D, config GUI, GIF export
quickstart_en.ipynb Interactive Jupyter notebook walkthrough

Architecture

synapsys/
├── api/            # MATLAB-compatible facade  (tf, ss, c2d, step, bode, feedback, ...)
├── core/           # LTI math — TransferFunction, StateSpace, TransferFunctionMatrix, LTIModel
├── algorithms/     # PID (discrete, anti-windup), LQR (ARE solver)
├── agents/         # PlantAgent, ControllerAgent, HardwareAgent, SyncEngine
├── broker/         # MessageBroker, Topic, SharedMemoryBackend, ZMQBrokerBackend
├── transport/      # SharedMemoryTransport, ZMQTransport, ZMQReqRepTransport
├── hw/             # HardwareInterface (abstract) + MockHardwareInterface
└── utils/          # StateEquations, mat(), col(), row()

The transport layer is the key abstraction: agents communicate exclusively through a TransportStrategy interface. The broker/ module adds a higher-level pub/sub bus (backed by shared memory or ZMQ) for multi-agent scenarios. Swapping the concrete transport or broker backend requires changing one line — algorithms and agents are untouched.


Testing

uv run pytest                      # run all tests
uv run pytest --cov=synapsys       # with coverage report
uv run mypy synapsys               # type checking
uv run ruff check synapsys tests   # linting
Metric Value
Test suite 287 tests
Coverage 100%
Type checking mypy strict — 0 errors
Pre-commit hooks ruff lint + format, mypy, pytest
Python versions 3.10, 3.11, 3.12

Roadmap

Version Status Features
v0.1.0 Released SISO LTI, PID, LQR, multi-agent, shared memory, ZMQ, hardware abstraction, Neural-LQR example
v0.2.0 Released MIMO support — TransferFunctionMatrix, MIMO feedback(), transmission zeros (Rosenbrock pencil), LQR Q/R validation, covariant type annotations
v0.2.1 Released Quadcopter MIMO Neural-LQR example with PyVista 3D, config GUI, GIF export, version sync fix
v0.2.2 Released MessageBroker pub/sub bus, 100% test coverage, mypy strict, pre-commit hooks
v0.3 Planned margin(), rlocus(), pole_placement(), Kalman filter, Luenberger observer
v0.5 Planned Real hardware drivers (serial, CAN, FPGA via PYNQ)

See CHANGELOG.md for the full release history.


Citing

If you use Synapsys in academic work, please cite it as:

BibTeX

@software{synapsys2026,
  author    = {Farias, Oseias D. and contributors},
  title     = {Synapsys: A Python Framework for Modelling and
               Real-Time Simulation of Linear Control Systems},
  year      = {2026},
  url       = {https://github.com/synapsys-lab/synapsys},
  license   = {MIT},
}

APA

Farias, O. D., & contributors. (2026). Synapsys: A Python framework for
modelling and real-time simulation of linear control systems.
https://github.com/synapsys-lab/synapsys

For the version number, use the version shown on PyPI.


Contributing

Contributions are welcome. Please open an issue to discuss what you would like to change before submitting a pull request.

git clone https://github.com/synapsys-lab/synapsys.git
cd synapsys
uv sync --extra dev
uv run pre-commit install   # install git hooks (ruff, mypy, pytest)
uv run pytest               # make sure everything passes before you start

Contributors


License

MIT © 2026 Synapsys Contributors

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

synapsys-0.2.2.tar.gz (11.1 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

synapsys-0.2.2-py3-none-any.whl (43.3 kB view details)

Uploaded Python 3

File details

Details for the file synapsys-0.2.2.tar.gz.

File metadata

  • Download URL: synapsys-0.2.2.tar.gz
  • Upload date:
  • Size: 11.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for synapsys-0.2.2.tar.gz
Algorithm Hash digest
SHA256 503364346c81d2cb32f092bbc8c66a1d672146dd0e062af128f8076321877c2b
MD5 71b61389b709019c6d9c00a52c3b04b6
BLAKE2b-256 cba58d2fb1c43f2fb6b0f0815ab54db318fb8b9d32412acd91060c1094b2435e

See more details on using hashes here.

Provenance

The following attestation bundles were made for synapsys-0.2.2.tar.gz:

Publisher: publish.yml on synapsys-lab/synapsys

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file synapsys-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: synapsys-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 43.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for synapsys-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 1b193d847100f21fcf537c13f10d3e5797476f77cb6137d5b3135d765b15e33c
MD5 14f8a983b532b74c9f17699ecbe99394
BLAKE2b-256 8be6af98e5b2675242d76217624eeac35aebba15e94f18116419717617a4a96b

See more details on using hashes here.

Provenance

The following attestation bundles were made for synapsys-0.2.2-py3-none-any.whl:

Publisher: publish.yml on synapsys-lab/synapsys

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page