|
1 | 1 | using ModelingToolkit
|
2 |
| -using JuMP, InfiniteOpt |
| 2 | +import JuMP, InfiniteOpt |
3 | 3 | using DiffEqDevTools, DiffEqBase
|
4 | 4 | using SimpleDiffEq
|
5 | 5 | using OrdinaryDiffEqSDIRK
|
6 | 6 | using Ipopt
|
7 | 7 | using BenchmarkTools
|
| 8 | +using CairoMakie |
8 | 9 | const M = ModelingToolkit
|
9 | 10 |
|
10 | 11 | @testset "ODE Solution, no cost" begin
|
11 | 12 | # Test solving without anything attached.
|
12 | 13 | @parameters α=1.5 β=1.0 γ=3.0 δ=1.0
|
13 |
| - M.@variables x(..) y(..) |
| 14 | + @variables x(..) y(..) |
14 | 15 | t = M.t_nounits
|
15 | 16 | D = M.D_nounits
|
16 | 17 |
|
17 | 18 | eqs = [D(x(t)) ~ α * x(t) - β * x(t) * y(t),
|
18 | 19 | D(y(t)) ~ -γ * y(t) + δ * x(t) * y(t)]
|
19 | 20 |
|
| 21 | + @mtkbuild sys = ODESystem(eqs, t) |
20 | 22 | tspan = (0.0, 1.0)
|
21 | 23 | u0map = [x(t) => 4.0, y(t) => 2.0]
|
22 | 24 | parammap = [α => 1.5, β => 1.0, γ => 3.0, δ => 1.0]
|
23 |
| - @mtkbuild sys = ODESystem(eqs, t) |
24 | 25 |
|
25 | 26 | # Test explicit method.
|
26 | 27 | jprob = JuMPControlProblem(sys, u0map, tspan, parammap, dt = 0.01)
|
@@ -58,27 +59,70 @@ const M = ModelingToolkit
|
58 | 59 | sol = isol.sol
|
59 | 60 | @test sol(0.6)[1] ≈ 3.5
|
60 | 61 | @test sol(0.3)[1] ≈ 7.0
|
| 62 | + |
| 63 | + # Test whole-interval constraints |
| 64 | + constr = [x(t) > 3, y(t) > 4] |
| 65 | + @mtkbuild lksys = ODESystem(eqs, t; constraints = constr) |
| 66 | + iprob = InfiniteOptControlProblem( |
| 67 | + lksys, u0map, tspan, parammap; guesses = guess, dt = 0.01) |
| 68 | + isol = @btime solve( |
| 69 | + $iprob, Ipopt.Optimizer, derivative_method = OrthogonalCollocation(3), silent = true) # 48.564 ms, 9.58 MiB |
| 70 | + sol = isol.sol |
| 71 | + @test all(u -> u .> [3, 4], sol.u) |
| 72 | + |
| 73 | + jprob = JuMPControlProblem(lksys, u0map, tspan, parammap; guesses = guess, dt = 0.01) |
| 74 | + jsol = @btime solve($jprob, Ipopt.Optimizer, :RadauIA3, silent = true) # 12.190 s, 9.68 GiB |
| 75 | + sol = jsol.sol |
| 76 | + @test all(u -> u .> [3, 4], sol.u) |
61 | 77 | end
|
62 | 78 |
|
63 |
| -#@testset "Optimal control: bees" begin |
64 |
| -# # Example from Lawrence Evans' notes |
65 |
| -# M.@variables w(..) q(..) |
66 |
| -# M.@parameters α(t) [bounds = [0, 1]] b c μ s ν |
67 |
| -# |
68 |
| -# tspan = (0, 4) |
69 |
| -# eqs = [D(w(t)) ~ -μ*w(t) + b*s*α*w(t), |
70 |
| -# D(q(t)) ~ -ν*q(t) + c*(1 - α)*s*w(t)] |
71 |
| -# costs = [-q(tspan[2])] |
72 |
| -# |
73 |
| -# @mtkbuild beesys = ODESystem(eqs, t; costs) |
74 |
| -# u0map = [w(0) => 40, q(0) => 2] |
75 |
| -# pmap = [b => 1, c => 1, μ => 1, s => 1, ν => 1] |
76 |
| -# |
77 |
| -# jprob = JuMPControlProblem(beesys, u0map, tspan, pmap) |
78 |
| -# jsol = solve(jprob, Ipopt.Optimizer, :Tsitouras5) |
79 |
| -# control_sol = jsol.control_sol |
80 |
| -# # Bang-bang control |
81 |
| -#end |
| 79 | +@testset "Linear systems" begin |
| 80 | + function is_bangbang(input_sol, lbounds, ubounds) |
| 81 | + bangbang = true |
| 82 | + for v in 1:length(input_sol.u[1]) |
| 83 | + all(i -> i[v] ≈ bounds[v] || i[v] ≈ bounds[u], input_sol.u) || (bangbang = false) |
| 84 | + end |
| 85 | + bangbang |
| 86 | + end |
| 87 | + |
| 88 | + # Double integrator |
| 89 | + @variables x(..) [bounds = (0., 0.25)] v(..) |
| 90 | + @variables u(t) [bounds = (-1., 1.), input = true] |
| 91 | + constr = [v(1.0) ~ 0.0] |
| 92 | + cost = [-x(1.0)] # Optimize the final distance. |
| 93 | + @named block = ODESystem([D(x(t)) ~ v(t), D(v(t)) ~ u], t) |
| 94 | + block, input_idxs = structural_simplify(block, ([u],[])) |
| 95 | + |
| 96 | + u0map = [x(t) => 0., v(t) => 0.] |
| 97 | + tspan = (0., 1.) |
| 98 | + parammap = [u => 0.] |
| 99 | + jprob = JuMPControlProblem(block, u0map, tspan, parammap; dt = 0.01) |
| 100 | + jsol = solve(jprob, Ipopt.Optimizer, :Verner8) |
| 101 | + # Linear systems have bang-bang controls |
| 102 | + @test is_bangbang(jsol.input_sol, [-1.], [1.]) |
| 103 | + # Test reached final position. |
| 104 | + @test jsol.sol.u[end][1] ≈ 0.25 |
| 105 | + |
| 106 | + # Cart-pole system |
| 107 | + |
| 108 | + # Bee example (from Lawrence Evans' notes) |
| 109 | + M.@variables w(..) q(..) |
| 110 | + M.@parameters α(t) [bounds = [0, 1]] b c μ s ν |
| 111 | + |
| 112 | + tspan = (0, 4) |
| 113 | + eqs = [D(w(t)) ~ -μ*w(t) + b*s*α*w(t), |
| 114 | + D(q(t)) ~ -ν*q(t) + c*(1 - α)*s*w(t)] |
| 115 | + costs = [-q(tspan[2])] |
| 116 | + |
| 117 | + @mtkbuild beesys = ODESystem(eqs, t; costs) |
| 118 | + u0map = [w(0) => 40, q(0) => 2] |
| 119 | + pmap = [b => 1, c => 1, μ => 1, s => 1, ν => 1] |
| 120 | + |
| 121 | + jprob = JuMPControlProblem(beesys, u0map, tspan, pmap) |
| 122 | + jsol = solve(jprob, Ipopt.Optimizer, :Tsitouras5) |
| 123 | + control_sol = jsol.control_sol |
| 124 | + # Bang-bang control |
| 125 | +end |
82 | 126 | #
|
83 | 127 | #@testset "Constrained optimal control problems" begin
|
84 | 128 | #end
|
0 commit comments