|
498 | 498 |
|
499 | 499 | Init the nonlinear optimization for [`NonLinMPC`](@ref) controllers. |
500 | 500 | """ |
501 | | -function init_optimization!(mpc::NonLinMPC, model::SimModel, optim::JuMP.GenericModel) |
| 501 | +function init_optimization!( |
| 502 | + mpc::NonLinMPC, model::SimModel, optim::JuMP.GenericModel{JNT} |
| 503 | +) where JNT<:Real |
502 | 504 | # --- variables and linear constraints --- |
503 | 505 | con, transcription = mpc.con, mpc.transcription |
504 | 506 | nZ̃ = length(mpc.Z̃) |
@@ -527,8 +529,68 @@ function init_optimization!(mpc::NonLinMPC, model::SimModel, optim::JuMP.Generic |
527 | 529 | ) |
528 | 530 | @operator(optim, J, nZ̃, Jfunc, ∇Jfunc!) |
529 | 531 | @objective(optim, Min, J(Z̃var...)) |
530 | | - init_nonlincon!(mpc, model, transcription, gfuncs, ∇gfuncs!, geqfuncs, ∇geqfuncs!) |
531 | | - set_nonlincon!(mpc, model, transcription, optim) |
| 532 | + if JuMP.solver_name(optim) ≠ "Ipopt" |
| 533 | + init_nonlincon!(mpc, model, transcription, gfuncs, ∇gfuncs!, geqfuncs, ∇geqfuncs!) |
| 534 | + set_nonlincon!(mpc, model, transcription, optim) |
| 535 | + else |
| 536 | + # Test new experimental feature: |
| 537 | + |
| 538 | + |
| 539 | + J::Vector{JNT} = zeros(JNT, 1) |
| 540 | + ΔŨ::Vector{JNT} = zeros(JNT, nΔŨ) |
| 541 | + x̂0end::Vector{JNT} = zeros(JNT, nx̂) |
| 542 | + K0::Vector{JNT} = zeros(JNT, nK) |
| 543 | + Ue::Vector{JNT}, Ŷe::Vector{JNT} = zeros(JNT, nUe), zeros(JNT, nŶe) |
| 544 | + U0::Vector{JNT}, Ŷ0::Vector{JNT} = zeros(JNT, nU), zeros(JNT, nŶ) |
| 545 | + Û0::Vector{JNT}, X̂0::Vector{JNT} = zeros(JNT, nU), zeros(JNT, nX̂) |
| 546 | + gc::Vector{JNT}, g::Vector{JNT} = zeros(JNT, nc), zeros(JNT, ng) |
| 547 | + geq::Vector{JNT} = zeros(JNT, neq) |
| 548 | + |
| 549 | + geq_min = zeros(JNT, mpc.con.neq) |
| 550 | + geq_max = zeros(JNT, mpc.con.neq) |
| 551 | + |
| 552 | + |
| 553 | + function geqfunc!(geq, Z̃, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K0, X̂0, gc, g) |
| 554 | + update_predictions!(ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K0, X̂0, gc, g, geq, mpc, Z̃) |
| 555 | + return nothing |
| 556 | + end |
| 557 | + Z̃_∇geq = fill(myNaN, nZ̃) # NaN to force update_predictions! at first call |
| 558 | + ∇geq_context = ( |
| 559 | + Cache(ΔŨ), Cache(x̂0end), Cache(Ue), Cache(Ŷe), Cache(U0), Cache(Ŷ0), |
| 560 | + Cache(Û0), Cache(K0), Cache(X̂0), |
| 561 | + Cache(gc), Cache(g) |
| 562 | + ) |
| 563 | + ∇geq_prep = prepare_jacobian(geqfunc!, geq, jac, Z̃_∇geq, ∇geq_context...; strict) |
| 564 | + ∇geq = init_diffmat(JNT, jac, ∇geq_prep, nZ̃, neq) |
| 565 | + |
| 566 | + function geqfunc_set!(geq, Z̃) |
| 567 | + return geqfunc!(geq, Z̃, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K0, X̂0, gc, g) |
| 568 | + end |
| 569 | + function ∇geqfunc_set!(∇geq, Z̃) |
| 570 | + value_and_jacobian!(geqfunc!, geq, ∇geq, ∇geq_prep, jac, Z̃, ∇geq_context...) |
| 571 | + return nothing |
| 572 | + end |
| 573 | + |
| 574 | + #= |
| 575 | + # Langragian of the optimization problem: |
| 576 | + function Lfunc!(Z̃, μ, ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K0, X̂0, gc, g, geq) |
| 577 | + update_predictions!(ΔŨ, x̂0end, Ue, Ŷe, U0, Ŷ0, Û0, K0, X̂0, gc, g, geq, mpc, Z̃) |
| 578 | + J = obj_nonlinprog!(Ŷ0, U0, mpc, model, Ue, Ŷe, ΔŨ) |
| 579 | + L = J + dot(μ, geq) |
| 580 | + return L |
| 581 | + end |
| 582 | + =# |
| 583 | + |
| 584 | + |
| 585 | + set = Ipopt._VectorNonlinearOracle(; |
| 586 | + mpc.con.neq, |
| 587 | + geq_min, |
| 588 | + geq_max, |
| 589 | + geqfunc_set!, |
| 590 | + jacobian_structure, |
| 591 | + ∇geqfunc_set! |
| 592 | + ) |
| 593 | + end |
532 | 594 | return nothing |
533 | 595 | end |
534 | 596 |
|
|
0 commit comments