Model Predictive Control of a DC Motor

Control a multivariable nonlinear system subjected to constraints using model predictive control (MPC). Many simple control systems take an ad hoc approach in which they effectively just "watch what a system does" without trying to have a specific model for what is going on inside the system. Model predictive control (MPC) is about having a specific model for a system and then deriving an optimal controller based on that model.
In this example, MPC is used to control the speed of a DC motor while constraining the value of electric current flowing in the circuit.
Import the Wolfram System Modeler model of the DC motor:
(Press Shift + Enter to evaluate.)
In[]:=
CloudImport["https://www.wolframcloud.com/obj/861cd6ae-7262-46d7-9860-88ac63dfbed6","MO"];
Check the model diagram of the DC motor:
In[]:=
sm=SystemModel["DCMotor"];​​sm[{"Diagram",ImageSizeLarge}]
Out[]=
Check the model parameters:
In[]:=
sm["TopParameterNames"]
Out[]=
{
R
,
L
,
J
,
emfK
,
B
}
Give suitable values to the parameters:
In[]:=
params=<|"R"1.2,"L"0.001,"J"0.01,"emfK"0.05,"B"0.001|>;​​SetSystemModel[sm,params];
Linearize the model and see its states, input and outputs:
In[]:=
SystemModelLinearize[sm]
Out[]=
​
​
V
inductor.i
-1200.
0.
-50.
1000.
inertiaWithDamper.phi
0.
0.
1.
0.
inertiaWithDamper.w
5.
0.
-0.1
0.
w
0.
0.
1.
0.
i
1.
0.
0.
0.
Set the model specification:
In[]:=
sspec=​​<|​​"InputModel"sm,​​"SamplingPeriod"0.1,​​"TrackedOutputs"{"w"},​​"SamplingMethod""ForwardRectangularRule"​​|>;
Predict over three time steps (time horizon) and provide weights for the error (to control the response speed) and input increment:
In[]:=
cost=<|"Horizon"3,"ErrorWeight"DiagonalMatrix[{2}],"InputIncrementWeight"DiagonalMatrix[{1}]|>;
Constrain the current flowing in the circuit:
In[]:=
cons1=0≤"i"≤1;
Create a model predictive controller:
In[]:=
cd1=ModelPredictiveController[sspec,cost,cons1]
Out[]=
SystemsModelControllerData
Design: MPC tracker
»
Horizon: 3

Create a controlled system:
In[]:=
csys=ConnectSystemModelController["test",sm,cd1]
Out[]=
Find its connectors:
In[]:=
SystemModel["test","Connectors"]
Out[]=
i∈
,refW∈
,w∈

Connect the controlled system to a constant reference source:
In[]:=
components={"constant1"∈"Modelica.Blocks.Sources.Constant","test1"∈"test"};​​connections={"constant1.y""test1.refW"};​​model=ConnectSystemModelComponents["testModel",components,connections]
Out[]=
Simulate and plot the angular velocity of the shaft of the DC motor:
In[]:=
sim=SystemModelSimulate["testModel",100];​​SystemModelPlot[sim,{"test1.w","constant1.y"},PlotRangeAll]
Out[]=
test1.w
constant1.y
Check the value of the constrained current:
In[]:=
SystemModelPlot[sim,{"test1.i"},PlotRangeAll]
Out[]=
Look for the name of the voltage variable in the controlled system:
In[]:=
controlledVoltage=sim[{"VariableNames","*.V"}]
Out[]=
{test1.eSys.sys.V}
Check the controlled voltage supplied to the circuit:
In[]:=
SystemModelPlot[sim,controlledVoltage,PlotRangeAll]
Out[]=
Compute the performance of the controlled system: