Control Design Made Easy

Suba Thomas
Wolfram Research, Inc.

System design - an overview

• Requirements
• Modeling
• Analysis
• Controller design
• Simulation / Post analysis
• Implementation
• Verification

https://www.wolfram.com/language/core-areas/controls/

State feedback design

B. A. Ogunnaike and W. H. Ray, Process Dynamics, Modeling, and Control, Oxford University Press, 1994

Basic design

A model:

ssm=StateSpaceModel[,,,{q[t]},t,,DescriptorStateSpace->True]/.(Subscript[q, 0])->(Subscript[q, 10])+(Subscript[q, 20])/.

Analysis:

olor=OutputResponse[ssm,{0,UnitBox[t-1]},{t,0,300}];
Plot[olor,{t,0,300},PlotRange->All]

Design:

cd=StateFeedbackGains[ssm,{-0.5,-0.3},"Data"]

cd["Properties"]

The closed-loop system:

csys=cd[{"ClosedLoopSystem",<|"Merge"->False|>}]

The block diagram:

cd["BlockDiagram"]

A simulation:

rd=InputOutputResponse[csys,{0,UnitBox[t-1]},{t,0,300},"Data"]

rd["Properties"]

The output response:

rd["OutputResponse"];
Plot[%,{t,0,30},PlotRange->All]

The control effort:

cd["BlockDiagram"]

rd[{"SubsystemOutputResponse","ComparatorModel"}];
Plot[%,{t,0,30},PlotRange->All]

Sampled-data design

The sampled-data closed-loop system:

csysSD=cd[{"ClosedLoopSystem",<|"Merge"->False,"SampledData"->True|>}]

Its block diagram:

cd[{"BlockDiagram",<|"SampledData"->True|>}]

A simulation:

rdSD=InputOutputResponse[csysSD,{0,UnitBox[t-1]},{t,0,300},"Data"]

Its output response:

rdSD["OutputResponse"];
Plot[%,{t,0,30},PlotRange->All]

The control effort:

rdSD[{"SubsystemOutputResponse","ComparatorModel"}];
Plot[%,{t,0,30},PlotRange->All]

Output feedback design

B. Freidland, Control System Design: An Introduction to State-Space Methods, Dover Publications, March 24, 2005

Basic design

A model:

turret=StateSpaceModel[/.,{θ[t],ω[t],𝓅[t],𝓆[t]},
{𝓊[t],(Subscript[𝒹, r])[t],(Subscript[𝒹, p])[t],(Subscript[𝒹, q])[t]},{θ[t],ω[t]},t]

Analysis:

OutputResponse[{turret,{0.6,0.05,0,0}},{0,0,0,0},{t,0,0.1}];
Plot[%,{t,0,1},PlotRange->All,PlotLegends->{θ,𝓆}]

Design specifications:

sspec=<|"InputModel"->turret,"FeedbackInputs"->1,"TrackedOutputs"->1|>;

cvs={ DiagonalMatrix[{1,1,1}],DiagonalMatrix[{1,1}]};
wts={DiagonalMatrix[{1,1,1,1,(10^10)}],{{(10^5)}}};

Design:

cd=LQGRegulator[sspec,cvs,wts,"Data"]

The closed-loop system:

csys=cd[{"ClosedLoopSystem",<|"Merge"->False|>}]

The block diagram:

cd["BlockDiagram"]

A simulation:

dinp=NormalDistribution[0,(10^(-3))];

rd=InputOutputResponse[csys,{dinp,dinp,dinp,5°,dinp,dinp},{t,0,10},"Data"]

The output response:

