Blocks¶
Basic dynamic blocks: the integrator.
- class minilink.blocks.basic.Integrator[source]¶
Single integrator block:
dx = k * u,y = x.The gain
kdefaults to 1.0 (a pure integrator); it also serves as the canonical scalar block parameter in tests and demos.- f(x, u, t=0, params=None)[source]¶
State derivative
dx = f(x, u, t; p).Subclasses should treat this as a function of
(x, u, t, params)only; the library does not verify purity.- Parameters:
x (array of shape (n,))
u (array of shape (m,))
t (float)
params (dict, optional) –
Nonemeans “useself.params”.
- Returns:
dx
- Return type:
array of shape (n,)
- h(x, u, t=0, params=None)[source]¶
Output
y = h(x, u, t; p).Default: the full state,
y = x, when theyport has the state dimension (p == n); zeros otherwise. Override for any other measurement.- Parameters:
x (array of shape (n,))
u (array of shape (m,))
t (float)
params (dict, optional)
- Returns:
y
- Return type:
array of shape (p,)
Source blocks: constant, step, sine, white noise and a replayed trajectory as a signal.
- class minilink.blocks.sources.Source(p, *, port='y')[source]¶
Constant source:
y = valuefor allt.Also the base class for time-signal sources; subclasses override
h()with their owny = h(t; p).portnames the output signal:yby default, or the input it drives (Step(port="r"),WhiteNoise(port="d")), which is howautowirefinds it.- property dim¶
The signal’s dimension, whatever the output port is named.
- h(x, u, t=0, params=None)[source]¶
Output
y = h(x, u, t; p).Same purity contract as port
compute(convention only; not enforced).- Parameters:
x (array of shape (n,))
u (array of shape (m,))
t (float)
params (dict, optional)
- Returns:
y
- Return type:
array of shape (p,)
- show_signal(t0=None, tf=None, n_pts=1000, ax=None)[source]¶
Plot the source output signal over a time range.
- Parameters:
t0 (float, optional) – Start time (default 0.0).
tf (float, optional) – End time (default 10.0).
n_pts (int, optional) – Number of evaluation points used for plotting.
ax (matplotlib.axes.Axes, optional) – Existing axis to draw on. If None, a new figure is created and shown (same policy as
minilink.graphical.signals.plot_time_signals()); if an axis is passed, the caller controls display.
- class minilink.blocks.sources.Step(initial_value=None, final_value=None, step_time=1.0, *, port='y')[source]¶
Step source:
y = initial_valueift < step_time, elsefinal_value.
- class minilink.blocks.sources.Sine(amplitude=1.0, omega=1.0, phase=0.0, offset=0.0, *, port='y')[source]¶
Sine source:
y = offset + amplitude sin(omega t + phase),omegain rad/s.amplitudesets the dimension;omega,phaseandoffsetare scalars or arrays of the same shape. A frequencyfin hertz isomega = 2 * np.pi * f.
- class minilink.blocks.sources.WhiteNoise(p=1, *, psd=1.0, sample_period=0.01, seed=0, hold='zoh', port='y')[source]¶
White noise of intensity
psd, held over eachsample_period.The intensity is the two-sided spectral density of the signal (a one-sided estimate such as
scipy.signal.welch’s default reads twice it). The per-sample covariance is the intensity over the period, so the physics does not change with the period; a per-sample variance over a period is an intensity of variance times period. The zero-order hold keeps each sample for its whole period;hold="linear"interpolates between samples, with a mid-period variance of half the per-sample one. A fixed step that divides the period keeps RK4’s stages inside one sample except the last stage of a boundary step, an effect first order in the step. The sample counter is 32 bits: the signal repeats after 2³² samples.seed=Nonegives the mean (zero); the seed is the block’s default realization,realize()draws another. A scalar or vectorpsdis a diagonal intensity, a matrix a full one.- is_random = True¶
Whether the block draws random numbers from a seed in its
params.
- property psd¶
a
(p,)diagonal or a(p, p)matrix.- Type:
The intensity
W
- class minilink.blocks.sources.TrajectorySource(t, values, *, interpolation='linear', port='y')[source]¶
Replay a stored signal
y(t)sampled at timest.The open-loop policy
u = pi(t): feed a planned input trajectory into a diagram,source >> plant. Between samples the signal is interpolated linearly (interpolation="linear", what a collocation or shooting transcription assumes) or held at the previous sample ("previous", the zero-order hold of a sampled controller). Values outside[t[0], t[-1]]hold the nearest endpoint.valueshas shape(p, N)(or(N,)for a scalar signal) aligned with theNsample times int.- classmethod from_trajectory(traj, signal='u', *, interpolation='linear')[source]¶
Build a source that replays a
Trajectorysignal (uorx).
Transfer-function blocks: a SISO TransferFunction in state space, and Lead / Lag.
- class minilink.blocks.transfer_function.TransferFunction(numerator, denominator, *, ports=None, name='Transfer Function', expose_state=True)[source]¶
Continuous-time SISO transfer function in state-space realization.
The default is a plant: input
u, outputsyandx;expose_state=Falsekeepsu -> yonly (a filter is not a plant). Compensator layouts match the other classical blocks:ports="error"ise -> u(C @ plantinserts the Error block;C >> plantis the loop gain);ports="reference"isr, y -> u.- f(x, u, t=0, params=None)[source]¶
State derivative
dx = f(x, u, t; p).Subclasses should treat this as a function of
(x, u, t, params)only; the library does not verify purity.- Parameters:
x (array of shape (n,))
u (array of shape (m,))
t (float)
params (dict, optional) –
Nonemeans “useself.params”.
- Returns:
dx
- Return type:
array of shape (n,)
- h(x, u, t=0, params=None)[source]¶
Output
y = h(x, u, t; p).Default: the full state,
y = x, when theyport has the state dimension (p == n); zeros otherwise. Override for any other measurement.- Parameters:
x (array of shape (n,))
u (array of shape (m,))
t (float)
params (dict, optional)
- Returns:
y
- Return type:
array of shape (p,)
- class minilink.blocks.transfer_function.Lead(K=1.0, z=1.0, p=10.0, *, ports='error')[source]¶
Lead compensator
C(s) = K (s + z) / (s + p)withz < p: phase lead betweenzandp.
- class minilink.blocks.transfer_function.Lag(K=1.0, z=1.0, p=0.1, *, ports='error')[source]¶
Lag compensator
C(s) = K (s + z) / (s + p)withp < z: gain at low frequency.
Signal routing blocks: the error comparison, a signed sum, a gain, mux and demux.
- class minilink.blocks.routing.Error(dim=1)[source]¶
Tracking-error comparison
e = r - yon ports+,-,e.The automatic feedback pattern (
C @ plant,feedback(L)) inserts this block so the diagram reads as a comparison, not a generic summer. All three ports share the same dimensiondim.
- class minilink.blocks.routing.Sum(signs=(1.0, -1.0), dim=1)[source]¶
Signed summing junction
y = Σ sign_i · in_ion portsin0, in1, ….The default
signs=(1.0, -1.0)is a two-input differencey = in0 - in1. UseErrorfor the named tracking-error comparison that@inserts. All input ports share the same dimensiondim.signsis a structural attribute fixed at construction (it sets the number of input ports), deliberately not a tunableparamsentry.
- class minilink.blocks.routing.Gain(K, dim=None)[source]¶
Constant gain
y = K · u.Kmay be a full(p, m)matrix, a 1-D vector (diagonal gain), or a scalar (needsdimto set the port size). The gain lives inparams["K"]so it can be tuned or differentiated.
- class minilink.blocks.routing.Mux(dims=(1, 1))[source]¶
Stack input signals
in0, in1, …into one vector outputy.dimslists each input-port dimension; the output dimension is their sum. The combined signal is just the concatenation in port order, so the compute is the identity on the stacked input vector.
- class minilink.blocks.routing.Demux(dims=(1, 1), *, port='u')[source]¶
Split one vector into NumPy-style slices of a named signal.
dimslists each output-port dimension; the input dimension is their sum. The input port isport(defaultu); each output is the corresponding slice,u[0],u[1], oru[0:2]for a wider block. Auto-wired feedback passes the plant port name so aymeasurement becomesyin andy[0],y[1], … out.
Static nonlinearities: saturation, dead zone, relay, and the stateful rate limiter.
- class minilink.blocks.nonlinear.Saturation(lower=-1.0, upper=1.0, dim=1)[source]¶
Symmetric or asymmetric clip
y = clip(u, lower, upper).
- class minilink.blocks.nonlinear.DeadZone(width=1.0, dim=1)[source]¶
Dead zone of half-width
width: zero inside, shifted outside.y = u - widthforu > width,y = u + widthforu < -width, andy = 0in between — the standard backlash/stiction model.
- class minilink.blocks.nonlinear.Relay(amplitude=1.0, dim=1)[source]¶
Bang-bang relay
y = amplitude · sign(u)(sign(0) = 0).
- class minilink.blocks.nonlinear.RateLimiter(rate_max=1.0, tau=0.05, lower=-inf, upper=inf, dim=1, x0=0.0)[source]¶
Pass a command through, limited to
rate_maxper second and to the end stops.- Parameters:
rate_max (float) – Largest rate of change of the output [unit/s]; must be positive.
tau (float) – Time constant of the lag the block shows for small steps [s]; must be positive. The knee between the two regimes sits at a step of about
tau * rate_max.lower (float) – End stops on the output [unit]; infinite by default, i.e. a rate limit only.
upper (float) – End stops on the output [unit]; infinite by default, i.e. a rate limit only.
dim (int) – Number of independent channels.
x0 (float or array) – Output at
t = 0[unit], one value or one per channel.
- f(x, u, t=0.0, params=None)[source]¶
State derivative
dx = f(x, u, t; p).Subclasses should treat this as a function of
(x, u, t, params)only; the library does not verify purity.- Parameters:
x (array of shape (n,))
u (array of shape (m,))
t (float)
params (dict, optional) –
Nonemeans “useself.params”.
- Returns:
dx
- Return type:
array of shape (n,)
- h(x, u, t=0.0, params=None)[source]¶
Output
y = h(x, u, t; p).Default: the full state,
y = x, when theyport has the state dimension (p == n); zeros otherwise. Override for any other measurement.- Parameters:
x (array of shape (n,))
u (array of shape (m,))
t (float)
params (dict, optional)
- Returns:
y
- Return type:
array of shape (p,)
Signal-conditioning filters: Butterworth low-pass, notch and washout, from a frequency in Hz.
- class minilink.blocks.filters.LowPassFilter(cutoff_hz=1.0, order=1)[source]¶
Butterworth low-pass with
-3 dBcutoff atcutoff_hz(order 1 default).First order is
H(s) = ω_c / (s + ω_c)withω_c = 2π·cutoff_hz; higherorderuses the analog Butterworth realization. A filter isu -> yand not a plant: it exposes no statex.
- class minilink.blocks.filters.NotchFilter(notch_hz=1.0, quality=10.0)[source]¶
Second-order notch (band-stop) at
notch_hzwith quality factorquality.H(s) = (s² + ω₀²) / (s² + (ω₀/Q)·s + ω₀²)withω₀ = 2π·notch_hz; largerqualitynarrows the rejected band. A filter isu -> yand not a plant: it exposes no statex.
- class minilink.blocks.filters.Washout(cutoff_hz=1.0)[source]¶
First-order high-pass / washout
H(s) = s / (s + ω_c).Passes transients and rejects the steady component;
ω_c = 2π·cutoff_hz. A filter isu -> yand not a plant: it exposes no statex.
Discrete-time wiring blocks: a command latch on the step side of a hybrid loop.
- class minilink.blocks.step.ZOHHold[source]¶
Command latch:
x_{k+1} = u_k,y_k = x_k.Teaches the zero-order hold / hold-register pattern on the step side of hybrid boundaries (plant-side holds are handled by
HybridSimulator).
Neural-network static blocks: the weights are parameters, the training lives outside.
- class minilink.blocks.neural.NeuralNetwork(input_dim, output_dim, hidden_dim=8, seed=0, scale=0.1)[source]¶
One-hidden-layer neural network
y = W2 tanh(W1 u + b1) + b2.- Parameters:
input_dim (int) – Dimension of the input port
u.output_dim (int) – Dimension of the output port
y.hidden_dim (int, optional) – Number of hidden units.
seed (int, optional) – Seed for deterministic weight initialization.
scale (float, optional) – Standard-deviation scale for the initial weights. Biases start at zero.
- class minilink.blocks.neural.MLP(input_dim, output_dim, hidden=(64, 64), activation='tanh', seed=0, output_gain=1.0)[source]¶
Multilayer perceptron
y = W_L a_{L-1} + b_Lwitha_k = act(W_k a_{k-1} + b_k).Weights live in
paramsas{"W0", "b0", "W1", "b1", ...}so training loops differentiate through the compiled diagram like any other parameter.- Parameters:
input_dim (int) – Port dimensions.
output_dim (int) – Port dimensions.
hidden (tuple of int) – Hidden layer widths;
()gives an affine map.activation ({"tanh", "relu"}) – Hidden nonlinearity.
seed (int) – Seed of the orthogonal initialization.
output_gain (float) – Gain of the last layer’s orthogonal init (
0.01for a policy mean that starts near zero,1.0for a value function).