| Title: | A Control Systems Toolbox |
|---|---|
| Description: | Solves control systems problems relating to time/frequency response, LTI systems design and analysis, transfer function manipulations, and system conversion. |
| Authors: | Ben C. Ubah [aut, cre] |
| Maintainer: | Ben C. Ubah <[email protected]> |
| License: | GPL-2 |
| Version: | 0.2.7 |
| Built: | 2026-05-13 06:33:34 UTC |
| Source: | https://github.com/benubah/control |
abcdchk verifies the dimensions of A,B,C,D matrices in its arguments, to ascertain that they are correctly defined.
abcdchk(a, b, c, d)abcdchk(a, b, c, d)
a |
An n x n matrix |
b |
An n x m matrix |
c |
An p x n matrix |
d |
An p x m matrix |
This is a utility function that is always invoked by other functions to
ascertain the dimensions of the arguments a,b,c,d and returns a message
if there is an ill-defined entry.
Returns an empty string if matrix dimensions are consistent. Otherwise it returns the associated error message
A <- rbind(c(0,1), c(-10000,-4)) B <- rbind(0,1) C <- rbind(c(1,0), c(0,1)) D <- rbind(0,0) message <- abcdchk(A,B,C,D)A <- rbind(c(0,1), c(-10000,-4)) B <- rbind(0,1) C <- rbind(c(1,0), c(0,1)) D <- rbind(0,0) message <- abcdchk(A,B,C,D)
Computes the Pole placement gain selection using Ackermann's formula.
acker(a, b, p)acker(a, b, p)
a |
State-matrix of a state-space system |
b |
Input-matrix of a state-space system |
p |
closed loop poles |
K <- ACKER(A,B,P) calculates the feedback gain matrix K such that the single input system . x <- Ax + Bu
with a feedback law of u <- -Kx has closed loop poles at the values specified in vector P, i.e., P <- eigen(A - B * K).
This method is NOT numerically stable and a warning message is printed if the nonzero closed loop poles are greater than 10 in P.
F <- rbind(c(0,1),c(0,0)) G <- rbind(0,1) H <- cbind(1,0); J <- 0 t <- 1 sys <- ss(F,G, H,J) A <- c2d(sys,t); j <- sqrt(as.complex(-1)); pc <- rbind(0.78+0.18*j, 0.78-0.18*j) K <- acker(A$A, A$B, pc)F <- rbind(c(0,1),c(0,0)) G <- rbind(0,1) H <- cbind(1,0); J <- 0 t <- 1 sys <- ss(F,G, H,J) A <- c2d(sys,t); j <- sqrt(as.complex(-1)); pc <- rbind(0.78+0.18*j, 0.78-0.18*j) K <- acker(A$A, A$B, pc)
append appends the dynamics of a set of n-state-space systems together
append(...)append(...)
... |
Variable argument for LTI system models of tf, ss or zpk class |
append(sys1, sys2, sys3,...sysN) first combines the the first two systems and then
goes on to combine the resulting state-space system to the next system and so forth.
This is achieved by calling the sysgroup(sys1, sys2) at each iteration to group
the systems in consecutive pairs until all systems are
completely appended to form one system.
sysgroup(sys1, sys2) appends only two systems and is used by append
If a system is not in state-space representation, the function tries to form a state-space representation for such system.
The function returns a state-space model of the formed appended system with A, B, C, D matrices
series parallel feedback connect
sys1 <- ss(1,2,3,4) sys2 <- ss(2,3,4,5) sys3 <- ss(6,7,8,9) append(sys1, sys2, sys3) sys4 <- tf(1, c(1,2,5)) append(sys1, sys2, sys4)sys1 <- ss(1,2,3,4) sys2 <- ss(2,3,4,5) sys3 <- ss(6,7,8,9) append(sys1, sys2, sys3) sys4 <- tf(1, c(1,2,5)) append(sys1, sys2, sys4)
bode computes the magnitude and phase of the frequency response of system sys
at given frequencies w
General Usage:
bode(sys)
bode(sys, w)
bode(sys, w, iu)
bode(sys, w = seq(0, 100, length = 10000), iu = 1)
bodeplot(sys)
bodeplot(sys, w)
bodeplot(sys, w, subtitle)
bode(sys, w, iu)bode(sys, w, iu)
sys |
LTI system of transfer-function, state-space and zero-pole classes |
w |
vector of range of frequencies at the response is computed in rad/sec |
iu |
number to specify an input for a MIMO state-space system. If the system has
3 inputs, then |
bode Compute the magnitude and phase of the frequency response of system sys
at given frequencies w. When sys is a transfer function, bode
computes the frequency response of the system using the signal package.
bodeplot plots the frequency response computed by bode. For a MIMO state-space system,
bodeplot uses selectsys to obtain the bode response for each input-to-output pair and plot
them individually. This means that for a 2-input, 2-output system, bodeplot obtains the response
for input 1 to output 1, input 1 to output 2, input 2 to output 1 and input 2 to output 2.
bodeplot uses the subtitle argument to allow a user assign the plot a sub-title
A list is returned by calling bode containing:
w - frequencies
mag - magnitude of the response
phase - phase of the response
A plot is returned by calling bodeplot
bode(tf(100, c(1,6,100))) bode(ssdata(tf(100, c(1,6,100)))) bode(tf(4, c(1,1))) A <- rbind(c(-2, -1), c(1,0)); B <- rbind(1,0); C <- cbind(0,1); D <- as.matrix(0); bode(ss(A,B,C,D)) ## MIMO plot A1 <- rbind(c(0,1), c(-25,-4)); B1 <- rbind(c(1,1), c(0,1)) C1 <- rbind(c(1,0), c(0,1)); D1 <- rbind(c(0,0), c(0,0)) sys1 <- ss(A1,B1,C1,D1) bodeplot(sys1) # Use: par(mfrow = c(2,1)); bodeplot(selectsys(sys1,1,2)) to obtain the response for a subsystem # of sys1 for input 1 and output 2 only # RESET your plot layout using par(mfrow = c(1,1))bode(tf(100, c(1,6,100))) bode(ssdata(tf(100, c(1,6,100)))) bode(tf(4, c(1,1))) A <- rbind(c(-2, -1), c(1,0)); B <- rbind(1,0); C <- cbind(0,1); D <- as.matrix(0); bode(ss(A,B,C,D)) ## MIMO plot A1 <- rbind(c(0,1), c(-25,-4)); B1 <- rbind(c(1,1), c(0,1)) C1 <- rbind(c(1,0), c(0,1)); D1 <- rbind(c(0,0), c(0,0)) sys1 <- ss(A1,B1,C1,D1) bodeplot(sys1) # Use: par(mfrow = c(2,1)); bodeplot(selectsys(sys1,1,2)) to obtain the response for a subsystem # of sys1 for input 1 and output 2 only # RESET your plot layout using par(mfrow = c(1,1))
c2d converts a system in continuous-time model to a discrete time model
c2d(sys, t)c2d(sys, t)
sys |
An object of transfer function, state-space or zero-pole class |
t |
Sample time; a numeric value greater than 0 |
c2d converts the continuous-time system: x = Ax + Bu
to the discrete-time state-space system: x[n+1] = Phi * x[n] + Gamma * u[n] based on the method
of assuming a zero-order hold on the inputs and sample time
Transfer function and zero-pole systems are converted to state-space representation before
conversion to discrete-time.
Returns the provided system (transfer function, state-space or zero-pole) in an equivalent discrete-time.
## for TF c2d(tf(c(1,-1), c(1,4,5)), 0.1) ## for ZPK sys <- zpkdata( tf(c(1,-1), c(1,4,5)) ) c2d(sys, 0.1) c2d(zpkdata( tf(c(1,-1), c(1,4,5)) ), 0.1)## for TF c2d(tf(c(1,-1), c(1,4,5)), 0.1) ## for ZPK sys <- zpkdata( tf(c(1,-1), c(1,4,5)) ) c2d(sys, 0.1) c2d(zpkdata( tf(c(1,-1), c(1,4,5)) ), 0.1)
Computes the unique solution to the continuous-time Riccati equation:
A'* X + X*A - X * B * R^-1 * B' * X + Q'*Q = 0
care(A, B, Q, R = 1)care(A, B, Q, R = 1)
A |
State-matrix of a state-space system |
B |
Input-matrix of a state-space system |
Q |
Symmetric output-matrix of a state-space system |
R |
Single number |
X <- care(A, B, Q, R) returns the stablizing solution (if it
exists) to the continuous-time Riccati equation.
The care function also returns the gain matrix, G
and a vector, L of the closed-loop eigenvalues, where
G = R^-1 B'X*E
L = eig(a-b*g)
Returns the stabilizing matrix, gain and closed-loop eigenvalues in a list.
A, B must be controllable
a <- matrix(c(-3, 2,1, 1), byrow = TRUE, ncol = 2) b <- matrix(c(0, 1), nrow = 2) c <- matrix(c(1, -1), ncol = 2) q <- t(c)%*%c r <- 3 care(a, b, q, r)a <- matrix(c(-3, 2,1, 1), byrow = TRUE, ncol = 2) b <- matrix(c(0, 1), nrow = 2) c <- matrix(c(1, -1), ncol = 2) q <- t(c)%*%c r <- 3 care(a, b, q, r)
cloop forms a closed feedback loop for a state-space or transfer function system
cloop(sys, e, f)cloop(sys, e, f)
sys |
LTI system model of transfer-function or state-space model |
e |
inputs vector |
f |
outputs vector |
Other possible usages of cloop:
cloop(sys)
cloop(sys, sgn)
If sys is a state-space model, cloop(sys, SGN) produces a state-space model
of the closed-loop system obtained by feeding all the outputs of
the system to all the inputs. Positive feedback is used when SGN <- 1 and negative
when SGN <- -1
If sys is a transfer function model, cloop(sys, SGN)
produces the SISO closed loop
system in transfer function form obtained by unity feedback with
the sign SGN.
cloop(sys,OUTPUTS,INPUTS) forms the closed
loop system obtained by feeding the specific outputs into
specific outputs. The vectors OUTPUTS and INPUTS contain indices
into the outputs and inputs of the system respectively. Positive
feedback is assumed. To form closed loop with negative feedback, negative values are used in the vector INPUTS.
Returns a closed feedback loop system
J <- 2.0; b <- 0.04; K <- 1.0; R <- 0.08; L <- 1e-4 P <- TF("K/(s*((J*s + b)*(L*s + R) + K^2))") cloop(P) cloop(ss(1,2,3,4))J <- 2.0; b <- 0.04; K <- 1.0; R <- 0.08; L <- 1e-4 P <- TF("K/(s*((J*s + b)*(L*s + R) + K^2))") cloop(P) cloop(ss(1,2,3,4))
connect is used to form a state-space model of a system from its block diagram.
connect(sysapp, q, inputs, outputs)connect(sysapp, q, inputs, outputs)
sysapp |
A state-space system containing several appended systems returned from the |
q |
Matrix that specifies the interconnections of the block diagram. Each row specifies a connection. The first element of each row is the number of the block. The other following elements of each row specify where the block gets its summing inputs, with negative elements used to indicate minus inputs to the summing junction. For example: cbind(2,1,3) means that block 2 has an input from block 1 and block 3 |
inputs |
A column matrix specifying the inputs of the resulting aggregate system |
outputs |
A column matrix specifying the outputs of the resulting aggregate system |
connect
This function requires calling the append function to group a set of unconnected dynamics system
in one system object. It then uses the q matrix to determine the interconnections between the systems
and finally specifies the inputs and outputs for the new aggregate system.
This approach helps to realize a block diagram as a single system on which further analysis could be performed.
See examples below.
Returns the interconnected system, returned as either a state-space model
append series parallel feedback
a1 <- rbind(c(0, 0), c(1,-3)) b1 <- rbind(-2,0) c1 <- cbind(0,-1) d <- as.matrix(0) a2 <- as.matrix(-5) b2 <- as.matrix(5) c2 <- as.matrix(1) d2 <- as.matrix(0) sysa1 <- ss(a1, b1, c1, d) sysa2 <- ss(a2, b2, c2, d2) al <- append(sysa1, sysa2) connect(al, cbind(2,1,0), cbind(1,2), cbind(1,2)) ## OR connect(append(sysa1, sysa2), cbind(2,1,0), cbind(1), cbind(2)) ## Not run: cbind(2,1,0) means that block 2 has an input from block 1 and block 0 (which doesnt exist) cbind(1) means that block 1 is the input of the system, and cbind(2) means block 2 is the output of the system. if we replace cbind(2) with cbind(1,2), this means that the system has two outputs from block 1 and 2 i.e. \code{connect(append(sysa1, sysa2), cbind(2,1,0), cbind(1), cbind(1,2))} ## End(Not run)a1 <- rbind(c(0, 0), c(1,-3)) b1 <- rbind(-2,0) c1 <- cbind(0,-1) d <- as.matrix(0) a2 <- as.matrix(-5) b2 <- as.matrix(5) c2 <- as.matrix(1) d2 <- as.matrix(0) sysa1 <- ss(a1, b1, c1, d) sysa2 <- ss(a2, b2, c2, d2) al <- append(sysa1, sysa2) connect(al, cbind(2,1,0), cbind(1,2), cbind(1,2)) ## OR connect(append(sysa1, sysa2), cbind(2,1,0), cbind(1), cbind(2)) ## Not run: cbind(2,1,0) means that block 2 has an input from block 1 and block 0 (which doesnt exist) cbind(1) means that block 1 is the input of the system, and cbind(2) means block 2 is the output of the system. if we replace cbind(2) with cbind(1,2), this means that the system has two outputs from block 1 and 2 i.e. \code{connect(append(sysa1, sysa2), cbind(2,1,0), cbind(1), cbind(1,2))} ## End(Not run)
ctrb forms the controllability matrix.
ctrb(A, B)ctrb(A, B)
A |
State matrix, A |
B |
State matrix, B |
ctrb ctrb(a, b) returns the controllability matrix, [B AB A^2B ... A^(n-1)B]. If the Controllability
matrix has full row rank, the system is controllable.
Returns the controllability matrix.
a1 <- rbind(c(0,0),c(1,-3)) b1 <- rbind(-2,0) ctrb(a1, b1)a1 <- rbind(c(0,0),c(1,-3)) b1 <- rbind(-2,0) ctrb(a1, b1)
damp computes the natural frequency and damping for
continuous systems.
damp(sys, doPrint = TRUE)damp(sys, doPrint = TRUE)
sys |
A Continuous-time system of state-space, transfer-function or zero-pole-gain model. |
doPrint |
If TRUE prints out the results. Default is TRUE. |
A table of the eigenvalues of the matrix a, the associated damping factors, the associated natural frequency (rad/s and Hz.) is displayed by calling the function.
When the continuous system is a state-space model, the eigenvalues of the state matrix are obtained and sorted. If the system is a transfer-function, the poles of the systems are obtained and sorted. For zero-pole systems, the poles are just extracted and sorted. The sorted eigenvalues are printed to output and used to obtain the natural frequencies and damping factors.
Returns the natrural frequencies and damping factors in a list:
omegan = Natural Frequencies (rad/s) zeta = Damping Factors
sys1 <- tf(1, c(1,2,5)) damp(sys1)sys1 <- tf(1, c(1,2,5)) damp(sys1)
dcgain Forms the Givens rotation matrix
dcgain(sys)dcgain(sys)
sys |
A transfer function or state-space model |
dcgain(sys) Computes the steady-state gain (or low frequency gain) of a continuous
system.
Returns the gain.
dlyap(A,C) solves the discrete Lyapunov equation:
A*X*A' + C = X
dlyap(a, c)dlyap(a, c)
a |
A square matrix |
c |
A square matrix |
The solution X is symmetric when C is symmetric.
The functions returns a matrix
D = rbind(c(1,2), c(2,1)) B = rbind(c(4,3), c(4,3)) dlyap(B,D)D = rbind(c(1,2), c(2,1)) B = rbind(c(4,3), c(4,3)) dlyap(B,D)
esort sorts the complex continuous eigenvalues in descending
order
esort(p)esort(p)
p |
A vector containing the poles of a transfer-function, zero-pole model or the eigenvalues of a state-matrix |
esort sorts the complex eigenvalues based on their real part. The unstable eigenvalues (positive
real part) are first shown.
This function is used to sort eigenvalues and system poles in damp
Returns the sorted eigenvalues and the cooresponding indices in a list:
s = sorted eigenvalues idx = index
feedback forms a feedback connection for two LTI state-space or transfer function systems
feedback(sys1, sys2, in1, out1)feedback(sys1, sys2, in1, out1)
sys1 |
LTI system model of transfer-function or state-space model |
sys2 |
LTI system model of transfer-function or state-space model |
in1 |
vector of inputs |
out1 |
vector of outputs |
When sys1 and sys2 are transfer functions feedback(sys1, sys2, SIGN) produces the SISO
closed loop system in transfer function form obtained by
connecting the two SISO transfer function systems in feedback
with the sign SIGN.
feedback(sys1, sys2, SIGN) produces an
aggregate state-space system consisting of the feedback connection
of the two systems 1 and 2. If SIGN = 1 then positive feedback is
used. If SIGN = -1 then negative feedback is used. In all cases,
the resulting system has the same inputs and outputs as system 1.
feedback(sys1, sys2, inputs, outputs)
produces the feedback system formed by feeding all the outputs of
system2 into the inputs of system 1 specified by INPUTS1 and by
feeding the outputs of system 2 specified by OUTPUTS1 into all the
inputs of system 2. Positive feedback is assumed. To connect
with negative feedback, use negative values in the vector INPUTS1.
feedback() calls fdbcksys() to perform the feedback connection for two systems.
Unity feedback calls are possile, for example, feedback(sys1, 1), feedback(1, sys1)
Returns the feedback system in tf or ss model
C <- pid(350,300,50) P <- TF(" 1/(s^2 + 10* s + 20)") feedback(C,P) feedback(P,P,1) feedback(P,P,-1) feedback(P,P) feedback(P,1) feedback(TF("C*P")) ## Not run: On Octave: feedback(C*P)C <- pid(350,300,50) P <- TF(" 1/(s^2 + 10* s + 20)") feedback(C,P) feedback(P,P,1) feedback(P,P,-1) feedback(P,P) feedback(P,1) feedback(TF("C*P")) ## Not run: On Octave: feedback(C*P)
This function obtains the low level frequency response of a system.
freqresp(sys, w = seq(0, 100, length = 10000), iu = 1)freqresp(sys, w = seq(0, 100, length = 10000), iu = 1)
sys |
An LTI system of |
w |
a vector of frequency points |
iu |
For calls to |
freqresp(sys, w) returns a vector of frequencies for sys in complex form
H <- freqresp(ssdata(tf(c(1,1), c(1,2,1))), (seq(0, 100, length = 10000))) H <- freqresp(tf(c(1,1), c(1,2,1)), seq(0, 100, length = 10000))H <- freqresp(ssdata(tf(c(1,1), c(1,2,1))), (seq(0, 100, length = 10000))) H <- freqresp(tf(c(1,1), c(1,2,1)), seq(0, 100, length = 10000))
gensig generates a periodic signal. More useful when used in combination with lsim
gensig(signal, tau, tfinal, tsam)gensig(signal, tau, tfinal, tsam)
signal |
A string input containing either values of: 'sq' or 'square' - Square wave 'si' or 'sine' - Sine wave 'co' or 'cos' - Cosine wave 'pu' or 'pulse' - Periodic pulse |
tau |
Duration of one period in seconds. Default is 5 |
tfinal |
Duration of the signal in seconds. Default is 30 |
tsam |
sampling time in seconds. Default is 0.01 |
gensig generates a periodic signal of the following types: square, sin, cos, pulse
Possible usage: gensig(signal)
Returns a list of two single column matrices, u and t
u is the vector of signal values
t is the time vector of the signal
## Not run: A square wave signal sig <- gensig('square', 4, 10, 0.1) plot(sig$t, sig$u, type = "l", col = "blue") grid(5,5, col = "lightgray") ## Not run: A sine wave signal sig <- gensig('sin') plot(sig$t, sig$u, type = "l", col = "blue") grid(5,5, col = "lightgray")## Not run: A square wave signal sig <- gensig('square', 4, 10, 0.1) plot(sig$t, sig$u, type = "l", col = "blue") grid(5,5, col = "lightgray") ## Not run: A sine wave signal sig <- gensig('sin') plot(sig$t, sig$u, type = "l", col = "blue") grid(5,5, col = "lightgray")
givens_rot Forms the Givens rotation matrix
givens_rot(a, b)givens_rot(a, b)
a |
Complex Square-matrix |
b |
complex Input-matrix |
givens_rot(a, b) returns the complex Givens rotation matrix
This function is called by ordschur
Returns the complex Givens rotation matrix.
impulse obtains the impulse response of the linear system:
to an impulse applied to the input
impulse(sys, t, input) impulseplot(sys, t, input)impulse(sys, t, input) impulseplot(sys, t, input)
sys |
LTI system of transfer-function, state-space and zero-pole classes |
t |
Time vector. If not provided, it is automatically set. |
input |
For calls to For calls to |
impulse produces the impulse response of linear systems using lsim
impulseplot produces the impulse response as a plot against time.
These functions can handle both SISO and MIMO (state-space) models.
Other possible calls using impulse and impulseplot are:
impulse(sys)
impulse(sys, t)
impulseplot(sys)
impulseplot(sys, t)
A list is returned by calling impulse containing:
t Time vector
x Individual response of each x variable
y Response of the system
The matrix y has as many rows as there are outputs, and columns of the same size of length(t).
The matrix x has as many rows as there are states. If the time
vector is not specified, then the automatically set time
vector is returned as t
A plot of y vs t is returned by calling impulseplot
res <- impulse(tf(1, c(1,2,1))) res$y res$t impulse(tf(1, c(1,2,1)), seq(0, 10, 0.1)) impulseplot(tf(1, c(1,2,1))) impulseplot(tf(1, c(1,2,1)), seq(0, 10, 0.1)) ## Not run: State-space MIMO systems A <- rbind(c(0,1), c(-25,-4)); B <- rbind(c(1,1), c(0,1)); C <- rbind(c(1,0), c(0,1)); D <- rbind(c(0,0), c(0,0)) res1 <- impulse(ss(A,B,C,D), input = 1) res2 <- impulse(ss(A,B,C,D), input = 2) res1$y # has two rows, i.e. for two outputs res2$y # has two rows, i.e. for two outputs impulseplot(ss(A,B,C,D), input = 1:2) # OR impulseplot(ss(A,B,C,D), input = 1:ncol(D)) impulseplot(ss(A,B,C,D), seq(0,3,0.01), 1:2)res <- impulse(tf(1, c(1,2,1))) res$y res$t impulse(tf(1, c(1,2,1)), seq(0, 10, 0.1)) impulseplot(tf(1, c(1,2,1))) impulseplot(tf(1, c(1,2,1)), seq(0, 10, 0.1)) ## Not run: State-space MIMO systems A <- rbind(c(0,1), c(-25,-4)); B <- rbind(c(1,1), c(0,1)); C <- rbind(c(1,0), c(0,1)); D <- rbind(c(0,0), c(0,0)) res1 <- impulse(ss(A,B,C,D), input = 1) res2 <- impulse(ss(A,B,C,D), input = 2) res1$y # has two rows, i.e. for two outputs res2$y # has two rows, i.e. for two outputs impulseplot(ss(A,B,C,D), input = 1:2) # OR impulseplot(ss(A,B,C,D), input = 1:ncol(D)) impulseplot(ss(A,B,C,D), seq(0,3,0.01), 1:2)
initial obtains the time response of the linear system:
to an initial condition.
initial(sys, x0, t) initialplot(sys, x0, t)initial(sys, x0, t) initialplot(sys, x0, t)
sys |
LTI system of transfer-function, state-space and zero-pole classes |
x0 |
initial conditions as a column vector. Should have as many rows as the rows of A. where x0 is not specified, random values are assigned |
t |
regularly spaced time vector. If not provided, it is automatically set. For calls to |
initial produces the time response of linear systems to initial conditions using lsim
initialplot produces the time response to initial conditions as a plot againts time.
The functions can handle both SISO and MIMO (state-space) models.
Other possible calls using initial and initialplot are:
initial(sys)
initial(sys, x0)
initialplot(sys)
initialplot(sys, x0)
A list is returned by calling initial containing:
x Individual response of each x variable
y Response of the system
t Time vector
The matrix y has as many rows as there are outputs, and columns of the same size of length(t).
The matrix X has as many rows as there are states. If the time
vector is not specified, then the automatically set time
vector is returned as t
A plot of y vs t is returned by calling initialplot
res <- initial(tf(1, c(1,2,1))) res$y res$t A <- rbind(c(-2, -1), c(1,0)); B <- rbind(1,0); C <- cbind(0,1); D <- as.matrix(0); x0 <- matrix(c( 0.51297, 0.98127)) initialplot(ss(A,B,C,D), x0) initialplot(tf(1, c(1,2,1)), t = seq(0, 10, 0.1)) ## Not run: State-space MIMO systems A <- rbind(c(0,1), c(-25,-4)); B <- rbind(c(1,1), c(0,1)); C <- rbind(c(1,0), c(0,1)); D <- rbind(c(0,0), c(0,0)) res <- initial(ss(A,B,C,D)) res$y # has two rows, i.e. for two outputs initialplot(ss(A,B,C,D))res <- initial(tf(1, c(1,2,1))) res$y res$t A <- rbind(c(-2, -1), c(1,0)); B <- rbind(1,0); C <- cbind(0,1); D <- as.matrix(0); x0 <- matrix(c( 0.51297, 0.98127)) initialplot(ss(A,B,C,D), x0) initialplot(tf(1, c(1,2,1)), t = seq(0, 10, 0.1)) ## Not run: State-space MIMO systems A <- rbind(c(0,1), c(-25,-4)); B <- rbind(c(1,1), c(0,1)); C <- rbind(c(1,0), c(0,1)); D <- rbind(c(0,0), c(0,0)) res <- initial(ss(A,B,C,D)) res$y # has two rows, i.e. for two outputs initialplot(ss(A,B,C,D))
issiso checks if state-space system is a single-input single-output system
ismimo checks if state-space system is a multiple-input multiple-output system
issiso(sys)issiso(sys)
sys |
Dynamic system of state-space model |
Returns TRUE or FALSE
lsim Computes the time response of a Linear system described by:
to the input time history u.
lsim(sys, u, t, x0)lsim(sys, u, t, x0)
sys |
An LTI system of |
u |
A row vector for single input systems. The input |
t |
time vector which must be regularly spaced. e.g. |
x0 |
a vector of initial conditions with as many rows as the rows of |
lsim(sys, u, t) provides the time history of the linear system with zero-initial conditions.
lsim(sys, u, t, x0) provides the time history of the linear system with initial conditions.
If the linear system is represented as a model of tf or zpk
it is first converted to state-space before linear simulation is performed. This function depends on c2d and ltitr
Returns a list of two matrices, x and y. The x values are returned from ltitr
call.
signal <- gensig('square',4,10,0.1) H <- tf(c(2, 5, 1),c(1, 2, 3)) response <- lsim(H, signal$u, signal$t) plot(signal$t, response$y, type = "l", main = "Linear Simulation Response", col = "blue") lines(signal$t, signal$u, type = "l", col = "grey") grid(5,5, col = "lightgray") ## Not run: based on example at: https://www.mathworks.com/help/ident/ref/lsim.html ## Not run: MIMO system response A <- rbind(c(0,1), c(-25,-4)); B <- rbind(c(1,1), c(0,1)) C <- rbind(c(1,0), c(0,1)); D <- rbind(c(0,0), c(0,0)) response <- lsim(ss(A,B,C,D), cbind(signal$u, signal$u), signal$t) plot(signal$t, response$y[1,], type = "l", main = "Linear Simulation Response", col = "blue"); grid(7,7) plot(signal$t, response$y[2,], type = "l", main = "Linear Simulation Response", col = "blue"); grid(7,7)signal <- gensig('square',4,10,0.1) H <- tf(c(2, 5, 1),c(1, 2, 3)) response <- lsim(H, signal$u, signal$t) plot(signal$t, response$y, type = "l", main = "Linear Simulation Response", col = "blue") lines(signal$t, signal$u, type = "l", col = "grey") grid(5,5, col = "lightgray") ## Not run: based on example at: https://www.mathworks.com/help/ident/ref/lsim.html ## Not run: MIMO system response A <- rbind(c(0,1), c(-25,-4)); B <- rbind(c(1,1), c(0,1)) C <- rbind(c(1,0), c(0,1)); D <- rbind(c(0,0), c(0,0)) response <- lsim(ss(A,B,C,D), cbind(signal$u, signal$u), signal$t) plot(signal$t, response$y[1,], type = "l", main = "Linear Simulation Response", col = "blue"); grid(7,7) plot(signal$t, response$y[2,], type = "l", main = "Linear Simulation Response", col = "blue"); grid(7,7)
lsimplot Plots the time response of a Linear system described by:
to the input time history u.
lsimplot(sys, u, t, x0)lsimplot(sys, u, t, x0)
sys |
An LTI system of |
u |
A row vector for single input systems. The input |
t |
time vector which must be regularly spaced. e.g. |
x0 |
a vector of initial conditions with as many rows as the rows of |
lsimplot(sys, u, t) plots the time history of the linear system with zero-initial conditions.
lsimplot(sys, u, t, x0) plots the time history of the linear system with given initial conditions.
If the linear system is represented as a model of tf or zpk
it is first converted to state-space before linear simulation is performed. This function depends on c2d and ltitr
Returns a plot for the response of the system
signal <- gensig('square',4,10,0.1) H <- tf(c(2, 5, 1),c(1, 2, 3)) lsimplot(H, signal$u, signal$t) ## Not run: MIMO system response A <- rbind(c(0,1), c(-25,-4)); B <- rbind(c(1,1), c(0,1)) C <- rbind(c(1,0), c(0,1)); D <- rbind(c(0,0), c(0,0)) lsimplot(ss(A,B,C,D), cbind(signal$u, signal$u), signal$t)signal <- gensig('square',4,10,0.1) H <- tf(c(2, 5, 1),c(1, 2, 3)) lsimplot(H, signal$u, signal$t) ## Not run: MIMO system response A <- rbind(c(0,1), c(-25,-4)); B <- rbind(c(1,1), c(0,1)) C <- rbind(c(1,0), c(0,1)); D <- rbind(c(0,0), c(0,0)) lsimplot(ss(A,B,C,D), cbind(signal$u, signal$u), signal$t)
This function computes the frequency response of the following system:
g(w) = (wI-A) \ B
for the complex frequencies contained in the vector W. The column vector B must have as many rows as the matrix A.
ltifr(A, B, w)ltifr(A, B, w)
A |
State-space matrix, A |
B |
State-space input-matrix, B. B must have as many rows as the matrix A. |
w |
Vector of complex frequencies |
Returns the frequency response in vector. freqresp utilizes this function for state-space systems.
## use \code{\link{freqresp}}## use \code{\link{freqresp}}
ltitr Computes the time response of a Linear Time-Invariant system
ltitr(a, b, u, x0)ltitr(a, b, u, x0)
a |
An n x n matrix of the state-space system |
b |
An n x m matrix of the state-space system |
u |
A row vector for single input systems. The input U must have as many rows as there are inputs
in the system. Each column of U corresponds to a new time point. |
x0 |
a vector of initial conditions with as many rows as the rows of |
ltitr computes the time response of a Linear Time-Invariant system in state-space representation of the form:
x[n+1] = Ax[n] + Bu[n] to an input, U
ltitr(a, b, u) computes the time response with zero-initial conditions since x0 is not supplied.
Returns a matrix X which has as
many rows as there are outputs y (and with max(dim(U)) columns).
A <- diag(1, 2) B <- rbind(1, 1) x0 <- rbind(-1, -2) u <- cbind(1, 2, 3, 4, 5) X <- ltitr(A, B, u) X <- ltitr(A, B, u, x0) A <- replicate(6, abs(rnorm(6))) B <- replicate(3, abs(rnorm(6))) U <- replicate(100, rnorm(3)) x0 <- rnorm(6) X <- ltitr(A, B, U) X <- ltitr(A, B, U, x0)A <- diag(1, 2) B <- rbind(1, 1) x0 <- rbind(-1, -2) u <- cbind(1, 2, 3, 4, 5) X <- ltitr(A, B, u) X <- ltitr(A, B, u, x0) A <- replicate(6, abs(rnorm(6))) B <- replicate(3, abs(rnorm(6))) U <- replicate(100, rnorm(3)) x0 <- rnorm(6) X <- ltitr(A, B, U) X <- ltitr(A, B, U, x0)
lyap(A, B) solves the particular Lyapunov equation:
A*X+X*A' = -B
lyap(A, B, C) solves the Sylvester equation
lyap(A, B, C = NULL)lyap(A, B, C = NULL)
A |
An appropriately dimensioned matrix |
B |
An appropriately dimensioned matrix |
C |
An appropriately dimensioned matrix |
This function solves the lyapunov equation using an eigenvalue decomposition. The solution X is symmetric when B is symmetric.
The functions returns a matrix
WARNING: This function assumes that there are no repeated eigenvalues. If repeated eigenvalues exist, then the solution may be unreliable.
A = rbind(c(1,2), c(-3, -4)) Q = rbind(c(3,1), c(1,1)) lyap(A, Q)A = rbind(c(1,2), c(-3, -4)) Q = rbind(c(3,1), c(1,1)) lyap(A, Q)
nyquist computes the real and imaginary parts of the frequency response of system sys
at given frequencies w
nyquist(sys, w, iu)nyquist(sys, w, iu)
sys |
LTI system of transfer-function, state-space and zero-pole classes |
w |
vector of range of frequencies at the response is computed in rad/sec |
iu |
number to specify an input for a MIMO state-space system. If the system has
3 inputs, then |
nyquist Compute the real and imaginary parts of the frequency response of system sys
at given frequencies w. When sys is a transfer function, nyquist
computes the frequency response of the system using the signal package.
nyquistplot plots the frequency response computed by nyquist. For a MIMO state-space system,
nyquistplot uses selectsys to obtain the nyquist response for each input-to-output pair and plot
them individually. This means that for a 2-input, 2-output system, nyquistplot obtains the response
for input 1 to output 1, input 1 to output 2, input 2 to output 1 and input 2 to output 2.
nyquistplot uses the subtitle argument to allow a user assign the plot a sub-title
Other possible calls using nyquist and nyquistplot are:
nyquist(sys)
nyquist(sys, w)
nyquist(sys, w = seq(0, 100, length = 10000), iu = 1)
nyquistplot(sys)
nyquistplot(sys, w)
nyquistplot(sys, w, subtitle)
A list is returned by calling nyquist containing:
h.real - real part of the frequency response
h.imag - imaginary part of the frequency response
A plot is returned by calling nyquistplot
nyquist(tf(100, c(1,6,100))) nyquist(ssdata(tf(100, c(1,6,100)))) ## Not run: MIMO plot A1 <- rbind(c(0,1), c(-25,-4)); B1 <- rbind(c(1,1), c(0,1)) C1 <- rbind(c(1,0), c(0,1)); D1 <- rbind(c(0,0), c(0,0)) sys1 <- ss(A1,B1,C1,D1) nyquistplot(sys1) ## Not run: Use nyquistplot(selectsys(sys1,1,2)) to obtain the response for a subsystem of sys1 for input 1 and output 2 only. RESET your plot layout using par(mfrow = c(1,1) ## End(Not run)nyquist(tf(100, c(1,6,100))) nyquist(ssdata(tf(100, c(1,6,100)))) ## Not run: MIMO plot A1 <- rbind(c(0,1), c(-25,-4)); B1 <- rbind(c(1,1), c(0,1)) C1 <- rbind(c(1,0), c(0,1)); D1 <- rbind(c(0,0), c(0,0)) sys1 <- ss(A1,B1,C1,D1) nyquistplot(sys1) ## Not run: Use nyquistplot(selectsys(sys1,1,2)) to obtain the response for a subsystem of sys1 for input 1 and output 2 only. RESET your plot layout using par(mfrow = c(1,1) ## End(Not run)
This function creates the observability matrix.
obsv(A, C)obsv(A, C)
A |
State-space matrix, A |
C |
State-space matrix, C |
obsv(A, C) returns the observability matrix, obsvm.
where
obsvm = | C CA CA^2 ... CA^(n-1) |
A <- rbind(c(0,1), c(-25,-4)) C <- rbind(c(1,0), c(0,1)) obsv(A, C)A <- rbind(c(0,1), c(-25,-4)) C <- rbind(c(1,0), c(0,1)) obsv(A, C)
ordschur Orders a schur decomposition
ordschur(Ui, Si, idx)ordschur(Ui, Si, idx)
Ui |
Square upper-triangular matrix matrix from schur decomposition. If Ui is not given it is set to the identity matrix. |
Si |
Orthogonal matrix from schur decomposition |
idx |
array index |
ordschur finds an orthogonal matrix, U so that the eigenvalues
appearing on the diagonal of Si are ordered according to the
increasing values of the array index where the i-th element
of index corresponds to the eigenvalue appearing as the
element Si[i,i].
ordschur could also be used in this syntax: ordschur(Si, idx)
Returns a list of ordered (U, S)
parallel connects two systems in the parallel block form below
|–>[System1]–| u–>+ 0—>y |<–[System2]–|
parallel(sys1, sys2, in1, in2, out1, out2)parallel(sys1, sys2, in1, in2, out1, out2)
sys1 |
LTI system object of tf, ss or zpk class |
sys2 |
LTI system object of tf, ss or zpk class |
in1 |
Numeric vector containing indexes to the inputs of sys1 |
in2 |
Numeric vector containing indexes to the inputs of sys2 |
out1 |
Numeric vector containing indexes to the outputs of sys1 |
out2 |
Numeric vector containing indexes to the outputs of sys2 |
psys <- parallel(sys1, sys2) produces a state-
space system consisting of the parallel connection of sys1
and sys2 that connects all the inputs together and sums all the
outputs of the two systems.
The parallel connection is performed by appending the two systems, summing the specified inputs and outputs, and removing the, now redundant, inputs and outputs of system 2.
If sys1 and sys2 are transfer functions, then parallel(sys1, sys2) produces a parallel connection of the two transfer function systems.
parallel(sys1, sys2,IN1,IN2,OUT1,OUT2)
connects the two systems in parallel by connecting the inputs
specified by IN1 and IN2 and by summing the outputs specified
by OUT1 and OUT2. The vector IN1 contains
indexes into the input vectors of sys1 while, IN2 contains indexes for sys2,
. Vectors OUT1 and OUT2 contain indexes for the outputs of the sys1 and sys2 respectively.
The function returns a state-space model of the parallel-connected system with A, B, C, D matrices
sys2 = ss(1,2,3,4) sys3 = ss(6,7,8,9) parallel(sys2, sys3) parallel(tf(1, c(1,2,3)), ss(1,2,3,4)) parallel(tf(1, c(1,2,3)),tf(2, c(3,2,3)))sys2 = ss(1,2,3,4) sys3 = ss(6,7,8,9) parallel(sys2, sys3) parallel(tf(1, c(1,2,3)), ss(1,2,3,4)) parallel(tf(1, c(1,2,3)),tf(2, c(3,2,3)))
pid Parallel form of the model of a PID controller
pid(p, i, d)pid(p, i, d)
p |
Proportional gain. A real and finite value. |
i |
Integral gain. A real and finite value. set this to zero for PD and P-control |
d |
Derivative gain. A real and finite value. set this to zero for PI and P-control |
pid creates the transfer function model for a PID, PI, PD, and P-controller.
Returns a transfer function model for the PID, PI, PD or P-controller.
C <- pid(350,300,50) # PID-control P <- TF(" 1/(s^2 + 10* s + 20)") T <- feedback(TF("C*P"), 1) stepplot(T, seq(0,2,0.01)) C <- pid(300,0,0) # P-control T <- feedback(TF("C*P"), 1) stepplot(T, seq(0,2,0.01)) C <- pid(30,70,0) # PI-control T <- feedback(TF("C*P"), 1) stepplot(T, seq(0,2,0.01)) C <- pid(300,0,10) # PD-control T <- feedback(TF("C*P"), 1) stepplot(T, seq(0,2,0.01))C <- pid(350,300,50) # PID-control P <- TF(" 1/(s^2 + 10* s + 20)") T <- feedback(TF("C*P"), 1) stepplot(T, seq(0,2,0.01)) C <- pid(300,0,0) # P-control T <- feedback(TF("C*P"), 1) stepplot(T, seq(0,2,0.01)) C <- pid(30,70,0) # PI-control T <- feedback(TF("C*P"), 1) stepplot(T, seq(0,2,0.01)) C <- pid(300,0,10) # PD-control T <- feedback(TF("C*P"), 1) stepplot(T, seq(0,2,0.01))
Computes the Pole placement gain selection using Ackermann's formula.
place(a, b, p)place(a, b, p)
a |
State-matrix of a state-space system |
b |
Input-matrix of a state-space system |
p |
closed loop poles |
K <- place(A,B,P) calculates the feedback gain matrix K such that the single input system . x <- Ax + Bu
with a feedback law of u <- -Kx has closed loop poles at the
values specified in vector P, i.e., P <- eigen(A - B * K). This function
is just a wrapper for the acker function.
This method is NOT numerically stable and a warning message is printed if the nonzero closed loop poles are greater than 10 in P.
F <- rbind(c(0,1),c(0,0)) G <- rbind(0,1) H <- cbind(1,0); J <- 0 t <- 1 sys <- ss(F,G, H,J) A <- c2d(sys,t); j <- sqrt(as.complex(-1)); pc <- rbind(0.78+0.18*j, 0.78-0.18*j) K <- place(A$A, A$B, pc)F <- rbind(c(0,1),c(0,0)) G <- rbind(0,1) H <- cbind(1,0); J <- 0 t <- 1 sys <- ss(F,G, H,J) A <- c2d(sys,t); j <- sqrt(as.complex(-1)); pc <- rbind(0.78+0.18*j, 0.78-0.18*j) K <- place(A$A, A$B, pc)
This function obtains the poles for a given system
pole(sys)pole(sys)
sys |
LTI system of tf, ss and zpk class |
pole returns the poles for a given system either a transfer function,
state-space or zero-pole models. If sys is a transfer function, it computes the roots of the denominator
If sys is a state-space object, it computes the eigenvalues of the A matrix.
If sys is a zpk object, it retrieves the poles from the object.
The function returns a column matrix containing the poles for the given system
H1 <- tf(c(2, 5, 1),c(1, 3, 5)) pole(zpk(NULL, c(-1,-1), 1)) pole(ssdata(tf(1, c(1,2,1))))H1 <- tf(c(2, 5, 1),c(1, 3, 5)) pole(zpk(NULL, c(-1,-1), 1)) pole(ssdata(tf(1, c(1,2,1))))
Print polynomial as a character string.
poly2str(p, svar = "x", smul = "*", d = options("digits")$digits)poly2str(p, svar = "x", smul = "*", d = options("digits")$digits)
p |
numeric vector representing a polynomial |
svar |
character representing the unknown, default x. |
smul |
multiplication symbol, default *. |
d |
significant digits, default options("digits"). |
Modified from package *pracma*. Modification: To hide any coefficient and power that is equal to 1 So that instead of '1s^3' we have 's^3' and instead of 's^1', we have 's'
Returns the usual string representing a polynomial in mathematics.
poly2str(c(2, -3, 1, 20, -11))poly2str(c(2, -3, 1, 20, -11))
Subtract two polynomials given as vectors
polysub(a, b)polysub(a, b)
a |
Vector representing first polynomial. |
b |
Vector representing second polynomial. |
Simply calls polyadd from pracma package
in the following manner: pracma::polyadd(a, -b)
Returns a Vector representing the resulting polynomial.
polysub(c(1, 1, 1), 1) polysub(c(1, 1, 1), c(0, 0, 1))polysub(c(1, 1, 1), 1) polysub(c(1, 1, 1), c(0, 0, 1))
ramp obtains the ramp response of the linear system:
ramp(sys, t, input) rampplot(sys, t, input)ramp(sys, t, input) rampplot(sys, t, input)
sys |
LTI system of transfer-function, state-space and zero-pole classes |
t |
Time vector. If not provided, it is automatically set. |
input |
For calls to For calls to |
ramp produces the ramp response of linear systems using lsim
rampplot produces the ramp response as a plot against time.
These functions can handle both SISO and MIMO (state-space) models.
#' Other possible calls using ramp and rampplot are:
ramp(sys)
ranp(sys, t)
rampplot(sys)
rampplot(sys, t)
A list is returned by calling ramp containing:
t Time vector
x Individual response of each x variable
y Response of the system
The matrix y has as many rows as there are outputs, and columns of the same size of length(t).
The matrix x has as many rows as there are states. If the time
vector is not specified, then the automatically set time
vector is returned as t
A plot of y vs t is returned by calling rampplot
res <- ramp(tf(1, c(1,2,1))) res$y res$t ramp(tf(1, c(1,2,1)), seq(0, 6, 0.1)) rampplot(tf(1, c(1,2,1))) rampplot(tf(1, c(1,2,1)), seq(0, 6, 0.1)) ## Not run: State-space MIMO systems A <- rbind(c(0,1), c(-25,-4)); B <- rbind(c(1,1), c(0,1)); C <- rbind(c(1,0), c(0,1)); D <- rbind(c(0,0), c(0,0)) res1 <- ramp(ss(A,B,C,D), input = 1) res2 <- ramp(ss(A,B,C,D), input = 2) res1$y # has two rows, i.e. for two outputs res2$y # has two rows, i.e. for two outputs rampplot(ss(A,B,C,D), input = 1:2) # OR rampplot(ss(A,B,C,D), input = 1:ncol(D)) rampplot(ss(A,B,C,D), seq(0,3,0.01), 1:2)res <- ramp(tf(1, c(1,2,1))) res$y res$t ramp(tf(1, c(1,2,1)), seq(0, 6, 0.1)) rampplot(tf(1, c(1,2,1))) rampplot(tf(1, c(1,2,1)), seq(0, 6, 0.1)) ## Not run: State-space MIMO systems A <- rbind(c(0,1), c(-25,-4)); B <- rbind(c(1,1), c(0,1)); C <- rbind(c(1,0), c(0,1)); D <- rbind(c(0,0), c(0,0)) res1 <- ramp(ss(A,B,C,D), input = 1) res2 <- ramp(ss(A,B,C,D), input = 2) res1$y # has two rows, i.e. for two outputs res2$y # has two rows, i.e. for two outputs rampplot(ss(A,B,C,D), input = 1:2) # OR rampplot(ss(A,B,C,D), input = 1:ncol(D)) rampplot(ss(A,B,C,D), seq(0,3,0.01), 1:2)
selectsys extracts a subsystem from a larger state-space system.
removesys removes specified inputs, outputs, and state from a state-space system.
selectsys(statesys, inputs, outputs, states) removesys(statesys, inputs, outputs, states)selectsys(statesys, inputs, outputs, states) removesys(statesys, inputs, outputs, states)
statesys |
LTI system model of state-space model |
inputs |
single integer or vector specifying the particular inputs to be selected/removed |
outputs |
single integer or vector specifying the particular outputs to be selected/removed |
states |
single integer or vector specifying the particular states to be selected/removed |
subsys <- selectsys(statesys,inputs,outputs) will extract a state
space subsystem with the specified inputs and outputs.
subsys <- selectsys(statesys, inputs,outputs,states) will return
the state space subsystem with the specified inputs, outputs, and states.
subsys <- removesys(statesys, inputs, outputs) will remove the specified inputs and outputs from the system.
subsys <- removesys(statesys, inputs, outputs, states) will
also return a state-space model with the specified inputs, outputs, and
states removed from the system.
Returns a subsystem of the state-space model
A <- rbind(c(33,2,5), c(23,200,2), c(9,2,45)) B <- rbind(c(4,5), c(12,5), c(82,1)) C <- rbind(c(34,56,2), c(6,2,112)) D <- rbind(c(2,0), c(0,19)) sys1 <- ss(A, B, C, D) selectsys(sys1, 1, 1) # extract subsystem for only input 1 and output 1 selectsys(sys1, 2,2) # extract subsystem for only input 2 and output 2 selectsys(sys1, 2, 1:2) # extract subsystem for only input 1 and output 1 to 2 selectsys(sys1, 1:2, 2) # extract subsystem for only input 1 to 2 and output 2 to 2 selectsys(sys1, 2, 2, 1:2) # extract subsystem for only input 2 and output 2 but states 1 to 2 removesys(sys1, 1,2) # removes input 1 and output 2A <- rbind(c(33,2,5), c(23,200,2), c(9,2,45)) B <- rbind(c(4,5), c(12,5), c(82,1)) C <- rbind(c(34,56,2), c(6,2,112)) D <- rbind(c(2,0), c(0,19)) sys1 <- ss(A, B, C, D) selectsys(sys1, 1, 1) # extract subsystem for only input 1 and output 1 selectsys(sys1, 2,2) # extract subsystem for only input 2 and output 2 selectsys(sys1, 2, 1:2) # extract subsystem for only input 1 and output 1 to 2 selectsys(sys1, 1:2, 2) # extract subsystem for only input 1 to 2 and output 2 to 2 selectsys(sys1, 2, 2, 1:2) # extract subsystem for only input 2 and output 2 but states 1 to 2 removesys(sys1, 1,2) # removes input 1 and output 2
series connects two systems in the series block form below
u —>[System1]—>[System2]—-> y
series(sys1, sys2, outputs, inputs)series(sys1, sys2, outputs, inputs)
sys1 |
LTI system object of tf, ss or zpk class |
sys2 |
LTI system object of tf, ss or zpk class |
outputs |
vector of outputs |
inputs |
vector of inputs |
seriessys <- series(sys1, sys2) connects the two state-space systems in series such that the outputs of sys1
specified are connected to the inputs of sys2 specified by input2.
If sys1 and sys2 are both transfer functions, series(systf1, systf2) produces the SISO system
in transfer function form obtained by connecting the two SISO
transfer function systems in series.
If a system is not in state-space representation, the function
tries to form a state-space representation for such system.
The function returns a state-space model of the aggregate system with A, B, C, D matrices
series(tf(1, c(1,2,3)), tf(2, c(2,3,5))) sys2 = ss(1,2,3,4) sys3 = ss(6,7,8,9) series(sys2, sys3) series(tf(1, c(1,2,3)), ss(1,2,3,4))series(tf(1, c(1,2,3)), tf(2, c(2,3,5))) sys2 = ss(1,2,3,4) sys3 = ss(6,7,8,9) series(sys2, sys3) series(tf(1, c(1,2,3)), ss(1,2,3,4))
ss creates the model for a system represented in state-space form
ss(A, B, C, D, Ts = NULL)ss(A, B, C, D, Ts = NULL)
A |
An n x n matrix |
B |
An n x m matrix |
C |
An p x n matrix |
D |
An p x m matrix |
Ts |
Sample time for discrete time systems |
ss creates a model object for state-space systems.
Returns a list object of 'ss' class.
A <- rbind(c(-2, -1), c(1,0)) B <- rbind(1,0) C <- cbind(0,1) D <- 0; sys <- ss(A,B,C,D) ## Not run: OR sys <- ss(c(-2,-1,1,0), c(1,0), c(0,1), 0) ## Not run: Access individual state-space sys elements as sys$A sys$B sys$C sys$DA <- rbind(c(-2, -1), c(1,0)) B <- rbind(1,0) C <- cbind(0,1) D <- 0; sys <- ss(A,B,C,D) ## Not run: OR sys <- ss(c(-2,-1,1,0), c(1,0), c(0,1), 0) ## Not run: Access individual state-space sys elements as sys$A sys$B sys$C sys$D
ss2tf converts the model for a state-space system to transfer function representation
ss2tf(a, b, c, d, iu)ss2tf(a, b, c, d, iu)
a |
An n x n matrix |
b |
An n x m matrix |
c |
An p x n matrix |
d |
An p x m matrix |
iu |
A numeric value denoting number of inputs. default value is 1.For example, if the system has three inputs (u1, u2, u3), then iu must be either 1, 2, or 3, where 1 implies u1, 2 implies u2, and 3 implies u3. |
ss2tf converts a model object in state-space form to transfer function model by calculating the transfer function of the system:
.
x = Ax + Bu
y = Cx + Du
#' Other possible usages for ss2tf are:
ss2tf(a,b,c,d)
ss2tf(sys)
ss2tf(sys, iu)
where sys is an object of state-space class
Returns an object of 'tf' class containing num and den. The numerator coefficients
are returned in matrix num with as many rows as outputs y.
sys2 <- tf2ss(tf(1, c(1,2,1))) ss2tf(sys2) ## Not run: OR ss2tf(sys2$A,sys2$B,sys2$C,sys2$D) # a single input multiple output system A <- rbind(c(0,1), c(-10000,-4)); B <- rbind(0,1); C <- rbind(c(1,0), c(0,1)); D <- rbind(0,0) ss2tf(A, B, C, D) # a MIMO system A = rbind(c(0,1), c(-25,-4)); B = rbind(c(1,1), c(0,1)); C = rbind(c(1,0), c(0,1)); D = rbind(c(0,0), c(0,0)) ss2tf(A,B,C,D,1) # to obtain output for input 1 ss2tf(A,B,C,D,2) # to obtain output for input 2 ## OR systems <- vector("list", ncol(D)) for(i in 1:ncol(D)){ systems[[i]] <- ss2tf(A,B,C,D,i) } systems systems[[1]] systems[[2]]sys2 <- tf2ss(tf(1, c(1,2,1))) ss2tf(sys2) ## Not run: OR ss2tf(sys2$A,sys2$B,sys2$C,sys2$D) # a single input multiple output system A <- rbind(c(0,1), c(-10000,-4)); B <- rbind(0,1); C <- rbind(c(1,0), c(0,1)); D <- rbind(0,0) ss2tf(A, B, C, D) # a MIMO system A = rbind(c(0,1), c(-25,-4)); B = rbind(c(1,1), c(0,1)); C = rbind(c(1,0), c(0,1)); D = rbind(c(0,0), c(0,0)) ss2tf(A,B,C,D,1) # to obtain output for input 1 ss2tf(A,B,C,D,2) # to obtain output for input 2 ## OR systems <- vector("list", ncol(D)) for(i in 1:ncol(D)){ systems[[i]] <- ss2tf(A,B,C,D,i) } systems systems[[1]] systems[[2]]
ss2zp converts a system represented in state-space form to zero-pole-gain model
ss2zp(a,b,c,d,iu)ss2zp(a,b,c,d,iu)
a |
An n x n matrix |
b |
An n x m matrix |
c |
An p x n matrix |
d |
An p x m matrix |
iu |
A numeric value denoting number of inputs. default value is 1.For example, if the system has three inputs (u1, u2, u3), then iu must be either 1, 2, or 3, where 1 implies u1, 2 implies u2, and 3 implies u3. |
ss2zp converts a system represented in zero-pole form to state-space by converting from zero-pole to transfer function and from transfer functon to state-space
The vector P contains the pole locations of the denominator of the transfer function.
Other possible usages for ss2zp are:
ss2zp(a,b,c,d)
ss2zp(sys)
ss2zp(sys, iu)
where sys is an object of state-space class
Returns a list object of 'zpk' class, consisting of z, p and k. The numerator zeros are returned in the columns of matrix Z with number of columns equal to number of outputs. The gains for each numerator transfer function are returned in column vector K. P, a column vector contains the pole locations of the denominator of the transfer function.
A <- rbind(c(-2, -1), c(1,0)); B <- rbind(1,0); C <- cbind(0,1); D <- 0; sys2 <- ss(A,B,C,D) ss2zp(sys2$A,sys2$B,sys2$C,sys2$D) ss2zp( zp2ss ( tf2zp( c(1,1,1), c(1,2,1) ) ) ) ## Not run: A MIMO system A = rbind(c(0,1), c(-25,-4)); B = rbind(c(1,1), c(0,1)); C = rbind(c(1,0), c(0,1)); D = rbind(c(0,0), c(0,0)) ss2tf(A,B,C,D,1) # to obtain output for input 1 ss2tf(A,B,C,D,2) # to obtain output for input 2 ## Not run: OR systems <- vector("list", ncol(D)) for(i in 1:ncol(D)){ systems[[i]] <- ss2zp(A,B,C,D,i) } systems systems[[1]] systems[[2]]A <- rbind(c(-2, -1), c(1,0)); B <- rbind(1,0); C <- cbind(0,1); D <- 0; sys2 <- ss(A,B,C,D) ss2zp(sys2$A,sys2$B,sys2$C,sys2$D) ss2zp( zp2ss ( tf2zp( c(1,1,1), c(1,2,1) ) ) ) ## Not run: A MIMO system A = rbind(c(0,1), c(-25,-4)); B = rbind(c(1,1), c(0,1)); C = rbind(c(1,0), c(0,1)); D = rbind(c(0,0), c(0,0)) ss2tf(A,B,C,D,1) # to obtain output for input 1 ss2tf(A,B,C,D,2) # to obtain output for input 2 ## Not run: OR systems <- vector("list", ncol(D)) for(i in 1:ncol(D)){ systems[[i]] <- ss2zp(A,B,C,D,i) } systems systems[[1]] systems[[2]]
ssdata retrieves the model for a state-space system from a sys object
ssdata(sys1)ssdata(sys1)
sys1 |
an LTI system object of tf, ss or zpk classes |
ssdata retrieves a model object for a state-space system, from a sys object of tf, ss and zpk classes
Returns a list object of ss class containing A, B, C and D matrices
sys1 <- tf(c(1), c(1,2,1)) ssdata(sys1) A <- rbind(c(-2, -1), c(1,0)); B <- rbind(1,0); C <- cbind(0,1); D <- 0; sys2 <- ss(A,B,C,D) ssdata(sys2) ss2zp(ssdata(zpk(NULL, c(-1,-1), 1)))sys1 <- tf(c(1), c(1,2,1)) ssdata(sys1) A <- rbind(c(-2, -1), c(1,0)); B <- rbind(1,0); C <- cbind(0,1); D <- 0; sys2 <- ss(A,B,C,D) ssdata(sys2) ss2zp(ssdata(zpk(NULL, c(-1,-1), 1)))
step obtains the time response of the linear system:
step(sys, t, input) stepplot(sys, t, input)step(sys, t, input) stepplot(sys, t, input)
sys |
LTI system of transfer-function, state-space and zero-pole classes |
t |
Time vector. If not provided, it is automatically set. |
input |
For calls to For calls to |
step produces the step response of linear systems using lsim
stepplot produces the step response as a plot againts time.
The functions can handle both SISO and MIMO (state-space) models.
Other possible calls using step and stepplot are:
step(sys)
step(sys, t)
stepplot(sys)
stepplot(sys, t)
A list is returned by calling step containing:
x Individual response of each x variable
y Response of the system
t Time vector
The matrix y has as many rows as there are outputs, and columns of the same size of length(t).
The matrix X has as many rows as there are states. If the time
vector is not specified, then the automatically set time
vector is returned as t
A plot of y vs t is returned by calling stepplot
res <- step(tf(1, c(1,2,1))) res$y res$t step(tf(1, c(1,2,1)), seq(0, 10, 0.1)) stepplot(tf(1, c(1,2,1))) stepplot(tf(1, c(1,2,1)), seq(0, 10, 0.1)) ## Not run: State-space MIMO systems A <- rbind(c(0,1), c(-25,-4)); B <- rbind(c(1,1), c(0,1)); C <- rbind(c(1,0), c(0,1)); D <- rbind(c(0,0), c(0,0)) res1 <- step(ss(A,B,C,D), input = 1) res2 <- step(ss(A,B,C,D), input = 2) res1$y # has two rows, i.e. for two outputs res2$y # has two rows, i.e. for two outputs stepplot(ss(A,B,C,D), input = 1:2) # OR stepplot(ss(A,B,C,D), input = 1:ncol(D))res <- step(tf(1, c(1,2,1))) res$y res$t step(tf(1, c(1,2,1)), seq(0, 10, 0.1)) stepplot(tf(1, c(1,2,1))) stepplot(tf(1, c(1,2,1)), seq(0, 10, 0.1)) ## Not run: State-space MIMO systems A <- rbind(c(0,1), c(-25,-4)); B <- rbind(c(1,1), c(0,1)); C <- rbind(c(1,0), c(0,1)); D <- rbind(c(0,0), c(0,0)) res1 <- step(ss(A,B,C,D), input = 1) res2 <- step(ss(A,B,C,D), input = 2) res1$y # has two rows, i.e. for two outputs res2$y # has two rows, i.e. for two outputs stepplot(ss(A,B,C,D), input = 1:2) # OR stepplot(ss(A,B,C,D), input = 1:ncol(D))
tf creates the model for a transfer function
tf(num, den, Ts = NULL)tf(num, den, Ts = NULL)
num |
A numeric vector or matrix (for multivariable systems) |
den |
A numeric vector or matrix (for multivariable systems) |
Ts |
Sample time for discrete time systems |
tf creates a model object for a transfer function, Where num is the numerator and den is the denominator
of the transfer function.
Returns an object of 'tf' class list with a proper transfer function or with warnings when not proper.
tf(1, c(1,2,1)) sys1 <- tf(1, c(1,2,1)) sys1$num sys1$den ## Not run: for single-input multi-output systems (SIMO) each numerator row for one output num = rbind(c(0,1,1), c(1,0,1)) den = rbind(c(1,3,2)) tf(num, den)tf(1, c(1,2,1)) sys1 <- tf(1, c(1,2,1)) sys1$num sys1$den ## Not run: for single-input multi-output systems (SIMO) each numerator row for one output num = rbind(c(0,1,1), c(1,0,1)) den = rbind(c(1,3,2)) tf(num, den)
TF Evaluates a given transfer function expression in the s-domain
TF(str_expr)TF(str_expr)
str_expr |
String expression containing the transfer function |
TF Evaluates a given transfer function polynomial expression in the s-domain.
The evaluation of the expressions are performed similar to symbolic math computations for polynomials.
A transfer function model is created as the result of the expression evaluation.
Thus, this is an alternative way of creating transfer function models following the natural math expressions
found in block diagrams. It also provides an alternative way to perform system interconnections. Only transfer
function models are currently supported for system interconnection using this function. System interconnections
for other models could be performed using the series, parallel, feedback or connect functions.
See the Examples section for further details.
Returns an object of 'tf' class list with a transfer function. Numerator and denominator
coefficients could then be retrieved from the object the same way as any other tf object
# Example taken from the GitHub page of Julia Control - an electric motor example J <- 2.0 b <- 0.04 K <- 1.0 R <- 0.08 L <- 1e-4 P <- TF("K/(s*((J*s + b)*(L*s + R) + K^2))") Cls <- TF("P/(1 + P)") # closed-loop connection # More examples TF("s+1") sys1 <- tf(1, c(1, 2, 5)) sys2 <- tf(2, c(1, 2, 5)) TF("sys1 + sys2") # parallel system interconnection TF("sys1 * sys2") # series system interconnection TF("sys1 - sys2") TF("sys1 - 1") TF("sys1 + 1") TF("sys1 - sys2 + sys2") TF("sys1 / sys2 / sys2")# Example taken from the GitHub page of Julia Control - an electric motor example J <- 2.0 b <- 0.04 K <- 1.0 R <- 0.08 L <- 1e-4 P <- TF("K/(s*((J*s + b)*(L*s + R) + K^2))") Cls <- TF("P/(1 + P)") # closed-loop connection # More examples TF("s+1") sys1 <- tf(1, c(1, 2, 5)) sys2 <- tf(2, c(1, 2, 5)) TF("sys1 + sys2") # parallel system interconnection TF("sys1 * sys2") # series system interconnection TF("sys1 - sys2") TF("sys1 - 1") TF("sys1 + 1") TF("sys1 - sys2 + sys2") TF("sys1 / sys2 / sys2")
tf2ss converts the model for a transfer function to state-space representation
tf2ss(num, den)tf2ss(num, den)
num |
A numeric vector containing the coefficients of the |
den |
A numeric vector containing the coefficients of the |
tf2ss converts a model object for a transfer function to a state-space model, Where num is the numerator and den is the denominator
of the transfer function and sys is a transfer function object
Another possible call is tf2ss(sys) where sys is object of transfer-function model.
Returns an object of 'ss' class.
tf2ss(tf(1, c(1,2,1))) ## Not run: OR sys <- tf(1, c(1,2,1)) tf2ss(sys) ## Not run: OR sys2 <- tf2ss(1, c(1,2,1))tf2ss(tf(1, c(1,2,1))) ## Not run: OR sys <- tf(1, c(1,2,1)) tf2ss(sys) ## Not run: OR sys2 <- tf2ss(1, c(1,2,1))
tf2zp converts the model for a transfer function to zero-pole-gain representation
tf2zp(num, den)tf2zp(num, den)
num |
A numeric vector containing the coefficients of the |
den |
A numeric vector containing the coefficients of the |
tf2zp converts a model object for a transfer function to a zero-pole model, Where num is the numerator and den is the denominator
of the transfer function and sys is a transfer function object
Another possible call is: tf2zp(sys)
where sys is an object of transfer-function model.
Returns a list object of 'zpk' class.
syszp1 <- tf2zp(c(1,1), c(1,2,1)) syszp1 syszp2 <- tf2zp(c(2,2,1), c(1,2,1)) syszp2 unclass(syszp2) # to see list of the zeros,poles and gain as vectors tf2zp(zp2tf(c(-1,-1), c(-1,-2), 5))syszp1 <- tf2zp(c(1,1), c(1,2,1)) syszp1 syszp2 <- tf2zp(c(2,2,1), c(1,2,1)) syszp2 unclass(syszp2) # to see list of the zeros,poles and gain as vectors tf2zp(zp2tf(c(-1,-1), c(-1,-2), 5))
tfchk verifies the structure of a transfer function
tfchk(num, den)tfchk(num, den)
num |
A numeric vector |
den |
A numeric vector |
This is a utility function that is always invoked by other functions to
verify the structure of num, den. Where num is the numerator and den is the denominator
of the transfer function. If the transfer function is not proper, it returns a list with length(num) = length(den).
Returns a list with a proper transfer function or with warnings when not proper.
tf1 <- tfchk(1, c(1,2,1))tf1 <- tfchk(1, c(1,2,1))
tfdata retrieves the model for a transfer function from a sys object
tfdata(sys1)tfdata(sys1)
sys1 |
an LTI system object of tf, ss or zpk classes |
tfdata retrieves a model object for a transfer function, from a sys object of tf, ss and zpk classes
Returns a list object of tf class containing numerator and denominator coefficients in desecending values of s.
For multiple-input multiple-output systems (MIMO) a list containing tf sys objects for as many outputs is returned
sys1 <- zpk(NULL, c(-1,-1), 1) tfdata(sys1) A <- rbind(c(-2, -1), c(1,0)); B <- rbind(1,0); C <- cbind(0,1); D <- 0 tfdata( ss(A, B, C, D) ) tfdata(ss2zp( A,B,C,D)) tfdata(tf(c(1), c(1,2,1))) ## Not run: MIMO system A = rbind(c(0,1), c(-25,-4)); B = rbind(c(1,1), c(0,1)); C = rbind(c(1,0), c(0,1)); D = rbind(c(0,0), c(0,0)) tfdata(ss(A,B,C,D))sys1 <- zpk(NULL, c(-1,-1), 1) tfdata(sys1) A <- rbind(c(-2, -1), c(1,0)); B <- rbind(1,0); C <- cbind(0,1); D <- 0 tfdata( ss(A, B, C, D) ) tfdata(ss2zp( A,B,C,D)) tfdata(tf(c(1), c(1,2,1))) ## Not run: MIMO system A = rbind(c(0,1), c(-25,-4)); B = rbind(c(1,1), c(0,1)); C = rbind(c(1,0), c(0,1)); D = rbind(c(0,0), c(0,0)) tfdata(ss(A,B,C,D))
zp2ss converts a system represented in zero-pole form to state-space
zp2ss(z,p,k)zp2ss(z,p,k)
z |
Zero, a vector or single row matrix |
p |
Pole, a vector or single row matrix |
k |
Gain, a vector |
zp2ss converts a system represented in zero-pole form to state-space by converting from zero-pole to transfer function and from transfer functon to state-space
Another possible usage is: zp2ss(sys)
where sys is an object of zero-pole-gain model.
Returns a list object of 'ss' class.
zp2ss(NULL, c(-1,-1), 1) zp2ss(tf2zp(c(1,1,1), c(1,2,1)))zp2ss(NULL, c(-1,-1), 1) zp2ss(tf2zp(c(1,1,1), c(1,2,1)))
zp2tf converts the model for a zero-pole-gain system to transfer function representation
zp2tf(z, p, k)zp2tf(z, p, k)
z |
A numeric vector containing zero locations |
p |
A numeric vector containing pole locations |
k |
A numeric vector for gain |
zp2tf converts a model object for a zero-pole-gain system to a transfer function model
Another possible usage is: zp2tf(sys)
where sys is an object of zero-pole-gain model.
Returns a list object of 'tf' class.
systf <- zp2tf(zpk(NULL, c(-1,-1), 1)) zp2tf(tf2zp(c(2,2,1), c(1,2,1)))systf <- zp2tf(zpk(NULL, c(-1,-1), 1)) zp2tf(tf2zp(c(2,2,1), c(1,2,1)))
zpk creates the model for a system represented in zero-pole form
zpk(zero, pole, gain, Ts = NULL)zpk(zero, pole, gain, Ts = NULL)
zero |
A vector |
pole |
A vector |
gain |
A vector |
Ts |
Sample time for discrete time systems |
zpk creates a model object for zero-pole systems.
Returns a list object of 'zpk' class.
sys <- zpk(NULL, c(-1,-1), 1) sys <- zpk(c(1,2), c(3,4), 5) sys <- zpk(c(1,2), c(3+1i,4+2i), 5) ## Not run: Access individual sys elements as sys$z sys$p sys$ksys <- zpk(NULL, c(-1,-1), 1) sys <- zpk(c(1,2), c(3,4), 5) sys <- zpk(c(1,2), c(3+1i,4+2i), 5) ## Not run: Access individual sys elements as sys$z sys$p sys$k
zpkdata retrieves the model for a zero-pole-gain system from a sys object
zpkdata(sys1)zpkdata(sys1)
sys1 |
an LTI system object of |
zpkdata retrieves a model object for a zero-pole-gain system, from a sys object of tf, ss and zpk classes
Returns a list object of zpk class containing zero, pole and gain matrices. For multivariable systems,
the zeros of each system is listed as a column in the zeros matrix, the poles are listed as a column-vector as well as the
gain
sys1 <- zpk(NULL, c(-1,-1), 1) zpkdata(sys1) sys3 <- tf(c(1), c(1,2,1)) zpkdata(sys3) ## Not run: MIMO system of 2-inputs and 2-outputs A = rbind(c(0,1), c(-25,-4)); B = rbind(c(1,1), c(0,1)); C = rbind(c(1,0), c(0,1)); D = rbind(c(0,0), c(0,0)) zpkdata(ss(A,B,C,D)) ## OR syszp <- zpkdata(ss(A,B,C,D)) syszp[[1]] syszp[[2]] syszp[[1]]$z # retrieve zeros of system 1 - Input 1 to Outputs 1 and 2 syszp[[2]]$z # retrieve zeros of system 2 - Input 2 to Outputs 1 and 2sys1 <- zpk(NULL, c(-1,-1), 1) zpkdata(sys1) sys3 <- tf(c(1), c(1,2,1)) zpkdata(sys3) ## Not run: MIMO system of 2-inputs and 2-outputs A = rbind(c(0,1), c(-25,-4)); B = rbind(c(1,1), c(0,1)); C = rbind(c(1,0), c(0,1)); D = rbind(c(0,0), c(0,0)) zpkdata(ss(A,B,C,D)) ## OR syszp <- zpkdata(ss(A,B,C,D)) syszp[[1]] syszp[[2]] syszp[[1]]$z # retrieve zeros of system 1 - Input 1 to Outputs 1 and 2 syszp[[2]]$z # retrieve zeros of system 2 - Input 2 to Outputs 1 and 2