The Control Libraries API contains functions for implementing discrete time linear time invariant (LTI) filters which can be used in the interrupt service routine for signal processing or closed loop control. The LTI controller may be specified as a general multi-input/multi-output (MIMO) system in either the state space or transfer function (numerator/denominator) form. The state of the filter may be arbitrarily specified for initialization, bumpless transfer, etc. The parameters of the filter may also be specified for on-line gain tuning. In addition to general MIMO LTI filters, a specific single-input/single-output (SISO) discrete proportional - integral - derivative (PID) controller is also provided. The PID gains can also be specified during run time by resetting the gains in the outer (slower) interrupt loop.
Every LTI filter created will be assigned a corresponding LTI structure. The creation of the LTI filter through
makess, makeND, or makePID would return a pointer to the structure. If a filter is no longer needed, it should
be freed so the associated memory may be used for othered memory may be used for other purposes.
The LTI structure is defined in control.h.
In the following example, we define a PID
controller, a state space filter, and a transfer matrix. The state
space filter is chosen to have two inputs, two outputs, and three
states. The transfer matrix is chosen to have two inputs and one
output. The first entry is chosen to have a constant numerator and a
second order denominator. The second entry is chosen to have a first
order numerator and a third order denominator.
The LTI structures arestructures are created in the main program. ISR0 is used to
perform the filtering based on encoder input and ISR1 is used to
update the parameters.
- LTIsys *sys1, *sys2, *sys3;
- float DT0=0.001; /* 1ms sampling rate */
- /* State space parameters */
- float Ad[9]={0.1, -0.02, 0.01, 0.05, 0.1, -0.1, 0.03, 0.03, 0.1};
- float Bd[6]={1.0, -0.2, 0.51, -0.42, 0.2, -0.1};
- float Cd[6]={-2.0, 0.02, 0.15, 0.2, 0.0, -0.1};
- float Dd[4]={0.0, 0.8, 0.2, 0.4};
- float x0[3]={1.0, 0.0, -1.0}
- /* Transfer matrix parameters */
- float n1[1]={2.0};
- float d1[3]={1.0, -0.02, 0.51};
- float n2[2]={-2.0, 0.8};
- float d2[4]={2.5, 0.8, -0.2, 0.4};
- /* PID controller parameters */
- float kp=0.5;
- float ki=0.02;
- float kd=0.4;
- main()
- {
- sys1=makepid(DT0); /* create PID controller structure */
- sys2=makeSS(3,2,2,DT0); /* create state space controller structure */
- sys3=makeND(2,1,DT0); /* create transfer matrix controller structure */
- /* set PID filter parameters */
- setPID(sys1, kp, ki, kd);
- /* set state space filter parameters */
- setSS_param(sys2, Ad, Bd, Cd, Dd);
- setSS_state(sys2, x0);
- /* set transfer matrix filter parameters */
- setND_param(sys3, n1, d1, 0, 2, 1, 1);
- setND_param(sys3, n2, d2, 1, 3, 2, 1);
- /* other initialization code, e.g., for I/O, communication etc. */
- ...
- }
Inon etc. */
...
}
In ISR0, the filter update is performed:
- float u1; /* output of PID controller */
- float u2[2]; /* output of State Space filter */
- float u3[2]; /* output of transfer matrix filter */
- float error1; /* input to PID controller */
- float error2[2]; /* input to State Space filter */
- float error3; /* input to transfer matrix filter */
- #pragma INTERRUPT (timer0)
- void timer0 ()
- {
- /* assumed inputs are already obtained */
- ...
- LTIfilter(sys1,&error1,&u1);
- LTIfilter(sys2,error2,u2);
- LTIfilter(sys3,&error3,u3);
- ...
- }
If the gains and filter parameters may need to be changed during run
time, they need to be periodically reset. We use ISR1 in this example
for this purpose.
- #pragma INTERRUPT (timer1)
- void timer1 ()
- {
- /* set PID filter parameters */
- setPID(sys1, kp, ki, kd);
- /* set state space filter parameters */
- setSS_param(sys2, Ad, Bd, Cd, Dd);
- setSS_state(sys2, x0);
- /* set transfer matrix filter parameters */
- setND_param(sys3, n1, d1, 0, 2, 1, 1);
- setND_param(sys3, n2, d2, 1, 3, 2, 1);
- ...
- }

makeSS
makeND
freeLTIsys
setSS_state
getSS_state
setSS_param
setND_state
getND_state
setND_param
makePID
setPID
freePID
LTIfilter

