@@ -224,6 +224,142 @@ function OptimalControlSolution(
224
224
)
225
225
end
226
226
227
+
228
+ """
229
+ $(TYPEDSIGNATURES)
230
+
231
+ Build OCP functional solution from discrete solution (given as raw variables and multipliers plus some optional infos)
232
+ """
233
+ function OptimalControlSolution (
234
+ ocp:: OptimalControlModel ,
235
+ T,
236
+ X,
237
+ U,
238
+ v,
239
+ P;
240
+ objective = 0 ,
241
+ iterations = 0 ,
242
+ constraints_violation = 0 ,
243
+ message = " No msg" ,
244
+ stopping = nothing ,
245
+ success = nothing ,
246
+ constraints_types = (nothing , nothing , nothing , nothing , nothing ),
247
+ constraints_mult = (nothing , nothing , nothing , nothing , nothing ),
248
+ box_multipliers = (nothing , nothing , nothing , nothing , nothing , nothing ),
249
+ )
250
+ dim_x = state_dimension (ocp)
251
+ dim_u = control_dimension (ocp)
252
+ dim_v = variable_dimension (ocp)
253
+
254
+ # check that time grid is strictly increasing
255
+ # if not proceed with list of indexes as time grid
256
+ if ! issorted (T, lt = <= )
257
+ println (
258
+ " WARNING: time grid at solution is not strictly increasing, replacing with list of indices..." ,
259
+ )
260
+ println (T)
261
+ dim_NLP_steps = length (T) - 1
262
+ T = LinRange (0 , dim_NLP_steps, dim_NLP_steps + 1 )
263
+ end
264
+
265
+ # variables: remove additional state for lagrange cost
266
+ x = ctinterpolate (T, matrix2vec (X[:, 1 : dim_x], 1 ))
267
+ p = ctinterpolate (T[1 : (end - 1 )], matrix2vec (P[:, 1 : dim_x], 1 ))
268
+ u = ctinterpolate (T, matrix2vec (U[:, 1 : dim_u], 1 ))
269
+
270
+ # force scalar output when dimension is 1
271
+ fx = (dim_x == 1 ) ? deepcopy (t -> x (t)[1 ]) : deepcopy (t -> x (t))
272
+ fu = (dim_u == 1 ) ? deepcopy (t -> u (t)[1 ]) : deepcopy (t -> u (t))
273
+ fp = (dim_x == 1 ) ? deepcopy (t -> p (t)[1 ]) : deepcopy (t -> p (t))
274
+ var = (dim_v == 1 ) ? v[1 ] : v
275
+
276
+ # misc infos
277
+ infos = Dict {Symbol, Any} ()
278
+ infos[:constraints_violation ] = constraints_violation
279
+
280
+ # nonlinear constraints and multipliers
281
+ control_constraints = t -> ctinterpolate (T, matrix2vec (constraints_types[1 ], 1 ))(t)
282
+ mult_control_constraints = t -> ctinterpolate (T, matrix2vec (constraints_mult[1 ], 1 ))(t)
283
+ state_constraints = t -> ctinterpolate (T, matrix2vec (constraints_types[2 ], 1 ))(t)
284
+ mult_state_constraints = t -> ctinterpolate (T, matrix2vec (constraints_mult[2 ], 1 ))(t)
285
+ mixed_constraints = t -> ctinterpolate (T, matrix2vec (constraints_types[3 ], 1 ))(t)
286
+ mult_mixed_constraints = t -> ctinterpolate (T, matrix2vec (constraints_mult[3 ], 1 ))(t)
287
+
288
+ # boundary and variable constraints
289
+ boundary_constraints = constraints_types[4 ]
290
+ mult_boundary_constraints = constraints_mult[4 ]
291
+ variable_constraints = constraints_types[5 ]
292
+ mult_variable_constraints = constraints_mult[5 ]
293
+
294
+ # box constraints multipliers
295
+ mult_state_box_lower = t -> ctinterpolate (T, matrix2vec (box_multipliers[1 ][:, 1 : dim_x], 1 ))(t)
296
+ mult_state_box_upper = t -> ctinterpolate (T, matrix2vec (box_multipliers[2 ][:, 1 : dim_x], 1 ))
297
+ mult_control_box_lower = t -> ctinterpolate (T, matrix2vec (box_multipliers[3 ][:, 1 : dim_u], 1 ))(t)
298
+ mult_control_box_upper = t -> ctinterpolate (T, matrix2vec (box_multipliers[4 ][:, 1 : dim_u], 1 ))
299
+ mult_variable_box_lower, mult_variable_box_upper = box_multipliers[5 ], box_multipliers[6 ]
300
+
301
+ # build and return solution
302
+ if is_variable_dependent (ocp)
303
+ return OptimalControlSolution (
304
+ ocp;
305
+ state = fx,
306
+ control = fu,
307
+ objective = objective,
308
+ costate = fp,
309
+ time_grid = T,
310
+ variable = var,
311
+ iterations = iterations,
312
+ stopping = stopping,
313
+ message = message,
314
+ success = success,
315
+ infos = infos,
316
+ control_constraints = control_constraints,
317
+ state_constraints = state_constraints,
318
+ mixed_constraints = mixed_constraints,
319
+ boundary_constraints = boundary_constraints,
320
+ variable_constraints = variable_constraints,
321
+ mult_control_constraints = mult_control_constraints,
322
+ mult_state_constraints = mult_state_constraints,
323
+ mult_mixed_constraints = mult_mixed_constraints,
324
+ mult_boundary_constraints = mult_boundary_constraints,
325
+ mult_variable_constraints = mult_variable_constraints,
326
+ mult_state_box_lower = mult_state_box_lower,
327
+ mult_state_box_upper = mult_state_box_upper,
328
+ mult_control_box_lower = mult_control_box_lower,
329
+ mult_control_box_upper = mult_control_box_upper,
330
+ mult_variable_box_lower = mult_variable_box_lower,
331
+ mult_variable_box_upper = mult_variable_box_upper,
332
+ )
333
+ else
334
+ return OptimalControlSolution (
335
+ ocp;
336
+ state = fx,
337
+ control = fu,
338
+ objective = objective,
339
+ costate = fp,
340
+ time_grid = T,
341
+ iterations = iterations,
342
+ stopping = stopping,
343
+ message = message,
344
+ success = success,
345
+ infos = infos,
346
+ control_constraints = control_constraints,
347
+ state_constraints = state_constraints,
348
+ mixed_constraints = mixed_constraints,
349
+ boundary_constraints = boundary_constraints,
350
+ mult_control_constraints = mult_control_constraints,
351
+ mult_state_constraints = mult_state_constraints,
352
+ mult_mixed_constraints = mult_mixed_constraints,
353
+ mult_boundary_constraints = mult_boundary_constraints,
354
+ mult_state_box_lower = mult_state_box_lower,
355
+ mult_state_box_upper = mult_state_box_upper,
356
+ mult_control_box_lower = mult_control_box_lower,
357
+ mult_control_box_upper = mult_control_box_upper,
358
+ )
359
+ end
360
+ end
361
+
362
+
227
363
# setters
228
364
# state!(sol::OptimalControlSolution, state::Function) = (sol.state = state; nothing)
229
365
# control!(sol::OptimalControlSolution, control::Function) = (sol.control = control; nothing)
0 commit comments