11using BenchmarkTools
22using ModelPredictiveControl, ControlSystemsBase, LinearAlgebra
3+ using JuMP, OSQP, DAQP, Ipopt, MadNLP
34
45Ts = 400.0
56sys = [ tf (1.90 ,[1800.0 ,1 ]) tf (1.90 ,[1800.0 ,1 ]) tf (1.90 ,[1800.0 ,1 ]);
67 tf (- 0.74 ,[800.0 ,1 ]) tf (0.74 ,[800.0 ,1 ]) tf (- 0.74 ,[800.0 ,1 ]) ]
78
8- const SUITE = BenchmarkGroup ()
9+ const SUITE = BenchmarkGroup ([ " ModelPredictiveControl " ] )
910
1011# # ==================================================================================
1112# # ================== SimModel benchmarks ===========================================
@@ -26,116 +27,200 @@ nonlinmodel = NonLinModel(f!, h!, Ts, 2, 4, 2, 1, p=linmodel, solver=nothing)
2627nonlinmodel = setop! (nonlinmodel, uop= [10 , 50 ], yop= [50 , 30 ], dop= [5 ])
2728u, d, y = [10 , 50 ], [5 ], [50 , 30 ]
2829
29- SUITE[" allocation" ][" SimModel" ] = BenchmarkGroup ([" allocation" ])
30- SUITE[" allocation" ][" SimModel" ][" LinModel_updatestate!" ] = @benchmarkable (
31- updatestate! ($ linmodel, $ u, $ d),
32- samples= 1
30+ # # ----------------- Runtime benchmarks ---------------------------------------------
31+ # TODO : Add runtime benchmarks for SimModel
32+
33+
34+ # # ----------------- Allocation benchmarks ------------------------------------------
35+ samples, evals = 1 , 1
36+ SUITE[" allocation" ][" SimModel" ][" LinModel" ][" updatestate!" ] = @benchmarkable (
37+ updatestate! ($ linmodel, $ u, $ d); samples= samples, evals= evals
3338)
34- SUITE[" allocation" ][" SimModel" ][" LinModel_evaloutput" ] = @benchmarkable (
35- evaloutput ($ linmodel, $ d),
36- samples= 1
39+ SUITE[" allocation" ][" SimModel" ][" LinModel" ][" evaloutput" ] = @benchmarkable (
40+ evaloutput ($ linmodel, $ d); samples= samples, evals= evals
3741)
38- SUITE[" allocation" ][" SimModel" ][" NonLinModel_updatestate!" ] = @benchmarkable (
39- updatestate! ($ nonlinmodel, $ u, $ d),
40- samples= 1
42+ SUITE[" allocation" ][" SimModel" ][" NonLinModel" ][" updatestate!" ] = @benchmarkable (
43+ updatestate! ($ nonlinmodel, $ u, $ d); samples= samples, evals= evals
4144)
42- SUITE[" allocation" ][" SimModel" ][" NonLinModel_evaloutput" ] = @benchmarkable (
43- evaloutput ($ nonlinmodel, $ d),
44- samples= 1
45+ SUITE[" allocation" ][" SimModel" ][" NonLinModel" ][" evaloutput" ] = @benchmarkable (
46+ evaloutput ($ nonlinmodel, $ d); samples= samples, evals= evals
4547)
46-
47- SUITE[" allocation" ][" SimModel" ][" NonLinModel_linearize!" ] = @benchmarkable (
48- linearize! ($ linmodel, $ nonlinmodel),
49- samples= 1
48+ SUITE[" allocation" ][" SimModel" ][" NonLinModel" ][" linearize!" ] = @benchmarkable (
49+ linearize! ($ linmodel, $ nonlinmodel); samples= samples, evals= evals
5050)
5151
5252# # ==================================================================================
5353# # ================== StateEstimator benchmarks =====================================
5454# # ==================================================================================
55+
56+
57+ # # ----------------- Runtime benchmarks ---------------------------------------------
58+ # TODO : Add runtime benchmarks for StateEstimator
59+
60+
61+ # # ----------------- Allocation benchmarks ------------------------------------------
62+ samples, evals = 1 , 1
63+
5564skf = SteadyKalmanFilter (linmodel)
56- SUITE[" allocation" ][" StateEstimator" ] = BenchmarkGroup ([" allocation" ])
57- SUITE[" allocation" ][" StateEstimator" ][" SteadyKalmanFilter_preparestate!" ] = @benchmarkable (
58- preparestate! ($ skf, $ y, $ d),
59- samples= 1
60- )
61- SUITE[" allocation" ][" StateEstimator" ][" SteadyKalmanFilter_updatestate!" ] = @benchmarkable (
62- updatestate! ($ skf, $ u, $ y, $ d),
63- setup= preparestate! ($ skf, $ y, $ d),
64- samples= 1
65- )
66- SUITE[" allocation" ][" StateEstimator" ][" SteadyKalmanFilter_evaloutput" ] = @benchmarkable (
67- evaloutput ($ skf, $ d),
68- setup= preparestate! ($ skf, $ y, $ d),
69- samples= 1
70- )
65+ SUITE[" allocation" ][" StateEstimator" ][" SteadyKalmanFilter" ][" preparestate!" ] =
66+ @benchmarkable (
67+ preparestate! ($ skf, $ y, $ d),
68+ samples= samples, evals= evals
69+ )
70+ SUITE[" allocation" ][" StateEstimator" ][" SteadyKalmanFilter" ][" updatestate!" ] =
71+ @benchmarkable (
72+ updatestate! ($ skf, $ u, $ y, $ d),
73+ setup= preparestate! ($ skf, $ y, $ d),
74+ samples= samples, evals= evals
75+ )
76+ SUITE[" allocation" ][" StateEstimator" ][" SteadyKalmanFilter" ][" evaloutput" ] =
77+ @benchmarkable (
78+ evaloutput ($ skf, $ d),
79+ setup= preparestate! ($ skf, $ y, $ d),
80+ samples= samples, evals= evals
81+ )
7182
7283kf = KalmanFilter (linmodel, nint_u= [1 , 1 ], direct= false )
73- SUITE[" allocation" ][" StateEstimator" ][" KalmanFilter_preparestate!" ] = @benchmarkable (
74- preparestate! ($ kf, $ y, $ d),
75- samples= 1
76- )
77- SUITE[" allocation" ][" StateEstimator" ][" KalmanFilter_updatestate!" ] = @benchmarkable (
78- updatestate! ($ kf, $ u, $ y, $ d),
79- setup= preparestate! ($ kf, $ y, $ d),
80- samples= 1
81- )
84+ SUITE[" allocation" ][" StateEstimator" ][" KalmanFilter" ][" preparestate!" ] =
85+ @benchmarkable (
86+ preparestate! ($ kf, $ y, $ d),
87+ samples= samples, evals= evals
88+ )
89+ SUITE[" allocation" ][" StateEstimator" ][" KalmanFilter" ][" updatestate!" ] =
90+ @benchmarkable (
91+ updatestate! ($ kf, $ u, $ y, $ d),
92+ setup= preparestate! ($ kf, $ y, $ d),
93+ samples= samples, evals= evals
94+ )
8295
8396lo = Luenberger (linmodel, nint_u= [1 , 1 ])
84- SUITE[" allocation" ][" StateEstimator" ][" Luenberger_preparestate!" ] = @benchmarkable (
85- preparestate! ($ lo, $ y, $ d),
86- samples= 1
87- )
88- SUITE[" allocation" ][" StateEstimator" ][" Luenberger_updatestate!" ] = @benchmarkable (
89- updatestate! ($ lo, $ u, $ y, $ d),
90- setup= preparestate! ($ lo, $ y, $ d),
91- samples= 1
92- )
97+ SUITE[" allocation" ][" StateEstimator" ][" Luenberger" ][" preparestate!" ] =
98+ @benchmarkable (
99+ preparestate! ($ lo, $ y, $ d),
100+ samples= samples, evals= evals
101+ )
102+ SUITE[" allocation" ][" StateEstimator" ][" Luenberger" ][" updatestate!" ] =
103+ @benchmarkable (
104+ updatestate! ($ lo, $ u, $ y, $ d),
105+ setup= preparestate! ($ lo, $ y, $ d),
106+ samples= samples, evals= evals
107+ )
93108
94109im = InternalModel (nonlinmodel)
95- SUITE[" allocation" ][" StateEstimator" ][" InternalModel_preparestate!" ] = @benchmarkable (
96- preparestate! ($ im, $ y, $ d),
97- samples= 1
98- )
99- SUITE[" allocation" ][" StateEstimator" ][" InternalModel_updatestate!" ] = @benchmarkable (
100- updatestate! ($ im, $ u, $ y, $ d),
101- setup= preparestate! ($ im, $ y, $ d),
102- samples= 1
103- )
110+ SUITE[" allocation" ][" StateEstimator" ][" InternalModel" ][" preparestate!" ] =
111+ @benchmarkable (
112+ preparestate! ($ im, $ y, $ d),
113+ samples= samples, evals= evals
114+ )
115+ SUITE[" allocation" ][" StateEstimator" ][" InternalModel" ][" updatestate!" ] =
116+ @benchmarkable (
117+ updatestate! ($ im, $ u, $ y, $ d),
118+ setup= preparestate! ($ im, $ y, $ d),
119+ samples= samples, evals= evals
120+ )
104121
105122ukf = UnscentedKalmanFilter (nonlinmodel)
106- SUITE[" allocation" ][" StateEstimator" ][" UnscentedKalmanFilter_preparestate!" ] = @benchmarkable (
107- preparestate! ($ ukf, $ y, $ d),
108- samples= 1
109- )
110- SUITE[" allocation" ][" StateEstimator" ][" UnscentedKalmanFilter_updatestate!" ] = @benchmarkable (
111- updatestate! ($ ukf, $ u, $ y, $ d),
112- setup= preparestate! ($ ukf, $ y, $ d),
113- samples= 1
114- )
115- SUITE[" allocation" ][" StateEstimator" ][" UnscentedKalmanFilter_evaloutput" ] = @benchmarkable (
116- evaloutput ($ ukf, $ d),
117- setup= preparestate! ($ ukf, $ y, $ d),
118- samples= 1
119- )
123+ SUITE[" allocation" ][" StateEstimator" ][" UnscentedKalmanFilter" ][" preparestate!" ] =
124+ @benchmarkable (
125+ preparestate! ($ ukf, $ y, $ d),
126+ samples= samples, evals= evals
127+ )
128+ SUITE[" allocation" ][" StateEstimator" ][" UnscentedKalmanFilter" ][" updatestate!" ] =
129+ @benchmarkable (
130+ updatestate! ($ ukf, $ u, $ y, $ d),
131+ setup= preparestate! ($ ukf, $ y, $ d),
132+ samples= samples, evals= evals
133+ )
134+ SUITE[" allocation" ][" StateEstimator" ][" UnscentedKalmanFilter" ][" evaloutput" ] =
135+ @benchmarkable (
136+ evaloutput ($ ukf, $ d),
137+ setup= preparestate! ($ ukf, $ y, $ d),
138+ samples= samples, evals= evals
139+ )
120140
121141ekf = ExtendedKalmanFilter (linmodel, nint_u= [1 , 1 ], direct= false )
122- SUITE[" allocation" ][" StateEstimator" ][" ExtendedKalmanFilter_preparestate!" ] = @benchmarkable (
123- preparestate! ($ ekf, $ y, $ d),
124- samples= 1
125- )
126- SUITE[" allocation" ][" StateEstimator" ][" ExtendedKalmanFilter_updatestate!" ] = @benchmarkable (
127- updatestate! ($ ekf, $ u, $ y, $ d),
128- setup= preparestate! ($ ekf, $ y, $ d),
129- samples= 1
130- )
142+ SUITE[" allocation" ][" StateEstimator" ][" ExtendedKalmanFilter" ][" preparestate!" ] =
143+ @benchmarkable (
144+ preparestate! ($ ekf, $ y, $ d),
145+ samples= samples, evals= evals
146+ )
147+ SUITE[" allocation" ][" StateEstimator" ][" ExtendedKalmanFilter" ][" updatestate!" ] =
148+ @benchmarkable (
149+ updatestate! ($ ekf, $ u, $ y, $ d),
150+ setup= preparestate! ($ ekf, $ y, $ d),
151+ samples= samples, evals= evals
152+ )
131153
132154# # ==================================================================================
133155# # ================== PredictiveController benchmarks ===============================
134156# # ==================================================================================
157+ G = [ tf (1.90 , [18 , 1 ]) tf (1.90 , [18 , 1 ]);
158+ tf (- 0.74 ,[8 , 1 ]) tf (0.74 , [8 , 1 ]) ]
159+ uop, yop = [20 , 20 ], [50 , 30 ]
160+ model = setop! (LinModel (G, 2.0 ); uop, yop)
161+ function test_mpc (mpc, plant)
162+ plant. x0 .= 0 ; y = plant ()
163+ initstate! (mpc, plant. uop, y)
164+ N = 75 ; ry = [50 , 30 ]; ul = 0
165+ U, Y, Ry = zeros (2 , N), zeros (2 , N), zeros (2 , N)
166+ for i = 1 : N
167+ i == 26 && (ry = [48 , 35 ])
168+ i == 51 && (ul = - 10 )
169+ y = plant ()
170+ preparestate! (mpc, y)
171+ u = mpc (ry)
172+ U[:,i], Y[:,i], Ry[:,i] = u, y, ry
173+ updatestate! (mpc, u, y)
174+ updatestate! (plant, u+ [0 ,ul])
175+ end
176+ return U, Y, Ry
177+ end
178+
179+ # # ----------------- Runtime benchmarks ---------------------------------------------
180+ optim = JuMP. Model (OSQP. Optimizer, add_bridges= false )
181+
182+ transcription = SingleShooting ()
183+ mpc_osqp_ss = setconstraint! (LinMPC (model; optim, transcription), ymin= [45 , - Inf ])
184+ JuMP. unset_time_limit_sec (mpc_osqp_ss. optim)
185+
186+ transcription = MultipleShooting ()
187+ mpc_osqp_ms = setconstraint! (LinMPC (model; optim, transcription), ymin= [45 , - Inf ])
188+ JuMP. unset_time_limit_sec (mpc_osqp_ms. optim)
189+
190+ optim = JuMP. Model (DAQP. Optimizer, add_bridges= false )
191+
192+ transcription = SingleShooting ()
193+ mpc_daqp_ss = setconstraint! (LinMPC (model; optim, transcription), ymin= [45 , - Inf ])
194+
195+ transcription = MultipleShooting ()
196+ mpc_daqp_ms = setconstraint! (LinMPC (model; optim, transcription), ymin= [45 , - Inf ])
197+
198+ samples, evals = 500 , 1
199+ SUITE[" runtime" ][" PredictiveController" ][" CSTR" ][" LinMPC" ][" OSQP" ][" SingleShooting" ] =
200+ @benchmarkable (test_mpc ($ mpc_osqp_ss, $ model);
201+ samples= samples, evals= evals
202+ )
203+ SUITE[" runtime" ][" PredictiveController" ][" CSTR" ][" LinMPC" ][" OSQP" ][" MultipleShooting" ] =
204+ @benchmarkable (test_mpc ($ mpc_osqp_ms, $ model);
205+ samples= samples, evals= evals
206+ )
207+ SUITE[" runtime" ][" PredictiveController" ][" CSTR" ][" LinMPC" ][" DAQP" ][" SingleShooting" ] =
208+ @benchmarkable (test_mpc ($ mpc_daqp_ss, $ model);
209+ samples= samples, evals= evals
210+ )
211+ SUITE[" runtime" ][" PredictiveController" ][" CSTR" ][" LinMPC" ][" DAQP" ][" MultipleShooting" ] =
212+ @benchmarkable (test_mpc ($ mpc_daqp_ms, $ model);
213+ samples= samples, evals= evals
214+ )
215+
216+
217+ # ---------------------- Allocation benchmarks ------------------------------------------
135218empc = ExplicitMPC (linmodel, Mwt= [1 , 1 ], Nwt= [0.1 , 0.1 ], Lwt= [0.1 , 0.1 ])
136- SUITE[" allocation" ][" PredictiveController" ] = BenchmarkGroup ([" allocation" ])
137- SUITE[" allocation" ][" PredictiveController" ][" ExplicitMPC_moveinput!" ] = @benchmarkable (
138- moveinput! ($ empc, $ y, $ d),
139- setup= preparestate! ($ empc, $ y, $ d),
140- samples= 1
141- )
219+
220+ samples, evals = 1 , 1
221+ SUITE[" allocation" ][" PredictiveController" ][" ExplicitMPC" ][" moveinput!" ] =
222+ @benchmarkable (
223+ moveinput! ($ empc, $ y, $ d),
224+ setup= preparestate! ($ empc, $ y, $ d),
225+ samples= samples, evals= evals
226+ )
0 commit comments