LTIsys *makeSS(unsigned int ns, unsigned int ni, unsigned int no,
float ts);
- Creation of a MIMO state space LTI discrete time filter structure.
Parameters are set through
setSS_param
command. The initial state is to be all zeros.
Input Parameters
- ns: number of states
- ni: number of inputs
- no: number of outputs
- ts: sampling rate (sec)
- Return
- pointer to the asslocated LTI structure
LTIsys *makeND( unsigned int ni, unsigned int no, float ts);
- Creation of a MIMO transfer function LTI discrete time filter structure.
Parameters are set through
e.
Parameters are set through setND_param
command.
Input Parameters
- ni: number of inputs
- no: number of outputs
- ts: sampling rate (sec)
- Return
- pointer to the asslocated LTI structure
void freeLTIsys(LTIsys *sys);
- Free the previously allocated LTI structures (through
makeSS or makeND ).
Input Parameters
- *sys: Pointer to the LTI structure to be deallocated
- Return
- None
void setSS_state(LTIsys *sys, float *newState);
- Set the state of an allocated state space LTI filter.
Input Parameters
- *sys: Pointer to the state space LTI structure
- *newState: Pointer to the array containing the new state
- Return
- None
void getSS_state(LTIsys *sys, float *state);
- Get the current state in an allocated state space LTI filter.
Input Parameters
- *sys: Pointer to the state space LTI structure
- Return Parameters
- *state: Array containing the current state
- Return
- None
void setSS_param(LTIsys *sys, float *A, float *B, float *C, float *D);
- Set the state space parameters (A,B,C,D) in a state space LTI fitler.
The LTI structure stores the pointers to the parameter
arrays (A, B, C, D ) instead of the
actual values, therefore these arrays cannot be deallocated.
Input Parameters
- *sys: Pointer to the state space LTI structure
- *A: Pointer to the system ter to the system matrix (row by row)
- *B: Pointer to the input matrix (row by row)
- *C: Pointer to the outputput matrix (row by row)
- *D: Pointer to the feedforward matrix (row by row)
- Return
- None
void setND_state(LTIsys *sys, float *newState, unsigned int row, unsigned int column);
- Set the state of an entry in an allocated MIMO transfer matrix
LTI filter. Note that setND_param needs to be issued
first.
Input Parameters
- *sys: Pointer to the transfer function LTI structure
- row: row number of the specified entry in the transfer matrix
- column: column number of the specified entry in the transfer matrix
- *newState: Pointer to the array containing the new state (past outputs)
- Return
- None
void getND_state(LTIsys *sys, float *state, unsigned int row,
unsigned int column);
- Get the state of an entry in an allocated MIMO transfer matrix
LTI filter.
Input Parameters
- *sys: Pointer to the transfer function LTI struct>*sys: Pointer to the transfer function LTI structure
- row: row number of the specified entry in the transfer matrix
- column: column number of the specified entry in the transfer matrix
- Return Parameters
- *state: Array containing the current state
- Return
- None
void setND_param(LTIsys *sys, float *n, float *d, unsigned int orderN,
unsigned int orderD, unsigned int row,
unsigned int column);
- Set the parameters in a specified entry in an allocated MIMO
transfer matrix: order of numerator, order of denominator,
coefficients of numerator, and coefficients of denominators (specified
from highest order term to lowest order term).
The LTI structure stores the pointers to the numerator and
denominator arrays ( n and d) instead of the
actual values, therefore they cannot be deallocated.
The initial state of the transfer function is set to be all zeros.
Input Parameters
- *sys: Pointer to the transfer function LTI structure
- row: row number of the specified entry in the transfer matrix
- column: column number of the specified entry in the transfer matrix
- orderN: order of the numerator polynomial
- orderD: order of the denominator polynomial
- *n: Pointer to the numerator polynomial coefficients (starting from the
highest order). Length = orderN+1
- *d: Pointer to the denominator polynomial coefficients (starting from the
highest order). Length = orderD+1
- Return
- None
LTIsys *makePID(float ts);
- Creates a SISO transfer function LTI structure corresponding to a
discrete time PID controller. Note numerator and denominator arrays
corresrator and denominator arrays
corresponding to the PID transfer function are allocated.
Input Parameters
- ts: sampling rate (sec)
- Return
- pointer to the asslocated LTI structure
void setPID(LTIsys *pidsys, float kp, float ki, float kd)
- Sets the PID parameters in a previously allocated LTI transfer
function structure corresponding to the PID controller. The transfer
functi. The transfer
function is of the following form:
[ (kp+ki+kd) z^2 - (kp+2*kd) z + kd ] / [z^2 - z ]
Input Parameters
- *pidsys: Pointer to the transfer function LTI structure
- kp: proportional gain
- ki: integral gain
- kd: derivative gain
- Return
- None
void freePID(LTIsys *pidsys)
- Deallocate a previously allocated SISO transfer function LTI
structure corresponding to a discrete time PID controller (this should
be called only after both makePID and setPID had
been called.
Input Parameters
- *pidsys: Pointer to the LTI structure to be deallocated
- ts: sampling rate (sec)
- Return
- None
void LTIfilter(LTIsys *sys, float *input, float *output)
- Calculates the discrete LTI filter output based on the current
state and current input.
If the LTI filter is of the state space type, output and state update are
computed as:
y = C x + D u
x = A x + B u
If the LTI filter is of the transfer function type, output and stI filter is of the transfer function type, output and state
update are:
y_i = sum_j ( [0...0 n_ij] . state_ij ) (if order n_ij < order d_ij)
y_i = sum_j ( n_ij(2..order n_ij+1) . state_ij + n_ij(1) * input j ) (if
order n_ij = order d_ij)
state_ij = - d_ij(2..order d_ij + 1) . state_ij / d_ij(1) + input j
Input Parameters
- *sys: Pointer to the LTI structure
- *input: Pointer to the input array
- Output Parameters
- *output: Pointer to the output array
- Return
- None
Last modified: Sun June 4 Eastern Standard Time
2000