rd["OutputResponse"]/Degree;
Plot[#,{t,0,1},PlotRange->All]&/@ %

The controller effort:

rd[{"SubsystemOutputResponse","ComparatorModel"}];
Plot[%,{t,0,1},PlotRange->All]

Sampled-data design

A sampled-data closed-loop system:

csysSD=cd[{"ClosedLoopSystem",<|"Merge"->False,"SampledData"->True,"SamplingPeriod"->0.1|>}]

Its block diagram:

cd[{"BlockDiagram",<|"SampledData"->True|>}]

A simulation:

rdSD=InputOutputResponse[csysSD,{dinp,dinp,dinp,5°,dinp,dinp},{t,0,10},"Data"];

Its output response:

rdSD["OutputResponse"]/Degree;
Plot[#,{t,0,10},PlotRange->All]&/@ %

The control effort:

rdSD[{"SubsystemOutputResponse","ComparatorModel"}];
Plot[%,{t,0,2},PlotRange->All]

Compare the actual and estimated states:

sr=rdSD["StateResponse"];
esr=Most@rdSD[{"SubsystemOutputResponse","EstimatorModel"}];

MapThread[Plot[{##},{t,0,2},PlotRange->All]&,{sr,esr}]

Compare the reference and actual output :

Join[rdSD[{"SubsystemOutputResponse","ReferenceInputSamplerModel"}],
rdSD[{"SubsystemOutputResponse","EstimatorModel"}][[{-1}]]]/Degree;

Plot[%,{t,0,2},PlotRange->All]

Simulation

Continuous-time systems

tfm=TransferFunctionModel[(1/s),s];

Simulate continuous-time responses from continuous- or discrete-time inputs:

InputOutputResponse[tfm,Sin[t],{t,0,5}]

InputOutputResponse[tfm,NormalDistribution[0,0.1],{t,0,20}]

InputOutputResponse[tfm,{inp=RandomVariate[NormalDistribution[0,0.1],21]},{t,0,20}]

Interpolation[Thread[{Range[0,20],inp}],t];
InputOutputResponse[tfm,%,{t,0,20}]

InputOutputResponse[tfm,{NormalDistribution[0,0.1],40},{t,0,20}]

Discrete-time systems

ssm=StateSpaceModel[{{{0.2}},{{1}}},SamplingPeriod->1];

Simulate discrete-time responses from discrete- or continuous-time inputs:

InputOutputResponse[ssm,Sin[t],{t,0,5}]

InputOutputResponse[ssm,{Table[Sin[t],{t,0,5}]},{t,0,5}]

Temporal data

InputOutputResponse[tfm,TimeSeries[],{t,0,15}]

InputOutputResponse[ssm,TimeSeries[]]

inp=RandomFunction[RandomWalkProcess[.5],{0,15}]

InputOutputResponse[tfm,inp,{t,0,15}]

InputOutputResponse[tfm,RandomWalkProcess[.5],{t,0,15}]

InputOutputResponse[ssm,inp]

Sampler and Holder models

Sampler model

Convert a continuous-time signal to a discrete-time signal:

r=InputOutputResponse[SamplerModel[],Sin[t],{t,0,2π}]

Plot[{r,Sin[t]},{t,0,2π}]

A custom model:

SamplerModel[<|"SamplingPeriod"->0.5,"SignalCount"->2|>]

r=InputOutputResponse[%,{Sin[t],Cos[t]},{t,0,2π}]

Show[Plot[{Sin[t],Cos[t]},{t,0,2π},PlotStyle->Dashed],Plot[r,{t,0,2π}]]

Holder model

Convert a discrete-time signal to a continuous-time signal:

r=InputOutputResponse[HolderModel[],inp=Table[Sin[t],{t,0,3π}]]

Show[Plot[r,{\[FormalT],0,3π}],ListPlot[inp,]]

A custom model:

HolderModel[<|"Order"->2,"SamplingPeriod"->(sp=0.5)|>]

r=InputOutputResponse[%,Table[Sin[t],{t,0,3π,sp}]];

Show[Plot[r,{\[FormalT],0,3π},PlotHighlighting->None],ListPlot[Table[{t,Sin[t]},{t,0,3π,sp}],]]

Properties

State-space model

ssm=StateSpaceModel[{m x''[t]+c x'[t]+k x[t]==f[t]},{{x[t],0},{x'[t],0}},{{f[t],0}},{x[t]},t]

ssm["Properties"]

ssm

ssm["StateMatrix"]

ssm["InputMatrix"]

ssm[{"InputMatrix","StateMatrix"}]

ssm["Equations"]

Transfer-function model

tfm=TransferFunctionModel[ssm]

tfm["Properties"]

tfm["Expressions"]

tfm["ComplexVariable"]

Select[tfm["Properties"],StringMatchQ[#,"Equation"~~__]&]

eqns=tfm["Equations"]

iVars=tfm["EquationInputVariables"]

vars=tfm["EquationVariables"]

oExprs=tfm["EquationOutputExpressions"]

tVar=tfm["TemporalVariable"]

DSolveValue[Join[eqns,{(Subscript[\[FormalY], 1,1])[0]==0,(Subscript[\[FormalY], 1,1])'[0]==0}]/.Thread[iVars->1],oExprs,tVar]//Simplify

InputOutputResponse[tfm,1,tVar]//Simplify

PossibleZeroQ[%-%%]

Typesetting

Appearance

Automatically choose appearance according to the size of the nb:

With[{n=2,ni=4,no=3},StateSpaceModel[{RandomReal[{-1,1},{n,n}],RandomReal[{-1,1},{n,ni}],RandomReal[{-1,1},{no,n}]}]]

With[{n=20,ni=4,no=3},StateSpaceModel[{RandomReal[{-1,1},{n,n}],RandomReal[{-1,1},{n,ni}],RandomReal[{-1,1},{no,n}]}]]

With[{n=40,ni=4,no=3},StateSpaceModel[{RandomReal[{-1,1},{n,n}],RandomReal[{-1,1},{n,ni}],RandomReal[{-1,1},{no,n}]}]]

NonlinearStateSpaceModel[%]

Specify the appearance:

ssm=StateSpaceModel[,,,,]

StateSpaceModel[ssm,Appearance->"Structured"]

StateSpaceModel[ssm,Appearance->"Elided"]

StateSpaceModel[ssm,Appearance->"Iconized"]

Specify a custom icon:

StateSpaceModel[ssm,Appearance->"Iconized",InputOutputModelIcon->]

Attached cell

ssm/.

Summary

• Automated and streamlined workflow for control design and deployment
• Streamlined simulation
• Compute model properties and enhanced typesetting